archived-mpp/mpp/codec/rc/rc_model_v2_smt.c
timkingh.huang 4a71a39dc7 fix[smt_rc]: Fix first frame QP error
Change-Id: Icc7c30e2f2153643c2b06482e21b1082d0e3e618
Signed-off-by: timkingh.huang <timkingh.huang@rock-chips.com>
2024-09-25 16:45:11 +08:00

1161 lines
39 KiB
C

/*
* Copyright 2016 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define MODULE_TAG "rc_model_v2_smt"
#include <string.h>
#include <math.h>
#include "mpp_env.h"
#include "mpp_mem.h"
#include "mpp_common.h"
#include "rc_base.h"
#include "rc_debug.h"
#include "rc_model_v2_smt.h"
#include "mpp_rc.h"
#define LOW_QP 34
#define LOW_LOW_QP 35
typedef struct RcModelV2SmtCtx_t {
RcCfg usr_cfg;
RK_U32 frame_type;
RK_U32 last_frame_type;
RK_U32 first_frm_flg;
RK_S64 frm_num;
RK_S32 qp_min;
RK_S32 qp_max;
MppEncGopMode gop_mode;
RK_S64 acc_intra_count;
RK_S64 acc_inter_count;
RK_S32 last_fps_bits;
RK_S32 pre_gop_left_bit;
MppData *qp_p;
MppDataV2 *motion_level;
MppDataV2 *complex_level;
MppDataV2 *stat_bits;
MppDataV2 *rt_bits; /* real time bits */
MppPIDCtx pid_fps;
RK_S64 count_real_bit;
RK_S64 count_pred_bit;
RK_S64 count_frame;
RK_S64 fixed_i_pred_bit;
RK_S64 fixed_p_pred_bit;
RK_S32 change_bit_flag;
RK_S32 bits_tgt_lower; /* bits target lower limit */
RK_S32 bits_tgt_upper; /* bits target upper limit */
RK_S32 bits_per_lower_i; /* bits per intra frame in low rate */
RK_S32 bits_per_upper_i; /* bits per intra frame in high rate */
RK_S32 bits_per_lower_p; /* bits per P frame in low rate */
RK_S32 bits_per_upper_p; /* bits per P frame in high rate */
RK_S32 pre_diff_bit_lower;
RK_S32 pre_diff_bit_upper;
RK_S32 igop;
MppPIDCtx pid_lower_i;
MppPIDCtx pid_upper_i;
MppPIDCtx pid_lower_all;
MppPIDCtx pid_upper_all;
MppDataV2 *pid_lower_p;
MppDataV2 *pid_upper_p;
RK_S32 qp_out;
RK_S32 qp_prev_out;
RK_S32 pre_real_bit_i; /* real bit of last intra frame */
RK_S32 pre_qp_i; /* qp of last intra frame */
RK_S32 gop_qp_sum;
RK_S32 gop_frm_cnt;
RK_S32 pre_iblk4_prop;
RK_S32 reenc_cnt;
RK_U32 drop_cnt;
RK_S32 on_drop;
RK_S32 on_pskip;
} RcModelV2SmtCtx;
// rc_container_bitrate_thd2
static RK_S32 rc_ctnr_qp_thd1[6] = { 51, 42, 42, 51, 38, 38 };
static RK_S32 rc_ctnr_qp_thd2[6] = { 51, 44, 44, 51, 40, 40 };
static RK_S32 rc_ctnr_br_thd1[6] = { 100, 110, 110, 100, 110, 110 };
static RK_S32 rc_ctnr_br_thd2[6] = { 100, 120, 120, 100, 125, 125 };
MPP_RET bits_model_smt_deinit(RcModelV2SmtCtx *ctx)
{
rc_dbg_func("enter %p\n", ctx);
if (ctx->qp_p) {
mpp_data_deinit(ctx->qp_p);
ctx->qp_p = NULL;
}
if (ctx->motion_level != NULL) {
mpp_data_deinit_v2(ctx->motion_level);
ctx->motion_level = NULL;
}
if (ctx->complex_level != NULL) {
mpp_data_deinit_v2(ctx->complex_level);
ctx->complex_level = NULL;
}
if (ctx->stat_bits != NULL) {
mpp_data_deinit_v2(ctx->stat_bits);
ctx->stat_bits = NULL;
}
if (ctx->rt_bits != NULL) {
mpp_data_deinit_v2(ctx->rt_bits);
ctx->rt_bits = NULL;
}
if (ctx->pid_lower_p != NULL) {
mpp_data_deinit_v2(ctx->pid_lower_p);
ctx->pid_lower_p = NULL;
}
if (ctx->pid_upper_p != NULL) {
mpp_data_deinit_v2(ctx->pid_upper_p);
ctx->pid_upper_p = NULL;
}
rc_dbg_func("leave %p\n", ctx);
return MPP_OK;
}
MPP_RET bits_model_smt_init(RcModelV2SmtCtx *ctx)
{
RK_S32 gop_len = ctx->usr_cfg.igop;
RcFpsCfg *fps = &ctx->usr_cfg.fps;
RK_S32 mad_len = 10;
RK_S32 ave_bits_lower = 0, ave_bits_uppper = 0;
RK_S32 bits_lower_i, bits_upper_i;
RK_S32 bits_lower_p, bits_upper_p;
RK_S32 bit_ratio[5] = { 7, 8, 9, 10, 11 };
RK_S32 nfps = fps->fps_out_num / fps->fps_out_denom;
RK_S32 win_len = mpp_clip(MPP_MAX3(gop_len, nfps, 10), 1, nfps);
RK_S32 rt_stat_len = fps->fps_out_num / fps->fps_out_denom; /* real time stat len */
RK_S32 stat_len = fps->fps_out_num * ctx->usr_cfg.stats_time / fps->fps_out_denom;
stat_len = stat_len ? stat_len : (fps->fps_out_num * 8 / fps->fps_out_denom);
rc_dbg_func("enter %p\n", ctx);
ctx->frm_num = 0;
ctx->first_frm_flg = 1;
ctx->gop_frm_cnt = 0;
ctx->gop_qp_sum = 0;
// smt
ctx->igop = gop_len;
ctx->qp_min = 10;
ctx->qp_max = 51;
if (ctx->motion_level)
mpp_data_deinit_v2(ctx->motion_level);
mpp_data_init_v2(&ctx->motion_level, mad_len, 0);
if (ctx->complex_level)
mpp_data_deinit_v2(ctx->complex_level);
mpp_data_init_v2(&ctx->complex_level, mad_len, 0);
if (ctx->pid_lower_p)
mpp_data_deinit_v2(ctx->pid_lower_p);
mpp_data_init_v2(&ctx->pid_lower_p, stat_len, 0);
if (ctx->pid_upper_p)
mpp_data_deinit_v2(ctx->pid_upper_p);
mpp_data_init_v2(&ctx->pid_upper_p, stat_len, 0);
mpp_pid_reset(&ctx->pid_fps);
mpp_pid_reset(&ctx->pid_lower_i);
mpp_pid_reset(&ctx->pid_upper_i);
mpp_pid_reset(&ctx->pid_lower_all);
mpp_pid_reset(&ctx->pid_upper_all);
mpp_pid_set_param(&ctx->pid_fps, 4, 6, 0, 90, win_len);
mpp_pid_set_param(&ctx->pid_lower_i, 4, 6, 0, 100, win_len);
mpp_pid_set_param(&ctx->pid_upper_i, 4, 6, 0, 100, win_len);
mpp_pid_set_param(&ctx->pid_lower_all, 4, 6, 0, 100, gop_len);
mpp_pid_set_param(&ctx->pid_upper_all, 4, 6, 0, 100, gop_len);
ave_bits_lower = axb_div_c(ctx->usr_cfg.bps_min, fps->fps_out_denom, fps->fps_out_num);
ave_bits_uppper = axb_div_c(ctx->usr_cfg.bps_max, fps->fps_out_denom, fps->fps_out_num);
ctx->acc_intra_count = 0;
ctx->acc_inter_count = 0;
ctx->last_fps_bits = 0;
if (gop_len == 0) {
ctx->gop_mode = MPP_GOP_ALL_INTER;
bits_lower_p = ave_bits_lower;
bits_lower_i = ave_bits_lower * 10;
bits_upper_p = ave_bits_uppper;
bits_upper_i = ave_bits_uppper * 10;
} else if (gop_len == 1) {
ctx->gop_mode = MPP_GOP_ALL_INTRA;
bits_lower_p = 0;
bits_lower_i = ave_bits_lower;
bits_upper_p = 0;
bits_upper_i = ave_bits_uppper;
/* disable debreath on all intra case */
if (ctx->usr_cfg.debreath_cfg.enable)
ctx->usr_cfg.debreath_cfg.enable = 0;
} else if (gop_len < win_len) {
ctx->gop_mode = MPP_GOP_SMALL;
bits_lower_p = ave_bits_lower >> 1;
bits_lower_i = bits_lower_p * (gop_len + 1);
bits_upper_p = ave_bits_uppper >> 1;
bits_upper_i = bits_upper_p * (gop_len + 1);
} else {
RK_S32 g = gop_len;
RK_S32 idx = g <= 50 ? 0 : (g <= 100 ? 1 : (g <= 200 ? 2 : (g <= 300 ? 3 : 4)));
ctx->gop_mode = MPP_GOP_LARGE;
bits_lower_i = ave_bits_lower * bit_ratio[idx] / 2;
bits_upper_i = ave_bits_uppper * bit_ratio[idx] / 2;
bits_lower_p = ave_bits_lower - bits_lower_i / (nfps - 1);
bits_upper_p = ave_bits_uppper - bits_upper_i / (nfps - 1);
ctx->fixed_i_pred_bit = (ctx->usr_cfg.bps_max / nfps * 8) / 8;
ctx->fixed_p_pred_bit = ((ctx->usr_cfg.bps_max * g / nfps - ctx->fixed_i_pred_bit) / (g - 1)) / 8;
}
ctx->bits_per_lower_i = bits_lower_i;
ctx->bits_per_upper_i = bits_upper_i;
ctx->bits_per_lower_p = bits_lower_p;
ctx->bits_per_upper_p = bits_upper_p;
rc_dbg_rc("bits_per_lower_i %d, bits_per_upper_i %d, "
"bits_per_lower_p %d, bits_per_upper_p %d\n",
bits_lower_i, bits_upper_i, bits_lower_p, bits_upper_p);
if (ctx->stat_bits)
mpp_data_deinit_v2(ctx->stat_bits);
mpp_data_init_v2(&ctx->stat_bits, stat_len, bits_upper_p);
if (ctx->rt_bits)
mpp_data_deinit_v2(ctx->rt_bits);
mpp_data_init_v2(&ctx->rt_bits, rt_stat_len, bits_upper_p);
rc_dbg_func("leave %p\n", ctx);
return MPP_OK;
}
MPP_RET bits_model_update_smt(RcModelV2SmtCtx *ctx, RK_S32 real_bit)
{
rc_dbg_func("enter %p\n", ctx);
RcFpsCfg *fps = &ctx->usr_cfg.fps;
RK_S32 bps_target_tmp = 0;
RK_S32 mod = 0;
rc_dbg_func("enter %p\n", ctx);
mpp_data_update_v2(ctx->stat_bits, real_bit);
ctx->pre_diff_bit_lower = ctx->bits_tgt_lower - real_bit;
ctx->pre_diff_bit_upper = ctx->bits_tgt_upper - real_bit;
ctx->count_real_bit = ctx->count_real_bit + real_bit / 8;
if (ctx->frame_type == INTRA_FRAME) {
ctx->count_pred_bit = ctx->count_pred_bit + ctx->fixed_i_pred_bit;
} else {
ctx->count_pred_bit = ctx->count_pred_bit + ctx->fixed_p_pred_bit;
}
ctx->count_frame ++;
if (ctx->count_real_bit > 72057594037927935 || ctx->count_pred_bit > 72057594037927935) {
ctx->count_real_bit = 0;
ctx->count_pred_bit = 0;
}
if (ctx->change_bit_flag == 1) {
real_bit = real_bit * 8 / 10;
}
if (ctx->frame_type == INTRA_FRAME) {
ctx->acc_intra_count++;
mpp_pid_update(&ctx->pid_lower_i, real_bit - ctx->bits_tgt_lower, 1);
mpp_pid_update(&ctx->pid_upper_i, real_bit - ctx->bits_tgt_upper, 1);
} else {
ctx->acc_inter_count++;
mpp_data_update_v2(ctx->pid_lower_p, real_bit - ctx->bits_tgt_lower);
mpp_data_update_v2(ctx->pid_upper_p, real_bit - ctx->bits_tgt_upper);
}
mpp_pid_update(&ctx->pid_lower_all, real_bit - ctx->bits_tgt_lower, 1);
mpp_pid_update(&ctx->pid_upper_all, real_bit - ctx->bits_tgt_upper, 1);
ctx->last_fps_bits += real_bit;
/* new fps start */
mod = ctx->acc_intra_count + ctx->acc_inter_count;
mod = mod % fps->fps_out_num;
if (0 == mod) {
bps_target_tmp = (ctx->usr_cfg.bps_min + ctx->usr_cfg.bps_max) >> 1;
if (bps_target_tmp * 3 > (ctx->last_fps_bits * 2))
mpp_pid_update(&ctx->pid_fps, bps_target_tmp - ctx->last_fps_bits, 0);
else {
bps_target_tmp = ctx->usr_cfg.bps_min * 4 / 10 + ctx->usr_cfg.bps_max * 6 / 10;
mpp_pid_update(&ctx->pid_fps, bps_target_tmp - ctx->last_fps_bits, 0);
}
ctx->last_fps_bits = 0;
}
/* new frame start */
ctx->qp_prev_out = ctx->qp_out;
rc_dbg_func("leave %p\n", ctx);
return MPP_OK;
}
MPP_RET rc_model_v2_smt_h265_init(void *ctx, RcCfg *cfg)
{
RcModelV2SmtCtx *p = (RcModelV2SmtCtx*)ctx;
rc_dbg_func("enter %p\n", ctx);
memcpy(&p->usr_cfg, cfg, sizeof(RcCfg));
bits_model_smt_init(p);
rc_dbg_func("leave %p\n", ctx);
return MPP_OK;
}
MPP_RET rc_model_v2_smt_h264_init(void *ctx, RcCfg *cfg)
{
RcModelV2SmtCtx *p = (RcModelV2SmtCtx*)ctx;
rc_dbg_func("enter %p\n", ctx);
memcpy(&p->usr_cfg, cfg, sizeof(RcCfg));
bits_model_smt_init(p);
rc_dbg_func("leave %p\n", ctx);
return MPP_OK;
}
MPP_RET rc_model_v2_smt_deinit(void *ctx)
{
RcModelV2SmtCtx *p = (RcModelV2SmtCtx *)ctx;
rc_dbg_func("enter %p\n", ctx);
bits_model_smt_deinit(p);
rc_dbg_func("leave %p\n", ctx);
return MPP_OK;
}
static void set_coef(void *ctx, RK_S32 *coef, RK_S32 val)
{
RcModelV2SmtCtx *p = (RcModelV2SmtCtx*)ctx;
RK_S32 cplx_lvl_0 = mpp_data_get_pre_val_v2(p->complex_level, 0);
RK_S32 cplx_lvl_1 = mpp_data_get_pre_val_v2(p->complex_level, 1);
RK_S32 cplx_lvl_sum = mpp_data_sum_v2(p->complex_level);
if (cplx_lvl_sum == 0)
*coef = val + 0;
else if (cplx_lvl_sum == 1) {
if (cplx_lvl_0 == 0)
*coef = val + 10;
else
*coef = val + 25;
} else if (cplx_lvl_sum == 2) {
if (cplx_lvl_0 == 0)
*coef = val + 25;
else
*coef = val + 35;
} else if (cplx_lvl_sum == 3) {
if (cplx_lvl_0 == 0)
*coef = val + 35;
else
*coef = val + 51;
} else if (cplx_lvl_sum >= 4 && cplx_lvl_sum <= 6) {
if (cplx_lvl_0 == 0) {
if (cplx_lvl_1 == 0)
*coef = val + 35;
else
*coef = val + 51;
} else
*coef = val + 64;
} else if (cplx_lvl_sum >= 7 && cplx_lvl_sum <= 9) {
if (cplx_lvl_0 == 0) {
if (cplx_lvl_1 == 0)
*coef = val + 64;
else
*coef = val + 72;
} else
*coef = val + 72;
} else
*coef = val + 80;
}
static RK_U32 mb_num[9] = {
0, 200, 700, 1200, 2000, 4000, 8000, 16000, 20000
};
static RK_U32 tab_bit[9] = {
3780, 3570, 3150, 2940, 2730, 3780, 2100, 1680, 2100
};
static RK_U8 qscale2qp[96] = {
15, 15, 15, 15, 15, 16, 18, 20, 21, 22, 23,
24, 25, 25, 26, 27, 28, 28, 29, 29, 30, 30,
30, 31, 31, 32, 32, 33, 33, 33, 34, 34, 34,
34, 35, 35, 35, 36, 36, 36, 36, 36, 37, 37,
37, 37, 38, 38, 38, 38, 38, 39, 39, 39, 39,
39, 39, 40, 40, 40, 40, 41, 41, 41, 41, 41,
41, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43,
43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44,
44, 44, 44, 44, 45, 45, 45, 45,
};
static RK_U8 inter_pqp0[52] = {
1, 1, 1, 1, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 17, 18, 19, 20, 21,
21, 21, 22, 23, 24, 25, 26, 26,
27, 28, 28, 29, 29, 29, 30, 31,
31, 32, 32, 33, 33, 34, 35, 35,
35, 36, 36, 36
};
static RK_U8 inter_pqp1[52] = {
1, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 20, 21, 22,
23, 24, 25, 26, 26, 27, 28, 29,
29, 30, 31, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 42,
42, 43, 43, 44
};
static RK_U8 intra_pqp0[3][52] = {
{
1, 1, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22,
23, 23, 24, 25, 26, 27, 27, 28,
28, 29, 30, 31, 32, 32, 33, 34,
34, 34, 35, 35, 36, 36, 36, 36,
37, 37, 37, 38
},
{
1, 1, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 17, 18, 18, 19, 19,
20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, 32, 32, 33, 34,
34, 34, 35, 35, 36, 36, 36, 36,
37, 37, 37, 38
},
{
1, 1, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14,
14, 15, 15, 16, 16, 17, 17, 18,
16, 16, 16, 17, 18, 19, 20, 21,
23, 24, 26, 28, 30, 31, 32, 33,
34, 34, 35, 35, 36, 36, 36, 36,
37, 37, 37, 38
},
};
static RK_U8 intra_pqp1[52] = {
2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31, 32, 33, 34,
35, 36, 37, 38, 39, 40, 41, 42,
43, 44, 45, 46, 47, 48, 49, 50,
51, 51, 51, 51
};
static RK_S32 cal_smt_first_i_start_qp(RK_S32 target_bit, RK_U32 total_mb)
{
RK_S32 cnt = 0;
RK_S32 index;
RK_S32 i;
for (i = 0; i < 8; i++) {
if (mb_num[i] > total_mb)
break;
cnt++;
}
index = (total_mb * tab_bit[cnt] - 350) / target_bit; // qscale
index = mpp_clip(index, 4, 95);
return qscale2qp[index];
}
static MPP_RET calc_smt_debreath_qp(RcModelV2SmtCtx * ctx)
{
RK_S32 fm_qp_sum = 0;
RK_S32 new_fm_qp = 0;
RcDebreathCfg *debreath_cfg = &ctx->usr_cfg.debreath_cfg;
RK_S32 dealt_qp = 0;
RK_S32 gop_qp_sum = ctx->gop_qp_sum;
RK_S32 gop_frm_cnt = ctx->gop_frm_cnt;
static RK_S8 intra_qp_map[8] = {
0, 0, 1, 1, 2, 2, 2, 2,
};
RK_U8 idx2 = MPP_MIN(ctx->pre_iblk4_prop >> 5, (RK_S32)sizeof(intra_qp_map) - 1);
static RK_S8 strength_map[36] = {
0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4,
5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8,
9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12
};
rc_dbg_func("enter %p\n", ctx);
fm_qp_sum = MPP_MIN(gop_qp_sum / gop_frm_cnt, (RK_S32)sizeof(strength_map) - 1);
rc_dbg_qp("i qp_out %d, qp_start_sum = %d, intra_lv4_prop %d",
ctx->qp_out, fm_qp_sum, ctx->pre_iblk4_prop);
dealt_qp = strength_map[debreath_cfg->strength] - intra_qp_map[idx2];
if (fm_qp_sum > dealt_qp)
new_fm_qp = fm_qp_sum - dealt_qp;
else
new_fm_qp = fm_qp_sum;
ctx->qp_out = mpp_clip(new_fm_qp, ctx->usr_cfg.min_i_quality, ctx->usr_cfg.max_i_quality);
ctx->gop_frm_cnt = 0;
ctx->gop_qp_sum = 0;
rc_dbg_func("leave %p\n", ctx);
return MPP_OK;
}
static MPP_RET smt_start_prepare(void *ctx, EncRcTask *task)
{
EncFrmStatus *frm = &task->frm;
RcModelV2SmtCtx *p = (RcModelV2SmtCtx *) ctx;
EncRcTaskInfo *info = &task->info;
RcFpsCfg *fps = &p->usr_cfg.fps;
RK_S32 fps_out = fps->fps_out_num / fps->fps_out_denom;
RK_S32 b_min = p->usr_cfg.bps_min;
RK_S32 b_max = p->usr_cfg.bps_max;
RK_S32 bits_lower, bits_upper;
p->frame_type = frm->is_intra ? INTRA_FRAME : INTER_P_FRAME;
if (frm->ref_mode == REF_TO_PREV_INTRA)
p->frame_type = INTER_VI_FRAME;
switch (p->gop_mode) {
case MPP_GOP_ALL_INTER: {
if (p->frame_type == INTRA_FRAME) {
bits_lower = p->bits_per_lower_i;
bits_upper = p->bits_per_upper_i;
} else {
bits_lower = p->bits_per_lower_p - mpp_data_mean_v2(p->pid_lower_p);
bits_upper = p->bits_per_upper_p - mpp_data_mean_v2(p->pid_upper_p);
}
} break;
case MPP_GOP_ALL_INTRA: {
bits_lower = p->bits_per_lower_i - mpp_pid_calc(&p->pid_lower_i);
bits_upper = p->bits_per_upper_i - mpp_pid_calc(&p->pid_upper_i);
} break;
default: {
if (p->frame_type == INTRA_FRAME) {
RK_S32 diff_bit = mpp_pid_calc(&p->pid_fps);
p->pre_gop_left_bit = p->pid_fps.i - diff_bit;
mpp_pid_reset(&p->pid_fps);
if (p->acc_intra_count) {
bits_lower = (p->bits_per_lower_i + diff_bit);
bits_upper = (p->bits_per_upper_i + diff_bit);
} else {
bits_lower = p->bits_per_lower_i - mpp_pid_calc(&p->pid_lower_i);
bits_upper = p->bits_per_upper_i - mpp_pid_calc(&p->pid_upper_i);
}
} else {
if (p->last_frame_type == INTRA_FRAME) {
RK_S32 bits_prev_i = p->pre_real_bit_i;
bits_lower = p->bits_per_lower_p
= ((RK_S64)b_min * p->igop / fps_out - bits_prev_i +
p->pre_gop_left_bit) / (p->igop - 1);
bits_upper = p->bits_per_upper_p
= ((RK_S64)b_max * p->igop / fps_out - bits_prev_i +
p->pre_gop_left_bit) / (p->igop - 1);
} else {
RK_S32 diff_bit_lr = mpp_data_mean_v2(p->pid_lower_p);
RK_S32 diff_bit_hr = mpp_data_mean_v2(p->pid_upper_p);
RK_S32 lr = axb_div_c(b_min, fps->fps_out_denom, fps->fps_out_num);
RK_S32 hr = axb_div_c(b_max, fps->fps_out_denom, fps->fps_out_num);
bits_lower = p->bits_per_lower_p - diff_bit_lr;
if (bits_lower > 2 * lr)
bits_lower = 2 * lr;
bits_upper = p->bits_per_upper_p - diff_bit_hr;
if (bits_upper > 2 * hr)
bits_upper = 2 * hr;
}
}
} break;
}
p->bits_tgt_lower = bits_lower;
p->bits_tgt_upper = bits_upper;
info->bit_max = (bits_lower + bits_upper) / 2;
if (info->bit_max < 100)
info->bit_max = 100;
if (NULL == p->qp_p) {
RK_S32 nfps = fps_out < 15 ? 4 * fps_out : (fps_out < 25 ? 3 * fps_out : 2 * fps_out);
mpp_data_init(&p->qp_p, mpp_clip(MPP_MAX(p->igop, nfps), 20, 50));
}
rc_dbg_rc("bits_tgt_lower %d, bits_tgt_upper %d, bit_max %d, qp_out %d",
p->bits_tgt_lower, p->bits_tgt_upper, info->bit_max, p->qp_out);
return MPP_OK;
}
static RK_S32 smt_calc_coef(void *ctx)
{
RcModelV2SmtCtx *p = (RcModelV2SmtCtx *) ctx;
RK_S32 coef = 1024;
RK_S32 coef2 = 512;
RK_S32 md_lvl_sum = mpp_data_sum_v2(p->motion_level);
RK_S32 md_lvl_0 = mpp_data_get_pre_val_v2(p->motion_level, 0);
RK_S32 md_lvl_1 = mpp_data_get_pre_val_v2(p->motion_level, 1);
if (md_lvl_sum < 100)
set_coef(ctx, &coef, 0);
else if (md_lvl_sum < 200) {
if (md_lvl_0 < 100)
set_coef(ctx, &coef, 102);
else
set_coef(ctx, &coef, 154);
} else if (md_lvl_sum < 300) {
if (md_lvl_0 < 100)
set_coef(ctx, &coef, 154);
else if (md_lvl_0 == 100) {
if (md_lvl_1 < 100)
set_coef(ctx, &coef, 205);
else if (md_lvl_1 == 100)
set_coef(ctx, &coef, 256);
else
set_coef(ctx, &coef, 307);
} else
set_coef(ctx, &coef, 307);
} else if (md_lvl_sum < 600) {
if (md_lvl_0 < 100) {
if (md_lvl_1 < 100)
set_coef(ctx, &coef, 307);
else if (md_lvl_1 == 100)
set_coef(ctx, &coef, 358);
else
set_coef(ctx, &coef, 410);
} else if (md_lvl_0 == 100) {
if (md_lvl_1 < 100)
set_coef(ctx, &coef, 358);
else if (md_lvl_1 == 100)
set_coef(ctx, &coef, 410);
else
set_coef(ctx, &coef, 461);
} else
set_coef(ctx, &coef, 461);
} else if (md_lvl_sum < 900) {
if (md_lvl_0 < 100) {
if (md_lvl_1 < 100)
set_coef(ctx, &coef, 410);
else if (md_lvl_1 == 100)
set_coef(ctx, &coef, 461);
else
set_coef(ctx, &coef, 512);
} else if (md_lvl_0 == 100) {
if (md_lvl_1 < 100)
set_coef(ctx, &coef, 512);
else if (md_lvl_1 == 100)
set_coef(ctx, &coef, 563);
else
set_coef(ctx, &coef, 614);
} else
set_coef(ctx, &coef, 614);
} else if (md_lvl_sum < 1500)
set_coef(ctx, &coef, 666);
else if (md_lvl_sum < 1900)
set_coef(ctx, &coef, 768);
else
set_coef(ctx, &coef, 900);
if (coef > 1024)
coef = 1024;
if (coef >= 900)
coef2 = 1024;
else if (coef >= 307) // 0.7~0.3 --> 1.0~0.5
coef2 = 512 + (coef - 307) * (1024 - 512) / (717 - 307);
else // 0.3~0.0 --> 0.5~0.0
coef2 = 0 + coef * (512 - 0) / (307 - 0);
if (coef2 >= 1024)
coef2 = 1024;
return coef2;
}
MPP_RET rc_model_v2_smt_start(void *ctx, EncRcTask * task)
{
RcModelV2SmtCtx *p = (RcModelV2SmtCtx *) ctx;
EncFrmStatus *frm = &task->frm;
EncRcTaskInfo *info = &task->info;
RcFpsCfg *fps = &p->usr_cfg.fps;
RK_S32 qp_add = 0, qp_add_p = 0, qp_minus = 0;
RK_S32 bit_target_use = 0;
RK_S32 avg_bps = (p->usr_cfg.bps_min + p->usr_cfg.bps_max) / 2;
RK_S32 fps_out = fps->fps_out_num / fps->fps_out_denom;
RK_S32 avg_pqp = 0;
RK_S32 prev_pqp = p->qp_prev_out;
RK_S32 fm_min_iqp = p->usr_cfg.fqp_min_i;
RK_S32 fm_min_pqp = p->usr_cfg.fqp_min_p;
RK_S32 fm_max_iqp = p->usr_cfg.fqp_max_i;
RK_S32 fm_max_pqp = p->usr_cfg.fqp_max_p;
RK_S32 md_lvl_sum = mpp_data_sum_v2(p->motion_level);
RK_S32 md_lvl_0 = mpp_data_get_pre_val_v2(p->motion_level, 0);
RK_S32 cplx_lvl_sum = mpp_data_sum_v2(p->complex_level);
if (frm->reencode)
return MPP_OK;
smt_start_prepare(ctx, task);
bit_target_use = info->bit_max;
avg_pqp = mpp_data_avg(p->qp_p, -1, 1, 1);
if (p->frm_num == 0) {
RK_S32 mb_w = MPP_ALIGN(p->usr_cfg.width, 16) / 16;
RK_S32 mb_h = MPP_ALIGN(p->usr_cfg.height, 16) / 16;
RK_S32 ratio = mpp_clip(fps_out / 10 + 1, 1, 3);
RK_S32 qp_out_f0 = 0;
if (p->usr_cfg.init_quality < 0) {
qp_out_f0 = cal_smt_first_i_start_qp(p->bits_tgt_upper * ratio, mb_w * mb_h);
qp_out_f0 = (fm_min_iqp > 31) ? mpp_clip(qp_out_f0, fm_min_iqp, p->qp_max) :
mpp_clip(qp_out_f0, 31, p->qp_max);
} else
qp_out_f0 = p->usr_cfg.init_quality;
p->qp_out = qp_out_f0;
p->count_real_bit = 0;
p->count_pred_bit = 0;
p->count_frame = 0;
rc_dbg_rc("first frame init_quality %d bits_tgt_upper %d "
"mb_w %d mb_h %d ratio %d qp_out %d\n",
p->usr_cfg.init_quality, p->bits_tgt_upper,
mb_w, mb_h, ratio, p->qp_out);
}
p->change_bit_flag = 0;
if (p->frame_type == INTRA_FRAME) {
if (p->frm_num > 0) {
RK_S32 avg_qp = mpp_clip(avg_pqp, p->qp_min, p->qp_max);
RK_S32 prev_iqp = p->pre_qp_i;
RK_S32 pre_bits_i = p->pre_real_bit_i;
RK_S32 qp_out_i = 0;
if (bit_target_use <= pre_bits_i) {
qp_out_i = (bit_target_use * 5 < pre_bits_i) ? prev_iqp + 3 :
(bit_target_use * 2 < pre_bits_i) ? prev_iqp + 2 :
(bit_target_use * 3 < pre_bits_i * 2) ? prev_iqp + 1 : prev_iqp;
} else {
qp_out_i = (pre_bits_i * 3 < bit_target_use) ? prev_iqp - 3 :
(pre_bits_i * 2 < bit_target_use) ? prev_iqp - 2 :
(pre_bits_i * 3 < bit_target_use * 2) ? prev_iqp - 1 : prev_iqp;
}
if (!p->reenc_cnt && p->usr_cfg.debreath_cfg.enable)
calc_smt_debreath_qp(p);
qp_out_i = mpp_clip(qp_out_i, inter_pqp0[avg_qp], inter_pqp1[avg_qp]);
qp_out_i = mpp_clip(qp_out_i, inter_pqp0[prev_pqp], inter_pqp1[prev_pqp]);
if (qp_out_i > 27)
p->qp_out = mpp_clip(qp_out_i, intra_pqp0[0][prev_iqp], intra_pqp1[prev_iqp]);
else if (qp_out_i > 22)
p->qp_out = mpp_clip(qp_out_i, intra_pqp0[1][prev_iqp], intra_pqp1[prev_iqp]);
else
p->qp_out = mpp_clip(qp_out_i, intra_pqp0[2][prev_iqp], intra_pqp1[prev_iqp]);
if (p->pre_gop_left_bit < 0) {
if (abs(p->pre_gop_left_bit) * 5 > avg_bps * (p->igop / fps_out))
p->qp_out = mpp_clip(p->qp_out, 20, 51);
else if (abs(p->pre_gop_left_bit) * 20 > avg_bps * (p->igop / fps_out))
p->qp_out = mpp_clip(p->qp_out, 15, 51);
}
}
} else {
if (p->last_frame_type == INTRA_FRAME)
p->qp_out = prev_pqp + (prev_pqp < 33 ? 3 : (prev_pqp < 35 ? 2 : 1));
else {
RK_S32 bits_tgt_use = 0;
RK_S32 pre_diff_bit_use = 0;
RK_S32 coef = smt_calc_coef(ctx);
RK_S32 m_tbr = p->bits_tgt_upper - p->bits_tgt_lower;
RK_S32 m_dbr = p->pre_diff_bit_upper - p->pre_diff_bit_lower;
RK_S32 diff_bit = (p->pid_lower_all.i + p->pid_upper_all.i) >> 1;
RK_S32 qp_out = p->qp_out;
bits_tgt_use = (m_tbr * coef + p->bits_tgt_lower * 1024) >> 10;
pre_diff_bit_use = (m_dbr * coef + p->pre_diff_bit_lower * 1024) >> 10;
if (bits_tgt_use < 100)
bits_tgt_use = 100;
if (abs(pre_diff_bit_use) * 100 <= bits_tgt_use * 3)
qp_out = prev_pqp - 1;
else if (pre_diff_bit_use * 100 > bits_tgt_use * 3) {
if (pre_diff_bit_use >= bits_tgt_use)
qp_out = qp_out >= 30 ? prev_pqp - 4 : prev_pqp - 3;
else if (pre_diff_bit_use * 4 >= bits_tgt_use * 1)
qp_out = qp_out >= 30 ? prev_pqp - 3 : prev_pqp - 2;
else if (pre_diff_bit_use * 10 > bits_tgt_use * 1)
qp_out = prev_pqp - 2;
else
qp_out = prev_pqp - 1;
} else {
RK_S32 qp_add_tmp = 1;
if (prev_pqp >= 36)
qp_add_tmp = 0;
pre_diff_bit_use = abs(pre_diff_bit_use);
qp_out = (pre_diff_bit_use >= 2 * bits_tgt_use) ? prev_pqp + 2 + qp_add_tmp :
(pre_diff_bit_use * 3 >= bits_tgt_use * 2) ? prev_pqp + 1 + qp_add_tmp :
(pre_diff_bit_use * 5 > bits_tgt_use) ? prev_pqp + 1 : prev_pqp;
}
qp_out = mpp_clip(qp_out, p->qp_min, p->qp_max);
pre_diff_bit_use = (m_dbr * coef + p->pre_diff_bit_lower * 1024) >> 10;
bits_tgt_use = avg_bps / fps_out;
bits_tgt_use = -bits_tgt_use / 5;
if (qp_out > LOW_QP) {
coef += pre_diff_bit_use <= 2 * bits_tgt_use ? 205 :
((pre_diff_bit_use <= bits_tgt_use) ? 102 : 51);
if (coef >= 1024 || qp_out > LOW_LOW_QP)
coef = 1024;
pre_diff_bit_use = (m_dbr * coef + p->pre_diff_bit_lower * 1024) >> 10;
bits_tgt_use = (m_tbr * coef + p->bits_tgt_lower * 1024) >> 10;
if (bits_tgt_use < 100)
bits_tgt_use = 100;
if (abs(pre_diff_bit_use) * 100 <= bits_tgt_use * 3)
qp_out = prev_pqp;
else if (pre_diff_bit_use * 100 > bits_tgt_use * 3) {
if (pre_diff_bit_use >= bits_tgt_use)
qp_out = qp_out >= 30 ? prev_pqp - 3 : prev_pqp - 2;
else if (pre_diff_bit_use * 4 >= bits_tgt_use * 1)
qp_out = qp_out >= 30 ? prev_pqp - 2 : prev_pqp - 1;
else if (pre_diff_bit_use * 10 > bits_tgt_use * 1)
qp_out = prev_pqp - 1;
else
qp_out = prev_pqp;
} else {
pre_diff_bit_use = abs(pre_diff_bit_use);
qp_out = prev_pqp + (pre_diff_bit_use * 3 >= bits_tgt_use * 2 ? 1 : 0);
}
}
qp_out = mpp_clip(qp_out, p->qp_min, p->qp_max);
//Add rc_container
if (p->usr_cfg.rc_container) {
RK_S32 cnt = p->usr_cfg.scene_mode * 3 + p->usr_cfg.rc_container;
if (p->count_real_bit < p->count_pred_bit * rc_ctnr_br_thd1[cnt] / 100) {
if (qp_out > rc_ctnr_qp_thd1[cnt]) {
p->change_bit_flag = 1;
}
qp_out = mpp_clip(qp_out, 10, rc_ctnr_qp_thd1[cnt]);
} else if (p->count_real_bit < p->count_pred_bit * rc_ctnr_br_thd2[cnt] / 100) {
if (qp_out > rc_ctnr_qp_thd2[cnt]) {
p->change_bit_flag = 1;
}
qp_out = mpp_clip(qp_out, 10, rc_ctnr_qp_thd2[cnt]);
}
}
qp_add = qp_out > 36 ? 1 : (qp_out > 33 ? 2 : (qp_out > 30 ? 3 : 4));
qp_minus = qp_out > 40 ? 4 : (qp_out > 36 ? 3 : (qp_out > 33 ? 2 : 1));
p->qp_out = mpp_clip(qp_out, prev_pqp - qp_minus, prev_pqp + qp_add);
if (diff_bit > 0) {
if (avg_bps * 5 > avg_bps)
p->qp_out = mpp_clip(p->qp_out, 25, 51);
else if (avg_bps * 20 > avg_bps)
p->qp_out = mpp_clip(p->qp_out, 21, 51);
}
}
}
qp_add = 4;
qp_add_p = 4;
if (md_lvl_sum >= 700 || md_lvl_0 == 200) {
qp_add = 6;
qp_add_p = 5;
} else if (md_lvl_sum >= 400 || md_lvl_0 == 100) {
qp_add = 5;
qp_add_p = 4;
}
if (cplx_lvl_sum >= 12) {
qp_add++;
qp_add_p++;
}
if (p->frame_type == INTRA_FRAME)
p->qp_out = mpp_clip(p->qp_out, fm_min_iqp + qp_add, fm_max_iqp);
else if (p->frame_type == INTER_VI_FRAME) {
p->qp_out -= 1;
p->qp_out = mpp_clip(p->qp_out, fm_min_pqp + qp_add - 1, fm_max_pqp);
} else
p->qp_out = mpp_clip(p->qp_out, fm_min_pqp + qp_add_p, fm_max_pqp);
p->qp_out = mpp_clip(p->qp_out, p->qp_min, p->qp_max);
info->quality_target = p->qp_out;
info->complex_scene = 0;
if (p->frame_type == INTER_P_FRAME && avg_pqp >= fm_max_pqp - 1 &&
p->qp_out == fm_max_pqp && p->qp_prev_out == fm_max_pqp)
info->complex_scene = 1;
info->quality_max = p->usr_cfg.max_quality;
info->quality_min = p->usr_cfg.min_quality;
rc_dbg_rc("frame %lld quality [%d : %d : %d] complex_scene %d\n",
p->frm_num, info->quality_min, info->quality_target,
info->quality_max, info->complex_scene);
p->frm_num++;
p->reenc_cnt = 0;
rc_dbg_func("leave %p\n", ctx);
return MPP_OK;
}
MPP_RET check_super_frame_smt(RcModelV2SmtCtx *ctx, EncRcTaskInfo *cfg)
{
MPP_RET ret = MPP_OK;
RK_S32 frame_type = ctx->frame_type;
RK_U32 bits_thr = 0;
RcCfg *usr_cfg = &ctx->usr_cfg;
rc_dbg_func("enter %p\n", ctx);
if (usr_cfg->super_cfg.super_mode) {
bits_thr = usr_cfg->super_cfg.super_p_thd;
if (frame_type == INTRA_FRAME)
bits_thr = usr_cfg->super_cfg.super_i_thd;
if ((RK_U32)cfg->bit_real >= bits_thr) {
if (usr_cfg->super_cfg.super_mode == MPP_ENC_RC_SUPER_FRM_DROP) {
rc_dbg_rc("super frame drop current frame");
usr_cfg->drop_mode = MPP_ENC_RC_DROP_FRM_NORMAL;
usr_cfg->drop_gap = 0;
}
ret = MPP_NOK;
}
}
rc_dbg_func("leave %p\n", ctx);
return ret;
}
MPP_RET check_re_enc_smt(RcModelV2SmtCtx *ctx, EncRcTaskInfo *cfg)
{
RcCfg *usr_cfg = &ctx->usr_cfg;
RK_S32 frame_type = ctx->frame_type;
RK_S32 bit_thr = 0;
RK_S32 stat_time = usr_cfg->stats_time;
RK_S32 last_ins_bps = mpp_data_sum_v2(ctx->stat_bits) / stat_time;
RK_S32 ins_bps = (last_ins_bps * stat_time - mpp_data_get_pre_val_v2(ctx->stat_bits, -1)
+ cfg->bit_real) / stat_time;
RK_S32 bps;
RK_S32 ret = MPP_OK;
rc_dbg_func("enter %p\n", ctx);
rc_dbg_rc("reenc check target_bps %d last_ins_bps %d ins_bps %d",
usr_cfg->bps_target, last_ins_bps, ins_bps);
if (ctx->reenc_cnt >= usr_cfg->max_reencode_times)
return MPP_OK;
if (check_super_frame_smt(ctx, cfg))
return MPP_NOK;
if (usr_cfg->debreath_cfg.enable && !ctx->first_frm_flg)
return MPP_OK;
rc_dbg_drop("drop mode %d frame_type %d\n", usr_cfg->drop_mode, frame_type);
if (usr_cfg->drop_mode && frame_type == INTER_P_FRAME) {
bit_thr = (RK_S32)(usr_cfg->bps_max * (100 + usr_cfg->drop_thd) / (float)100);
rc_dbg_drop("drop mode %d check max_bps %d bit_thr %d ins_bps %d",
usr_cfg->drop_mode, usr_cfg->bps_target, bit_thr, ins_bps);
return (ins_bps > bit_thr) ? MPP_NOK : MPP_OK;
}
switch (frame_type) {
case INTRA_FRAME:
bit_thr = 3 * cfg->bit_max / 2;
break;
case INTER_P_FRAME:
bit_thr = 3 * cfg->bit_max;
break;
default:
break;
}
if (cfg->bit_real > bit_thr) {
bps = usr_cfg->bps_max;
if ((bps - (bps >> 3) < ins_bps) && (bps / 20 < ins_bps - last_ins_bps))
ret = MPP_NOK;
}
rc_dbg_func("leave %p ret %d\n", ctx, ret);
return ret;
}
MPP_RET rc_model_v2_smt_check_reenc(void *ctx, EncRcTask *task)
{
RcModelV2SmtCtx *p = (RcModelV2SmtCtx *)ctx;
EncRcTaskInfo *cfg = (EncRcTaskInfo *)&task->info;
EncFrmStatus *frm = &task->frm;
RcCfg *usr_cfg = &p->usr_cfg;
rc_dbg_func("enter ctx %p cfg %p\n", ctx, cfg);
frm->reencode = 0;
if ((usr_cfg->mode == RC_FIXQP) ||
(task->force.force_flag & ENC_RC_FORCE_QP) ||
p->on_drop || p->on_pskip)
return MPP_OK;
if (check_re_enc_smt(p, cfg)) {
MppEncRcDropFrmMode drop_mode = usr_cfg->drop_mode;
if (frm->is_intra)
drop_mode = MPP_ENC_RC_DROP_FRM_DISABLED;
if (usr_cfg->drop_gap && p->drop_cnt >= usr_cfg->drop_gap)
drop_mode = MPP_ENC_RC_DROP_FRM_DISABLED;
rc_dbg_drop("reenc drop_mode %d drop_cnt %d\n", drop_mode, p->drop_cnt);
switch (drop_mode) {
case MPP_ENC_RC_DROP_FRM_NORMAL : {
frm->drop = 1;
frm->reencode = 1;
p->on_drop = 1;
p->drop_cnt++;
rc_dbg_drop("drop\n");
} break;
case MPP_ENC_RC_DROP_FRM_PSKIP : {
frm->force_pskip = 1;
frm->reencode = 1;
p->on_pskip = 1;
p->drop_cnt++;
rc_dbg_drop("force_pskip\n");
} break;
case MPP_ENC_RC_DROP_FRM_DISABLED :
default : {
RK_S32 bits_thr = usr_cfg->super_cfg.super_p_thd;
if (p->frame_type == INTRA_FRAME)
bits_thr = usr_cfg->super_cfg.super_i_thd;
if (cfg->bit_real > bits_thr * 2)
cfg->quality_target += 3;
else if (cfg->bit_real > bits_thr * 3 / 2)
cfg->quality_target += 2;
else if (cfg->bit_real > bits_thr)
cfg->quality_target ++;
if (cfg->quality_target < cfg->quality_max) {
p->reenc_cnt++;
frm->reencode = 1;
}
p->drop_cnt = 0;
} break;
}
}
return MPP_OK;
}
MPP_RET rc_model_v2_smt_end(void *ctx, EncRcTask * task)
{
RcModelV2SmtCtx *p = (RcModelV2SmtCtx *) ctx;
EncRcTaskInfo *cfg = (EncRcTaskInfo *) & task->info;
RK_S32 bit_real = cfg->bit_real;
rc_dbg_func("enter ctx %p cfg %p\n", ctx, cfg);
rc_dbg_rc("motion_level %u, complex_level %u\n", cfg->motion_level, cfg->complex_level);
mpp_data_update_v2(p->rt_bits, bit_real);
cfg->rt_bits = mpp_data_sum_v2(p->rt_bits);
rc_dbg_rc("frame %lld real_bit %d real time bits %d\n",
p->frm_num - 1, bit_real, cfg->rt_bits);
mpp_data_update_v2(p->motion_level, cfg->motion_level);
mpp_data_update_v2(p->complex_level, cfg->complex_level);
p->first_frm_flg = 0;
if (p->frame_type == INTER_P_FRAME || p->gop_mode == MPP_GOP_ALL_INTRA)
mpp_data_update(p->qp_p, p->qp_out);
else {
p->pre_qp_i = p->qp_out;
p->pre_real_bit_i = bit_real;
}
bits_model_update_smt(p, bit_real);
p->qp_prev_out = p->qp_out;
p->last_frame_type = p->frame_type;
p->pre_iblk4_prop = cfg->iblk4_prop;
p->gop_frm_cnt++;
p->gop_qp_sum += p->qp_out;
rc_dbg_func("leave %p\n", ctx);
return MPP_OK;
}
MPP_RET rc_model_v2_smt_hal_start(void *ctx, EncRcTask *task)
{
rc_dbg_func("smt_hal_start enter ctx %p task %p\n", ctx, task);
return MPP_OK;
}
MPP_RET rc_model_v2_smt_hal_end(void *ctx, EncRcTask *task)
{
rc_dbg_func("smt_hal_end enter ctx %p task %p\n", ctx, task);
rc_dbg_func("leave %p\n", ctx);
return MPP_OK;
}
const RcImplApi smt_h264e = {
"smart",
MPP_VIDEO_CodingAVC,
sizeof(RcModelV2SmtCtx),
rc_model_v2_smt_h264_init,
rc_model_v2_smt_deinit,
NULL,
rc_model_v2_smt_check_reenc,
rc_model_v2_smt_start,
rc_model_v2_smt_end,
rc_model_v2_smt_hal_start,
rc_model_v2_smt_hal_end,
};
const RcImplApi smt_h265e = {
"smart",
MPP_VIDEO_CodingHEVC,
sizeof(RcModelV2SmtCtx),
rc_model_v2_smt_h265_init,
rc_model_v2_smt_deinit,
NULL,
rc_model_v2_smt_check_reenc,
rc_model_v2_smt_start,
rc_model_v2_smt_end,
rc_model_v2_smt_hal_start,
rc_model_v2_smt_hal_end,
};