]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
media: uvcvideo: Allow userspace to increase the meta buffersize
authorRicardo Ribalda <ribalda@chromium.org>
Mon, 9 Mar 2026 15:01:56 +0000 (15:01 +0000)
committerHans Verkuil <hverkuil+cisco@kernel.org>
Wed, 25 Mar 2026 08:40:28 +0000 (09:40 +0100)
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>
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://patch.msgid.link/20260309-uvc-metadata-dmabuf-v1-3-fc8b87bd29c5@chromium.org
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
drivers/media/usb/uvc/uvc_metadata.c
drivers/media/usb/uvc/uvc_queue.c
drivers/media/usb/uvc/uvcvideo.h

index 0a906ae3f971262b03d00d32c969100f3bb18705..9de8aba1229ef07a5d29ea18e9b72239094ed53b 100644 (file)
@@ -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,
index 68ed2883edb220fe2ce3694de06fe88f381dc209..89206f761006ff475a097692c1899762e452a9fb 100644 (file)
@@ -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:
index 9b4849fda12f515659b7e16f2884217de9fd90d8..5ba698d2a23d4ae772b18d545f1df5b445b60965 100644 (file)
@@ -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. */