Commit 137272cd authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

media: vb2: add V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF

This patch adds support for the V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF
flag.

It also adds a new V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF
capability.

Drivers should set vb2_queue->subsystem_flags to
VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF to indicate support
for this flag.
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent 4b1d7c27
...@@ -607,6 +607,19 @@ Buffer Flags ...@@ -607,6 +607,19 @@ Buffer Flags
applications shall use this flag for output buffers if the data in applications shall use this flag for output buffers if the data in
this buffer has not been created by the CPU but by some this buffer has not been created by the CPU but by some
DMA-capable unit, in which case caches have not been used. DMA-capable unit, in which case caches have not been used.
* .. _`V4L2-BUF-FLAG-M2M-HOLD-CAPTURE-BUF`:
- ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF``
- 0x00000200
- Only valid if ``V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF`` is
set. It is typically used with stateless decoders where multiple
output buffers each decode to a slice of the decoded frame.
Applications can set this flag when queueing the output buffer
to prevent the driver from dequeueing the capture buffer after
the output buffer has been decoded (i.e. the capture buffer is
'held'). If the timestamp of this output buffer differs from that
of the previous output buffer, then that indicates the start of a
new frame and the previously held capture buffer is dequeued.
* .. _`V4L2-BUF-FLAG-LAST`: * .. _`V4L2-BUF-FLAG-LAST`:
- ``V4L2_BUF_FLAG_LAST`` - ``V4L2_BUF_FLAG_LAST``
......
...@@ -125,6 +125,7 @@ aborting or finishing any DMA in progress, an implicit ...@@ -125,6 +125,7 @@ aborting or finishing any DMA in progress, an implicit
.. _V4L2-BUF-CAP-SUPPORTS-DMABUF: .. _V4L2-BUF-CAP-SUPPORTS-DMABUF:
.. _V4L2-BUF-CAP-SUPPORTS-REQUESTS: .. _V4L2-BUF-CAP-SUPPORTS-REQUESTS:
.. _V4L2-BUF-CAP-SUPPORTS-ORPHANED-BUFS: .. _V4L2-BUF-CAP-SUPPORTS-ORPHANED-BUFS:
.. _V4L2-BUF-CAP-SUPPORTS-M2M-HOLD-CAPTURE-BUF:
.. cssclass:: longtable .. cssclass:: longtable
...@@ -150,6 +151,11 @@ aborting or finishing any DMA in progress, an implicit ...@@ -150,6 +151,11 @@ aborting or finishing any DMA in progress, an implicit
- The kernel allows calling :ref:`VIDIOC_REQBUFS` while buffers are still - The kernel allows calling :ref:`VIDIOC_REQBUFS` while buffers are still
mapped or exported via DMABUF. These orphaned buffers will be freed mapped or exported via DMABUF. These orphaned buffers will be freed
when they are unmapped or when the exported DMABUF fds are closed. when they are unmapped or when the exported DMABUF fds are closed.
* - ``V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF``
- 0x00000020
- Only valid for stateless decoders. If set, then userspace can set the
``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag to hold off on returning the
capture buffer until the OUTPUT timestamp changes.
Return Value Return Value
============ ============
......
...@@ -49,8 +49,11 @@ module_param(debug, int, 0644); ...@@ -49,8 +49,11 @@ module_param(debug, int, 0644);
V4L2_BUF_FLAG_REQUEST_FD | \ V4L2_BUF_FLAG_REQUEST_FD | \
V4L2_BUF_FLAG_TIMESTAMP_MASK) V4L2_BUF_FLAG_TIMESTAMP_MASK)
/* Output buffer flags that should be passed on to the driver */ /* Output buffer flags that should be passed on to the driver */
#define V4L2_BUFFER_OUT_FLAGS (V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME | \ #define V4L2_BUFFER_OUT_FLAGS (V4L2_BUF_FLAG_PFRAME | \
V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_TIMECODE) V4L2_BUF_FLAG_BFRAME | \
V4L2_BUF_FLAG_KEYFRAME | \
V4L2_BUF_FLAG_TIMECODE | \
V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF)
/* /*
* __verify_planes_array() - verify that the planes array passed in struct * __verify_planes_array() - verify that the planes array passed in struct
...@@ -194,6 +197,7 @@ static int vb2_fill_vb2_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b ...@@ -194,6 +197,7 @@ static int vb2_fill_vb2_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b
} }
vbuf->sequence = 0; vbuf->sequence = 0;
vbuf->request_fd = -1; vbuf->request_fd = -1;
vbuf->is_held = false;
if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
switch (b->memory) { switch (b->memory) {
...@@ -321,6 +325,8 @@ static int vb2_fill_vb2_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b ...@@ -321,6 +325,8 @@ static int vb2_fill_vb2_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b
*/ */
vbuf->flags &= ~V4L2_BUF_FLAG_TIMECODE; vbuf->flags &= ~V4L2_BUF_FLAG_TIMECODE;
vbuf->field = b->field; vbuf->field = b->field;
if (!(q->subsystem_flags & VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF))
vbuf->flags &= ~V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF;
} else { } else {
/* Zero any output buffer flags as this is a capture buffer */ /* Zero any output buffer flags as this is a capture buffer */
vbuf->flags &= ~V4L2_BUFFER_OUT_FLAGS; vbuf->flags &= ~V4L2_BUFFER_OUT_FLAGS;
...@@ -654,6 +660,8 @@ static void fill_buf_caps(struct vb2_queue *q, u32 *caps) ...@@ -654,6 +660,8 @@ static void fill_buf_caps(struct vb2_queue *q, u32 *caps)
*caps |= V4L2_BUF_CAP_SUPPORTS_USERPTR; *caps |= V4L2_BUF_CAP_SUPPORTS_USERPTR;
if (q->io_modes & VB2_DMABUF) if (q->io_modes & VB2_DMABUF)
*caps |= V4L2_BUF_CAP_SUPPORTS_DMABUF; *caps |= V4L2_BUF_CAP_SUPPORTS_DMABUF;
if (q->subsystem_flags & VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF)
*caps |= V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF;
#ifdef CONFIG_MEDIA_CONTROLLER_REQUEST_API #ifdef CONFIG_MEDIA_CONTROLLER_REQUEST_API
if (q->supports_requests) if (q->supports_requests)
*caps |= V4L2_BUF_CAP_SUPPORTS_REQUESTS; *caps |= V4L2_BUF_CAP_SUPPORTS_REQUESTS;
......
...@@ -505,6 +505,8 @@ struct vb2_buf_ops { ...@@ -505,6 +505,8 @@ struct vb2_buf_ops {
* @buf_ops: callbacks to deliver buffer information. * @buf_ops: callbacks to deliver buffer information.
* between user-space and kernel-space. * between user-space and kernel-space.
* @drv_priv: driver private data. * @drv_priv: driver private data.
* @subsystem_flags: Flags specific to the subsystem (V4L2/DVB/etc.). Not used
* by the vb2 core.
* @buf_struct_size: size of the driver-specific buffer structure; * @buf_struct_size: size of the driver-specific buffer structure;
* "0" indicates the driver doesn't want to use a custom buffer * "0" indicates the driver doesn't want to use a custom buffer
* structure type. for example, ``sizeof(struct vb2_v4l2_buffer)`` * structure type. for example, ``sizeof(struct vb2_v4l2_buffer)``
...@@ -571,6 +573,7 @@ struct vb2_queue { ...@@ -571,6 +573,7 @@ struct vb2_queue {
const struct vb2_buf_ops *buf_ops; const struct vb2_buf_ops *buf_ops;
void *drv_priv; void *drv_priv;
u32 subsystem_flags;
unsigned int buf_struct_size; unsigned int buf_struct_size;
u32 timestamp_flags; u32 timestamp_flags;
gfp_t gfp_flags; gfp_t gfp_flags;
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
* @timecode: frame timecode. * @timecode: frame timecode.
* @sequence: sequence count of this frame. * @sequence: sequence count of this frame.
* @request_fd: the request_fd associated with this buffer * @request_fd: the request_fd associated with this buffer
* @is_held: if true, then this capture buffer was held
* @planes: plane information (userptr/fd, length, bytesused, data_offset). * @planes: plane information (userptr/fd, length, bytesused, data_offset).
* *
* Should contain enough information to be able to cover all the fields * Should contain enough information to be able to cover all the fields
...@@ -46,9 +47,13 @@ struct vb2_v4l2_buffer { ...@@ -46,9 +47,13 @@ struct vb2_v4l2_buffer {
struct v4l2_timecode timecode; struct v4l2_timecode timecode;
__u32 sequence; __u32 sequence;
__s32 request_fd; __s32 request_fd;
bool is_held;
struct vb2_plane planes[VB2_MAX_PLANES]; struct vb2_plane planes[VB2_MAX_PLANES];
}; };
/* VB2 V4L2 flags as set in vb2_queue.subsystem_flags */
#define VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF (1 << 0)
/* /*
* to_vb2_v4l2_buffer() - cast struct vb2_buffer * to struct vb2_v4l2_buffer * * to_vb2_v4l2_buffer() - cast struct vb2_buffer * to struct vb2_v4l2_buffer *
*/ */
......
...@@ -925,6 +925,7 @@ struct v4l2_requestbuffers { ...@@ -925,6 +925,7 @@ struct v4l2_requestbuffers {
#define V4L2_BUF_CAP_SUPPORTS_DMABUF (1 << 2) #define V4L2_BUF_CAP_SUPPORTS_DMABUF (1 << 2)
#define V4L2_BUF_CAP_SUPPORTS_REQUESTS (1 << 3) #define V4L2_BUF_CAP_SUPPORTS_REQUESTS (1 << 3)
#define V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS (1 << 4) #define V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS (1 << 4)
#define V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF (1 << 5)
/** /**
* struct v4l2_plane - plane info for multi-planar buffers * struct v4l2_plane - plane info for multi-planar buffers
...@@ -1046,6 +1047,8 @@ static inline __u64 v4l2_timeval_to_ns(const struct timeval *tv) ...@@ -1046,6 +1047,8 @@ static inline __u64 v4l2_timeval_to_ns(const struct timeval *tv)
#define V4L2_BUF_FLAG_IN_REQUEST 0x00000080 #define V4L2_BUF_FLAG_IN_REQUEST 0x00000080
/* timecode field is valid */ /* timecode field is valid */
#define V4L2_BUF_FLAG_TIMECODE 0x00000100 #define V4L2_BUF_FLAG_TIMECODE 0x00000100
/* Don't return the capture buffer until OUTPUT timestamp changes */
#define V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF 0x00000200
/* Buffer is prepared for queuing */ /* Buffer is prepared for queuing */
#define V4L2_BUF_FLAG_PREPARED 0x00000400 #define V4L2_BUF_FLAG_PREPARED 0x00000400
/* Cache handling flags */ /* Cache handling flags */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment