mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-06 09:36:49 +08:00
[rkvenc] modfiy ratecontrol to be more smooth
1. use max min qp to limit qp range 2. open aq mode used adaptive aq prop according inter.p 3. open frame ratecontrol on re-encoding 4. modify bits_per_intra equal ctx->bits_per_pic * 3 5. limit target_bit larger then zero Change-Id: I71c5b2747ba4e89b5121093a7b110a2a8af20e02 Signed-off-by: sayon.chen <sayon.chen@rock-chips.com>
This commit is contained in:
@@ -165,6 +165,12 @@ MPP_RET h264e_encode(void *ctx, HalEncTask *task)
|
||||
p->idr_request--;
|
||||
|
||||
mpp_rc_bits_allocation(p->rc, rc_syn);
|
||||
if (rc_syn->bit_target <= 0) {
|
||||
int mb_width = ((cfg->prep.width + 15) & (~15)) >> 4;
|
||||
int mb_height = ((cfg->prep.height + 15) & (~15)) >> 4;
|
||||
/* When there is no bit to allocate set bit_target as total mb count */
|
||||
rc_syn->bit_target = mb_width * mb_height;
|
||||
}
|
||||
mpp_rc_record_param(&p->rc_list, p->rc, rc_syn);
|
||||
|
||||
task->syntax.data = &p->syntax;
|
||||
|
@@ -192,6 +192,8 @@ typedef struct MppRateControl_s {
|
||||
/* start from ONE */
|
||||
RK_U32 frm_cnt;
|
||||
RK_S32 real_bps;
|
||||
RK_S32 prev_aq_prop_offset;
|
||||
|
||||
} MppRateControl;
|
||||
|
||||
/*
|
||||
@@ -206,6 +208,7 @@ typedef struct RcSyntax_s {
|
||||
RK_S32 bit_target;
|
||||
RK_S32 bit_max;
|
||||
RK_S32 bit_min;
|
||||
RK_S32 aq_prop_offset;
|
||||
|
||||
/* head node of rc parameter list */
|
||||
struct list_head *rc_head;
|
||||
|
@@ -369,7 +369,7 @@ MPP_RET mpp_rc_update_user_cfg(MppRateControl *ctx, MppEncRcCfg *cfg, RK_S32 for
|
||||
mpp_env_get_u32("intra_rate", &intra_to_inter_rate, 3);
|
||||
ctx->intra_to_inter_rate = intra_to_inter_rate;
|
||||
ctx->bits_per_inter = ctx->bits_per_pic;
|
||||
ctx->bits_per_intra = ctx->bps_target * 2 / 3;
|
||||
ctx->bits_per_intra = ctx->bits_per_pic * 3;
|
||||
ctx->bits_per_inter -= ctx->bits_per_intra / (ctx->fps_out - 1);
|
||||
}
|
||||
}
|
||||
@@ -459,6 +459,20 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
@@ -481,7 +495,8 @@ 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;
|
||||
rc_syn->bit_target = ctx->bits_target;
|
||||
|
||||
/* step 2: calc min and max bits */
|
||||
|
@@ -79,11 +79,24 @@ static H264eRkvMbRcMcfg mb_rc_m_cfg[H264E_MB_RC_M_NUM] = {
|
||||
{16, 1, 0, 1}, // mode = 0
|
||||
{8, 1, 1, 2}, // mode = 1
|
||||
{4, 1, 1, 4}, // mode = 2
|
||||
{2, 1, 1, 4}, // mode = 3
|
||||
{0, 1, 1, 2}, // mode = 4
|
||||
{8, 2, 1, 10}, // mode = 3
|
||||
{8, 1.8, 1, 10}, // mode = 4
|
||||
{0, 0, 1, 15}, // mode = 5
|
||||
};
|
||||
|
||||
static H264eRkvMbRcQRcfg mb_rc_qr_cfg[9] = {
|
||||
/*qp min offset to qp hdr, qp_range */
|
||||
{8, 0, 10}, //qp 0 - 5
|
||||
{8, 0, 10}, //qp 6 - 11
|
||||
{6, 0, 8 }, //qp 12 - 17
|
||||
{6, 0, 8 }, //qp 18 - 23
|
||||
{4, 0, 6 }, //qp 24 - 29
|
||||
{4, 0, 5 }, //qp 30 - 35
|
||||
{0, 4, 6 }, //qp 36 - 41
|
||||
{0, 2, 8 }, //qp 42 - 45
|
||||
{0, 2, 5 }, //qp 46 - 51
|
||||
};
|
||||
|
||||
static H264eRkvMbRcQcfg mb_rc_q_cfg[MPP_ENC_RC_QUALITY_BUTT] = {
|
||||
/* qp_min, qp_max */
|
||||
{31, 51}, // worst
|
||||
@@ -1848,6 +1861,31 @@ static MPP_RET h264e_rkv_set_rc_regs(H264eHalContext *ctx, H264eRkvRegSet *regs,
|
||||
syn->qp_min = q_cfg.qp_min;
|
||||
syn->qp_max = q_cfg.qp_max;
|
||||
}
|
||||
} else {
|
||||
if (ctx->frame_cnt > 1 && ctx->hw_cfg.frame_type != H264E_RKV_FRAME_I) {
|
||||
H264eRkvMbRcQRcfg qr_cfg = mb_rc_qr_cfg[syn->qp / 6];
|
||||
if (syn->qp > 45) {
|
||||
qr_cfg = mb_rc_qr_cfg[48 / 6];
|
||||
}
|
||||
if (qr_cfg.qp_min_offset)
|
||||
syn->qp_min = (RK_U32)MPP_MAX(syn->qp_min, (RK_S32)(syn->qp - qr_cfg.qp_min_offset));
|
||||
else
|
||||
syn->qp_min = (RK_U32)MPP_MAX(syn->qp_min, (RK_S32)(syn->qp - qr_cfg.qp_range));
|
||||
|
||||
if (qr_cfg.qp_max_offset)
|
||||
syn->qp_max = (RK_U32)MPP_MIN(syn->qp_max, (RK_S32)(syn->qp + qr_cfg.qp_max_offset));
|
||||
else
|
||||
syn->qp_max = (RK_U32)MPP_MIN(syn->qp_max, (RK_S32)(syn->qp + qr_cfg.qp_range));
|
||||
|
||||
m_cfg.qp_range = qr_cfg.qp_range;
|
||||
ctx->qp_scale = 1;
|
||||
if (rc_syn->aq_prop_offset) {
|
||||
m_cfg.aq_prop = mpp_clip((m_cfg.aq_prop + rc_syn->aq_prop_offset), 0, m_cfg.aq_prop);
|
||||
}
|
||||
} else if (ctx->hw_cfg.frame_type == H264E_RKV_FRAME_I) {
|
||||
syn->qp_min = (RK_U32)MPP_MAX(10, syn->qp_min);
|
||||
syn->qp_max = (RK_U32)MPP_MIN(37, syn->qp_max);
|
||||
}
|
||||
}
|
||||
|
||||
regs->swreg10.pic_qp = syn->qp;
|
||||
@@ -1870,11 +1908,11 @@ static MPP_RET h264e_rkv_set_rc_regs(H264eHalContext *ctx, H264eRkvRegSet *regs,
|
||||
if (regs->swreg54.rc_max_qp < regs->swreg54.rc_min_qp)
|
||||
MPP_SWAP(RK_U32, regs->swreg54.rc_max_qp, regs->swreg54.rc_min_qp);
|
||||
}
|
||||
|
||||
if (regs->swreg46.rc_mode) { //checkpoint rc open
|
||||
RK_U32 target = mb_target_size * m_cfg.mb_num;
|
||||
|
||||
regs->swreg54.rc_qp_range = m_cfg.qp_range * ctx->qp_scale;
|
||||
|
||||
regs->swreg46.rc_ctu_num = m_cfg.mb_num;
|
||||
regs->swreg55.ctu_ebits = mb_target_size_mul_16;
|
||||
|
||||
@@ -1882,21 +1920,21 @@ static MPP_RET h264e_rkv_set_rc_regs(H264eHalContext *ctx, H264eRkvRegSet *regs,
|
||||
regs->swreg47.bits_error1 = (RK_S32)((pow(0.88, 3) - 1) * (double)target);
|
||||
regs->swreg48.bits_error2 = (RK_S32)((pow(0.88, 2) - 1) * (double)target);
|
||||
regs->swreg48.bits_error3 = (RK_S32)((pow(0.88, 1) - 1) * (double)target);
|
||||
regs->swreg49.bits_error4 = (RK_S32)((pow(1.12, 1) - 1) * (double)target);
|
||||
regs->swreg49.bits_error5 = (RK_S32)((pow(1.12, 2) - 1) * (double)target);
|
||||
regs->swreg50.bits_error6 = (RK_S32)((pow(1.12, 3) - 1) * (double)target);
|
||||
regs->swreg50.bits_error7 = (RK_S32)((pow(1.12, 4) - 1) * (double)target);
|
||||
regs->swreg51.bits_error8 = (RK_S32)((pow(1.12, 5) - 1) * (double)target);
|
||||
regs->swreg49.bits_error4 = (RK_S32)((pow(1.12, 2) - 1) * (double)target);
|
||||
regs->swreg49.bits_error5 = (RK_S32)((pow(1.12, 3) - 1) * (double)target);
|
||||
regs->swreg50.bits_error6 = (RK_S32)((pow(1.12, 4) - 1) * (double)target);
|
||||
regs->swreg50.bits_error7 = (RK_S32)((pow(2, 4) - 1) * (double)target);
|
||||
regs->swreg51.bits_error8 = (RK_S32)((pow(2, 5) - 1) * (double)target);
|
||||
|
||||
regs->swreg52.qp_adjust0 = -4;
|
||||
regs->swreg52.qp_adjust1 = -3;
|
||||
regs->swreg52.qp_adjust2 = -2;
|
||||
regs->swreg52.qp_adjust3 = -1;
|
||||
regs->swreg52.qp_adjust4 = 0;
|
||||
regs->swreg52.qp_adjust5 = 1;
|
||||
regs->swreg53.qp_adjust6 = 2;
|
||||
regs->swreg53.qp_adjust7 = 3;
|
||||
regs->swreg53.qp_adjust8 = 4;
|
||||
regs->swreg52.qp_adjust4 = 1;
|
||||
regs->swreg52.qp_adjust5 = 2;
|
||||
regs->swreg53.qp_adjust6 = 3;
|
||||
regs->swreg53.qp_adjust7 = 4;
|
||||
regs->swreg53.qp_adjust8 = 8;
|
||||
|
||||
}
|
||||
regs->swreg62.sli_beta_ofst = 0;
|
||||
@@ -2256,12 +2294,10 @@ h264e_rkv_update_hw_cfg(H264eHalContext *ctx, HalEncTask *task,
|
||||
|
||||
/* limit QP by qp_step */
|
||||
if (ctx->frame_cnt > 1) {
|
||||
hw_cfg->qp_min = mpp_clip(hw_cfg->qp_min,
|
||||
hw_cfg->qp_prev - codec->qp_max_step,
|
||||
hw_cfg->qp_prev - codec->qp_max_step / 2);
|
||||
hw_cfg->qp_max = mpp_clip(hw_cfg->qp_max,
|
||||
hw_cfg->qp_prev + codec->qp_max_step / 2,
|
||||
hw_cfg->qp_prev + codec->qp_max_step);
|
||||
|
||||
hw_cfg->qp_min = codec->qp_min;
|
||||
hw_cfg->qp_max = codec->qp_max;
|
||||
|
||||
hw_cfg->qp = mpp_clip(hw_cfg->qp,
|
||||
hw_cfg->qp_prev - codec->qp_max_step,
|
||||
hw_cfg->qp_prev + codec->qp_max_step);
|
||||
@@ -2365,6 +2401,7 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task)
|
||||
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);
|
||||
if (rc_syn->bit_target > extra_info->nal[0].i_payload)
|
||||
rc_syn->bit_target -= extra_info->nal[0].i_payload; // take off SEI size
|
||||
}
|
||||
|
||||
@@ -2595,7 +2632,6 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task)
|
||||
regs->swreg56.vlc_lmt = (sps->i_profile_idc < H264_PROFILE_HIGH
|
||||
&& !pps->b_cabac);
|
||||
regs->swreg56.rdo_mark = 0;
|
||||
|
||||
{
|
||||
RK_U32 i_nal_type = 0, i_nal_ref_idc = 0;
|
||||
|
||||
@@ -2962,12 +2998,12 @@ MPP_RET hal_h264e_rkv_wait(void *hal, HalTaskInfo *task)
|
||||
h264e_hal_dbg(H264E_DBG_DETAIL,
|
||||
"re-encode for first frame overflow ...\n");
|
||||
fb->qp_sum = new_qp * num_mb;
|
||||
h264e_rkv_resend(ctx, 0);
|
||||
h264e_rkv_resend(ctx, 1);
|
||||
} else {
|
||||
/* The first and second frame, that is the first I and P frame,
|
||||
* is re-encoded for getting appropriate QP for target bits.
|
||||
*/
|
||||
h264e_rkv_resend(ctx, 0);
|
||||
h264e_rkv_resend(ctx, 1);
|
||||
}
|
||||
h264e_rkv_set_feedback(ctx, reg_out, enc_task);
|
||||
} else if ((RK_S32)frame_cnt < rc->fps_out_num / rc->fps_out_denorm &&
|
||||
|
@@ -892,9 +892,9 @@ typedef struct H264eRkvIoctlOutput_t {
|
||||
|
||||
/* mode cfg */
|
||||
typedef struct H264eRkvMbRcMcfg_t {
|
||||
RK_U32 aq_prop; //0~16, 0:only enable aq, 16:only enable checkpoint
|
||||
RK_S32 aq_prop; //0~16, 0:only enable aq, 16:only enable checkpoint
|
||||
|
||||
RK_U32 aq_strength; //0~3
|
||||
double aq_strength; //0~3
|
||||
|
||||
RK_U32 mb_num;
|
||||
RK_U32 qp_range; //0~15
|
||||
@@ -906,6 +906,12 @@ typedef struct H264eRkvMbRcQcfg_t {
|
||||
RK_U32 qp_max;
|
||||
} H264eRkvMbRcQcfg;
|
||||
|
||||
typedef struct H264eRkvMbRcQRcfg_t {
|
||||
RK_U32 qp_min_offset;
|
||||
RK_U32 qp_max_offset;
|
||||
RK_U32 qp_range;
|
||||
} H264eRkvMbRcQRcfg;
|
||||
|
||||
#define RK_H264E_NUM_REGS ((RK_S32)(sizeof(H264eRkvRegSet)/4))
|
||||
|
||||
MPP_RET hal_h264e_rkv_init (void *hal, MppHalCfg *cfg);
|
||||
|
Reference in New Issue
Block a user