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
State Superseded
Headers show
Series [v2,1/3] media: videobuf2-v4l2.c: 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.


-- 
Regards,

Laurent Pinchart
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.