* [PATCH 0/3] media: uvcvideo: Improvements for UVC metadata
@ 2026-03-09 15:01 Ricardo Ribalda
2026-03-09 15:01 ` [PATCH 1/3] media: uvcvideo: Enable VB2_DMABUF for metadata stream Ricardo Ribalda
` (3 more replies)
0 siblings, 4 replies; 16+ messages in thread
From: Ricardo Ribalda @ 2026-03-09 15:01 UTC (permalink / raw)
To: Laurent Pinchart, Hans de Goede, Mauro Carvalho Chehab,
Guennadi Liakhovetski
Cc: linux-media, linux-kernel, Yunke Cao, Ricardo Ribalda, stable
This series introduces some improvements for UVC metadata:
- Allow bigger sizes of metadata.
- Refactor the code to avoid invalid pointer arithmetic.
- Add support for DMABUF
Cheers!
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
---
Ricardo Ribalda (3):
media: uvcvideo: Enable VB2_DMABUF for metadata stream
media: uvcvideo: uvc_queue_to_stream(): Support meta queues
media: uvcvideo: Allow userspace to increase the meta buffersize
drivers/media/usb/uvc/uvc_isight.c | 3 ++-
drivers/media/usb/uvc/uvc_metadata.c | 9 +++++++--
drivers/media/usb/uvc/uvc_queue.c | 18 ++++++++----------
drivers/media/usb/uvc/uvcvideo.h | 7 +++++--
4 files changed, 22 insertions(+), 15 deletions(-)
---
base-commit: a7da7fb57f2a787412da1a62292a17fa00fbfbdf
change-id: 20260309-uvc-metadata-dmabuf-b98359eec8dd
Best regards,
--
Ricardo Ribalda <ribalda@chromium.org>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 1/3] media: uvcvideo: Enable VB2_DMABUF for metadata stream
2026-03-09 15:01 [PATCH 0/3] media: uvcvideo: Improvements for UVC metadata Ricardo Ribalda
@ 2026-03-09 15:01 ` Ricardo Ribalda
2026-03-16 11:47 ` Hans de Goede
2026-03-18 19:15 ` Laurent Pinchart
2026-03-09 15:01 ` [PATCH 2/3] media: uvcvideo: uvc_queue_to_stream(): Support meta queues Ricardo Ribalda
` (2 subsequent siblings)
3 siblings, 2 replies; 16+ messages in thread
From: Ricardo Ribalda @ 2026-03-09 15:01 UTC (permalink / raw)
To: Laurent Pinchart, Hans de Goede, Mauro Carvalho Chehab,
Guennadi Liakhovetski
Cc: linux-media, linux-kernel, Yunke Cao, Ricardo Ribalda, stable
The UVC driver has two video streams, one for the frames and another one
for the metadata. Both streams share most of the codebase, but only the
data stream declares support for DMABUF transfer mode.
I have tried the DMABUF transfer mode with CONFIG_DMABUF_HEAPS_SYSTEM
and the frames looked correct.
This patch announces the support for DMABUF for the metadata stream.
This is useful for apps/HALs that only want to support DMABUF.
Cc: stable@vger.kernel.org
Fixes: 088ead2552458 ("media: uvcvideo: Add a metadata device node")
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
---
drivers/media/usb/uvc/uvc_queue.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
index 8b8f44b4a045..0eddd4f872ca 100644
--- a/drivers/media/usb/uvc/uvc_queue.c
+++ b/drivers/media/usb/uvc/uvc_queue.c
@@ -243,7 +243,7 @@ int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
int ret;
queue->queue.type = type;
- queue->queue.io_modes = VB2_MMAP | VB2_USERPTR;
+ queue->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
queue->queue.drv_priv = queue;
queue->queue.buf_struct_size = sizeof(struct uvc_buffer);
queue->queue.mem_ops = &vb2_vmalloc_memops;
@@ -256,7 +256,6 @@ int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
queue->queue.ops = &uvc_meta_queue_qops;
break;
default:
- queue->queue.io_modes |= VB2_DMABUF;
queue->queue.ops = &uvc_queue_qops;
break;
}
--
2.53.0.473.g4a7958ca14-goog
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 2/3] media: uvcvideo: uvc_queue_to_stream(): Support meta queues
2026-03-09 15:01 [PATCH 0/3] media: uvcvideo: Improvements for UVC metadata Ricardo Ribalda
2026-03-09 15:01 ` [PATCH 1/3] media: uvcvideo: Enable VB2_DMABUF for metadata stream Ricardo Ribalda
@ 2026-03-09 15:01 ` Ricardo Ribalda
2026-03-16 11:49 ` Hans de Goede
2026-03-18 19:18 ` Laurent Pinchart
2026-03-09 15:01 ` [PATCH 3/3] media: uvcvideo: Allow userspace to increase the meta buffersize Ricardo Ribalda
2026-03-16 12:05 ` [PATCH 0/3] media: uvcvideo: Improvements for UVC metadata Hans de Goede
3 siblings, 2 replies; 16+ messages in thread
From: Ricardo Ribalda @ 2026-03-09 15:01 UTC (permalink / raw)
To: Laurent Pinchart, Hans de Goede, Mauro Carvalho Chehab,
Guennadi Liakhovetski
Cc: linux-media, linux-kernel, Yunke Cao, Ricardo Ribalda
The stream data structure has two queues: the metadata and the data
queues, but uvc_queue_to_stream() only supports the data queue. If we
pass the metadata queue the function will return an invalid pointer.
This patch add a parameter to the function to explicitly tell the
function which queue are we using.
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
---
drivers/media/usb/uvc/uvc_isight.c | 3 ++-
drivers/media/usb/uvc/uvc_queue.c | 13 ++++++-------
drivers/media/usb/uvc/uvcvideo.h | 4 +++-
3 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/media/usb/uvc/uvc_isight.c b/drivers/media/usb/uvc/uvc_isight.c
index 43cda5e760a3..ea9dc31dfbad 100644
--- a/drivers/media/usb/uvc/uvc_isight.c
+++ b/drivers/media/usb/uvc/uvc_isight.c
@@ -41,7 +41,8 @@ static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf,
0xde, 0xad, 0xfa, 0xce
};
- struct uvc_streaming *stream = uvc_queue_to_stream(queue);
+ struct uvc_streaming *stream = uvc_queue_to_stream(queue,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE);
unsigned int maxlen, nbytes;
u8 *mem;
int is_header = 0;
diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
index 0eddd4f872ca..68ed2883edb2 100644
--- a/drivers/media/usb/uvc/uvc_queue.c
+++ b/drivers/media/usb/uvc/uvc_queue.c
@@ -78,7 +78,7 @@ static int uvc_queue_setup(struct vb2_queue *vq,
unsigned int sizes[], struct device *alloc_devs[])
{
struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
- struct uvc_streaming *stream;
+ struct uvc_streaming *stream = uvc_queue_to_stream(queue, vq->type);
unsigned int size;
switch (vq->type) {
@@ -87,7 +87,6 @@ static int uvc_queue_setup(struct vb2_queue *vq,
break;
default:
- stream = uvc_queue_to_stream(queue);
size = stream->ctrl.dwMaxVideoFrameSize;
break;
}
@@ -113,7 +112,7 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb)
if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) {
- uvc_dbg(uvc_queue_to_stream(queue)->dev, CAPTURE,
+ uvc_dbg(uvc_queue_to_stream(queue, vb->type)->dev, CAPTURE,
"[E] Bytes used out of bounds\n");
return -EINVAL;
}
@@ -160,7 +159,7 @@ static void uvc_buffer_finish(struct vb2_buffer *vb)
{
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
- struct uvc_streaming *stream = uvc_queue_to_stream(queue);
+ struct uvc_streaming *stream = uvc_queue_to_stream(queue, vb->type);
struct uvc_buffer *buf = uvc_vbuf_to_buffer(vbuf);
if (vb->state == VB2_BUF_STATE_DONE)
@@ -170,7 +169,7 @@ static void uvc_buffer_finish(struct vb2_buffer *vb)
static int uvc_start_streaming_video(struct vb2_queue *vq, unsigned int count)
{
struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
- struct uvc_streaming *stream = uvc_queue_to_stream(queue);
+ struct uvc_streaming *stream = uvc_queue_to_stream(queue, vq->type);
int ret;
lockdep_assert_irqs_enabled();
@@ -197,11 +196,11 @@ static int uvc_start_streaming_video(struct vb2_queue *vq, unsigned int count)
static void uvc_stop_streaming_video(struct vb2_queue *vq)
{
struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
- struct uvc_streaming *stream = uvc_queue_to_stream(queue);
+ struct uvc_streaming *stream = uvc_queue_to_stream(queue, vq->type);
lockdep_assert_irqs_enabled();
- uvc_video_stop_streaming(uvc_queue_to_stream(queue));
+ uvc_video_stop_streaming(stream);
uvc_pm_put(stream->dev);
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 8480d65ecb85..9b4849fda12f 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -703,8 +703,10 @@ static inline int uvc_queue_streaming(struct uvc_video_queue *queue)
}
static inline struct uvc_streaming *
-uvc_queue_to_stream(struct uvc_video_queue *queue)
+uvc_queue_to_stream(struct uvc_video_queue *queue, unsigned int type)
{
+ if (type == V4L2_BUF_TYPE_META_CAPTURE)
+ return container_of(queue, struct uvc_streaming, meta.queue);
return container_of(queue, struct uvc_streaming, queue);
}
--
2.53.0.473.g4a7958ca14-goog
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 3/3] media: uvcvideo: Allow userspace to increase the meta buffersize
2026-03-09 15:01 [PATCH 0/3] media: uvcvideo: Improvements for UVC metadata Ricardo Ribalda
2026-03-09 15:01 ` [PATCH 1/3] media: uvcvideo: Enable VB2_DMABUF for metadata stream Ricardo Ribalda
2026-03-09 15:01 ` [PATCH 2/3] media: uvcvideo: uvc_queue_to_stream(): Support meta queues Ricardo Ribalda
@ 2026-03-09 15:01 ` Ricardo Ribalda
2026-03-16 11:53 ` Hans de Goede
2026-03-18 19:22 ` Laurent Pinchart
2026-03-16 12:05 ` [PATCH 0/3] media: uvcvideo: Improvements for UVC metadata Hans de Goede
3 siblings, 2 replies; 16+ messages in thread
From: Ricardo Ribalda @ 2026-03-09 15:01 UTC (permalink / raw)
To: Laurent Pinchart, Hans de Goede, Mauro Carvalho Chehab,
Guennadi Liakhovetski
Cc: linux-media, linux-kernel, Yunke Cao, Ricardo Ribalda
Now we have the metadata size hardcoded to 10 KiB, this is a value that
works fine for bulk cameras or frames with no extra metadata. But not
for all usecases.
We have seen some cameras that produce more metadata per frame. Eg:
Frame 1 captured (Bytes: 11154)
Frame 2 captured (Bytes: 11616)
Frame 3 captured (Bytes: 11374)
Frame 4 captured (Bytes: 11132)
Frame 5 captured (Bytes: 11594)
Frame 6 captured (Bytes: 11352)
Frame 7 captured (Bytes: 11110)
Frame 8 captured (Bytes: 11572)
Frame 9 captured (Bytes: 11308)
When this happens, the driver (correctly) marks the metadata as ERROR.
This patch let userspace set bigger buffersize via S_FMT.
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
---
drivers/media/usb/uvc/uvc_metadata.c | 9 +++++++--
drivers/media/usb/uvc/uvc_queue.c | 2 +-
drivers/media/usb/uvc/uvcvideo.h | 3 ++-
3 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/media/usb/uvc/uvc_metadata.c b/drivers/media/usb/uvc/uvc_metadata.c
index 0a906ae3f971..9de8aba1229e 100644
--- a/drivers/media/usb/uvc/uvc_metadata.c
+++ b/drivers/media/usb/uvc/uvc_metadata.c
@@ -50,7 +50,7 @@ static int uvc_meta_v4l2_get_format(struct file *file, void *priv,
return -EINVAL;
fmt->dataformat = stream->meta.format;
- fmt->buffersize = UVC_METADATA_BUF_SIZE;
+ fmt->buffersize = stream->meta.buffersize;
return 0;
}
@@ -63,6 +63,7 @@ static int uvc_meta_v4l2_try_format(struct file *file, void *priv,
struct uvc_device *dev = stream->dev;
struct v4l2_meta_format *fmt = &format->fmt.meta;
u32 fmeta = V4L2_META_FMT_UVC;
+ u32 buffersize;
if (format->type != vfh->vdev->queue->type)
return -EINVAL;
@@ -74,10 +75,12 @@ static int uvc_meta_v4l2_try_format(struct file *file, void *priv,
}
}
+ buffersize = max(UVC_METADATA_BUF_MIN_SIZE, fmt->buffersize);
+
memset(fmt, 0, sizeof(*fmt));
fmt->dataformat = fmeta;
- fmt->buffersize = UVC_METADATA_BUF_SIZE;
+ fmt->buffersize = buffersize;
return 0;
}
@@ -103,6 +106,7 @@ static int uvc_meta_v4l2_set_format(struct file *file, void *priv,
return -EBUSY;
stream->meta.format = fmt->dataformat;
+ stream->meta.buffersize = fmt->buffersize;
return 0;
}
@@ -229,6 +233,7 @@ int uvc_meta_register(struct uvc_streaming *stream)
struct uvc_video_queue *queue = &stream->meta.queue;
stream->meta.format = V4L2_META_FMT_UVC;
+ stream->meta.buffersize = UVC_METADATA_BUF_MIN_SIZE;
return uvc_register_video_device(dev, stream, queue,
V4L2_BUF_TYPE_META_CAPTURE,
diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
index 68ed2883edb2..89206f761006 100644
--- a/drivers/media/usb/uvc/uvc_queue.c
+++ b/drivers/media/usb/uvc/uvc_queue.c
@@ -83,7 +83,7 @@ static int uvc_queue_setup(struct vb2_queue *vq,
switch (vq->type) {
case V4L2_BUF_TYPE_META_CAPTURE:
- size = UVC_METADATA_BUF_SIZE;
+ size = stream->meta.buffersize;
break;
default:
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 9b4849fda12f..5ba698d2a23d 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -409,7 +409,7 @@ struct uvc_stats_stream {
unsigned int max_sof; /* Maximum STC.SOF value */
};
-#define UVC_METADATA_BUF_SIZE 10240
+#define UVC_METADATA_BUF_MIN_SIZE 10240
/**
* struct uvc_copy_op: Context structure to schedule asynchronous memcpy
@@ -482,6 +482,7 @@ struct uvc_streaming {
struct {
struct uvc_video_queue queue;
u32 format;
+ u32 buffersize;
} meta;
/* Context data used by the bulk completion handler. */
--
2.53.0.473.g4a7958ca14-goog
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 1/3] media: uvcvideo: Enable VB2_DMABUF for metadata stream
2026-03-09 15:01 ` [PATCH 1/3] media: uvcvideo: Enable VB2_DMABUF for metadata stream Ricardo Ribalda
@ 2026-03-16 11:47 ` Hans de Goede
2026-03-18 19:15 ` Laurent Pinchart
1 sibling, 0 replies; 16+ messages in thread
From: Hans de Goede @ 2026-03-16 11:47 UTC (permalink / raw)
To: Ricardo Ribalda, Laurent Pinchart, Mauro Carvalho Chehab,
Guennadi Liakhovetski
Cc: linux-media, linux-kernel, Yunke Cao, stable
Hi,
On 9-Mar-26 4:01 PM, Ricardo Ribalda wrote:
> The UVC driver has two video streams, one for the frames and another one
> for the metadata. Both streams share most of the codebase, but only the
> data stream declares support for DMABUF transfer mode.
>
> I have tried the DMABUF transfer mode with CONFIG_DMABUF_HEAPS_SYSTEM
> and the frames looked correct.
>
> This patch announces the support for DMABUF for the metadata stream.
> This is useful for apps/HALs that only want to support DMABUF.
>
> Cc: stable@vger.kernel.org
> Fixes: 088ead2552458 ("media: uvcvideo: Add a metadata device node")
> Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
Thanks, patch looks good to me:
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Regards,
Hans
> ---
> drivers/media/usb/uvc/uvc_queue.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
> index 8b8f44b4a045..0eddd4f872ca 100644
> --- a/drivers/media/usb/uvc/uvc_queue.c
> +++ b/drivers/media/usb/uvc/uvc_queue.c
> @@ -243,7 +243,7 @@ int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
> int ret;
>
> queue->queue.type = type;
> - queue->queue.io_modes = VB2_MMAP | VB2_USERPTR;
> + queue->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
> queue->queue.drv_priv = queue;
> queue->queue.buf_struct_size = sizeof(struct uvc_buffer);
> queue->queue.mem_ops = &vb2_vmalloc_memops;
> @@ -256,7 +256,6 @@ int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
> queue->queue.ops = &uvc_meta_queue_qops;
> break;
> default:
> - queue->queue.io_modes |= VB2_DMABUF;
> queue->queue.ops = &uvc_queue_qops;
> break;
> }
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 2/3] media: uvcvideo: uvc_queue_to_stream(): Support meta queues
2026-03-09 15:01 ` [PATCH 2/3] media: uvcvideo: uvc_queue_to_stream(): Support meta queues Ricardo Ribalda
@ 2026-03-16 11:49 ` Hans de Goede
2026-03-18 19:18 ` Laurent Pinchart
1 sibling, 0 replies; 16+ messages in thread
From: Hans de Goede @ 2026-03-16 11:49 UTC (permalink / raw)
To: Ricardo Ribalda, Laurent Pinchart, Mauro Carvalho Chehab,
Guennadi Liakhovetski
Cc: linux-media, linux-kernel, Yunke Cao
Hi,
On 9-Mar-26 4:01 PM, Ricardo Ribalda wrote:
> The stream data structure has two queues: the metadata and the data
> queues, but uvc_queue_to_stream() only supports the data queue. If we
> pass the metadata queue the function will return an invalid pointer.
>
> This patch add a parameter to the function to explicitly tell the
> function which queue are we using.
>
> Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
Thanks, patch looks good to me:
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Regards,
Hans
> ---
> drivers/media/usb/uvc/uvc_isight.c | 3 ++-
> drivers/media/usb/uvc/uvc_queue.c | 13 ++++++-------
> drivers/media/usb/uvc/uvcvideo.h | 4 +++-
> 3 files changed, 11 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/media/usb/uvc/uvc_isight.c b/drivers/media/usb/uvc/uvc_isight.c
> index 43cda5e760a3..ea9dc31dfbad 100644
> --- a/drivers/media/usb/uvc/uvc_isight.c
> +++ b/drivers/media/usb/uvc/uvc_isight.c
> @@ -41,7 +41,8 @@ static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf,
> 0xde, 0xad, 0xfa, 0xce
> };
>
> - struct uvc_streaming *stream = uvc_queue_to_stream(queue);
> + struct uvc_streaming *stream = uvc_queue_to_stream(queue,
> + V4L2_BUF_TYPE_VIDEO_CAPTURE);
> unsigned int maxlen, nbytes;
> u8 *mem;
> int is_header = 0;
> diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
> index 0eddd4f872ca..68ed2883edb2 100644
> --- a/drivers/media/usb/uvc/uvc_queue.c
> +++ b/drivers/media/usb/uvc/uvc_queue.c
> @@ -78,7 +78,7 @@ static int uvc_queue_setup(struct vb2_queue *vq,
> unsigned int sizes[], struct device *alloc_devs[])
> {
> struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
> - struct uvc_streaming *stream;
> + struct uvc_streaming *stream = uvc_queue_to_stream(queue, vq->type);
> unsigned int size;
>
> switch (vq->type) {
> @@ -87,7 +87,6 @@ static int uvc_queue_setup(struct vb2_queue *vq,
> break;
>
> default:
> - stream = uvc_queue_to_stream(queue);
> size = stream->ctrl.dwMaxVideoFrameSize;
> break;
> }
> @@ -113,7 +112,7 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb)
>
> if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
> vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) {
> - uvc_dbg(uvc_queue_to_stream(queue)->dev, CAPTURE,
> + uvc_dbg(uvc_queue_to_stream(queue, vb->type)->dev, CAPTURE,
> "[E] Bytes used out of bounds\n");
> return -EINVAL;
> }
> @@ -160,7 +159,7 @@ static void uvc_buffer_finish(struct vb2_buffer *vb)
> {
> struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
> struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
> - struct uvc_streaming *stream = uvc_queue_to_stream(queue);
> + struct uvc_streaming *stream = uvc_queue_to_stream(queue, vb->type);
> struct uvc_buffer *buf = uvc_vbuf_to_buffer(vbuf);
>
> if (vb->state == VB2_BUF_STATE_DONE)
> @@ -170,7 +169,7 @@ static void uvc_buffer_finish(struct vb2_buffer *vb)
> static int uvc_start_streaming_video(struct vb2_queue *vq, unsigned int count)
> {
> struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
> - struct uvc_streaming *stream = uvc_queue_to_stream(queue);
> + struct uvc_streaming *stream = uvc_queue_to_stream(queue, vq->type);
> int ret;
>
> lockdep_assert_irqs_enabled();
> @@ -197,11 +196,11 @@ static int uvc_start_streaming_video(struct vb2_queue *vq, unsigned int count)
> static void uvc_stop_streaming_video(struct vb2_queue *vq)
> {
> struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
> - struct uvc_streaming *stream = uvc_queue_to_stream(queue);
> + struct uvc_streaming *stream = uvc_queue_to_stream(queue, vq->type);
>
> lockdep_assert_irqs_enabled();
>
> - uvc_video_stop_streaming(uvc_queue_to_stream(queue));
> + uvc_video_stop_streaming(stream);
>
> uvc_pm_put(stream->dev);
>
> diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> index 8480d65ecb85..9b4849fda12f 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -703,8 +703,10 @@ static inline int uvc_queue_streaming(struct uvc_video_queue *queue)
> }
>
> static inline struct uvc_streaming *
> -uvc_queue_to_stream(struct uvc_video_queue *queue)
> +uvc_queue_to_stream(struct uvc_video_queue *queue, unsigned int type)
> {
> + if (type == V4L2_BUF_TYPE_META_CAPTURE)
> + return container_of(queue, struct uvc_streaming, meta.queue);
> return container_of(queue, struct uvc_streaming, queue);
> }
>
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 3/3] media: uvcvideo: Allow userspace to increase the meta buffersize
2026-03-09 15:01 ` [PATCH 3/3] media: uvcvideo: Allow userspace to increase the meta buffersize Ricardo Ribalda
@ 2026-03-16 11:53 ` Hans de Goede
2026-03-18 19:22 ` Laurent Pinchart
1 sibling, 0 replies; 16+ messages in thread
From: Hans de Goede @ 2026-03-16 11:53 UTC (permalink / raw)
To: Ricardo Ribalda, Laurent Pinchart, Mauro Carvalho Chehab,
Guennadi Liakhovetski
Cc: linux-media, linux-kernel, Yunke Cao
Hi,
On 9-Mar-26 4:01 PM, Ricardo Ribalda wrote:
> Now we have the metadata size hardcoded to 10 KiB, this is a value that
> works fine for bulk cameras or frames with no extra metadata. But not
> for all usecases.
>
> We have seen some cameras that produce more metadata per frame. Eg:
> Frame 1 captured (Bytes: 11154)
> Frame 2 captured (Bytes: 11616)
> Frame 3 captured (Bytes: 11374)
> Frame 4 captured (Bytes: 11132)
> Frame 5 captured (Bytes: 11594)
> Frame 6 captured (Bytes: 11352)
> Frame 7 captured (Bytes: 11110)
> Frame 8 captured (Bytes: 11572)
> Frame 9 captured (Bytes: 11308)
>
> When this happens, the driver (correctly) marks the metadata as ERROR.
>
> This patch let userspace set bigger buffersize via S_FMT.
>
> Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
Thanks, patch looks good to me:
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Regards,
Hans
> ---
> drivers/media/usb/uvc/uvc_metadata.c | 9 +++++++--
> drivers/media/usb/uvc/uvc_queue.c | 2 +-
> drivers/media/usb/uvc/uvcvideo.h | 3 ++-
> 3 files changed, 10 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/media/usb/uvc/uvc_metadata.c b/drivers/media/usb/uvc/uvc_metadata.c
> index 0a906ae3f971..9de8aba1229e 100644
> --- a/drivers/media/usb/uvc/uvc_metadata.c
> +++ b/drivers/media/usb/uvc/uvc_metadata.c
> @@ -50,7 +50,7 @@ static int uvc_meta_v4l2_get_format(struct file *file, void *priv,
> return -EINVAL;
>
> fmt->dataformat = stream->meta.format;
> - fmt->buffersize = UVC_METADATA_BUF_SIZE;
> + fmt->buffersize = stream->meta.buffersize;
>
> return 0;
> }
> @@ -63,6 +63,7 @@ static int uvc_meta_v4l2_try_format(struct file *file, void *priv,
> struct uvc_device *dev = stream->dev;
> struct v4l2_meta_format *fmt = &format->fmt.meta;
> u32 fmeta = V4L2_META_FMT_UVC;
> + u32 buffersize;
>
> if (format->type != vfh->vdev->queue->type)
> return -EINVAL;
> @@ -74,10 +75,12 @@ static int uvc_meta_v4l2_try_format(struct file *file, void *priv,
> }
> }
>
> + buffersize = max(UVC_METADATA_BUF_MIN_SIZE, fmt->buffersize);
> +
> memset(fmt, 0, sizeof(*fmt));
>
> fmt->dataformat = fmeta;
> - fmt->buffersize = UVC_METADATA_BUF_SIZE;
> + fmt->buffersize = buffersize;
>
> return 0;
> }
> @@ -103,6 +106,7 @@ static int uvc_meta_v4l2_set_format(struct file *file, void *priv,
> return -EBUSY;
>
> stream->meta.format = fmt->dataformat;
> + stream->meta.buffersize = fmt->buffersize;
>
> return 0;
> }
> @@ -229,6 +233,7 @@ int uvc_meta_register(struct uvc_streaming *stream)
> struct uvc_video_queue *queue = &stream->meta.queue;
>
> stream->meta.format = V4L2_META_FMT_UVC;
> + stream->meta.buffersize = UVC_METADATA_BUF_MIN_SIZE;
>
> return uvc_register_video_device(dev, stream, queue,
> V4L2_BUF_TYPE_META_CAPTURE,
> diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
> index 68ed2883edb2..89206f761006 100644
> --- a/drivers/media/usb/uvc/uvc_queue.c
> +++ b/drivers/media/usb/uvc/uvc_queue.c
> @@ -83,7 +83,7 @@ static int uvc_queue_setup(struct vb2_queue *vq,
>
> switch (vq->type) {
> case V4L2_BUF_TYPE_META_CAPTURE:
> - size = UVC_METADATA_BUF_SIZE;
> + size = stream->meta.buffersize;
> break;
>
> default:
> diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> index 9b4849fda12f..5ba698d2a23d 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -409,7 +409,7 @@ struct uvc_stats_stream {
> unsigned int max_sof; /* Maximum STC.SOF value */
> };
>
> -#define UVC_METADATA_BUF_SIZE 10240
> +#define UVC_METADATA_BUF_MIN_SIZE 10240
>
> /**
> * struct uvc_copy_op: Context structure to schedule asynchronous memcpy
> @@ -482,6 +482,7 @@ struct uvc_streaming {
> struct {
> struct uvc_video_queue queue;
> u32 format;
> + u32 buffersize;
> } meta;
>
> /* Context data used by the bulk completion handler. */
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/3] media: uvcvideo: Improvements for UVC metadata
2026-03-09 15:01 [PATCH 0/3] media: uvcvideo: Improvements for UVC metadata Ricardo Ribalda
` (2 preceding siblings ...)
2026-03-09 15:01 ` [PATCH 3/3] media: uvcvideo: Allow userspace to increase the meta buffersize Ricardo Ribalda
@ 2026-03-16 12:05 ` Hans de Goede
2026-03-18 19:23 ` Laurent Pinchart
3 siblings, 1 reply; 16+ messages in thread
From: Hans de Goede @ 2026-03-16 12:05 UTC (permalink / raw)
To: Ricardo Ribalda, Laurent Pinchart, Mauro Carvalho Chehab,
Guennadi Liakhovetski
Cc: linux-media, linux-kernel, Yunke Cao, stable
Hi,
On 9-Mar-26 4:01 PM, Ricardo Ribalda wrote:
> This series introduces some improvements for UVC metadata:
>
> - Allow bigger sizes of metadata.
> - Refactor the code to avoid invalid pointer arithmetic.
> - Add support for DMABUF
>
> Cheers!
>
> Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
Thank you.
This entire series seems simple/safe enough and looks good to me
from a review pov, so I've pushed this to uvc/for-next now.
While it also rebasing uvc/for-next on top of the latest
media-committers/next .
Regards,
Hans
> ---
> Ricardo Ribalda (3):
> media: uvcvideo: Enable VB2_DMABUF for metadata stream
> media: uvcvideo: uvc_queue_to_stream(): Support meta queues
> media: uvcvideo: Allow userspace to increase the meta buffersize
>
> drivers/media/usb/uvc/uvc_isight.c | 3 ++-
> drivers/media/usb/uvc/uvc_metadata.c | 9 +++++++--
> drivers/media/usb/uvc/uvc_queue.c | 18 ++++++++----------
> drivers/media/usb/uvc/uvcvideo.h | 7 +++++--
> 4 files changed, 22 insertions(+), 15 deletions(-)
> ---
> base-commit: a7da7fb57f2a787412da1a62292a17fa00fbfbdf
> change-id: 20260309-uvc-metadata-dmabuf-b98359eec8dd
>
> Best regards,
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 1/3] media: uvcvideo: Enable VB2_DMABUF for metadata stream
2026-03-09 15:01 ` [PATCH 1/3] media: uvcvideo: Enable VB2_DMABUF for metadata stream Ricardo Ribalda
2026-03-16 11:47 ` Hans de Goede
@ 2026-03-18 19:15 ` Laurent Pinchart
1 sibling, 0 replies; 16+ messages in thread
From: Laurent Pinchart @ 2026-03-18 19:15 UTC (permalink / raw)
To: Ricardo Ribalda
Cc: Hans de Goede, Mauro Carvalho Chehab, Guennadi Liakhovetski,
linux-media, linux-kernel, Yunke Cao, stable
On Mon, Mar 09, 2026 at 03:01:54PM +0000, Ricardo Ribalda wrote:
> The UVC driver has two video streams, one for the frames and another one
> for the metadata. Both streams share most of the codebase, but only the
> data stream declares support for DMABUF transfer mode.
>
> I have tried the DMABUF transfer mode with CONFIG_DMABUF_HEAPS_SYSTEM
> and the frames looked correct.
>
> This patch announces the support for DMABUF for the metadata stream.
> This is useful for apps/HALs that only want to support DMABUF.
Is that something you plan to use in Android ?
> Cc: stable@vger.kernel.org
> Fixes: 088ead2552458 ("media: uvcvideo: Add a metadata device node")
> Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
> ---
> drivers/media/usb/uvc/uvc_queue.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
> index 8b8f44b4a045..0eddd4f872ca 100644
> --- a/drivers/media/usb/uvc/uvc_queue.c
> +++ b/drivers/media/usb/uvc/uvc_queue.c
> @@ -243,7 +243,7 @@ int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
> int ret;
>
> queue->queue.type = type;
> - queue->queue.io_modes = VB2_MMAP | VB2_USERPTR;
> + queue->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
One day we should start warning about USERPTR being deprecated.
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> queue->queue.drv_priv = queue;
> queue->queue.buf_struct_size = sizeof(struct uvc_buffer);
> queue->queue.mem_ops = &vb2_vmalloc_memops;
> @@ -256,7 +256,6 @@ int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
> queue->queue.ops = &uvc_meta_queue_qops;
> break;
> default:
> - queue->queue.io_modes |= VB2_DMABUF;
> queue->queue.ops = &uvc_queue_qops;
> break;
> }
>
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 2/3] media: uvcvideo: uvc_queue_to_stream(): Support meta queues
2026-03-09 15:01 ` [PATCH 2/3] media: uvcvideo: uvc_queue_to_stream(): Support meta queues Ricardo Ribalda
2026-03-16 11:49 ` Hans de Goede
@ 2026-03-18 19:18 ` Laurent Pinchart
1 sibling, 0 replies; 16+ messages in thread
From: Laurent Pinchart @ 2026-03-18 19:18 UTC (permalink / raw)
To: Ricardo Ribalda
Cc: Hans de Goede, Mauro Carvalho Chehab, Guennadi Liakhovetski,
linux-media, linux-kernel, Yunke Cao
Hi Ricardo,
Thank you for the patch.
On Mon, Mar 09, 2026 at 03:01:55PM +0000, Ricardo Ribalda wrote:
> The stream data structure has two queues: the metadata and the data
> queues, but uvc_queue_to_stream() only supports the data queue. If we
> pass the metadata queue the function will return an invalid pointer.
>
> This patch add a parameter to the function to explicitly tell the
> function which queue are we using.
>
> Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
> ---
> drivers/media/usb/uvc/uvc_isight.c | 3 ++-
> drivers/media/usb/uvc/uvc_queue.c | 13 ++++++-------
> drivers/media/usb/uvc/uvcvideo.h | 4 +++-
> 3 files changed, 11 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/media/usb/uvc/uvc_isight.c b/drivers/media/usb/uvc/uvc_isight.c
> index 43cda5e760a3..ea9dc31dfbad 100644
> --- a/drivers/media/usb/uvc/uvc_isight.c
> +++ b/drivers/media/usb/uvc/uvc_isight.c
> @@ -41,7 +41,8 @@ static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf,
> 0xde, 0xad, 0xfa, 0xce
> };
>
> - struct uvc_streaming *stream = uvc_queue_to_stream(queue);
> + struct uvc_streaming *stream = uvc_queue_to_stream(queue,
> + V4L2_BUF_TYPE_VIDEO_CAPTURE);
> unsigned int maxlen, nbytes;
> u8 *mem;
> int is_header = 0;
> diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
> index 0eddd4f872ca..68ed2883edb2 100644
> --- a/drivers/media/usb/uvc/uvc_queue.c
> +++ b/drivers/media/usb/uvc/uvc_queue.c
> @@ -78,7 +78,7 @@ static int uvc_queue_setup(struct vb2_queue *vq,
> unsigned int sizes[], struct device *alloc_devs[])
> {
> struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
> - struct uvc_streaming *stream;
> + struct uvc_streaming *stream = uvc_queue_to_stream(queue, vq->type);
> unsigned int size;
>
> switch (vq->type) {
> @@ -87,7 +87,6 @@ static int uvc_queue_setup(struct vb2_queue *vq,
> break;
>
> default:
> - stream = uvc_queue_to_stream(queue);
> size = stream->ctrl.dwMaxVideoFrameSize;
> break;
> }
> @@ -113,7 +112,7 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb)
>
> if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
> vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) {
> - uvc_dbg(uvc_queue_to_stream(queue)->dev, CAPTURE,
> + uvc_dbg(uvc_queue_to_stream(queue, vb->type)->dev, CAPTURE,
> "[E] Bytes used out of bounds\n");
> return -EINVAL;
> }
> @@ -160,7 +159,7 @@ static void uvc_buffer_finish(struct vb2_buffer *vb)
> {
> struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
> struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
> - struct uvc_streaming *stream = uvc_queue_to_stream(queue);
> + struct uvc_streaming *stream = uvc_queue_to_stream(queue, vb->type);
> struct uvc_buffer *buf = uvc_vbuf_to_buffer(vbuf);
>
> if (vb->state == VB2_BUF_STATE_DONE)
> @@ -170,7 +169,7 @@ static void uvc_buffer_finish(struct vb2_buffer *vb)
> static int uvc_start_streaming_video(struct vb2_queue *vq, unsigned int count)
> {
> struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
> - struct uvc_streaming *stream = uvc_queue_to_stream(queue);
> + struct uvc_streaming *stream = uvc_queue_to_stream(queue, vq->type);
> int ret;
>
> lockdep_assert_irqs_enabled();
> @@ -197,11 +196,11 @@ static int uvc_start_streaming_video(struct vb2_queue *vq, unsigned int count)
> static void uvc_stop_streaming_video(struct vb2_queue *vq)
> {
> struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
> - struct uvc_streaming *stream = uvc_queue_to_stream(queue);
> + struct uvc_streaming *stream = uvc_queue_to_stream(queue, vq->type);
>
> lockdep_assert_irqs_enabled();
>
> - uvc_video_stop_streaming(uvc_queue_to_stream(queue));
> + uvc_video_stop_streaming(stream);
>
> uvc_pm_put(stream->dev);
>
> diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> index 8480d65ecb85..9b4849fda12f 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -703,8 +703,10 @@ static inline int uvc_queue_streaming(struct uvc_video_queue *queue)
> }
>
> static inline struct uvc_streaming *
> -uvc_queue_to_stream(struct uvc_video_queue *queue)
> +uvc_queue_to_stream(struct uvc_video_queue *queue, unsigned int type)
> {
> + if (type == V4L2_BUF_TYPE_META_CAPTURE)
> + return container_of(queue, struct uvc_streaming, meta.queue);
> return container_of(queue, struct uvc_streaming, queue);
This was implemented with container_of() as there has never been a need
to get the uvc_streaming for the metadata queue. As that's changing in
patch 3/3, I'd rather use a backpointer from uvc_video_queue to
uvc_streaming. That will be simpler for the callers, and less
error-prone.
> }
>
>
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 3/3] media: uvcvideo: Allow userspace to increase the meta buffersize
2026-03-09 15:01 ` [PATCH 3/3] media: uvcvideo: Allow userspace to increase the meta buffersize Ricardo Ribalda
2026-03-16 11:53 ` Hans de Goede
@ 2026-03-18 19:22 ` Laurent Pinchart
2026-03-18 19:29 ` Ricardo Ribalda
1 sibling, 1 reply; 16+ messages in thread
From: Laurent Pinchart @ 2026-03-18 19:22 UTC (permalink / raw)
To: Ricardo Ribalda
Cc: Hans de Goede, Mauro Carvalho Chehab, Guennadi Liakhovetski,
linux-media, linux-kernel, Yunke Cao
On Mon, Mar 09, 2026 at 03:01:56PM +0000, Ricardo Ribalda wrote:
> Now we have the metadata size hardcoded to 10 KiB, this is a value that
> works fine for bulk cameras or frames with no extra metadata. But not
> for all usecases.
>
> We have seen some cameras that produce more metadata per frame. Eg:
Can you tell what camera that is ?
> Frame 1 captured (Bytes: 11154)
> Frame 2 captured (Bytes: 11616)
> Frame 3 captured (Bytes: 11374)
> Frame 4 captured (Bytes: 11132)
> Frame 5 captured (Bytes: 11594)
> Frame 6 captured (Bytes: 11352)
> Frame 7 captured (Bytes: 11110)
> Frame 8 captured (Bytes: 11572)
> Frame 9 captured (Bytes: 11308)
>
> When this happens, the driver (correctly) marks the metadata as ERROR.
Is the maximum metadata size queryable through an XU on your devices ?
> This patch let userspace set bigger buffersize via S_FMT.
>
> Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
> ---
> drivers/media/usb/uvc/uvc_metadata.c | 9 +++++++--
> drivers/media/usb/uvc/uvc_queue.c | 2 +-
> drivers/media/usb/uvc/uvcvideo.h | 3 ++-
> 3 files changed, 10 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/media/usb/uvc/uvc_metadata.c b/drivers/media/usb/uvc/uvc_metadata.c
> index 0a906ae3f971..9de8aba1229e 100644
> --- a/drivers/media/usb/uvc/uvc_metadata.c
> +++ b/drivers/media/usb/uvc/uvc_metadata.c
> @@ -50,7 +50,7 @@ static int uvc_meta_v4l2_get_format(struct file *file, void *priv,
> return -EINVAL;
>
> fmt->dataformat = stream->meta.format;
> - fmt->buffersize = UVC_METADATA_BUF_SIZE;
> + fmt->buffersize = stream->meta.buffersize;
>
> return 0;
> }
> @@ -63,6 +63,7 @@ static int uvc_meta_v4l2_try_format(struct file *file, void *priv,
> struct uvc_device *dev = stream->dev;
> struct v4l2_meta_format *fmt = &format->fmt.meta;
> u32 fmeta = V4L2_META_FMT_UVC;
> + u32 buffersize;
>
> if (format->type != vfh->vdev->queue->type)
> return -EINVAL;
> @@ -74,10 +75,12 @@ static int uvc_meta_v4l2_try_format(struct file *file, void *priv,
> }
> }
>
> + buffersize = max(UVC_METADATA_BUF_MIN_SIZE, fmt->buffersize);
> +
> memset(fmt, 0, sizeof(*fmt));
>
> fmt->dataformat = fmeta;
> - fmt->buffersize = UVC_METADATA_BUF_SIZE;
> + fmt->buffersize = buffersize;
>
> return 0;
> }
> @@ -103,6 +106,7 @@ static int uvc_meta_v4l2_set_format(struct file *file, void *priv,
> return -EBUSY;
>
> stream->meta.format = fmt->dataformat;
> + stream->meta.buffersize = fmt->buffersize;
>
> return 0;
> }
> @@ -229,6 +233,7 @@ int uvc_meta_register(struct uvc_streaming *stream)
> struct uvc_video_queue *queue = &stream->meta.queue;
>
> stream->meta.format = V4L2_META_FMT_UVC;
> + stream->meta.buffersize = UVC_METADATA_BUF_MIN_SIZE;
>
> return uvc_register_video_device(dev, stream, queue,
> V4L2_BUF_TYPE_META_CAPTURE,
> diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
> index 68ed2883edb2..89206f761006 100644
> --- a/drivers/media/usb/uvc/uvc_queue.c
> +++ b/drivers/media/usb/uvc/uvc_queue.c
> @@ -83,7 +83,7 @@ static int uvc_queue_setup(struct vb2_queue *vq,
>
> switch (vq->type) {
> case V4L2_BUF_TYPE_META_CAPTURE:
> - size = UVC_METADATA_BUF_SIZE;
> + size = stream->meta.buffersize;
> break;
>
> default:
> diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> index 9b4849fda12f..5ba698d2a23d 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -409,7 +409,7 @@ struct uvc_stats_stream {
> unsigned int max_sof; /* Maximum STC.SOF value */
> };
>
> -#define UVC_METADATA_BUF_SIZE 10240
> +#define UVC_METADATA_BUF_MIN_SIZE 10240
I wondered if we should have a max limit to avoid letting userspace
starve system memory, but that can already be done through allocation of
arbitrarily large image buffers anyway. We need proper memory accounting
in V4L2.
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>
> /**
> * struct uvc_copy_op: Context structure to schedule asynchronous memcpy
> @@ -482,6 +482,7 @@ struct uvc_streaming {
> struct {
> struct uvc_video_queue queue;
> u32 format;
> + u32 buffersize;
> } meta;
>
> /* Context data used by the bulk completion handler. */
>
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/3] media: uvcvideo: Improvements for UVC metadata
2026-03-16 12:05 ` [PATCH 0/3] media: uvcvideo: Improvements for UVC metadata Hans de Goede
@ 2026-03-18 19:23 ` Laurent Pinchart
2026-03-18 20:22 ` [PATCH] media: uvcvideo: Add a stream backpointer in uvc_video_queue Ricardo Ribalda
0 siblings, 1 reply; 16+ messages in thread
From: Laurent Pinchart @ 2026-03-18 19:23 UTC (permalink / raw)
To: Hans de Goede
Cc: Ricardo Ribalda, Mauro Carvalho Chehab, Guennadi Liakhovetski,
linux-media, linux-kernel, Yunke Cao, stable
On Mon, Mar 16, 2026 at 01:05:30PM +0100, Hans de Goede wrote:
> On 9-Mar-26 4:01 PM, Ricardo Ribalda wrote:
> > This series introduces some improvements for UVC metadata:
> >
> > - Allow bigger sizes of metadata.
> > - Refactor the code to avoid invalid pointer arithmetic.
> > - Add support for DMABUF
> >
> > Cheers!
> >
> > Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
>
> Thank you.
>
> This entire series seems simple/safe enough and looks good to me
> from a review pov, so I've pushed this to uvc/for-next now.
I'd like a small change in 2/3. Ricardo, if you submit a new version of
2/3, I can merge it and handle the rebase.
> While it also rebasing uvc/for-next on top of the latest
> media-committers/next .
>
> > ---
> > Ricardo Ribalda (3):
> > media: uvcvideo: Enable VB2_DMABUF for metadata stream
> > media: uvcvideo: uvc_queue_to_stream(): Support meta queues
> > media: uvcvideo: Allow userspace to increase the meta buffersize
> >
> > drivers/media/usb/uvc/uvc_isight.c | 3 ++-
> > drivers/media/usb/uvc/uvc_metadata.c | 9 +++++++--
> > drivers/media/usb/uvc/uvc_queue.c | 18 ++++++++----------
> > drivers/media/usb/uvc/uvcvideo.h | 7 +++++--
> > 4 files changed, 22 insertions(+), 15 deletions(-)
> > ---
> > base-commit: a7da7fb57f2a787412da1a62292a17fa00fbfbdf
> > change-id: 20260309-uvc-metadata-dmabuf-b98359eec8dd
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 3/3] media: uvcvideo: Allow userspace to increase the meta buffersize
2026-03-18 19:22 ` Laurent Pinchart
@ 2026-03-18 19:29 ` Ricardo Ribalda
2026-03-18 19:36 ` Laurent Pinchart
0 siblings, 1 reply; 16+ messages in thread
From: Ricardo Ribalda @ 2026-03-18 19:29 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Hans de Goede, Mauro Carvalho Chehab, Guennadi Liakhovetski,
linux-media, linux-kernel, Yunke Cao
Hi Laurent
On Wed, 18 Mar 2026 at 20:22, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> On Mon, Mar 09, 2026 at 03:01:56PM +0000, Ricardo Ribalda wrote:
> > Now we have the metadata size hardcoded to 10 KiB, this is a value that
> > works fine for bulk cameras or frames with no extra metadata. But not
> > for all usecases.
> >
> > We have seen some cameras that produce more metadata per frame. Eg:
>
> Can you tell what camera that is ?
It is a pretty standard Sunplus camera. It should be producing frames
at 30fps, but it had AutoFramerate based on exposure enabled and the
real fps was 15.
As a result of that there was twice of empty packages.
If you are really curious I can try to dig the lsusb.
>
> > Frame 1 captured (Bytes: 11154)
> > Frame 2 captured (Bytes: 11616)
> > Frame 3 captured (Bytes: 11374)
> > Frame 4 captured (Bytes: 11132)
> > Frame 5 captured (Bytes: 11594)
> > Frame 6 captured (Bytes: 11352)
> > Frame 7 captured (Bytes: 11110)
> > Frame 8 captured (Bytes: 11572)
> > Frame 9 captured (Bytes: 11308)
> >
> > When this happens, the driver (correctly) marks the metadata as ERROR.
>
> Is the maximum metadata size queryable through an XU on your devices ?
There is no metadata in this device, just timing information.
In MSXU there is a contol to set the size of the metadata. It is in
kilobytes :S and pretty much every device I've seen implements it
incorrectly.
>
> > This patch let userspace set bigger buffersize via S_FMT.
> >
> > Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
> > ---
> > drivers/media/usb/uvc/uvc_metadata.c | 9 +++++++--
> > drivers/media/usb/uvc/uvc_queue.c | 2 +-
> > drivers/media/usb/uvc/uvcvideo.h | 3 ++-
> > 3 files changed, 10 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/media/usb/uvc/uvc_metadata.c b/drivers/media/usb/uvc/uvc_metadata.c
> > index 0a906ae3f971..9de8aba1229e 100644
> > --- a/drivers/media/usb/uvc/uvc_metadata.c
> > +++ b/drivers/media/usb/uvc/uvc_metadata.c
> > @@ -50,7 +50,7 @@ static int uvc_meta_v4l2_get_format(struct file *file, void *priv,
> > return -EINVAL;
> >
> > fmt->dataformat = stream->meta.format;
> > - fmt->buffersize = UVC_METADATA_BUF_SIZE;
> > + fmt->buffersize = stream->meta.buffersize;
> >
> > return 0;
> > }
> > @@ -63,6 +63,7 @@ static int uvc_meta_v4l2_try_format(struct file *file, void *priv,
> > struct uvc_device *dev = stream->dev;
> > struct v4l2_meta_format *fmt = &format->fmt.meta;
> > u32 fmeta = V4L2_META_FMT_UVC;
> > + u32 buffersize;
> >
> > if (format->type != vfh->vdev->queue->type)
> > return -EINVAL;
> > @@ -74,10 +75,12 @@ static int uvc_meta_v4l2_try_format(struct file *file, void *priv,
> > }
> > }
> >
> > + buffersize = max(UVC_METADATA_BUF_MIN_SIZE, fmt->buffersize);
> > +
> > memset(fmt, 0, sizeof(*fmt));
> >
> > fmt->dataformat = fmeta;
> > - fmt->buffersize = UVC_METADATA_BUF_SIZE;
> > + fmt->buffersize = buffersize;
> >
> > return 0;
> > }
> > @@ -103,6 +106,7 @@ static int uvc_meta_v4l2_set_format(struct file *file, void *priv,
> > return -EBUSY;
> >
> > stream->meta.format = fmt->dataformat;
> > + stream->meta.buffersize = fmt->buffersize;
> >
> > return 0;
> > }
> > @@ -229,6 +233,7 @@ int uvc_meta_register(struct uvc_streaming *stream)
> > struct uvc_video_queue *queue = &stream->meta.queue;
> >
> > stream->meta.format = V4L2_META_FMT_UVC;
> > + stream->meta.buffersize = UVC_METADATA_BUF_MIN_SIZE;
> >
> > return uvc_register_video_device(dev, stream, queue,
> > V4L2_BUF_TYPE_META_CAPTURE,
> > diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
> > index 68ed2883edb2..89206f761006 100644
> > --- a/drivers/media/usb/uvc/uvc_queue.c
> > +++ b/drivers/media/usb/uvc/uvc_queue.c
> > @@ -83,7 +83,7 @@ static int uvc_queue_setup(struct vb2_queue *vq,
> >
> > switch (vq->type) {
> > case V4L2_BUF_TYPE_META_CAPTURE:
> > - size = UVC_METADATA_BUF_SIZE;
> > + size = stream->meta.buffersize;
> > break;
> >
> > default:
> > diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> > index 9b4849fda12f..5ba698d2a23d 100644
> > --- a/drivers/media/usb/uvc/uvcvideo.h
> > +++ b/drivers/media/usb/uvc/uvcvideo.h
> > @@ -409,7 +409,7 @@ struct uvc_stats_stream {
> > unsigned int max_sof; /* Maximum STC.SOF value */
> > };
> >
> > -#define UVC_METADATA_BUF_SIZE 10240
> > +#define UVC_METADATA_BUF_MIN_SIZE 10240
>
> I wondered if we should have a max limit to avoid letting userspace
> starve system memory, but that can already be done through allocation of
> arbitrarily large image buffers anyway. We need proper memory accounting
> in V4L2.
>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>
> >
> > /**
> > * struct uvc_copy_op: Context structure to schedule asynchronous memcpy
> > @@ -482,6 +482,7 @@ struct uvc_streaming {
> > struct {
> > struct uvc_video_queue queue;
> > u32 format;
> > + u32 buffersize;
> > } meta;
> >
> > /* Context data used by the bulk completion handler. */
> >
>
> --
> Regards,
>
> Laurent Pinchart
--
Ricardo Ribalda
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 3/3] media: uvcvideo: Allow userspace to increase the meta buffersize
2026-03-18 19:29 ` Ricardo Ribalda
@ 2026-03-18 19:36 ` Laurent Pinchart
0 siblings, 0 replies; 16+ messages in thread
From: Laurent Pinchart @ 2026-03-18 19:36 UTC (permalink / raw)
To: Ricardo Ribalda
Cc: Hans de Goede, Mauro Carvalho Chehab, Guennadi Liakhovetski,
linux-media, linux-kernel, Yunke Cao
On Wed, Mar 18, 2026 at 08:29:58PM +0100, Ricardo Ribalda wrote:
> On Wed, 18 Mar 2026 at 20:22, Laurent Pinchart wrote:
> > On Mon, Mar 09, 2026 at 03:01:56PM +0000, Ricardo Ribalda wrote:
> > > Now we have the metadata size hardcoded to 10 KiB, this is a value that
> > > works fine for bulk cameras or frames with no extra metadata. But not
> > > for all usecases.
> > >
> > > We have seen some cameras that produce more metadata per frame. Eg:
> >
> > Can you tell what camera that is ?
>
> It is a pretty standard Sunplus camera. It should be producing frames
> at 30fps, but it had AutoFramerate based on exposure enabled and the
> real fps was 15.
> As a result of that there was twice of empty packages.
>
> If you are really curious I can try to dig the lsusb.
No, it's OK. I was wondering if it was anything special.
> > > Frame 1 captured (Bytes: 11154)
> > > Frame 2 captured (Bytes: 11616)
> > > Frame 3 captured (Bytes: 11374)
> > > Frame 4 captured (Bytes: 11132)
> > > Frame 5 captured (Bytes: 11594)
> > > Frame 6 captured (Bytes: 11352)
> > > Frame 7 captured (Bytes: 11110)
> > > Frame 8 captured (Bytes: 11572)
> > > Frame 9 captured (Bytes: 11308)
> > >
> > > When this happens, the driver (correctly) marks the metadata as ERROR.
> >
> > Is the maximum metadata size queryable through an XU on your devices ?
>
> There is no metadata in this device, just timing information.
>
> In MSXU there is a contol to set the size of the metadata. It is in
> kilobytes :S and pretty much every device I've seen implements it
> incorrectly.
Ah yes I remember you told me that. Lovely :-)
> > > This patch let userspace set bigger buffersize via S_FMT.
> > >
> > > Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
> > > ---
> > > drivers/media/usb/uvc/uvc_metadata.c | 9 +++++++--
> > > drivers/media/usb/uvc/uvc_queue.c | 2 +-
> > > drivers/media/usb/uvc/uvcvideo.h | 3 ++-
> > > 3 files changed, 10 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/drivers/media/usb/uvc/uvc_metadata.c b/drivers/media/usb/uvc/uvc_metadata.c
> > > index 0a906ae3f971..9de8aba1229e 100644
> > > --- a/drivers/media/usb/uvc/uvc_metadata.c
> > > +++ b/drivers/media/usb/uvc/uvc_metadata.c
> > > @@ -50,7 +50,7 @@ static int uvc_meta_v4l2_get_format(struct file *file, void *priv,
> > > return -EINVAL;
> > >
> > > fmt->dataformat = stream->meta.format;
> > > - fmt->buffersize = UVC_METADATA_BUF_SIZE;
> > > + fmt->buffersize = stream->meta.buffersize;
> > >
> > > return 0;
> > > }
> > > @@ -63,6 +63,7 @@ static int uvc_meta_v4l2_try_format(struct file *file, void *priv,
> > > struct uvc_device *dev = stream->dev;
> > > struct v4l2_meta_format *fmt = &format->fmt.meta;
> > > u32 fmeta = V4L2_META_FMT_UVC;
> > > + u32 buffersize;
> > >
> > > if (format->type != vfh->vdev->queue->type)
> > > return -EINVAL;
> > > @@ -74,10 +75,12 @@ static int uvc_meta_v4l2_try_format(struct file *file, void *priv,
> > > }
> > > }
> > >
> > > + buffersize = max(UVC_METADATA_BUF_MIN_SIZE, fmt->buffersize);
> > > +
> > > memset(fmt, 0, sizeof(*fmt));
> > >
> > > fmt->dataformat = fmeta;
> > > - fmt->buffersize = UVC_METADATA_BUF_SIZE;
> > > + fmt->buffersize = buffersize;
> > >
> > > return 0;
> > > }
> > > @@ -103,6 +106,7 @@ static int uvc_meta_v4l2_set_format(struct file *file, void *priv,
> > > return -EBUSY;
> > >
> > > stream->meta.format = fmt->dataformat;
> > > + stream->meta.buffersize = fmt->buffersize;
> > >
> > > return 0;
> > > }
> > > @@ -229,6 +233,7 @@ int uvc_meta_register(struct uvc_streaming *stream)
> > > struct uvc_video_queue *queue = &stream->meta.queue;
> > >
> > > stream->meta.format = V4L2_META_FMT_UVC;
> > > + stream->meta.buffersize = UVC_METADATA_BUF_MIN_SIZE;
> > >
> > > return uvc_register_video_device(dev, stream, queue,
> > > V4L2_BUF_TYPE_META_CAPTURE,
> > > diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
> > > index 68ed2883edb2..89206f761006 100644
> > > --- a/drivers/media/usb/uvc/uvc_queue.c
> > > +++ b/drivers/media/usb/uvc/uvc_queue.c
> > > @@ -83,7 +83,7 @@ static int uvc_queue_setup(struct vb2_queue *vq,
> > >
> > > switch (vq->type) {
> > > case V4L2_BUF_TYPE_META_CAPTURE:
> > > - size = UVC_METADATA_BUF_SIZE;
> > > + size = stream->meta.buffersize;
> > > break;
> > >
> > > default:
> > > diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> > > index 9b4849fda12f..5ba698d2a23d 100644
> > > --- a/drivers/media/usb/uvc/uvcvideo.h
> > > +++ b/drivers/media/usb/uvc/uvcvideo.h
> > > @@ -409,7 +409,7 @@ struct uvc_stats_stream {
> > > unsigned int max_sof; /* Maximum STC.SOF value */
> > > };
> > >
> > > -#define UVC_METADATA_BUF_SIZE 10240
> > > +#define UVC_METADATA_BUF_MIN_SIZE 10240
> >
> > I wondered if we should have a max limit to avoid letting userspace
> > starve system memory, but that can already be done through allocation of
> > arbitrarily large image buffers anyway. We need proper memory accounting
> > in V4L2.
> >
> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> >
> > >
> > > /**
> > > * struct uvc_copy_op: Context structure to schedule asynchronous memcpy
> > > @@ -482,6 +482,7 @@ struct uvc_streaming {
> > > struct {
> > > struct uvc_video_queue queue;
> > > u32 format;
> > > + u32 buffersize;
> > > } meta;
> > >
> > > /* Context data used by the bulk completion handler. */
> > >
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH] media: uvcvideo: Add a stream backpointer in uvc_video_queue
2026-03-18 19:23 ` Laurent Pinchart
@ 2026-03-18 20:22 ` Ricardo Ribalda
2026-03-23 22:34 ` Laurent Pinchart
0 siblings, 1 reply; 16+ messages in thread
From: Ricardo Ribalda @ 2026-03-18 20:22 UTC (permalink / raw)
To: Laurent Pinchart, Hans de Goede, linux-media, linux-kernel
Cc: Ricardo Ribalda
It is less prone to errors if we add a backpointer to stream from
struct uvc_video_queue.
Refactor the code.
Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
---
Tested in real hardware with yavta:
(console A) # yavta -c /dev/video1
(console B) # yavta -c /dev/video0
It would be great if we add it as a follow-up patch to the already
merged series.
Thanks!
drivers/media/usb/uvc/uvc_driver.c | 2 +-
drivers/media/usb/uvc/uvc_isight.c | 3 +--
drivers/media/usb/uvc/uvc_queue.c | 15 ++++++++-------
drivers/media/usb/uvc/uvcvideo.h | 12 +++---------
4 files changed, 13 insertions(+), 19 deletions(-)
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index b0ca81d924b6..017b1f4ae3ab 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -2033,7 +2033,7 @@ int uvc_register_video_device(struct uvc_device *dev,
int ret;
/* Initialize the video buffers queue. */
- ret = uvc_queue_init(queue, type);
+ ret = uvc_queue_init(stream, queue, type);
if (ret)
return ret;
diff --git a/drivers/media/usb/uvc/uvc_isight.c b/drivers/media/usb/uvc/uvc_isight.c
index ea9dc31dfbad..bb3e13c0d5a6 100644
--- a/drivers/media/usb/uvc/uvc_isight.c
+++ b/drivers/media/usb/uvc/uvc_isight.c
@@ -41,8 +41,7 @@ static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf,
0xde, 0xad, 0xfa, 0xce
};
- struct uvc_streaming *stream = uvc_queue_to_stream(queue,
- V4L2_BUF_TYPE_VIDEO_CAPTURE);
+ struct uvc_streaming *stream = queue->stream;
unsigned int maxlen, nbytes;
u8 *mem;
int is_header = 0;
diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
index 89206f761006..3c002c8f442f 100644
--- a/drivers/media/usb/uvc/uvc_queue.c
+++ b/drivers/media/usb/uvc/uvc_queue.c
@@ -78,7 +78,7 @@ static int uvc_queue_setup(struct vb2_queue *vq,
unsigned int sizes[], struct device *alloc_devs[])
{
struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
- struct uvc_streaming *stream = uvc_queue_to_stream(queue, vq->type);
+ struct uvc_streaming *stream = queue->stream;
unsigned int size;
switch (vq->type) {
@@ -112,7 +112,7 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb)
if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) {
- uvc_dbg(uvc_queue_to_stream(queue, vb->type)->dev, CAPTURE,
+ uvc_dbg(queue->stream->dev, CAPTURE,
"[E] Bytes used out of bounds\n");
return -EINVAL;
}
@@ -159,17 +159,16 @@ static void uvc_buffer_finish(struct vb2_buffer *vb)
{
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
- struct uvc_streaming *stream = uvc_queue_to_stream(queue, vb->type);
struct uvc_buffer *buf = uvc_vbuf_to_buffer(vbuf);
if (vb->state == VB2_BUF_STATE_DONE)
- uvc_video_clock_update(stream, vbuf, buf);
+ uvc_video_clock_update(queue->stream, vbuf, buf);
}
static int uvc_start_streaming_video(struct vb2_queue *vq, unsigned int count)
{
struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
- struct uvc_streaming *stream = uvc_queue_to_stream(queue, vq->type);
+ struct uvc_streaming *stream = queue->stream;
int ret;
lockdep_assert_irqs_enabled();
@@ -196,7 +195,7 @@ static int uvc_start_streaming_video(struct vb2_queue *vq, unsigned int count)
static void uvc_stop_streaming_video(struct vb2_queue *vq)
{
struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
- struct uvc_streaming *stream = uvc_queue_to_stream(queue, vq->type);
+ struct uvc_streaming *stream = queue->stream;
lockdep_assert_irqs_enabled();
@@ -237,10 +236,12 @@ static const struct vb2_ops uvc_meta_queue_qops = {
.stop_streaming = uvc_stop_streaming_meta,
};
-int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
+int uvc_queue_init(struct uvc_streaming *stream, struct uvc_video_queue *queue,
+ enum v4l2_buf_type type)
{
int ret;
+ queue->stream = stream;
queue->queue.type = type;
queue->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
queue->queue.drv_priv = queue;
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 5ba698d2a23d..0a0c01b2420f 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -331,6 +331,7 @@ struct uvc_buffer {
#define UVC_QUEUE_DISCONNECTED (1 << 0)
struct uvc_video_queue {
+ struct uvc_streaming *stream;
struct video_device vdev;
struct vb2_queue queue;
struct mutex mutex; /*
@@ -692,7 +693,8 @@ do { \
struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id);
/* Video buffers queue management. */
-int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type);
+int uvc_queue_init(struct uvc_streaming *stream, struct uvc_video_queue *queue,
+ enum v4l2_buf_type type);
void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect);
struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
struct uvc_buffer *buf);
@@ -703,14 +705,6 @@ static inline int uvc_queue_streaming(struct uvc_video_queue *queue)
return vb2_is_streaming(&queue->queue);
}
-static inline struct uvc_streaming *
-uvc_queue_to_stream(struct uvc_video_queue *queue, unsigned int type)
-{
- if (type == V4L2_BUF_TYPE_META_CAPTURE)
- return container_of(queue, struct uvc_streaming, meta.queue);
- return container_of(queue, struct uvc_streaming, queue);
-}
-
/* V4L2 interface */
extern const struct v4l2_ioctl_ops uvc_ioctl_ops;
extern const struct v4l2_file_operations uvc_fops;
--
2.53.0.983.g0bb29b3bc5-goog
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH] media: uvcvideo: Add a stream backpointer in uvc_video_queue
2026-03-18 20:22 ` [PATCH] media: uvcvideo: Add a stream backpointer in uvc_video_queue Ricardo Ribalda
@ 2026-03-23 22:34 ` Laurent Pinchart
0 siblings, 0 replies; 16+ messages in thread
From: Laurent Pinchart @ 2026-03-23 22:34 UTC (permalink / raw)
To: Ricardo Ribalda; +Cc: Hans de Goede, linux-media, linux-kernel
Hi Ricardo,
Thank you for the patch.
On Wed, Mar 18, 2026 at 08:22:36PM +0000, Ricardo Ribalda wrote:
> It is less prone to errors if we add a backpointer to stream from
> struct uvc_video_queue.
>
> Refactor the code.
>
> Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> Tested in real hardware with yavta:
> (console A) # yavta -c /dev/video1
> (console B) # yavta -c /dev/video0
> It would be great if we add it as a follow-up patch to the already
> merged series.
>
> Thanks!
>
> drivers/media/usb/uvc/uvc_driver.c | 2 +-
> drivers/media/usb/uvc/uvc_isight.c | 3 +--
> drivers/media/usb/uvc/uvc_queue.c | 15 ++++++++-------
> drivers/media/usb/uvc/uvcvideo.h | 12 +++---------
> 4 files changed, 13 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
> index b0ca81d924b6..017b1f4ae3ab 100644
> --- a/drivers/media/usb/uvc/uvc_driver.c
> +++ b/drivers/media/usb/uvc/uvc_driver.c
> @@ -2033,7 +2033,7 @@ int uvc_register_video_device(struct uvc_device *dev,
> int ret;
>
> /* Initialize the video buffers queue. */
> - ret = uvc_queue_init(queue, type);
> + ret = uvc_queue_init(stream, queue, type);
> if (ret)
> return ret;
>
> diff --git a/drivers/media/usb/uvc/uvc_isight.c b/drivers/media/usb/uvc/uvc_isight.c
> index ea9dc31dfbad..bb3e13c0d5a6 100644
> --- a/drivers/media/usb/uvc/uvc_isight.c
> +++ b/drivers/media/usb/uvc/uvc_isight.c
> @@ -41,8 +41,7 @@ static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf,
> 0xde, 0xad, 0xfa, 0xce
> };
>
> - struct uvc_streaming *stream = uvc_queue_to_stream(queue,
> - V4L2_BUF_TYPE_VIDEO_CAPTURE);
> + struct uvc_streaming *stream = queue->stream;
> unsigned int maxlen, nbytes;
> u8 *mem;
> int is_header = 0;
> diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
> index 89206f761006..3c002c8f442f 100644
> --- a/drivers/media/usb/uvc/uvc_queue.c
> +++ b/drivers/media/usb/uvc/uvc_queue.c
> @@ -78,7 +78,7 @@ static int uvc_queue_setup(struct vb2_queue *vq,
> unsigned int sizes[], struct device *alloc_devs[])
> {
> struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
> - struct uvc_streaming *stream = uvc_queue_to_stream(queue, vq->type);
> + struct uvc_streaming *stream = queue->stream;
> unsigned int size;
>
> switch (vq->type) {
> @@ -112,7 +112,7 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb)
>
> if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
> vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) {
> - uvc_dbg(uvc_queue_to_stream(queue, vb->type)->dev, CAPTURE,
> + uvc_dbg(queue->stream->dev, CAPTURE,
> "[E] Bytes used out of bounds\n");
> return -EINVAL;
> }
> @@ -159,17 +159,16 @@ static void uvc_buffer_finish(struct vb2_buffer *vb)
> {
> struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
> struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
> - struct uvc_streaming *stream = uvc_queue_to_stream(queue, vb->type);
> struct uvc_buffer *buf = uvc_vbuf_to_buffer(vbuf);
>
> if (vb->state == VB2_BUF_STATE_DONE)
> - uvc_video_clock_update(stream, vbuf, buf);
> + uvc_video_clock_update(queue->stream, vbuf, buf);
> }
>
> static int uvc_start_streaming_video(struct vb2_queue *vq, unsigned int count)
> {
> struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
> - struct uvc_streaming *stream = uvc_queue_to_stream(queue, vq->type);
> + struct uvc_streaming *stream = queue->stream;
> int ret;
>
> lockdep_assert_irqs_enabled();
> @@ -196,7 +195,7 @@ static int uvc_start_streaming_video(struct vb2_queue *vq, unsigned int count)
> static void uvc_stop_streaming_video(struct vb2_queue *vq)
> {
> struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
> - struct uvc_streaming *stream = uvc_queue_to_stream(queue, vq->type);
> + struct uvc_streaming *stream = queue->stream;
>
> lockdep_assert_irqs_enabled();
>
> @@ -237,10 +236,12 @@ static const struct vb2_ops uvc_meta_queue_qops = {
> .stop_streaming = uvc_stop_streaming_meta,
> };
>
> -int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
> +int uvc_queue_init(struct uvc_streaming *stream, struct uvc_video_queue *queue,
> + enum v4l2_buf_type type)
> {
> int ret;
>
> + queue->stream = stream;
> queue->queue.type = type;
> queue->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
> queue->queue.drv_priv = queue;
> diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> index 5ba698d2a23d..0a0c01b2420f 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -331,6 +331,7 @@ struct uvc_buffer {
> #define UVC_QUEUE_DISCONNECTED (1 << 0)
>
> struct uvc_video_queue {
> + struct uvc_streaming *stream;
> struct video_device vdev;
> struct vb2_queue queue;
> struct mutex mutex; /*
> @@ -692,7 +693,8 @@ do { \
> struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id);
>
> /* Video buffers queue management. */
> -int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type);
> +int uvc_queue_init(struct uvc_streaming *stream, struct uvc_video_queue *queue,
> + enum v4l2_buf_type type);
> void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect);
> struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
> struct uvc_buffer *buf);
> @@ -703,14 +705,6 @@ static inline int uvc_queue_streaming(struct uvc_video_queue *queue)
> return vb2_is_streaming(&queue->queue);
> }
>
> -static inline struct uvc_streaming *
> -uvc_queue_to_stream(struct uvc_video_queue *queue, unsigned int type)
> -{
> - if (type == V4L2_BUF_TYPE_META_CAPTURE)
> - return container_of(queue, struct uvc_streaming, meta.queue);
> - return container_of(queue, struct uvc_streaming, queue);
> -}
> -
> /* V4L2 interface */
> extern const struct v4l2_ioctl_ops uvc_ioctl_ops;
> extern const struct v4l2_file_operations uvc_fops;
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2026-03-23 22:34 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-09 15:01 [PATCH 0/3] media: uvcvideo: Improvements for UVC metadata Ricardo Ribalda
2026-03-09 15:01 ` [PATCH 1/3] media: uvcvideo: Enable VB2_DMABUF for metadata stream Ricardo Ribalda
2026-03-16 11:47 ` Hans de Goede
2026-03-18 19:15 ` Laurent Pinchart
2026-03-09 15:01 ` [PATCH 2/3] media: uvcvideo: uvc_queue_to_stream(): Support meta queues Ricardo Ribalda
2026-03-16 11:49 ` Hans de Goede
2026-03-18 19:18 ` Laurent Pinchart
2026-03-09 15:01 ` [PATCH 3/3] media: uvcvideo: Allow userspace to increase the meta buffersize Ricardo Ribalda
2026-03-16 11:53 ` Hans de Goede
2026-03-18 19:22 ` Laurent Pinchart
2026-03-18 19:29 ` Ricardo Ribalda
2026-03-18 19:36 ` Laurent Pinchart
2026-03-16 12:05 ` [PATCH 0/3] media: uvcvideo: Improvements for UVC metadata Hans de Goede
2026-03-18 19:23 ` Laurent Pinchart
2026-03-18 20:22 ` [PATCH] media: uvcvideo: Add a stream backpointer in uvc_video_queue Ricardo Ribalda
2026-03-23 22:34 ` Laurent Pinchart
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox