Skip to content

Commit

Permalink
media: uapi: mpeg2: Cleanup flags
Browse files Browse the repository at this point in the history
Our current MPEG-2 uAPI uses 1-byte fields for MPEG-2
boolean syntax elements. Clean these by adding a 'flags'
field and flag macro for each boolean syntax element.

Move quantization "load" flags to struct v4l2_mpeg2_picture,
so the applications can skip passing the quantization matrices
(by not setting the MPEG2_QUANTIZATION control in decode request).

A follow-up change will refactor this uAPI so we don't need
to add padding fields just yet.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
  • Loading branch information
ezequielgarcia authored and intel-lab-lkp committed Sep 29, 2020
1 parent c0c8db7 commit 66b4192
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 167 deletions.
108 changes: 68 additions & 40 deletions Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
Expand Up @@ -2275,13 +2275,28 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
- ``profile_and_level_indication``
- The current profile and level indication as extracted from the
bitstream.
* - __u8
- ``progressive_sequence``
- Indication that all the frames for the sequence are progressive instead
of interlaced.
* - __u8
- ``chroma_format``
- The chrominance sub-sampling format (1: 4:2:0, 2: 4:2:2, 3: 4:4:4).
* - __u32
- ``flags``
- See :ref:`MPEG-2 Sequence Flags <mpeg2_sequence_flags>`.

.. _mpeg2_sequence_flags:

``MPEG-2 Sequence Flags``

.. cssclass:: longtable

.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 1 2

* - ``V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE``
- 0x00000001
- Indication that all the frames for the sequence are progressive instead
of interlaced.

.. c:type:: v4l2_mpeg2_picture
Expand Down Expand Up @@ -2310,30 +2325,60 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
- ``picture_structure``
- Picture structure (1: interlaced top field, 2: interlaced bottom field,
3: progressive frame).
* - __u8
- ``top_field_first``
- If set to 1 and interlaced stream, top field is output first.
* - __u8
- ``frame_pred_frame_dct``
- If set to 1, only frame-DCT and frame prediction are used.
* - __u8
- ``concealment_motion_vectors``
- If set to 1, motion vectors are coded for intra macroblocks.
* - __u8
- ``q_scale_type``
* - __u32
- ``flags``
- See :ref:`MPEG-2 Picture Flags <mpeg2_picture_flags>`.


.. _mpeg2_picture_flags:

``MPEG-2 Picture Flags``

.. cssclass:: longtable

.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 1 2

* - ``V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST``
- 0x00000001
- If set and it's an interlaced stream, top field is output first.
* - ``V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT``
- 0x00000002
- If set only frame-DCT and frame prediction are used.
* - ``V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV``
- 0x00000004
- If set motion vectors are coded for intra macroblocks.
* - ``V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE``
- 0x00000008
- This flag affects the inverse quantization process.
* - __u8
- ``intra_vlc_format``
* - ``V4L2_MPEG2_PIC_FLAG_INTRA_VLC``
- 0x00000010
- This flag affects the decoding of transform coefficient data.
* - __u8
- ``alternate_scan``
* - ``V4L2_MPEG2_PIC_FLAG_ALT_SCAN``
- 0x00000020
- This flag affects the decoding of transform coefficient data.
* - __u8
- ``repeat_first_field``
* - ``V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST``
- 0x00000040
- This flag affects the decoding process of progressive frames.
* - __u16
- ``progressive_frame``
* - ``V4L2_MPEG2_PIC_FLAG_PROGRESSIVE``
- 0x00000080
- Indicates whether the current frame is progressive.
* - ``V4L2_MPEG2_PIC_FLAG_LOAD_INTRA``
* - 0x00000100
- Indicate whether to load the user-specified intra quantiser matrix.
* - ``V4L2_MPEG2_PIC_FLAG_LOAD_NON_INTRA``
* - 0x00000200
- Indicate whether to load the user-specified non-intra quantiser matrix.
* - ``V4L2_MPEG2_PIC_FLAG_LOAD_CHROMA_INTRA``
* - 0x00000400
- Indicate whether to load the user-specified chroma intra quantiser
matrix, only relevant for 4:2:2 and 4:4:4 YUV formats.
* - ``V4L2_MPEG2_PIC_FLAG_LOAD_CHROMA_NON_INTRA``
* - 0x0000800
- Indicate whether to load the user-specified chroma non-intra quantiser
matrix, only relevant for 4:2:2 and 4:4:4 YUV formats.

``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION (struct)``
Specifies quantization matrices (as extracted from the bitstream) for the
Expand All @@ -2359,23 +2404,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
:stub-columns: 0
:widths: 1 1 2

* - __u8
- ``load_intra_quantiser_matrix``
- One bit to indicate whether to load the ``intra_quantiser_matrix`` data.
* - __u8
- ``load_non_intra_quantiser_matrix``
- One bit to indicate whether to load the ``non_intra_quantiser_matrix``
data.
* - __u8
- ``load_chroma_intra_quantiser_matrix``
- One bit to indicate whether to load the
``chroma_intra_quantiser_matrix`` data, only relevant for non-4:2:0 YUV
formats.
* - __u8
- ``load_chroma_non_intra_quantiser_matrix``
- One bit to indicate whether to load the
``chroma_non_intra_quantiser_matrix`` data, only relevant for non-4:2:0
YUV formats.
* - __u8
- ``intra_quantiser_matrix[64]``
- The quantization matrix coefficients for intra-coded frames, in zigzag
Expand Down
14 changes: 7 additions & 7 deletions drivers/media/v4l2-core/v4l2-ctrls.c
Expand Up @@ -1641,7 +1641,7 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
/* interlaced top field */
p_mpeg2_slice_params->picture.picture_structure = 1;
p_mpeg2_slice_params->picture.picture_coding_type =
V4L2_MPEG2_PICTURE_CODING_TYPE_I;
V4L2_MPEG2_PIC_CODING_TYPE_I;
break;
}
}
Expand Down Expand Up @@ -1803,18 +1803,18 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
}

switch (p_mpeg2_slice_params->picture.picture_structure) {
case 1: /* interlaced top field */
case 2: /* interlaced bottom field */
case 3: /* progressive */
case V4L2_MPEG2_PIC_TOP_FIELD:
case V4L2_MPEG2_PIC_BOTTOM_FIELD:
case V4L2_MPEG2_PIC_FRAME:
break;
default:
return -EINVAL;
}

switch (p_mpeg2_slice_params->picture.picture_coding_type) {
case V4L2_MPEG2_PICTURE_CODING_TYPE_I:
case V4L2_MPEG2_PICTURE_CODING_TYPE_P:
case V4L2_MPEG2_PICTURE_CODING_TYPE_B:
case V4L2_MPEG2_PIC_CODING_TYPE_I:
case V4L2_MPEG2_PIC_CODING_TYPE_P:
case V4L2_MPEG2_PIC_CODING_TYPE_B:
break;
default:
return -EINVAL;
Expand Down
76 changes: 36 additions & 40 deletions drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
Expand Up @@ -77,10 +77,6 @@

#define G1_REG_APF_THRESHOLD(v) (((v) << 0) & GENMASK(13, 0))

#define PICT_TOP_FIELD 1
#define PICT_BOTTOM_FIELD 2
#define PICT_FRAME 3

static void
hantro_g1_mpeg2_dec_set_quantization(struct hantro_dev *vpu,
struct hantro_ctx *ctx)
Expand All @@ -99,19 +95,19 @@ static void
hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx,
struct vb2_buffer *src_buf,
struct vb2_buffer *dst_buf,
const struct v4l2_mpeg2_sequence *sequence,
const struct v4l2_mpeg2_picture *picture,
const struct v4l2_mpeg2_sequence *seq,
const struct v4l2_mpeg2_picture *pic,
const struct v4l2_ctrl_mpeg2_slice_params *slice_params)
{
dma_addr_t forward_addr = 0, backward_addr = 0;
dma_addr_t current_addr, addr;

switch (picture->picture_coding_type) {
case V4L2_MPEG2_PICTURE_CODING_TYPE_B:
switch (pic->picture_coding_type) {
case V4L2_MPEG2_PIC_CODING_TYPE_B:
backward_addr = hantro_get_ref(ctx,
slice_params->backward_ref_ts);
fallthrough;
case V4L2_MPEG2_PICTURE_CODING_TYPE_P:
case V4L2_MPEG2_PIC_CODING_TYPE_P:
forward_addr = hantro_get_ref(ctx,
slice_params->forward_ref_ts);
}
Expand All @@ -124,7 +120,7 @@ hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx,
addr = hantro_get_dec_buf_addr(ctx, dst_buf);
current_addr = addr;

if (picture->picture_structure == PICT_BOTTOM_FIELD)
if (pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD)
addr += ALIGN(ctx->dst_fmt.width, 16);
vdpu_write_relaxed(vpu, addr, G1_REG_DEC_OUT_BASE);

Expand All @@ -134,18 +130,18 @@ hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx,
backward_addr = current_addr;

/* Set forward ref frame (top/bottom field) */
if (picture->picture_structure == PICT_FRAME ||
picture->picture_coding_type == V4L2_MPEG2_PICTURE_CODING_TYPE_B ||
(picture->picture_structure == PICT_TOP_FIELD &&
picture->top_field_first) ||
(picture->picture_structure == PICT_BOTTOM_FIELD &&
!picture->top_field_first)) {
if (pic->picture_structure == V4L2_MPEG2_PIC_FRAME ||
pic->picture_coding_type == V4L2_MPEG2_PIC_CODING_TYPE_B ||
(pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD &&
pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST) ||
(pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD &&
!(pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST))) {
vdpu_write_relaxed(vpu, forward_addr, G1_REG_REFER0_BASE);
vdpu_write_relaxed(vpu, forward_addr, G1_REG_REFER1_BASE);
} else if (picture->picture_structure == PICT_TOP_FIELD) {
} else if (pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD) {
vdpu_write_relaxed(vpu, forward_addr, G1_REG_REFER0_BASE);
vdpu_write_relaxed(vpu, current_addr, G1_REG_REFER1_BASE);
} else if (picture->picture_structure == PICT_BOTTOM_FIELD) {
} else if (pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD) {
vdpu_write_relaxed(vpu, current_addr, G1_REG_REFER0_BASE);
vdpu_write_relaxed(vpu, forward_addr, G1_REG_REFER1_BASE);
}
Expand All @@ -160,8 +156,8 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
struct hantro_dev *vpu = ctx->dev;
struct vb2_v4l2_buffer *src_buf, *dst_buf;
const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
const struct v4l2_mpeg2_sequence *sequence;
const struct v4l2_mpeg2_picture *picture;
const struct v4l2_mpeg2_sequence *seq;
const struct v4l2_mpeg2_picture *pic;
u32 reg;

src_buf = hantro_get_src_buf(ctx);
Expand All @@ -172,8 +168,8 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)

slice_params = hantro_get_ctrl(ctx,
V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
sequence = &slice_params->sequence;
picture = &slice_params->picture;
seq = &slice_params->sequence;
pic = &slice_params->picture;

reg = G1_REG_DEC_AXI_RD_ID(0) |
G1_REG_DEC_TIMEOUT_E(1) |
Expand All @@ -193,11 +189,11 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)

reg = G1_REG_DEC_MODE(5) |
G1_REG_RLC_MODE_E(0) |
G1_REG_PIC_INTERLACE_E(!sequence->progressive_sequence) |
G1_REG_PIC_FIELDMODE_E(picture->picture_structure != PICT_FRAME) |
G1_REG_PIC_B_E(picture->picture_coding_type == V4L2_MPEG2_PICTURE_CODING_TYPE_B) |
G1_REG_PIC_INTER_E(picture->picture_coding_type != V4L2_MPEG2_PICTURE_CODING_TYPE_I) |
G1_REG_PIC_TOPFIELD_E(picture->picture_structure == PICT_TOP_FIELD) |
G1_REG_PIC_INTERLACE_E(!(seq->flags & V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE)) |
G1_REG_PIC_FIELDMODE_E(pic->picture_structure != V4L2_MPEG2_PIC_FRAME) |
G1_REG_PIC_B_E(pic->picture_coding_type == V4L2_MPEG2_PIC_CODING_TYPE_B) |
G1_REG_PIC_INTER_E(pic->picture_coding_type != V4L2_MPEG2_PIC_CODING_TYPE_I) |
G1_REG_PIC_TOPFIELD_E(pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD) |
G1_REG_FWD_INTERLACE_E(0) |
G1_REG_FILTERING_DIS(1) |
G1_REG_WRITE_MVS_E(0) |
Expand All @@ -206,27 +202,27 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)

reg = G1_REG_PIC_MB_WIDTH(MB_WIDTH(ctx->dst_fmt.width)) |
G1_REG_PIC_MB_HEIGHT_P(MB_HEIGHT(ctx->dst_fmt.height)) |
G1_REG_ALT_SCAN_E(picture->alternate_scan) |
G1_REG_TOPFIELDFIRST_E(picture->top_field_first);
G1_REG_ALT_SCAN_E(pic->flags & V4L2_MPEG2_PIC_FLAG_ALT_SCAN) |
G1_REG_TOPFIELDFIRST_E(pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST);
vdpu_write_relaxed(vpu, reg, G1_SWREG(4));

reg = G1_REG_STRM_START_BIT(slice_params->data_bit_offset) |
G1_REG_QSCALE_TYPE(picture->q_scale_type) |
G1_REG_CON_MV_E(picture->concealment_motion_vectors) |
G1_REG_INTRA_DC_PREC(picture->intra_dc_precision) |
G1_REG_INTRA_VLC_TAB(picture->intra_vlc_format) |
G1_REG_FRAME_PRED_DCT(picture->frame_pred_frame_dct);
G1_REG_QSCALE_TYPE(pic->flags & V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE) |
G1_REG_CON_MV_E(pic->flags & V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV) |
G1_REG_INTRA_DC_PREC(pic->intra_dc_precision) |
G1_REG_INTRA_VLC_TAB(pic->flags & V4L2_MPEG2_PIC_FLAG_INTRA_VLC) |
G1_REG_FRAME_PRED_DCT(pic->flags & V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT);
vdpu_write_relaxed(vpu, reg, G1_SWREG(5));

reg = G1_REG_INIT_QP(1) |
G1_REG_STREAM_LEN(slice_params->bit_size >> 3);
vdpu_write_relaxed(vpu, reg, G1_SWREG(6));

reg = G1_REG_ALT_SCAN_FLAG_E(picture->alternate_scan) |
G1_REG_FCODE_FWD_HOR(picture->f_code[0][0]) |
G1_REG_FCODE_FWD_VER(picture->f_code[0][1]) |
G1_REG_FCODE_BWD_HOR(picture->f_code[1][0]) |
G1_REG_FCODE_BWD_VER(picture->f_code[1][1]) |
reg = G1_REG_ALT_SCAN_FLAG_E(pic->flags & V4L2_MPEG2_PIC_FLAG_ALT_SCAN) |
G1_REG_FCODE_FWD_HOR(pic->f_code[0][0]) |
G1_REG_FCODE_FWD_VER(pic->f_code[0][1]) |
G1_REG_FCODE_BWD_HOR(pic->f_code[1][0]) |
G1_REG_FCODE_BWD_VER(pic->f_code[1][1]) |
G1_REG_MV_ACCURACY_FWD(1) |
G1_REG_MV_ACCURACY_BWD(1);
vdpu_write_relaxed(vpu, reg, G1_SWREG(18));
Expand All @@ -242,7 +238,7 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)

hantro_g1_mpeg2_dec_set_buffers(vpu, ctx, &src_buf->vb2_buf,
&dst_buf->vb2_buf,
sequence, picture, slice_params);
seq, pic, slice_params);

hantro_end_prepare_run(ctx);

Expand Down

0 comments on commit 66b4192

Please sign in to comment.