From f04fabc136304aa89bb03d695a64e18091f2153c Mon Sep 17 00:00:00 2001 From: Herman Chen Date: Tue, 5 Jan 2021 20:47:32 +0800 Subject: [PATCH] [mpp_enc_cfg]: Add global rc qp config 1. Add rc:qp config for user rate control config at frame level. 2. Add hw:qp config for hardware detail config. NOTE: hardware config is only recommended for expert developer. Change-Id: I8e28de97304577bcf77d67521f945355779ae102 Signed-off-by: Herman Chen --- inc/rk_venc_cmd.h | 57 ++++++++++++++++++++++++++++++-- mpp/base/mpp_enc_cfg.cpp | 19 +++++++++-- mpp/base/test/mpp_enc_cfg_test.c | 29 +++++++++++++++- mpp/codec/mpp_enc_impl.cpp | 36 ++++++++++++++++++++ mpp/inc/mpp_enc_cfg.h | 3 ++ 5 files changed, 138 insertions(+), 6 deletions(-) diff --git a/inc/rk_venc_cmd.h b/inc/rk_venc_cmd.h index 8be26db4..dd01ab16 100644 --- a/inc/rk_venc_cmd.h +++ b/inc/rk_venc_cmd.h @@ -181,6 +181,17 @@ typedef enum MppEncRcCfgChange_e { MPP_ENC_RC_CFG_CHANGE_INIT_IP_RATIO = (1 << 13), MPP_ENC_RC_CFG_CHANGE_PRIORITY = (1 << 14), MPP_ENC_RC_CFG_CHANGE_SUPER_FRM = (1 << 15), + /* qp related change flag */ + MPP_ENC_RC_CFG_CHANGE_QP_INIT = (1 << 16), + MPP_ENC_RC_CFG_CHANGE_QP_RANGE = (1 << 17), + MPP_ENC_RC_CFG_CHANGE_QP_RANGE_I = (1 << 18), + MPP_ENC_RC_CFG_CHANGE_QP_MAX_STEP = (1 << 19), + MPP_ENC_RC_CFG_CHANGE_QP_IP = (1 << 20), + MPP_ENC_RC_CFG_CHANGE_QP_VI = (1 << 21), + MPP_ENC_RC_CFG_CHANGE_QP_ROW = (1 << 22), + MPP_ENC_RC_CFG_CHANGE_QP_ROW_I = (1 << 23), + MPP_ENC_RC_CFG_CHANGE_AQ_THRD_I = (1 << 24), + MPP_ENC_RC_CFG_CHANGE_AQ_THRD_P = (1 << 25), MPP_ENC_RC_CFG_CHANGE_ALL = (0xFFFFFFFF), } MppEncRcCfgChange; @@ -332,11 +343,51 @@ typedef struct MppEncRcCfg_t { MppEncRcPriority rc_priority; - RK_S32 max_i_prop; - RK_S32 min_i_prop; - RK_S32 init_ip_ratio; + RK_S32 max_i_prop; + RK_S32 min_i_prop; + RK_S32 init_ip_ratio; + + /* general qp control */ + RK_S32 qp_init; + RK_S32 qp_max; + RK_S32 qp_max_i; + RK_S32 qp_min; + RK_S32 qp_min_i; + RK_S32 qp_max_step; /* delta qp between each two P frame */ + RK_S32 qp_delta_ip; /* delta qp between I and P */ + RK_S32 qp_delta_vi; /* delta qp between vi and P */ } MppEncRcCfg; + +typedef enum MppEncHwCfgChange_e { + /* qp related hardware config flag */ + MPP_ENC_HW_CFG_CHANGE_QP_ROW = (1 << 0), + MPP_ENC_HW_CFG_CHANGE_QP_ROW_I = (1 << 1), + MPP_ENC_HW_CFG_CHANGE_AQ_THRD_I = (1 << 2), + MPP_ENC_HW_CFG_CHANGE_AQ_THRD_P = (1 << 3), + MPP_ENC_HW_CFG_CHANGE_AQ_STEP_I = (1 << 4), + MPP_ENC_HW_CFG_CHANGE_AQ_STEP_P = (1 << 5), + MPP_ENC_HW_CFG_CHANGE_ALL = (0xFFFFFFFF), +} MppEncHwCfgChange; + +/* + * Hardware related rate control config + * + * This config will open some detail feature to external user to control + * hardware behavior directly. + */ +typedef struct MppEncHwCfg_t { + RK_U32 change; + + /* vepu541/vepu540 */ + RK_S32 qp_delta_row; /* delta qp between two row in P frame */ + RK_S32 qp_delta_row_i; /* delta qp between two row in I frame */ + RK_U32 aq_thrd_i[16]; + RK_U32 aq_thrd_p[16]; + RK_S32 aq_step_i[16]; + RK_S32 aq_step_p[16]; +} MppEncHwCfg; + /* * Mpp preprocess parameter */ diff --git a/mpp/base/mpp_enc_cfg.cpp b/mpp/base/mpp_enc_cfg.cpp index 718193e4..ea72f36b 100644 --- a/mpp/base/mpp_enc_cfg.cpp +++ b/mpp/base/mpp_enc_cfg.cpp @@ -137,6 +137,14 @@ RK_U32 mpp_enc_cfg_debug = 0; ENTRY(rc, super_mode, U32, MppEncRcSuperFrameMode, MPP_ENC_RC_CFG_CHANGE_SUPER_FRM, rc, super_mode) \ ENTRY(rc, super_i_thd, U32, RK_U32, MPP_ENC_RC_CFG_CHANGE_SUPER_FRM, rc, super_i_thd) \ ENTRY(rc, super_p_thd, U32, RK_U32, MPP_ENC_RC_CFG_CHANGE_SUPER_FRM, rc, super_p_thd) \ + ENTRY(rc, qp_init, S32, RK_S32, MPP_ENC_RC_CFG_CHANGE_QP_INIT, rc, qp_init) \ + ENTRY(rc, qp_min, S32, RK_S32, MPP_ENC_RC_CFG_CHANGE_QP_RANGE, rc, qp_min) \ + ENTRY(rc, qp_max, S32, RK_S32, MPP_ENC_RC_CFG_CHANGE_QP_RANGE, rc, qp_max) \ + ENTRY(rc, qp_min_i, S32, RK_S32, MPP_ENC_RC_CFG_CHANGE_QP_RANGE_I, rc, qp_min_i) \ + ENTRY(rc, qp_max_i, S32, RK_S32, MPP_ENC_RC_CFG_CHANGE_QP_RANGE_I, rc, qp_max_i) \ + ENTRY(rc, qp_step, S32, RK_S32, MPP_ENC_RC_CFG_CHANGE_QP_MAX_STEP, rc, qp_max_step) \ + ENTRY(rc, qp_ip, S32, RK_S32, MPP_ENC_RC_CFG_CHANGE_QP_IP, rc, qp_delta_ip) \ + ENTRY(rc, qp_vi, S32, RK_S32, MPP_ENC_RC_CFG_CHANGE_QP_VI, rc, qp_delta_vi) \ /* prep config */ \ ENTRY(prep, width, S32, RK_S32, MPP_ENC_PREP_CFG_CHANGE_INPUT, prep, width) \ ENTRY(prep, height, S32, RK_S32, MPP_ENC_PREP_CFG_CHANGE_INPUT, prep, height) \ @@ -214,7 +222,14 @@ RK_U32 mpp_enc_cfg_debug = 0; ENTRY(jpeg, qf_min, S32, RK_S32, MPP_ENC_JPEG_CFG_CHANGE_QFACTOR, codec.jpeg, qf_min) \ /* split config */ \ ENTRY(split, mode, U32, RK_U32, MPP_ENC_SPLIT_CFG_CHANGE_MODE, split, split_mode) \ - ENTRY(split, arg, U32, RK_U32, MPP_ENC_SPLIT_CFG_CHANGE_ARG, split, split_arg) + ENTRY(split, arg, U32, RK_U32, MPP_ENC_SPLIT_CFG_CHANGE_ARG, split, split_arg) \ + /* hardware detail config */ \ + ENTRY(hw, qp_row, S32, RK_S32, MPP_ENC_HW_CFG_CHANGE_QP_ROW, hw, qp_delta_row) \ + ENTRY(hw, qp_row_i, S32, RK_S32, MPP_ENC_HW_CFG_CHANGE_QP_ROW_I, hw, qp_delta_row_i) \ + ENTRY(hw, aq_thrd_i, St, RK_S32 *, MPP_ENC_HW_CFG_CHANGE_AQ_THRD_I, hw, aq_thrd_i) \ + ENTRY(hw, aq_thrd_p, St, RK_S32 *, MPP_ENC_HW_CFG_CHANGE_AQ_THRD_P, hw, aq_thrd_p) \ + ENTRY(hw, aq_step_i, St, RK_S32 *, MPP_ENC_HW_CFG_CHANGE_AQ_STEP_I, hw, aq_step_i) \ + ENTRY(hw, aq_step_p, St, RK_S32 *, MPP_ENC_HW_CFG_CHANGE_AQ_STEP_P, hw, aq_step_p) ENTRY_TABLE(EXPAND_AS_FUNC) ENTRY_TABLE(EXPAND_AS_API) @@ -228,7 +243,7 @@ RK_S32 const_strlen(const char* str) return *str ? 1 + const_strlen(str + 1) : 0; } -static RK_S32 node_len = ENTRY_TABLE(EXPAND_AS_STRLEN) - 40; +static RK_S32 node_len = ENTRY_TABLE(EXPAND_AS_STRLEN) - 89; class MppEncCfgService { diff --git a/mpp/base/test/mpp_enc_cfg_test.c b/mpp/base/test/mpp_enc_cfg_test.c index a3375cc9..aac3ef54 100644 --- a/mpp/base/test/mpp_enc_cfg_test.c +++ b/mpp/base/test/mpp_enc_cfg_test.c @@ -43,6 +43,19 @@ int main() RK_S32 rc_mode = 1; RK_S32 bps_target = 400000; + RK_S32 aq_thrd_i[16] = { + 0, 0, 0, 0, + 3, 3, 5, 5, + 8, 8, 8, 15, + 15, 20, 25, 35 + }; + + RK_S32 aq_thrd_i_ret[16] = { + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + }; MppEncCfgImpl *impl = (MppEncCfgImpl *)cfg; @@ -67,9 +80,23 @@ int main() ret = mpp_enc_cfg_get_s32(cfg, "rc:mode", &rc_mode); ret = mpp_enc_cfg_get_s32(cfg, "rc:bps_target", &bps_target); - mpp_log("after get: rc mode %d bps_target %d\n", rc_mode, bps_target); + mpp_log("before set: rc aq_thrd_i: %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d\n", + aq_thrd_i_ret[0], aq_thrd_i_ret[1], aq_thrd_i_ret[2], aq_thrd_i_ret[3], + aq_thrd_i_ret[4], aq_thrd_i_ret[5], aq_thrd_i_ret[6], aq_thrd_i_ret[7], + aq_thrd_i_ret[8], aq_thrd_i_ret[9], aq_thrd_i_ret[10], aq_thrd_i_ret[11], + aq_thrd_i_ret[12], aq_thrd_i_ret[13], aq_thrd_i_ret[14], aq_thrd_i_ret[15]); + + ret = mpp_enc_cfg_set_st(cfg, "hw:aq_step_i", aq_thrd_i); + ret = mpp_enc_cfg_get_st(cfg, "hw:aq_step_i", aq_thrd_i_ret); + + mpp_log("after get: rc aq_thrd_i: %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d\n", + aq_thrd_i_ret[0], aq_thrd_i_ret[1], aq_thrd_i_ret[2], aq_thrd_i_ret[3], + aq_thrd_i_ret[4], aq_thrd_i_ret[5], aq_thrd_i_ret[6], aq_thrd_i_ret[7], + aq_thrd_i_ret[8], aq_thrd_i_ret[9], aq_thrd_i_ret[10], aq_thrd_i_ret[11], + aq_thrd_i_ret[12], aq_thrd_i_ret[13], aq_thrd_i_ret[14], aq_thrd_i_ret[15]); + ret = mpp_enc_cfg_deinit(cfg); if (ret) { mpp_err("mpp_enc_cfg_deinit failed\n"); diff --git a/mpp/codec/mpp_enc_impl.cpp b/mpp/codec/mpp_enc_impl.cpp index 1b67bbd8..bb9c04d3 100644 --- a/mpp/codec/mpp_enc_impl.cpp +++ b/mpp/codec/mpp_enc_impl.cpp @@ -471,6 +471,36 @@ static RK_S32 check_low_delay_part_mode(MppEncImpl *enc) return 1; } +MPP_RET mpp_enc_proc_hw_cfg(MppEncHwCfg *dst, MppEncHwCfg *src) +{ + MPP_RET ret = MPP_OK; + RK_U32 change = src->change; + + if (change) { + if (change & MPP_ENC_HW_CFG_CHANGE_QP_ROW) + dst->qp_delta_row = src->qp_delta_row; + + if (change & MPP_ENC_HW_CFG_CHANGE_QP_ROW_I) + dst->qp_delta_row_i = src->qp_delta_row_i; + + if (change & MPP_ENC_HW_CFG_CHANGE_AQ_THRD_I) + memcpy(dst->aq_thrd_i, src->aq_thrd_i, sizeof(dst->aq_thrd_i)); + + if (change & MPP_ENC_HW_CFG_CHANGE_AQ_THRD_P) + memcpy(dst->aq_thrd_p, src->aq_thrd_p, sizeof(dst->aq_thrd_p)); + + if (change & MPP_ENC_HW_CFG_CHANGE_AQ_STEP_I) + memcpy(dst->aq_step_i, src->aq_step_i, sizeof(dst->aq_step_i)); + + if (change & MPP_ENC_HW_CFG_CHANGE_AQ_STEP_P) + memcpy(dst->aq_step_p, src->aq_step_p, sizeof(dst->aq_step_p)); + + dst->change |= change; + } + + return ret; +} + MPP_RET mpp_enc_proc_cfg(MppEncImpl *enc, MpiCmd cmd, void *param) { MPP_RET ret = MPP_OK; @@ -491,6 +521,12 @@ MPP_RET mpp_enc_proc_cfg(MppEncImpl *enc, MpiCmd cmd, void *param) src->base.change = 0; } + /* process hardware cfg at mpp_enc module */ + if (src->hw.change) { + ret = mpp_enc_proc_hw_cfg(&enc->cfg.hw, &src->hw); + src->hw.change = 0; + } + ret = enc_impl_proc_cfg(enc->impl, cmd, param); } break; case MPP_ENC_GET_HDR_SYNC : diff --git a/mpp/inc/mpp_enc_cfg.h b/mpp/inc/mpp_enc_cfg.h index afd5d649..44a2cb4e 100644 --- a/mpp/inc/mpp_enc_cfg.h +++ b/mpp/inc/mpp_enc_cfg.h @@ -35,6 +35,9 @@ typedef struct MppEncCfgSet_t { MppEncPrepCfg prep; MppEncRcCfg rc; + // hardware related config + MppEncHwCfg hw; + // codec detail config MppEncCodecCfg codec;