Re: [PATCH] videobuf2-core: add queue_busy/idle queue ops

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

 



Hi Jacob,

When going through my TODO list with pending patches I came across this one from
a few weeks back. I noticed that your rga patch series didn't pick this up.

Does that mean that the ROTATE control can be changed while streaming without
requiring buffer size changes?

If not, then you will need this patch and update the rga driver.

Regards,

	Hans

On 09/22/2017 02:29 PM, Hans Verkuil wrote:
> Some controls (ROTATE) change the buffer layout. This means that they cannot
> be set when buffers are allocated. This can be achieved by calling
> v4l2_ctrl_grab(ctrl, true) when the queue becomes busy (i.e. the first buffer
> is allocated) and v4l2_ctrl_grab(ctrl, false) when the queue becomes idle (i.e.
> the last buffer is released).
> 
> However, we do not have such queue ops at the moment. This patch adds a queue_busy
> and a queue_idle op.
> 
> Note that currently queue_busy returns a void, so it assumes that it can't return
> an error.
> 
> Signed-off-by: Hans Verkuil <hans.verkuil@xxxxxxxxx>
> ---
> Jacob, this has only been compile-tested. It's best if you add this patch to your
> rockchip-rga patch series and test it there.
> ---
> diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
> index 14f83cecfa92..e8ad0e9f78d2 100644
> --- a/drivers/media/v4l2-core/videobuf2-core.c
> +++ b/drivers/media/v4l2-core/videobuf2-core.c
> @@ -665,6 +665,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
>  	}
> 
>  	if (*count == 0 || q->num_buffers != 0 || q->memory != memory) {
> +		num_buffers = q->num_buffers;
>  		/*
>  		 * We already have buffers allocated, so first check if they
>  		 * are not in use and can be freed.
> @@ -686,6 +687,8 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
>  		mutex_unlock(&q->mmap_lock);
>  		if (ret)
>  			return ret;
> +		if (num_buffers)
> +			call_void_qop(q, queue_idle, q);
> 
>  		/*
>  		 * In case of REQBUFS(0) return immediately without calling
> @@ -752,6 +755,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
>  		 */
>  	}
> 
> +	call_void_qop(q, queue_busy, q);
>  	mutex_lock(&q->mmap_lock);
>  	q->num_buffers = allocated_buffers;
> 
> @@ -762,6 +766,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
>  		 */
>  		__vb2_queue_free(q, allocated_buffers);
>  		mutex_unlock(&q->mmap_lock);
> +		call_void_qop(q, queue_idle, q);
>  		return ret;
>  	}
>  	mutex_unlock(&q->mmap_lock);
> @@ -842,6 +847,8 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
>  		 */
>  	}
> 
> +	if (!q->num_buffers)
> +		call_void_qop(q, queue_busy, q);
>  	mutex_lock(&q->mmap_lock);
>  	q->num_buffers += allocated_buffers;
> 
> @@ -852,6 +859,8 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
>  		 */
>  		__vb2_queue_free(q, allocated_buffers);
>  		mutex_unlock(&q->mmap_lock);
> +		if (!q->num_buffers)
> +			call_void_qop(q, queue_idle, q);
>  		return -ENOMEM;
>  	}
>  	mutex_unlock(&q->mmap_lock);
> @@ -2011,11 +2020,15 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read);
>  static int __vb2_cleanup_fileio(struct vb2_queue *q);
>  void vb2_core_queue_release(struct vb2_queue *q)
>  {
> +	bool was_busy = vb2_is_busy(q);
> +
>  	__vb2_cleanup_fileio(q);
>  	__vb2_queue_cancel(q);
>  	mutex_lock(&q->mmap_lock);
>  	__vb2_queue_free(q, q->num_buffers);
>  	mutex_unlock(&q->mmap_lock);
> +	if (was_busy)
> +		call_void_qop(q, queue_idle, q);
>  }
>  EXPORT_SYMBOL_GPL(vb2_core_queue_release);
> 
> diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
> index cb97c224be73..3aa039fd29ce 100644
> --- a/include/media/videobuf2-core.h
> +++ b/include/media/videobuf2-core.h
> @@ -315,6 +315,10 @@ struct vb2_buffer {
>   *			\*num_buffers are being allocated additionally to
>   *			q->num_buffers. If either \*num_planes or the requested
>   *			sizes are invalid callback must return %-EINVAL.
> + * @queue_busy:		called when the queue becomes busy (i.e. at least one
> + *			buffer has been allocated).
> + * @queue_idle:		called when the last buffer from the queue is released
> + *			and the queue is no longer marked busy.
>   * @wait_prepare:	release any locks taken while calling vb2 functions;
>   *			it is called before an ioctl needs to wait for a new
>   *			buffer to arrive; required to avoid a deadlock in
> @@ -380,6 +384,8 @@ struct vb2_ops {
>  	int (*queue_setup)(struct vb2_queue *q,
>  			   unsigned int *num_buffers, unsigned int *num_planes,
>  			   unsigned int sizes[], struct device *alloc_devs[]);
> +	void (*queue_busy)(struct vb2_queue *q);
> +	void (*queue_idle)(struct vb2_queue *q);
> 
>  	void (*wait_prepare)(struct vb2_queue *q);
>  	void (*wait_finish)(struct vb2_queue *q);
> @@ -547,6 +553,8 @@ struct vb2_queue {
>  	 * called. Used to check for unbalanced ops.
>  	 */
>  	u32				cnt_queue_setup;
> +	u32				cnt_queue_busy;
> +	u32				cnt_queue_idle;
>  	u32				cnt_wait_prepare;
>  	u32				cnt_wait_finish;
>  	u32				cnt_start_streaming;
> 




[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