[rc_v2]: Reorganize rc_mode_v2 code

ratio_calc used Register function in mode init according rc_mode

Change-Id: I0317ecc004a2c882e005cf791207c6a5a7e50598
Signed-off-by: sayon.chen <sayon.chen@rock-chips.com>
This commit is contained in:
sayon.chen
2020-09-24 10:29:43 +08:00
committed by Herman Chen
parent f8b77d6aa2
commit d8a5fb18b7
2 changed files with 269 additions and 259 deletions

View File

@@ -93,6 +93,9 @@ typedef struct RcModelV2Ctx_t {
RK_U32 drop_cnt;
RK_S32 on_drop;
RK_S32 on_pskip;
MPP_RET (*calc_ratio)(void* ctx, EncRcTaskInfo *cfg);
MPP_RET (*re_calc_ratio)(void* ctx, EncRcTaskInfo *cfg);
} RcModelV2Ctx;
@@ -108,12 +111,6 @@ MPP_RET bits_model_alloc(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg, RK_S64 total_bit
MPP_RET bits_model_update(RcModelV2Ctx *ctx, RK_S32 real_bit, RK_U32 madi);
MPP_RET calc_next_i_ratio(RcModelV2Ctx *ctx);
MPP_RET calc_cbr_ratio(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg);
MPP_RET reenc_calc_cbr_ratio(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg);
MPP_RET calc_vbr_ratio(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg);
MPP_RET reenc_calc_vbr_ratio(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg);
MPP_RET calc_avbr_ratio(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg);
MPP_RET check_re_enc(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg);
#ifdef __cplusplus

View File

@@ -69,7 +69,7 @@ RK_U32 bit2percent[100] = {
32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
};
MPP_RET bits_model_deinit(RcModelV2Ctx *ctx)
MPP_RET bits_model_param_deinit(RcModelV2Ctx *ctx)
{
rc_dbg_func("enter %p\n", ctx);
@@ -123,6 +123,83 @@ MPP_RET bits_model_deinit(RcModelV2Ctx *ctx)
return MPP_OK;
}
MPP_RET bits_model_param_init(RcModelV2Ctx *ctx)
{
RK_S32 gop_len = ctx->usr_cfg.igop;
RcFpsCfg *fps = &ctx->usr_cfg.fps;
RK_U32 stat_len = fps->fps_out_num * ctx->usr_cfg.stat_times / fps->fps_out_denorm;
bits_model_param_deinit(ctx);
mpp_data_init_v2(&ctx->i_bit, I_WINDOW_LEN);
if (ctx->i_bit == NULL) {
mpp_err("i_bit init fail");
return MPP_ERR_MALLOC;
}
mpp_data_init_v2(&ctx->vi_bit, I_WINDOW_LEN);
if (ctx->vi_bit == NULL) {
mpp_err("vi_bit init fail");
return MPP_ERR_MALLOC;
}
mpp_data_init_v2(&ctx->p_bit, P_WINDOW1_LEN);
if (ctx->p_bit == NULL) {
mpp_err("p_bit init fail");
return MPP_ERR_MALLOC;
}
mpp_data_init_v2(&ctx->pre_p_bit, P_WINDOW2_LEN);
if (ctx->pre_p_bit == NULL) {
mpp_err("pre_p_bit init fail");
return MPP_ERR_MALLOC;
}
mpp_data_init_v2(&ctx->pre_i_bit, I_WINDOW_LEN);
if (ctx->pre_i_bit == NULL) {
mpp_err("pre_i_bit init fail");
return MPP_ERR_MALLOC;
}
mpp_data_init_v2(&ctx->pre_i_mean_qp, I_WINDOW_LEN);
if (ctx->pre_i_mean_qp == NULL) {
mpp_err("pre_i_mean_qp init fail");
return MPP_ERR_MALLOC;
}
mpp_data_reset_v2(ctx->pre_i_mean_qp, -1);
mpp_data_init_v2(&ctx->madi, P_WINDOW2_LEN);
if (ctx->madi == NULL) {
mpp_err("madi init fail");
return MPP_ERR_MALLOC;
}
mpp_data_init_v2(&ctx->madp, P_WINDOW2_LEN);
if (ctx->madp == NULL) {
mpp_err("madp init fail");
return MPP_ERR_MALLOC;
}
mpp_data_init_v2(&ctx->stat_rate, fps->fps_out_num);
if (ctx->stat_rate == NULL) {
mpp_err("stat_rate init fail fps_out_num %d", fps->fps_out_num);
return MPP_ERR_MALLOC;
}
mpp_data_init_v2(&ctx->stat_bits, stat_len);
if (ctx->stat_bits == NULL) {
mpp_err("stat_bits init fail stat_len %d", stat_len);
return MPP_ERR_MALLOC;
}
mpp_data_reset_v2(ctx->stat_rate, 0);
mpp_data_init_v2(&ctx->gop_bits, gop_len);
if (ctx->gop_bits == NULL) {
mpp_err("gop_bits init fail gop_len %d", gop_len);
return MPP_ERR_MALLOC;
}
mpp_data_reset_v2(ctx->gop_bits, 0);
mpp_data_reset_v2(ctx->stat_bits, ctx->bit_per_frame);
return MPP_OK;
}
void bits_frm_init(RcModelV2Ctx *ctx)
{
RcCfg *usr_cfg = &ctx->usr_cfg;
@@ -171,149 +248,6 @@ void bits_frm_init(RcModelV2Ctx *ctx)
rc_dbg_func("leave %p\n", ctx);
}
MPP_RET bits_model_init(RcModelV2Ctx *ctx)
{
RcCfg *usr_cfg = &ctx->usr_cfg;
RK_S32 gop_len = usr_cfg->igop;
RcFpsCfg *fps = &usr_cfg->fps;
RK_S64 gop_bits = 0;
RK_U32 stat_times = usr_cfg->stat_times;
RK_U32 stat_len;
RK_U32 target_bps;
rc_dbg_func("enter %p\n", ctx);
if (stat_times == 0) {
stat_times = 3;
usr_cfg->stat_times = stat_times;
}
if (usr_cfg->max_i_bit_prop <= 0) {
usr_cfg->max_i_bit_prop = 30;
} else if (usr_cfg->max_i_bit_prop > 100) {
usr_cfg->max_i_bit_prop = 100;
}
rc_dbg_rc("max_i_bit_prop %d", usr_cfg->max_i_bit_prop);
if (!gop_len || gop_len > 500) {
mpp_log("infinte gop, set default for rc bit calc\n");
usr_cfg->igop = gop_len = 500;
}
if (!ctx->min_still_percent) {
if (usr_cfg->bps_min && usr_cfg->bps_max) {
ctx->min_still_percent = usr_cfg->bps_min * 100 / usr_cfg->bps_max;
} else {
ctx->min_still_percent = 25;
}
rc_dbg_rc("min_still_percent %d", ctx->min_still_percent);
}
ctx->max_still_qp = 35;
ctx->super_ifrm_bits_thr = -1;
ctx->super_pfrm_bits_thr = -1;
ctx->motion_sensitivity = 90;
ctx->first_frm_flg = 1;
stat_len = fps->fps_out_num * usr_cfg->stat_times / fps->fps_out_denorm;
if ( usr_cfg->mode == RC_FIXQP) {
return MPP_OK;
} else if (usr_cfg->mode == RC_CBR) {
target_bps = usr_cfg->bps_target;
} else {
target_bps = usr_cfg->bps_max;
}
ctx->target_bps = usr_cfg->bps_target;
if (gop_len >= 1)
gop_bits = (RK_S64)gop_len * target_bps * fps->fps_out_denorm;
else
gop_bits = (RK_S64)fps->fps_out_num * target_bps * fps->fps_out_denorm;
ctx->gop_total_bits = gop_bits / fps->fps_out_num;
bits_model_deinit(ctx);
mpp_data_init_v2(&ctx->i_bit, I_WINDOW_LEN);
if (ctx->i_bit == NULL) {
mpp_err("i_bit init fail");
return -1;
}
mpp_data_init_v2(&ctx->vi_bit, I_WINDOW_LEN);
if (ctx->vi_bit == NULL) {
mpp_err("vi_bit init fail");
return -1;
}
mpp_data_init_v2(&ctx->p_bit, P_WINDOW1_LEN);
if (ctx->p_bit == NULL) {
mpp_err("p_bit init fail");
return -1;
}
mpp_data_init_v2(&ctx->pre_p_bit, P_WINDOW2_LEN);
if (ctx->pre_p_bit == NULL) {
mpp_err("pre_p_bit init fail");
return -1;
}
mpp_data_init_v2(&ctx->pre_i_bit, I_WINDOW_LEN);
if (ctx->pre_i_bit == NULL) {
mpp_err("pre_i_bit init fail");
return -1;
}
mpp_data_init_v2(&ctx->pre_i_mean_qp, I_WINDOW_LEN);
if (ctx->pre_i_mean_qp == NULL) {
mpp_err("pre_i_mean_qp init fail");
return -1;
}
mpp_data_reset_v2(ctx->pre_i_mean_qp, -1);
mpp_data_init_v2(&ctx->madi, P_WINDOW2_LEN);
if (ctx->madi == NULL) {
mpp_err("madi init fail");
return -1;
}
mpp_data_init_v2(&ctx->madp, P_WINDOW2_LEN);
if (ctx->madp == NULL) {
mpp_err("madp init fail");
return -1;
}
mpp_data_init_v2(&ctx->stat_rate, fps->fps_out_num);
if (ctx->stat_rate == NULL) {
mpp_err("stat_rate init fail fps_out_num %d", fps->fps_out_num);
return -1;
}
mpp_data_init_v2(&ctx->stat_bits, stat_len);
if (ctx->stat_bits == NULL) {
mpp_err("stat_bits init fail stat_len %d", stat_len);
return -1;
}
mpp_data_reset_v2(ctx->stat_rate, 0);
mpp_data_init_v2(&ctx->gop_bits, gop_len);
if (ctx->gop_bits == NULL) {
mpp_err("gop_bits init fail gop_len %d", gop_len);
return -1;
}
mpp_data_reset_v2(ctx->gop_bits, 0);
ctx->bit_per_frame = target_bps * fps->fps_out_denorm / fps->fps_out_num;
ctx->watl_thrd = 3 * target_bps;
ctx->stat_watl = ctx->watl_thrd >> 3;
ctx->watl_base = ctx->stat_watl;
mpp_data_reset_v2(ctx->stat_bits, ctx->bit_per_frame);
rc_dbg_rc("gop %d total bit %lld per_frame %d statistics time %d second\n",
usr_cfg->igop, ctx->gop_total_bits, ctx->bit_per_frame,
usr_cfg->stat_times);
bits_frm_init(ctx);
rc_dbg_func("leave %p\n", ctx);
return MPP_OK;
}
RK_S32 moving_judge_update(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg)
{
switch (ctx->frame_type) {
@@ -439,11 +373,7 @@ MPP_RET bits_model_alloc(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg, RK_S64 total_bit
} else {
switch (ctx->frame_type) {
case INTRA_FRAME: {
if (usr_cfg->mode == RC_CBR)
i_scale = mpp_clip(i_scale, 16, 800);
else
i_scale = mpp_clip(i_scale, 16, 16000);
i_scale = mpp_clip(i_scale, 16, 16000);
total_bits = total_bits * i_scale;
} break;
@@ -502,28 +432,28 @@ MPP_RET calc_next_i_ratio(RcModelV2Ctx *ctx)
}
MPP_RET calc_cbr_ratio(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg)
MPP_RET calc_cbr_ratio(void *ctx, EncRcTaskInfo *cfg)
{
RK_S32 target_bps = ctx->target_bps;
RK_S32 ins_bps = ctx->ins_bps;
RK_S32 pre_target_bits = ctx->pre_target_bits;
RK_S32 pre_real_bits = ctx->pre_real_bits;
RK_S32 pre_ins_bps = ctx->last_inst_bps;
RcModelV2Ctx *p = (RcModelV2Ctx *)ctx;
RK_S32 target_bps = p->target_bps;
RK_S32 ins_bps = p->ins_bps;
RK_S32 pre_target_bits = p->pre_target_bits;
RK_S32 pre_real_bits = p->pre_real_bits;
RK_S32 pre_ins_bps = p->last_inst_bps;
RK_S32 idx1, idx2;
RK_S32 bit_diff_ratio, ins_ratio, bps_ratio, wl_ratio;
RK_S32 flag = 0;
RK_S32 fluc_l = 3;
rc_dbg_func("enter %p\n", ctx);
rc_dbg_func("enter %p\n", p);
rc_dbg_bps("%10s|%10s|%10s|%10s|%10s|%8s", "r_bits", "t_bits", "ins_bps", "p_ins_bps", "target_bps", "watl");
rc_dbg_bps("%10d %10d %10d %10d %10d %8d", pre_real_bits, pre_target_bits, ins_bps, pre_ins_bps, target_bps, ctx->stat_watl >> 10);
rc_dbg_bps("%10d %10d %10d %10d %10d %8d", pre_real_bits, pre_target_bits, ins_bps, pre_ins_bps, target_bps, p->stat_watl >> 10);
bits_model_alloc(ctx, cfg, ctx->gop_total_bits);
bits_model_alloc(p, cfg, p->gop_total_bits);
mpp_assert(target_bps > 0);
if (pre_target_bits > pre_real_bits)
bit_diff_ratio = 52 * (pre_real_bits - pre_target_bits) / pre_target_bits;
else
@@ -536,7 +466,6 @@ MPP_RET calc_cbr_ratio(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg)
idx2 = mpp_clip(idx2, 0, 64);
ins_ratio = tab_lnx[idx1] - tab_lnx[idx2]; // %3
/*ins_bps is increase and pre_ins > target_bps*15/16 will raise up ins_ratio to decrease bit
*ins_bps is decresase and pre_ins < target_bps*17/16 will decrease ins_ratio to increase bit
*/
@@ -562,41 +491,42 @@ MPP_RET calc_cbr_ratio(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg)
}
bps_ratio = (ins_bps - target_bps) * fluc_l / (target_bps >> 4);
wl_ratio = 4 * (ctx->stat_watl - ctx->watl_base) * fluc_l / ctx->watl_base;
wl_ratio = 4 * (p->stat_watl - p->watl_base) * fluc_l / p->watl_base;
bps_ratio = mpp_clip(bps_ratio, -32, 32);
wl_ratio = mpp_clip(wl_ratio, -16, 32);
ctx->next_ratio = ins_ratio + bps_ratio + wl_ratio;
p->next_ratio = ins_ratio + bps_ratio + wl_ratio;
rc_dbg_qp("%10s|%10s|%10s|%10s|%10s|%10s", "diff_ratio", "ins_ratio", "bps_ratio",
"wl_ratio", "next_ratio", "cur_qp_s");
rc_dbg_qp("%10d %10d %10d %10d %10d|%10d", bit_diff_ratio, ins_ratio - bit_diff_ratio,
bps_ratio, wl_ratio, ctx->next_ratio, ctx->cur_scale_qp);
bps_ratio, wl_ratio, p->next_ratio, p->cur_scale_qp);
rc_dbg_func("leave %p\n", ctx);
rc_dbg_func("leave %p\n", p);
return MPP_OK;
}
MPP_RET reenc_calc_cbr_ratio(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg)
MPP_RET reenc_calc_cbr_ratio(void *ctx, EncRcTaskInfo *cfg)
{
RcCfg *usr_cfg = &ctx->usr_cfg;
RcModelV2Ctx *p = (RcModelV2Ctx *)ctx;
RcCfg *usr_cfg = &p->usr_cfg;
RK_S32 stat_time = usr_cfg->stat_times;
RK_S32 pre_ins_bps = mpp_data_sum_v2(ctx->stat_bits) / stat_time;
RK_S32 ins_bps = (pre_ins_bps * stat_time - ctx->stat_bits->val[0] + cfg->bit_real) / stat_time;
RK_S32 pre_ins_bps = mpp_data_sum_v2(p->stat_bits) / stat_time;
RK_S32 ins_bps = (pre_ins_bps * stat_time - p->stat_bits->val[0] + cfg->bit_real) / stat_time;
RK_S32 real_bit = cfg->bit_real;
RK_S32 target_bit = cfg->bit_target;
RK_S32 target_bps = ctx->target_bps;
RK_S32 target_bps = p->target_bps;
RK_S32 water_level = 0;
RK_S32 idx1, idx2;
RK_S32 bit_diff_ratio, ins_ratio, bps_ratio, wl_ratio;
RK_S32 mb_w = MPP_ALIGN(usr_cfg->width, 16) / 16;
RK_S32 mb_h = MPP_ALIGN(usr_cfg->height, 16) / 16;
rc_dbg_func("enter %p\n", ctx);
rc_dbg_func("enter %p\n", p);
if (real_bit + ctx->stat_watl > ctx->watl_thrd)
water_level = ctx->watl_thrd - ctx->bit_per_frame;
if (real_bit + p->stat_watl > p->watl_thrd)
water_level = p->watl_thrd - p->bit_per_frame;
else
water_level = real_bit + ctx->stat_watl - ctx->bit_per_frame;
water_level = real_bit + p->stat_watl - p->bit_per_frame;
if (water_level < 0) {
water_level = 0;
@@ -615,12 +545,12 @@ MPP_RET reenc_calc_cbr_ratio(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg)
ins_ratio = tab_lnx[idx1] - tab_lnx[idx2];
bps_ratio = 96 * (ins_bps - target_bps) / target_bps;
wl_ratio = 32 * (water_level - ctx->watl_base) / ctx->watl_base;
wl_ratio = 32 * (water_level - p->watl_base) / p->watl_base;
if (pre_ins_bps < ins_bps && target_bps != pre_ins_bps) {
ins_ratio = 6 * ins_ratio;
ins_ratio = mpp_clip(ins_ratio, -192, 256);
} else {
if (ctx->frame_type == INTRA_FRAME) {
if (p->frame_type == INTRA_FRAME) {
ins_ratio = 3 * ins_ratio;
ins_ratio = mpp_clip(ins_ratio, -192, 256);
} else {
@@ -631,37 +561,39 @@ MPP_RET reenc_calc_cbr_ratio(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg)
bit_diff_ratio = mpp_clip(bit_diff_ratio, -128, 256);
bps_ratio = mpp_clip(bps_ratio, -32, 32);
wl_ratio = mpp_clip(wl_ratio, -32, 32);
ctx->next_ratio = bit_diff_ratio + ins_ratio + bps_ratio + wl_ratio;
if (ctx->frame_type == INTRA_FRAME && (cfg->madi > 0)) {
p->next_ratio = bit_diff_ratio + ins_ratio + bps_ratio + wl_ratio;
if (p->frame_type == INTRA_FRAME && (cfg->madi > 0)) {
RK_U32 tar_bpp = target_bit / (mb_w * mb_h);
float lnb_t = log(tar_bpp);
float c = 6.7204, a = -0.1435, b = 0.0438;
float start_qp = (ctx->cur_scale_qp >> 6);
float start_qp = (p->cur_scale_qp >> 6);
int qp_c = ((lnb_t - cfg->madi * b - c) / a + 14);
if (qp_c > start_qp)
ctx->next_ratio = (qp_c << 6) - ctx->cur_scale_qp;
p->next_ratio = (qp_c << 6) - p->cur_scale_qp;
}
rc_dbg_rc("cbr target_bit %d real_bit %d reenc next ratio %d", target_bit, real_bit, ctx->next_ratio);
rc_dbg_func("leave %p\n", ctx);
rc_dbg_rc("cbr target_bit %d real_bit %d reenc next ratio %d", target_bit, real_bit, p->next_ratio);
rc_dbg_func("leave %p\n", p);
return MPP_OK;
}
MPP_RET calc_vbr_ratio(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg)
MPP_RET calc_vbr_ratio(void *ctx, EncRcTaskInfo *cfg)
{
RcCfg *usr_cfg = &ctx->usr_cfg;
RK_S32 bps_change = ctx->target_bps;
RcModelV2Ctx *p = (RcModelV2Ctx *)ctx;
RcCfg *usr_cfg = &p->usr_cfg;
RK_S32 bps_change = p->target_bps;
RK_S32 max_bps_target = usr_cfg->bps_max;
RK_S32 ins_bps = ctx->ins_bps;
RK_S32 pre_target_bits = ctx->pre_target_bits;
RK_S32 pre_real_bits = ctx->pre_real_bits;
RK_S32 pre_ins_bps = ctx->last_inst_bps;
RK_S32 ins_bps = p->ins_bps;
RK_S32 pre_target_bits = p->pre_target_bits;
RK_S32 pre_real_bits = p->pre_real_bits;
RK_S32 pre_ins_bps = p->last_inst_bps;
RK_S32 idx1, idx2;
RK_S32 bit_diff_ratio, ins_ratio, bps_ratio;
RK_S32 flag = 0;
rc_dbg_func("enter %p\n", ctx);
rc_dbg_func("enter %p\n", p);
bits_model_alloc(ctx, cfg, ctx->gop_total_bits);
bits_model_alloc(p, cfg, p->gop_total_bits);
if (pre_target_bits > pre_real_bits)
bit_diff_ratio = 32 * (pre_real_bits - pre_target_bits) / pre_target_bits;
else
@@ -694,33 +626,36 @@ MPP_RET calc_vbr_ratio(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg)
ins_ratio = mpp_clip(ins_ratio, -128, 256);
bps_ratio = 3 * (ins_bps - bps_change) / (max_bps_target >> 4);
bps_ratio = mpp_clip(bps_ratio, -16, 32);
if (ctx->i_scale > 640) {
if (p->i_scale > 640) {
bit_diff_ratio = mpp_clip(bit_diff_ratio, -16, 32);
ins_ratio = mpp_clip(ins_ratio, -16, 32);
}
ctx->next_ratio = bit_diff_ratio + ins_ratio + bps_ratio;
p->next_ratio = bit_diff_ratio + ins_ratio + bps_ratio;
rc_dbg_qp("%10s|%10s|%10s|%10s|%10s", "diff_ratio", "ins_ratio", "bps_ratio", "next_ratio", "cur_qp_s");
rc_dbg_qp("%10d %10d %10d %10d|%10d", bit_diff_ratio, ins_ratio, bps_ratio, ctx->next_ratio, ctx->cur_scale_qp);
rc_dbg_func("leave %p\n", ctx);
rc_dbg_qp("%10d %10d %10d %10d|%10d", bit_diff_ratio, ins_ratio, bps_ratio, p->next_ratio, p->cur_scale_qp);
rc_dbg_func("leave %p\n", p);
return MPP_OK;
}
MPP_RET reenc_calc_vbr_ratio(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg)
MPP_RET reenc_calc_vbr_ratio(void *ctx, EncRcTaskInfo *cfg)
{
RcCfg *usr_cfg = &ctx->usr_cfg;
RcModelV2Ctx *p = (RcModelV2Ctx *)ctx;
RcCfg *usr_cfg = &p->usr_cfg;
RK_S32 stat_time = usr_cfg->stat_times;
RK_S32 pre_ins_bps = mpp_data_sum_v2(ctx->stat_bits) / stat_time;
RK_S32 ins_bps = (pre_ins_bps * stat_time - ctx->stat_bits->val[0] + cfg->bit_real) / stat_time;
RK_S32 bps_change = ctx->target_bps;
RK_S32 pre_ins_bps = mpp_data_sum_v2(p->stat_bits) / stat_time;
RK_S32 ins_bps = (pre_ins_bps * stat_time - p->stat_bits->val[0] + cfg->bit_real) / stat_time;
RK_S32 bps_change = p->target_bps;
RK_S32 max_bps_target = usr_cfg->bps_max;
RK_S32 real_bit = cfg->bit_real;
RK_S32 target_bit = cfg->bit_target;
RK_S32 idx1, idx2;
RK_S32 bit_diff_ratio, ins_ratio, bps_ratio;
rc_dbg_func("enter %p\n", ctx);
rc_dbg_func("enter %p\n", p);
if (target_bit <= real_bit)
bit_diff_ratio = 32 * (real_bit - target_bit) / target_bit;
@@ -742,9 +677,9 @@ MPP_RET reenc_calc_vbr_ratio(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg)
bit_diff_ratio = mpp_clip(bit_diff_ratio, -128, 256);
bps_ratio = mpp_clip(bps_ratio, -32, 32);
ctx->next_ratio = bit_diff_ratio + ins_ratio + bps_ratio;
rc_dbg_rc("vbr reenc next ratio %d", ctx->next_ratio);
rc_dbg_func("leave %p\n", ctx);
p->next_ratio = bit_diff_ratio + ins_ratio + bps_ratio;
rc_dbg_rc("vbr reenc next ratio %d", p->next_ratio);
rc_dbg_func("leave %p\n", p);
return MPP_OK;
}
@@ -810,40 +745,41 @@ RK_S32 moving_ratio_calc(RcModelV2Ctx *ctx)
return moving_ratio;
}
MPP_RET calc_avbr_ratio(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg)
MPP_RET calc_avbr_ratio(void *ctx, EncRcTaskInfo *cfg)
{
RcCfg *usr_cfg = &ctx->usr_cfg;
RK_S32 bps_change = ctx->target_bps;
RcModelV2Ctx *p = (RcModelV2Ctx *)ctx;
RcCfg *usr_cfg = &p->usr_cfg;
RK_S32 bps_change = p->target_bps;
RK_S32 max_bps_target = usr_cfg->bps_max;
RK_S32 ins_bps = ctx->ins_bps;
RK_S32 pre_target_bits = ctx->pre_target_bits;
RK_S32 pre_real_bits = ctx->pre_real_bits;
RK_S32 pre_ins_bps = ctx->last_inst_bps;
RK_S32 ins_bps = p->ins_bps;
RK_S32 pre_target_bits = p->pre_target_bits;
RK_S32 pre_real_bits = p->pre_real_bits;
RK_S32 pre_ins_bps = p->last_inst_bps;
RK_S32 idx1, idx2;
RK_S32 bit_diff_ratio, ins_ratio, agop_dratio, rgop_dratio;
RK_S32 moving_ratio = 0, moving_percent;
RK_S32 gop_bits = 0, gop_kbits = 0;
RK_S32 i_ratio, max_bps;
RK_S32 qratio, final_qratio;
rc_dbg_func("enter %p\n", ctx);
moving_ratio = moving_ratio_calc(ctx);
if (ctx->moving_ratio - 2 >= moving_ratio) {
moving_ratio = ctx->moving_ratio - 2;
rc_dbg_func("enter %p\n", p);
moving_ratio = moving_ratio_calc(p);
if (p->moving_ratio - 2 >= moving_ratio) {
moving_ratio = p->moving_ratio - 2;
}
if (ctx->moving_ratio > moving_ratio && (ctx->max_still_qp << 6) <= ctx->scale_qp) {
ctx->moving_ratio = mpp_clip(ctx->moving_ratio + 1, 0, 255);
if (p->moving_ratio > moving_ratio && (p->max_still_qp << 6) <= p->scale_qp) {
p->moving_ratio = mpp_clip(p->moving_ratio + 1, 0, 255);
} else {
ctx->moving_ratio = moving_ratio;
p->moving_ratio = moving_ratio;
}
rc_dbg_rc("final moving_ratio = %d", moving_ratio);
gop_bits = moving_ratio * ctx->gop_total_bits >> 8;
gop_bits = moving_ratio * p->gop_total_bits >> 8;
gop_kbits = gop_bits >> 10;
if (gop_kbits < 1) {
gop_kbits = 1;
}
bits_model_alloc(ctx, cfg, gop_bits);
bits_model_alloc(p, cfg, gop_bits);
bps_change = moving_ratio * bps_change >> 8;
if (moving_ratio < 0) {
moving_ratio += 255;
@@ -851,14 +787,14 @@ MPP_RET calc_avbr_ratio(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg)
moving_percent = 100 * moving_ratio >> 8;
rc_dbg_bps("%10s|%10s|%10s|%10s|%10s", "m_ratio", "r_bits", "t_bits", "ins_bps", "p_ins_bps");
rc_dbg_bps("%10d %10d %10d %10d %10d", ctx->moving_ratio, pre_real_bits, pre_target_bits, ins_bps, pre_ins_bps);
rc_dbg_bps("%10d %10d %10d %10d %10d", p->moving_ratio, pre_real_bits, pre_target_bits, ins_bps, pre_ins_bps);
if (pre_target_bits > pre_real_bits)
bit_diff_ratio = 32 * (pre_real_bits - pre_target_bits) / pre_target_bits;
else
bit_diff_ratio = 64 * (pre_real_bits - pre_target_bits) / pre_target_bits * moving_percent;
i_ratio = mpp_clip(ctx->pre_i_scale >> 4, 10, 200);
i_ratio = mpp_clip(p->pre_i_scale >> 4, 10, 200);
idx1 = ins_bps / (max_bps_target >> 5);
idx2 = pre_ins_bps / (max_bps_target >> 5);
idx1 = mpp_clip(idx1, 0, 64);
@@ -880,9 +816,9 @@ MPP_RET calc_avbr_ratio(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg)
ins_ratio = mpp_clip(ins_ratio >> 2, -128, 256);
bit_diff_ratio = mpp_clip(10 * bit_diff_ratio / i_ratio, -128, 256);
rgop_dratio = mpp_clip(24 * ((ctx->real_gbits - gop_bits) >> 10) / gop_kbits, -1, 1);
agop_dratio = mpp_clip(48 * ((ctx->avg_gbits - gop_bits) >> 10) / gop_kbits , -1, 1);
if (ctx->pre_i_scale > 640) {
rgop_dratio = mpp_clip(24 * ((p->real_gbits - gop_bits) >> 10) / gop_kbits, -1, 1);
agop_dratio = mpp_clip(48 * ((p->avg_gbits - gop_bits) >> 10) / gop_kbits , -1, 1);
if (p->pre_i_scale > 640) {
bit_diff_ratio = mpp_clip(bit_diff_ratio, -16, 32);
ins_ratio = mpp_clip(ins_ratio, -16, 32);
}
@@ -890,18 +826,108 @@ MPP_RET calc_avbr_ratio(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg)
final_qratio = ins_ratio + bit_diff_ratio + agop_dratio + rgop_dratio;
if (max_bps_target >= ins_bps) {
if (final_qratio > 0) {
if (ctx->scale_qp >= (ctx->max_still_qp << 6)) {
if (p->scale_qp >= (p->max_still_qp << 6)) {
final_qratio = ins_ratio + agop_dratio + rgop_dratio;
qratio = -6;
}
}
}
ctx->next_ratio = qratio + final_qratio;
p->next_ratio = qratio + final_qratio;
rc_dbg_qp("%10s|%10s|%10s|%10s|%10s|%10s|%10s", "diff_ratio", "ins_ratio", "rg_ratio",
"ag_ratio", "qratio", "next_ratio", "cur_qp_s");
rc_dbg_qp("%10d %10d %10d %10d %10d %10d %10d", bit_diff_ratio, ins_ratio, rgop_dratio,
agop_dratio, qratio, ctx->next_ratio, ctx->cur_scale_qp);
agop_dratio, qratio, p->next_ratio, p->cur_scale_qp);
rc_dbg_func("leave %p\n", p);
return MPP_OK;
}
MPP_RET bits_model_init(RcModelV2Ctx *ctx)
{
RcCfg *usr_cfg = &ctx->usr_cfg;
RK_S32 gop_len = ctx->usr_cfg.igop;
RcFpsCfg *fps = &ctx->usr_cfg.fps;
RK_S64 gop_bits = 0;
RK_U32 stat_times = ctx->usr_cfg.stat_times;
RK_U32 target_bps;
rc_dbg_func("enter %p\n", ctx);
if (stat_times == 0) {
stat_times = 3;
usr_cfg->stat_times = stat_times;
}
if (usr_cfg->max_i_bit_prop <= 0) {
usr_cfg->max_i_bit_prop = 30;
} else if (usr_cfg->max_i_bit_prop > 100) {
usr_cfg->max_i_bit_prop = 100;
}
rc_dbg_rc("max_i_bit_prop %d", ctx->usr_cfg.max_i_bit_prop);
if (!gop_len || gop_len > 500) {
mpp_log("infinte gop, set default for rc bit calc\n");
usr_cfg->igop = gop_len = 500;
}
if (!ctx->min_still_percent) {
if (usr_cfg->bps_min && usr_cfg->bps_max) {
ctx->min_still_percent = usr_cfg->bps_min * 100 / usr_cfg->bps_max;
} else {
ctx->min_still_percent = 25;
}
rc_dbg_rc("min_still_percent %d", ctx->min_still_percent);
}
ctx->max_still_qp = 35;
ctx->super_ifrm_bits_thr = -1;
ctx->super_pfrm_bits_thr = -1;
ctx->motion_sensitivity = 90;
ctx->first_frm_flg = 1;
target_bps = ctx->usr_cfg.bps_max;
ctx->re_calc_ratio = reenc_calc_vbr_ratio;
switch (ctx->usr_cfg.mode) {
case RC_CBR: {
ctx->calc_ratio = calc_cbr_ratio;
ctx->re_calc_ratio = reenc_calc_cbr_ratio;
target_bps = ctx->usr_cfg.bps_target;
} break;
case RC_VBR: {
ctx->calc_ratio = calc_vbr_ratio;
} break;
case RC_FIXQP: {
return MPP_OK;
}
case RC_AVBR: {
ctx->calc_ratio = calc_avbr_ratio;
} break;
default:
mpp_log("rc mode set error");
break;
}
ctx->target_bps = ctx->usr_cfg.bps_target;
if (gop_len >= 1)
gop_bits = (RK_S64)gop_len * target_bps * fps->fps_out_denorm;
else
gop_bits = (RK_S64)fps->fps_out_num * target_bps * fps->fps_out_denorm;
ctx->gop_total_bits = gop_bits / fps->fps_out_num;
ctx->bit_per_frame = target_bps * fps->fps_out_denorm / fps->fps_out_num;
ctx->watl_thrd = 3 * target_bps;
ctx->stat_watl = ctx->watl_thrd >> 3;
ctx->watl_base = ctx->stat_watl;
rc_dbg_rc("gop %d total bit %lld per_frame %d statistics time %d second\n",
ctx->usr_cfg.igop, ctx->gop_total_bits, ctx->bit_per_frame,
ctx->usr_cfg.stat_times);
if (bits_model_param_init(ctx)) {
return MPP_NOK;
}
bits_frm_init(ctx);
rc_dbg_func("leave %p\n", ctx);
return MPP_OK;
}
@@ -1009,7 +1035,7 @@ MPP_RET rc_model_v2_deinit(void *ctx)
RcModelV2Ctx *p = (RcModelV2Ctx *)ctx;
rc_dbg_func("enter %p\n", ctx);
bits_model_deinit(p);
bits_model_param_deinit(p);
rc_dbg_func("leave %p\n", ctx);
return MPP_OK;
@@ -1069,20 +1095,8 @@ MPP_RET rc_model_v2_start(void *ctx, EncRcTask *task)
}
if (!p->first_frm_flg) {
switch (usr_cfg->mode) {
case RC_CBR: {
calc_cbr_ratio(p, info);
} break;
case RC_VBR: {
calc_vbr_ratio(p, info);
} break;
case RC_AVBR: {
calc_avbr_ratio(p, info);
} break;
default:
mpp_log("rc mode set error");
break;
}
if (p->calc_ratio)
p->calc_ratio(p, info);
} else {
bits_model_alloc(p, info, p->gop_total_bits);
}
@@ -1202,10 +1216,14 @@ MPP_RET rc_model_v2_hal_start(void *ctx, EncRcTask *task)
if (p->reenc_cnt > 0) {
p->cur_scale_qp += p->next_ratio;
p->start_qp = p->cur_scale_qp >> 6;
rc_dbg_rc("p->start_qp = %d, p->cur_scale_qp %d,p->next_ratio %d ", p->start_qp, p->cur_scale_qp, p->next_ratio);
} else {
p->start_qp -= usr_cfg->i_quality_delta;
}
rc_dbg_rc("qp: start %2d cur_scale %d next_ratio %d i_delta %d reenc %d\n",
p->start_qp, p->cur_scale_qp, p->next_ratio,
usr_cfg->i_quality_delta, p->reenc_cnt);
p->cur_scale_qp = mpp_clip(p->cur_scale_qp, (info->quality_min << 6), (info->quality_max << 6));
p->pre_i_qp = p->cur_scale_qp >> 6;
p->pre_p_qp = p->cur_scale_qp >> 6;
@@ -1213,6 +1231,7 @@ MPP_RET rc_model_v2_hal_start(void *ctx, EncRcTask *task)
RK_S32 qp_scale = p->cur_scale_qp + p->next_ratio;
RK_S32 start_qp = 0;
RK_S32 dealt_qp = 0;
if (frm->is_intra) {
qp_scale = mpp_clip(qp_scale, (info->quality_min << 6), (info->quality_max << 6));
@@ -1225,6 +1244,7 @@ MPP_RET rc_model_v2_hal_start(void *ctx, EncRcTask *task)
if (usr_cfg->i_quality_delta && !p->reenc_cnt) {
RK_U8 index = mpp_data_mean_v2(p->madi) / 4;
index = mpp_clip(index, 0, 7);
dealt_qp = max_ip_qp_dealt[index];
if (dealt_qp > usr_cfg->i_quality_delta ) {
@@ -1232,10 +1252,7 @@ MPP_RET rc_model_v2_hal_start(void *ctx, EncRcTask *task)
}
}
dealt_qp = mpp_clip(dealt_qp, 5, usr_cfg->i_quality_delta);
if (usr_cfg->i_quality_delta) {
p->start_qp -= dealt_qp;
}
p->start_qp -= dealt_qp;
} else {
qp_scale = mpp_clip(qp_scale, (info->quality_min << 6), (info->quality_max << 6));
p->cur_scale_qp = qp_scale;
@@ -1256,7 +1273,6 @@ MPP_RET rc_model_v2_hal_start(void *ctx, EncRcTask *task)
rc_dbg_rc("quality [%d : %d : %d] -> [%d : %d : %d]\n",
quality_min, quality_target, quality_max,
info->quality_min, info->quality_target, info->quality_max);
rc_dbg_func("leave %p\n", p);
return MPP_OK;
}
@@ -1312,11 +1328,8 @@ MPP_RET rc_model_v2_check_reenc(void *ctx, EncRcTask *task)
} break;
case MPP_ENC_RC_DROP_FRM_DISABLED :
default : {
if (usr_cfg->mode == RC_CBR) {
reenc_calc_cbr_ratio(p, cfg);
} else {
reenc_calc_vbr_ratio(p, cfg);
}
if (p->re_calc_ratio)
p->re_calc_ratio(p, cfg);
if (p->next_ratio != 0 && cfg->quality_target < cfg->quality_max) {
p->reenc_cnt++;