xref: /rockchip-linux_mpp/mpp/codec/rc/rc_model_v2_smt.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  * Copyright 2016 Rockchip Electronics Co. LTD
3*437bfbebSnyanmisaka  *
4*437bfbebSnyanmisaka  * Licensed under the Apache License, Version 2.0 (the "License");
5*437bfbebSnyanmisaka  * you may not use this file except in compliance with the License.
6*437bfbebSnyanmisaka  * You may obtain a copy of the License at
7*437bfbebSnyanmisaka  *
8*437bfbebSnyanmisaka  *      http://www.apache.org/licenses/LICENSE-2.0
9*437bfbebSnyanmisaka  *
10*437bfbebSnyanmisaka  * Unless required by applicable law or agreed to in writing, software
11*437bfbebSnyanmisaka  * distributed under the License is distributed on an "AS IS" BASIS,
12*437bfbebSnyanmisaka  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*437bfbebSnyanmisaka  * See the License for the specific language governing permissions and
14*437bfbebSnyanmisaka  * limitations under the License.
15*437bfbebSnyanmisaka  */
16*437bfbebSnyanmisaka 
17*437bfbebSnyanmisaka #define MODULE_TAG "rc_model_v2_smt"
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka #include <string.h>
20*437bfbebSnyanmisaka #include <math.h>
21*437bfbebSnyanmisaka 
22*437bfbebSnyanmisaka #include "mpp_env.h"
23*437bfbebSnyanmisaka #include "mpp_mem.h"
24*437bfbebSnyanmisaka #include "mpp_common.h"
25*437bfbebSnyanmisaka 
26*437bfbebSnyanmisaka #include "rc_base.h"
27*437bfbebSnyanmisaka #include "rc_debug.h"
28*437bfbebSnyanmisaka #include "rc_model_v2_smt.h"
29*437bfbebSnyanmisaka #include "mpp_rc.h"
30*437bfbebSnyanmisaka 
31*437bfbebSnyanmisaka #define LOW_QP 34
32*437bfbebSnyanmisaka #define LOW_LOW_QP 35
33*437bfbebSnyanmisaka 
34*437bfbebSnyanmisaka typedef struct RcModelV2SmtCtx_t {
35*437bfbebSnyanmisaka     RcCfg           usr_cfg;
36*437bfbebSnyanmisaka     RK_U32          frame_type;
37*437bfbebSnyanmisaka     RK_U32          last_frame_type;
38*437bfbebSnyanmisaka     RK_U32          first_frm_flg;
39*437bfbebSnyanmisaka     RK_S64          frm_num;
40*437bfbebSnyanmisaka     RK_S32          qp_min;
41*437bfbebSnyanmisaka     RK_S32          qp_max;
42*437bfbebSnyanmisaka     MppEncGopMode   gop_mode;
43*437bfbebSnyanmisaka     RK_S64          acc_intra_count;
44*437bfbebSnyanmisaka     RK_S64          acc_inter_count;
45*437bfbebSnyanmisaka     RK_S32          last_fps_bits;
46*437bfbebSnyanmisaka     RK_S32          pre_gop_left_bit;
47*437bfbebSnyanmisaka     MppData         *qp_p;
48*437bfbebSnyanmisaka     MppDataV2       *motion_level;
49*437bfbebSnyanmisaka     MppDataV2       *complex_level;
50*437bfbebSnyanmisaka     MppDataV2       *stat_bits;
51*437bfbebSnyanmisaka     MppDataV2       *rt_bits; /* real time bits */
52*437bfbebSnyanmisaka     MppPIDCtx       pid_fps;
53*437bfbebSnyanmisaka     RK_S64          count_real_bit;
54*437bfbebSnyanmisaka     RK_S64          count_pred_bit;
55*437bfbebSnyanmisaka     RK_S64          count_frame;
56*437bfbebSnyanmisaka     RK_S64          fixed_i_pred_bit;
57*437bfbebSnyanmisaka     RK_S64          fixed_p_pred_bit;
58*437bfbebSnyanmisaka     RK_S32          change_bit_flag;
59*437bfbebSnyanmisaka 
60*437bfbebSnyanmisaka     RK_S32          bits_tgt_lower; /* bits target lower limit */
61*437bfbebSnyanmisaka     RK_S32          bits_tgt_upper; /* bits target upper limit */
62*437bfbebSnyanmisaka     RK_S32          bits_per_lower_i; /* bits per intra frame in low rate */
63*437bfbebSnyanmisaka     RK_S32          bits_per_upper_i; /* bits per intra frame in high rate */
64*437bfbebSnyanmisaka     RK_S32          bits_per_lower_p; /* bits per P frame in low rate */
65*437bfbebSnyanmisaka     RK_S32          bits_per_upper_p; /* bits per P frame in high rate */
66*437bfbebSnyanmisaka 
67*437bfbebSnyanmisaka     RK_S32          pre_diff_bit_lower;
68*437bfbebSnyanmisaka     RK_S32          pre_diff_bit_upper;
69*437bfbebSnyanmisaka     RK_S32          igop;
70*437bfbebSnyanmisaka     MppPIDCtx       pid_lower_i;
71*437bfbebSnyanmisaka     MppPIDCtx       pid_upper_i;
72*437bfbebSnyanmisaka     MppPIDCtx       pid_lower_all;
73*437bfbebSnyanmisaka     MppPIDCtx       pid_upper_all;
74*437bfbebSnyanmisaka     MppDataV2       *pid_lower_p;
75*437bfbebSnyanmisaka     MppDataV2       *pid_upper_p;
76*437bfbebSnyanmisaka     RK_S32          qp_out;
77*437bfbebSnyanmisaka     RK_S32          qp_prev_out;
78*437bfbebSnyanmisaka     RK_S32          pre_real_bit_i; /* real bit of last intra frame */
79*437bfbebSnyanmisaka     RK_S32          pre_qp_i; /* qp of last intra frame */
80*437bfbebSnyanmisaka     RK_S32          gop_qp_sum;
81*437bfbebSnyanmisaka     RK_S32          gop_frm_cnt;
82*437bfbebSnyanmisaka     RK_S32          pre_iblk4_prop;
83*437bfbebSnyanmisaka     RK_S32          reenc_cnt;
84*437bfbebSnyanmisaka     RK_U32          drop_cnt;
85*437bfbebSnyanmisaka     RK_S32          on_drop;
86*437bfbebSnyanmisaka     RK_S32          on_pskip;
87*437bfbebSnyanmisaka } RcModelV2SmtCtx;
88*437bfbebSnyanmisaka 
89*437bfbebSnyanmisaka // rc_container_bitrate_thd2
90*437bfbebSnyanmisaka static RK_S32 rc_ctnr_qp_thd1[6] = { 51, 42, 42, 51, 38, 38 };
91*437bfbebSnyanmisaka static RK_S32 rc_ctnr_qp_thd2[6] = { 51, 44, 44, 51, 40, 40 };
92*437bfbebSnyanmisaka static RK_S32 rc_ctnr_br_thd1[6] = { 100, 110, 110, 100, 110, 110 };
93*437bfbebSnyanmisaka static RK_S32 rc_ctnr_br_thd2[6] = { 100, 120, 120, 100, 125, 125 };
94*437bfbebSnyanmisaka 
bits_model_smt_deinit(RcModelV2SmtCtx * ctx)95*437bfbebSnyanmisaka MPP_RET bits_model_smt_deinit(RcModelV2SmtCtx *ctx)
96*437bfbebSnyanmisaka {
97*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
98*437bfbebSnyanmisaka 
99*437bfbebSnyanmisaka     if (ctx->qp_p) {
100*437bfbebSnyanmisaka         mpp_data_deinit(ctx->qp_p);
101*437bfbebSnyanmisaka         ctx->qp_p = NULL;
102*437bfbebSnyanmisaka     }
103*437bfbebSnyanmisaka 
104*437bfbebSnyanmisaka     if (ctx->motion_level != NULL) {
105*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->motion_level);
106*437bfbebSnyanmisaka         ctx->motion_level = NULL;
107*437bfbebSnyanmisaka     }
108*437bfbebSnyanmisaka 
109*437bfbebSnyanmisaka     if (ctx->complex_level != NULL) {
110*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->complex_level);
111*437bfbebSnyanmisaka         ctx->complex_level = NULL;
112*437bfbebSnyanmisaka     }
113*437bfbebSnyanmisaka 
114*437bfbebSnyanmisaka     if (ctx->stat_bits != NULL) {
115*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->stat_bits);
116*437bfbebSnyanmisaka         ctx->stat_bits = NULL;
117*437bfbebSnyanmisaka     }
118*437bfbebSnyanmisaka 
119*437bfbebSnyanmisaka     if (ctx->rt_bits != NULL) {
120*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->rt_bits);
121*437bfbebSnyanmisaka         ctx->rt_bits = NULL;
122*437bfbebSnyanmisaka     }
123*437bfbebSnyanmisaka 
124*437bfbebSnyanmisaka     if (ctx->pid_lower_p != NULL) {
125*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->pid_lower_p);
126*437bfbebSnyanmisaka         ctx->pid_lower_p = NULL;
127*437bfbebSnyanmisaka     }
128*437bfbebSnyanmisaka 
129*437bfbebSnyanmisaka     if (ctx->pid_upper_p != NULL) {
130*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->pid_upper_p);
131*437bfbebSnyanmisaka         ctx->pid_upper_p = NULL;
132*437bfbebSnyanmisaka     }
133*437bfbebSnyanmisaka 
134*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
135*437bfbebSnyanmisaka     return MPP_OK;
136*437bfbebSnyanmisaka }
137*437bfbebSnyanmisaka 
bits_model_smt_init(RcModelV2SmtCtx * ctx)138*437bfbebSnyanmisaka MPP_RET bits_model_smt_init(RcModelV2SmtCtx *ctx)
139*437bfbebSnyanmisaka {
140*437bfbebSnyanmisaka     RK_S32 gop_len = ctx->usr_cfg.igop;
141*437bfbebSnyanmisaka     RcFpsCfg *fps = &ctx->usr_cfg.fps;
142*437bfbebSnyanmisaka     RK_S32 mad_len = 10;
143*437bfbebSnyanmisaka     RK_S32 ave_bits_lower = 0, ave_bits_uppper = 0;
144*437bfbebSnyanmisaka     RK_S32 bits_lower_i, bits_upper_i;
145*437bfbebSnyanmisaka     RK_S32 bits_lower_p, bits_upper_p;
146*437bfbebSnyanmisaka     RK_S32 bit_ratio[5] = { 7, 8, 9, 10, 11 };
147*437bfbebSnyanmisaka     RK_S32 nfps = fps->fps_out_num / fps->fps_out_denom;
148*437bfbebSnyanmisaka     RK_S32 win_len = mpp_clip(MPP_MAX3(gop_len, nfps, 10), 1, nfps);
149*437bfbebSnyanmisaka     RK_S32 rt_stat_len = fps->fps_out_num / fps->fps_out_denom; /* real time stat len */
150*437bfbebSnyanmisaka     RK_S32 stat_len = fps->fps_out_num * ctx->usr_cfg.stats_time / fps->fps_out_denom;
151*437bfbebSnyanmisaka     stat_len = stat_len ? stat_len : (fps->fps_out_num * 8 / fps->fps_out_denom);
152*437bfbebSnyanmisaka 
153*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
154*437bfbebSnyanmisaka     ctx->frm_num = 0;
155*437bfbebSnyanmisaka     ctx->first_frm_flg = 1;
156*437bfbebSnyanmisaka     ctx->gop_frm_cnt = 0;
157*437bfbebSnyanmisaka     ctx->gop_qp_sum = 0;
158*437bfbebSnyanmisaka 
159*437bfbebSnyanmisaka     // smt
160*437bfbebSnyanmisaka     ctx->igop = gop_len;
161*437bfbebSnyanmisaka     ctx->qp_min = 10;
162*437bfbebSnyanmisaka     ctx->qp_max = 51;
163*437bfbebSnyanmisaka 
164*437bfbebSnyanmisaka     if (ctx->motion_level)
165*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->motion_level);
166*437bfbebSnyanmisaka     mpp_data_init_v2(&ctx->motion_level, mad_len, 0);
167*437bfbebSnyanmisaka 
168*437bfbebSnyanmisaka     if (ctx->complex_level)
169*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->complex_level);
170*437bfbebSnyanmisaka     mpp_data_init_v2(&ctx->complex_level, mad_len, 0);
171*437bfbebSnyanmisaka 
172*437bfbebSnyanmisaka     if (ctx->pid_lower_p)
173*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->pid_lower_p);
174*437bfbebSnyanmisaka     mpp_data_init_v2(&ctx->pid_lower_p, stat_len, 0);
175*437bfbebSnyanmisaka 
176*437bfbebSnyanmisaka     if (ctx->pid_upper_p)
177*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->pid_upper_p);
178*437bfbebSnyanmisaka     mpp_data_init_v2(&ctx->pid_upper_p, stat_len, 0);
179*437bfbebSnyanmisaka 
180*437bfbebSnyanmisaka     mpp_pid_reset(&ctx->pid_fps);
181*437bfbebSnyanmisaka     mpp_pid_reset(&ctx->pid_lower_i);
182*437bfbebSnyanmisaka     mpp_pid_reset(&ctx->pid_upper_i);
183*437bfbebSnyanmisaka     mpp_pid_reset(&ctx->pid_lower_all);
184*437bfbebSnyanmisaka     mpp_pid_reset(&ctx->pid_upper_all);
185*437bfbebSnyanmisaka 
186*437bfbebSnyanmisaka     mpp_pid_set_param(&ctx->pid_fps, 4, 6, 0, 90, win_len);
187*437bfbebSnyanmisaka     mpp_pid_set_param(&ctx->pid_lower_i, 4, 6, 0, 100, win_len);
188*437bfbebSnyanmisaka     mpp_pid_set_param(&ctx->pid_upper_i, 4, 6, 0, 100, win_len);
189*437bfbebSnyanmisaka     mpp_pid_set_param(&ctx->pid_lower_all, 4, 6, 0, 100, gop_len);
190*437bfbebSnyanmisaka     mpp_pid_set_param(&ctx->pid_upper_all, 4, 6, 0, 100, gop_len);
191*437bfbebSnyanmisaka 
192*437bfbebSnyanmisaka     ave_bits_lower = (RK_S64)ctx->usr_cfg.bps_min * fps->fps_out_denom / fps->fps_out_num;
193*437bfbebSnyanmisaka     ave_bits_uppper = (RK_S64)ctx->usr_cfg.bps_max * fps->fps_out_denom / fps->fps_out_num;
194*437bfbebSnyanmisaka 
195*437bfbebSnyanmisaka     ctx->acc_intra_count = 0;
196*437bfbebSnyanmisaka     ctx->acc_inter_count = 0;
197*437bfbebSnyanmisaka     ctx->last_fps_bits = 0;
198*437bfbebSnyanmisaka 
199*437bfbebSnyanmisaka     if (gop_len == 0) {
200*437bfbebSnyanmisaka         ctx->gop_mode = MPP_GOP_ALL_INTER;
201*437bfbebSnyanmisaka         bits_lower_p = ave_bits_lower;
202*437bfbebSnyanmisaka         bits_lower_i = ave_bits_lower * 10;
203*437bfbebSnyanmisaka         bits_upper_p = ave_bits_uppper;
204*437bfbebSnyanmisaka         bits_upper_i = ave_bits_uppper * 10;
205*437bfbebSnyanmisaka     } else if (gop_len == 1) {
206*437bfbebSnyanmisaka         ctx->gop_mode = MPP_GOP_ALL_INTRA;
207*437bfbebSnyanmisaka         bits_lower_p = 0;
208*437bfbebSnyanmisaka         bits_lower_i = ave_bits_lower;
209*437bfbebSnyanmisaka         bits_upper_p = 0;
210*437bfbebSnyanmisaka         bits_upper_i = ave_bits_uppper;
211*437bfbebSnyanmisaka         /* disable debreath on all intra case */
212*437bfbebSnyanmisaka         if (ctx->usr_cfg.debreath_cfg.enable)
213*437bfbebSnyanmisaka             ctx->usr_cfg.debreath_cfg.enable = 0;
214*437bfbebSnyanmisaka     } else if (gop_len < win_len) {
215*437bfbebSnyanmisaka         ctx->gop_mode = MPP_GOP_SMALL;
216*437bfbebSnyanmisaka         bits_lower_p = ave_bits_lower >> 1;
217*437bfbebSnyanmisaka         bits_lower_i = bits_lower_p * (gop_len + 1);
218*437bfbebSnyanmisaka         bits_upper_p = ave_bits_uppper >> 1;
219*437bfbebSnyanmisaka         bits_upper_i = bits_upper_p * (gop_len + 1);
220*437bfbebSnyanmisaka     } else {
221*437bfbebSnyanmisaka         RK_S32 g = gop_len;
222*437bfbebSnyanmisaka         RK_S32 idx = g <= 50 ? 0 : (g <= 100 ? 1 : (g <= 200 ? 2 : (g <= 300 ? 3 : 4)));
223*437bfbebSnyanmisaka 
224*437bfbebSnyanmisaka         ctx->gop_mode = MPP_GOP_LARGE;
225*437bfbebSnyanmisaka         bits_lower_i = ave_bits_lower * bit_ratio[idx] / 2;
226*437bfbebSnyanmisaka         bits_upper_i = ave_bits_uppper * bit_ratio[idx] / 2;
227*437bfbebSnyanmisaka         bits_lower_p = ave_bits_lower - bits_lower_i / (nfps - 1);
228*437bfbebSnyanmisaka         bits_upper_p = ave_bits_uppper - bits_upper_i / (nfps - 1);
229*437bfbebSnyanmisaka         ctx->fixed_i_pred_bit = (ctx->usr_cfg.bps_max / nfps * 8) / 8;
230*437bfbebSnyanmisaka         ctx->fixed_p_pred_bit = ((ctx->usr_cfg.bps_max * g / nfps - ctx->fixed_i_pred_bit) / (g - 1)) / 8;
231*437bfbebSnyanmisaka     }
232*437bfbebSnyanmisaka 
233*437bfbebSnyanmisaka     ctx->bits_per_lower_i = bits_lower_i;
234*437bfbebSnyanmisaka     ctx->bits_per_upper_i = bits_upper_i;
235*437bfbebSnyanmisaka     ctx->bits_per_lower_p = bits_lower_p;
236*437bfbebSnyanmisaka     ctx->bits_per_upper_p = bits_upper_p;
237*437bfbebSnyanmisaka 
238*437bfbebSnyanmisaka     rc_dbg_rc("bits_per_lower_i %d, bits_per_upper_i %d, "
239*437bfbebSnyanmisaka               "bits_per_lower_p %d, bits_per_upper_p %d\n",
240*437bfbebSnyanmisaka               bits_lower_i, bits_upper_i, bits_lower_p, bits_upper_p);
241*437bfbebSnyanmisaka 
242*437bfbebSnyanmisaka     if (ctx->stat_bits)
243*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->stat_bits);
244*437bfbebSnyanmisaka     mpp_data_init_v2(&ctx->stat_bits, stat_len, bits_upper_p);
245*437bfbebSnyanmisaka 
246*437bfbebSnyanmisaka     if (ctx->rt_bits)
247*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->rt_bits);
248*437bfbebSnyanmisaka     mpp_data_init_v2(&ctx->rt_bits, rt_stat_len, bits_upper_p);
249*437bfbebSnyanmisaka 
250*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
251*437bfbebSnyanmisaka     return MPP_OK;
252*437bfbebSnyanmisaka }
253*437bfbebSnyanmisaka 
bits_model_update_smt(RcModelV2SmtCtx * ctx,RK_S32 real_bit)254*437bfbebSnyanmisaka MPP_RET bits_model_update_smt(RcModelV2SmtCtx *ctx, RK_S32 real_bit)
255*437bfbebSnyanmisaka {
256*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
257*437bfbebSnyanmisaka     RcFpsCfg *fps = &ctx->usr_cfg.fps;
258*437bfbebSnyanmisaka     RK_S32 bps_target_tmp = 0;
259*437bfbebSnyanmisaka     RK_S32 mod = 0;
260*437bfbebSnyanmisaka 
261*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
262*437bfbebSnyanmisaka 
263*437bfbebSnyanmisaka     mpp_data_update_v2(ctx->stat_bits, real_bit);
264*437bfbebSnyanmisaka     ctx->pre_diff_bit_lower = ctx->bits_tgt_lower - real_bit;
265*437bfbebSnyanmisaka     ctx->pre_diff_bit_upper = ctx->bits_tgt_upper - real_bit;
266*437bfbebSnyanmisaka 
267*437bfbebSnyanmisaka     ctx->count_real_bit = ctx->count_real_bit + real_bit / 8;
268*437bfbebSnyanmisaka     if (ctx->frame_type == INTRA_FRAME) {
269*437bfbebSnyanmisaka         ctx->count_pred_bit = ctx->count_pred_bit + ctx->fixed_i_pred_bit;
270*437bfbebSnyanmisaka     } else {
271*437bfbebSnyanmisaka         ctx->count_pred_bit = ctx->count_pred_bit + ctx->fixed_p_pred_bit;
272*437bfbebSnyanmisaka     }
273*437bfbebSnyanmisaka     ctx->count_frame ++;
274*437bfbebSnyanmisaka     if (ctx->count_real_bit > 72057594037927935 || ctx->count_pred_bit > 72057594037927935) {
275*437bfbebSnyanmisaka         ctx->count_real_bit = 0;
276*437bfbebSnyanmisaka         ctx->count_pred_bit = 0;
277*437bfbebSnyanmisaka     }
278*437bfbebSnyanmisaka 
279*437bfbebSnyanmisaka     if (ctx->change_bit_flag == 1) {
280*437bfbebSnyanmisaka         real_bit = real_bit * 8 / 10;
281*437bfbebSnyanmisaka     }
282*437bfbebSnyanmisaka 
283*437bfbebSnyanmisaka     if (ctx->frame_type == INTRA_FRAME) {
284*437bfbebSnyanmisaka         ctx->acc_intra_count++;
285*437bfbebSnyanmisaka         mpp_pid_update(&ctx->pid_lower_i, real_bit - ctx->bits_tgt_lower, 1);
286*437bfbebSnyanmisaka         mpp_pid_update(&ctx->pid_upper_i, real_bit - ctx->bits_tgt_upper, 1);
287*437bfbebSnyanmisaka     } else {
288*437bfbebSnyanmisaka         ctx->acc_inter_count++;
289*437bfbebSnyanmisaka         mpp_data_update_v2(ctx->pid_lower_p, real_bit - ctx->bits_tgt_lower);
290*437bfbebSnyanmisaka         mpp_data_update_v2(ctx->pid_upper_p, real_bit - ctx->bits_tgt_upper);
291*437bfbebSnyanmisaka     }
292*437bfbebSnyanmisaka     mpp_pid_update(&ctx->pid_lower_all, real_bit - ctx->bits_tgt_lower, 1);
293*437bfbebSnyanmisaka     mpp_pid_update(&ctx->pid_upper_all, real_bit - ctx->bits_tgt_upper, 1);
294*437bfbebSnyanmisaka 
295*437bfbebSnyanmisaka     ctx->last_fps_bits += real_bit;
296*437bfbebSnyanmisaka     /* new fps start */
297*437bfbebSnyanmisaka     mod = ctx->acc_intra_count + ctx->acc_inter_count;
298*437bfbebSnyanmisaka     mod = mod % (fps->fps_out_num / fps->fps_out_denom);
299*437bfbebSnyanmisaka     if (0 == mod) {
300*437bfbebSnyanmisaka         bps_target_tmp = (ctx->usr_cfg.bps_min + ctx->usr_cfg.bps_max) >> 1;
301*437bfbebSnyanmisaka         if (bps_target_tmp * 3 > (ctx->last_fps_bits * 2))
302*437bfbebSnyanmisaka             mpp_pid_update(&ctx->pid_fps, bps_target_tmp - ctx->last_fps_bits, 0);
303*437bfbebSnyanmisaka         else {
304*437bfbebSnyanmisaka             bps_target_tmp = ctx->usr_cfg.bps_min * 4 / 10 + ctx->usr_cfg.bps_max * 6 / 10;
305*437bfbebSnyanmisaka             mpp_pid_update(&ctx->pid_fps, bps_target_tmp - ctx->last_fps_bits, 0);
306*437bfbebSnyanmisaka         }
307*437bfbebSnyanmisaka         ctx->last_fps_bits = 0;
308*437bfbebSnyanmisaka     }
309*437bfbebSnyanmisaka 
310*437bfbebSnyanmisaka     /* new frame start */
311*437bfbebSnyanmisaka     ctx->qp_prev_out = ctx->qp_out;
312*437bfbebSnyanmisaka 
313*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
314*437bfbebSnyanmisaka 
315*437bfbebSnyanmisaka     return MPP_OK;
316*437bfbebSnyanmisaka }
317*437bfbebSnyanmisaka 
rc_model_v2_smt_h265_init(void * ctx,RcCfg * cfg)318*437bfbebSnyanmisaka MPP_RET rc_model_v2_smt_h265_init(void *ctx, RcCfg *cfg)
319*437bfbebSnyanmisaka {
320*437bfbebSnyanmisaka     RcModelV2SmtCtx *p = (RcModelV2SmtCtx*)ctx;
321*437bfbebSnyanmisaka 
322*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
323*437bfbebSnyanmisaka 
324*437bfbebSnyanmisaka     memcpy(&p->usr_cfg, cfg, sizeof(RcCfg));
325*437bfbebSnyanmisaka     bits_model_smt_init(p);
326*437bfbebSnyanmisaka 
327*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
328*437bfbebSnyanmisaka     return MPP_OK;
329*437bfbebSnyanmisaka }
330*437bfbebSnyanmisaka 
rc_model_v2_smt_h264_init(void * ctx,RcCfg * cfg)331*437bfbebSnyanmisaka MPP_RET rc_model_v2_smt_h264_init(void *ctx, RcCfg *cfg)
332*437bfbebSnyanmisaka {
333*437bfbebSnyanmisaka     RcModelV2SmtCtx *p = (RcModelV2SmtCtx*)ctx;
334*437bfbebSnyanmisaka 
335*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
336*437bfbebSnyanmisaka 
337*437bfbebSnyanmisaka     memcpy(&p->usr_cfg, cfg, sizeof(RcCfg));
338*437bfbebSnyanmisaka     bits_model_smt_init(p);
339*437bfbebSnyanmisaka 
340*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
341*437bfbebSnyanmisaka     return MPP_OK;
342*437bfbebSnyanmisaka }
343*437bfbebSnyanmisaka 
344*437bfbebSnyanmisaka 
rc_model_v2_smt_deinit(void * ctx)345*437bfbebSnyanmisaka MPP_RET rc_model_v2_smt_deinit(void *ctx)
346*437bfbebSnyanmisaka {
347*437bfbebSnyanmisaka     RcModelV2SmtCtx *p = (RcModelV2SmtCtx *)ctx;
348*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
349*437bfbebSnyanmisaka     bits_model_smt_deinit(p);
350*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
351*437bfbebSnyanmisaka     return MPP_OK;
352*437bfbebSnyanmisaka }
353*437bfbebSnyanmisaka 
set_coef(void * ctx,RK_S32 * coef,RK_S32 val)354*437bfbebSnyanmisaka static void set_coef(void *ctx, RK_S32 *coef, RK_S32 val)
355*437bfbebSnyanmisaka {
356*437bfbebSnyanmisaka     RcModelV2SmtCtx *p = (RcModelV2SmtCtx*)ctx;
357*437bfbebSnyanmisaka     RK_S32 cplx_lvl_0 = mpp_data_get_pre_val_v2(p->complex_level, 0);
358*437bfbebSnyanmisaka     RK_S32 cplx_lvl_1 = mpp_data_get_pre_val_v2(p->complex_level, 1);
359*437bfbebSnyanmisaka     RK_S32 cplx_lvl_sum = mpp_data_sum_v2(p->complex_level);
360*437bfbebSnyanmisaka 
361*437bfbebSnyanmisaka     if (cplx_lvl_sum == 0)
362*437bfbebSnyanmisaka         *coef = val + 0;
363*437bfbebSnyanmisaka     else if (cplx_lvl_sum == 1) {
364*437bfbebSnyanmisaka         if (cplx_lvl_0 == 0)
365*437bfbebSnyanmisaka             *coef = val + 10;
366*437bfbebSnyanmisaka         else
367*437bfbebSnyanmisaka             *coef = val + 25;
368*437bfbebSnyanmisaka     } else if (cplx_lvl_sum == 2) {
369*437bfbebSnyanmisaka         if (cplx_lvl_0 == 0)
370*437bfbebSnyanmisaka             *coef = val + 25;
371*437bfbebSnyanmisaka         else
372*437bfbebSnyanmisaka             *coef = val + 35;
373*437bfbebSnyanmisaka     } else if (cplx_lvl_sum == 3) {
374*437bfbebSnyanmisaka         if (cplx_lvl_0 == 0)
375*437bfbebSnyanmisaka             *coef = val + 35;
376*437bfbebSnyanmisaka         else
377*437bfbebSnyanmisaka             *coef = val + 51;
378*437bfbebSnyanmisaka     } else if (cplx_lvl_sum >= 4 && cplx_lvl_sum <= 6) {
379*437bfbebSnyanmisaka         if (cplx_lvl_0 == 0) {
380*437bfbebSnyanmisaka             if (cplx_lvl_1 == 0)
381*437bfbebSnyanmisaka                 *coef = val + 35;
382*437bfbebSnyanmisaka             else
383*437bfbebSnyanmisaka                 *coef = val + 51;
384*437bfbebSnyanmisaka         } else
385*437bfbebSnyanmisaka             *coef = val + 64;
386*437bfbebSnyanmisaka     } else if (cplx_lvl_sum >= 7 && cplx_lvl_sum <= 9) {
387*437bfbebSnyanmisaka         if (cplx_lvl_0 == 0) {
388*437bfbebSnyanmisaka             if (cplx_lvl_1 == 0)
389*437bfbebSnyanmisaka                 *coef = val + 64;
390*437bfbebSnyanmisaka             else
391*437bfbebSnyanmisaka                 *coef = val + 72;
392*437bfbebSnyanmisaka         } else
393*437bfbebSnyanmisaka             *coef = val + 72;
394*437bfbebSnyanmisaka     } else
395*437bfbebSnyanmisaka         *coef = val + 80;
396*437bfbebSnyanmisaka }
397*437bfbebSnyanmisaka 
398*437bfbebSnyanmisaka static RK_U32 mb_num[9] = {
399*437bfbebSnyanmisaka     0, 200, 700, 1200, 2000, 4000, 8000, 16000, 20000
400*437bfbebSnyanmisaka };
401*437bfbebSnyanmisaka 
402*437bfbebSnyanmisaka static RK_U32 tab_bit[9] = {
403*437bfbebSnyanmisaka     3780, 3570, 3150, 2940, 2730, 3780, 2100, 1680, 2100
404*437bfbebSnyanmisaka };
405*437bfbebSnyanmisaka 
406*437bfbebSnyanmisaka static RK_U8 qscale2qp[96] = {
407*437bfbebSnyanmisaka     15,  15,  15,  15,  15,  16, 18, 20, 21, 22, 23,
408*437bfbebSnyanmisaka     24,  25,  25,  26,  27,  28, 28, 29, 29, 30, 30,
409*437bfbebSnyanmisaka     30,  31,  31,  32,  32,  33, 33, 33, 34, 34, 34,
410*437bfbebSnyanmisaka     34,  35,  35,  35,  36,  36, 36, 36, 36, 37, 37,
411*437bfbebSnyanmisaka     37,  37,  38,  38,  38,  38, 38, 39, 39, 39, 39,
412*437bfbebSnyanmisaka     39,  39,  40,  40,  40,  40, 41, 41, 41, 41, 41,
413*437bfbebSnyanmisaka     41,  41,  42,  42,  42,  42, 42, 42, 42, 42, 43,
414*437bfbebSnyanmisaka     43,  43,  43,  43,  43,  43, 43, 44, 44, 44, 44,
415*437bfbebSnyanmisaka     44,  44,  44,  44,  45,  45, 45, 45,
416*437bfbebSnyanmisaka };
417*437bfbebSnyanmisaka 
418*437bfbebSnyanmisaka static RK_U8 inter_pqp0[52] = {
419*437bfbebSnyanmisaka     1,  1,  1,  1,  1,  2,  3,  4,
420*437bfbebSnyanmisaka     5,  6,  7,  8,  9,  10, 11, 12,
421*437bfbebSnyanmisaka     13, 14, 15, 17, 18, 19, 20, 21,
422*437bfbebSnyanmisaka     21, 21, 22, 23, 24, 25, 26, 26,
423*437bfbebSnyanmisaka     27, 28, 28, 29, 29, 29, 30, 31,
424*437bfbebSnyanmisaka     31, 32, 32, 33, 33, 34, 35, 35,
425*437bfbebSnyanmisaka     35, 36, 36, 36
426*437bfbebSnyanmisaka };
427*437bfbebSnyanmisaka 
428*437bfbebSnyanmisaka static RK_U8 inter_pqp1[52] = {
429*437bfbebSnyanmisaka     1,  1,  2,  3,  4,  5,  6,  7,
430*437bfbebSnyanmisaka     8,  9,  10, 11, 12, 13, 14, 15,
431*437bfbebSnyanmisaka     16, 17, 18, 19, 20, 20, 21, 22,
432*437bfbebSnyanmisaka     23, 24, 25, 26, 26, 27, 28, 29,
433*437bfbebSnyanmisaka     29, 30, 31, 31, 32, 33, 34, 35,
434*437bfbebSnyanmisaka     36, 37, 38, 39, 40, 41, 42, 42,
435*437bfbebSnyanmisaka     42, 43, 43, 44
436*437bfbebSnyanmisaka };
437*437bfbebSnyanmisaka 
438*437bfbebSnyanmisaka static RK_U8 intra_pqp0[3][52] = {
439*437bfbebSnyanmisaka     {
440*437bfbebSnyanmisaka         1,  1,  1,  2,  3,  4,  5,  6,
441*437bfbebSnyanmisaka         7,  8,  9,  10, 11, 12, 13, 14,
442*437bfbebSnyanmisaka         15, 16, 17, 18, 19, 20, 21, 22,
443*437bfbebSnyanmisaka         23, 23, 24, 25, 26, 27, 27, 28,
444*437bfbebSnyanmisaka         28, 29, 30, 31, 32, 32, 33, 34,
445*437bfbebSnyanmisaka         34, 34, 35, 35, 36, 36, 36, 36,
446*437bfbebSnyanmisaka         37, 37, 37, 38
447*437bfbebSnyanmisaka     },
448*437bfbebSnyanmisaka 
449*437bfbebSnyanmisaka     {
450*437bfbebSnyanmisaka         1,  1,  1,  2,  3,  4,  5,  6,
451*437bfbebSnyanmisaka         7,  8,  9,  10, 11, 12, 13, 14,
452*437bfbebSnyanmisaka         15, 16, 17, 17, 18, 18, 19, 19,
453*437bfbebSnyanmisaka         20, 21, 22, 23, 24, 25, 26, 27,
454*437bfbebSnyanmisaka         28, 29, 30, 31, 32, 32, 33, 34,
455*437bfbebSnyanmisaka         34, 34, 35, 35, 36, 36, 36, 36,
456*437bfbebSnyanmisaka         37, 37, 37, 38
457*437bfbebSnyanmisaka     },
458*437bfbebSnyanmisaka 
459*437bfbebSnyanmisaka     {
460*437bfbebSnyanmisaka         1,  1,  1,  2,  3,  4,  5,  6,
461*437bfbebSnyanmisaka         7,  8,  9,  10, 11, 12, 13, 14,
462*437bfbebSnyanmisaka         14, 15, 15, 16, 16, 17, 17, 18,
463*437bfbebSnyanmisaka         16, 16, 16, 17, 18, 19, 20, 21,
464*437bfbebSnyanmisaka         23, 24, 26, 28, 30, 31, 32, 33,
465*437bfbebSnyanmisaka         34, 34, 35, 35, 36, 36, 36, 36,
466*437bfbebSnyanmisaka         37, 37, 37, 38
467*437bfbebSnyanmisaka     },
468*437bfbebSnyanmisaka };
469*437bfbebSnyanmisaka 
470*437bfbebSnyanmisaka static RK_U8 intra_pqp1[52] = {
471*437bfbebSnyanmisaka     2,  3,  4,  5,  6,  7,  8,  9,
472*437bfbebSnyanmisaka     10, 11, 12, 13, 14, 15, 16, 17,
473*437bfbebSnyanmisaka     18, 19, 20, 22, 23, 24, 25, 26,
474*437bfbebSnyanmisaka     27, 28, 29, 30, 31, 32, 33, 34,
475*437bfbebSnyanmisaka     35, 36, 37, 38, 39, 40, 41, 42,
476*437bfbebSnyanmisaka     43, 44, 45, 46, 47, 48, 49, 50,
477*437bfbebSnyanmisaka     51, 51, 51, 51
478*437bfbebSnyanmisaka };
479*437bfbebSnyanmisaka 
cal_smt_first_i_start_qp(RK_S32 target_bit,RK_U32 total_mb)480*437bfbebSnyanmisaka static RK_S32 cal_smt_first_i_start_qp(RK_S32 target_bit, RK_U32 total_mb)
481*437bfbebSnyanmisaka {
482*437bfbebSnyanmisaka     RK_S32 cnt = 0;
483*437bfbebSnyanmisaka     RK_S32 index;
484*437bfbebSnyanmisaka     RK_S32 i;
485*437bfbebSnyanmisaka 
486*437bfbebSnyanmisaka     for (i = 0; i < 8; i++) {
487*437bfbebSnyanmisaka         if (mb_num[i] > total_mb)
488*437bfbebSnyanmisaka             break;
489*437bfbebSnyanmisaka         cnt++;
490*437bfbebSnyanmisaka     }
491*437bfbebSnyanmisaka 
492*437bfbebSnyanmisaka     index = (total_mb * tab_bit[cnt] - 350) / target_bit; // qscale
493*437bfbebSnyanmisaka     index = mpp_clip(index, 4, 95);
494*437bfbebSnyanmisaka 
495*437bfbebSnyanmisaka     return qscale2qp[index];
496*437bfbebSnyanmisaka }
497*437bfbebSnyanmisaka 
calc_smt_debreath_qp(RcModelV2SmtCtx * ctx)498*437bfbebSnyanmisaka static MPP_RET calc_smt_debreath_qp(RcModelV2SmtCtx * ctx)
499*437bfbebSnyanmisaka {
500*437bfbebSnyanmisaka     RK_S32 fm_qp_sum = 0;
501*437bfbebSnyanmisaka     RK_S32 new_fm_qp = 0;
502*437bfbebSnyanmisaka     RcDebreathCfg *debreath_cfg = &ctx->usr_cfg.debreath_cfg;
503*437bfbebSnyanmisaka     RK_S32 dealt_qp = 0;
504*437bfbebSnyanmisaka     RK_S32 gop_qp_sum = ctx->gop_qp_sum;
505*437bfbebSnyanmisaka     RK_S32 gop_frm_cnt = ctx->gop_frm_cnt;
506*437bfbebSnyanmisaka     static RK_S8 intra_qp_map[8] = {
507*437bfbebSnyanmisaka         0, 0, 1, 1, 2, 2, 2, 2,
508*437bfbebSnyanmisaka     };
509*437bfbebSnyanmisaka     RK_U8 idx2 = MPP_MIN(ctx->pre_iblk4_prop >> 5, (RK_S32)sizeof(intra_qp_map) - 1);
510*437bfbebSnyanmisaka 
511*437bfbebSnyanmisaka     static RK_S8 strength_map[36] = {
512*437bfbebSnyanmisaka         0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4,
513*437bfbebSnyanmisaka         5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8,
514*437bfbebSnyanmisaka         9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12
515*437bfbebSnyanmisaka     };
516*437bfbebSnyanmisaka 
517*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
518*437bfbebSnyanmisaka 
519*437bfbebSnyanmisaka     fm_qp_sum = MPP_MIN(gop_qp_sum / gop_frm_cnt, (RK_S32)sizeof(strength_map) - 1);
520*437bfbebSnyanmisaka 
521*437bfbebSnyanmisaka     rc_dbg_qp("i qp_out %d, qp_start_sum = %d, intra_lv4_prop %d",
522*437bfbebSnyanmisaka               ctx->qp_out, fm_qp_sum, ctx->pre_iblk4_prop);
523*437bfbebSnyanmisaka 
524*437bfbebSnyanmisaka     dealt_qp = strength_map[debreath_cfg->strength] - intra_qp_map[idx2];
525*437bfbebSnyanmisaka     if (fm_qp_sum > dealt_qp)
526*437bfbebSnyanmisaka         new_fm_qp = fm_qp_sum - dealt_qp;
527*437bfbebSnyanmisaka     else
528*437bfbebSnyanmisaka         new_fm_qp = fm_qp_sum;
529*437bfbebSnyanmisaka 
530*437bfbebSnyanmisaka     ctx->qp_out = mpp_clip(new_fm_qp, ctx->usr_cfg.min_i_quality, ctx->usr_cfg.max_i_quality);
531*437bfbebSnyanmisaka     ctx->gop_frm_cnt = 0;
532*437bfbebSnyanmisaka     ctx->gop_qp_sum = 0;
533*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
534*437bfbebSnyanmisaka     return MPP_OK;
535*437bfbebSnyanmisaka }
536*437bfbebSnyanmisaka 
smt_start_prepare(void * ctx,EncRcTask * task)537*437bfbebSnyanmisaka static MPP_RET smt_start_prepare(void *ctx, EncRcTask *task)
538*437bfbebSnyanmisaka {
539*437bfbebSnyanmisaka     EncFrmStatus *frm = &task->frm;
540*437bfbebSnyanmisaka     RcModelV2SmtCtx *p = (RcModelV2SmtCtx *) ctx;
541*437bfbebSnyanmisaka     EncRcTaskInfo *info = &task->info;
542*437bfbebSnyanmisaka     RcFpsCfg *fps = &p->usr_cfg.fps;
543*437bfbebSnyanmisaka     RK_S32 fps_out = fps->fps_out_num / fps->fps_out_denom;
544*437bfbebSnyanmisaka     RK_S32 b_min = p->usr_cfg.bps_min;
545*437bfbebSnyanmisaka     RK_S32 b_max = p->usr_cfg.bps_max;
546*437bfbebSnyanmisaka     RK_S32 bits_lower, bits_upper;
547*437bfbebSnyanmisaka 
548*437bfbebSnyanmisaka     p->frame_type = frm->is_intra ? INTRA_FRAME : INTER_P_FRAME;
549*437bfbebSnyanmisaka     if (frm->ref_mode == REF_TO_PREV_INTRA)
550*437bfbebSnyanmisaka         p->frame_type = info->frame_type = INTER_VI_FRAME;
551*437bfbebSnyanmisaka 
552*437bfbebSnyanmisaka     switch (p->gop_mode) {
553*437bfbebSnyanmisaka     case MPP_GOP_ALL_INTER: {
554*437bfbebSnyanmisaka         if (p->frame_type == INTRA_FRAME) {
555*437bfbebSnyanmisaka             bits_lower = p->bits_per_lower_i;
556*437bfbebSnyanmisaka             bits_upper = p->bits_per_upper_i;
557*437bfbebSnyanmisaka         } else {
558*437bfbebSnyanmisaka             bits_lower = p->bits_per_lower_p - mpp_data_mean_v2(p->pid_lower_p);
559*437bfbebSnyanmisaka             bits_upper = p->bits_per_upper_p - mpp_data_mean_v2(p->pid_upper_p);
560*437bfbebSnyanmisaka         }
561*437bfbebSnyanmisaka     } break;
562*437bfbebSnyanmisaka     case MPP_GOP_ALL_INTRA: {
563*437bfbebSnyanmisaka         bits_lower = p->bits_per_lower_i - mpp_pid_calc(&p->pid_lower_i);
564*437bfbebSnyanmisaka         bits_upper = p->bits_per_upper_i - mpp_pid_calc(&p->pid_upper_i);
565*437bfbebSnyanmisaka     } break;
566*437bfbebSnyanmisaka     default: {
567*437bfbebSnyanmisaka         if (p->frame_type == INTRA_FRAME) {
568*437bfbebSnyanmisaka             RK_S32 diff_bit = mpp_pid_calc(&p->pid_fps);
569*437bfbebSnyanmisaka 
570*437bfbebSnyanmisaka             p->pre_gop_left_bit = p->pid_fps.i - diff_bit;
571*437bfbebSnyanmisaka             mpp_pid_reset(&p->pid_fps);
572*437bfbebSnyanmisaka             if (p->acc_intra_count) {
573*437bfbebSnyanmisaka                 bits_lower = (p->bits_per_lower_i + diff_bit);
574*437bfbebSnyanmisaka                 bits_upper = (p->bits_per_upper_i + diff_bit);
575*437bfbebSnyanmisaka             } else {
576*437bfbebSnyanmisaka                 bits_lower = p->bits_per_lower_i - mpp_pid_calc(&p->pid_lower_i);
577*437bfbebSnyanmisaka                 bits_upper = p->bits_per_upper_i - mpp_pid_calc(&p->pid_upper_i);
578*437bfbebSnyanmisaka             }
579*437bfbebSnyanmisaka         } else {
580*437bfbebSnyanmisaka             if (p->last_frame_type == INTRA_FRAME) {
581*437bfbebSnyanmisaka                 RK_S32 bits_prev_i = p->pre_real_bit_i;
582*437bfbebSnyanmisaka 
583*437bfbebSnyanmisaka                 bits_lower = p->bits_per_lower_p
584*437bfbebSnyanmisaka                              = ((RK_S64)b_min * p->igop / fps_out - bits_prev_i +
585*437bfbebSnyanmisaka                                 p->pre_gop_left_bit) / (p->igop - 1);
586*437bfbebSnyanmisaka 
587*437bfbebSnyanmisaka                 bits_upper = p->bits_per_upper_p
588*437bfbebSnyanmisaka                              = ((RK_S64)b_max * p->igop / fps_out - bits_prev_i +
589*437bfbebSnyanmisaka                                 p->pre_gop_left_bit) / (p->igop - 1);
590*437bfbebSnyanmisaka 
591*437bfbebSnyanmisaka             } else {
592*437bfbebSnyanmisaka                 RK_S32 diff_bit_lr = mpp_data_mean_v2(p->pid_lower_p);
593*437bfbebSnyanmisaka                 RK_S32 diff_bit_hr = mpp_data_mean_v2(p->pid_upper_p);
594*437bfbebSnyanmisaka                 RK_S32 lr = (RK_S64)b_min * fps->fps_out_denom / fps->fps_out_num;
595*437bfbebSnyanmisaka                 RK_S32 hr = (RK_S64)b_max * fps->fps_out_denom / fps->fps_out_num;
596*437bfbebSnyanmisaka 
597*437bfbebSnyanmisaka                 bits_lower = p->bits_per_lower_p - diff_bit_lr;
598*437bfbebSnyanmisaka                 if (bits_lower > 2 * lr)
599*437bfbebSnyanmisaka                     bits_lower = 2 * lr;
600*437bfbebSnyanmisaka 
601*437bfbebSnyanmisaka                 bits_upper = p->bits_per_upper_p - diff_bit_hr;
602*437bfbebSnyanmisaka                 if (bits_upper > 2 * hr)
603*437bfbebSnyanmisaka                     bits_upper = 2 * hr;
604*437bfbebSnyanmisaka             }
605*437bfbebSnyanmisaka 
606*437bfbebSnyanmisaka         }
607*437bfbebSnyanmisaka     } break;
608*437bfbebSnyanmisaka     }
609*437bfbebSnyanmisaka 
610*437bfbebSnyanmisaka     p->bits_tgt_lower = bits_lower;
611*437bfbebSnyanmisaka     p->bits_tgt_upper = bits_upper;
612*437bfbebSnyanmisaka     info->bit_max = (bits_lower + bits_upper) / 2;
613*437bfbebSnyanmisaka     if (info->bit_max < 100)
614*437bfbebSnyanmisaka         info->bit_max = 100;
615*437bfbebSnyanmisaka 
616*437bfbebSnyanmisaka     if (NULL == p->qp_p) {
617*437bfbebSnyanmisaka         RK_S32 nfps = fps_out < 15 ? 4 * fps_out : (fps_out < 25 ? 3 * fps_out : 2 * fps_out);
618*437bfbebSnyanmisaka         mpp_data_init(&p->qp_p, mpp_clip(MPP_MAX(p->igop, nfps), 20, 50));
619*437bfbebSnyanmisaka     }
620*437bfbebSnyanmisaka 
621*437bfbebSnyanmisaka     rc_dbg_rc("bits_tgt_lower %d, bits_tgt_upper %d, bit_max %d, qp_out %d",
622*437bfbebSnyanmisaka               p->bits_tgt_lower, p->bits_tgt_upper, info->bit_max, p->qp_out);
623*437bfbebSnyanmisaka 
624*437bfbebSnyanmisaka     return MPP_OK;
625*437bfbebSnyanmisaka }
626*437bfbebSnyanmisaka 
smt_calc_coef(void * ctx)627*437bfbebSnyanmisaka static RK_S32 smt_calc_coef(void *ctx)
628*437bfbebSnyanmisaka {
629*437bfbebSnyanmisaka     RcModelV2SmtCtx *p = (RcModelV2SmtCtx *) ctx;
630*437bfbebSnyanmisaka     RK_S32 coef = 1024;
631*437bfbebSnyanmisaka     RK_S32 coef2 = 512;
632*437bfbebSnyanmisaka     RK_S32 md_lvl_sum = mpp_data_sum_v2(p->motion_level);
633*437bfbebSnyanmisaka     RK_S32 md_lvl_0 = mpp_data_get_pre_val_v2(p->motion_level, 0);
634*437bfbebSnyanmisaka     RK_S32 md_lvl_1 = mpp_data_get_pre_val_v2(p->motion_level, 1);
635*437bfbebSnyanmisaka 
636*437bfbebSnyanmisaka     if (md_lvl_sum < 100)
637*437bfbebSnyanmisaka         set_coef(ctx, &coef, 0);
638*437bfbebSnyanmisaka     else if (md_lvl_sum < 200) {
639*437bfbebSnyanmisaka         if (md_lvl_0 < 100)
640*437bfbebSnyanmisaka             set_coef(ctx, &coef, 102);
641*437bfbebSnyanmisaka         else
642*437bfbebSnyanmisaka             set_coef(ctx, &coef, 154);
643*437bfbebSnyanmisaka     } else if (md_lvl_sum < 300) {
644*437bfbebSnyanmisaka         if (md_lvl_0 < 100)
645*437bfbebSnyanmisaka             set_coef(ctx, &coef, 154);
646*437bfbebSnyanmisaka         else if (md_lvl_0 == 100) {
647*437bfbebSnyanmisaka             if (md_lvl_1  < 100)
648*437bfbebSnyanmisaka                 set_coef(ctx, &coef, 205);
649*437bfbebSnyanmisaka             else if (md_lvl_1 == 100)
650*437bfbebSnyanmisaka                 set_coef(ctx, &coef, 256);
651*437bfbebSnyanmisaka             else
652*437bfbebSnyanmisaka                 set_coef(ctx, &coef, 307);
653*437bfbebSnyanmisaka         } else
654*437bfbebSnyanmisaka             set_coef(ctx, &coef, 307);
655*437bfbebSnyanmisaka     } else if (md_lvl_sum < 600) {
656*437bfbebSnyanmisaka         if (md_lvl_0 < 100) {
657*437bfbebSnyanmisaka             if (md_lvl_1  < 100)
658*437bfbebSnyanmisaka                 set_coef(ctx, &coef, 307);
659*437bfbebSnyanmisaka             else if (md_lvl_1 == 100)
660*437bfbebSnyanmisaka                 set_coef(ctx, &coef, 358);
661*437bfbebSnyanmisaka             else
662*437bfbebSnyanmisaka                 set_coef(ctx, &coef, 410);
663*437bfbebSnyanmisaka         } else if (md_lvl_0 == 100) {
664*437bfbebSnyanmisaka             if (md_lvl_1  < 100)
665*437bfbebSnyanmisaka                 set_coef(ctx, &coef, 358);
666*437bfbebSnyanmisaka             else if (md_lvl_1 == 100)
667*437bfbebSnyanmisaka                 set_coef(ctx, &coef, 410);
668*437bfbebSnyanmisaka             else
669*437bfbebSnyanmisaka                 set_coef(ctx, &coef, 461);
670*437bfbebSnyanmisaka         } else
671*437bfbebSnyanmisaka             set_coef(ctx, &coef, 461);
672*437bfbebSnyanmisaka     } else if (md_lvl_sum < 900) {
673*437bfbebSnyanmisaka         if (md_lvl_0 < 100) {
674*437bfbebSnyanmisaka             if (md_lvl_1 < 100)
675*437bfbebSnyanmisaka                 set_coef(ctx, &coef, 410);
676*437bfbebSnyanmisaka             else if (md_lvl_1 == 100)
677*437bfbebSnyanmisaka                 set_coef(ctx, &coef, 461);
678*437bfbebSnyanmisaka             else
679*437bfbebSnyanmisaka                 set_coef(ctx, &coef, 512);
680*437bfbebSnyanmisaka         } else if (md_lvl_0 == 100) {
681*437bfbebSnyanmisaka             if (md_lvl_1 < 100)
682*437bfbebSnyanmisaka                 set_coef(ctx, &coef, 512);
683*437bfbebSnyanmisaka             else if (md_lvl_1 == 100)
684*437bfbebSnyanmisaka                 set_coef(ctx, &coef, 563);
685*437bfbebSnyanmisaka             else
686*437bfbebSnyanmisaka                 set_coef(ctx, &coef, 614);
687*437bfbebSnyanmisaka         } else
688*437bfbebSnyanmisaka             set_coef(ctx, &coef, 614);
689*437bfbebSnyanmisaka     } else if (md_lvl_sum < 1500)
690*437bfbebSnyanmisaka         set_coef(ctx, &coef, 666);
691*437bfbebSnyanmisaka     else if (md_lvl_sum < 1900)
692*437bfbebSnyanmisaka         set_coef(ctx, &coef, 768);
693*437bfbebSnyanmisaka     else
694*437bfbebSnyanmisaka         set_coef(ctx, &coef, 900);
695*437bfbebSnyanmisaka 
696*437bfbebSnyanmisaka     if (coef > 1024)
697*437bfbebSnyanmisaka         coef = 1024;
698*437bfbebSnyanmisaka 
699*437bfbebSnyanmisaka     if (coef >= 900)
700*437bfbebSnyanmisaka         coef2 = 1024;
701*437bfbebSnyanmisaka     else if (coef >= 307)    // 0.7~0.3 --> 1.0~0.5
702*437bfbebSnyanmisaka         coef2 = 512 + (coef - 307) * (1024 - 512) / (717 - 307);
703*437bfbebSnyanmisaka     else    // 0.3~0.0 --> 0.5~0.0
704*437bfbebSnyanmisaka         coef2 = 0 + coef * (512 - 0) / (307 - 0);
705*437bfbebSnyanmisaka     if (coef2 >= 1024)
706*437bfbebSnyanmisaka         coef2 = 1024;
707*437bfbebSnyanmisaka 
708*437bfbebSnyanmisaka     return coef2;
709*437bfbebSnyanmisaka }
710*437bfbebSnyanmisaka 
711*437bfbebSnyanmisaka /* bit_target_use: average of bits_tgt_lower and bits_tgt_upper */
derive_iframe_qp_by_bitrate(RcModelV2SmtCtx * p,RK_S32 bit_target_use)712*437bfbebSnyanmisaka static RK_S32 derive_iframe_qp_by_bitrate(RcModelV2SmtCtx *p, RK_S32 bit_target_use)
713*437bfbebSnyanmisaka {
714*437bfbebSnyanmisaka     RcFpsCfg *fps = &p->usr_cfg.fps;
715*437bfbebSnyanmisaka     RK_S32 avg_bps = (p->usr_cfg.bps_min + p->usr_cfg.bps_max) / 2;
716*437bfbebSnyanmisaka     RK_S32 fps_out = fps->fps_out_num / fps->fps_out_denom;
717*437bfbebSnyanmisaka     RK_S32 avg_pqp = mpp_data_avg(p->qp_p, -1, 1, 1);
718*437bfbebSnyanmisaka     RK_S32 avg_qp = mpp_clip(avg_pqp, p->qp_min, p->qp_max);
719*437bfbebSnyanmisaka     RK_S32 prev_iqp = p->pre_qp_i;
720*437bfbebSnyanmisaka     RK_S32 prev_pqp = p->qp_prev_out;
721*437bfbebSnyanmisaka     RK_S32 pre_bits_i = p->pre_real_bit_i;
722*437bfbebSnyanmisaka     RK_S32 qp_out_i = 0;
723*437bfbebSnyanmisaka 
724*437bfbebSnyanmisaka     if (bit_target_use <= pre_bits_i) {
725*437bfbebSnyanmisaka         qp_out_i = (bit_target_use * 5 < pre_bits_i) ? prev_iqp + 3 :
726*437bfbebSnyanmisaka                    (bit_target_use * 2 < pre_bits_i) ? prev_iqp + 2 :
727*437bfbebSnyanmisaka                    (bit_target_use * 3 < pre_bits_i * 2) ? prev_iqp + 1 : prev_iqp;
728*437bfbebSnyanmisaka     } else {
729*437bfbebSnyanmisaka         qp_out_i = (pre_bits_i * 3 < bit_target_use) ? prev_iqp - 3 :
730*437bfbebSnyanmisaka                    (pre_bits_i * 2 < bit_target_use) ? prev_iqp - 2 :
731*437bfbebSnyanmisaka                    (pre_bits_i * 3 < bit_target_use * 2) ? prev_iqp - 1 : prev_iqp;
732*437bfbebSnyanmisaka     }
733*437bfbebSnyanmisaka     rc_dbg_rc("frame %lld bit_target_use %d pre_bits_i %d prev_iqp %d qp_out_i %d\n",
734*437bfbebSnyanmisaka               p->frm_num, bit_target_use, pre_bits_i, prev_iqp, qp_out_i);
735*437bfbebSnyanmisaka 
736*437bfbebSnyanmisaka     //FIX: may be invalid(2025.01.06)
737*437bfbebSnyanmisaka     if (!p->reenc_cnt && p->usr_cfg.debreath_cfg.enable)
738*437bfbebSnyanmisaka         calc_smt_debreath_qp(p);
739*437bfbebSnyanmisaka 
740*437bfbebSnyanmisaka     qp_out_i = mpp_clip(qp_out_i, inter_pqp0[avg_qp], inter_pqp1[avg_qp]);
741*437bfbebSnyanmisaka     qp_out_i = mpp_clip(qp_out_i, inter_pqp0[prev_pqp], inter_pqp1[prev_pqp]);
742*437bfbebSnyanmisaka     if (qp_out_i > 27)
743*437bfbebSnyanmisaka         qp_out_i = mpp_clip(qp_out_i, intra_pqp0[0][prev_iqp], intra_pqp1[prev_iqp]);
744*437bfbebSnyanmisaka     else if (qp_out_i > 22)
745*437bfbebSnyanmisaka         qp_out_i = mpp_clip(qp_out_i, intra_pqp0[1][prev_iqp], intra_pqp1[prev_iqp]);
746*437bfbebSnyanmisaka     else
747*437bfbebSnyanmisaka         qp_out_i = mpp_clip(qp_out_i, intra_pqp0[2][prev_iqp], intra_pqp1[prev_iqp]);
748*437bfbebSnyanmisaka 
749*437bfbebSnyanmisaka     rc_dbg_rc("frame %lld qp_out_i %d avg_qp %d prev_pqp %d prev_iqp %d qp_out_i %d\n",
750*437bfbebSnyanmisaka               p->frm_num, qp_out_i, avg_qp, prev_pqp, prev_iqp, qp_out_i);
751*437bfbebSnyanmisaka 
752*437bfbebSnyanmisaka     if (p->pre_gop_left_bit < 0) {
753*437bfbebSnyanmisaka         if (abs(p->pre_gop_left_bit) * 5 > avg_bps * (p->igop / fps_out))
754*437bfbebSnyanmisaka             qp_out_i = mpp_clip(qp_out_i, 20, 51);
755*437bfbebSnyanmisaka         else if (abs(p->pre_gop_left_bit) * 20 > avg_bps * (p->igop / fps_out))
756*437bfbebSnyanmisaka             qp_out_i = mpp_clip(qp_out_i, 15, 51);
757*437bfbebSnyanmisaka 
758*437bfbebSnyanmisaka         rc_dbg_rc("frame %lld pre_gop_left_bit %d avg_bps %d qp_out_i %d\n",
759*437bfbebSnyanmisaka                   p->frm_num, p->pre_gop_left_bit, avg_bps, qp_out_i);
760*437bfbebSnyanmisaka     }
761*437bfbebSnyanmisaka 
762*437bfbebSnyanmisaka     return qp_out_i;
763*437bfbebSnyanmisaka }
764*437bfbebSnyanmisaka 
derive_pframe_qp_by_bitrate(RcModelV2SmtCtx * p)765*437bfbebSnyanmisaka static RK_S32 derive_pframe_qp_by_bitrate(RcModelV2SmtCtx *p)
766*437bfbebSnyanmisaka {
767*437bfbebSnyanmisaka     RcFpsCfg *fps = &p->usr_cfg.fps;
768*437bfbebSnyanmisaka     RK_S32 avg_bps = (p->usr_cfg.bps_min + p->usr_cfg.bps_max) / 2;
769*437bfbebSnyanmisaka     RK_S32 fps_out = fps->fps_out_num / fps->fps_out_denom;
770*437bfbebSnyanmisaka     RK_S32 bits_target_use = 0;
771*437bfbebSnyanmisaka     RK_S32 pre_diff_bit_use = 0;
772*437bfbebSnyanmisaka     RK_S32 coef = smt_calc_coef(p);
773*437bfbebSnyanmisaka     RK_S32 m_tbr = p->bits_tgt_upper - p->bits_tgt_lower;
774*437bfbebSnyanmisaka     RK_S32 m_dbr = p->pre_diff_bit_upper - p->pre_diff_bit_lower;
775*437bfbebSnyanmisaka     RK_S32 diff_bit = (p->pid_lower_all.i + p->pid_upper_all.i) >> 1;
776*437bfbebSnyanmisaka     RK_S32 prev_pqp = p->qp_prev_out;
777*437bfbebSnyanmisaka     RK_S32 qp_out = p->qp_out;
778*437bfbebSnyanmisaka     RK_S32 qp_add = 0, qp_minus = 0;
779*437bfbebSnyanmisaka 
780*437bfbebSnyanmisaka     bits_target_use = ((RK_S64)m_tbr * coef + (RK_S64)p->bits_tgt_lower * 1024) >> 10;
781*437bfbebSnyanmisaka     pre_diff_bit_use = ((RK_S64)m_dbr * coef + (RK_S64)p->pre_diff_bit_lower * 1024) >> 10;
782*437bfbebSnyanmisaka 
783*437bfbebSnyanmisaka     if (bits_target_use < 100)
784*437bfbebSnyanmisaka         bits_target_use = 100;
785*437bfbebSnyanmisaka 
786*437bfbebSnyanmisaka     rc_dbg_rc("frame %lld bits_target_use %d m_tbr %d coef %d bits_tgt_lower %d\n"
787*437bfbebSnyanmisaka               "pre_diff_bit_use %d m_dbr %d  pre_diff_bit_lower %d "
788*437bfbebSnyanmisaka               "bits_tgt_upper %d pre_diff_bit_upper %d qp_out_0 %d\n",
789*437bfbebSnyanmisaka               p->frm_num, bits_target_use, m_tbr, coef, p->bits_tgt_lower,
790*437bfbebSnyanmisaka               pre_diff_bit_use, m_dbr, p->pre_diff_bit_lower,
791*437bfbebSnyanmisaka               p->bits_tgt_upper, p->pre_diff_bit_upper, qp_out);
792*437bfbebSnyanmisaka 
793*437bfbebSnyanmisaka     if (abs(pre_diff_bit_use) * 100 <= bits_target_use * 3)
794*437bfbebSnyanmisaka         qp_out = prev_pqp - 1;
795*437bfbebSnyanmisaka     else if (pre_diff_bit_use * 100 > bits_target_use * 3) {
796*437bfbebSnyanmisaka         if (pre_diff_bit_use >= bits_target_use)
797*437bfbebSnyanmisaka             qp_out = qp_out >= 30 ? prev_pqp - 4 : prev_pqp - 3;
798*437bfbebSnyanmisaka         else if (pre_diff_bit_use * 4 >= bits_target_use * 1)
799*437bfbebSnyanmisaka             qp_out = qp_out >= 30 ? prev_pqp - 3 : prev_pqp - 2;
800*437bfbebSnyanmisaka         else if (pre_diff_bit_use * 10 > bits_target_use * 1)
801*437bfbebSnyanmisaka             qp_out = prev_pqp - 2;
802*437bfbebSnyanmisaka         else
803*437bfbebSnyanmisaka             qp_out = prev_pqp - 1;
804*437bfbebSnyanmisaka     } else {
805*437bfbebSnyanmisaka         RK_S32 qp_add_tmp = (prev_pqp >= 36) ? 0 : 1;
806*437bfbebSnyanmisaka         pre_diff_bit_use = abs(pre_diff_bit_use);
807*437bfbebSnyanmisaka         qp_out = (pre_diff_bit_use >= 2 * bits_target_use) ? prev_pqp + 2 + qp_add_tmp :
808*437bfbebSnyanmisaka                  (pre_diff_bit_use * 3 >= bits_target_use * 2) ? prev_pqp + 1 + qp_add_tmp :
809*437bfbebSnyanmisaka                  (pre_diff_bit_use * 5 >  bits_target_use) ? prev_pqp + 1 : prev_pqp;
810*437bfbebSnyanmisaka     }
811*437bfbebSnyanmisaka     rc_dbg_rc("frame %lld prev_pqp %d qp_out_1 %d\n", p->frm_num, prev_pqp, qp_out);
812*437bfbebSnyanmisaka 
813*437bfbebSnyanmisaka     qp_out = mpp_clip(qp_out, p->qp_min, p->qp_max);
814*437bfbebSnyanmisaka     if (qp_out > LOW_QP) {
815*437bfbebSnyanmisaka         pre_diff_bit_use = ((RK_S64)m_dbr * coef + (RK_S64)p->pre_diff_bit_lower * 1024) >> 10;
816*437bfbebSnyanmisaka         bits_target_use = avg_bps / fps_out;
817*437bfbebSnyanmisaka         bits_target_use = -bits_target_use / 5;
818*437bfbebSnyanmisaka         coef += pre_diff_bit_use <= 2 * bits_target_use ? 205 :
819*437bfbebSnyanmisaka                 ((pre_diff_bit_use <= bits_target_use) ? 102 : 51);
820*437bfbebSnyanmisaka 
821*437bfbebSnyanmisaka         if (coef >= 1024 || qp_out > LOW_LOW_QP)
822*437bfbebSnyanmisaka             coef = 1024;
823*437bfbebSnyanmisaka         rc_dbg_rc("frame %lld pre_diff_bit_use %d bits_target_use %d coef %d\n",
824*437bfbebSnyanmisaka                   p->frm_num, pre_diff_bit_use, bits_target_use, coef);
825*437bfbebSnyanmisaka 
826*437bfbebSnyanmisaka         pre_diff_bit_use = ((RK_S64)m_dbr * coef + (RK_S64)p->pre_diff_bit_lower * 1024) >> 10;
827*437bfbebSnyanmisaka         bits_target_use = ((RK_S64)m_tbr * coef + (RK_S64)p->bits_tgt_lower * 1024) >> 10;
828*437bfbebSnyanmisaka         if (bits_target_use < 100)
829*437bfbebSnyanmisaka             bits_target_use = 100;
830*437bfbebSnyanmisaka 
831*437bfbebSnyanmisaka         if (abs(pre_diff_bit_use) * 100 <= bits_target_use * 3)
832*437bfbebSnyanmisaka             qp_out = prev_pqp;
833*437bfbebSnyanmisaka         else if (pre_diff_bit_use * 100 > bits_target_use * 3) {
834*437bfbebSnyanmisaka             if (pre_diff_bit_use >= bits_target_use)
835*437bfbebSnyanmisaka                 qp_out = qp_out >= 30 ? prev_pqp - 3 : prev_pqp - 2;
836*437bfbebSnyanmisaka             else if (pre_diff_bit_use * 4 >= bits_target_use * 1)
837*437bfbebSnyanmisaka                 qp_out = qp_out >= 30 ? prev_pqp - 2 : prev_pqp - 1;
838*437bfbebSnyanmisaka             else if (pre_diff_bit_use * 10 > bits_target_use * 1)
839*437bfbebSnyanmisaka                 qp_out = prev_pqp - 1;
840*437bfbebSnyanmisaka             else
841*437bfbebSnyanmisaka                 qp_out = prev_pqp;
842*437bfbebSnyanmisaka         } else {
843*437bfbebSnyanmisaka             pre_diff_bit_use = abs(pre_diff_bit_use);
844*437bfbebSnyanmisaka             qp_out = prev_pqp + (pre_diff_bit_use * 3 >= bits_target_use * 2 ? 1 : 0);
845*437bfbebSnyanmisaka         }
846*437bfbebSnyanmisaka         rc_dbg_rc("frame %lld pre_diff_bit_use %d bits_target_use %d prev_pqp %d qp_out_2 %d\n",
847*437bfbebSnyanmisaka                   p->frm_num, pre_diff_bit_use, bits_target_use, prev_pqp, qp_out);
848*437bfbebSnyanmisaka     }
849*437bfbebSnyanmisaka 
850*437bfbebSnyanmisaka     qp_out = mpp_clip(qp_out, p->qp_min, p->qp_max);
851*437bfbebSnyanmisaka 
852*437bfbebSnyanmisaka     //Add rc_container
853*437bfbebSnyanmisaka     p->change_bit_flag = 0;
854*437bfbebSnyanmisaka     if (p->usr_cfg.rc_container) {
855*437bfbebSnyanmisaka         RK_S32 cnt = p->usr_cfg.scene_mode * 3 + p->usr_cfg.rc_container;
856*437bfbebSnyanmisaka         if (p->count_real_bit < p->count_pred_bit * rc_ctnr_br_thd1[cnt] / 100) {
857*437bfbebSnyanmisaka             if (qp_out > rc_ctnr_qp_thd1[cnt]) {
858*437bfbebSnyanmisaka                 p->change_bit_flag = 1;
859*437bfbebSnyanmisaka             }
860*437bfbebSnyanmisaka 
861*437bfbebSnyanmisaka             qp_out = mpp_clip(qp_out, 10, rc_ctnr_qp_thd1[cnt]);
862*437bfbebSnyanmisaka         } else if (p->count_real_bit < p->count_pred_bit * rc_ctnr_br_thd2[cnt] / 100) {
863*437bfbebSnyanmisaka             if (qp_out > rc_ctnr_qp_thd2[cnt]) {
864*437bfbebSnyanmisaka                 p->change_bit_flag = 1;
865*437bfbebSnyanmisaka             }
866*437bfbebSnyanmisaka             qp_out = mpp_clip(qp_out, 10, rc_ctnr_qp_thd2[cnt]);
867*437bfbebSnyanmisaka         }
868*437bfbebSnyanmisaka     }
869*437bfbebSnyanmisaka 
870*437bfbebSnyanmisaka     qp_add = qp_out > 36 ? 1 : (qp_out > 33 ? 2 : (qp_out > 30 ? 3 : 4));
871*437bfbebSnyanmisaka     qp_minus = qp_out > 40 ? 4 : (qp_out > 36 ? 3 : (qp_out > 33 ? 2 : 1));
872*437bfbebSnyanmisaka     qp_out = mpp_clip(qp_out, prev_pqp - qp_minus, prev_pqp + qp_add);
873*437bfbebSnyanmisaka     rc_dbg_rc("frame %lld qp_out_3 %d qp_add %d qp_minus %d\n",
874*437bfbebSnyanmisaka               p->frm_num, qp_out, qp_add, qp_minus);
875*437bfbebSnyanmisaka 
876*437bfbebSnyanmisaka     if (diff_bit > 0) {
877*437bfbebSnyanmisaka         if (avg_bps * 5 > avg_bps) //FIXME: avg_bps is typo error?(2025.01.06)
878*437bfbebSnyanmisaka             qp_out = mpp_clip(qp_out, 25, 51);
879*437bfbebSnyanmisaka         else if (avg_bps * 20 > avg_bps)
880*437bfbebSnyanmisaka             qp_out = mpp_clip(qp_out, 21, 51);
881*437bfbebSnyanmisaka         rc_dbg_rc("frame %lld avg_bps %d qp_out_4 %d\n", p->frm_num, avg_bps, qp_out);
882*437bfbebSnyanmisaka     }
883*437bfbebSnyanmisaka 
884*437bfbebSnyanmisaka     return qp_out;
885*437bfbebSnyanmisaka }
886*437bfbebSnyanmisaka 
revise_qp_by_complexity(RcModelV2SmtCtx * p,RK_S32 fm_min_iqp,RK_S32 fm_min_pqp,RK_S32 fm_max_iqp,RK_S32 fm_max_pqp)887*437bfbebSnyanmisaka static RK_S32 revise_qp_by_complexity(RcModelV2SmtCtx *p, RK_S32 fm_min_iqp,
888*437bfbebSnyanmisaka                                       RK_S32 fm_min_pqp, RK_S32 fm_max_iqp, RK_S32 fm_max_pqp)
889*437bfbebSnyanmisaka {
890*437bfbebSnyanmisaka     RK_S32 md_lvl_sum = mpp_data_sum_v2(p->motion_level);
891*437bfbebSnyanmisaka     RK_S32 md_lvl_0 = mpp_data_get_pre_val_v2(p->motion_level, 0);
892*437bfbebSnyanmisaka     RK_S32 cplx_lvl_sum = mpp_data_sum_v2(p->complex_level);
893*437bfbebSnyanmisaka     RK_S32 qp_add = 0, qp_add_p = 0;
894*437bfbebSnyanmisaka     RK_S32 qp_final = p->qp_out;
895*437bfbebSnyanmisaka 
896*437bfbebSnyanmisaka     qp_add = 4;
897*437bfbebSnyanmisaka     qp_add_p = 4;
898*437bfbebSnyanmisaka     if (md_lvl_sum >= 700 || md_lvl_0 == 200) {
899*437bfbebSnyanmisaka         qp_add = 6;
900*437bfbebSnyanmisaka         qp_add_p = 6;
901*437bfbebSnyanmisaka     } else if (md_lvl_sum >= 400 || md_lvl_0 == 100) {
902*437bfbebSnyanmisaka         qp_add = 5;
903*437bfbebSnyanmisaka         qp_add_p = 5;
904*437bfbebSnyanmisaka     }
905*437bfbebSnyanmisaka     if (cplx_lvl_sum >= 12) {
906*437bfbebSnyanmisaka         qp_add++;
907*437bfbebSnyanmisaka         qp_add_p++;
908*437bfbebSnyanmisaka     }
909*437bfbebSnyanmisaka 
910*437bfbebSnyanmisaka     rc_dbg_rc("frame %lld md_lvl_sum %d md_lvl_0 %d cplx_lvl_sum %d "
911*437bfbebSnyanmisaka               "qp_add_cplx %d qp_add_p %d qp_final_0 %d\n",
912*437bfbebSnyanmisaka               p->frm_num, md_lvl_sum, md_lvl_0, cplx_lvl_sum,
913*437bfbebSnyanmisaka               qp_add, qp_add_p, qp_final);
914*437bfbebSnyanmisaka 
915*437bfbebSnyanmisaka     if (p->frame_type == INTRA_FRAME)
916*437bfbebSnyanmisaka         qp_final = mpp_clip(qp_final, fm_min_iqp + qp_add, fm_max_iqp);
917*437bfbebSnyanmisaka     else if (p->frame_type == INTER_VI_FRAME) {
918*437bfbebSnyanmisaka         RK_S32 vi_max_qp = (fm_max_pqp > 42) ? (fm_max_pqp - 5) :
919*437bfbebSnyanmisaka                            (fm_max_pqp > 39) ? (fm_max_pqp - 3) :
920*437bfbebSnyanmisaka                            (fm_max_pqp > 35) ? (fm_max_pqp - 2) : fm_max_pqp;
921*437bfbebSnyanmisaka         qp_final -= 1;
922*437bfbebSnyanmisaka         qp_final = mpp_clip(qp_final, fm_min_pqp + qp_add - 1, fm_max_pqp);
923*437bfbebSnyanmisaka         qp_final = mpp_clip(qp_final, qp_final, vi_max_qp);
924*437bfbebSnyanmisaka     } else
925*437bfbebSnyanmisaka         qp_final = mpp_clip(qp_final, fm_min_pqp + qp_add_p, fm_max_pqp);
926*437bfbebSnyanmisaka 
927*437bfbebSnyanmisaka     qp_final = mpp_clip(qp_final, p->qp_min, p->qp_max);
928*437bfbebSnyanmisaka     rc_dbg_rc("frame %lld frm_type %d frm_qp %d:%d:%d:%d blk_qp %d:%d qp_final_1 %d\n",
929*437bfbebSnyanmisaka               p->frm_num, p->frame_type, fm_min_iqp, fm_max_iqp,
930*437bfbebSnyanmisaka               fm_min_pqp, fm_max_pqp, p->qp_min, p->qp_max, qp_final);
931*437bfbebSnyanmisaka 
932*437bfbebSnyanmisaka     return qp_final;
933*437bfbebSnyanmisaka }
934*437bfbebSnyanmisaka 
rc_model_v2_smt_start(void * ctx,EncRcTask * task)935*437bfbebSnyanmisaka MPP_RET rc_model_v2_smt_start(void *ctx, EncRcTask * task)
936*437bfbebSnyanmisaka {
937*437bfbebSnyanmisaka     RcModelV2SmtCtx *p = (RcModelV2SmtCtx *) ctx;
938*437bfbebSnyanmisaka     EncFrmStatus *frm = &task->frm;
939*437bfbebSnyanmisaka     EncRcTaskInfo *info = &task->info;
940*437bfbebSnyanmisaka     RcFpsCfg *fps = &p->usr_cfg.fps;
941*437bfbebSnyanmisaka     RK_S32 fps_out = fps->fps_out_num / fps->fps_out_denom;
942*437bfbebSnyanmisaka     RK_S32 avg_pqp = 0;
943*437bfbebSnyanmisaka     RK_S32 fm_min_iqp = p->usr_cfg.fqp_min_i;
944*437bfbebSnyanmisaka     RK_S32 fm_min_pqp = p->usr_cfg.fqp_min_p;
945*437bfbebSnyanmisaka     RK_S32 fm_max_iqp = p->usr_cfg.fqp_max_i;
946*437bfbebSnyanmisaka     RK_S32 fm_max_pqp = p->usr_cfg.fqp_max_p;
947*437bfbebSnyanmisaka 
948*437bfbebSnyanmisaka     if (frm->reencode)
949*437bfbebSnyanmisaka         return MPP_OK;
950*437bfbebSnyanmisaka 
951*437bfbebSnyanmisaka     smt_start_prepare(ctx, task);
952*437bfbebSnyanmisaka     avg_pqp = mpp_data_avg(p->qp_p, -1, 1, 1);
953*437bfbebSnyanmisaka 
954*437bfbebSnyanmisaka     if (p->frm_num == 0) {
955*437bfbebSnyanmisaka         RK_S32 mb_w = MPP_ALIGN(p->usr_cfg.width, 16) / 16;
956*437bfbebSnyanmisaka         RK_S32 mb_h = MPP_ALIGN(p->usr_cfg.height, 16) / 16;
957*437bfbebSnyanmisaka         RK_S32 ratio = mpp_clip(fps_out  / 10 + 1, 1, 3);
958*437bfbebSnyanmisaka         RK_S32 qp_out_f0 = 0;
959*437bfbebSnyanmisaka         if (p->usr_cfg.init_quality < 0) {
960*437bfbebSnyanmisaka             qp_out_f0 = cal_smt_first_i_start_qp(p->bits_tgt_upper * ratio, mb_w * mb_h);
961*437bfbebSnyanmisaka             qp_out_f0 = (fm_min_iqp > 31) ? mpp_clip(qp_out_f0, fm_min_iqp, p->qp_max) :
962*437bfbebSnyanmisaka                         mpp_clip(qp_out_f0, 31, p->qp_max);
963*437bfbebSnyanmisaka         } else
964*437bfbebSnyanmisaka             qp_out_f0 = p->usr_cfg.init_quality;
965*437bfbebSnyanmisaka 
966*437bfbebSnyanmisaka         p->qp_out = qp_out_f0;
967*437bfbebSnyanmisaka         p->count_real_bit = 0;
968*437bfbebSnyanmisaka         p->count_pred_bit = 0;
969*437bfbebSnyanmisaka         p->count_frame = 0;
970*437bfbebSnyanmisaka         rc_dbg_rc("first frame init_quality %d bits_tgt_upper %d "
971*437bfbebSnyanmisaka                   "mb_w %d mb_h %d ratio %d qp_out %d\n",
972*437bfbebSnyanmisaka                   p->usr_cfg.init_quality, p->bits_tgt_upper,
973*437bfbebSnyanmisaka                   mb_w, mb_h, ratio, p->qp_out);
974*437bfbebSnyanmisaka     } else if (p->frame_type == INTRA_FRAME) {
975*437bfbebSnyanmisaka         // if (p->frm_num > 0)
976*437bfbebSnyanmisaka         p->qp_out = derive_iframe_qp_by_bitrate(p, info->bit_max);
977*437bfbebSnyanmisaka     } else {
978*437bfbebSnyanmisaka         if (p->last_frame_type == INTRA_FRAME) {
979*437bfbebSnyanmisaka             RK_S32 prev_qp = p->qp_prev_out;
980*437bfbebSnyanmisaka             p->qp_out = prev_qp + (prev_qp < 33 ? 3 : (prev_qp < 35 ? 2 : 1));
981*437bfbebSnyanmisaka         } else
982*437bfbebSnyanmisaka             p->qp_out = derive_pframe_qp_by_bitrate(p);
983*437bfbebSnyanmisaka     }
984*437bfbebSnyanmisaka 
985*437bfbebSnyanmisaka     p->qp_out = revise_qp_by_complexity(p, fm_min_iqp, fm_min_pqp, fm_max_iqp, fm_max_pqp);
986*437bfbebSnyanmisaka 
987*437bfbebSnyanmisaka     info->quality_target = p->qp_out;
988*437bfbebSnyanmisaka     info->complex_scene = 0;
989*437bfbebSnyanmisaka     if (p->frame_type == INTER_P_FRAME && avg_pqp >= fm_max_pqp - 1 &&
990*437bfbebSnyanmisaka         p->qp_out == fm_max_pqp && p->qp_prev_out == fm_max_pqp)
991*437bfbebSnyanmisaka         info->complex_scene = 1;
992*437bfbebSnyanmisaka 
993*437bfbebSnyanmisaka     info->quality_max = p->usr_cfg.max_quality;
994*437bfbebSnyanmisaka     info->quality_min = p->usr_cfg.min_quality;
995*437bfbebSnyanmisaka 
996*437bfbebSnyanmisaka     rc_dbg_rc("frame %lld quality [%d : %d : %d] complex_scene %d\n",
997*437bfbebSnyanmisaka               p->frm_num, info->quality_min, info->quality_target,
998*437bfbebSnyanmisaka               info->quality_max, info->complex_scene);
999*437bfbebSnyanmisaka 
1000*437bfbebSnyanmisaka     p->frm_num++;
1001*437bfbebSnyanmisaka     p->reenc_cnt = 0;
1002*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
1003*437bfbebSnyanmisaka     return MPP_OK;
1004*437bfbebSnyanmisaka }
1005*437bfbebSnyanmisaka 
check_super_frame_smt(RcModelV2SmtCtx * ctx,EncRcTaskInfo * cfg)1006*437bfbebSnyanmisaka MPP_RET check_super_frame_smt(RcModelV2SmtCtx *ctx, EncRcTaskInfo *cfg)
1007*437bfbebSnyanmisaka {
1008*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
1009*437bfbebSnyanmisaka     RK_S32 frame_type = ctx->frame_type;
1010*437bfbebSnyanmisaka     RK_U32 bits_thr = 0;
1011*437bfbebSnyanmisaka     RcCfg *usr_cfg = &ctx->usr_cfg;
1012*437bfbebSnyanmisaka 
1013*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
1014*437bfbebSnyanmisaka     if (usr_cfg->super_cfg.super_mode) {
1015*437bfbebSnyanmisaka         bits_thr = usr_cfg->super_cfg.super_p_thd;
1016*437bfbebSnyanmisaka         if (frame_type == INTRA_FRAME)
1017*437bfbebSnyanmisaka             bits_thr = usr_cfg->super_cfg.super_i_thd;
1018*437bfbebSnyanmisaka 
1019*437bfbebSnyanmisaka         if ((RK_U32)cfg->bit_real >= bits_thr) {
1020*437bfbebSnyanmisaka             if (usr_cfg->super_cfg.super_mode == MPP_ENC_RC_SUPER_FRM_DROP) {
1021*437bfbebSnyanmisaka                 rc_dbg_rc("super frame drop current frame");
1022*437bfbebSnyanmisaka                 usr_cfg->drop_mode = MPP_ENC_RC_DROP_FRM_NORMAL;
1023*437bfbebSnyanmisaka                 usr_cfg->drop_gap  = 0;
1024*437bfbebSnyanmisaka             }
1025*437bfbebSnyanmisaka             ret = MPP_NOK;
1026*437bfbebSnyanmisaka         }
1027*437bfbebSnyanmisaka     }
1028*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
1029*437bfbebSnyanmisaka     return ret;
1030*437bfbebSnyanmisaka }
1031*437bfbebSnyanmisaka 
check_re_enc_smt(RcModelV2SmtCtx * ctx,EncRcTaskInfo * cfg)1032*437bfbebSnyanmisaka MPP_RET check_re_enc_smt(RcModelV2SmtCtx *ctx, EncRcTaskInfo *cfg)
1033*437bfbebSnyanmisaka {
1034*437bfbebSnyanmisaka     RcCfg *usr_cfg = &ctx->usr_cfg;
1035*437bfbebSnyanmisaka     RK_S32 frame_type = ctx->frame_type;
1036*437bfbebSnyanmisaka     RK_S32 bit_thr = 0;
1037*437bfbebSnyanmisaka     RK_S32 stat_time = usr_cfg->stats_time;
1038*437bfbebSnyanmisaka     RK_S32 last_ins_bps = mpp_data_sum_v2(ctx->stat_bits) / stat_time;
1039*437bfbebSnyanmisaka     RK_S32 ins_bps = (last_ins_bps * stat_time - mpp_data_get_pre_val_v2(ctx->stat_bits, -1)
1040*437bfbebSnyanmisaka                       + cfg->bit_real) / stat_time;
1041*437bfbebSnyanmisaka     RK_S32 bps;
1042*437bfbebSnyanmisaka     RK_S32 ret = MPP_OK;
1043*437bfbebSnyanmisaka 
1044*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
1045*437bfbebSnyanmisaka     rc_dbg_rc("reenc check target_bps %d last_ins_bps %d ins_bps %d",
1046*437bfbebSnyanmisaka               usr_cfg->bps_target, last_ins_bps, ins_bps);
1047*437bfbebSnyanmisaka 
1048*437bfbebSnyanmisaka     if (ctx->reenc_cnt >= usr_cfg->max_reencode_times)
1049*437bfbebSnyanmisaka         return MPP_OK;
1050*437bfbebSnyanmisaka 
1051*437bfbebSnyanmisaka     if (check_super_frame_smt(ctx, cfg))
1052*437bfbebSnyanmisaka         return MPP_NOK;
1053*437bfbebSnyanmisaka 
1054*437bfbebSnyanmisaka     if (usr_cfg->debreath_cfg.enable && !ctx->first_frm_flg)
1055*437bfbebSnyanmisaka         return MPP_OK;
1056*437bfbebSnyanmisaka 
1057*437bfbebSnyanmisaka     rc_dbg_drop("drop mode %d frame_type %d\n", usr_cfg->drop_mode, frame_type);
1058*437bfbebSnyanmisaka     if (usr_cfg->drop_mode && frame_type == INTER_P_FRAME) {
1059*437bfbebSnyanmisaka         bit_thr = (RK_S32)(usr_cfg->bps_max * (100 + usr_cfg->drop_thd) / (float)100);
1060*437bfbebSnyanmisaka         rc_dbg_drop("drop mode %d check max_bps %d bit_thr %d ins_bps %d",
1061*437bfbebSnyanmisaka                     usr_cfg->drop_mode, usr_cfg->bps_target, bit_thr, ins_bps);
1062*437bfbebSnyanmisaka         return (ins_bps > bit_thr) ? MPP_NOK : MPP_OK;
1063*437bfbebSnyanmisaka     }
1064*437bfbebSnyanmisaka 
1065*437bfbebSnyanmisaka     switch (frame_type) {
1066*437bfbebSnyanmisaka     case INTRA_FRAME:
1067*437bfbebSnyanmisaka         bit_thr = 3 * cfg->bit_max / 2;
1068*437bfbebSnyanmisaka         break;
1069*437bfbebSnyanmisaka     case INTER_P_FRAME:
1070*437bfbebSnyanmisaka         bit_thr = 3 * cfg->bit_max;
1071*437bfbebSnyanmisaka         break;
1072*437bfbebSnyanmisaka     default:
1073*437bfbebSnyanmisaka         break;
1074*437bfbebSnyanmisaka     }
1075*437bfbebSnyanmisaka 
1076*437bfbebSnyanmisaka     if (cfg->bit_real > bit_thr) {
1077*437bfbebSnyanmisaka         bps = usr_cfg->bps_max;
1078*437bfbebSnyanmisaka         if ((bps - (bps >> 3) < ins_bps) && (bps / 20  < ins_bps - last_ins_bps))
1079*437bfbebSnyanmisaka             ret =  MPP_NOK;
1080*437bfbebSnyanmisaka     }
1081*437bfbebSnyanmisaka 
1082*437bfbebSnyanmisaka     rc_dbg_func("leave %p ret %d\n", ctx, ret);
1083*437bfbebSnyanmisaka     return ret;
1084*437bfbebSnyanmisaka }
1085*437bfbebSnyanmisaka 
rc_model_v2_smt_check_reenc(void * ctx,EncRcTask * task)1086*437bfbebSnyanmisaka MPP_RET rc_model_v2_smt_check_reenc(void *ctx, EncRcTask *task)
1087*437bfbebSnyanmisaka {
1088*437bfbebSnyanmisaka     RcModelV2SmtCtx *p = (RcModelV2SmtCtx *)ctx;
1089*437bfbebSnyanmisaka     EncRcTaskInfo *cfg = (EncRcTaskInfo *)&task->info;
1090*437bfbebSnyanmisaka     EncFrmStatus *frm = &task->frm;
1091*437bfbebSnyanmisaka     RcCfg *usr_cfg = &p->usr_cfg;
1092*437bfbebSnyanmisaka 
1093*437bfbebSnyanmisaka     rc_dbg_func("enter ctx %p cfg %p\n", ctx, cfg);
1094*437bfbebSnyanmisaka 
1095*437bfbebSnyanmisaka     frm->reencode = 0;
1096*437bfbebSnyanmisaka 
1097*437bfbebSnyanmisaka     if ((usr_cfg->mode == RC_FIXQP) ||
1098*437bfbebSnyanmisaka         (task->force.force_flag & ENC_RC_FORCE_QP) ||
1099*437bfbebSnyanmisaka         p->on_drop || p->on_pskip)
1100*437bfbebSnyanmisaka         return MPP_OK;
1101*437bfbebSnyanmisaka 
1102*437bfbebSnyanmisaka     if (check_re_enc_smt(p, cfg)) {
1103*437bfbebSnyanmisaka         MppEncRcDropFrmMode drop_mode = usr_cfg->drop_mode;
1104*437bfbebSnyanmisaka 
1105*437bfbebSnyanmisaka         if (frm->is_intra)
1106*437bfbebSnyanmisaka             drop_mode = MPP_ENC_RC_DROP_FRM_DISABLED;
1107*437bfbebSnyanmisaka 
1108*437bfbebSnyanmisaka         if (usr_cfg->drop_gap && p->drop_cnt >= usr_cfg->drop_gap)
1109*437bfbebSnyanmisaka             drop_mode = MPP_ENC_RC_DROP_FRM_DISABLED;
1110*437bfbebSnyanmisaka 
1111*437bfbebSnyanmisaka         rc_dbg_drop("reenc drop_mode %d drop_cnt %d\n", drop_mode, p->drop_cnt);
1112*437bfbebSnyanmisaka 
1113*437bfbebSnyanmisaka         switch (drop_mode) {
1114*437bfbebSnyanmisaka         case MPP_ENC_RC_DROP_FRM_NORMAL : {
1115*437bfbebSnyanmisaka             frm->drop = 1;
1116*437bfbebSnyanmisaka             frm->reencode = 1;
1117*437bfbebSnyanmisaka             p->on_drop = 1;
1118*437bfbebSnyanmisaka             p->drop_cnt++;
1119*437bfbebSnyanmisaka             rc_dbg_drop("drop\n");
1120*437bfbebSnyanmisaka         } break;
1121*437bfbebSnyanmisaka         case MPP_ENC_RC_DROP_FRM_PSKIP : {
1122*437bfbebSnyanmisaka             frm->force_pskip = 1;
1123*437bfbebSnyanmisaka             frm->reencode = 1;
1124*437bfbebSnyanmisaka             p->on_pskip = 1;
1125*437bfbebSnyanmisaka             p->drop_cnt++;
1126*437bfbebSnyanmisaka             rc_dbg_drop("force_pskip\n");
1127*437bfbebSnyanmisaka         } break;
1128*437bfbebSnyanmisaka         case MPP_ENC_RC_DROP_FRM_DISABLED :
1129*437bfbebSnyanmisaka         default : {
1130*437bfbebSnyanmisaka             RK_S32 bits_thr = usr_cfg->super_cfg.super_p_thd;
1131*437bfbebSnyanmisaka             if (p->frame_type == INTRA_FRAME)
1132*437bfbebSnyanmisaka                 bits_thr = usr_cfg->super_cfg.super_i_thd;
1133*437bfbebSnyanmisaka 
1134*437bfbebSnyanmisaka             if (cfg->bit_real > bits_thr * 2)
1135*437bfbebSnyanmisaka                 cfg->quality_target += 3;
1136*437bfbebSnyanmisaka             else if (cfg->bit_real > bits_thr * 3 / 2)
1137*437bfbebSnyanmisaka                 cfg->quality_target += 2;
1138*437bfbebSnyanmisaka             else if (cfg->bit_real > bits_thr)
1139*437bfbebSnyanmisaka                 cfg->quality_target ++;
1140*437bfbebSnyanmisaka 
1141*437bfbebSnyanmisaka             if (cfg->quality_target < cfg->quality_max) {
1142*437bfbebSnyanmisaka                 p->reenc_cnt++;
1143*437bfbebSnyanmisaka                 frm->reencode = 1;
1144*437bfbebSnyanmisaka             }
1145*437bfbebSnyanmisaka             p->drop_cnt = 0;
1146*437bfbebSnyanmisaka         } break;
1147*437bfbebSnyanmisaka         }
1148*437bfbebSnyanmisaka     }
1149*437bfbebSnyanmisaka 
1150*437bfbebSnyanmisaka     return MPP_OK;
1151*437bfbebSnyanmisaka }
1152*437bfbebSnyanmisaka 
rc_model_v2_smt_end(void * ctx,EncRcTask * task)1153*437bfbebSnyanmisaka MPP_RET rc_model_v2_smt_end(void *ctx, EncRcTask * task)
1154*437bfbebSnyanmisaka {
1155*437bfbebSnyanmisaka     RcModelV2SmtCtx *p = (RcModelV2SmtCtx *) ctx;
1156*437bfbebSnyanmisaka     EncRcTaskInfo *cfg = (EncRcTaskInfo *) & task->info;
1157*437bfbebSnyanmisaka     RK_S32 bit_real = cfg->bit_real;
1158*437bfbebSnyanmisaka 
1159*437bfbebSnyanmisaka     rc_dbg_func("enter ctx %p cfg %p\n", ctx, cfg);
1160*437bfbebSnyanmisaka     rc_dbg_rc("motion_level %u, complex_level %u\n", cfg->motion_level, cfg->complex_level);
1161*437bfbebSnyanmisaka 
1162*437bfbebSnyanmisaka     mpp_data_update_v2(p->rt_bits, bit_real);
1163*437bfbebSnyanmisaka     cfg->rt_bits = mpp_data_sum_v2(p->rt_bits);
1164*437bfbebSnyanmisaka     rc_dbg_rc("frame %lld real_bit %d real time bits %d\n",
1165*437bfbebSnyanmisaka               p->frm_num - 1, bit_real, cfg->rt_bits);
1166*437bfbebSnyanmisaka 
1167*437bfbebSnyanmisaka     mpp_data_update_v2(p->motion_level, cfg->motion_level);
1168*437bfbebSnyanmisaka     mpp_data_update_v2(p->complex_level, cfg->complex_level);
1169*437bfbebSnyanmisaka     p->first_frm_flg = 0;
1170*437bfbebSnyanmisaka 
1171*437bfbebSnyanmisaka     if (p->frame_type == INTER_P_FRAME || p->gop_mode == MPP_GOP_ALL_INTRA)
1172*437bfbebSnyanmisaka         mpp_data_update(p->qp_p, p->qp_out);
1173*437bfbebSnyanmisaka     else {
1174*437bfbebSnyanmisaka         p->pre_qp_i = p->qp_out;
1175*437bfbebSnyanmisaka         p->pre_real_bit_i = bit_real;
1176*437bfbebSnyanmisaka     }
1177*437bfbebSnyanmisaka 
1178*437bfbebSnyanmisaka     bits_model_update_smt(p, bit_real);
1179*437bfbebSnyanmisaka     p->qp_prev_out = p->qp_out;
1180*437bfbebSnyanmisaka     p->last_frame_type = p->frame_type;
1181*437bfbebSnyanmisaka     p->pre_iblk4_prop = cfg->iblk4_prop;
1182*437bfbebSnyanmisaka     p->gop_frm_cnt++;
1183*437bfbebSnyanmisaka     p->gop_qp_sum += p->qp_out;
1184*437bfbebSnyanmisaka 
1185*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
1186*437bfbebSnyanmisaka     return MPP_OK;
1187*437bfbebSnyanmisaka }
1188*437bfbebSnyanmisaka 
rc_model_v2_smt_hal_start(void * ctx,EncRcTask * task)1189*437bfbebSnyanmisaka MPP_RET rc_model_v2_smt_hal_start(void *ctx, EncRcTask *task)
1190*437bfbebSnyanmisaka {
1191*437bfbebSnyanmisaka     rc_dbg_func("smt_hal_start enter ctx %p task %p\n", ctx, task);
1192*437bfbebSnyanmisaka     return MPP_OK;
1193*437bfbebSnyanmisaka }
1194*437bfbebSnyanmisaka 
rc_model_v2_smt_hal_end(void * ctx,EncRcTask * task)1195*437bfbebSnyanmisaka MPP_RET rc_model_v2_smt_hal_end(void *ctx, EncRcTask *task)
1196*437bfbebSnyanmisaka {
1197*437bfbebSnyanmisaka     rc_dbg_func("smt_hal_end enter ctx %p task %p\n", ctx, task);
1198*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
1199*437bfbebSnyanmisaka     return MPP_OK;
1200*437bfbebSnyanmisaka }
1201*437bfbebSnyanmisaka 
1202*437bfbebSnyanmisaka const RcImplApi smt_h264e = {
1203*437bfbebSnyanmisaka     "smart",
1204*437bfbebSnyanmisaka     MPP_VIDEO_CodingAVC,
1205*437bfbebSnyanmisaka     sizeof(RcModelV2SmtCtx),
1206*437bfbebSnyanmisaka     rc_model_v2_smt_h264_init,
1207*437bfbebSnyanmisaka     rc_model_v2_smt_deinit,
1208*437bfbebSnyanmisaka     NULL,
1209*437bfbebSnyanmisaka     rc_model_v2_smt_check_reenc,
1210*437bfbebSnyanmisaka     rc_model_v2_smt_start,
1211*437bfbebSnyanmisaka     rc_model_v2_smt_end,
1212*437bfbebSnyanmisaka     rc_model_v2_smt_hal_start,
1213*437bfbebSnyanmisaka     rc_model_v2_smt_hal_end,
1214*437bfbebSnyanmisaka };
1215*437bfbebSnyanmisaka 
1216*437bfbebSnyanmisaka const RcImplApi smt_h265e = {
1217*437bfbebSnyanmisaka     "smart",
1218*437bfbebSnyanmisaka     MPP_VIDEO_CodingHEVC,
1219*437bfbebSnyanmisaka     sizeof(RcModelV2SmtCtx),
1220*437bfbebSnyanmisaka     rc_model_v2_smt_h265_init,
1221*437bfbebSnyanmisaka     rc_model_v2_smt_deinit,
1222*437bfbebSnyanmisaka     NULL,
1223*437bfbebSnyanmisaka     rc_model_v2_smt_check_reenc,
1224*437bfbebSnyanmisaka     rc_model_v2_smt_start,
1225*437bfbebSnyanmisaka     rc_model_v2_smt_end,
1226*437bfbebSnyanmisaka     rc_model_v2_smt_hal_start,
1227*437bfbebSnyanmisaka     rc_model_v2_smt_hal_end,
1228*437bfbebSnyanmisaka };
1229