feat[rc_v2]: Support flex fps rate control

Change-Id: I45a8544c15ab4baede232e1a3b16c517f965092e
Signed-off-by: sayon.chen <sayon.chen@rock-chips.com>
This commit is contained in:
sayon.chen
2022-09-15 16:06:38 +08:00
committed by Herman Chen
parent a4b66352f1
commit 65439d38a4
3 changed files with 76 additions and 3 deletions

View File

@@ -185,6 +185,7 @@ typedef struct RcCfg_s {
RcHierQPCfg hier_qp_cfg;
RK_U32 refresh_len;
RK_S32 scene_mode;
RK_U32 fps_chg_prop;
} RcCfg;
/*

View File

@@ -98,6 +98,11 @@ typedef struct RcModelV2Ctx_t {
RK_S32 qp_layer_id;
RK_S32 hier_frm_cnt[4];
RK_S64 time_base;
RK_S64 time_end;
RK_S32 frm_cnt;
RK_S32 last_fps;
MPP_RET (*calc_ratio)(void* ctx, EncRcTaskInfo *cfg);
MPP_RET (*re_calc_ratio)(void* ctx, EncRcTaskInfo *cfg);
} RcModelV2Ctx;

View File

@@ -22,7 +22,7 @@
#include "mpp_env.h"
#include "mpp_mem.h"
#include "mpp_common.h"
#include "mpp_time.h"
#include "rc_debug.h"
#include "rc_ctx.h"
#include "rc_model_v2.h"
@@ -1065,7 +1065,7 @@ MPP_RET bits_model_init(RcModelV2Ctx *ctx)
RK_S32 gop_len = ctx->usr_cfg.igop;
RcFpsCfg *fps = &ctx->usr_cfg.fps;
RK_S64 gop_bits = 0;
RK_U32 target_bps;
RK_U32 target_bps = 0;
rc_dbg_func("enter %p\n", ctx);
@@ -1099,6 +1099,10 @@ MPP_RET bits_model_init(RcModelV2Ctx *ctx)
ctx->gop_frm_cnt = 0;
ctx->gop_qp_sum = 0;
if (!usr_cfg->fps_chg_prop) {
usr_cfg->fps_chg_prop = 25;
}
target_bps = ctx->usr_cfg.bps_max;
ctx->re_calc_ratio = reenc_calc_vbr_ratio;
switch (ctx->usr_cfg.mode) {
@@ -1139,6 +1143,7 @@ MPP_RET bits_model_init(RcModelV2Ctx *ctx)
ctx->watl_thrd = 3 * target_bps;
ctx->stat_watl = ctx->watl_thrd >> 3;
ctx->watl_base = ctx->stat_watl;
ctx->last_fps = fps->fps_out_num / fps->fps_out_denorm;
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,
@@ -1147,12 +1152,70 @@ MPP_RET bits_model_init(RcModelV2Ctx *ctx)
if (bits_model_param_init(ctx)) {
return MPP_NOK;
}
ctx->time_base = mpp_time();
bits_frm_init(ctx);
rc_dbg_func("leave %p\n", ctx);
return MPP_OK;
}
static MPP_RET update_mode_param(RcModelV2Ctx *ctx, RK_U32 fps)
{
RcCfg *usr_cfg = &ctx->usr_cfg;
RK_S32 gop_len = ctx->usr_cfg.igop;
RK_S64 gop_bits = 0;
RK_U32 target_bps;
RK_U32 stat_len = fps * usr_cfg->stats_time;
target_bps = ctx->usr_cfg.bps_max;
if (ctx->usr_cfg.mode == RC_CBR) {
target_bps = ctx->usr_cfg.bps_target;
}
if (gop_len >= 1)
gop_bits = (RK_S64)gop_len * target_bps;
else
gop_bits = (RK_S64)target_bps;
ctx->gop_total_bits = gop_bits / fps;
ctx->bit_per_frame = target_bps / fps;
if (ctx->stat_bits != NULL) {
mpp_data_deinit_v2(ctx->stat_bits);
ctx->stat_bits = NULL;
}
mpp_data_init_v2(&ctx->stat_bits, stat_len , ctx->bit_per_frame);
if (ctx->stat_bits == NULL) {
mpp_err("stat_bits init fail stat_len %d", stat_len);
return MPP_ERR_MALLOC;
}
return MPP_OK;
}
static MPP_RET fps_chg_update_mode(RcModelV2Ctx *ctx)
{
ctx->time_end = mpp_time();
ctx->frm_cnt++;
if (ctx->time_base && ctx->time_end &&
((ctx->time_end - ctx->time_base) >= (RK_S64)(250 * 1000))) {
RK_S32 time_diff = ((RK_S32)(ctx->time_end - ctx->time_base) / 1000);
RK_U32 fps = ctx->frm_cnt * 1000 / time_diff;
if (ctx->last_fps > 0 && fps &&
abs(ctx->last_fps - (RK_S32)fps) * 100 / ctx->last_fps > (RK_S32)ctx->usr_cfg.fps_chg_prop) {
update_mode_param(ctx, fps);
mpp_log("fps chg from %d -> %d", ctx->last_fps, fps);
ctx->last_fps = fps;
}
ctx->time_base = ctx->time_end;
ctx->frm_cnt = 0;
}
return MPP_OK;
}
MPP_RET bits_mode_reset(RcModelV2Ctx *ctx)
{
rc_dbg_func("enter %p\n", ctx);
@@ -1320,6 +1383,10 @@ MPP_RET rc_model_v2_start(void *ctx, EncRcTask *task)
return MPP_OK;
}
if (usr_cfg->fps.fps_out_flex) {
fps_chg_update_mode(ctx);
}
info->frame_type = (frm->is_intra) ? (INTRA_FRAME) : (INTER_P_FRAME);
if (frm->ref_mode == REF_TO_PREV_INTRA)