@@ -672,7 +672,8 @@ int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b)
EXPORT_SYMBOL(vb2_querybuf);
static void vb2_set_flags_and_caps(struct vb2_queue *q, u32 memory,
- u32 *flags, u32 *caps, u32 *max_num_bufs)
+ u32 *flags, u32 *caps, u32 *max_num_bufs,
+ u16 *min_num_bufs, u16 *rec_num_bufs)
{
if (!q->allow_cache_hints || memory != V4L2_MEMORY_MMAP) {
/*
@@ -702,6 +703,11 @@ static void vb2_set_flags_and_caps(struct vb2_queue *q, u32 memory,
*max_num_bufs = q->max_num_buffers;
*caps |= V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS;
}
+ if (min_num_bufs && rec_num_bufs) {
+ *min_num_bufs = q->min_queued_buffers + 1;
+ *rec_num_bufs = q->min_reqbufs_allocation;
+ *caps |= V4L2_BUF_CAP_SUPPORTS_MIN_REC_NUM_BUFFERS;
+ }
}
int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
@@ -710,7 +716,7 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
u32 flags = req->flags;
vb2_set_flags_and_caps(q, req->memory, &flags,
- &req->capabilities, NULL);
+ &req->capabilities, NULL, NULL, NULL);
req->flags = flags;
return ret ? ret : vb2_core_reqbufs(q, req->memory,
req->flags, &req->count);
@@ -753,7 +759,9 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
create->index = vb2_get_num_buffers(q);
vb2_set_flags_and_caps(q, create->memory, &create->flags,
- &create->capabilities, &create->max_num_buffers);
+ &create->capabilities, &create->max_num_buffers,
+ &create->min_num_buffers,
+ &create->rec_num_buffers);
if (create->count == 0)
return ret != -EBUSY ? ret : 0;
@@ -1027,7 +1035,7 @@ int vb2_ioctl_reqbufs(struct file *file, void *priv,
u32 flags = p->flags;
vb2_set_flags_and_caps(vdev->queue, p->memory, &flags,
- &p->capabilities, NULL);
+ &p->capabilities, NULL, NULL, NULL);
p->flags = flags;
if (res)
return res;
@@ -1050,7 +1058,8 @@ int vb2_ioctl_create_bufs(struct file *file, void *priv,
p->index = vb2_get_num_buffers(vdev->queue);
vb2_set_flags_and_caps(vdev->queue, p->memory, &p->flags,
- &p->capabilities, &p->max_num_buffers);
+ &p->capabilities, &p->max_num_buffers,
+ &p->min_num_buffers, &p->rec_num_buffers);
/*
* If count == 0, then just check if memory and type are valid.
* Any -EBUSY result from vb2_verify_memory_type can be mapped to 0.
@@ -1079,6 +1079,7 @@ struct v4l2_requestbuffers {
#define V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS (1 << 6)
#define V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS (1 << 7)
#define V4L2_BUF_CAP_SUPPORTS_REMOVE_BUFS (1 << 8)
+#define V4L2_BUF_CAP_SUPPORTS_MIN_REC_NUM_BUFFERS (1 << 9)
/**
* struct v4l2_plane - plane info for multi-planar buffers
@@ -2660,9 +2661,18 @@ struct v4l2_dbg_chip_info {
* @flags: additional buffer management attributes (ignored unless the
* queue has V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS capability
* and configured for MMAP streaming I/O).
- * @max_num_buffers: if V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS capability flag is set
- * this field indicate the maximum possible number of buffers
- * for this queue.
+ * @max_num_buffers: if the V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS capability
+ * flag is set, then this field indicate the maximum possible
+ * number of buffers for this queue.
+ * @min_num_buffers: if the V4L2_BUF_CAP_SUPPORTS_MIN_REC_NUM_BUFFERS capability
+ * flag is set, then this field indicate the minimum possible
+ * number of buffers for this queue. Using this value might cause
+ * dropped frames, but it will be able to stream video. Useful for
+ * capturing only a single frame.
+ * @rec_num_buffers: if the V4L2_BUF_CAP_SUPPORTS_MIN_REC_NUM_BUFFERS capability
+ * flag is set, then this field indicates the recommended number
+ * of buffers for this queue. This is also used when calling
+ * VIDIOC_REQBUFS with count = 1.
* @reserved: future extensions
*/
struct v4l2_create_buffers {
@@ -2673,7 +2683,9 @@ struct v4l2_create_buffers {
__u32 capabilities;
__u32 flags;
__u32 max_num_buffers;
- __u32 reserved[5];
+ __u16 min_num_buffers;
+ __u16 rec_num_buffers;
+ __u32 reserved[4];
};
/**
Report the minimum and recommended number of buffers in struct v4l2_create_buffers. This is useful for those applications that want to have more precise control over how many buffers they want to allocate. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> --- This is a follow up to my RFC here: https://lore.kernel.org/linux-media/126cd76a-6224-483b-a18d-a3cc89e5ff2d@xs4all.nl/T/#u This patch adds a new buffer capability and new fields for struct v4l2_create_buffers to report the absolute minimum number of buffers that you have to allocate to stream, and the recommended number of buffers. min_num_buffers equals q->min_queued_buffers + 1 and rec_num_buffers equals q->min_reqbufs_allocation. I have one question how this relates to V4L2_CID_MIN_BUFFERS_FOR_CAPTURE/OUTPUT as used by codecs: I think drivers that set those controls should also update q->min_reqbufs_allocation to the same value. I think that would make sense. This is an RFC, once we are in agreement on this I will make a proper patch which also includes updating the documentation. Regards, Hans --- .../media/common/videobuf2/videobuf2-v4l2.c | 19 +++++++++++++----- include/uapi/linux/videodev2.h | 20 +++++++++++++++---- 2 files changed, 30 insertions(+), 9 deletions(-)