[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 <sayon.chen@rock-chips.com>
This commit is contained in:
sayon.chen
2017-11-30 15:11:24 +08:00
committed by Herman Chen
parent 84947e3998
commit 6c74d876a3
5 changed files with 74 additions and 31 deletions

View File

@@ -65,6 +65,7 @@ typedef enum MppEncRcQuality_t {
MPP_ENC_RC_QUALITY_BETTER, MPP_ENC_RC_QUALITY_BETTER,
MPP_ENC_RC_QUALITY_BEST, MPP_ENC_RC_QUALITY_BEST,
MPP_ENC_RC_QUALITY_CQP, MPP_ENC_RC_QUALITY_CQP,
MPP_ENC_RC_QUALITY_AQ_ONLY,
MPP_ENC_RC_QUALITY_BUTT MPP_ENC_RC_QUALITY_BUTT
} MppEncRcQuality; } MppEncRcQuality;

View File

@@ -193,6 +193,7 @@ typedef struct MppRateControl_s {
RK_U32 frm_cnt; RK_U32 frm_cnt;
RK_S32 real_bps; RK_S32 real_bps;
RK_S32 prev_aq_prop_offset; RK_S32 prev_aq_prop_offset;
RK_S32 quality;
} MppRateControl; } MppRateControl;

View File

@@ -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_inter_bits_in_fps = 0;
ctx->acc_intra_bits_in_fps = 0; ctx->acc_intra_bits_in_fps = 0;
} }
ctx->quality = cfg->quality;
cfg->change = 0; cfg->change = 0;
return MPP_OK; 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", mpp_rc_dbg_rc("RC: rc ctx %p inter pid diff %d target %d\n",
ctx, diff_bit, ctx->bits_target); ctx, diff_bit, ctx->bits_target);
if (ctx->pid_inter.p > ctx->bits_per_inter * 1 / 2) { if (ctx->quality != MPP_ENC_RC_QUALITY_AQ_ONLY) {
ctx->prev_aq_prop_offset -= 4; if (ctx->pid_inter.p > ctx->bits_per_inter * 1 / 2) {
} else if (ctx->pid_inter.p > ctx->bits_per_inter * 1 / 3) { ctx->prev_aq_prop_offset -= 4;
ctx->prev_aq_prop_offset -= 3; } else if (ctx->pid_inter.p > ctx->bits_per_inter * 1 / 3) {
} else if (ctx->pid_inter.p > ctx->bits_per_inter * 1 / 6) { ctx->prev_aq_prop_offset -= 3;
ctx->prev_aq_prop_offset -= 2; } else if (ctx->pid_inter.p > ctx->bits_per_inter * 1 / 6) {
} else if (ctx->pid_inter.p > ctx->bits_per_inter * 1 / 10) { ctx->prev_aq_prop_offset -= 2;
ctx->prev_aq_prop_offset -= 1; } 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) { if (ctx->bits_target > (ctx->bits_per_inter * 11 / 12) && ctx->prev_aq_prop_offset < 0) {
ctx->prev_aq_prop_offset += 1; 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); 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; rc_syn->bit_target = ctx->bits_target;
/* step 2: calc min and max bits */ /* step 2: calc min and max bits */

View File

@@ -161,7 +161,8 @@ extern RK_U32 h264e_hal_log_mode;
#define H264E_MB_RC_MORE_BITRATE 3 #define H264E_MB_RC_MORE_BITRATE 3
#define H264E_MB_RC_ONLY_BITRATE 4 #define H264E_MB_RC_ONLY_BITRATE 4
#define H264E_MB_RC_WIDE_RANGE 5 #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 { typedef enum H264eRkvCsp_e {
H264E_RKV_CSP_BGRA8888, // 0 H264E_RKV_CSP_BGRA8888, // 0

View File

@@ -52,8 +52,10 @@ static H264eRkvMbRcMcfg mb_rc_m_cfg[H264E_MB_RC_M_NUM] = {
{8, 2, 1, 10}, // mode = 3 {8, 2, 1, 10}, // mode = 3
{8, 1.8, 1, 10}, // mode = 4 {8, 1.8, 1, 10}, // mode = 4
{0, 0, 1, 15}, // mode = 5 {0, 0, 1, 15}, // mode = 5
{16, 2.8, 1, 20}, // mode = 6
}; };
static H264eRkvMbRcQRcfg mb_rc_qr_cfg[9] = { static H264eRkvMbRcQRcfg mb_rc_qr_cfg[9] = {
/*qp min offset to qp hdr, qp_range */ /*qp min offset to qp hdr, qp_range */
{8, 0, 10}, //qp 0 - 5 {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) { if (rc->rc_mode == MPP_ENC_RC_MODE_VBR) {
m = H264E_MB_RC_ONLY_QUALITY; m = H264E_MB_RC_ONLY_QUALITY;
q = rc->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 */ /* better quality for intra frame */
if (hw->frame_type == H264E_RKV_FRAME_I) if (hw->frame_type == H264E_RKV_FRAME_I)
q++; 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 */ /* (VBR) if focus on quality, qp range is limited more precisely */
if (rc->rc_mode == MPP_ENC_RC_MODE_VBR) { 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_min = syn->qp;
syn->qp_max = syn->qp; syn->qp_max = syn->qp;
} else { } 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_adjust6 = 3;
regs->swreg53.qp_adjust7 = 4; regs->swreg53.qp_adjust7 = 4;
regs->swreg53.qp_adjust8 = 8; regs->swreg53.qp_adjust8 = 8;
} }
regs->swreg62.sli_beta_ofst = 0; regs->swreg62.sli_beta_ofst = 0;
regs->swreg62.sli_alph_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; 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 if (ctx->enc_mode == 2 || ctx->enc_mode == 3) { //link table mode
RK_U32 idx = ctx->frame_cnt_gen_ready; 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); 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 regs->swreg56.rect_size = (sps->i_profile_idc == H264_PROFILE_BASELINE
&& sps->i_level_idc <= 30); && sps->i_level_idc <= 30);
regs->swreg56.inter_4x4 = 1; regs->swreg56.inter_4x4 = 1;
@@ -1756,8 +1770,11 @@ MPP_RET hal_h264e_rkv_wait(void *hal, HalTaskInfo *task)
result.bits * 1024 / avg_sse); result.bits * 1024 / avg_sse);
mpp_quadreg_update(ctx->inter_qs, wlen); mpp_quadreg_update(ctx->inter_qs, wlen);
} }
if (rc->quality == MPP_ENC_RC_QUALITY_AQ_ONLY) {
hw_cfg->qp_prev = avg_qp; 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) { if (syn->type == INTER_P_FRAME || syn->gop_mode == MPP_GOP_ALL_INTRA) {
mpp_data_update(ctx->qp_p, avg_qp); mpp_data_update(ctx->qp_p, avg_qp);