media: mfc: support hierarchical bitrate control
authorAyoung Sim <a.sim@samsung.com>
Fri, 23 Feb 2018 02:00:33 +0000 (11:00 +0900)
committerSunyoung Kang <sy0816.kang@samsung.com>
Tue, 29 May 2018 06:59:18 +0000 (15:59 +0900)
HIERARCHICAL_BIT_RATE_CONTROL[8] set to 1,
FW alloate the bit rate for each temporal layer base on E_RC_BITRATE.

Change-Id: I9ffc34eed1fc78da6d66b67e8c637f85f98de881
Signed-off-by: Ayoung Sim <a.sim@samsung.com>
drivers/media/platform/exynos/mfc/exynos_mfc_media.h
drivers/media/platform/exynos/mfc/s5p_mfc_common.h
drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h
drivers/media/platform/exynos/mfc/s5p_mfc_enc.c
drivers/media/platform/exynos/mfc/s5p_mfc_enc_internal.h
drivers/media/platform/exynos/mfc/s5p_mfc_enc_ops.c
drivers/media/platform/exynos/mfc/s5p_mfc_enc_param.c

index b6fdd0046a2d251328e35d7dae8a59bddeac525c..83d794a6b9eae7dc78864ecb319ab31928885d89 100644 (file)
@@ -425,6 +425,8 @@ enum v4l2_mpeg_video_hevc_hierarchical_coding_type {
                                        (V4L2_CID_MPEG_MFC_BASE + 197)
 #define V4L2_CID_MPEG_VIDEO_RATIO_OF_INTRA                     \
                                        (V4L2_CID_MPEG_MFC_BASE + 198)
+#define V4L2_CID_MPEG_VIDEO_HIERARCHICAL_BITRATE_CTRL          \
+                                       (V4L2_CID_MPEG_MFC_BASE + 199)
 
 /* QP BOUND interface */
 #define V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P                      \
index b6621ac517ef377916b62f98f96869a7558bc55d..7dc722fad617e19b1fec0ac80fb13855d2cda975 100644 (file)
 #define        ENC_SET_PVC_MODE                (1 << 7)
 #define        ENC_SET_RATIO_OF_INTRA          (1 << 8)
 #define        ENC_SET_COLOR_ASPECT            (1 << 9)
+#define        ENC_SET_HP_BITRATE_CONTROL      (1 << 10)
 
 #define MFC_VER_MAJOR(dev)     ((s5p_mfc_version(dev) >> 8) & 0xFF)
 #define MFC_VER_MINOR(dev)     (s5p_mfc_version(dev) & 0xFF)
                                        (dev->fw.date >= 0x171113))
 #define FW_HAS_ENC_COLOR_ASPECT(dev)   (FROM_MFCV11X(dev) &&           \
                                        (dev->fw.date >= 0x171023))
+#define FW_HAS_HP_BITRATE_CONTROL(dev) (FROM_MFCV11X(dev) &&           \
+                                       (dev->fw.date >= 0x180314))
 
 static inline unsigned int s5p_mfc_version(struct s5p_mfc_dev *dev)
 {
index c5093d06bba54f0343e949587f15ea6681b93d53..6573a38b938dbe79b4a3e36c2dca75cd433cd550 100644 (file)
@@ -985,6 +985,7 @@ struct s5p_mfc_enc_params {
        enum v4l2_mpeg_mfc51_video_frame_skip_mode frame_skip_mode;
        u8 fixed_target_bit;
        u8 num_hier_max_layer;
+       u8 hier_bitrate_ctrl;
        u8 weighted_enable;
        u8 roi_enable;
        u8 ivf_header_disable;  /* VP8, VP9 */
index 9fd44a4a647b7120cbabe9c89d679899c610e263..55392d0a607dd529c676f73253264a156e1c05f2 100644 (file)
@@ -764,6 +764,9 @@ static int mfc_enc_ext_info(struct s5p_mfc_ctx *ctx)
        if (FW_HAS_ENC_COLOR_ASPECT(dev))
                val |= ENC_SET_COLOR_ASPECT;
 
+       if (FW_HAS_HP_BITRATE_CONTROL(dev))
+               val |= ENC_SET_HP_BITRATE_CONTROL;
+
        return val;
 }
 
@@ -1594,6 +1597,9 @@ static int mfc_enc_set_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl)
        case V4L2_CID_MPEG_VIDEO_MATRIX_COEFFICIENTS:
                p->matrix_coefficients = ctrl->value;
                break;
+       case V4L2_CID_MPEG_VIDEO_HIERARCHICAL_BITRATE_CTRL:
+               p->hier_bitrate_ctrl = ctrl->value;
+               break;
        default:
                mfc_err_ctx("Invalid control: 0x%08x\n", ctrl->id);
                ret = -EINVAL;
index 955fb964d0f6e3264de5f4285441da08564d9992..5ca05276426a6323510877a4f3db3e303ea2a921 100644 (file)
@@ -2273,6 +2273,15 @@ static struct v4l2_queryctrl controls[] = {
                .step = 1,
                .default_value = 0,
        },
+       {
+               .id = V4L2_CID_MPEG_VIDEO_HIERARCHICAL_BITRATE_CTRL,
+               .type = V4L2_CTRL_TYPE_BOOLEAN,
+               .name = "Hierarchical bitrate control",
+               .minimum = 0,
+               .maximum = 1,
+               .step = 1,
+               .default_value = 1,
+       },
 };
 
 #define NUM_CTRLS ARRAY_SIZE(controls)
index aea21a93f0914f41169fa5fbce922080e076e96e..62a748abcb1e950ab6151063442694346780657c 100644 (file)
@@ -1031,7 +1031,7 @@ static void mfc_enc_set_buf_ctrls_temporal_svc(struct s5p_mfc_ctx *ctx,
 
                /* enable RC_BIT_RATE_CHANGE */
                value = MFC_READL(buf_ctrl->flag_addr);
-               if (temporal_LC.temporal_layer_bitrate[0] > 0)
+               if (temporal_LC.temporal_layer_bitrate[0] > 0 || p->hier_bitrate_ctrl)
                        /* set RC_BIT_RATE_CHANGE */
                        value |= (1 << 2);
                else
@@ -1046,11 +1046,13 @@ static void mfc_enc_set_buf_ctrls_temporal_svc(struct s5p_mfc_ctx *ctx,
                buf_ctrl->old_val2 = value;
                value &= ~(0x7);
                value |= (temporal_LC.temporal_layer_count & 0x7);
+               value &= ~(0x1 << 8);
+               value |= (p->hier_bitrate_ctrl & 0x1) << 8;
                MFC_WRITEL(value, S5P_FIMV_E_NUM_T_LAYER);
                mfc_debug(3, "Temporal SVC: E_NUM_T_LAYER %#x\n", value);
                for (i = 0; i < (temporal_LC.temporal_layer_count & 0x7); i++) {
-                       mfc_debug(3, "Temporal SVC: layer bitrate[%d] %d\n",
-                                       i, temporal_LC.temporal_layer_bitrate[i]);
+                       mfc_debug(3, "Temporal SVC: layer bitrate[%d] %d (FW ctrl: %d)\n",
+                                       i, temporal_LC.temporal_layer_bitrate[i], p->hier_bitrate_ctrl);
                        MFC_WRITEL(temporal_LC.temporal_layer_bitrate[i],
                                        buf_ctrl->addr + i * 4);
                }
@@ -1363,7 +1365,7 @@ static int s5p_mfc_enc_set_buf_ctrls_val_nal_q_enc(struct s5p_mfc_ctx *ctx,
                                        temporal_LC.temporal_layer_count & 0x7;
 
                        /* enable RC_BIT_RATE_CHANGE */
-                       if (temporal_LC.temporal_layer_bitrate[0] > 0)
+                       if (temporal_LC.temporal_layer_bitrate[0] > 0 || p->hier_bitrate_ctrl)
                                pInStr->ParamChange |= (1 << 2);
                        else
                                pInStr->ParamChange &= ~(1 << 2);
@@ -1378,9 +1380,11 @@ static int s5p_mfc_enc_set_buf_ctrls_val_nal_q_enc(struct s5p_mfc_ctx *ctx,
 
                        pInStr->NumTLayer &= ~(0x7);
                        pInStr->NumTLayer |= (temporal_LC.temporal_layer_count & 0x7);
+                       pInStr->NumTLayer &= ~(0x1 << 8);
+                       pInStr->NumTLayer |= (p->hier_bitrate_ctrl & 0x1) << 8;
                        for (i = 0; i < (temporal_LC.temporal_layer_count & 0x7); i++) {
-                               mfc_debug(3, "Temporal SVC: layer bitrate[%d] %d\n",
-                                       i, temporal_LC.temporal_layer_bitrate[i]);
+                               mfc_debug(3, "Temporal SVC: layer bitrate[%d] %d (FW ctrl: %d)\n",
+                                       i, temporal_LC.temporal_layer_bitrate[i], p->hier_bitrate_ctrl);
                                pInStr->HierarchicalBitRateLayer[i] =
                                        temporal_LC.temporal_layer_bitrate[i];
                        }
index 1e60d80ab022f17fc35b3316044ab01dd8ac9010..b509a36d7e8284db8370c628ec843776fdd10caa 100644 (file)
@@ -352,6 +352,8 @@ static void mfc_set_temporal_svc_h264(struct s5p_mfc_ctx *ctx, struct s5p_mfc_h2
        } else {
                reg |= 0x7 << 4;
        }
+       reg &= ~(0x1 << 8);
+       reg |= (p->hier_bitrate_ctrl & 0x1) << 8;
        MFC_WRITEL(reg, S5P_FIMV_E_NUM_T_LAYER);
        mfc_debug(3, "Temporal SVC: hier_qp_enable %d, enable_ltr %d, "
                "num_hier_layer %d, max_layer %d, hier_ref_type %d, NUM_T_LAYER 0x%x\n",
@@ -361,11 +363,12 @@ static void mfc_set_temporal_svc_h264(struct s5p_mfc_ctx *ctx, struct s5p_mfc_h2
        for (i = 0; i < 7; i++) {
                MFC_WRITEL(p_264->hier_qp_layer[i],
                                S5P_FIMV_E_HIERARCHICAL_QP_LAYER0 + i * 4);
+               /* If hier_bitrate_ctrl is set to 1, this is meaningless */
                MFC_WRITEL(p_264->hier_bit_layer[i],
                                S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0 + i * 4);
-               mfc_debug(3, "Temporal SVC: layer[%d] QP: %#x, bitrate: %d\n",
+               mfc_debug(3, "Temporal SVC: layer[%d] QP: %#x, bitrate: %d(FW ctrl: %d)\n",
                                        i, p_264->hier_qp_layer[i],
-                                       p_264->hier_bit_layer[i]);
+                                       p_264->hier_bit_layer[i], p->hier_bitrate_ctrl);
        }
        if (p_264->set_priority) {
                reg = 0;
@@ -901,6 +904,8 @@ void s5p_mfc_set_enc_params_vp8(struct s5p_mfc_ctx *ctx)
        reg |= p_vp8->num_hier_layer & 0x3;
        reg &= ~(0x7 << 4);
        reg |= 0x3 << 4;
+       reg &= ~(0x1 << 8);
+       reg |= (p->hier_bitrate_ctrl & 0x1) << 8;
        MFC_WRITEL(reg, S5P_FIMV_E_NUM_T_LAYER);
        mfc_debug(3, "Temporal SVC: hier_qp_enable %d, num_hier_layer %d, NUM_T_LAYER 0x%x\n",
                        p_vp8->hier_qp_enable, p_vp8->num_hier_layer, reg);
@@ -909,11 +914,12 @@ void s5p_mfc_set_enc_params_vp8(struct s5p_mfc_ctx *ctx)
        for (i = 0; i < 3; i++) {
                MFC_WRITEL(p_vp8->hier_qp_layer[i],
                                S5P_FIMV_E_HIERARCHICAL_QP_LAYER0 + i * 4);
+               /* If hier_bitrate_ctrl is set to 1, this is meaningless */
                MFC_WRITEL(p_vp8->hier_bit_layer[i],
                                S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0 + i * 4);
-               mfc_debug(3, "Temporal SVC: layer[%d] QP: %#x, bitrate: %#x\n",
+               mfc_debug(3, "Temporal SVC: layer[%d] QP: %#x, bitrate: %#x(FW ctrl: %d)\n",
                                        i, p_vp8->hier_qp_layer[i],
-                                       p_vp8->hier_bit_layer[i]);
+                                       p_vp8->hier_bit_layer[i], p->hier_bitrate_ctrl);
        }
 
        reg = 0;
@@ -1049,6 +1055,8 @@ void s5p_mfc_set_enc_params_vp9(struct s5p_mfc_ctx *ctx)
        reg |= p_vp9->num_hier_layer & 0x3;
        reg &= ~(0x7 << 4);
        reg |= 0x3 << 4;
+       reg &= ~(0x1 << 8);
+       reg |= (p->hier_bitrate_ctrl & 0x1) << 8;
        MFC_WRITEL(reg, S5P_FIMV_E_NUM_T_LAYER);
        mfc_debug(3, "Temporal SVC: hier_qp_enable %d, num_hier_layer %d, NUM_T_LAYER 0x%x\n",
                        p_vp9->hier_qp_enable, p_vp9->num_hier_layer, reg);
@@ -1057,11 +1065,12 @@ void s5p_mfc_set_enc_params_vp9(struct s5p_mfc_ctx *ctx)
        for (i = 0; i < 3; i++) {
                MFC_WRITEL(p_vp9->hier_qp_layer[i],
                                S5P_FIMV_E_HIERARCHICAL_QP_LAYER0 + i * 4);
+               /* If hier_bitrate_ctrl is set to 1, this is meaningless */
                MFC_WRITEL(p_vp9->hier_bit_layer[i],
                                S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0 + i * 4);
-               mfc_debug(3, "Temporal SVC: layer[%d] QP: %#x, bitrate: %#x\n",
+               mfc_debug(3, "Temporal SVC: layer[%d] QP: %#x, bitrate: %#x (FW ctrl: %d)\n",
                                        i, p_vp9->hier_qp_layer[i],
-                                       p_vp9->hier_bit_layer[i]);
+                                       p_vp9->hier_bit_layer[i], p->hier_bitrate_ctrl);
        }
 
        /* qp */
@@ -1276,6 +1285,8 @@ void s5p_mfc_set_enc_params_hevc(struct s5p_mfc_ctx *ctx)
        } else {
                reg |= 0x7 << 4;
        }
+       reg &= ~(0x1 << 8);
+       reg |= (p->hier_bitrate_ctrl & 0x1) << 8;
        MFC_WRITEL(reg, S5P_FIMV_E_NUM_T_LAYER);
        mfc_debug(2, "Temporal SVC: hier_qp_enable %d, enable_ltr %d, "
                "num_hier_layer %d, max_layer %d, hier_ref_type %d, NUM_T_LAYER 0x%x\n",
@@ -1288,9 +1299,9 @@ void s5p_mfc_set_enc_params_hevc(struct s5p_mfc_ctx *ctx)
                        S5P_FIMV_E_HIERARCHICAL_QP_LAYER0 + i * 4);
                MFC_WRITEL(p_hevc->hier_bit_layer[i],
                        S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0 + i * 4);
-               mfc_debug(3, "Temporal SVC: layer[%d] QP: %#x, bitrate: %#x\n",
+               mfc_debug(3, "Temporal SVC: layer[%d] QP: %#x, bitrate: %d(FW ctrl: %d)\n",
                                        i, p_hevc->hier_qp_layer[i],
-                                       p_hevc->hier_bit_layer[i]);
+                                       p_hevc->hier_bit_layer[i], p->hier_bitrate_ctrl);
        }
 
        /* rate control config. */