media: uapi: h264: Split prediction weight parameters
authorEzequiel Garcia <ezequiel@collabora.com>
Tue, 25 Aug 2020 03:52:29 +0000 (05:52 +0200)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Tue, 1 Sep 2020 12:13:28 +0000 (14:13 +0200)
The prediction weight parameters are only required under
certain conditions, which depend on slice header parameters.

As specified in section 7.3.3 Slice header syntax, the prediction
weight table is present if:

((weighted_pred_flag && (slice_type == P || slice_type == SP)) || \
(weighted_bipred_idc == 1 && slice_type == B))

Given its size, it makes sense to move this table to its control,
so applications can avoid passing it if the slice doesn't specify it.

Before this change struct v4l2_ctrl_h264_slice_params was 960 bytes.
With this change, it's 188 bytes and struct v4l2_ctrl_h264_pred_weight
is 772 bytes.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Tested-by: Jonas Karlman <jonas@kwiboo.se>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
drivers/media/v4l2-core/v4l2-ctrls.c
drivers/staging/media/sunxi/cedrus/cedrus.c
drivers/staging/media/sunxi/cedrus/cedrus.h
drivers/staging/media/sunxi/cedrus/cedrus_dec.c
drivers/staging/media/sunxi/cedrus/cedrus_h264.c
include/media/h264-ctrls.h
include/media/v4l2-ctrls.h

index 2cce412f5be12cadf4932fd41588d24687a62f83..9e4421a7c6a6d11d071f725e51a20ff5dfef5c64 100644 (file)
@@ -1879,18 +1879,23 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
       - 0x00000008
       -
 
-``Prediction Weight Table``
+``V4L2_CID_MPEG_VIDEO_H264_PRED_WEIGHTS (struct)``
+    Prediction weight table defined according to :ref:`h264`,
+    section 7.4.3.2 "Prediction Weight Table Semantics".
+    The prediction weight table must be passed by applications
+    under the conditions explained in section 7.3.3 "Slice header
+    syntax".
 
-    The bitstream parameters are defined according to :ref:`h264`,
-    section 7.4.3.2 "Prediction Weight Table Semantics". For further
-    documentation, refer to the above specification, unless there is
-    an explicit comment stating otherwise.
+    .. note::
+
+       This compound control is not yet part of the public kernel API and
+       it is expected to change.
 
-.. c:type:: v4l2_h264_pred_weight_table
+.. c:type:: v4l2_ctrl_h264_pred_weights
 
 .. cssclass:: longtable
 
-.. flat-table:: struct v4l2_h264_pred_weight_table
+.. flat-table:: struct v4l2_ctrl_h264_pred_weights
     :header-rows:  0
     :stub-columns: 0
     :widths:       1 1 2
index 3f3fbcd60cc6211acf0062de7f5072ba1d81f255..76c8dc8fb31c401240808b4755bf00264069a3d8 100644 (file)
@@ -897,6 +897,7 @@ const char *v4l2_ctrl_get_name(u32 id)
        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_H264_START_CODE:               return "H264 Start Code";
+       case V4L2_CID_MPEG_VIDEO_H264_PRED_WEIGHTS:             return "H264 Prediction Weight Table";
        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";
@@ -1412,6 +1413,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
        case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS:
                *type = V4L2_CTRL_TYPE_H264_DECODE_PARAMS;
                break;
+       case V4L2_CID_MPEG_VIDEO_H264_PRED_WEIGHTS:
+               *type = V4L2_CTRL_TYPE_H264_PRED_WEIGHTS;
+               break;
        case V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER:
                *type = V4L2_CTRL_TYPE_VP8_FRAME_HEADER;
                break;
@@ -1790,6 +1794,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
        case V4L2_CTRL_TYPE_H264_SPS:
        case V4L2_CTRL_TYPE_H264_PPS:
        case V4L2_CTRL_TYPE_H264_SCALING_MATRIX:
+       case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS:
        case V4L2_CTRL_TYPE_H264_SLICE_PARAMS:
        case V4L2_CTRL_TYPE_H264_DECODE_PARAMS:
                break;
@@ -2553,6 +2558,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
        case V4L2_CTRL_TYPE_H264_DECODE_PARAMS:
                elem_size = sizeof(struct v4l2_ctrl_h264_decode_params);
                break;
+       case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS:
+               elem_size = sizeof(struct v4l2_ctrl_h264_pred_weights);
+               break;
        case V4L2_CTRL_TYPE_VP8_FRAME_HEADER:
                elem_size = sizeof(struct v4l2_ctrl_vp8_frame_header);
                break;
index bc27f9430eeb14712169a16f9807ee6536a4d5b1..826324faad7e728c91106e176efbc477bed8cbd8 100644 (file)
@@ -78,6 +78,13 @@ static const struct cedrus_control cedrus_controls[] = {
                .codec          = CEDRUS_CODEC_H264,
                .required       = true,
        },
+       {
+               .cfg = {
+                       .id     = V4L2_CID_MPEG_VIDEO_H264_PRED_WEIGHTS,
+               },
+               .codec          = CEDRUS_CODEC_H264,
+               .required       = false,
+       },
        {
                .cfg = {
                        .id     = V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE,
index 96765555ab8af1d1dc4d88499713bfead0c2d1c4..93c843ae14bb98ec25887eeac5a22f01f65d4a06 100644 (file)
@@ -62,6 +62,7 @@ struct cedrus_h264_run {
        const struct v4l2_ctrl_h264_scaling_matrix      *scaling_matrix;
        const struct v4l2_ctrl_h264_slice_params        *slice_params;
        const struct v4l2_ctrl_h264_sps                 *sps;
+       const struct v4l2_ctrl_h264_pred_weights        *pred_weights;
 };
 
 struct cedrus_mpeg2_run {
index 58c48e4fdfe95661f05e67e89852afc59468316b..6385026d1b6be47e5c62e695d3350d0e7be13631 100644 (file)
@@ -57,6 +57,8 @@ void cedrus_device_run(void *priv)
                        V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS);
                run.h264.sps = cedrus_find_control_data(ctx,
                        V4L2_CID_MPEG_VIDEO_H264_SPS);
+               run.h264.pred_weights = cedrus_find_control_data(ctx,
+                       V4L2_CID_MPEG_VIDEO_H264_PRED_WEIGHTS);
                break;
 
        case V4L2_PIX_FMT_HEVC_SLICE:
index cce527bbdf86c5858dc6b261f62bbbdc728aa2c3..d5636dbbb622433364c17bedb8e336fa13432147 100644 (file)
@@ -256,10 +256,8 @@ static void cedrus_write_scaling_lists(struct cedrus_ctx *ctx,
 static void cedrus_write_pred_weight_table(struct cedrus_ctx *ctx,
                                           struct cedrus_run *run)
 {
-       const struct v4l2_ctrl_h264_slice_params *slice =
-               run->h264.slice_params;
-       const struct v4l2_h264_pred_weight_table *pred_weight =
-               &slice->pred_weight_table;
+       const struct v4l2_ctrl_h264_pred_weights *pred_weight =
+               run->h264.pred_weights;
        struct cedrus_dev *dev = ctx->dev;
        int i, j, k;
 
@@ -367,11 +365,7 @@ static void cedrus_set_params(struct cedrus_ctx *ctx,
 
        cedrus_skip_bits(dev, slice->header_bit_size);
 
-       if (((pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED) &&
-            (slice->slice_type == V4L2_H264_SLICE_TYPE_P ||
-             slice->slice_type == V4L2_H264_SLICE_TYPE_SP)) ||
-           (pps->weighted_bipred_idc == 1 &&
-            slice->slice_type == V4L2_H264_SLICE_TYPE_B))
+       if (V4L2_H264_CTRL_PRED_WEIGHTS_REQUIRED(pps, slice))
                cedrus_write_pred_weight_table(ctx, run);
 
        if ((slice->slice_type == V4L2_H264_SLICE_TYPE_P) ||
index 3c613b84e5ae0f5544641478b24ec061cec9a539..31c6f4c5963b42160b634a5b8cdaba65a3b7b07e 100644 (file)
@@ -36,6 +36,7 @@
 #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)
 #define V4L2_CID_MPEG_VIDEO_H264_START_CODE    (V4L2_CID_MPEG_BASE+1006)
+#define V4L2_CID_MPEG_VIDEO_H264_PRED_WEIGHTS  (V4L2_CID_MPEG_BASE+1007)
 
 /* enum v4l2_ctrl_type type values */
 #define V4L2_CTRL_TYPE_H264_SPS                        0x0110
@@ -43,6 +44,7 @@
 #define V4L2_CTRL_TYPE_H264_SCALING_MATRIX     0x0112
 #define V4L2_CTRL_TYPE_H264_SLICE_PARAMS       0x0113
 #define V4L2_CTRL_TYPE_H264_DECODE_PARAMS      0x0114
+#define V4L2_CTRL_TYPE_H264_PRED_WEIGHTS       0x0115
 
 enum v4l2_mpeg_video_h264_decode_mode {
        V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED,
@@ -125,7 +127,14 @@ struct v4l2_h264_weight_factors {
        __s16 chroma_offset[32][2];
 };
 
-struct v4l2_h264_pred_weight_table {
+#define V4L2_H264_CTRL_PRED_WEIGHTS_REQUIRED(pps, slice) \
+       ((((pps)->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED) && \
+        ((slice)->slice_type == V4L2_H264_SLICE_TYPE_P || \
+         (slice)->slice_type == V4L2_H264_SLICE_TYPE_SP)) || \
+        ((pps)->weighted_bipred_idc == 1 && \
+         (slice)->slice_type == V4L2_H264_SLICE_TYPE_B))
+
+struct v4l2_ctrl_h264_pred_weights {
        __u16 luma_log2_weight_denom;
        __u16 chroma_log2_weight_denom;
        struct v4l2_h264_weight_factors weight_factors[2];
@@ -175,7 +184,6 @@ struct v4l2_ctrl_h264_slice_params {
        __s32 delta_pic_order_cnt0;
        __s32 delta_pic_order_cnt1;
 
-       struct v4l2_h264_pred_weight_table pred_weight_table;
        /* Size in bits of dec_ref_pic_marking() syntax element. */
        __u32 dec_ref_pic_marking_bit_size;
        /* Size in bits of pic order count syntax. */
index f40e2cbb21d344f99dc6bf2feef23422968804ad..cb25f345e9adc5cdb508eb894f8ca9e8188a6ec4 100644 (file)
@@ -51,6 +51,7 @@ struct video_device;
  * @p_h264_scaling_matrix:     Pointer to a struct v4l2_ctrl_h264_scaling_matrix.
  * @p_h264_slice_params:       Pointer to a struct v4l2_ctrl_h264_slice_params.
  * @p_h264_decode_params:      Pointer to a struct v4l2_ctrl_h264_decode_params.
+ * @p_h264_pred_weights:       Pointer to a struct v4l2_ctrl_h264_pred_weights.
  * @p_vp8_frame_header:                Pointer to a VP8 frame header structure.
  * @p_hevc_sps:                        Pointer to an HEVC sequence parameter set structure.
  * @p_hevc_pps:                        Pointer to an HEVC picture parameter set structure.
@@ -74,6 +75,7 @@ union v4l2_ctrl_ptr {
        struct v4l2_ctrl_h264_scaling_matrix *p_h264_scaling_matrix;
        struct v4l2_ctrl_h264_slice_params *p_h264_slice_params;
        struct v4l2_ctrl_h264_decode_params *p_h264_decode_params;
+       struct v4l2_ctrl_h264_pred_weights *p_h264_pred_weights;
        struct v4l2_ctrl_vp8_frame_header *p_vp8_frame_header;
        struct v4l2_ctrl_hevc_sps *p_hevc_sps;
        struct v4l2_ctrl_hevc_pps *p_hevc_pps;