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