Message ID | 20191119113457.57833-5-hverkuil-cisco@xs4all.nl (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Stateful Encoding: final bits | expand |
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@xs4all.nl> > --- > 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
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 | \ V4L2_BUF_FLAG_PREPARED | \ V4L2_BUF_FLAG_IN_REQUEST | \ V4L2_BUF_FLAG_REQUEST_FD | \ @@ -546,6 +547,9 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb) case VB2_BUF_STATE_IN_REQUEST: b->flags |= V4L2_BUF_FLAG_IN_REQUEST; break; + case VB2_BUF_STATE_ERROR_TOO_SMALL: + b->flags |= V4L2_BUF_FLAG_TOO_SMALL; + /* fall through */ case VB2_BUF_STATE_ERROR: b->flags |= V4L2_BUF_FLAG_ERROR; /* fall through */ diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index a2b2208b02da..289c3e090257 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -215,6 +215,9 @@ enum vb2_io_modes { * @VB2_BUF_STATE_ERROR: same as above, but the operation on the buffer * has ended with an error, which will be reported * to the userspace when it is dequeued. + * @VB2_BUF_STATE_ERROR_TOO_SMALL: same as above, but the operation on the buffer + * has ended with an error because the receiving buffer + * is too small. */ enum vb2_buffer_state { VB2_BUF_STATE_DEQUEUED, @@ -224,6 +227,7 @@ enum vb2_buffer_state { VB2_BUF_STATE_ACTIVE, VB2_BUF_STATE_DONE, VB2_BUF_STATE_ERROR, + VB2_BUF_STATE_ERROR_TOO_SMALL, }; struct vb2_queue; diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 7aa1293ac7bc..c7c1179eea65 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -1064,6 +1064,8 @@ static inline __u64 v4l2_timeval_to_ns(const struct timeval *tv) #define V4L2_BUF_FLAG_TSTAMP_SRC_MASK 0x00070000 #define V4L2_BUF_FLAG_TSTAMP_SRC_EOF 0x00000000 #define V4L2_BUF_FLAG_TSTAMP_SRC_SOE 0x00010000 +/* mem2mem encoder */ +#define V4L2_BUF_FLAG_TOO_SMALL 0x00080000 /* mem2mem encoder/decoder */ #define V4L2_BUF_FLAG_LAST 0x00100000 /* request_fd is valid */
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@xs4all.nl> --- 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(-)