[PATCH 4/5] videodev2.h: add V4L2_BUF_FLAG_TOO_SMALL flag

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 | \
 				 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 */
-- 
2.23.0




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux