diff --git a/mpp/codec/rc/rc_ctx.h b/mpp/codec/rc/rc_ctx.h index 92d7fbfa..7ef60fc5 100644 --- a/mpp/codec/rc/rc_ctx.h +++ b/mpp/codec/rc/rc_ctx.h @@ -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 diff --git a/mpp/codec/rc/rc_model_v2.c b/mpp/codec/rc/rc_model_v2.c index 66807084..c3e0d2bf 100644 --- a/mpp/codec/rc/rc_model_v2.c +++ b/mpp/codec/rc/rc_model_v2.c @@ -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++;