media: uapi: h264: Add the concept of decoding mode

Some stateless decoders don't support per-slice decoding granularity
(or at least not in a way that would make them efficient or easy to use).

Expose a menu to control the supported decoding modes. Drivers are
allowed to support only one decoding but they can support both too.

To fully specify the decoding operation, we need to introduce
a start_byte_offset, to indicate where slices start.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Tested-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
Boris Brezillon 2019-08-16 13:01:24 -03:00 committed by Mauro Carvalho Chehab
parent 7bb3c32abd
commit 5604be66a5
4 changed files with 79 additions and 3 deletions

View File

@ -1747,6 +1747,14 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
* - __u32
- ``size``
-
* - __u32
- ``start_byte_offset``
Offset (in bytes) from the beginning of the OUTPUT buffer to the start
of the slice. If the slice starts with a start code, then this is the
offset to such start code. When operating in slice-based decoding mode
(see :c:type:`v4l2_mpeg_video_h264_decode_mode`), this field should
be set to 0. When operating in frame-based decoding mode, this field
should be 0 for the first slice.
* - __u32
- ``header_bit_size``
-
@ -1930,7 +1938,10 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
-
* - __u16
- ``num_slices``
- Number of slices needed to decode the current frame
- Number of slices needed to decode the current frame/field. When
operating in slice-based decoding mode (see
:c:type:`v4l2_mpeg_video_h264_decode_mode`), this field
should always be set to one.
* - __u16
- ``nal_ref_idc``
- NAL reference ID value coming from the NAL Unit header
@ -2021,6 +2032,50 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
- 0x00000004
- The DPB entry is a long term reference frame
``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (enum)``
Specifies the decoding mode to use. Currently exposes slice-based and
frame-based decoding but new modes might be added later on.
This control is used as a modifier for V4L2_PIX_FMT_H264_SLICE
pixel format. Applications that support V4L2_PIX_FMT_H264_SLICE
are required to set this control in order to specify the decoding mode
that is expected for the buffer.
Drivers may expose a single or multiple decoding modes, depending
on what they can support.
.. note::
This menu control is not yet part of the public kernel API and
it is expected to change.
.. c:type:: v4l2_mpeg_video_h264_decode_mode
.. cssclass:: longtable
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 1 2
* - ``V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED``
- 0
- Decoding is done at the slice granularity.
In this mode, ``num_slices`` field in struct
:c:type:`v4l2_ctrl_h264_decode_params` should be set to 1,
and ``start_byte_offset`` in struct
:c:type:`v4l2_ctrl_h264_slice_params` should be set to 0.
The OUTPUT buffer must contain a single slice.
* - ``V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED``
- 1
- Decoding is done at the frame granularity.
In this mode, ``num_slices`` field in struct
:c:type:`v4l2_ctrl_h264_decode_params` should be set to the number
of slices in the frame, and ``start_byte_offset`` in struct
:c:type:`v4l2_ctrl_h264_slice_params` should be set accordingly
for each slice. For the first slice, ``start_byte_offset`` should
be zero.
The OUTPUT buffer must contain all slices needed to decode the
frame. The OUTPUT buffer must also contain both fields.
.. _v4l2-mpeg-mpeg2:
``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS (struct)``

View File

@ -60,8 +60,10 @@ Compressed Formats
extracted from the H264 bitstream. This format is adapted for
stateless video decoders that implement an H264 pipeline
(using the :ref:`mem2mem` and :ref:`media-request-api`).
Metadata associated with the frame to decode are required to
be passed through the ``V4L2_CID_MPEG_VIDEO_H264_SPS``,
This pixelformat has a modifier that must be set at least once
through the ``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE`` control.
In addition, metadata associated with the frame to decode are
required to be passed through the ``V4L2_CID_MPEG_VIDEO_H264_SPS``,
``V4L2_CID_MPEG_VIDEO_H264_PPS``,
``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX``,
``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS`` and

View File

@ -402,6 +402,11 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
"Explicit",
NULL,
};
static const char * const h264_decode_mode[] = {
"Slice-Based",
"Frame-Based",
NULL,
};
static const char * const mpeg_mpeg2_level[] = {
"Low",
"Main",
@ -633,6 +638,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
return h264_fp_arrangement_type;
case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE:
return h264_fmo_map_type;
case V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE:
return h264_decode_mode;
case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL:
return mpeg_mpeg2_level;
case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE:
@ -852,6 +859,7 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX: return "H264 Scaling Matrix";
case V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS: return "H264 Slice Parameters";
case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS: return "H264 Decode Parameters";
case V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE: return "H264 Decode Mode";
case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: return "MPEG2 Level";
case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: return "MPEG2 Profile";
case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value";
@ -1220,6 +1228,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE:
case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE:
case V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE:
case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL:
case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE:
case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:

View File

@ -26,6 +26,7 @@
#define V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX (V4L2_CID_MPEG_BASE+1002)
#define V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS (V4L2_CID_MPEG_BASE+1003)
#define V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS (V4L2_CID_MPEG_BASE+1004)
#define V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (V4L2_CID_MPEG_BASE+1005)
/* enum v4l2_ctrl_type type values */
#define V4L2_CTRL_TYPE_H264_SPS 0x0110
@ -34,6 +35,11 @@
#define V4L2_CTRL_TYPE_H264_SLICE_PARAMS 0x0113
#define V4L2_CTRL_TYPE_H264_DECODE_PARAMS 0x0114
enum v4l2_mpeg_video_h264_decode_mode {
V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED,
V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED,
};
#define V4L2_H264_SPS_CONSTRAINT_SET0_FLAG 0x01
#define V4L2_H264_SPS_CONSTRAINT_SET1_FLAG 0x02
#define V4L2_H264_SPS_CONSTRAINT_SET2_FLAG 0x04
@ -125,6 +131,10 @@ struct v4l2_h264_pred_weight_table {
struct v4l2_ctrl_h264_slice_params {
/* Size in bytes, including header */
__u32 size;
/* Offset in bytes to the start of slice in the OUTPUT buffer. */
__u32 start_byte_offset;
/* Offset in bits to slice_data() from the beginning of this slice. */
__u32 header_bit_size;