/* Dequeue a buffer */ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) { const struct v4l2_event ev = { .type = V4L2_EVENT_EOS }; struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); int ret; if (ctx->state == MFCINST_ERROR) { mfc_err("Call on DQBUF after unrecoverable error\n"); return -EIO; } switch (buf->type) { case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: return vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK); case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: ret = vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK); if (ret) return ret; if (ctx->state == MFCINST_FINISHED && (ctx->dst_bufs[buf->index].flags & MFC_BUF_FLAG_EOS)) v4l2_event_queue_fh(&ctx->fh, &ev); return 0; default: return -EINVAL; } }
/* * msm_fd_wq_handler - Fd device workqueue handler. * @work: Pointer to work struct. * * This function is bottom half of fd irq what it does: * * - Stop the fd engine. * - Getter fd result and store in stats buffer. * - If available schedule next buffer for processing. * - Sent event to v4l2. * - Release buffer from v4l2 queue. */ static void msm_fd_wq_handler(struct work_struct *work) { struct msm_fd_buffer *active_buf; struct msm_fd_stats *stats; struct msm_fd_event *fd_event; struct msm_fd_device *fd; struct fd_ctx *ctx; struct v4l2_event event; int i; fd = container_of(work, struct msm_fd_device, work); active_buf = msm_fd_hw_get_active_buffer(fd); if (!active_buf) { /* This should never happen, something completely wrong */ dev_err(fd->dev, "Oops no active buffer empty queue\n"); return; } ctx = vb2_get_drv_priv(active_buf->vb.vb2_queue); /* Increment sequence number, 0 means sequence is not valid */ ctx->sequence++; if (unlikely(!ctx->sequence)) ctx->sequence = 1; /* Fill face detection statistics */ stats = &ctx->stats[ctx->sequence % MSM_FD_MAX_RESULT_BUFS]; /* First mark stats as invalid */ atomic_set(&stats->frame_id, 0); stats->face_cnt = msm_fd_hw_get_face_count(fd); for (i = 0; i < stats->face_cnt; i++) msm_fd_fill_results(fd, &stats->face_data[i], i); /* Stats are ready, set correct frame id */ atomic_set(&stats->frame_id, ctx->sequence); /* We have the data from fd hw, we can start next processing */ msm_fd_hw_schedule_next_buffer(fd); /* Sent event */ memset(&event, 0x00, sizeof(event)); event.type = MSM_EVENT_FD; fd_event = (struct msm_fd_event *)event.u.data; fd_event->face_cnt = stats->face_cnt; fd_event->buf_index = active_buf->vb.v4l2_buf.index; fd_event->frame_id = ctx->sequence; v4l2_event_queue_fh(&ctx->fh, &event); /* Return buffer to vb queue */ active_buf->vb.v4l2_buf.sequence = ctx->fh.sequence; vb2_buffer_done(&active_buf->vb, VB2_BUF_STATE_DONE); /* Release buffer from the device */ msm_fd_hw_buffer_done(fd, active_buf); }
static void hwcam_user_notify( hwcam_user_intf_t* intf, struct v4l2_event* ev) { hwcam_user_t* user = I2USER(intf); HWCAM_CFG_INFO("instance(0x%p). \n", user); if (user->eq.vdev) { v4l2_event_queue_fh(&user->eq, ev); HWCAM_CFG_INFO("instance(0x%p). \n", user); } }
/* Dequeue a buffer */ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) { const struct v4l2_event ev = { .type = V4L2_EVENT_EOS }; struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); int ret; if (ctx->state == MFCINST_ERROR) { mfc_err("Call on DQBUF after unrecoverable error\n"); return -EIO; } if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ret = vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK); else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { ret = vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK); if (ret == 0 && ctx->state == MFCINST_FINISHED && list_empty(&ctx->vq_dst.done_list)) v4l2_event_queue_fh(&ctx->fh, &ev); } else { ret = -EINVAL; } return ret; }
static void mtk_vdec_queue_res_chg_event(struct mtk_vcodec_ctx *ctx) { static const struct v4l2_event ev_src_ch = { .type = V4L2_EVENT_SOURCE_CHANGE, .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION, }; mtk_v4l2_debug(1, "[%d]", ctx->id); v4l2_event_queue_fh(&ctx->fh, &ev_src_ch); } static void mtk_vdec_flush_decoder(struct mtk_vcodec_ctx *ctx) { bool res_chg; int ret = 0; ret = vdec_if_decode(ctx, NULL, NULL, &res_chg); if (ret) mtk_v4l2_err("DecodeFinal failed, ret=%d", ret); clean_display_buffer(ctx); clean_free_buffer(ctx); }