Re: [PATCH/RFC] media: vb2: change queue initialization order

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Marek,

Are you planning a RFCv2 for this?

I've been implementing vb2 in an internal driver and this initialization
order of vb2 is a bit of a pain to be honest.

Regards,

	Hans

On Wednesday, June 29, 2011 11:49:06 Marek Szyprowski wrote:
> This patch introduces VB2_STREAMON_WITHOUT_BUFFERS io flag and changes
> the order of operations during stream on operation. Now the buffer are
> first queued to the driver and then the start_streaming method is called.
> This resolves the most common case when the driver needs to know buffer
> addresses to enable dma engine and start streaming. For drivers that can
> handle start_streaming without queued buffers (mem2mem and 'one shot'
> capture case) a new VB2_STREAMON_WITHOUT_BUFFERS io flag has been
> introduced. Driver can set it to let videobuf2 know that it support this
> mode.
> 
> This patch also updates videobuf2 clients (s5p-fimc, mem2mem_testdev and
> vivi) to work properly with the changed order of operations and enables
> use of the newly introduced flag.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@xxxxxxxxxxx>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@xxxxxxxxxxx>
> Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx>
> CC: Pawel Osciak <pawel@xxxxxxxxxx>
> ---
> 
>  drivers/media/video/mem2mem_testdev.c       |    4 +-
>  drivers/media/video/s5p-fimc/fimc-capture.c |   65 
++++++++++++++++----------
>  drivers/media/video/s5p-fimc/fimc-core.c    |    4 +-
>  drivers/media/video/videobuf2-core.c        |   21 ++++-----
>  drivers/media/video/vivi.c                  |    2 +-
>  include/media/videobuf2-core.h              |   11 +++--
>  6 files changed, 62 insertions(+), 45 deletions(-)
> 
> 
> ---
> 
> Hello,
> 
> This patch introduces significant changes in the vb2 streamon operation,
> so all vb2 clients need to be checked and updated. Right now I didn't
> update mx3_camera and sh_mobile_ceu_camera drivers. Once we agree that
> this patch can be merged, I will update it to include all the required
> changes to these two drivers as well.
> 
> Best regards
> -- 
> Marek Szyprowski
> Samsung Poland R&D Center
> 
> diff --git a/drivers/media/video/mem2mem_testdev.c 
b/drivers/media/video/mem2mem_testdev.c
> index b03d74e..65fb4ad 100644
> --- a/drivers/media/video/mem2mem_testdev.c
> +++ b/drivers/media/video/mem2mem_testdev.c
> @@ -808,7 +808,7 @@ static int queue_init(void *priv, struct vb2_queue 
*src_vq, struct vb2_queue *ds
>  
>  	memset(src_vq, 0, sizeof(*src_vq));
>  	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
> -	src_vq->io_modes = VB2_MMAP;
> +	src_vq->io_modes = VB2_MMAP | VB2_STREAMON_WITHOUT_BUFFERS;
>  	src_vq->drv_priv = ctx;
>  	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
>  	src_vq->ops = &m2mtest_qops;
> @@ -820,7 +820,7 @@ static int queue_init(void *priv, struct vb2_queue 
*src_vq, struct vb2_queue *ds
>  
>  	memset(dst_vq, 0, sizeof(*dst_vq));
>  	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> -	dst_vq->io_modes = VB2_MMAP;
> +	dst_vq->io_modes = VB2_MMAP | VB2_STREAMON_WITHOUT_BUFFERS;
>  	dst_vq->drv_priv = ctx;
>  	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
>  	dst_vq->ops = &m2mtest_qops;
> diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c 
b/drivers/media/video/s5p-fimc/fimc-capture.c
> index d142b40..20a5bd4 100644
> --- a/drivers/media/video/s5p-fimc/fimc-capture.c
> +++ b/drivers/media/video/s5p-fimc/fimc-capture.c
> @@ -152,27 +152,11 @@ static int fimc_isp_subdev_init(struct fimc_dev *fimc, 
unsigned int index)
>  	return ret;
>  }
>  
> -static int fimc_stop_capture(struct fimc_dev *fimc)
> +static void fimc_capture_state_cleanup(struct fimc_dev *fimc)
>  {
> -	unsigned long flags;
> -	struct fimc_vid_cap *cap;
> +	struct fimc_vid_cap *cap = &fimc->vid_cap;
>  	struct fimc_vid_buffer *buf;
> -
> -	cap = &fimc->vid_cap;
> -
> -	if (!fimc_capture_active(fimc))
> -		return 0;
> -
> -	spin_lock_irqsave(&fimc->slock, flags);
> -	set_bit(ST_CAPT_SHUT, &fimc->state);
> -	fimc_deactivate_capture(fimc);
> -	spin_unlock_irqrestore(&fimc->slock, flags);
> -
> -	wait_event_timeout(fimc->irq_queue,
> -			   !test_bit(ST_CAPT_SHUT, &fimc->state),
> -			   FIMC_SHUTDOWN_TIMEOUT);
> -
> -	v4l2_subdev_call(cap->sd, video, s_stream, 0);
> +	unsigned long flags;
>  
>  	spin_lock_irqsave(&fimc->slock, flags);
>  	fimc->state &= ~(1 << ST_CAPT_RUN | 1 << ST_CAPT_PEND |
> @@ -192,27 +176,50 @@ static int fimc_stop_capture(struct fimc_dev *fimc)
>  	}
>  
>  	spin_unlock_irqrestore(&fimc->slock, flags);
> +}
> +
> +static int fimc_stop_capture(struct fimc_dev *fimc)
> +{
> +	struct fimc_vid_cap *cap = &fimc->vid_cap;
> +	unsigned long flags;
> +
> +	if (!fimc_capture_active(fimc))
> +		return 0;
> +
> +	spin_lock_irqsave(&fimc->slock, flags);
> +	set_bit(ST_CAPT_SHUT, &fimc->state);
> +	fimc_deactivate_capture(fimc);
> +	spin_unlock_irqrestore(&fimc->slock, flags);
> +
> +	wait_event_timeout(fimc->irq_queue,
> +			   !test_bit(ST_CAPT_SHUT, &fimc->state),
> +			   FIMC_SHUTDOWN_TIMEOUT);
>  
> +	v4l2_subdev_call(cap->sd, video, s_stream, 0);
> +
> +	fimc_capture_state_cleanup(fimc);
>  	dbg("state: 0x%lx", fimc->state);
>  	return 0;
>  }
>  
> +
>  static int start_streaming(struct vb2_queue *q)
>  {
>  	struct fimc_ctx *ctx = q->drv_priv;
>  	struct fimc_dev *fimc = ctx->fimc_dev;
>  	struct s5p_fimc_isp_info *isp_info;
> +	int min_bufs;
>  	int ret;
>  
>  	fimc_hw_reset(fimc);
>  
>  	ret = v4l2_subdev_call(fimc->vid_cap.sd, video, s_stream, 1);
>  	if (ret && ret != -ENOIOCTLCMD)
> -		return ret;
> +		goto error;
>  
>  	ret = fimc_prepare_config(ctx, ctx->state);
>  	if (ret)
> -		return ret;
> +		goto error;
>  
>  	isp_info = &fimc->pdata->isp_info[fimc->vid_cap.input_index];
>  	fimc_hw_set_camera_type(fimc, isp_info);
> @@ -223,7 +230,7 @@ static int start_streaming(struct vb2_queue *q)
>  		ret = fimc_set_scaler_info(ctx);
>  		if (ret) {
>  			err("Scaler setup error");
> -			return ret;
> +			goto error;
>  		}
>  		fimc_hw_set_input_path(ctx);
>  		fimc_hw_set_prescaler(ctx);
> @@ -238,13 +245,20 @@ static int start_streaming(struct vb2_queue *q)
>  
>  	INIT_LIST_HEAD(&fimc->vid_cap.pending_buf_q);
>  	INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
> -	fimc->vid_cap.active_buf_cnt = 0;
>  	fimc->vid_cap.frame_count = 0;
>  	fimc->vid_cap.buf_index = 0;
>  
>  	set_bit(ST_CAPT_PEND, &fimc->state);
>  
> +	min_bufs = fimc->vid_cap.reqbufs_count > 1 ? 2 : 1;
> +
> +	if (fimc->vid_cap.active_buf_cnt >= min_bufs)
> +		fimc_activate_capture(ctx);
> +
>  	return 0;
> +error:
> +	fimc_capture_state_cleanup(fimc);
> +	return ret;
>  }
>  
>  static int stop_streaming(struct vb2_queue *q)
> @@ -357,7 +371,8 @@ static void buffer_queue(struct vb2_buffer *vb)
>  
>  	min_bufs = vid_cap->reqbufs_count > 1 ? 2 : 1;
>  
> -	if (vid_cap->active_buf_cnt >= min_bufs &&
> +	if (vb2_is_streaming(vb->vb2_queue) &&
> +	    vid_cap->active_buf_cnt >= min_bufs &&
>  	    !test_and_set_bit(ST_CAPT_STREAM, &fimc->state))
>  		fimc_activate_capture(ctx);
>  
> @@ -878,7 +893,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc)
>  	q = &fimc->vid_cap.vbq;
>  	memset(q, 0, sizeof(*q));
>  	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
> -	q->io_modes = VB2_MMAP | VB2_USERPTR;
> +	q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_STREAMON_WITHOUT_BUFFERS;
>  	q->drv_priv = fimc->vid_cap.ctx;
>  	q->ops = &fimc_capture_qops;
>  	q->mem_ops = &vb2_dma_contig_memops;
> diff --git a/drivers/media/video/s5p-fimc/fimc-core.c 
b/drivers/media/video/s5p-fimc/fimc-core.c
> index dc91a85..6a405c8 100644
> --- a/drivers/media/video/s5p-fimc/fimc-core.c
> +++ b/drivers/media/video/s5p-fimc/fimc-core.c
> @@ -1386,7 +1386,7 @@ static int queue_init(void *priv, struct vb2_queue 
*src_vq,
>  
>  	memset(src_vq, 0, sizeof(*src_vq));
>  	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
> -	src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
> +	src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_STREAMON_WITHOUT_BUFFERS;
>  	src_vq->drv_priv = ctx;
>  	src_vq->ops = &fimc_qops;
>  	src_vq->mem_ops = &vb2_dma_contig_memops;
> @@ -1398,7 +1398,7 @@ static int queue_init(void *priv, struct vb2_queue 
*src_vq,
>  
>  	memset(dst_vq, 0, sizeof(*dst_vq));
>  	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
> -	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
> +	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_STREAMON_WITHOUT_BUFFERS;
>  	dst_vq->drv_priv = ctx;
>  	dst_vq->ops = &fimc_qops;
>  	dst_vq->mem_ops = &vb2_dma_contig_memops;
> diff --git a/drivers/media/video/videobuf2-core.c 
b/drivers/media/video/videobuf2-core.c
> index 5517913..911e2eb 100644
> --- a/drivers/media/video/videobuf2-core.c
> +++ b/drivers/media/video/videobuf2-core.c
> @@ -1136,17 +1136,23 @@ int vb2_streamon(struct vb2_queue *q, enum 
v4l2_buf_type type)
>  	}
>  
>  	/*
> -	 * Cannot start streaming on an OUTPUT device if no buffers have
> -	 * been queued yet.
> +	 * Cannot start streaming if driver requires queued buffers.
>  	 */
> -	if (V4L2_TYPE_IS_OUTPUT(q->type)) {
> +	if (!(q->io_flags & VB2_STREAMON_WITHOUT_BUFFERS)) {
>  		if (list_empty(&q->queued_list)) {
> -			dprintk(1, "streamon: no output buffers queued\n");
> +			dprintk(1, "streamon: no buffers queued\n");
>  			return -EINVAL;
>  		}
>  	}
>  
>  	/*
> +	 * If any buffers were queued before streamon,
> +	 * we can now pass them to driver for processing.
> +	 */
> +	list_for_each_entry(vb, &q->queued_list, queued_entry)
> +		__enqueue_in_driver(vb);
> +
> +	/*
>  	 * Let driver notice that streaming state has been enabled.
>  	 */
>  	ret = call_qop(q, start_streaming, q);
> @@ -1157,13 +1163,6 @@ int vb2_streamon(struct vb2_queue *q, enum 
v4l2_buf_type type)
>  
>  	q->streaming = 1;
>  
> -	/*
> -	 * If any buffers were queued before streamon,
> -	 * we can now pass them to driver for processing.
> -	 */
> -	list_for_each_entry(vb, &q->queued_list, queued_entry)
> -		__enqueue_in_driver(vb);
> -
>  	dprintk(3, "Streamon successful\n");
>  	return 0;
>  }
> diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
> index 2238a61..e740a44 100644
> --- a/drivers/media/video/vivi.c
> +++ b/drivers/media/video/vivi.c
> @@ -1232,7 +1232,7 @@ static int __init vivi_create_instance(int inst)
>  	q = &dev->vb_vidq;
>  	memset(q, 0, sizeof(dev->vb_vidq));
>  	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> -	q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
> +	q->io_modes = VB2_MMAP | VB2_READ | VB2_STREAMON_WITHOUT_BUFFERS;
>  	q->drv_priv = dev;
>  	q->buf_struct_size = sizeof(struct vivi_buffer);
>  	q->ops = &vivi_video_qops;
> diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
> index f87472a..cdc0558 100644
> --- a/include/media/videobuf2-core.h
> +++ b/include/media/videobuf2-core.h
> @@ -84,12 +84,15 @@ struct vb2_plane {
>   * @VB2_USERPTR:	driver supports USERPTR with streaming API
>   * @VB2_READ:		driver supports read() style access
>   * @VB2_WRITE:		driver supports write() style access
> + * @VB2_STREAMON_WITHOUT_BUFFERS: driver supports stream_on() without 
buffers
> + *			queued
>   */
>  enum vb2_io_modes {
> -	VB2_MMAP	= (1 << 0),
> -	VB2_USERPTR	= (1 << 1),
> -	VB2_READ	= (1 << 2),
> -	VB2_WRITE	= (1 << 3),
> +	VB2_MMAP			= (1 << 0),
> +	VB2_USERPTR			= (1 << 1),
> +	VB2_READ			= (1 << 2),
> +	VB2_WRITE			= (1 << 3),
> +	VB2_STREAMON_WITHOUT_BUFFERS	= (1 << 16),
>  };
>  
>  /**
> -- 
> 1.7.1.569.g6f426
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux