[2/4] v4l2: v4l2_camera_proxy: Set buffer field unconditionally
diff mbox series

Message ID 20261027212447.2551591-3-laurent.pinchart@ideasonboard.com
State New
Headers show
Series
  • v4l2: Fix v4l2-compliance errors
Related show

Commit Message

Laurent Pinchart Oct. 27, 2026, 9:24 p.m. UTC
When handling a buffer with the V4L2_BUF_FLAG_ERROR flag set, the
v4l2-compat layer doesn't set any if the v4l2_buffer fields except for
the flag. This leaves the value of v4l2_buffer::field unmodified, and
equal to V4L2_FIELD_ANY (0) if the error occurs the first time the
buffer is dequeued. v4l2-compliance then reports a failure:

Streaming ioctls:
        test read/write: OK (Not Supported)
                fail: v4l2-test-buffers.cpp(423): g_field() == V4L2_FIELD_ANY
                fail: v4l2-test-buffers.cpp(1293): buf.check(q, last_seq)
                fail: v4l2-test-buffers.cpp(1748): captureBufs(node, node_m2m_cap, q, m2m_q, frame_count, pollmode, capture_count)
        test MMAP (no poll, REQBUFS): FAIL

As the v4l2-compat layer doesn't support interlacing, fix this by
unconditionally setting v4l2_buffer::field to V4L2_FIELD_NONE when
allocating buffers.

While at it, sort the member assignments in the same order as in the
structure definition.

Closes: https://gitlab.freedesktop.org/camera/libcamera/-/work_items/369
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 src/v4l2/v4l2_camera_proxy.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

Comments

Jacopo Mondi Oct. 28, 2026, 7:32 a.m. UTC | #1
Hi Laurent

On Tue, Oct 27, 2026 at 11:24:45PM +0200, Laurent Pinchart wrote:
> When handling a buffer with the V4L2_BUF_FLAG_ERROR flag set, the
> v4l2-compat layer doesn't set any if the v4l2_buffer fields except for
> the flag. This leaves the value of v4l2_buffer::field unmodified, and
> equal to V4L2_FIELD_ANY (0) if the error occurs the first time the
> buffer is dequeued. v4l2-compliance then reports a failure:
>
> Streaming ioctls:
>         test read/write: OK (Not Supported)
>                 fail: v4l2-test-buffers.cpp(423): g_field() == V4L2_FIELD_ANY
>                 fail: v4l2-test-buffers.cpp(1293): buf.check(q, last_seq)
>                 fail: v4l2-test-buffers.cpp(1748): captureBufs(node, node_m2m_cap, q, m2m_q, frame_count, pollmode, capture_count)
>         test MMAP (no poll, REQBUFS): FAIL
>
> As the v4l2-compat layer doesn't support interlacing, fix this by
> unconditionally setting v4l2_buffer::field to V4L2_FIELD_NONE when
> allocating buffers.
>
> While at it, sort the member assignments in the same order as in the
> structure definition.
>
> Closes: https://gitlab.freedesktop.org/camera/libcamera/-/work_items/369
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>

> ---
>  src/v4l2/v4l2_camera_proxy.cpp | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
> index ca1115d017ac..2786e29e1ed7 100644
> --- a/src/v4l2/v4l2_camera_proxy.cpp
> +++ b/src/v4l2/v4l2_camera_proxy.cpp
> @@ -255,7 +255,6 @@ void V4L2CameraProxy::updateBuffers()
>  							[](unsigned int total, const auto &plane) {
>  								return total + plane.bytesused;
>  							});
> -			buf.field = V4L2_FIELD_NONE;
>  			buf.timestamp.tv_sec = fmd.timestamp / 1000000000;
>  			buf.timestamp.tv_usec = (fmd.timestamp / 1000) % 1000000;
>  			buf.sequence = fmd.sequence;
> @@ -557,12 +556,13 @@ int V4L2CameraProxy::vidioc_reqbufs(V4L2CameraFile *file, struct v4l2_requestbuf
>  	buffers_.resize(arg->count);
>  	for (unsigned int i = 0; i < arg->count; i++) {
>  		struct v4l2_buffer buf = {};
> +		buf.index = i;
>  		buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> -		buf.length = v4l2PixFormat_.sizeimage;
> +		buf.flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
> +		buf.field = V4L2_FIELD_NONE;
>  		buf.memory = V4L2_MEMORY_MMAP;
>  		buf.m.offset = i * v4l2PixFormat_.sizeimage;
> -		buf.index = i;
> -		buf.flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
> +		buf.length = v4l2PixFormat_.sizeimage;
>
>  		buffers_[i] = buf;
>  	}
> --
> Regards,
>
> Laurent Pinchart
>

Patch
diff mbox series

diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
index ca1115d017ac..2786e29e1ed7 100644
--- a/src/v4l2/v4l2_camera_proxy.cpp
+++ b/src/v4l2/v4l2_camera_proxy.cpp
@@ -255,7 +255,6 @@  void V4L2CameraProxy::updateBuffers()
 							[](unsigned int total, const auto &plane) {
 								return total + plane.bytesused;
 							});
-			buf.field = V4L2_FIELD_NONE;
 			buf.timestamp.tv_sec = fmd.timestamp / 1000000000;
 			buf.timestamp.tv_usec = (fmd.timestamp / 1000) % 1000000;
 			buf.sequence = fmd.sequence;
@@ -557,12 +556,13 @@  int V4L2CameraProxy::vidioc_reqbufs(V4L2CameraFile *file, struct v4l2_requestbuf
 	buffers_.resize(arg->count);
 	for (unsigned int i = 0; i < arg->count; i++) {
 		struct v4l2_buffer buf = {};
+		buf.index = i;
 		buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		buf.length = v4l2PixFormat_.sizeimage;
+		buf.flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+		buf.field = V4L2_FIELD_NONE;
 		buf.memory = V4L2_MEMORY_MMAP;
 		buf.m.offset = i * v4l2PixFormat_.sizeimage;
-		buf.index = i;
-		buf.flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+		buf.length = v4l2PixFormat_.sizeimage;
 
 		buffers_[i] = buf;
 	}