From 6c74d876a34b835bb4ce4d221ad9b0c3c48bd14f Mon Sep 17 00:00:00 2001 From: "sayon.chen" Date: Thu, 30 Nov 2017 15:11:24 +0800 Subject: [PATCH] [rkv_enc]: VBR case add new ratecontrol add AQ_ONLY quality ratecontrol for CVR qp adjust according bit allocate,mb qp dealt adjust accroding adaptive quant Change-Id: Ia9a46e765646a88e2659f5fb19b94a0a5c667681 Signed-off-by: sayon.chen --- inc/rk_mpi_cmd.h | 1 + mpp/codec/inc/mpp_rc.h | 1 + mpp/codec/mpp_rc.cpp | 53 +++++++++++++++++++++-------- mpp/hal/common/h264/hal_h264e_com.h | 3 +- mpp/hal/rkenc/h264e/hal_h264e_rkv.c | 47 +++++++++++++++++-------- 5 files changed, 74 insertions(+), 31 deletions(-) diff --git a/inc/rk_mpi_cmd.h b/inc/rk_mpi_cmd.h index 13fd81b4..0ac86a20 100644 --- a/inc/rk_mpi_cmd.h +++ b/inc/rk_mpi_cmd.h @@ -65,6 +65,7 @@ typedef enum MppEncRcQuality_t { MPP_ENC_RC_QUALITY_BETTER, MPP_ENC_RC_QUALITY_BEST, MPP_ENC_RC_QUALITY_CQP, + MPP_ENC_RC_QUALITY_AQ_ONLY, MPP_ENC_RC_QUALITY_BUTT } MppEncRcQuality; diff --git a/mpp/codec/inc/mpp_rc.h b/mpp/codec/inc/mpp_rc.h index 773d1748..657651fe 100644 --- a/mpp/codec/inc/mpp_rc.h +++ b/mpp/codec/inc/mpp_rc.h @@ -193,6 +193,7 @@ typedef struct MppRateControl_s { RK_U32 frm_cnt; RK_S32 real_bps; RK_S32 prev_aq_prop_offset; + RK_S32 quality; } MppRateControl; diff --git a/mpp/codec/mpp_rc.cpp b/mpp/codec/mpp_rc.cpp index 5c0cbb16..0748e6c5 100644 --- a/mpp/codec/mpp_rc.cpp +++ b/mpp/codec/mpp_rc.cpp @@ -390,7 +390,7 @@ MPP_RET mpp_rc_update_user_cfg(MppRateControl *ctx, MppEncRcCfg *cfg, RK_S32 for ctx->acc_inter_bits_in_fps = 0; ctx->acc_intra_bits_in_fps = 0; } - + ctx->quality = cfg->quality; cfg->change = 0; return MPP_OK; @@ -460,18 +460,34 @@ MPP_RET mpp_rc_bits_allocation(MppRateControl *ctx, RcSyntax *rc_syn) mpp_rc_dbg_rc("RC: rc ctx %p inter pid diff %d target %d\n", ctx, diff_bit, ctx->bits_target); - if (ctx->pid_inter.p > ctx->bits_per_inter * 1 / 2) { - ctx->prev_aq_prop_offset -= 4; - } else if (ctx->pid_inter.p > ctx->bits_per_inter * 1 / 3) { - ctx->prev_aq_prop_offset -= 3; - } else if (ctx->pid_inter.p > ctx->bits_per_inter * 1 / 6) { - ctx->prev_aq_prop_offset -= 2; - } else if (ctx->pid_inter.p > ctx->bits_per_inter * 1 / 10) { - ctx->prev_aq_prop_offset -= 1; - } - - if (ctx->bits_target > ctx->bits_per_inter * 11 / 12 && ctx->prev_aq_prop_offset < 0) { - ctx->prev_aq_prop_offset += 1; + if (ctx->quality != MPP_ENC_RC_QUALITY_AQ_ONLY) { + if (ctx->pid_inter.p > ctx->bits_per_inter * 1 / 2) { + ctx->prev_aq_prop_offset -= 4; + } else if (ctx->pid_inter.p > ctx->bits_per_inter * 1 / 3) { + ctx->prev_aq_prop_offset -= 3; + } else if (ctx->pid_inter.p > ctx->bits_per_inter * 1 / 6) { + ctx->prev_aq_prop_offset -= 2; + } else if (ctx->pid_inter.p > ctx->bits_per_inter * 1 / 10) { + ctx->prev_aq_prop_offset -= 1; + } + if (ctx->bits_target > (ctx->bits_per_inter * 11 / 12) && ctx->prev_aq_prop_offset < 0) { + ctx->prev_aq_prop_offset += 1; + } + } else { + if (ctx->pid_inter.p > ctx->bits_per_inter) { + ctx->prev_aq_prop_offset -= 4; + } else if (ctx->pid_inter.p > ctx->bits_per_inter * 2 / 3) { + ctx->prev_aq_prop_offset -= 3; + } else if (ctx->pid_inter.p > ctx->bits_per_inter * 1 / 2) { + ctx->prev_aq_prop_offset -= 2; + } else if (ctx->pid_inter.p > ctx->bits_per_inter * 1 / 3) { + ctx->prev_aq_prop_offset -= 1; + } + if (ctx->bits_target > ctx->bits_per_inter * 5 / 4) { + ctx->prev_aq_prop_offset += 2 ; + } else if (ctx->bits_target > ctx->bits_per_inter * 8 / 7) { + ctx->prev_aq_prop_offset += 1; + } } } } @@ -495,8 +511,15 @@ MPP_RET mpp_rc_bits_allocation(MppRateControl *ctx, RcSyntax *rc_syn) mpp_rc_dbg_rc("after adjustment, target bits %d\n", ctx->bits_target); } } - ctx->prev_aq_prop_offset = mpp_clip(ctx->prev_aq_prop_offset, -8, 0); - rc_syn->aq_prop_offset = ctx->prev_aq_prop_offset; + + if (ctx->quality == MPP_ENC_RC_QUALITY_AQ_ONLY) { + rc_syn->aq_prop_offset = ctx->prev_aq_prop_offset; + ctx->prev_aq_prop_offset = 0; + } else { + ctx->prev_aq_prop_offset = mpp_clip(ctx->prev_aq_prop_offset, -8, 0); + rc_syn->aq_prop_offset = ctx->prev_aq_prop_offset; + } + rc_syn->bit_target = ctx->bits_target; /* step 2: calc min and max bits */ diff --git a/mpp/hal/common/h264/hal_h264e_com.h b/mpp/hal/common/h264/hal_h264e_com.h index 0fb88de8..8ce7c1c5 100644 --- a/mpp/hal/common/h264/hal_h264e_com.h +++ b/mpp/hal/common/h264/hal_h264e_com.h @@ -161,7 +161,8 @@ extern RK_U32 h264e_hal_log_mode; #define H264E_MB_RC_MORE_BITRATE 3 #define H264E_MB_RC_ONLY_BITRATE 4 #define H264E_MB_RC_WIDE_RANGE 5 -#define H264E_MB_RC_M_NUM 6 +#define H264E_MB_RC_ONLY_AQ 6 +#define H264E_MB_RC_M_NUM 7 typedef enum H264eRkvCsp_e { H264E_RKV_CSP_BGRA8888, // 0 diff --git a/mpp/hal/rkenc/h264e/hal_h264e_rkv.c b/mpp/hal/rkenc/h264e/hal_h264e_rkv.c index 6aa3bfe0..8e732cd0 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_rkv.c +++ b/mpp/hal/rkenc/h264e/hal_h264e_rkv.c @@ -52,8 +52,10 @@ static H264eRkvMbRcMcfg mb_rc_m_cfg[H264E_MB_RC_M_NUM] = { {8, 2, 1, 10}, // mode = 3 {8, 1.8, 1, 10}, // mode = 4 {0, 0, 1, 15}, // mode = 5 + {16, 2.8, 1, 20}, // mode = 6 }; + static H264eRkvMbRcQRcfg mb_rc_qr_cfg[9] = { /*qp min offset to qp hdr, qp_range */ {8, 0, 10}, //qp 0 - 5 @@ -500,7 +502,9 @@ static void h264e_rkv_set_mb_rc(H264eHalContext *ctx) if (rc->rc_mode == MPP_ENC_RC_MODE_VBR) { m = H264E_MB_RC_ONLY_QUALITY; q = rc->quality; - if (q != MPP_ENC_RC_QUALITY_CQP) { + if (q == MPP_ENC_RC_QUALITY_AQ_ONLY) { + m = H264E_MB_RC_ONLY_AQ; + } else if (q != MPP_ENC_RC_QUALITY_CQP) { /* better quality for intra frame */ if (hw->frame_type == H264E_RKV_FRAME_I) q++; @@ -544,7 +548,17 @@ static MPP_RET h264e_rkv_set_rc_regs(H264eHalContext *ctx, H264eRkvRegSet *regs, /* (VBR) if focus on quality, qp range is limited more precisely */ if (rc->rc_mode == MPP_ENC_RC_MODE_VBR) { - if (rc->quality == MPP_ENC_RC_QUALITY_CQP) { + if (rc->quality == MPP_ENC_RC_QUALITY_AQ_ONLY) { + m_cfg = mb_rc_m_cfg[mb_rc->mode]; + syn->qp = ctx->hw_cfg.qp_prev; + if (rc_syn->aq_prop_offset) { + syn->qp -= rc_syn->aq_prop_offset; + syn->qp = mpp_clip(syn->qp, syn->qp_min, 33); + if (syn->qp == 33) { + syn->qp_min = 24; + } + } + } else if (rc->quality == MPP_ENC_RC_QUALITY_CQP) { syn->qp_min = syn->qp; syn->qp_max = syn->qp; } else { @@ -625,7 +639,6 @@ static MPP_RET h264e_rkv_set_rc_regs(H264eHalContext *ctx, H264eRkvRegSet *regs, regs->swreg53.qp_adjust6 = 3; regs->swreg53.qp_adjust7 = 4; regs->swreg53.qp_adjust8 = 8; - } regs->swreg62.sli_beta_ofst = 0; regs->swreg62.sli_alph_ofst = 0; @@ -1073,16 +1086,6 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task) return MPP_ERR_MALLOC; } } - if (ctx->sei_mode != MPP_ENC_SEI_MODE_DISABLE) { - extra_info->nal_num = 0; - h264e_rkv_stream_reset(&extra_info->stream); - h264e_rkv_nal_start(extra_info, H264E_NAL_SEI, H264E_NAL_PRIORITY_DISPOSABLE); - h264e_rkv_sei_encode(ctx, rc_syn); - h264e_rkv_nal_end(extra_info); -#ifdef SEI_ADD_NAL_HEADER - h264e_rkv_encapsulate_nals(extra_info); -#endif - } if (ctx->enc_mode == 2 || ctx->enc_mode == 3) { //link table mode RK_U32 idx = ctx->frame_cnt_gen_ready; @@ -1291,6 +1294,17 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task) h264e_rkv_set_rc_regs(ctx, regs, syn, rc_syn); + if (ctx->sei_mode != MPP_ENC_SEI_MODE_DISABLE) { + extra_info->nal_num = 0; + h264e_rkv_stream_reset(&extra_info->stream); + h264e_rkv_nal_start(extra_info, H264E_NAL_SEI, H264E_NAL_PRIORITY_DISPOSABLE); + h264e_rkv_sei_encode(ctx, rc_syn); + h264e_rkv_nal_end(extra_info); +#ifdef SEI_ADD_NAL_HEADER + h264e_rkv_encapsulate_nals(extra_info); +#endif + } + regs->swreg56.rect_size = (sps->i_profile_idc == H264_PROFILE_BASELINE && sps->i_level_idc <= 30); regs->swreg56.inter_4x4 = 1; @@ -1756,8 +1770,11 @@ MPP_RET hal_h264e_rkv_wait(void *hal, HalTaskInfo *task) result.bits * 1024 / avg_sse); mpp_quadreg_update(ctx->inter_qs, wlen); } - - hw_cfg->qp_prev = avg_qp; + if (rc->quality == MPP_ENC_RC_QUALITY_AQ_ONLY) { + hw_cfg->qp_prev = hw_cfg->qp; + } else { + hw_cfg->qp_prev = avg_qp; + } if (syn->type == INTER_P_FRAME || syn->gop_mode == MPP_GOP_ALL_INTRA) { mpp_data_update(ctx->qp_p, avg_qp);