diff mbox series

[v2,1/3] media: videobuf2-v4l2.c: add vb2_queue_change_type() helper

Message ID 20210412110211.275791-2-tomi.valkeinen@ideasonboard.com (mailing list archive)
State New, archived
Headers show
Series media: add vb2_queue_change_type() helper | expand

Commit Message

Tomi Valkeinen April 12, 2021, 11:02 a.m. UTC
On some platforms a video device can capture either video data or
metadata. The driver can implement vidioc functions for both video and
metadata, and use a single vb2_queue for the buffers. However, vb2_queue
requires choosing a single buffer type, which conflicts with the idea of
capturing either video or metadata.

The buffer type of vb2_queue can be changed, but it's not obvious how
this should be done in the drivers. To help this, add a new helper
function vb2_queue_change_type() which ensures the correct checks and
documents how it can be used.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
 drivers/media/common/videobuf2/videobuf2-v4l2.c | 14 ++++++++++++++
 include/media/videobuf2-v4l2.h                  | 15 +++++++++++++++
 2 files changed, 29 insertions(+)

Comments

Tomi Valkeinen April 23, 2021, 8:40 a.m. UTC | #1
On 12/04/2021 14:02, Tomi Valkeinen wrote:
> On some platforms a video device can capture either video data or
> metadata. The driver can implement vidioc functions for both video and
> metadata, and use a single vb2_queue for the buffers. However, vb2_queue
> requires choosing a single buffer type, which conflicts with the idea of
> capturing either video or metadata.
> 
> The buffer type of vb2_queue can be changed, but it's not obvious how
> this should be done in the drivers. To help this, add a new helper
> function vb2_queue_change_type() which ensures the correct checks and
> documents how it can be used.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
> ---
>   drivers/media/common/videobuf2/videobuf2-v4l2.c | 14 ++++++++++++++
>   include/media/videobuf2-v4l2.h                  | 15 +++++++++++++++
>   2 files changed, 29 insertions(+)
> 
> diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> index 7e96f67c60ba..2988bb38ceb1 100644
> --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
> +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> @@ -939,6 +939,20 @@ void vb2_queue_release(struct vb2_queue *q)
>   }
>   EXPORT_SYMBOL_GPL(vb2_queue_release);
>   
> +int vb2_queue_change_type(struct vb2_queue *q, unsigned int type)
> +{
> +	if (type == q->type)
> +		return 0;
> +
> +	if (vb2_is_busy(q))
> +		return -EBUSY;
> +
> +	q->type = type;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(vb2_queue_change_type);
> +
>   __poll_t vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
>   {
>   	struct video_device *vfd = video_devdata(file);
> diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h
> index c203047eb834..12fa72a664cf 100644
> --- a/include/media/videobuf2-v4l2.h
> +++ b/include/media/videobuf2-v4l2.h
> @@ -261,6 +261,21 @@ int __must_check vb2_queue_init_name(struct vb2_queue *q, const char *name);
>    */
>   void vb2_queue_release(struct vb2_queue *q);
>   
> +/**
> + * vb2_queue_change_type() - change the type of an inactive vb2_queue
> + * @q:		pointer to &struct vb2_queue with videobuf2 queue.
> + *
> + * This function changes the type of the vb2_queue. This is only possible
> + * if the queue is not busy (i.e. no buffers have been allocated).
> + *
> + * vb2_queue_change_type() can be used to support multiple buffer types using
> + * the same queue. The driver can implement v4l2_ioctl_ops.vidioc_reqbufs and
> + * v4l2_ioctl_ops.vidioc_create_bufs functions and call vb2_queue_change_type()
> + * before calling vb2_ioctl_reqbufs() or vb2_ioctl_create_bufs(), and thus
> + * "lock" the buffer type until the buffers have been released.
> + */
> +int vb2_queue_change_type(struct vb2_queue *q, unsigned int type);
> +
>   /**
>    * vb2_poll() - implements poll userspace operation
>    * @q:		pointer to &struct vb2_queue with videobuf2 queue.
> 

This is missing doc for the type parameter. I have added this to my branch:

@type:      The type to change to (V4L2_BUF_TYPE_VIDEO_*)

I'll send a v3 after I get feedback on the vivid patches.

  Tomi
Tomasz Figa June 4, 2021, 11:13 a.m. UTC | #2
Hi Tomi,

On Mon, Apr 12, 2021 at 02:02:09PM +0300, Tomi Valkeinen wrote:
> On some platforms a video device can capture either video data or
> metadata. The driver can implement vidioc functions for both video and
> metadata, and use a single vb2_queue for the buffers. However, vb2_queue
> requires choosing a single buffer type, which conflicts with the idea of
> capturing either video or metadata.
> 
> The buffer type of vb2_queue can be changed, but it's not obvious how
> this should be done in the drivers. To help this, add a new helper
> function vb2_queue_change_type() which ensures the correct checks and
> documents how it can be used.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
> ---
>  drivers/media/common/videobuf2/videobuf2-v4l2.c | 14 ++++++++++++++
>  include/media/videobuf2-v4l2.h                  | 15 +++++++++++++++
>  2 files changed, 29 insertions(+)
> 

Good to see you contributing to the media subsystem. Not sure if you
still remember me from the Common Display Framework discussions. ;)

Anyway, thanks for the patch. I think the code itself is okay, but I'm
wondering why the driver couldn't just have two queues, one for each
type?

Best regards,
Tomasz

> diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> index 7e96f67c60ba..2988bb38ceb1 100644
> --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
> +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> @@ -939,6 +939,20 @@ void vb2_queue_release(struct vb2_queue *q)
>  }
>  EXPORT_SYMBOL_GPL(vb2_queue_release);
>  
> +int vb2_queue_change_type(struct vb2_queue *q, unsigned int type)
> +{
> +	if (type == q->type)
> +		return 0;
> +
> +	if (vb2_is_busy(q))
> +		return -EBUSY;
> +
> +	q->type = type;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(vb2_queue_change_type);
> +
>  __poll_t vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
>  {
>  	struct video_device *vfd = video_devdata(file);
> diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h
> index c203047eb834..12fa72a664cf 100644
> --- a/include/media/videobuf2-v4l2.h
> +++ b/include/media/videobuf2-v4l2.h
> @@ -261,6 +261,21 @@ int __must_check vb2_queue_init_name(struct vb2_queue *q, const char *name);
>   */
>  void vb2_queue_release(struct vb2_queue *q);
>  
> +/**
> + * vb2_queue_change_type() - change the type of an inactive vb2_queue
> + * @q:		pointer to &struct vb2_queue with videobuf2 queue.
> + *
> + * This function changes the type of the vb2_queue. This is only possible
> + * if the queue is not busy (i.e. no buffers have been allocated).
> + *
> + * vb2_queue_change_type() can be used to support multiple buffer types using
> + * the same queue. The driver can implement v4l2_ioctl_ops.vidioc_reqbufs and
> + * v4l2_ioctl_ops.vidioc_create_bufs functions and call vb2_queue_change_type()
> + * before calling vb2_ioctl_reqbufs() or vb2_ioctl_create_bufs(), and thus
> + * "lock" the buffer type until the buffers have been released.
> + */
> +int vb2_queue_change_type(struct vb2_queue *q, unsigned int type);
> +
>  /**
>   * vb2_poll() - implements poll userspace operation
>   * @q:		pointer to &struct vb2_queue with videobuf2 queue.
> -- 
> 2.25.1
>
Tomi Valkeinen June 4, 2021, 2:09 p.m. UTC | #3
Hi Tomasz,

On 04/06/2021 14:13, Tomasz Figa wrote:
> Hi Tomi,
> 
> On Mon, Apr 12, 2021 at 02:02:09PM +0300, Tomi Valkeinen wrote:
>> On some platforms a video device can capture either video data or
>> metadata. The driver can implement vidioc functions for both video and
>> metadata, and use a single vb2_queue for the buffers. However, vb2_queue
>> requires choosing a single buffer type, which conflicts with the idea of
>> capturing either video or metadata.
>>
>> The buffer type of vb2_queue can be changed, but it's not obvious how
>> this should be done in the drivers. To help this, add a new helper
>> function vb2_queue_change_type() which ensures the correct checks and
>> documents how it can be used.
>>
>> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
>> ---
>>   drivers/media/common/videobuf2/videobuf2-v4l2.c | 14 ++++++++++++++
>>   include/media/videobuf2-v4l2.h                  | 15 +++++++++++++++
>>   2 files changed, 29 insertions(+)
>>
> 
> Good to see you contributing to the media subsystem. Not sure if you
> still remember me from the Common Display Framework discussions. ;)

I barely remember CDF... ;)

> Anyway, thanks for the patch. I think the code itself is okay, but I'm
> wondering why the driver couldn't just have two queues, one for each
> type?

There was an email thread about this:

https://www.spinics.net/lists/linux-media/msg189144.html

struct video_device has 'queue' field, so if you have two queues, you'd 
need to change the vd->queue based on the format. Possibly that could be 
a solution too (and, if I recall right, that's what I initially tried as 
a quick hack). Changing the whole queue sounds riskier than changing 
just the type.

  Tomi
Laurent Pinchart June 4, 2021, 2:38 p.m. UTC | #4
Hi Tomi,

Thank you for the patch.

On Mon, Apr 12, 2021 at 02:02:09PM +0300, Tomi Valkeinen wrote:
> On some platforms a video device can capture either video data or
> metadata. The driver can implement vidioc functions for both video and
> metadata, and use a single vb2_queue for the buffers. However, vb2_queue
> requires choosing a single buffer type, which conflicts with the idea of
> capturing either video or metadata.
> 
> The buffer type of vb2_queue can be changed, but it's not obvious how
> this should be done in the drivers. To help this, add a new helper
> function vb2_queue_change_type() which ensures the correct checks and
> documents how it can be used.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
> ---
>  drivers/media/common/videobuf2/videobuf2-v4l2.c | 14 ++++++++++++++
>  include/media/videobuf2-v4l2.h                  | 15 +++++++++++++++
>  2 files changed, 29 insertions(+)
> 
> diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> index 7e96f67c60ba..2988bb38ceb1 100644
> --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
> +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> @@ -939,6 +939,20 @@ void vb2_queue_release(struct vb2_queue *q)
>  }
>  EXPORT_SYMBOL_GPL(vb2_queue_release);
>  
> +int vb2_queue_change_type(struct vb2_queue *q, unsigned int type)
> +{
> +	if (type == q->type)
> +		return 0;
> +
> +	if (vb2_is_busy(q))
> +		return -EBUSY;
> +
> +	q->type = type;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(vb2_queue_change_type);
> +
>  __poll_t vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
>  {
>  	struct video_device *vfd = video_devdata(file);
> diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h
> index c203047eb834..12fa72a664cf 100644
> --- a/include/media/videobuf2-v4l2.h
> +++ b/include/media/videobuf2-v4l2.h
> @@ -261,6 +261,21 @@ int __must_check vb2_queue_init_name(struct vb2_queue *q, const char *name);
>   */
>  void vb2_queue_release(struct vb2_queue *q);
>  
> +/**
> + * vb2_queue_change_type() - change the type of an inactive vb2_queue
> + * @q:		pointer to &struct vb2_queue with videobuf2 queue.
> + *
> + * This function changes the type of the vb2_queue. This is only possible
> + * if the queue is not busy (i.e. no buffers have been allocated).
> + *
> + * vb2_queue_change_type() can be used to support multiple buffer types using
> + * the same queue. The driver can implement v4l2_ioctl_ops.vidioc_reqbufs and

I think this should be &v4l2_ioctl_ops.vidioc_reqbufs() (same below) to
generate links properly.

> + * v4l2_ioctl_ops.vidioc_create_bufs functions and call vb2_queue_change_type()
> + * before calling vb2_ioctl_reqbufs() or vb2_ioctl_create_bufs(), and thus
> + * "lock" the buffer type until the buffers have been released.

It would be nice if selection of the type could be moved to the
.queue_setup() operation, but that's more difficult and would require
rework of the reqbufs and create_bufs implementations that may be
tricky.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> + */
> +int vb2_queue_change_type(struct vb2_queue *q, unsigned int type);
> +
>  /**
>   * vb2_poll() - implements poll userspace operation
>   * @q:		pointer to &struct vb2_queue with videobuf2 queue.
Tomasz Figa June 8, 2021, 5:11 a.m. UTC | #5
On Fri, Jun 4, 2021 at 11:09 PM Tomi Valkeinen
<tomi.valkeinen@ideasonboard.com> wrote:
>
> Hi Tomasz,
>
> On 04/06/2021 14:13, Tomasz Figa wrote:
> > Hi Tomi,
> >
> > On Mon, Apr 12, 2021 at 02:02:09PM +0300, Tomi Valkeinen wrote:
> >> On some platforms a video device can capture either video data or
> >> metadata. The driver can implement vidioc functions for both video and
> >> metadata, and use a single vb2_queue for the buffers. However, vb2_queue
> >> requires choosing a single buffer type, which conflicts with the idea of
> >> capturing either video or metadata.
> >>
> >> The buffer type of vb2_queue can be changed, but it's not obvious how
> >> this should be done in the drivers. To help this, add a new helper
> >> function vb2_queue_change_type() which ensures the correct checks and
> >> documents how it can be used.
> >>
> >> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
> >> ---
> >>   drivers/media/common/videobuf2/videobuf2-v4l2.c | 14 ++++++++++++++
> >>   include/media/videobuf2-v4l2.h                  | 15 +++++++++++++++
> >>   2 files changed, 29 insertions(+)
> >>
> >
> > Good to see you contributing to the media subsystem. Not sure if you
> > still remember me from the Common Display Framework discussions. ;)
>
> I barely remember CDF... ;)
>
> > Anyway, thanks for the patch. I think the code itself is okay, but I'm
> > wondering why the driver couldn't just have two queues, one for each
> > type?
>
> There was an email thread about this:
>
> https://www.spinics.net/lists/linux-media/msg189144.html
>
> struct video_device has 'queue' field, so if you have two queues, you'd
> need to change the vd->queue based on the format. Possibly that could be
> a solution too (and, if I recall right, that's what I initially tried as
> a quick hack). Changing the whole queue sounds riskier than changing
> just the type.

Okay, I see. Thanks for the pointer.

Generally I'm fine with this, although it's worth noting that it's not
true that one video_device can only have 1 queue. See the numerous
mem-to-mem devices, which use two queues simultaneously.

Anyway,

Acked-by: Tomasz Figa <tfiga@chromium.org>

Best regards,
Tomasz
diff mbox series

Patch

diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c
index 7e96f67c60ba..2988bb38ceb1 100644
--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
@@ -939,6 +939,20 @@  void vb2_queue_release(struct vb2_queue *q)
 }
 EXPORT_SYMBOL_GPL(vb2_queue_release);
 
+int vb2_queue_change_type(struct vb2_queue *q, unsigned int type)
+{
+	if (type == q->type)
+		return 0;
+
+	if (vb2_is_busy(q))
+		return -EBUSY;
+
+	q->type = type;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_queue_change_type);
+
 __poll_t vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
 {
 	struct video_device *vfd = video_devdata(file);
diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h
index c203047eb834..12fa72a664cf 100644
--- a/include/media/videobuf2-v4l2.h
+++ b/include/media/videobuf2-v4l2.h
@@ -261,6 +261,21 @@  int __must_check vb2_queue_init_name(struct vb2_queue *q, const char *name);
  */
 void vb2_queue_release(struct vb2_queue *q);
 
+/**
+ * vb2_queue_change_type() - change the type of an inactive vb2_queue
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ *
+ * This function changes the type of the vb2_queue. This is only possible
+ * if the queue is not busy (i.e. no buffers have been allocated).
+ *
+ * vb2_queue_change_type() can be used to support multiple buffer types using
+ * the same queue. The driver can implement v4l2_ioctl_ops.vidioc_reqbufs and
+ * v4l2_ioctl_ops.vidioc_create_bufs functions and call vb2_queue_change_type()
+ * before calling vb2_ioctl_reqbufs() or vb2_ioctl_create_bufs(), and thus
+ * "lock" the buffer type until the buffers have been released.
+ */
+int vb2_queue_change_type(struct vb2_queue *q, unsigned int type);
+
 /**
  * vb2_poll() - implements poll userspace operation
  * @q:		pointer to &struct vb2_queue with videobuf2 queue.