Esempio n. 1
0
/* 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;
	}
}
Esempio n. 2
0
/*
 * 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);
}
Esempio n. 3
0
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);
    }
}
Esempio n. 4
0
/* 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;
}
Esempio n. 5
0
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);
}