[3/4] v4l2: v4l2_camera_proxy: Clear ERROR flag when dequeuing or stopping streaming
diff mbox series

Message ID 20261027212447.2551591-4-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 a buffer is dequeued with VIDIOC_DQBUF, the V4L2 API reports buffer
erros with the V4L2_BUF_FLAG_ERROR. The API documentation doesn't state
what flags a subsequent VIDIOC_QUERYBUF call should return for the same
buffer, but videobuf2 sets the buffer state to dequeued just before
returning from VIDIOC_DQBUF, effectively clearing V4L2_BUF_FLAG_ERROR.
Similarly, a call to VIDIOC_STREAMOFF also put all queued buffers back
in the dequeued state.

Implement the same behaviour and clear the flag in vidioc_dqbuf() and
vidioc_streamoff().

This issue isn't caught by v4l2-compliance.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 src/v4l2/v4l2_camera_proxy.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Comments

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

On Tue, Oct 27, 2026 at 11:24:46PM +0200, Laurent Pinchart wrote:
> When a buffer is dequeued with VIDIOC_DQBUF, the V4L2 API reports buffer
> erros with the V4L2_BUF_FLAG_ERROR. The API documentation doesn't state
> what flags a subsequent VIDIOC_QUERYBUF call should return for the same
> buffer, but videobuf2 sets the buffer state to dequeued just before
> returning from VIDIOC_DQBUF, effectively clearing V4L2_BUF_FLAG_ERROR.
> Similarly, a call to VIDIOC_STREAMOFF also put all queued buffers back
> in the dequeued state.
>
> Implement the same behaviour and clear the flag in vidioc_dqbuf() and
> vidioc_streamoff().
>
> This issue isn't caught by v4l2-compliance.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  src/v4l2/v4l2_camera_proxy.cpp | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
> index 2786e29e1ed7..03b8a4210046 100644
> --- a/src/v4l2/v4l2_camera_proxy.cpp
> +++ b/src/v4l2/v4l2_camera_proxy.cpp
> @@ -698,6 +698,8 @@ int V4L2CameraProxy::vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg,
>  	buf.length = sizeimage_;
>  	*arg = buf;
>
> +	buf.flags &= ~V4L2_BUF_FLAG_ERROR;
> +

So what we want here is to copy in *arg the buffer with errors, and
the clear the flag after ?


>  	currentBuf_ = (currentBuf_ + 1) % bufferCount_;
>
>  	uint64_t data;
> @@ -778,7 +780,7 @@ int V4L2CameraProxy::vidioc_streamoff(V4L2CameraFile *file, int *arg)
>
>  	for (struct v4l2_buffer &buf : buffers_)
>  		buf.flags &= ~(V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE |
> -			       V4L2_BUF_FLAG_PREPARED);
> +			       V4L2_BUF_FLAG_ERROR | V4L2_BUF_FLAG_PREPARED);
>
>  	return ret;
>  }
> --
> Regards,
>
> Laurent Pinchart
>
Laurent Pinchart Oct. 28, 2026, 8:12 a.m. UTC | #2
On Wed, Oct 28, 2026 at 08:36:41AM +0100, Jacopo Mondi wrote:
> On Tue, Oct 27, 2026 at 11:24:46PM +0200, Laurent Pinchart wrote:
> > When a buffer is dequeued with VIDIOC_DQBUF, the V4L2 API reports buffer
> > erros with the V4L2_BUF_FLAG_ERROR. The API documentation doesn't state
> > what flags a subsequent VIDIOC_QUERYBUF call should return for the same
> > buffer, but videobuf2 sets the buffer state to dequeued just before
> > returning from VIDIOC_DQBUF, effectively clearing V4L2_BUF_FLAG_ERROR.
> > Similarly, a call to VIDIOC_STREAMOFF also put all queued buffers back
> > in the dequeued state.
> >
> > Implement the same behaviour and clear the flag in vidioc_dqbuf() and
> > vidioc_streamoff().
> >
> > This issue isn't caught by v4l2-compliance.
> >
> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > ---
> >  src/v4l2/v4l2_camera_proxy.cpp | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
> > index 2786e29e1ed7..03b8a4210046 100644
> > --- a/src/v4l2/v4l2_camera_proxy.cpp
> > +++ b/src/v4l2/v4l2_camera_proxy.cpp
> > @@ -698,6 +698,8 @@ int V4L2CameraProxy::vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg,
> >  	buf.length = sizeimage_;
> >  	*arg = buf;
> >
> > +	buf.flags &= ~V4L2_BUF_FLAG_ERROR;
> > +
> 
> So what we want here is to copy in *arg the buffer with errors, and
> the clear the flag after ?

That's right. It's required so that subsequent QUERYBUF calls will not
return the ERROR flag.

> >  	currentBuf_ = (currentBuf_ + 1) % bufferCount_;
> >
> >  	uint64_t data;
> > @@ -778,7 +780,7 @@ int V4L2CameraProxy::vidioc_streamoff(V4L2CameraFile *file, int *arg)
> >
> >  	for (struct v4l2_buffer &buf : buffers_)
> >  		buf.flags &= ~(V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE |
> > -			       V4L2_BUF_FLAG_PREPARED);
> > +			       V4L2_BUF_FLAG_ERROR | V4L2_BUF_FLAG_PREPARED);
> >
> >  	return ret;
> >  }
Jacopo Mondi Oct. 28, 2026, 8:28 a.m. UTC | #3
On Wed, Oct 28, 2026 at 10:12:00AM +0200, Laurent Pinchart wrote:
> On Wed, Oct 28, 2026 at 08:36:41AM +0100, Jacopo Mondi wrote:
> > On Tue, Oct 27, 2026 at 11:24:46PM +0200, Laurent Pinchart wrote:
> > > When a buffer is dequeued with VIDIOC_DQBUF, the V4L2 API reports buffer
> > > erros with the V4L2_BUF_FLAG_ERROR. The API documentation doesn't state
> > > what flags a subsequent VIDIOC_QUERYBUF call should return for the same
> > > buffer, but videobuf2 sets the buffer state to dequeued just before
> > > returning from VIDIOC_DQBUF, effectively clearing V4L2_BUF_FLAG_ERROR.
> > > Similarly, a call to VIDIOC_STREAMOFF also put all queued buffers back
> > > in the dequeued state.
> > >
> > > Implement the same behaviour and clear the flag in vidioc_dqbuf() and
> > > vidioc_streamoff().
> > >
> > > This issue isn't caught by v4l2-compliance.
> > >
> > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > > ---
> > >  src/v4l2/v4l2_camera_proxy.cpp | 4 +++-
> > >  1 file changed, 3 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
> > > index 2786e29e1ed7..03b8a4210046 100644
> > > --- a/src/v4l2/v4l2_camera_proxy.cpp
> > > +++ b/src/v4l2/v4l2_camera_proxy.cpp
> > > @@ -698,6 +698,8 @@ int V4L2CameraProxy::vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg,
> > >  	buf.length = sizeimage_;
> > >  	*arg = buf;
> > >
> > > +	buf.flags &= ~V4L2_BUF_FLAG_ERROR;
> > > +
> >
> > So what we want here is to copy in *arg the buffer with errors, and
> > the clear the flag after ?
>
> That's right. It's required so that subsequent QUERYBUF calls will not
> return the ERROR flag.
>

Ack, if this matches what videobuf2 does in practice, then let's go
for it
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>

> > >  	currentBuf_ = (currentBuf_ + 1) % bufferCount_;
> > >
> > >  	uint64_t data;
> > > @@ -778,7 +780,7 @@ int V4L2CameraProxy::vidioc_streamoff(V4L2CameraFile *file, int *arg)
> > >
> > >  	for (struct v4l2_buffer &buf : buffers_)
> > >  		buf.flags &= ~(V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE |
> > > -			       V4L2_BUF_FLAG_PREPARED);
> > > +			       V4L2_BUF_FLAG_ERROR | V4L2_BUF_FLAG_PREPARED);
> > >
> > >  	return ret;
> > >  }
>
> --
> Regards,
>
> Laurent Pinchart

Patch
diff mbox series

diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
index 2786e29e1ed7..03b8a4210046 100644
--- a/src/v4l2/v4l2_camera_proxy.cpp
+++ b/src/v4l2/v4l2_camera_proxy.cpp
@@ -698,6 +698,8 @@  int V4L2CameraProxy::vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg,
 	buf.length = sizeimage_;
 	*arg = buf;
 
+	buf.flags &= ~V4L2_BUF_FLAG_ERROR;
+
 	currentBuf_ = (currentBuf_ + 1) % bufferCount_;
 
 	uint64_t data;
@@ -778,7 +780,7 @@  int V4L2CameraProxy::vidioc_streamoff(V4L2CameraFile *file, int *arg)
 
 	for (struct v4l2_buffer &buf : buffers_)
 		buf.flags &= ~(V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE |
-			       V4L2_BUF_FLAG_PREPARED);
+			       V4L2_BUF_FLAG_ERROR | V4L2_BUF_FLAG_PREPARED);
 
 	return ret;
 }