On 11/19/19 12:34 PM, Hans Verkuil wrote: > Stateful encoders need to know if V4L2_BUF_FLAG_ERROR was because > the capture buffer was too small or because there was another > error. Set this flag (always in combination with FLAG_ERROR) to > indicate that the buffer was too small. > > A corresponding VB2_BUF_STATE_ERROR_TOO_SMALL vb2 state was added. > > Signed-off-by: Hans Verkuil <hverkuil-cisco@xxxxxxxxx> > --- > Documentation/media/uapi/v4l/buffer.rst | 9 +++++++++ > drivers/media/common/videobuf2/videobuf2-core.c | 12 +++++++++--- > drivers/media/common/videobuf2/videobuf2-v4l2.c | 4 ++++ > include/media/videobuf2-core.h | 4 ++++ > include/uapi/linux/videodev2.h | 2 ++ > 5 files changed, 28 insertions(+), 3 deletions(-) > > diff --git a/Documentation/media/uapi/v4l/buffer.rst b/Documentation/media/uapi/v4l/buffer.rst > index 9149b57728e5..64a97677ec20 100644 > --- a/Documentation/media/uapi/v4l/buffer.rst > +++ b/Documentation/media/uapi/v4l/buffer.rst > @@ -540,6 +540,15 @@ Buffer Flags > streaming may continue as normal and the buffer may be reused > normally. Drivers set this flag when the ``VIDIOC_DQBUF`` ioctl is > called. > + * .. _`V4L2-BUF-FLAG-TOO-SMALL`: > + > + - ``V4L2_BUF_FLAG_TOO_SMALL`` > + - 0x00080000 > + - When this flag is set, the buffer has been dequeued successfully, > + but no data was written since the buffer was too small. If this > + flag is set, then ``V4L2_BUF_FLAG_ERROR`` was also set. This can > + only happen for capture buffers. Drivers set this flag when > + the ``VIDIOC_DQBUF`` ioctl is called. > * .. _`V4L2-BUF-FLAG-IN-REQUEST`: > > - ``V4L2_BUF_FLAG_IN_REQUEST`` > diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c > index 4489744fbbd9..187a4589a7bb 100644 > --- a/drivers/media/common/videobuf2/videobuf2-core.c > +++ b/drivers/media/common/videobuf2/videobuf2-core.c > @@ -929,6 +929,7 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) > > if (WARN_ON(state != VB2_BUF_STATE_DONE && > state != VB2_BUF_STATE_ERROR && > + state != VB2_BUF_STATE_ERROR_TOO_SMALL && > state != VB2_BUF_STATE_QUEUED)) > state = VB2_BUF_STATE_ERROR; > > @@ -1816,6 +1817,9 @@ int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb, > case VB2_BUF_STATE_ERROR: > dprintk(3, "returning done buffer with errors\n"); > break; > + case VB2_BUF_STATE_ERROR_TOO_SMALL: > + dprintk(3, "returning done buffer that's too small\n"); > + break; > default: > dprintk(1, "invalid buffer state\n"); > return -EINVAL; > @@ -2383,8 +2387,9 @@ __poll_t vb2_core_poll(struct vb2_queue *q, struct file *file, > done_entry); > spin_unlock_irqrestore(&q->done_lock, flags); > > - if (vb && (vb->state == VB2_BUF_STATE_DONE > - || vb->state == VB2_BUF_STATE_ERROR)) { > + if (vb && (vb->state == VB2_BUF_STATE_DONE || > + vb->state == VB2_BUF_STATE_ERROR || > + vb->state == VB2_BUF_STATE_ERROR_TOO_SMALL)) { > return (q->is_output) ? > EPOLLOUT | EPOLLWRNORM : > EPOLLIN | EPOLLRDNORM; > @@ -2812,7 +2817,8 @@ static int vb2_thread(void *data) > break; > try_to_freeze(); > > - if (vb->state != VB2_BUF_STATE_ERROR) > + if (vb->state != VB2_BUF_STATE_ERROR && > + vb->state != VB2_BUF_STATE_ERROR_TOO_SMALL) > if (threadio->fnc(vb, threadio->priv)) > break; > call_void_qop(q, wait_finish, q); > diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c > index e652f4318284..6ac19734e4a2 100644 > --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c > +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c > @@ -44,6 +44,7 @@ module_param(debug, int, 0644); > /* Flags that are set by us */ > #define V4L2_BUFFER_MASK_FLAGS (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \ > V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR | \ > + V4L2_BUF_FLAG_ERROR_TOO_SMALL | \ Oops, should have been V4L2_BUF_FLAG_TOO_SMALL. Sorry about that. Regards, Hans