mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-05 09:06:50 +08:00
[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:
@@ -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;
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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,6 +460,7 @@ 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->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) {
|
||||
@@ -469,10 +470,25 @@ MPP_RET mpp_rc_bits_allocation(MppRateControl *ctx, RcSyntax *rc_syn)
|
||||
} 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;
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
Reference in New Issue
Block a user