mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-05 17:16: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_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;
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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
|
||||||
|
@@ -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);
|
||||||
|
Reference in New Issue
Block a user