From: Ayoung Sim Date: Fri, 23 Feb 2018 02:00:33 +0000 (+0900) Subject: media: mfc: support hierarchical bitrate control X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=10af75c7810dcb97bb1dc75a382ec8ce8c1f5445;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git media: mfc: support hierarchical bitrate control 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 --- diff --git a/drivers/media/platform/exynos/mfc/exynos_mfc_media.h b/drivers/media/platform/exynos/mfc/exynos_mfc_media.h index b6fdd0046a2d..83d794a6b9ea 100644 --- a/drivers/media/platform/exynos/mfc/exynos_mfc_media.h +++ b/drivers/media/platform/exynos/mfc/exynos_mfc_media.h @@ -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 \ diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_common.h b/drivers/media/platform/exynos/mfc/s5p_mfc_common.h index b6621ac517ef..7dc722fad617 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_common.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_common.h @@ -164,6 +164,7 @@ #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) @@ -199,6 +200,8 @@ (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) { diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h b/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h index c5093d06bba5..6573a38b938d 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h @@ -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 */ diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_enc.c b/drivers/media/platform/exynos/mfc/s5p_mfc_enc.c index 9fd44a4a647b..55392d0a607d 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_enc.c @@ -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; diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_enc_internal.h b/drivers/media/platform/exynos/mfc/s5p_mfc_enc_internal.h index 955fb964d0f6..5ca05276426a 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_enc_internal.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_enc_internal.h @@ -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) diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_enc_ops.c b/drivers/media/platform/exynos/mfc/s5p_mfc_enc_ops.c index aea21a93f091..62a748abcb1e 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_enc_ops.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_enc_ops.c @@ -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]; } diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_enc_param.c b/drivers/media/platform/exynos/mfc/s5p_mfc_enc_param.c index 1e60d80ab022..b509a36d7e82 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_enc_param.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_enc_param.c @@ -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. */