diff --git a/mpp/codec/rc/rc_model_v2.c b/mpp/codec/rc/rc_model_v2.c index b367ad75..370a6667 100644 --- a/mpp/codec/rc/rc_model_v2.c +++ b/mpp/codec/rc/rc_model_v2.c @@ -1359,6 +1359,9 @@ MPP_RET rc_model_v2_init(void *ctx, RcCfg *cfg) rc_dbg_func("enter %p\n", ctx); memcpy(&p->usr_cfg, cfg, sizeof(RcCfg)); + rc_dbg_rc("init rc param: fqp %d:%d:%d:%d\n", cfg->fqp_min_i, cfg->fqp_max_i, + cfg->fqp_min_p, cfg->fqp_max_p); + bits_model_init(p); rc_dbg_func("leave %p\n", ctx); @@ -1507,6 +1510,50 @@ static RK_S32 cal_first_i_start_qp(RK_S32 target_bit, RK_U32 total_mb) return qscale2qp[index]; } +static RK_S32 derive_min_qp_from_complexity(RcModelV2Ctx *ctx, EncRcTaskInfo *info, RK_U32 is_intra) +{ + RcCfg *usr_cfg = &ctx->usr_cfg; + RcMode rc_mode = usr_cfg->mode; + RK_S32 qp_min = info->quality_min; + RK_S32 fqp_min_i = usr_cfg->fqp_min_i; + RK_S32 fqp_min_p = usr_cfg->fqp_min_p; + RK_S32 cplx = mpp_data_sum_v2(ctx->complex_level); + RK_S32 md = mpp_data_sum_v2(ctx->motion_level); + RK_S32 md3 = mpp_data_get_pre_val_v2(ctx->motion_level, 0) + + mpp_data_get_pre_val_v2(ctx->motion_level, 1) + + mpp_data_get_pre_val_v2(ctx->motion_level, 2); + + if (RC_AVBR == rc_mode || RC_VBR == rc_mode || RC_CBR == rc_mode) { + if (md >= 700) { + qp_min = is_intra ? fqp_min_i : fqp_min_p; + if (md >= 1400) + qp_min += md3 > 300 ? 3 : 2; + else + qp_min += md3 > 300 ? 2 : 1; + + if (cplx >= 15) + qp_min++; + } else if (RC_CBR != rc_mode) { + if (md > 100) { + if (cplx >= 16) + qp_min = (is_intra ? fqp_min_i : fqp_min_p) + 1; + else if (cplx >= 10) + qp_min = (is_intra ? fqp_min_i : fqp_min_p) + 0; + } else { + qp_min = (is_intra ? fqp_min_i : fqp_min_p); + qp_min += (cplx >= 15) ? 3 : (cplx >= 10) ? 2 : (cplx >= 5) ? 1 : 0; + } + } + + qp_min = mpp_clip(qp_min, info->quality_min, info->quality_max); + + rc_dbg_rc("frame %d complex_level %d motion_level %d md3 %d qp_min %d\n", + ctx->frm_num, cplx, md, md3, qp_min); + } + + return qp_min; +} + MPP_RET rc_model_v2_hal_start(void *ctx, EncRcTask *task) { RcModelV2Ctx *p = (RcModelV2Ctx *)ctx; @@ -1522,13 +1569,8 @@ MPP_RET rc_model_v2_hal_start(void *ctx, EncRcTask *task) RK_S32 quality_min = info->quality_min; RK_S32 quality_max = info->quality_max; RK_S32 quality_target = info->quality_target; - RK_S32 min_i_frame_qp = usr_cfg->fqp_min_i; - RK_S32 min_p_frame_qp = usr_cfg->fqp_min_p; - RK_S32 max_i_frame_qp = usr_cfg->fqp_max_i; - RK_S32 max_p_frame_qp = usr_cfg->fqp_max_p; rc_dbg_func("enter p %p task %p\n", p, task); - rc_dbg_rc("seq_idx %d intra %d\n", frm->seq_idx, frm->is_intra); if (force->force_flag & ENC_RC_FORCE_QP) { @@ -1582,42 +1624,7 @@ MPP_RET rc_model_v2_hal_start(void *ctx, EncRcTask *task) } else { RK_S32 qp_scale = p->cur_scale_qp + p->next_ratio; RK_S32 start_qp = 0; - RK_S32 qpmin = 26; - RK_S32 cplx = mpp_data_sum_v2(p->complex_level); - RK_S32 md = mpp_data_sum_v2(p->motion_level); - RK_S32 md3 = mpp_data_get_pre_val_v2(p->motion_level, 0) + mpp_data_get_pre_val_v2(p->motion_level, - 1) + mpp_data_get_pre_val_v2(p->motion_level, 2); - - if (RC_AVBR == usr_cfg->mode || RC_VBR == usr_cfg->mode || RC_CBR == usr_cfg->mode) { - if (md >= 700) { - if (md >= 1400) - qpmin = (frm->is_intra ? min_i_frame_qp : min_p_frame_qp) + (md3 > 300 ? 3 : 2); - else - qpmin = (frm->is_intra ? min_i_frame_qp : min_p_frame_qp) + (md3 > 300 ? 2 : 1); - - if (cplx >= 15) - qpmin ++; - } else if (RC_CBR != usr_cfg->mode) { - if (md > 100) { - if (cplx >= 16) - qpmin = (frm->is_intra ? min_i_frame_qp : min_p_frame_qp) + 1; - else if (cplx >= 10) - qpmin = (frm->is_intra ? min_i_frame_qp : min_p_frame_qp) + 0; - } else { - qpmin = (frm->is_intra ? min_i_frame_qp : min_p_frame_qp); - if (cplx >= 15) - qpmin += 3; - else if (cplx >= 10) - qpmin += 2; - else if (cplx >= 5) - qpmin += 1; - } - } - if (qpmin > info->quality_max) - qpmin = info->quality_max; - if (qpmin < info->quality_min) - qpmin = info->quality_min; - } + RK_S32 qpmin = derive_min_qp_from_complexity(p, info, frm->is_intra); if (frm->is_intra && !frm->is_i_refresh) { RK_S32 i_quality_delta = usr_cfg->i_quality_delta; @@ -1630,8 +1637,6 @@ MPP_RET rc_model_v2_hal_start(void *ctx, EncRcTask *task) else start_qp = (p->pre_i_qp + qp_scale_t) >> 1; - - if (i_quality_delta) { RK_U32 index = mpp_clip(mpp_data_mean_v2(p->madi) / 4, 0, 7); RK_S32 max_ip_delta = max_ip_qp_dealt[index]; @@ -1648,9 +1653,8 @@ MPP_RET rc_model_v2_hal_start(void *ctx, EncRcTask *task) start_qp -= i_quality_delta; //} } - start_qp = mpp_clip(start_qp, qpmin, info->quality_max); - start_qp = mpp_clip(start_qp, qpmin, max_i_frame_qp); + start_qp = mpp_clip(start_qp, qpmin, usr_cfg->fqp_max_i); start_qp = mpp_clip(start_qp, info->quality_min, info->quality_max); p->start_qp = start_qp; @@ -1673,7 +1677,7 @@ MPP_RET rc_model_v2_hal_start(void *ctx, EncRcTask *task) rc_dbg_rc("qp %d -> %d (vi)\n", p->start_qp, p->start_qp - usr_cfg->vi_quality_delta); p->start_qp -= usr_cfg->vi_quality_delta; } - p->start_qp = mpp_clip(p->start_qp, qpmin, max_p_frame_qp); + p->start_qp = mpp_clip(p->start_qp, qpmin, usr_cfg->fqp_max_p); } if (p->pre_target_bits_fix_count * 90 / 100 > p->pre_real_bits_count) { p->start_qp = mpp_clip(p->start_qp, info->quality_min, 35); diff --git a/mpp/hal/rkenc/h264e/hal_h264e_vepu510.c b/mpp/hal/rkenc/h264e/hal_h264e_vepu510.c index 1b25ac65..d239d5c4 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_vepu510.c +++ b/mpp/hal/rkenc/h264e/hal_h264e_vepu510.c @@ -156,21 +156,6 @@ static RK_S32 h264_I_aq_step_default[16] = { 0, 1, 2, 3, 4, 5, 7, 8 }; -static RK_S32 h264_aq_tthd_smart[16] = { - 0, 0, 0, 0, 3, 3, 5, 5, - 8, 8, 8, 15, 15, 20, 25, 28 -}; - -static RK_S32 h264_P_aq_step_smart[16] = { - -8, -7, -6, -5, -4, -3, -2, -1, - 0, 1, 2, 3, 4, 6, 8, 10 -}; - -static RK_S32 h264_I_aq_step_smart[16] = { - -8, -7, -6, -5, -4, -3, -2, -1, - 0, 1, 2, 3, 4, 6, 8, 10 -}; - static void setup_ext_line_bufs(HalH264eVepu510Ctx *ctx) { RK_U32 i; @@ -354,17 +339,10 @@ static MPP_RET hal_h264e_vepu510_init(void *hal, MppEncHalCfg *cfg) hw->qbias_p = 341; hw->qbias_en = 0; - if (p->smart_en) { - memcpy(hw->aq_thrd_i, h264_aq_tthd_smart, sizeof(hw->aq_thrd_i)); - memcpy(hw->aq_thrd_p, h264_aq_tthd_smart, sizeof(hw->aq_thrd_p)); - memcpy(hw->aq_step_i, h264_I_aq_step_smart, sizeof(hw->aq_step_i)); - memcpy(hw->aq_step_p, h264_P_aq_step_smart, sizeof(hw->aq_step_p)); - } else { - memcpy(hw->aq_thrd_i, h264_aq_tthd_default, sizeof(hw->aq_thrd_i)); - memcpy(hw->aq_thrd_p, h264_aq_tthd_default, sizeof(hw->aq_thrd_p)); - memcpy(hw->aq_step_i, h264_I_aq_step_default, sizeof(hw->aq_step_i)); - memcpy(hw->aq_step_p, h264_P_aq_step_default, sizeof(hw->aq_step_p)); - } + memcpy(hw->aq_thrd_i, h264_aq_tthd_default, sizeof(hw->aq_thrd_i)); + memcpy(hw->aq_thrd_p, h264_aq_tthd_default, sizeof(hw->aq_thrd_p)); + memcpy(hw->aq_step_i, h264_I_aq_step_default, sizeof(hw->aq_step_i)); + memcpy(hw->aq_step_p, h264_P_aq_step_default, sizeof(hw->aq_step_p)); for (i = 0; i < MPP_ARRAY_ELEMS(hw->mode_bias); i++) hw->mode_bias[i] = 8; @@ -1125,13 +1103,14 @@ static void setup_vepu510_rdo_pred(HalH264eVepu510Ctx *ctx, H264eSps *sps, { HalVepu510RegSet *regs = ctx->regs_set; H264eVepu510Frame *reg_frm = ®s->reg_frm; + RK_U32 is_ipc_scene = (ctx->cfg->tune.scene_mode == MPP_ENC_SCENE_MODE_IPC); hal_h264e_dbg_func("enter\n"); if (slice->slice_type == H264_I_SLICE) { regs->reg_rc_roi.klut_ofst.chrm_klut_ofst = 6; } else { - regs->reg_rc_roi.klut_ofst.chrm_klut_ofst = 9; + regs->reg_rc_roi.klut_ofst.chrm_klut_ofst = is_ipc_scene ? 9 : 6; } reg_frm->rdo_cfg.rect_size = (sps->profile_idc == H264_PROFILE_BASELINE && @@ -1594,9 +1573,12 @@ static void setup_vepu510_split(HalVepu510RegSet *regs, MppEncCfgSet *enc_cfg) hal_h264e_dbg_func("leave\n"); } -static void setup_vepu510_me(HalVepu510RegSet *regs) +static void setup_vepu510_me(HalH264eVepu510Ctx *ctx) { + HalVepu510RegSet *regs = ctx->regs_set; H264eVepu510Frame *reg_frm = ®s->reg_frm; + H264eVepu510Param *reg_param = ®s->reg_param; + MppEncSceneMode sm = ctx->cfg->tune.scene_mode; hal_h264e_dbg_func("enter\n"); @@ -1614,6 +1596,60 @@ static void setup_vepu510_me(HalVepu510RegSet *regs) reg_frm->common.me_rnge.dlt_frm_num = 0x0; reg_frm->common.me_cach.cime_zero_thre = 64; + /* CIME: 0x1760 - 0x176C */ + reg_param->me_sqi_comb.cime_pmv_num = 1; + reg_param->me_sqi_comb.cime_fuse = 1; + reg_param->me_sqi_comb.itp_mode = 0; + reg_param->me_sqi_comb.move_lambda = 0; + reg_param->me_sqi_comb.rime_lvl_mrg = 1; + reg_param->me_sqi_comb.rime_prelvl_en = 0; + reg_param->me_sqi_comb.rime_prersu_en = 0; + reg_param->cime_mvd_th_comb.cime_mvd_th0 = 16; + reg_param->cime_mvd_th_comb.cime_mvd_th1 = 48; + reg_param->cime_mvd_th_comb.cime_mvd_th2 = 80; + reg_param->cime_madp_th_comb.cime_madp_th = 16; + reg_param->cime_multi_comb.cime_multi0 = 8; + reg_param->cime_multi_comb.cime_multi1 = 12; + reg_param->cime_multi_comb.cime_multi2 = 16; + reg_param->cime_multi_comb.cime_multi3 = 20; + + /* RFME: 0x1770 - 0x1778 */ + reg_param->rime_mvd_th_comb.rime_mvd_th0 = 1; + reg_param->rime_mvd_th_comb.rime_mvd_th1 = 2; + reg_param->rime_mvd_th_comb.fme_madp_th = 0; + reg_param->rime_madp_th_comb.rime_madp_th0 = 8; + reg_param->rime_madp_th_comb.rime_madp_th1 = 16; + reg_param->rime_multi_comb.rime_multi0 = 4; + reg_param->rime_multi_comb.rime_multi1 = 8; + reg_param->rime_multi_comb.rime_multi2 = 12; + reg_param->cmv_st_th_comb.cmv_th0 = 64; + reg_param->cmv_st_th_comb.cmv_th1 = 96; + reg_param->cmv_st_th_comb.cmv_th2 = 128; + + if (sm != MPP_ENC_SCENE_MODE_IPC) { + /* disable subjective optimization */ + reg_param->cime_madp_th_comb.cime_madp_th = 0; + reg_param->rime_madp_th_comb.rime_madp_th0 = 0; + reg_param->rime_madp_th_comb.rime_madp_th1 = 0; + reg_param->cime_multi_comb.cime_multi0 = 4; + reg_param->cime_multi_comb.cime_multi1 = 4; + reg_param->cime_multi_comb.cime_multi2 = 4; + reg_param->cime_multi_comb.cime_multi3 = 4; + reg_param->rime_multi_comb.rime_multi0 = 4; + reg_param->rime_multi_comb.rime_multi1 = 4; + reg_param->rime_multi_comb.rime_multi2 = 4; + } + + /* 0x1064 */ + regs->reg_rc_roi.madi_st_thd.madi_th0 = 5; + regs->reg_rc_roi.madi_st_thd.madi_th1 = 12; + regs->reg_rc_roi.madi_st_thd.madi_th2 = 20; + /* 0x1068 */ + regs->reg_rc_roi.madp_st_thd0.madp_th0 = 4 << 4; + regs->reg_rc_roi.madp_st_thd0.madp_th1 = 9 << 4; + /* 0x106C */ + regs->reg_rc_roi.madp_st_thd1.madp_th2 = 15 << 4; + hal_h264e_dbg_func("leave\n"); } @@ -1680,66 +1716,6 @@ setup_vepu510_l2(HalH264eVepu510Ctx *ctx, MppEncHwCfg *hw) regs->reg_param.qnt_bias_comb.qnt_f_bias_p = 341; } - /* CIME */ - { - /* 0x1760 */ - regs->reg_param.me_sqi_comb.cime_pmv_num = 1; - regs->reg_param.me_sqi_comb.cime_fuse = 1; - regs->reg_param.me_sqi_comb.itp_mode = 0; - regs->reg_param.me_sqi_comb.move_lambda = 0; - regs->reg_param.me_sqi_comb.rime_lvl_mrg = 1; - regs->reg_param.me_sqi_comb.rime_prelvl_en = 0; - regs->reg_param.me_sqi_comb.rime_prersu_en = 0; - - /* 0x1764 */ - regs->reg_param.cime_mvd_th_comb.cime_mvd_th0 = 16; - regs->reg_param.cime_mvd_th_comb.cime_mvd_th1 = 48; - regs->reg_param.cime_mvd_th_comb.cime_mvd_th2 = 80; - - /* 0x1768 */ - regs->reg_param.cime_madp_th_comb.cime_madp_th = 16; - - /* 0x176c */ - regs->reg_param.cime_multi_comb.cime_multi0 = 8; - regs->reg_param.cime_multi_comb.cime_multi1 = 12; - regs->reg_param.cime_multi_comb.cime_multi2 = 16; - regs->reg_param.cime_multi_comb.cime_multi3 = 20; - } - - /* RIME && FME */ - { - /* 0x1770 */ - regs->reg_param.rime_mvd_th_comb.rime_mvd_th0 = 1; - regs->reg_param.rime_mvd_th_comb.rime_mvd_th1 = 2; - regs->reg_param.rime_mvd_th_comb.fme_madp_th = 0; - - /* 0x1774 */ - regs->reg_param.rime_madp_th_comb.rime_madp_th0 = 8; - regs->reg_param.rime_madp_th_comb.rime_madp_th1 = 16; - - /* 0x1778 */ - regs->reg_param.rime_multi_comb.rime_multi0 = 4; - regs->reg_param.rime_multi_comb.rime_multi1 = 8; - regs->reg_param.rime_multi_comb.rime_multi2 = 12; - - /* 0x177C */ - regs->reg_param.cmv_st_th_comb.cmv_th0 = 64; - regs->reg_param.cmv_st_th_comb.cmv_th1 = 96; - regs->reg_param.cmv_st_th_comb.cmv_th2 = 128; - } - /* madi and madp */ - { - /* 0x1064 */ - regs->reg_rc_roi.madi_st_thd.madi_th0 = 5; - regs->reg_rc_roi.madi_st_thd.madi_th1 = 12; - regs->reg_rc_roi.madi_st_thd.madi_th2 = 20; - /* 0x1068 */ - regs->reg_rc_roi.madp_st_thd0.madp_th0 = 4 << 4; - regs->reg_rc_roi.madp_st_thd0.madp_th1 = 9 << 4; - /* 0x106C */ - regs->reg_rc_roi.madp_st_thd1.madp_th2 = 15 << 4; - } - hal_h264e_dbg_func("leave\n"); } @@ -2175,7 +2151,7 @@ static MPP_RET hal_h264e_vepu510_gen_regs(void *hal, HalEncTask *task) reg_frm->common.pic_ofst.pic_ofst_x = mpp_frame_get_offset_x(task->frame); setup_vepu510_split(regs, cfg); - setup_vepu510_me(regs); + setup_vepu510_me(ctx); if (frm_status->is_i_refresh) setup_vepu510_intra_refresh(regs, ctx, frm_status->seq_idx % cfg->rc.gop); diff --git a/test/mpi_enc_test.c b/test/mpi_enc_test.c index 04dc5909..30cc6351 100644 --- a/test/mpi_enc_test.c +++ b/test/mpi_enc_test.c @@ -35,6 +35,16 @@ #include "mpp_enc_roi_utils.h" #include "mpp_rc_api.h" +static RK_S32 aq_thd_smart[16] = { + 0, 0, 0, 0, 3, 3, 5, 5, + 8, 8, 8, 15, 15, 20, 25, 28 +}; + +static RK_S32 aq_step_smart[16] = { + -8, -7, -6, -5, -4, -3, -2, -1, + 0, 1, 2, 3, 4, 6, 8, 10 +}; + typedef struct { // base flow context MppCtx ctx; @@ -345,6 +355,14 @@ MPP_RET test_mpp_enc_cfg_setup(MpiEncMultiCtxInfo *info) if (!p->bps) p->bps = p->width * p->height / 8 * (p->fps_out_num / p->fps_out_den); + if (cmd->rc_mode == MPP_ENC_RC_MODE_SMTRC) { + mpp_enc_cfg_set_st(cfg, "hw:aq_thrd_i", aq_thd_smart); + mpp_enc_cfg_set_st(cfg, "hw:aq_thrd_p", aq_thd_smart); + mpp_enc_cfg_set_st(cfg, "hw:aq_step_i", aq_step_smart); + mpp_enc_cfg_set_st(cfg, "hw:aq_step_p", aq_step_smart); + } + + mpp_enc_cfg_set_s32(cfg, "rc:max_reenc_times", 0); mpp_enc_cfg_set_s32(cfg, "rc:cu_qp_delta_depth", p->cu_qp_delta_depth); mpp_enc_cfg_set_s32(cfg, "tune:anti_flicker_str", p->anti_flicker_str); mpp_enc_cfg_set_s32(cfg, "tune:atr_str_i", p->atr_str_i);