xref: /rockchip-linux_mpp/mpp/codec/rc/rc_model_v2.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"
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka #include <math.h>
20*437bfbebSnyanmisaka #include <string.h>
21*437bfbebSnyanmisaka 
22*437bfbebSnyanmisaka #include "mpp_env.h"
23*437bfbebSnyanmisaka #include "mpp_mem.h"
24*437bfbebSnyanmisaka #include "mpp_common.h"
25*437bfbebSnyanmisaka #include "mpp_time.h"
26*437bfbebSnyanmisaka #include "rc_debug.h"
27*437bfbebSnyanmisaka #include "rc_ctx.h"
28*437bfbebSnyanmisaka #include "rc_model_v2.h"
29*437bfbebSnyanmisaka 
30*437bfbebSnyanmisaka #define I_WINDOW_LEN 2
31*437bfbebSnyanmisaka #define P_WINDOW1_LEN 5
32*437bfbebSnyanmisaka #define P_WINDOW2_LEN 8
33*437bfbebSnyanmisaka #define MAX_BIT_COUNT_VALUE 1000000000000000
34*437bfbebSnyanmisaka 
35*437bfbebSnyanmisaka static const RK_S32 max_i_delta_qp[51] = {
36*437bfbebSnyanmisaka     640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640,
37*437bfbebSnyanmisaka     576, 576, 512, 512, 448, 448, 384, 384, 320, 320, 320, 256, 256, 256,
38*437bfbebSnyanmisaka     192, 192, 192, 192, 192, 128, 128, 128, 128, 128, 128, 64,  64,  64,
39*437bfbebSnyanmisaka     64,  64,  64,  0,   0,   0,   0,   0,   0,
40*437bfbebSnyanmisaka };
41*437bfbebSnyanmisaka 
42*437bfbebSnyanmisaka RK_S32 tab_lnx[64] = {
43*437bfbebSnyanmisaka     -1216, -972, -830, -729, -651, -587, -533, -486,
44*437bfbebSnyanmisaka     -445, -408, -374, -344, -316, -290, -265, -243,
45*437bfbebSnyanmisaka     -221, -201, -182, -164, -147, -131, -115, -100,
46*437bfbebSnyanmisaka     -86,  -72,  -59,  -46,  -34,  -22,  -11,    0,
47*437bfbebSnyanmisaka     10,   21,   31,   41,   50,   60,   69,   78,
48*437bfbebSnyanmisaka     86,   95,   87,  103,  111,  119,  127,  134,
49*437bfbebSnyanmisaka     142,  149,  156,  163,  170,  177,  183,  190,
50*437bfbebSnyanmisaka     196,  202,  208,  214,  220,  226,  232,  237,
51*437bfbebSnyanmisaka };
52*437bfbebSnyanmisaka 
53*437bfbebSnyanmisaka RK_S32 mean_qp2scale[16] = {
54*437bfbebSnyanmisaka     14,  15,  16, 18, 20, 22, 25, 28,
55*437bfbebSnyanmisaka     32,  36,  40, 44, 50, 56, 64, 72
56*437bfbebSnyanmisaka };
57*437bfbebSnyanmisaka const RK_S8 max_ip_qp_dealt[8] = {
58*437bfbebSnyanmisaka     7, 7, 6, 6, 5, 5, 4, 4
59*437bfbebSnyanmisaka };
60*437bfbebSnyanmisaka RK_U32 bit2percent[100] = {
61*437bfbebSnyanmisaka     99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
62*437bfbebSnyanmisaka     99, 95, 90, 85, 80, 75, 72, 69, 66, 64,
63*437bfbebSnyanmisaka     62, 59, 58, 57, 56, 55, 54, 53, 52, 51,
64*437bfbebSnyanmisaka     50, 49, 48, 47, 47, 46, 46, 45, 45, 44,
65*437bfbebSnyanmisaka     44, 43, 43, 43, 42, 42, 42, 41, 41, 41,
66*437bfbebSnyanmisaka     40, 40, 40, 39, 39, 39, 38, 38, 38, 37,
67*437bfbebSnyanmisaka     37, 37, 37, 37, 37, 37, 36, 36, 36, 36,
68*437bfbebSnyanmisaka     36, 36, 36, 35, 35, 35, 34, 34, 34, 34,
69*437bfbebSnyanmisaka     34, 33, 33, 33, 33, 33, 33, 33, 33, 33,
70*437bfbebSnyanmisaka     32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
71*437bfbebSnyanmisaka };
72*437bfbebSnyanmisaka 
73*437bfbebSnyanmisaka RK_S8 intra_qp_map[8] = {
74*437bfbebSnyanmisaka     0, 0, 1, 1, 2, 2, 2, 2,
75*437bfbebSnyanmisaka };
76*437bfbebSnyanmisaka 
bits_model_param_deinit(RcModelV2Ctx * ctx)77*437bfbebSnyanmisaka MPP_RET bits_model_param_deinit(RcModelV2Ctx *ctx)
78*437bfbebSnyanmisaka {
79*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
80*437bfbebSnyanmisaka 
81*437bfbebSnyanmisaka     if (ctx->i_bit != NULL) {
82*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->i_bit);
83*437bfbebSnyanmisaka         ctx->i_bit = NULL;
84*437bfbebSnyanmisaka     }
85*437bfbebSnyanmisaka 
86*437bfbebSnyanmisaka     if (ctx->p_bit != NULL) {
87*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->p_bit);
88*437bfbebSnyanmisaka         ctx->p_bit = NULL;
89*437bfbebSnyanmisaka     }
90*437bfbebSnyanmisaka 
91*437bfbebSnyanmisaka     if (ctx->vi_bit != NULL) {
92*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->vi_bit);
93*437bfbebSnyanmisaka         ctx->vi_bit = NULL;
94*437bfbebSnyanmisaka     }
95*437bfbebSnyanmisaka 
96*437bfbebSnyanmisaka     if (ctx->pre_p_bit != NULL) {
97*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->pre_p_bit);
98*437bfbebSnyanmisaka         ctx->pre_p_bit = NULL;
99*437bfbebSnyanmisaka     }
100*437bfbebSnyanmisaka 
101*437bfbebSnyanmisaka     if (ctx->pre_i_bit != NULL) {
102*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->pre_i_bit);
103*437bfbebSnyanmisaka         ctx->pre_i_bit = NULL;
104*437bfbebSnyanmisaka     }
105*437bfbebSnyanmisaka 
106*437bfbebSnyanmisaka     if (ctx->pre_i_mean_qp != NULL) {
107*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->pre_i_mean_qp);
108*437bfbebSnyanmisaka         ctx->pre_i_mean_qp = NULL;
109*437bfbebSnyanmisaka     }
110*437bfbebSnyanmisaka 
111*437bfbebSnyanmisaka     if (ctx->madi != NULL) {
112*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->madi);
113*437bfbebSnyanmisaka         ctx->madi = NULL;
114*437bfbebSnyanmisaka     }
115*437bfbebSnyanmisaka     if (ctx->madp != NULL) {
116*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->madp);
117*437bfbebSnyanmisaka         ctx->madp = NULL;
118*437bfbebSnyanmisaka     }
119*437bfbebSnyanmisaka 
120*437bfbebSnyanmisaka     if (ctx->stat_rate != NULL) {
121*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->stat_rate);
122*437bfbebSnyanmisaka         ctx->stat_rate = NULL;
123*437bfbebSnyanmisaka     }
124*437bfbebSnyanmisaka 
125*437bfbebSnyanmisaka     if (ctx->stat_bits != NULL) {
126*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->stat_bits);
127*437bfbebSnyanmisaka         ctx->stat_bits = NULL;
128*437bfbebSnyanmisaka     }
129*437bfbebSnyanmisaka     if (ctx->gop_bits != NULL) {
130*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->gop_bits);
131*437bfbebSnyanmisaka         ctx->gop_bits = NULL;
132*437bfbebSnyanmisaka     }
133*437bfbebSnyanmisaka     if (ctx->motion_level != NULL) {
134*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->motion_level);
135*437bfbebSnyanmisaka         ctx->motion_level = NULL;
136*437bfbebSnyanmisaka     }
137*437bfbebSnyanmisaka     if (ctx->complex_level != NULL) {
138*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->complex_level);
139*437bfbebSnyanmisaka         ctx->complex_level = NULL;
140*437bfbebSnyanmisaka     }
141*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
142*437bfbebSnyanmisaka     return MPP_OK;
143*437bfbebSnyanmisaka }
144*437bfbebSnyanmisaka 
bits_model_param_init(RcModelV2Ctx * ctx)145*437bfbebSnyanmisaka MPP_RET bits_model_param_init(RcModelV2Ctx *ctx)
146*437bfbebSnyanmisaka {
147*437bfbebSnyanmisaka     RK_S32 gop_len = ctx->usr_cfg.igop;
148*437bfbebSnyanmisaka     RcFpsCfg *fps = &ctx->usr_cfg.fps;
149*437bfbebSnyanmisaka     RK_S32 mad_len = 10;
150*437bfbebSnyanmisaka     RK_U32 stat_len = fps->fps_out_num * ctx->usr_cfg.stats_time / fps->fps_out_denom;
151*437bfbebSnyanmisaka     stat_len = stat_len ? stat_len : 1;
152*437bfbebSnyanmisaka 
153*437bfbebSnyanmisaka     bits_model_param_deinit(ctx);
154*437bfbebSnyanmisaka     mpp_data_init_v2(&ctx->i_bit, I_WINDOW_LEN, 0);
155*437bfbebSnyanmisaka     if (ctx->i_bit == NULL) {
156*437bfbebSnyanmisaka         mpp_err("i_bit init fail");
157*437bfbebSnyanmisaka         return MPP_ERR_MALLOC;
158*437bfbebSnyanmisaka     }
159*437bfbebSnyanmisaka 
160*437bfbebSnyanmisaka     mpp_data_init_v2(&ctx->vi_bit, I_WINDOW_LEN, 0);
161*437bfbebSnyanmisaka     if (ctx->vi_bit == NULL) {
162*437bfbebSnyanmisaka         mpp_err("vi_bit init fail");
163*437bfbebSnyanmisaka         return MPP_ERR_MALLOC;
164*437bfbebSnyanmisaka     }
165*437bfbebSnyanmisaka     mpp_data_init_v2(&ctx->p_bit, P_WINDOW1_LEN, 0);
166*437bfbebSnyanmisaka     if (ctx->p_bit == NULL) {
167*437bfbebSnyanmisaka         mpp_err("p_bit init fail");
168*437bfbebSnyanmisaka         return MPP_ERR_MALLOC;
169*437bfbebSnyanmisaka     }
170*437bfbebSnyanmisaka 
171*437bfbebSnyanmisaka     mpp_data_init_v2(&ctx->pre_p_bit, P_WINDOW2_LEN, 0);
172*437bfbebSnyanmisaka     if (ctx->pre_p_bit == NULL) {
173*437bfbebSnyanmisaka         mpp_err("pre_p_bit init fail");
174*437bfbebSnyanmisaka         return MPP_ERR_MALLOC;
175*437bfbebSnyanmisaka     }
176*437bfbebSnyanmisaka 
177*437bfbebSnyanmisaka     mpp_data_init_v2(&ctx->pre_i_bit, I_WINDOW_LEN, 0);
178*437bfbebSnyanmisaka     if (ctx->pre_i_bit == NULL) {
179*437bfbebSnyanmisaka         mpp_err("pre_i_bit init fail");
180*437bfbebSnyanmisaka         return MPP_ERR_MALLOC;
181*437bfbebSnyanmisaka     }
182*437bfbebSnyanmisaka 
183*437bfbebSnyanmisaka     mpp_data_init_v2(&ctx->pre_i_mean_qp, I_WINDOW_LEN, -1);
184*437bfbebSnyanmisaka     if (ctx->pre_i_mean_qp == NULL) {
185*437bfbebSnyanmisaka         mpp_err("pre_i_mean_qp init fail");
186*437bfbebSnyanmisaka         return MPP_ERR_MALLOC;
187*437bfbebSnyanmisaka     }
188*437bfbebSnyanmisaka     mpp_data_init_v2(&ctx->madi, P_WINDOW2_LEN, 0);
189*437bfbebSnyanmisaka     if (ctx->madi == NULL) {
190*437bfbebSnyanmisaka         mpp_err("madi init fail");
191*437bfbebSnyanmisaka         return MPP_ERR_MALLOC;
192*437bfbebSnyanmisaka     }
193*437bfbebSnyanmisaka     mpp_data_init_v2(&ctx->madp, P_WINDOW2_LEN, 0);
194*437bfbebSnyanmisaka     if (ctx->madp == NULL) {
195*437bfbebSnyanmisaka         mpp_err("madp init fail");
196*437bfbebSnyanmisaka         return MPP_ERR_MALLOC;
197*437bfbebSnyanmisaka     }
198*437bfbebSnyanmisaka     mpp_data_init_v2(&ctx->stat_rate, fps->fps_out_num, 0);
199*437bfbebSnyanmisaka     if (ctx->stat_rate == NULL) {
200*437bfbebSnyanmisaka         mpp_err("stat_rate init fail fps_out_num %d", fps->fps_out_num);
201*437bfbebSnyanmisaka         return MPP_ERR_MALLOC;
202*437bfbebSnyanmisaka     }
203*437bfbebSnyanmisaka 
204*437bfbebSnyanmisaka     mpp_data_init_v2(&ctx->stat_bits, stat_len, ctx->bit_per_frame);
205*437bfbebSnyanmisaka     if (ctx->stat_bits == NULL) {
206*437bfbebSnyanmisaka         mpp_err("stat_bits init fail stat_len %d", stat_len);
207*437bfbebSnyanmisaka         return MPP_ERR_MALLOC;
208*437bfbebSnyanmisaka     }
209*437bfbebSnyanmisaka 
210*437bfbebSnyanmisaka     mpp_data_init_v2(&ctx->gop_bits, gop_len, 0);
211*437bfbebSnyanmisaka     if (ctx->gop_bits == NULL) {
212*437bfbebSnyanmisaka         mpp_err("gop_bits init fail gop_len %d", gop_len);
213*437bfbebSnyanmisaka         return MPP_ERR_MALLOC;
214*437bfbebSnyanmisaka     }
215*437bfbebSnyanmisaka 
216*437bfbebSnyanmisaka     if (ctx->usr_cfg.refresh_len) {
217*437bfbebSnyanmisaka         mpp_data_init_v2(&ctx->i_refresh_bit, ctx->usr_cfg.refresh_len, 0);
218*437bfbebSnyanmisaka         if (ctx->i_refresh_bit == NULL) {
219*437bfbebSnyanmisaka             mpp_err("i_refresh_bit init fail refresh_len %d", ctx->usr_cfg.refresh_len);
220*437bfbebSnyanmisaka             return MPP_ERR_MALLOC;
221*437bfbebSnyanmisaka         }
222*437bfbebSnyanmisaka     }
223*437bfbebSnyanmisaka 
224*437bfbebSnyanmisaka     mpp_data_init_v2(&ctx->motion_level, mad_len, 0);
225*437bfbebSnyanmisaka     if (ctx->motion_level == NULL) {
226*437bfbebSnyanmisaka         mpp_err("motion_level init fail mad_len %d\n", mad_len);
227*437bfbebSnyanmisaka         return MPP_ERR_MALLOC;
228*437bfbebSnyanmisaka     }
229*437bfbebSnyanmisaka 
230*437bfbebSnyanmisaka     mpp_data_init_v2(&ctx->complex_level, mad_len, 0);
231*437bfbebSnyanmisaka     if (ctx->complex_level == NULL) {
232*437bfbebSnyanmisaka         mpp_err("complex_level init fail mad_len %d\n", mad_len);
233*437bfbebSnyanmisaka         return MPP_ERR_MALLOC;
234*437bfbebSnyanmisaka     }
235*437bfbebSnyanmisaka 
236*437bfbebSnyanmisaka     return MPP_OK;
237*437bfbebSnyanmisaka }
238*437bfbebSnyanmisaka 
bits_frm_init(RcModelV2Ctx * ctx)239*437bfbebSnyanmisaka void bits_frm_init(RcModelV2Ctx *ctx)
240*437bfbebSnyanmisaka {
241*437bfbebSnyanmisaka     RcCfg *usr_cfg = &ctx->usr_cfg;
242*437bfbebSnyanmisaka     RK_U32 gop_len = usr_cfg->igop;
243*437bfbebSnyanmisaka     RK_U32 p_bit = 0;
244*437bfbebSnyanmisaka     RK_U32 refresh_bit = 0;
245*437bfbebSnyanmisaka 
246*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
247*437bfbebSnyanmisaka 
248*437bfbebSnyanmisaka     switch (usr_cfg->gop_mode) {
249*437bfbebSnyanmisaka     case NORMAL_P: {
250*437bfbebSnyanmisaka         ctx->i_scale = ctx->usr_cfg.init_ip_ratio;
251*437bfbebSnyanmisaka         ctx->p_scale = 16;
252*437bfbebSnyanmisaka         if (gop_len <= 1)
253*437bfbebSnyanmisaka             p_bit = ctx->gop_total_bits * 16;
254*437bfbebSnyanmisaka         else
255*437bfbebSnyanmisaka             p_bit = ctx->gop_total_bits * 16 / (ctx->i_scale + ctx->p_scale * (gop_len - 1));
256*437bfbebSnyanmisaka         mpp_data_reset_v2(ctx->p_bit, p_bit);
257*437bfbebSnyanmisaka         ctx->p_sumbits = 5 * p_bit;
258*437bfbebSnyanmisaka         mpp_data_reset_v2(ctx->i_bit, p_bit * ctx->i_scale / 16);
259*437bfbebSnyanmisaka         ctx->i_sumbits = 2 * p_bit * ctx->i_scale / 16;
260*437bfbebSnyanmisaka         if (usr_cfg->refresh_len) {
261*437bfbebSnyanmisaka             ctx->i_refresh_scale = ctx->i_scale / usr_cfg->refresh_len  +  ctx->p_scale;
262*437bfbebSnyanmisaka             refresh_bit = ctx->gop_total_bits *  16 / (ctx->i_refresh_scale * usr_cfg->refresh_len
263*437bfbebSnyanmisaka                                                        + ctx->p_scale * (gop_len - usr_cfg->refresh_len));
264*437bfbebSnyanmisaka             mpp_data_reset_v2(ctx->i_refresh_bit, refresh_bit);
265*437bfbebSnyanmisaka             ctx->i_refresh_sumbits = usr_cfg->refresh_len * refresh_bit;
266*437bfbebSnyanmisaka         }
267*437bfbebSnyanmisaka     } break;
268*437bfbebSnyanmisaka     case SMART_P: {
269*437bfbebSnyanmisaka         RK_U32 vi_num = 0;
270*437bfbebSnyanmisaka         mpp_assert(usr_cfg->vgop > 1);
271*437bfbebSnyanmisaka         ctx->i_scale = 320;
272*437bfbebSnyanmisaka         ctx->p_scale = 16;
273*437bfbebSnyanmisaka         ctx->vi_scale = 32;
274*437bfbebSnyanmisaka         vi_num = gop_len / usr_cfg->vgop;
275*437bfbebSnyanmisaka         if (vi_num > 0) {
276*437bfbebSnyanmisaka             vi_num = vi_num - 1;
277*437bfbebSnyanmisaka         }
278*437bfbebSnyanmisaka         p_bit = ctx->gop_total_bits * 16 / (ctx->i_scale + ctx->vi_scale * vi_num + ctx->p_scale * (gop_len - vi_num));
279*437bfbebSnyanmisaka         mpp_data_reset_v2(ctx->p_bit, p_bit);
280*437bfbebSnyanmisaka         ctx->p_sumbits = 5 * p_bit;
281*437bfbebSnyanmisaka 
282*437bfbebSnyanmisaka         mpp_data_reset_v2(ctx->i_bit, p_bit * ctx->i_scale / 16);
283*437bfbebSnyanmisaka         ctx->i_sumbits = 2 * p_bit * ctx->i_scale / 16;
284*437bfbebSnyanmisaka 
285*437bfbebSnyanmisaka         mpp_data_reset_v2(ctx->vi_bit, p_bit * ctx->vi_scale / 16);
286*437bfbebSnyanmisaka         ctx->vi_sumbits = 2 * p_bit * ctx->vi_scale / 16;
287*437bfbebSnyanmisaka     } break;
288*437bfbebSnyanmisaka     default:
289*437bfbebSnyanmisaka         break;
290*437bfbebSnyanmisaka     }
291*437bfbebSnyanmisaka     rc_dbg_rc("p_sumbits %d i_sumbits %d vi_sumbits %d\n", ctx->p_sumbits, ctx->i_sumbits, ctx->vi_sumbits);
292*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
293*437bfbebSnyanmisaka }
294*437bfbebSnyanmisaka 
moving_judge_update(RcModelV2Ctx * ctx,EncRcTaskInfo * cfg)295*437bfbebSnyanmisaka RK_S32 moving_judge_update(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg)
296*437bfbebSnyanmisaka {
297*437bfbebSnyanmisaka     switch (cfg->frame_type) {
298*437bfbebSnyanmisaka     case INTRA_FRAME: {
299*437bfbebSnyanmisaka         mpp_data_update_v2(ctx->pre_i_bit, cfg->bit_real);
300*437bfbebSnyanmisaka         mpp_data_update_v2(ctx->pre_i_mean_qp, cfg->quality_real);
301*437bfbebSnyanmisaka     } break;
302*437bfbebSnyanmisaka 
303*437bfbebSnyanmisaka     case INTER_P_FRAME: {
304*437bfbebSnyanmisaka         mpp_data_update_v2(ctx->pre_p_bit, cfg->bit_real);
305*437bfbebSnyanmisaka         mpp_data_update_v2(ctx->madp, cfg->madp);
306*437bfbebSnyanmisaka     } break;
307*437bfbebSnyanmisaka 
308*437bfbebSnyanmisaka     default:
309*437bfbebSnyanmisaka         break;
310*437bfbebSnyanmisaka     }
311*437bfbebSnyanmisaka     return 0;
312*437bfbebSnyanmisaka }
313*437bfbebSnyanmisaka 
bit_statics_update(RcModelV2Ctx * ctx,RK_U32 real_bit)314*437bfbebSnyanmisaka void bit_statics_update(RcModelV2Ctx *ctx, RK_U32 real_bit)
315*437bfbebSnyanmisaka {
316*437bfbebSnyanmisaka     RK_S32 mean_pbits, mean_ibits;
317*437bfbebSnyanmisaka     RcCfg  *usr_cfg = &ctx->usr_cfg;
318*437bfbebSnyanmisaka     RK_U32 gop_len = usr_cfg->igop;
319*437bfbebSnyanmisaka 
320*437bfbebSnyanmisaka     mpp_data_update_v2(ctx->gop_bits, real_bit);
321*437bfbebSnyanmisaka     mean_pbits = mpp_data_mean_v2(ctx->pre_p_bit);
322*437bfbebSnyanmisaka     mean_ibits = mpp_data_mean_v2(ctx->pre_i_bit);
323*437bfbebSnyanmisaka     ctx->real_gbits  = mpp_data_sum_v2(ctx->gop_bits);
324*437bfbebSnyanmisaka     ctx->avg_gbits  = (gop_len - 1) * (RK_S64)mean_pbits + mean_ibits;
325*437bfbebSnyanmisaka }
326*437bfbebSnyanmisaka 
bits_model_preset(RcModelV2Ctx * ctx,EncRcTaskInfo * info)327*437bfbebSnyanmisaka MPP_RET bits_model_preset(RcModelV2Ctx *ctx, EncRcTaskInfo *info)
328*437bfbebSnyanmisaka {
329*437bfbebSnyanmisaka     RcCfg *usr_cfg = &ctx->usr_cfg;
330*437bfbebSnyanmisaka     RK_S32 preset_bit = info->bit_target;
331*437bfbebSnyanmisaka     RK_S32 water_level = 0;
332*437bfbebSnyanmisaka 
333*437bfbebSnyanmisaka     mpp_data_preset_v2(ctx->stat_rate, preset_bit != 0);
334*437bfbebSnyanmisaka     mpp_data_preset_v2(ctx->stat_bits, preset_bit);
335*437bfbebSnyanmisaka 
336*437bfbebSnyanmisaka     ctx->ins_bps = mpp_data_sum_v2(ctx->stat_bits) / usr_cfg->stats_time;
337*437bfbebSnyanmisaka     if (preset_bit + ctx->stat_watl > ctx->watl_thrd)
338*437bfbebSnyanmisaka         water_level = ctx->watl_thrd - ctx->bit_per_frame;
339*437bfbebSnyanmisaka     else
340*437bfbebSnyanmisaka         water_level = preset_bit + ctx->stat_watl - ctx->bit_per_frame;
341*437bfbebSnyanmisaka 
342*437bfbebSnyanmisaka     if (water_level < 0) {
343*437bfbebSnyanmisaka         water_level = 0;
344*437bfbebSnyanmisaka     }
345*437bfbebSnyanmisaka     ctx->stat_watl = water_level;
346*437bfbebSnyanmisaka     switch (info->frame_type) {
347*437bfbebSnyanmisaka     case INTRA_FRAME : {
348*437bfbebSnyanmisaka         mpp_data_preset_v2(ctx->i_bit, preset_bit);
349*437bfbebSnyanmisaka         ctx->i_sumbits = mpp_data_sum_v2(ctx->i_bit);
350*437bfbebSnyanmisaka         ctx->i_scale = 80 * ctx->i_sumbits / (2 * ctx->p_sumbits);
351*437bfbebSnyanmisaka         rc_dbg_rc("i_sumbits %d p_sumbits %d i_scale %d\n",
352*437bfbebSnyanmisaka                   ctx->i_sumbits, ctx->p_sumbits, ctx->i_scale);
353*437bfbebSnyanmisaka     } break;
354*437bfbebSnyanmisaka     case INTER_P_FRAME : {
355*437bfbebSnyanmisaka         mpp_data_preset_v2(ctx->p_bit, preset_bit);
356*437bfbebSnyanmisaka         ctx->p_sumbits = mpp_data_sum_v2(ctx->p_bit);
357*437bfbebSnyanmisaka 
358*437bfbebSnyanmisaka         /* Avoid div zero when P frame successive drop */
359*437bfbebSnyanmisaka         if (!ctx->p_sumbits)
360*437bfbebSnyanmisaka             ctx->p_sumbits = 1;
361*437bfbebSnyanmisaka 
362*437bfbebSnyanmisaka         ctx->p_scale = 16;
363*437bfbebSnyanmisaka     } break;
364*437bfbebSnyanmisaka     case INTER_VI_FRAME : {
365*437bfbebSnyanmisaka         mpp_data_preset_v2(ctx->vi_bit, preset_bit);
366*437bfbebSnyanmisaka         ctx->vi_sumbits = mpp_data_sum_v2(ctx->vi_bit);
367*437bfbebSnyanmisaka         ctx->vi_scale = 80 * ctx->vi_sumbits / (2 * ctx->p_sumbits);
368*437bfbebSnyanmisaka         /* NOTE: vi_scale may be set to zero. So we should limit the range */
369*437bfbebSnyanmisaka         ctx->vi_scale = mpp_clip(ctx->vi_scale, 16, 320);
370*437bfbebSnyanmisaka     } break;
371*437bfbebSnyanmisaka     case INTRA_RFH_FRAME: {
372*437bfbebSnyanmisaka         mpp_data_update_v2(ctx->i_refresh_bit, preset_bit);
373*437bfbebSnyanmisaka         mpp_data_update_v2(ctx->madi,  info->madi);
374*437bfbebSnyanmisaka         ctx->i_refresh_sumbits = mpp_data_sum_v2(ctx->i_refresh_bit);
375*437bfbebSnyanmisaka         ctx->i_refresh_scale = 80 * ctx->i_refresh_sumbits / (usr_cfg->refresh_len * ctx->p_sumbits);
376*437bfbebSnyanmisaka         ctx->i_refresh_scale = mpp_clip(ctx->i_refresh_scale, 16, 64);
377*437bfbebSnyanmisaka     } break;
378*437bfbebSnyanmisaka     default : {
379*437bfbebSnyanmisaka     } break;
380*437bfbebSnyanmisaka     }
381*437bfbebSnyanmisaka     return MPP_OK;
382*437bfbebSnyanmisaka }
383*437bfbebSnyanmisaka 
bits_model_update(RcModelV2Ctx * ctx,EncRcTaskInfo * cfg)384*437bfbebSnyanmisaka MPP_RET bits_model_update(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg)
385*437bfbebSnyanmisaka {
386*437bfbebSnyanmisaka     RcCfg *usr_cfg = &ctx->usr_cfg;
387*437bfbebSnyanmisaka     RK_S32 real_bit = cfg->bit_real;
388*437bfbebSnyanmisaka     RK_U32 madi = cfg->madi;
389*437bfbebSnyanmisaka     RK_S32 water_level = 0;
390*437bfbebSnyanmisaka 
391*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
392*437bfbebSnyanmisaka 
393*437bfbebSnyanmisaka     mpp_data_update_v2(ctx->stat_rate, real_bit != 0);
394*437bfbebSnyanmisaka     mpp_data_update_v2(ctx->stat_bits, real_bit);
395*437bfbebSnyanmisaka 
396*437bfbebSnyanmisaka     ctx->ins_bps = mpp_data_sum_v2(ctx->stat_bits) / usr_cfg->stats_time;
397*437bfbebSnyanmisaka     if (real_bit + ctx->stat_watl > ctx->watl_thrd)
398*437bfbebSnyanmisaka         water_level = ctx->watl_thrd - ctx->bit_per_frame;
399*437bfbebSnyanmisaka     else
400*437bfbebSnyanmisaka         water_level = real_bit + ctx->stat_watl - ctx->bit_per_frame;
401*437bfbebSnyanmisaka 
402*437bfbebSnyanmisaka     if (water_level < 0)
403*437bfbebSnyanmisaka         water_level = 0;
404*437bfbebSnyanmisaka 
405*437bfbebSnyanmisaka     ctx->stat_watl = water_level;
406*437bfbebSnyanmisaka 
407*437bfbebSnyanmisaka     switch (cfg->frame_type) {
408*437bfbebSnyanmisaka     case INTRA_FRAME : {
409*437bfbebSnyanmisaka         mpp_data_update_v2(ctx->i_bit, real_bit);
410*437bfbebSnyanmisaka         ctx->i_sumbits = mpp_data_sum_v2(ctx->i_bit);
411*437bfbebSnyanmisaka         ctx->i_scale = 80 * ctx->i_sumbits / (2 * ctx->p_sumbits);
412*437bfbebSnyanmisaka         rc_dbg_rc("i_sumbits %d p_sumbits %d i_scale %d\n",
413*437bfbebSnyanmisaka                   ctx->i_sumbits, ctx->p_sumbits, ctx->i_scale);
414*437bfbebSnyanmisaka     } break;
415*437bfbebSnyanmisaka     case INTER_P_FRAME : {
416*437bfbebSnyanmisaka         mpp_data_update_v2(ctx->p_bit, real_bit);
417*437bfbebSnyanmisaka         mpp_data_update_v2(ctx->madi,  madi);
418*437bfbebSnyanmisaka         ctx->p_sumbits = mpp_data_sum_v2(ctx->p_bit);
419*437bfbebSnyanmisaka 
420*437bfbebSnyanmisaka         /* Avoid div zero when P frame successive drop */
421*437bfbebSnyanmisaka         if (!ctx->p_sumbits)
422*437bfbebSnyanmisaka             ctx->p_sumbits = 1;
423*437bfbebSnyanmisaka 
424*437bfbebSnyanmisaka         ctx->p_scale = 16;
425*437bfbebSnyanmisaka     } break;
426*437bfbebSnyanmisaka     case INTER_VI_FRAME: {
427*437bfbebSnyanmisaka         mpp_data_update_v2(ctx->vi_bit, real_bit);
428*437bfbebSnyanmisaka         ctx->vi_sumbits = mpp_data_sum_v2(ctx->vi_bit);
429*437bfbebSnyanmisaka         ctx->vi_scale = 80 * ctx->vi_sumbits / (2 * ctx->p_sumbits);
430*437bfbebSnyanmisaka         /* NOTE: vi_scale may be set to zero. So we should limit the range */
431*437bfbebSnyanmisaka         ctx->vi_scale = mpp_clip(ctx->vi_scale, 16, 320);
432*437bfbebSnyanmisaka     } break;
433*437bfbebSnyanmisaka     case INTRA_RFH_FRAME: {
434*437bfbebSnyanmisaka         mpp_data_update_v2(ctx->i_refresh_bit, real_bit);
435*437bfbebSnyanmisaka         mpp_data_update_v2(ctx->madi,  madi);
436*437bfbebSnyanmisaka         ctx->i_refresh_sumbits = mpp_data_sum_v2(ctx->i_refresh_bit);
437*437bfbebSnyanmisaka         ctx->i_refresh_scale = 80 * ctx->i_refresh_sumbits / (usr_cfg->refresh_len * ctx->p_sumbits);
438*437bfbebSnyanmisaka         ctx->i_refresh_scale = mpp_clip(ctx->i_refresh_scale, 16, 64);
439*437bfbebSnyanmisaka     } break;
440*437bfbebSnyanmisaka     default : {
441*437bfbebSnyanmisaka     } break;
442*437bfbebSnyanmisaka     }
443*437bfbebSnyanmisaka 
444*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
445*437bfbebSnyanmisaka     return MPP_OK;
446*437bfbebSnyanmisaka }
447*437bfbebSnyanmisaka 
bits_model_alloc(RcModelV2Ctx * ctx,EncRcTaskInfo * cfg,RK_S64 total_bits)448*437bfbebSnyanmisaka MPP_RET bits_model_alloc(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg, RK_S64 total_bits)
449*437bfbebSnyanmisaka {
450*437bfbebSnyanmisaka     RcCfg *usr_cfg = &ctx->usr_cfg;
451*437bfbebSnyanmisaka     RK_U32 max_i_prop = usr_cfg->max_i_bit_prop * 16;
452*437bfbebSnyanmisaka     RK_S32 gop_len = usr_cfg->igop;
453*437bfbebSnyanmisaka     RK_S32 i_scale = ctx->i_scale;
454*437bfbebSnyanmisaka     RK_S32 vi_scale = ctx->vi_scale;
455*437bfbebSnyanmisaka     RK_S32 alloc_bits = 0;
456*437bfbebSnyanmisaka     RK_S32 super_bit_thr = 0x7fffffff;
457*437bfbebSnyanmisaka     RK_S64 total_bits_fix = total_bits;
458*437bfbebSnyanmisaka 
459*437bfbebSnyanmisaka     ctx->i_scale = 80 * ctx->i_sumbits / (2 * ctx->p_sumbits);
460*437bfbebSnyanmisaka     i_scale = ctx->i_scale;
461*437bfbebSnyanmisaka 
462*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
463*437bfbebSnyanmisaka     rc_dbg_rc("frame_type %d max_i_prop %d i_scale %d total_bits %lld\n",
464*437bfbebSnyanmisaka               cfg->frame_type, max_i_prop, i_scale, total_bits);
465*437bfbebSnyanmisaka     if (usr_cfg->super_cfg.super_mode) {
466*437bfbebSnyanmisaka         super_bit_thr = usr_cfg->super_cfg.super_p_thd;
467*437bfbebSnyanmisaka     }
468*437bfbebSnyanmisaka     if (usr_cfg->gop_mode == SMART_P) {
469*437bfbebSnyanmisaka         RK_U32 vi_num = 0;
470*437bfbebSnyanmisaka         mpp_assert(usr_cfg->vgop > 1);
471*437bfbebSnyanmisaka         vi_num = gop_len / usr_cfg->vgop;
472*437bfbebSnyanmisaka         if (vi_num > 0) {
473*437bfbebSnyanmisaka             vi_num = vi_num - 1;
474*437bfbebSnyanmisaka         }
475*437bfbebSnyanmisaka         switch (cfg->frame_type) {
476*437bfbebSnyanmisaka         case INTRA_FRAME: {
477*437bfbebSnyanmisaka             i_scale = mpp_clip(i_scale, 16, 16000);
478*437bfbebSnyanmisaka             total_bits = total_bits * i_scale;
479*437bfbebSnyanmisaka             if (usr_cfg->super_cfg.super_mode) {
480*437bfbebSnyanmisaka                 super_bit_thr = usr_cfg->super_cfg.super_i_thd;
481*437bfbebSnyanmisaka             }
482*437bfbebSnyanmisaka         } break;
483*437bfbebSnyanmisaka         case INTER_P_FRAME: {
484*437bfbebSnyanmisaka             i_scale = mpp_clip(i_scale, 16, max_i_prop);
485*437bfbebSnyanmisaka             total_bits = total_bits * 16;
486*437bfbebSnyanmisaka         } break;
487*437bfbebSnyanmisaka         case INTER_VI_FRAME: {
488*437bfbebSnyanmisaka             i_scale = mpp_clip(i_scale, 16, max_i_prop);
489*437bfbebSnyanmisaka             total_bits = total_bits * vi_scale;
490*437bfbebSnyanmisaka         } break;
491*437bfbebSnyanmisaka         default:
492*437bfbebSnyanmisaka             break;
493*437bfbebSnyanmisaka         }
494*437bfbebSnyanmisaka 
495*437bfbebSnyanmisaka         alloc_bits = total_bits / (i_scale + 16 * (gop_len - vi_num) + vi_num * vi_scale);
496*437bfbebSnyanmisaka 
497*437bfbebSnyanmisaka         if (!alloc_bits) {
498*437bfbebSnyanmisaka             mpp_log_f("found zero alloc bits\n");
499*437bfbebSnyanmisaka             mpp_log_f("total_bits %lld, i_scale %d, gop_len %d, vi_num %d, vi_scale %d",
500*437bfbebSnyanmisaka                       total_bits, i_scale, gop_len, vi_num, vi_scale);
501*437bfbebSnyanmisaka             mpp_log_f("gop_total_bits %lld, i_sumbits %d, p_sumbits %d, vgop %d igop %d",
502*437bfbebSnyanmisaka                       ctx->gop_total_bits, ctx->i_sumbits, ctx->p_sumbits, usr_cfg->vgop, usr_cfg->igop);
503*437bfbebSnyanmisaka         }
504*437bfbebSnyanmisaka     } else {
505*437bfbebSnyanmisaka         switch (cfg->frame_type) {
506*437bfbebSnyanmisaka         case INTRA_FRAME: {
507*437bfbebSnyanmisaka             i_scale = mpp_clip(i_scale, 16, 16000);
508*437bfbebSnyanmisaka             total_bits = total_bits * i_scale;
509*437bfbebSnyanmisaka             if (usr_cfg->super_cfg.super_mode) {
510*437bfbebSnyanmisaka                 super_bit_thr = usr_cfg->super_cfg.super_i_thd;
511*437bfbebSnyanmisaka             }
512*437bfbebSnyanmisaka         } break;
513*437bfbebSnyanmisaka 
514*437bfbebSnyanmisaka         case INTER_P_FRAME: {
515*437bfbebSnyanmisaka             i_scale = mpp_clip(i_scale, 16, max_i_prop);
516*437bfbebSnyanmisaka             total_bits = total_bits * 16;
517*437bfbebSnyanmisaka         } break;
518*437bfbebSnyanmisaka         case INTRA_RFH_FRAME: {
519*437bfbebSnyanmisaka             i_scale = mpp_clip(i_scale, 16, max_i_prop);
520*437bfbebSnyanmisaka             total_bits = total_bits * ctx->i_refresh_scale;
521*437bfbebSnyanmisaka             rc_dbg_rc("ctx->i_refresh_scale = %d", ctx->i_refresh_scale);
522*437bfbebSnyanmisaka         } break;
523*437bfbebSnyanmisaka         default:
524*437bfbebSnyanmisaka             break;
525*437bfbebSnyanmisaka         }
526*437bfbebSnyanmisaka         if (gop_len > 1) {
527*437bfbebSnyanmisaka             if (!usr_cfg->refresh_len || cfg->frame_type == INTRA_FRAME)
528*437bfbebSnyanmisaka                 alloc_bits = total_bits / (i_scale + 16 * (gop_len - 1));
529*437bfbebSnyanmisaka             else
530*437bfbebSnyanmisaka                 alloc_bits = total_bits /
531*437bfbebSnyanmisaka                              (ctx->i_refresh_scale * usr_cfg->refresh_len +
532*437bfbebSnyanmisaka                               16 * (gop_len - usr_cfg->refresh_len));
533*437bfbebSnyanmisaka         } else {
534*437bfbebSnyanmisaka             alloc_bits = total_bits / i_scale;
535*437bfbebSnyanmisaka         }
536*437bfbebSnyanmisaka     }
537*437bfbebSnyanmisaka     rc_dbg_rc("i_scale  %d, total_bits %lld", i_scale, total_bits);
538*437bfbebSnyanmisaka     if (alloc_bits > super_bit_thr &&
539*437bfbebSnyanmisaka         (usr_cfg->super_cfg.rc_priority == MPP_ENC_RC_BY_FRM_SIZE_FIRST)) {
540*437bfbebSnyanmisaka         alloc_bits = super_bit_thr - (super_bit_thr >> 4);
541*437bfbebSnyanmisaka         rc_dbg_rc("alloc bits max then super_bit_thr %d", super_bit_thr);
542*437bfbebSnyanmisaka     }
543*437bfbebSnyanmisaka 
544*437bfbebSnyanmisaka     ctx->cur_super_thd = super_bit_thr;
545*437bfbebSnyanmisaka     cfg->bit_target = alloc_bits;
546*437bfbebSnyanmisaka     if (cfg->frame_type == INTRA_FRAME)
547*437bfbebSnyanmisaka         cfg->bit_target_fix = total_bits_fix * 240 / (240 + 16 * (gop_len - 1));
548*437bfbebSnyanmisaka     else
549*437bfbebSnyanmisaka         cfg->bit_target_fix = total_bits_fix * 16 / (240 + 16 * (gop_len - 1));
550*437bfbebSnyanmisaka 
551*437bfbebSnyanmisaka     mpp_assert(alloc_bits);
552*437bfbebSnyanmisaka 
553*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
554*437bfbebSnyanmisaka     return MPP_OK;
555*437bfbebSnyanmisaka }
556*437bfbebSnyanmisaka 
calc_next_i_ratio(RcModelV2Ctx * ctx)557*437bfbebSnyanmisaka MPP_RET calc_next_i_ratio(RcModelV2Ctx *ctx)
558*437bfbebSnyanmisaka {
559*437bfbebSnyanmisaka     RcCfg *usr_cfg = &ctx->usr_cfg;
560*437bfbebSnyanmisaka     RK_S32 max_i_prop = usr_cfg->max_i_bit_prop * 16;
561*437bfbebSnyanmisaka     RK_S32 gop_len    = usr_cfg->igop;
562*437bfbebSnyanmisaka     RK_S32 pre_qp     = ctx->pre_i_qp;
563*437bfbebSnyanmisaka     RK_S32 bits_alloc;
564*437bfbebSnyanmisaka 
565*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
566*437bfbebSnyanmisaka     if (gop_len > 1) {
567*437bfbebSnyanmisaka         bits_alloc = ctx->gop_total_bits * max_i_prop / (max_i_prop + 16 * (gop_len - 1));
568*437bfbebSnyanmisaka     } else {
569*437bfbebSnyanmisaka         bits_alloc = ctx->gop_total_bits * max_i_prop / max_i_prop;
570*437bfbebSnyanmisaka     }
571*437bfbebSnyanmisaka 
572*437bfbebSnyanmisaka     if (ctx->pre_real_bits > bits_alloc || ctx->next_i_ratio) {
573*437bfbebSnyanmisaka         RK_S32 ratio = ((ctx->pre_real_bits - bits_alloc) << 8) / bits_alloc;
574*437bfbebSnyanmisaka 
575*437bfbebSnyanmisaka         ratio = mpp_clip(ratio, -256, 256);
576*437bfbebSnyanmisaka         ratio = ctx->next_i_ratio + ratio;
577*437bfbebSnyanmisaka         if (ratio >= 0) {
578*437bfbebSnyanmisaka             if (ratio > max_i_delta_qp[pre_qp])
579*437bfbebSnyanmisaka                 ratio = max_i_delta_qp[pre_qp];
580*437bfbebSnyanmisaka         } else {
581*437bfbebSnyanmisaka             ratio = 0;
582*437bfbebSnyanmisaka         }
583*437bfbebSnyanmisaka         ctx->next_i_ratio = ratio;
584*437bfbebSnyanmisaka         rc_dbg_rc("ctx->next_i_ratio %d", ctx->next_i_ratio);
585*437bfbebSnyanmisaka     }
586*437bfbebSnyanmisaka 
587*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
588*437bfbebSnyanmisaka     return MPP_OK;
589*437bfbebSnyanmisaka 
590*437bfbebSnyanmisaka }
591*437bfbebSnyanmisaka 
calc_debreath_qp(RcModelV2Ctx * ctx)592*437bfbebSnyanmisaka MPP_RET calc_debreath_qp(RcModelV2Ctx *ctx)
593*437bfbebSnyanmisaka {
594*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
595*437bfbebSnyanmisaka     RcDebreathCfg *debreath_cfg = &ctx->usr_cfg.debreath_cfg;
596*437bfbebSnyanmisaka     RK_S32 qp_start_sum = 0;
597*437bfbebSnyanmisaka     RK_S32 new_start_qp = 0;
598*437bfbebSnyanmisaka     RK_U8 idx2 = MPP_MIN(ctx->pre_iblk4_prop >> 5, (RK_S32)sizeof(intra_qp_map) - 1);
599*437bfbebSnyanmisaka 
600*437bfbebSnyanmisaka     static RK_S8 strength_map[36] = {
601*437bfbebSnyanmisaka         0, 1, 1, 2,  2,  2,  3,  3,  3,  4,  4,  4,
602*437bfbebSnyanmisaka         5, 5, 5, 6,  6,  6,  7,  7,  7,  8,  8,  8,
603*437bfbebSnyanmisaka         9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12
604*437bfbebSnyanmisaka     };
605*437bfbebSnyanmisaka 
606*437bfbebSnyanmisaka     qp_start_sum = MPP_MIN(ctx->gop_qp_sum / ctx->gop_frm_cnt, (RK_S32)sizeof(strength_map) - 1);
607*437bfbebSnyanmisaka 
608*437bfbebSnyanmisaka     rc_dbg_qp("i start_qp %d, qp_start_sum = %d, intra_lv4_prop %d",
609*437bfbebSnyanmisaka               ctx->start_qp, qp_start_sum, ctx->pre_iblk4_prop);
610*437bfbebSnyanmisaka 
611*437bfbebSnyanmisaka     RK_S32 dealt_qp = strength_map[debreath_cfg->strength] - intra_qp_map[idx2];
612*437bfbebSnyanmisaka     if (qp_start_sum > dealt_qp)
613*437bfbebSnyanmisaka         new_start_qp = qp_start_sum - dealt_qp;
614*437bfbebSnyanmisaka     else
615*437bfbebSnyanmisaka         new_start_qp = qp_start_sum;
616*437bfbebSnyanmisaka 
617*437bfbebSnyanmisaka     ctx->start_qp = mpp_clip(new_start_qp, ctx->usr_cfg.min_i_quality, ctx->usr_cfg.max_i_quality);
618*437bfbebSnyanmisaka 
619*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
620*437bfbebSnyanmisaka     return MPP_OK;
621*437bfbebSnyanmisaka }
622*437bfbebSnyanmisaka 
calc_cbr_ratio(void * ctx,EncRcTaskInfo * cfg)623*437bfbebSnyanmisaka MPP_RET calc_cbr_ratio(void *ctx, EncRcTaskInfo *cfg)
624*437bfbebSnyanmisaka {
625*437bfbebSnyanmisaka     RcModelV2Ctx *p = (RcModelV2Ctx *)ctx;
626*437bfbebSnyanmisaka     RK_S32 target_bps = p->target_bps;
627*437bfbebSnyanmisaka     RK_S32 ins_bps = p->ins_bps;
628*437bfbebSnyanmisaka     RK_S32 pre_target_bits = p->pre_target_bits;
629*437bfbebSnyanmisaka     RK_S32 pre_real_bits = p->pre_real_bits;
630*437bfbebSnyanmisaka     RK_S32 pre_ins_bps = p->last_inst_bps;
631*437bfbebSnyanmisaka     RK_S32 idx1, idx2;
632*437bfbebSnyanmisaka     RK_S32 bit_diff_ratio, ins_ratio, bps_ratio, wl_ratio;
633*437bfbebSnyanmisaka     RK_S32 fluc_l = 3;
634*437bfbebSnyanmisaka 
635*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", p);
636*437bfbebSnyanmisaka 
637*437bfbebSnyanmisaka     rc_dbg_bps("%10s|%10s|%10s|%10s|%10s|%8s", "r_bits", "t_bits", "ins_bps", "p_ins_bps", "target_bps", "watl");
638*437bfbebSnyanmisaka     rc_dbg_bps("%10d %10d %10d %10d %10d %8d", pre_real_bits, pre_target_bits, ins_bps, pre_ins_bps, target_bps, p->stat_watl >> 10);
639*437bfbebSnyanmisaka 
640*437bfbebSnyanmisaka     bits_model_alloc(p, cfg, p->gop_total_bits);
641*437bfbebSnyanmisaka 
642*437bfbebSnyanmisaka     mpp_assert(target_bps > 0);
643*437bfbebSnyanmisaka 
644*437bfbebSnyanmisaka     p->pre_real_bits_count = p->pre_real_bits_count + pre_real_bits;
645*437bfbebSnyanmisaka     p->pre_target_bits_fix_count = p->pre_target_bits_fix_count + p->pre_target_bits_fix;
646*437bfbebSnyanmisaka     if (p->pre_real_bits_count > MAX_BIT_COUNT_VALUE || p->pre_target_bits_fix_count > MAX_BIT_COUNT_VALUE) {
647*437bfbebSnyanmisaka         p->pre_real_bits_count = 0;
648*437bfbebSnyanmisaka         p->pre_target_bits_fix_count = 0;
649*437bfbebSnyanmisaka     }
650*437bfbebSnyanmisaka 
651*437bfbebSnyanmisaka     if (pre_target_bits > pre_real_bits)
652*437bfbebSnyanmisaka         bit_diff_ratio = 52 * (pre_real_bits - pre_target_bits) / pre_target_bits;
653*437bfbebSnyanmisaka     else
654*437bfbebSnyanmisaka         bit_diff_ratio = 64 * (pre_real_bits - pre_target_bits) / pre_target_bits;
655*437bfbebSnyanmisaka 
656*437bfbebSnyanmisaka     idx1 = (ins_bps << 5) / target_bps;
657*437bfbebSnyanmisaka     idx2 = (pre_ins_bps << 5) / target_bps;
658*437bfbebSnyanmisaka 
659*437bfbebSnyanmisaka     idx1 = mpp_clip(idx1, 0, 63);
660*437bfbebSnyanmisaka     idx2 = mpp_clip(idx2, 0, 63);
661*437bfbebSnyanmisaka     ins_ratio = tab_lnx[idx1] - tab_lnx[idx2]; // %3
662*437bfbebSnyanmisaka 
663*437bfbebSnyanmisaka     /*ins_bps is increase and pre_ins > target_bps*15/16 will raise up ins_ratio to decrease bit
664*437bfbebSnyanmisaka      *ins_bps is decresase and pre_ins < target_bps*17/16 will decrease ins_ratio to increase bit
665*437bfbebSnyanmisaka      */
666*437bfbebSnyanmisaka 
667*437bfbebSnyanmisaka     if (ins_bps > pre_ins_bps && target_bps - pre_ins_bps < (target_bps >> 4)) { // %6
668*437bfbebSnyanmisaka         ins_ratio = 6 * ins_ratio;
669*437bfbebSnyanmisaka     } else if ( ins_bps < pre_ins_bps && pre_ins_bps - target_bps < (target_bps >> 4)) {
670*437bfbebSnyanmisaka         ins_ratio = 4 * ins_ratio;
671*437bfbebSnyanmisaka     } else {
672*437bfbebSnyanmisaka         ins_ratio = 0;
673*437bfbebSnyanmisaka     }
674*437bfbebSnyanmisaka 
675*437bfbebSnyanmisaka     bit_diff_ratio = mpp_clip(bit_diff_ratio, -128, 256);
676*437bfbebSnyanmisaka 
677*437bfbebSnyanmisaka     ins_ratio = mpp_clip(ins_ratio, -128, 256);
678*437bfbebSnyanmisaka 
679*437bfbebSnyanmisaka     bps_ratio = (ins_bps - target_bps) * fluc_l / (target_bps >> 4);
680*437bfbebSnyanmisaka     wl_ratio = 4 * (p->stat_watl - p->watl_base) * fluc_l / p->watl_base;
681*437bfbebSnyanmisaka     bps_ratio = mpp_clip(bps_ratio, -32, 32);
682*437bfbebSnyanmisaka     wl_ratio  = mpp_clip(wl_ratio, -16, 32);
683*437bfbebSnyanmisaka     p->next_ratio = bit_diff_ratio + ins_ratio + bps_ratio + wl_ratio;
684*437bfbebSnyanmisaka 
685*437bfbebSnyanmisaka     rc_dbg_qp("%10s|%10s|%10s|%10s|%10s|%10s", "diff_ratio", "ins_ratio", "bps_ratio",
686*437bfbebSnyanmisaka               "wl_ratio", "next_ratio", "cur_qp_s");
687*437bfbebSnyanmisaka     rc_dbg_qp("%10d %10d %10d %10d %10d|%10d", bit_diff_ratio, ins_ratio - bit_diff_ratio,
688*437bfbebSnyanmisaka               bps_ratio, wl_ratio, p->next_ratio, p->cur_scale_qp);
689*437bfbebSnyanmisaka 
690*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", p);
691*437bfbebSnyanmisaka     return MPP_OK;
692*437bfbebSnyanmisaka }
693*437bfbebSnyanmisaka 
reenc_calc_super_frm_ratio(void * ctx,EncRcTaskInfo * cfg)694*437bfbebSnyanmisaka MPP_RET reenc_calc_super_frm_ratio(void *ctx, EncRcTaskInfo *cfg)
695*437bfbebSnyanmisaka {
696*437bfbebSnyanmisaka     RcModelV2Ctx *p = (RcModelV2Ctx *)ctx;
697*437bfbebSnyanmisaka 
698*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", p);
699*437bfbebSnyanmisaka     p->next_ratio = 160 * (4 * (cfg->bit_real - p->cur_super_thd) / cfg->bit_target);
700*437bfbebSnyanmisaka     p->next_ratio = mpp_clip(p->next_ratio, 128, 640);
701*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", p);
702*437bfbebSnyanmisaka     return MPP_OK;
703*437bfbebSnyanmisaka }
704*437bfbebSnyanmisaka 
reenc_calc_cbr_ratio(void * ctx,EncRcTaskInfo * cfg)705*437bfbebSnyanmisaka MPP_RET reenc_calc_cbr_ratio(void *ctx, EncRcTaskInfo *cfg)
706*437bfbebSnyanmisaka {
707*437bfbebSnyanmisaka     RcModelV2Ctx *p = (RcModelV2Ctx *)ctx;
708*437bfbebSnyanmisaka     RcCfg *usr_cfg = &p->usr_cfg;
709*437bfbebSnyanmisaka     RK_S32 stat_time = usr_cfg->stats_time;
710*437bfbebSnyanmisaka     RK_S32 pre_ins_bps = mpp_data_sum_v2(p->stat_bits) / stat_time;
711*437bfbebSnyanmisaka     RK_S32 ins_bps = (pre_ins_bps * stat_time - mpp_data_get_pre_val_v2(p->stat_bits, -1) + cfg->bit_real) / stat_time;
712*437bfbebSnyanmisaka     RK_S32 real_bit = cfg->bit_real;
713*437bfbebSnyanmisaka     RK_S32 target_bit = cfg->bit_target;
714*437bfbebSnyanmisaka     RK_S32 target_bps = p->target_bps;
715*437bfbebSnyanmisaka     RK_S32 water_level = 0;
716*437bfbebSnyanmisaka     RK_S32 idx1, idx2;
717*437bfbebSnyanmisaka     RK_S32 bit_diff_ratio, ins_ratio, bps_ratio, wl_ratio;
718*437bfbebSnyanmisaka     RK_S32 mb_w = MPP_ALIGN(usr_cfg->width, 16) / 16;
719*437bfbebSnyanmisaka     RK_S32 mb_h = MPP_ALIGN(usr_cfg->height, 16) / 16;
720*437bfbebSnyanmisaka 
721*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", p);
722*437bfbebSnyanmisaka 
723*437bfbebSnyanmisaka     if (p->cur_super_thd <= cfg->bit_real &&
724*437bfbebSnyanmisaka         usr_cfg->super_cfg.rc_priority == MPP_ENC_RC_BY_FRM_SIZE_FIRST) {
725*437bfbebSnyanmisaka         return reenc_calc_super_frm_ratio(ctx, cfg);
726*437bfbebSnyanmisaka     }
727*437bfbebSnyanmisaka 
728*437bfbebSnyanmisaka     if (real_bit + p->stat_watl > p->watl_thrd)
729*437bfbebSnyanmisaka         water_level = p->watl_thrd - p->bit_per_frame;
730*437bfbebSnyanmisaka     else
731*437bfbebSnyanmisaka         water_level = real_bit + p->stat_watl - p->bit_per_frame;
732*437bfbebSnyanmisaka 
733*437bfbebSnyanmisaka     if (water_level < 0) {
734*437bfbebSnyanmisaka         water_level = 0;
735*437bfbebSnyanmisaka     }
736*437bfbebSnyanmisaka 
737*437bfbebSnyanmisaka     if (target_bit > real_bit)
738*437bfbebSnyanmisaka         bit_diff_ratio = 32 * (real_bit - target_bit) / real_bit;
739*437bfbebSnyanmisaka     else
740*437bfbebSnyanmisaka         bit_diff_ratio = 32 * (real_bit - target_bit) / target_bit;
741*437bfbebSnyanmisaka 
742*437bfbebSnyanmisaka     idx1 = ins_bps / (target_bps >> 5);
743*437bfbebSnyanmisaka     idx2 = pre_ins_bps / (target_bps >> 5);
744*437bfbebSnyanmisaka 
745*437bfbebSnyanmisaka     idx1 = mpp_clip(idx1, 0, 63);
746*437bfbebSnyanmisaka     idx2 = mpp_clip(idx2, 0, 63);
747*437bfbebSnyanmisaka     ins_ratio = tab_lnx[idx1] - tab_lnx[idx2];
748*437bfbebSnyanmisaka 
749*437bfbebSnyanmisaka     bps_ratio = 96 * (ins_bps - target_bps) / target_bps;
750*437bfbebSnyanmisaka     wl_ratio = 32 * (water_level - p->watl_base) /  p->watl_base;
751*437bfbebSnyanmisaka     if (pre_ins_bps < ins_bps && target_bps != pre_ins_bps) {
752*437bfbebSnyanmisaka         ins_ratio = 6 * ins_ratio;
753*437bfbebSnyanmisaka         ins_ratio = mpp_clip(ins_ratio, -192, 256);
754*437bfbebSnyanmisaka     } else {
755*437bfbebSnyanmisaka         if (cfg->frame_type == INTRA_FRAME) {
756*437bfbebSnyanmisaka             ins_ratio = 3 * ins_ratio;
757*437bfbebSnyanmisaka             ins_ratio = mpp_clip(ins_ratio, -192, 256);
758*437bfbebSnyanmisaka         } else {
759*437bfbebSnyanmisaka             ins_ratio = 0;
760*437bfbebSnyanmisaka         }
761*437bfbebSnyanmisaka     }
762*437bfbebSnyanmisaka 
763*437bfbebSnyanmisaka     bit_diff_ratio = mpp_clip(bit_diff_ratio, -128, 256);
764*437bfbebSnyanmisaka     bps_ratio = mpp_clip(bps_ratio, -32, 32);
765*437bfbebSnyanmisaka     wl_ratio  = mpp_clip(wl_ratio, -32, 32);
766*437bfbebSnyanmisaka     p->next_ratio = bit_diff_ratio + ins_ratio + bps_ratio + wl_ratio;
767*437bfbebSnyanmisaka     if (cfg->frame_type  == INTRA_FRAME && (cfg->madi > 0)) {
768*437bfbebSnyanmisaka         RK_U32 tar_bpp = target_bit / (mb_w * mb_h);
769*437bfbebSnyanmisaka         float lnb_t = log(tar_bpp);
770*437bfbebSnyanmisaka         float c = 6.7204, a = -0.1435, b = 0.0438;
771*437bfbebSnyanmisaka         float start_qp = (p->cur_scale_qp >> 6);
772*437bfbebSnyanmisaka         int qp_c = ((lnb_t - cfg->madi * b - c) / a + 14);
773*437bfbebSnyanmisaka         if (qp_c > start_qp)
774*437bfbebSnyanmisaka             p->next_ratio  = (qp_c << 6) - p->cur_scale_qp;
775*437bfbebSnyanmisaka     }
776*437bfbebSnyanmisaka     rc_dbg_rc("cbr target_bit %d real_bit %d reenc next ratio %d", target_bit, real_bit, p->next_ratio);
777*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", p);
778*437bfbebSnyanmisaka     return MPP_OK;
779*437bfbebSnyanmisaka }
780*437bfbebSnyanmisaka 
rc_hier_calc_dealt_qp(RcModelV2Ctx * p,EncRcTaskInfo * info)781*437bfbebSnyanmisaka void rc_hier_calc_dealt_qp(RcModelV2Ctx *p, EncRcTaskInfo *info)
782*437bfbebSnyanmisaka {
783*437bfbebSnyanmisaka     RcHierQPCfg *hier_qp_cfg = &p->usr_cfg.hier_qp_cfg;
784*437bfbebSnyanmisaka 
785*437bfbebSnyanmisaka     if (!hier_qp_cfg->hier_qp_en)
786*437bfbebSnyanmisaka         return;
787*437bfbebSnyanmisaka 
788*437bfbebSnyanmisaka     if (info->frame_type == INTRA_FRAME || info->frame_type == INTER_VI_FRAME) {
789*437bfbebSnyanmisaka         p->hier_frm_cnt[3] = 0;
790*437bfbebSnyanmisaka         p->hier_frm_cnt[2] = 0;
791*437bfbebSnyanmisaka         p->hier_frm_cnt[1] = 0;
792*437bfbebSnyanmisaka         p->hier_frm_cnt[0] = 0;
793*437bfbebSnyanmisaka         p->qp_layer_id = 0;
794*437bfbebSnyanmisaka     } else {
795*437bfbebSnyanmisaka         if (p->hier_frm_cnt[3] < hier_qp_cfg->hier_frame_num[3]) {
796*437bfbebSnyanmisaka             p->hier_frm_cnt[3]++;
797*437bfbebSnyanmisaka             p->qp_layer_id = 4;
798*437bfbebSnyanmisaka         } else if (p->hier_frm_cnt[2] < hier_qp_cfg->hier_frame_num[2]) {
799*437bfbebSnyanmisaka             p->hier_frm_cnt[2]++;
800*437bfbebSnyanmisaka             p->hier_frm_cnt[3] = 0;
801*437bfbebSnyanmisaka             p->qp_layer_id = 3;
802*437bfbebSnyanmisaka         } else if (p->hier_frm_cnt[1] < hier_qp_cfg->hier_frame_num[1]) {
803*437bfbebSnyanmisaka             p->hier_frm_cnt[1]++;
804*437bfbebSnyanmisaka             p->hier_frm_cnt[3] = 0;
805*437bfbebSnyanmisaka             p->hier_frm_cnt[2] = 0;
806*437bfbebSnyanmisaka             p->qp_layer_id = 2;
807*437bfbebSnyanmisaka         } else if (p->hier_frm_cnt[0] < hier_qp_cfg->hier_frame_num[0]) {
808*437bfbebSnyanmisaka             p->hier_frm_cnt[0]++;
809*437bfbebSnyanmisaka             p->hier_frm_cnt[3] = 0;
810*437bfbebSnyanmisaka             p->hier_frm_cnt[2] = 0;
811*437bfbebSnyanmisaka             p->hier_frm_cnt[1] = 0;
812*437bfbebSnyanmisaka             p->qp_layer_id = 1;
813*437bfbebSnyanmisaka         } else {
814*437bfbebSnyanmisaka             p->hier_frm_cnt[3] = 0;
815*437bfbebSnyanmisaka             p->hier_frm_cnt[2] = 0;
816*437bfbebSnyanmisaka             p->hier_frm_cnt[1] = 0;
817*437bfbebSnyanmisaka             p->hier_frm_cnt[0] = 0;
818*437bfbebSnyanmisaka             p->qp_layer_id = 0;
819*437bfbebSnyanmisaka         }
820*437bfbebSnyanmisaka     }
821*437bfbebSnyanmisaka 
822*437bfbebSnyanmisaka     return;
823*437bfbebSnyanmisaka }
824*437bfbebSnyanmisaka 
calc_vbr_ratio(void * ctx,EncRcTaskInfo * cfg)825*437bfbebSnyanmisaka MPP_RET calc_vbr_ratio(void *ctx, EncRcTaskInfo *cfg)
826*437bfbebSnyanmisaka {
827*437bfbebSnyanmisaka     RcModelV2Ctx *p = (RcModelV2Ctx *)ctx;
828*437bfbebSnyanmisaka     RcCfg *usr_cfg = &p->usr_cfg;
829*437bfbebSnyanmisaka     RK_S32 bps_change = p->target_bps;
830*437bfbebSnyanmisaka     RK_S32 max_bps_target = usr_cfg->bps_max;
831*437bfbebSnyanmisaka     RK_S32 ins_bps = p->ins_bps;
832*437bfbebSnyanmisaka     RK_S32 pre_target_bits = p->pre_target_bits;
833*437bfbebSnyanmisaka     RK_S32 pre_real_bits = p->pre_real_bits;
834*437bfbebSnyanmisaka     RK_S32 pre_ins_bps = p->last_inst_bps;
835*437bfbebSnyanmisaka 
836*437bfbebSnyanmisaka     RK_S32 idx1, idx2;
837*437bfbebSnyanmisaka     RK_S32 bit_diff_ratio, ins_ratio, bps_ratio;
838*437bfbebSnyanmisaka 
839*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", p);
840*437bfbebSnyanmisaka 
841*437bfbebSnyanmisaka     bits_model_alloc(p, cfg, p->gop_total_bits);
842*437bfbebSnyanmisaka     if (pre_target_bits > pre_real_bits)
843*437bfbebSnyanmisaka         bit_diff_ratio = 32 * (pre_real_bits - pre_target_bits) / pre_target_bits;
844*437bfbebSnyanmisaka     else
845*437bfbebSnyanmisaka         bit_diff_ratio = 64 * (pre_real_bits - pre_target_bits) / pre_target_bits;
846*437bfbebSnyanmisaka 
847*437bfbebSnyanmisaka     idx1 = ins_bps / (max_bps_target >> 5);
848*437bfbebSnyanmisaka     idx2 = pre_ins_bps / (max_bps_target >> 5);
849*437bfbebSnyanmisaka 
850*437bfbebSnyanmisaka     idx1 = mpp_clip(idx1, 0, 63);
851*437bfbebSnyanmisaka     idx2 = mpp_clip(idx2, 0, 63);
852*437bfbebSnyanmisaka     ins_ratio = tab_lnx[idx1] - tab_lnx[idx2];
853*437bfbebSnyanmisaka 
854*437bfbebSnyanmisaka     rc_dbg_bps("%10s|%10s|%10s|%10s|%10s|%10s", "r_bits", "t_bits", "ins_bps", "p_ins_bps",
855*437bfbebSnyanmisaka                "bps_ch", "max_bps");
856*437bfbebSnyanmisaka     rc_dbg_bps("%10d %10d %10d %10d %10d %10d", pre_real_bits, pre_target_bits, ins_bps,
857*437bfbebSnyanmisaka                pre_ins_bps, bps_change, max_bps_target);
858*437bfbebSnyanmisaka 
859*437bfbebSnyanmisaka 
860*437bfbebSnyanmisaka     if (ins_bps > bps_change && ins_bps > pre_ins_bps) {
861*437bfbebSnyanmisaka         ins_ratio = 6 * ins_ratio;
862*437bfbebSnyanmisaka     } else if (ins_bps <= pre_ins_bps && bps_change > pre_ins_bps) {
863*437bfbebSnyanmisaka         ins_ratio = 3 * ins_ratio;
864*437bfbebSnyanmisaka     } else {
865*437bfbebSnyanmisaka         ins_ratio = 0;
866*437bfbebSnyanmisaka     }
867*437bfbebSnyanmisaka 
868*437bfbebSnyanmisaka     bit_diff_ratio = mpp_clip(bit_diff_ratio, -128, 256);
869*437bfbebSnyanmisaka     ins_ratio = mpp_clip(ins_ratio, -128, 256);
870*437bfbebSnyanmisaka     bps_ratio = 3 * (ins_bps - bps_change) / (max_bps_target >> 4);
871*437bfbebSnyanmisaka     bps_ratio = mpp_clip(bps_ratio, -16, 32);
872*437bfbebSnyanmisaka     if (p->i_scale > 640) {
873*437bfbebSnyanmisaka         bit_diff_ratio = mpp_clip(bit_diff_ratio, -16, 32);
874*437bfbebSnyanmisaka         ins_ratio = mpp_clip(ins_ratio, -16, 32);
875*437bfbebSnyanmisaka     }
876*437bfbebSnyanmisaka 
877*437bfbebSnyanmisaka     p->next_ratio = bit_diff_ratio + ins_ratio + bps_ratio;
878*437bfbebSnyanmisaka 
879*437bfbebSnyanmisaka     rc_dbg_qp("%10s|%10s|%10s|%10s|%10s", "diff_ratio", "ins_ratio", "bps_ratio", "next_ratio", "cur_qp_s");
880*437bfbebSnyanmisaka     rc_dbg_qp("%10d %10d %10d %10d|%10d", bit_diff_ratio, ins_ratio, bps_ratio, p->next_ratio, p->cur_scale_qp);
881*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", p);
882*437bfbebSnyanmisaka     return MPP_OK;
883*437bfbebSnyanmisaka }
884*437bfbebSnyanmisaka 
reenc_calc_vbr_ratio(void * ctx,EncRcTaskInfo * cfg)885*437bfbebSnyanmisaka MPP_RET reenc_calc_vbr_ratio(void *ctx, EncRcTaskInfo *cfg)
886*437bfbebSnyanmisaka {
887*437bfbebSnyanmisaka 
888*437bfbebSnyanmisaka     RcModelV2Ctx *p = (RcModelV2Ctx *)ctx;
889*437bfbebSnyanmisaka     RcCfg *usr_cfg = &p->usr_cfg;
890*437bfbebSnyanmisaka     RK_S32 stat_time = usr_cfg->stats_time;
891*437bfbebSnyanmisaka     RK_S32 pre_ins_bps = mpp_data_sum_v2(p->stat_bits) / stat_time;
892*437bfbebSnyanmisaka     RK_S32 ins_bps = (pre_ins_bps * stat_time - mpp_data_get_pre_val_v2(p->stat_bits, -1) + cfg->bit_real) / stat_time;
893*437bfbebSnyanmisaka     RK_S32 bps_change = p->target_bps;
894*437bfbebSnyanmisaka     RK_S32 max_bps_target = usr_cfg->bps_max;
895*437bfbebSnyanmisaka 
896*437bfbebSnyanmisaka     RK_S32 real_bit = cfg->bit_real;
897*437bfbebSnyanmisaka     RK_S32 target_bit = cfg->bit_target;
898*437bfbebSnyanmisaka     RK_S32 idx1, idx2;
899*437bfbebSnyanmisaka     RK_S32 bit_diff_ratio, ins_ratio, bps_ratio;
900*437bfbebSnyanmisaka 
901*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", p);
902*437bfbebSnyanmisaka 
903*437bfbebSnyanmisaka     if (p->cur_super_thd <= cfg->bit_real &&
904*437bfbebSnyanmisaka         usr_cfg->super_cfg.rc_priority == MPP_ENC_RC_BY_FRM_SIZE_FIRST) {
905*437bfbebSnyanmisaka         return reenc_calc_super_frm_ratio(ctx, cfg);
906*437bfbebSnyanmisaka     }
907*437bfbebSnyanmisaka 
908*437bfbebSnyanmisaka     if (target_bit <= real_bit)
909*437bfbebSnyanmisaka         bit_diff_ratio = 32 * (real_bit - target_bit) / target_bit;
910*437bfbebSnyanmisaka     else
911*437bfbebSnyanmisaka         bit_diff_ratio = 32 * (real_bit - target_bit) / real_bit;
912*437bfbebSnyanmisaka 
913*437bfbebSnyanmisaka     idx1 = ins_bps / (max_bps_target >> 5);
914*437bfbebSnyanmisaka     idx2 = pre_ins_bps / (max_bps_target >> 5);
915*437bfbebSnyanmisaka     idx1 = mpp_clip(idx1, 0, 63);
916*437bfbebSnyanmisaka     idx2 = mpp_clip(idx2, 0, 63);
917*437bfbebSnyanmisaka     if (pre_ins_bps < ins_bps && bps_change < ins_bps) {
918*437bfbebSnyanmisaka         ins_ratio = 6 * (tab_lnx[idx1] - tab_lnx[idx2]);
919*437bfbebSnyanmisaka         ins_ratio = mpp_clip(ins_ratio, -192, 256);
920*437bfbebSnyanmisaka     } else {
921*437bfbebSnyanmisaka         ins_ratio = 0;
922*437bfbebSnyanmisaka     }
923*437bfbebSnyanmisaka 
924*437bfbebSnyanmisaka     bps_ratio = 96 * (ins_bps - bps_change) / bps_change;
925*437bfbebSnyanmisaka     bit_diff_ratio = mpp_clip(bit_diff_ratio, -128, 256);
926*437bfbebSnyanmisaka     bps_ratio = mpp_clip(bps_ratio, -32, 32);
927*437bfbebSnyanmisaka 
928*437bfbebSnyanmisaka     p->next_ratio = bit_diff_ratio + ins_ratio + bps_ratio;
929*437bfbebSnyanmisaka     rc_dbg_rc("vbr reenc next ratio %d", p->next_ratio);
930*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", p);
931*437bfbebSnyanmisaka     return MPP_OK;
932*437bfbebSnyanmisaka }
933*437bfbebSnyanmisaka 
moving_ratio_calc(RcModelV2Ctx * ctx)934*437bfbebSnyanmisaka RK_S32 moving_ratio_calc(RcModelV2Ctx *ctx)
935*437bfbebSnyanmisaka {
936*437bfbebSnyanmisaka     RK_S32 motion_sensitivity = ctx->motion_sensitivity;
937*437bfbebSnyanmisaka     RK_S32 scale = 0, i;
938*437bfbebSnyanmisaka     RK_S32 total_bit = 0, pbit_sum = 0;
939*437bfbebSnyanmisaka     RK_S32 madi_sum = 0, madp_sum = 0;
940*437bfbebSnyanmisaka     RK_S32 percent = 0;
941*437bfbebSnyanmisaka 
942*437bfbebSnyanmisaka     for (i = 0; i < 2; i++) {
943*437bfbebSnyanmisaka         RK_S32 pre_I_bit = mpp_data_get_pre_val_v2(ctx->pre_i_bit, i);
944*437bfbebSnyanmisaka         RK_S32 pre_mean_qp = mpp_data_get_pre_val_v2(ctx->pre_i_mean_qp, i);
945*437bfbebSnyanmisaka         if (pre_mean_qp == -1) {
946*437bfbebSnyanmisaka             scale = 32;
947*437bfbebSnyanmisaka         } else {
948*437bfbebSnyanmisaka             RK_S32 index = pre_mean_qp + 8 - ctx->pre_mean_qp;
949*437bfbebSnyanmisaka             if (index >= 0) {
950*437bfbebSnyanmisaka                 index = mpp_clip(index, 0 , 15);
951*437bfbebSnyanmisaka                 scale = mean_qp2scale[index];
952*437bfbebSnyanmisaka             } else {
953*437bfbebSnyanmisaka                 scale = 14;
954*437bfbebSnyanmisaka             }
955*437bfbebSnyanmisaka         }
956*437bfbebSnyanmisaka         total_bit += (scale * pre_I_bit >> 5);
957*437bfbebSnyanmisaka         rc_dbg_rc("pre_mean_qp = %d, ctx->pre_mean_qp %d", pre_mean_qp, ctx->pre_mean_qp);
958*437bfbebSnyanmisaka         rc_dbg_rc("scale = %d, pre_I_bit %d", scale, pre_I_bit);
959*437bfbebSnyanmisaka     }
960*437bfbebSnyanmisaka 
961*437bfbebSnyanmisaka     pbit_sum = mpp_data_sum_v2(ctx->pre_p_bit);
962*437bfbebSnyanmisaka     madi_sum = mpp_data_sum_v2(ctx->madi);
963*437bfbebSnyanmisaka     madp_sum = mpp_data_sum_v2(ctx->madp);
964*437bfbebSnyanmisaka     rc_dbg_rc("pbit_sum %d,madi_sum = %d, madp_sum = %d", pbit_sum, madi_sum, madp_sum);
965*437bfbebSnyanmisaka     if ( pbit_sum == 0 || total_bit == 0) {
966*437bfbebSnyanmisaka         percent = 255;
967*437bfbebSnyanmisaka     } else {
968*437bfbebSnyanmisaka         RK_S32 index = (total_bit << 6) / pbit_sum;
969*437bfbebSnyanmisaka         index = mpp_clip(index >> 4, 1, 99);
970*437bfbebSnyanmisaka         percent = (bit2percent[index] << 8) / 100;
971*437bfbebSnyanmisaka     }
972*437bfbebSnyanmisaka     rc_dbg_rc("means qp percent %d min_still_percent %d", percent, ctx->min_still_percent);
973*437bfbebSnyanmisaka     RK_S32 percent_a = (ctx->min_still_percent - 30) << 8;
974*437bfbebSnyanmisaka     RK_S32 percent_b = 100 - ctx->min_still_percent;
975*437bfbebSnyanmisaka 
976*437bfbebSnyanmisaka     percent = (percent_a + percent * percent_b) / 70;
977*437bfbebSnyanmisaka     rc_dbg_rc("percent_a = %d percent_b %d", percent_a, percent_b);
978*437bfbebSnyanmisaka     RK_S32 mv_percnt = (ctx->prev_md_prop * 100) >> 8;
979*437bfbebSnyanmisaka     RK_S32 mv_ratio = (percent_a + 7680 + mv_percnt * percent_b) / 100;
980*437bfbebSnyanmisaka     rc_dbg_rc("mv_ratio = %d", mv_ratio);
981*437bfbebSnyanmisaka     RK_S32 mad_ratio = 256;
982*437bfbebSnyanmisaka     if (madi_sum) {
983*437bfbebSnyanmisaka         mad_ratio = 20 * madp_sum / madi_sum;
984*437bfbebSnyanmisaka         mad_ratio = mpp_clip(mad_ratio, 5, 100);
985*437bfbebSnyanmisaka         rc_dbg_rc("mad_ratio = %d", mad_ratio);
986*437bfbebSnyanmisaka         mad_ratio = (mad_ratio << 8) / 100;
987*437bfbebSnyanmisaka     }
988*437bfbebSnyanmisaka     mad_ratio = (percent_a + 7680 + percent_b * mad_ratio) / 100;
989*437bfbebSnyanmisaka 
990*437bfbebSnyanmisaka     RK_S32 moving_ratio = (percent + 1 + (mv_ratio * motion_sensitivity + (100 - motion_sensitivity) * mad_ratio) / 100) >> 1;
991*437bfbebSnyanmisaka     rc_dbg_rc("moving_ratio = %d, motion_sensitivity = %d", moving_ratio, motion_sensitivity);
992*437bfbebSnyanmisaka     rc_dbg_rc("percent %d mad_ratio %d hr_ratio %d, moving_ratio %d", percent, mad_ratio, mv_ratio, moving_ratio);
993*437bfbebSnyanmisaka     return moving_ratio;
994*437bfbebSnyanmisaka }
995*437bfbebSnyanmisaka 
calc_avbr_ratio(void * ctx,EncRcTaskInfo * cfg)996*437bfbebSnyanmisaka MPP_RET calc_avbr_ratio(void *ctx, EncRcTaskInfo *cfg)
997*437bfbebSnyanmisaka {
998*437bfbebSnyanmisaka     RcModelV2Ctx *p = (RcModelV2Ctx *)ctx;
999*437bfbebSnyanmisaka     RcCfg *usr_cfg = &p->usr_cfg;
1000*437bfbebSnyanmisaka     RK_S32 bps_change = p->target_bps;
1001*437bfbebSnyanmisaka     RK_S32 max_bps_target = usr_cfg->bps_max;
1002*437bfbebSnyanmisaka     RK_S32 ins_bps = p->ins_bps;
1003*437bfbebSnyanmisaka     RK_S32 pre_target_bits = p->pre_target_bits;
1004*437bfbebSnyanmisaka     RK_S32 pre_real_bits = p->pre_real_bits;
1005*437bfbebSnyanmisaka     RK_S32 pre_ins_bps = p->last_inst_bps;
1006*437bfbebSnyanmisaka     RK_S32 idx1, idx2;
1007*437bfbebSnyanmisaka     RK_S32 bit_diff_ratio, ins_ratio, agop_dratio, rgop_dratio;
1008*437bfbebSnyanmisaka     RK_S32 moving_ratio = 0, moving_percent;
1009*437bfbebSnyanmisaka     RK_S32 gop_bits = 0, gop_kbits = 0;
1010*437bfbebSnyanmisaka     RK_S32 i_ratio, max_bps;
1011*437bfbebSnyanmisaka     RK_S32 qratio, final_qratio;
1012*437bfbebSnyanmisaka 
1013*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", p);
1014*437bfbebSnyanmisaka 
1015*437bfbebSnyanmisaka     moving_ratio = moving_ratio_calc(p);
1016*437bfbebSnyanmisaka     if (p->moving_ratio - 2 >= moving_ratio)
1017*437bfbebSnyanmisaka         moving_ratio = p->moving_ratio - 2;
1018*437bfbebSnyanmisaka 
1019*437bfbebSnyanmisaka     if (p->moving_ratio > moving_ratio && (p->max_still_qp << 6) <= p->scale_qp) {
1020*437bfbebSnyanmisaka         p->moving_ratio = mpp_clip(p->moving_ratio + 1, 1, 255);
1021*437bfbebSnyanmisaka     } else {
1022*437bfbebSnyanmisaka         p->moving_ratio = moving_ratio;
1023*437bfbebSnyanmisaka     }
1024*437bfbebSnyanmisaka     rc_dbg_rc("final moving_ratio = %d", moving_ratio);
1025*437bfbebSnyanmisaka 
1026*437bfbebSnyanmisaka     if (moving_ratio <= 0)
1027*437bfbebSnyanmisaka         moving_ratio = 1;
1028*437bfbebSnyanmisaka 
1029*437bfbebSnyanmisaka     gop_bits = moving_ratio * p->gop_total_bits >> 8;
1030*437bfbebSnyanmisaka     gop_kbits = gop_bits >> 10;
1031*437bfbebSnyanmisaka     if (gop_kbits < 1)
1032*437bfbebSnyanmisaka         gop_kbits = 1;
1033*437bfbebSnyanmisaka 
1034*437bfbebSnyanmisaka     bits_model_alloc(p, cfg, gop_bits);
1035*437bfbebSnyanmisaka     bps_change = moving_ratio * bps_change >> 8;
1036*437bfbebSnyanmisaka     if (moving_ratio < 0) {
1037*437bfbebSnyanmisaka         moving_ratio += 255;
1038*437bfbebSnyanmisaka     }
1039*437bfbebSnyanmisaka     moving_percent = 100 * moving_ratio >> 8;
1040*437bfbebSnyanmisaka 
1041*437bfbebSnyanmisaka     rc_dbg_bps("%10s|%10s|%10s|%10s|%10s", "m_ratio", "r_bits", "t_bits", "ins_bps", "p_ins_bps");
1042*437bfbebSnyanmisaka     rc_dbg_bps("%10d %10d %10d %10d %10d", p->moving_ratio, pre_real_bits, pre_target_bits, ins_bps, pre_ins_bps);
1043*437bfbebSnyanmisaka 
1044*437bfbebSnyanmisaka     if (pre_target_bits > pre_real_bits)
1045*437bfbebSnyanmisaka         bit_diff_ratio = 32 * (pre_real_bits - pre_target_bits) / pre_target_bits;
1046*437bfbebSnyanmisaka     else
1047*437bfbebSnyanmisaka         bit_diff_ratio = 64 * (pre_real_bits - pre_target_bits) / pre_target_bits * moving_percent;
1048*437bfbebSnyanmisaka 
1049*437bfbebSnyanmisaka     i_ratio = mpp_clip(p->pre_i_scale >> 4, 10, 200);
1050*437bfbebSnyanmisaka     idx1 = ins_bps / (max_bps_target >> 5);
1051*437bfbebSnyanmisaka     idx2 = pre_ins_bps / (max_bps_target >> 5);
1052*437bfbebSnyanmisaka     idx1 = mpp_clip(idx1, 0, 63);
1053*437bfbebSnyanmisaka     idx2 = mpp_clip(idx2, 0, 63);
1054*437bfbebSnyanmisaka     ins_ratio = tab_lnx[idx2] - tab_lnx[idx1];
1055*437bfbebSnyanmisaka     max_bps = bps_change;
1056*437bfbebSnyanmisaka 
1057*437bfbebSnyanmisaka     if (max_bps < pre_ins_bps) {
1058*437bfbebSnyanmisaka         max_bps = pre_ins_bps;
1059*437bfbebSnyanmisaka     }
1060*437bfbebSnyanmisaka 
1061*437bfbebSnyanmisaka     if (ins_bps >  max_bps) {
1062*437bfbebSnyanmisaka         ins_ratio = 6 * ins_ratio;
1063*437bfbebSnyanmisaka     } else  if (ins_bps < pre_ins_bps && bps_change > pre_ins_bps) {
1064*437bfbebSnyanmisaka         ins_ratio = 3 * ins_ratio;
1065*437bfbebSnyanmisaka     } else {
1066*437bfbebSnyanmisaka         ins_ratio = 0;
1067*437bfbebSnyanmisaka     }
1068*437bfbebSnyanmisaka 
1069*437bfbebSnyanmisaka     ins_ratio = mpp_clip(ins_ratio >> 2, -128, 256);
1070*437bfbebSnyanmisaka     bit_diff_ratio = mpp_clip(10 * bit_diff_ratio / i_ratio, -128, 256);
1071*437bfbebSnyanmisaka     rgop_dratio  = mpp_clip(24 * ((p->real_gbits - gop_bits) >> 10) / gop_kbits, -1, 1);
1072*437bfbebSnyanmisaka     agop_dratio  = mpp_clip(48 * ((p->avg_gbits - gop_bits) >> 10) / gop_kbits , -1, 1);
1073*437bfbebSnyanmisaka     if (p->pre_i_scale > 640) {
1074*437bfbebSnyanmisaka         bit_diff_ratio = mpp_clip(bit_diff_ratio, -16, 32);
1075*437bfbebSnyanmisaka         ins_ratio = mpp_clip(ins_ratio, -16, 32);
1076*437bfbebSnyanmisaka     }
1077*437bfbebSnyanmisaka     qratio = 0;
1078*437bfbebSnyanmisaka     final_qratio = ins_ratio + bit_diff_ratio + agop_dratio + rgop_dratio;
1079*437bfbebSnyanmisaka     if (max_bps_target >= ins_bps) {
1080*437bfbebSnyanmisaka         if (final_qratio > 0) {
1081*437bfbebSnyanmisaka             if (p->scale_qp >= (p->max_still_qp << 6)) {
1082*437bfbebSnyanmisaka                 final_qratio = ins_ratio + agop_dratio + rgop_dratio;
1083*437bfbebSnyanmisaka                 qratio = -6;
1084*437bfbebSnyanmisaka             }
1085*437bfbebSnyanmisaka         }
1086*437bfbebSnyanmisaka     }
1087*437bfbebSnyanmisaka     p->next_ratio = qratio + final_qratio;
1088*437bfbebSnyanmisaka 
1089*437bfbebSnyanmisaka     rc_dbg_qp("%10s|%10s|%10s|%10s|%10s|%10s|%10s", "diff_ratio", "ins_ratio", "rg_ratio",
1090*437bfbebSnyanmisaka               "ag_ratio", "qratio", "next_ratio", "cur_qp_s");
1091*437bfbebSnyanmisaka     rc_dbg_qp("%10d %10d %10d %10d %10d %10d %10d", bit_diff_ratio, ins_ratio, rgop_dratio,
1092*437bfbebSnyanmisaka               agop_dratio, qratio, p->next_ratio, p->cur_scale_qp);
1093*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", p);
1094*437bfbebSnyanmisaka     return MPP_OK;
1095*437bfbebSnyanmisaka }
1096*437bfbebSnyanmisaka 
bits_model_init(RcModelV2Ctx * ctx)1097*437bfbebSnyanmisaka MPP_RET bits_model_init(RcModelV2Ctx *ctx)
1098*437bfbebSnyanmisaka {
1099*437bfbebSnyanmisaka     RcCfg *usr_cfg = &ctx->usr_cfg;
1100*437bfbebSnyanmisaka     RK_S32 gop_len = ctx->usr_cfg.igop;
1101*437bfbebSnyanmisaka     RcFpsCfg *fps = &ctx->usr_cfg.fps;
1102*437bfbebSnyanmisaka     RK_S64 gop_bits = 0;
1103*437bfbebSnyanmisaka     RK_U32 target_bps = 0;
1104*437bfbebSnyanmisaka 
1105*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
1106*437bfbebSnyanmisaka 
1107*437bfbebSnyanmisaka     usr_cfg->min_i_bit_prop = mpp_clip(usr_cfg->min_i_bit_prop, 10, 100);
1108*437bfbebSnyanmisaka     usr_cfg->max_i_bit_prop = mpp_clip(usr_cfg->max_i_bit_prop,
1109*437bfbebSnyanmisaka                                        usr_cfg->min_i_bit_prop, 100);
1110*437bfbebSnyanmisaka     usr_cfg->init_ip_ratio  = mpp_clip(usr_cfg->init_ip_ratio, 160, 640);
1111*437bfbebSnyanmisaka 
1112*437bfbebSnyanmisaka     rc_dbg_rc("min_i_bit_prop %d max_i_bit_prop %d, init_ip_ratio %d",
1113*437bfbebSnyanmisaka               usr_cfg->min_i_bit_prop, usr_cfg->max_i_bit_prop, usr_cfg->init_ip_ratio);
1114*437bfbebSnyanmisaka 
1115*437bfbebSnyanmisaka     if (!gop_len) {
1116*437bfbebSnyanmisaka         rc_dbg_rc("infinte gop, set default for rc bit calc\n");
1117*437bfbebSnyanmisaka         usr_cfg->igop = gop_len = 500;
1118*437bfbebSnyanmisaka     } else if (gop_len == 1) {
1119*437bfbebSnyanmisaka         rc_dbg_rc("all intra gop \n");
1120*437bfbebSnyanmisaka         usr_cfg->init_ip_ratio  = 16;
1121*437bfbebSnyanmisaka 
1122*437bfbebSnyanmisaka         /* disable debreath on all intra case */
1123*437bfbebSnyanmisaka         if (usr_cfg->debreath_cfg.enable)
1124*437bfbebSnyanmisaka             usr_cfg->debreath_cfg.enable = 0;
1125*437bfbebSnyanmisaka 
1126*437bfbebSnyanmisaka         usr_cfg->igop = gop_len = 500;
1127*437bfbebSnyanmisaka     } else {
1128*437bfbebSnyanmisaka         usr_cfg->igop = gop_len = mpp_clip(usr_cfg->igop, usr_cfg->igop, 500);
1129*437bfbebSnyanmisaka     }
1130*437bfbebSnyanmisaka     ctx->max_still_qp = 35;
1131*437bfbebSnyanmisaka     ctx->motion_sensitivity = 90;
1132*437bfbebSnyanmisaka 
1133*437bfbebSnyanmisaka     ctx->first_frm_flg = 1;
1134*437bfbebSnyanmisaka     ctx->gop_frm_cnt = 0;
1135*437bfbebSnyanmisaka     ctx->gop_qp_sum = 0;
1136*437bfbebSnyanmisaka 
1137*437bfbebSnyanmisaka     if (!usr_cfg->fps_chg_prop) {
1138*437bfbebSnyanmisaka         usr_cfg->fps_chg_prop = 25;
1139*437bfbebSnyanmisaka     }
1140*437bfbebSnyanmisaka 
1141*437bfbebSnyanmisaka     target_bps = ctx->usr_cfg.bps_max;
1142*437bfbebSnyanmisaka     ctx->re_calc_ratio = reenc_calc_vbr_ratio;
1143*437bfbebSnyanmisaka     switch (ctx->usr_cfg.mode) {
1144*437bfbebSnyanmisaka     case RC_CBR: {
1145*437bfbebSnyanmisaka         ctx->calc_ratio = calc_cbr_ratio;
1146*437bfbebSnyanmisaka         ctx->re_calc_ratio = reenc_calc_cbr_ratio;
1147*437bfbebSnyanmisaka         target_bps = ctx->usr_cfg.bps_target;
1148*437bfbebSnyanmisaka     } break;
1149*437bfbebSnyanmisaka     case RC_VBR: {
1150*437bfbebSnyanmisaka         ctx->calc_ratio = calc_vbr_ratio;
1151*437bfbebSnyanmisaka     } break;
1152*437bfbebSnyanmisaka     case RC_FIXQP: {
1153*437bfbebSnyanmisaka         return MPP_OK;
1154*437bfbebSnyanmisaka     }
1155*437bfbebSnyanmisaka     case RC_AVBR: {
1156*437bfbebSnyanmisaka         ctx->calc_ratio = calc_avbr_ratio;
1157*437bfbebSnyanmisaka         if (usr_cfg->bps_min && usr_cfg->bps_max) {
1158*437bfbebSnyanmisaka             ctx->min_still_percent = (RK_S64)usr_cfg->bps_min * 100 / usr_cfg->bps_max;
1159*437bfbebSnyanmisaka         } else {
1160*437bfbebSnyanmisaka             ctx->min_still_percent = 25;
1161*437bfbebSnyanmisaka         }
1162*437bfbebSnyanmisaka         rc_dbg_rc("min_still_percent  %d", ctx->min_still_percent);
1163*437bfbebSnyanmisaka     } break;
1164*437bfbebSnyanmisaka     case RC_SMT: {
1165*437bfbebSnyanmisaka         mpp_log("rc mode is smart");
1166*437bfbebSnyanmisaka     } break;
1167*437bfbebSnyanmisaka     case RC_SE: {
1168*437bfbebSnyanmisaka         mpp_log("rc mode is super-encode");
1169*437bfbebSnyanmisaka     } break;
1170*437bfbebSnyanmisaka     default:
1171*437bfbebSnyanmisaka         mpp_log("rc mode set error");
1172*437bfbebSnyanmisaka         break;
1173*437bfbebSnyanmisaka     }
1174*437bfbebSnyanmisaka 
1175*437bfbebSnyanmisaka     ctx->target_bps = ctx->usr_cfg.bps_target;
1176*437bfbebSnyanmisaka 
1177*437bfbebSnyanmisaka     if (gop_len >= 1)
1178*437bfbebSnyanmisaka         gop_bits = (RK_S64)gop_len * target_bps * fps->fps_out_denom;
1179*437bfbebSnyanmisaka     else
1180*437bfbebSnyanmisaka         gop_bits = (RK_S64)fps->fps_out_num * target_bps * fps->fps_out_denom;
1181*437bfbebSnyanmisaka 
1182*437bfbebSnyanmisaka     ctx->gop_total_bits = gop_bits / fps->fps_out_num;
1183*437bfbebSnyanmisaka     ctx->bit_per_frame = target_bps * fps->fps_out_denom / fps->fps_out_num;
1184*437bfbebSnyanmisaka     ctx->watl_thrd = 3 * target_bps;
1185*437bfbebSnyanmisaka     ctx->stat_watl = ctx->watl_thrd  >> 3;
1186*437bfbebSnyanmisaka     ctx->watl_base = ctx->stat_watl;
1187*437bfbebSnyanmisaka     ctx->last_fps = fps->fps_out_num / fps->fps_out_denom;
1188*437bfbebSnyanmisaka 
1189*437bfbebSnyanmisaka     rc_dbg_rc("gop %d total bit %lld per_frame %d statistics time %d second\n",
1190*437bfbebSnyanmisaka               ctx->usr_cfg.igop, ctx->gop_total_bits, ctx->bit_per_frame,
1191*437bfbebSnyanmisaka               ctx->usr_cfg.stats_time);
1192*437bfbebSnyanmisaka 
1193*437bfbebSnyanmisaka     if (bits_model_param_init(ctx)) {
1194*437bfbebSnyanmisaka         return MPP_NOK;
1195*437bfbebSnyanmisaka     }
1196*437bfbebSnyanmisaka     ctx->time_base = mpp_time();
1197*437bfbebSnyanmisaka     bits_frm_init(ctx);
1198*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
1199*437bfbebSnyanmisaka     return MPP_OK;
1200*437bfbebSnyanmisaka }
1201*437bfbebSnyanmisaka 
update_mode_param(RcModelV2Ctx * ctx,RK_U32 fps)1202*437bfbebSnyanmisaka static MPP_RET update_mode_param(RcModelV2Ctx *ctx, RK_U32 fps)
1203*437bfbebSnyanmisaka {
1204*437bfbebSnyanmisaka     RcCfg *usr_cfg = &ctx->usr_cfg;
1205*437bfbebSnyanmisaka     RK_S32 gop_len = ctx->usr_cfg.igop;
1206*437bfbebSnyanmisaka     RK_S64 gop_bits = 0;
1207*437bfbebSnyanmisaka     RK_U32 target_bps;
1208*437bfbebSnyanmisaka     RK_U32  stat_len = fps * usr_cfg->stats_time;
1209*437bfbebSnyanmisaka 
1210*437bfbebSnyanmisaka     target_bps = ctx->usr_cfg.bps_max;
1211*437bfbebSnyanmisaka     if (ctx->usr_cfg.mode == RC_CBR) {
1212*437bfbebSnyanmisaka         target_bps = ctx->usr_cfg.bps_target;
1213*437bfbebSnyanmisaka     }
1214*437bfbebSnyanmisaka 
1215*437bfbebSnyanmisaka     if (gop_len >= 1)
1216*437bfbebSnyanmisaka         gop_bits = (RK_S64)gop_len * target_bps;
1217*437bfbebSnyanmisaka     else
1218*437bfbebSnyanmisaka         gop_bits = (RK_S64)target_bps;
1219*437bfbebSnyanmisaka 
1220*437bfbebSnyanmisaka     ctx->gop_total_bits = gop_bits / fps;
1221*437bfbebSnyanmisaka 
1222*437bfbebSnyanmisaka     ctx->bit_per_frame = target_bps / fps;
1223*437bfbebSnyanmisaka 
1224*437bfbebSnyanmisaka     if (ctx->stat_bits != NULL) {
1225*437bfbebSnyanmisaka         mpp_data_deinit_v2(ctx->stat_bits);
1226*437bfbebSnyanmisaka         ctx->stat_bits = NULL;
1227*437bfbebSnyanmisaka     }
1228*437bfbebSnyanmisaka     mpp_data_init_v2(&ctx->stat_bits, stat_len , ctx->bit_per_frame);
1229*437bfbebSnyanmisaka     if (ctx->stat_bits == NULL) {
1230*437bfbebSnyanmisaka         mpp_err("stat_bits init fail stat_len %d", stat_len);
1231*437bfbebSnyanmisaka         return MPP_ERR_MALLOC;
1232*437bfbebSnyanmisaka     }
1233*437bfbebSnyanmisaka     return MPP_OK;
1234*437bfbebSnyanmisaka }
1235*437bfbebSnyanmisaka 
fps_chg_update_mode(RcModelV2Ctx * ctx)1236*437bfbebSnyanmisaka static MPP_RET fps_chg_update_mode(RcModelV2Ctx *ctx)
1237*437bfbebSnyanmisaka {
1238*437bfbebSnyanmisaka     ctx->time_end = mpp_time();
1239*437bfbebSnyanmisaka     ctx->frm_cnt++;
1240*437bfbebSnyanmisaka 
1241*437bfbebSnyanmisaka     if (ctx->time_base && ctx->time_end &&
1242*437bfbebSnyanmisaka         ((ctx->time_end - ctx->time_base) >= (RK_S64)(250 * 1000))) {
1243*437bfbebSnyanmisaka 
1244*437bfbebSnyanmisaka         RK_S32 time_diff = ((RK_S32)(ctx->time_end - ctx->time_base) / 1000);
1245*437bfbebSnyanmisaka         RK_U32 fps = ctx->frm_cnt * 1000 / time_diff;
1246*437bfbebSnyanmisaka 
1247*437bfbebSnyanmisaka         if (ctx->last_fps > 0 && fps &&
1248*437bfbebSnyanmisaka             abs(ctx->last_fps - (RK_S32)fps) * 100 / ctx->last_fps > (RK_S32)ctx->usr_cfg.fps_chg_prop) {
1249*437bfbebSnyanmisaka             update_mode_param(ctx, fps);
1250*437bfbebSnyanmisaka             mpp_log("fps chg from %d -> %d", ctx->last_fps, fps);
1251*437bfbebSnyanmisaka             ctx->last_fps = fps;
1252*437bfbebSnyanmisaka         }
1253*437bfbebSnyanmisaka         ctx->time_base = ctx->time_end;
1254*437bfbebSnyanmisaka         ctx->frm_cnt = 0;
1255*437bfbebSnyanmisaka     }
1256*437bfbebSnyanmisaka 
1257*437bfbebSnyanmisaka     return MPP_OK;
1258*437bfbebSnyanmisaka }
1259*437bfbebSnyanmisaka 
bits_mode_reset(RcModelV2Ctx * ctx)1260*437bfbebSnyanmisaka MPP_RET bits_mode_reset(RcModelV2Ctx *ctx)
1261*437bfbebSnyanmisaka {
1262*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
1263*437bfbebSnyanmisaka     (void) ctx;
1264*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
1265*437bfbebSnyanmisaka     return MPP_OK;
1266*437bfbebSnyanmisaka }
1267*437bfbebSnyanmisaka 
check_super_frame(RcModelV2Ctx * ctx,EncRcTaskInfo * cfg)1268*437bfbebSnyanmisaka MPP_RET check_super_frame(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg)
1269*437bfbebSnyanmisaka {
1270*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
1271*437bfbebSnyanmisaka     RK_S32 frame_type = cfg->frame_type;
1272*437bfbebSnyanmisaka     RK_U32 bits_thr = 0;
1273*437bfbebSnyanmisaka     RcCfg *usr_cfg = &ctx->usr_cfg;
1274*437bfbebSnyanmisaka 
1275*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
1276*437bfbebSnyanmisaka     if (usr_cfg->super_cfg.super_mode) {
1277*437bfbebSnyanmisaka         bits_thr = usr_cfg->super_cfg.super_p_thd;
1278*437bfbebSnyanmisaka         if (frame_type == INTRA_FRAME) {
1279*437bfbebSnyanmisaka             bits_thr = usr_cfg->super_cfg.super_i_thd;
1280*437bfbebSnyanmisaka         }
1281*437bfbebSnyanmisaka 
1282*437bfbebSnyanmisaka         if ((RK_U32)cfg->bit_real >= bits_thr) {
1283*437bfbebSnyanmisaka             if (usr_cfg->super_cfg.super_mode == MPP_ENC_RC_SUPER_FRM_DROP) {
1284*437bfbebSnyanmisaka                 rc_dbg_rc("super frame drop current frame");
1285*437bfbebSnyanmisaka                 usr_cfg->drop_mode = MPP_ENC_RC_DROP_FRM_NORMAL;
1286*437bfbebSnyanmisaka                 usr_cfg->drop_gap  = 0;
1287*437bfbebSnyanmisaka             }
1288*437bfbebSnyanmisaka             ret = MPP_NOK;
1289*437bfbebSnyanmisaka         }
1290*437bfbebSnyanmisaka     }
1291*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
1292*437bfbebSnyanmisaka     return ret;
1293*437bfbebSnyanmisaka }
1294*437bfbebSnyanmisaka 
check_re_enc(RcModelV2Ctx * ctx,EncRcTaskInfo * cfg)1295*437bfbebSnyanmisaka MPP_RET check_re_enc(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg)
1296*437bfbebSnyanmisaka {
1297*437bfbebSnyanmisaka     RcCfg *usr_cfg = &ctx->usr_cfg;
1298*437bfbebSnyanmisaka     RK_S32 frame_type = cfg->frame_type;
1299*437bfbebSnyanmisaka     RK_S32 bit_thr = 0;
1300*437bfbebSnyanmisaka     RK_S32 stat_time = usr_cfg->stats_time;
1301*437bfbebSnyanmisaka     RK_S32 last_ins_bps = mpp_data_sum_v2(ctx->stat_bits) / stat_time;
1302*437bfbebSnyanmisaka     RK_S32 ins_bps = (last_ins_bps * stat_time - mpp_data_get_pre_val_v2(ctx->stat_bits, -1)
1303*437bfbebSnyanmisaka                       + cfg->bit_real) / stat_time;
1304*437bfbebSnyanmisaka     RK_S32 target_bps;
1305*437bfbebSnyanmisaka     RK_S32 ret = MPP_OK;
1306*437bfbebSnyanmisaka 
1307*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
1308*437bfbebSnyanmisaka     rc_dbg_rc("reenc check target_bps %d last_ins_bps %d ins_bps %d",
1309*437bfbebSnyanmisaka               usr_cfg->bps_target, last_ins_bps, ins_bps);
1310*437bfbebSnyanmisaka 
1311*437bfbebSnyanmisaka     if (ctx->reenc_cnt >= usr_cfg->max_reencode_times)
1312*437bfbebSnyanmisaka         return MPP_OK;
1313*437bfbebSnyanmisaka 
1314*437bfbebSnyanmisaka     if (check_super_frame(ctx, cfg))
1315*437bfbebSnyanmisaka         return MPP_NOK;
1316*437bfbebSnyanmisaka 
1317*437bfbebSnyanmisaka     if (usr_cfg->debreath_cfg.enable && !ctx->first_frm_flg)
1318*437bfbebSnyanmisaka         return MPP_OK;
1319*437bfbebSnyanmisaka 
1320*437bfbebSnyanmisaka     rc_dbg_drop("drop mode %d frame_type %d\n", usr_cfg->drop_mode, frame_type);
1321*437bfbebSnyanmisaka     if (usr_cfg->drop_mode && frame_type == INTER_P_FRAME) {
1322*437bfbebSnyanmisaka         bit_thr = (RK_S32)(usr_cfg->bps_max * (100 + usr_cfg->drop_thd) / (float)100);
1323*437bfbebSnyanmisaka         rc_dbg_drop("drop mode %d check max_bps %d bit_thr %d ins_bps %d",
1324*437bfbebSnyanmisaka                     usr_cfg->drop_mode, usr_cfg->bps_target, bit_thr, ins_bps);
1325*437bfbebSnyanmisaka         return (ins_bps > bit_thr) ? MPP_NOK : MPP_OK;
1326*437bfbebSnyanmisaka     }
1327*437bfbebSnyanmisaka 
1328*437bfbebSnyanmisaka     switch (frame_type) {
1329*437bfbebSnyanmisaka     case INTRA_FRAME:
1330*437bfbebSnyanmisaka         bit_thr = 3 * cfg->bit_target / 2;
1331*437bfbebSnyanmisaka         break;
1332*437bfbebSnyanmisaka     case INTER_P_FRAME:
1333*437bfbebSnyanmisaka         bit_thr = 3 * cfg->bit_target;
1334*437bfbebSnyanmisaka         break;
1335*437bfbebSnyanmisaka     default:
1336*437bfbebSnyanmisaka         break;
1337*437bfbebSnyanmisaka     }
1338*437bfbebSnyanmisaka 
1339*437bfbebSnyanmisaka     if (cfg->bit_real > bit_thr) {
1340*437bfbebSnyanmisaka         if (usr_cfg->mode == RC_CBR) {
1341*437bfbebSnyanmisaka             target_bps = usr_cfg->bps_target;
1342*437bfbebSnyanmisaka             if (target_bps / 20 < ins_bps - last_ins_bps &&
1343*437bfbebSnyanmisaka                 (target_bps + target_bps / 10 < ins_bps
1344*437bfbebSnyanmisaka                  || target_bps - target_bps / 10 > ins_bps)) {
1345*437bfbebSnyanmisaka                 ret =  MPP_NOK;
1346*437bfbebSnyanmisaka             }
1347*437bfbebSnyanmisaka         } else {
1348*437bfbebSnyanmisaka             target_bps = usr_cfg->bps_max;
1349*437bfbebSnyanmisaka             if ((target_bps - (target_bps >> 3) < ins_bps) &&
1350*437bfbebSnyanmisaka                 (target_bps / 20  < ins_bps - last_ins_bps)) {
1351*437bfbebSnyanmisaka                 ret =  MPP_NOK;
1352*437bfbebSnyanmisaka             }
1353*437bfbebSnyanmisaka         }
1354*437bfbebSnyanmisaka     }
1355*437bfbebSnyanmisaka 
1356*437bfbebSnyanmisaka     rc_dbg_func("leave %p ret %d\n", ctx, ret);
1357*437bfbebSnyanmisaka     return ret;
1358*437bfbebSnyanmisaka }
1359*437bfbebSnyanmisaka 
1360*437bfbebSnyanmisaka 
rc_model_v2_init(void * ctx,RcCfg * cfg)1361*437bfbebSnyanmisaka MPP_RET rc_model_v2_init(void *ctx, RcCfg *cfg)
1362*437bfbebSnyanmisaka {
1363*437bfbebSnyanmisaka     RcModelV2Ctx *p = (RcModelV2Ctx*)ctx;
1364*437bfbebSnyanmisaka 
1365*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
1366*437bfbebSnyanmisaka 
1367*437bfbebSnyanmisaka     memcpy(&p->usr_cfg, cfg, sizeof(RcCfg));
1368*437bfbebSnyanmisaka     rc_dbg_rc("init rc param: fqp %d:%d:%d:%d\n", cfg->fqp_min_i, cfg->fqp_max_i,
1369*437bfbebSnyanmisaka               cfg->fqp_min_p, cfg->fqp_max_p);
1370*437bfbebSnyanmisaka 
1371*437bfbebSnyanmisaka     bits_model_init(p);
1372*437bfbebSnyanmisaka 
1373*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
1374*437bfbebSnyanmisaka     return MPP_OK;
1375*437bfbebSnyanmisaka }
1376*437bfbebSnyanmisaka 
rc_model_v2_deinit(void * ctx)1377*437bfbebSnyanmisaka MPP_RET rc_model_v2_deinit(void *ctx)
1378*437bfbebSnyanmisaka {
1379*437bfbebSnyanmisaka     RcModelV2Ctx *p = (RcModelV2Ctx *)ctx;
1380*437bfbebSnyanmisaka 
1381*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
1382*437bfbebSnyanmisaka     bits_model_param_deinit(p);
1383*437bfbebSnyanmisaka 
1384*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
1385*437bfbebSnyanmisaka     return MPP_OK;
1386*437bfbebSnyanmisaka }
1387*437bfbebSnyanmisaka 
rc_model_v2_start(void * ctx,EncRcTask * task)1388*437bfbebSnyanmisaka MPP_RET rc_model_v2_start(void *ctx, EncRcTask *task)
1389*437bfbebSnyanmisaka {
1390*437bfbebSnyanmisaka     RcModelV2Ctx *p = (RcModelV2Ctx*)ctx;
1391*437bfbebSnyanmisaka     EncFrmStatus *frm = &task->frm;
1392*437bfbebSnyanmisaka     EncRcTaskInfo *info = &task->info;
1393*437bfbebSnyanmisaka     RcCfg *usr_cfg = &p->usr_cfg;
1394*437bfbebSnyanmisaka 
1395*437bfbebSnyanmisaka     rc_dbg_func("enter %p\n", ctx);
1396*437bfbebSnyanmisaka 
1397*437bfbebSnyanmisaka     if (usr_cfg->mode == RC_FIXQP) {
1398*437bfbebSnyanmisaka         if (usr_cfg->init_quality <= 0) {
1399*437bfbebSnyanmisaka             mpp_log("invalid fix %d qp found set default qp 26\n",
1400*437bfbebSnyanmisaka                     usr_cfg->init_quality);
1401*437bfbebSnyanmisaka             usr_cfg->init_quality = 26;
1402*437bfbebSnyanmisaka         }
1403*437bfbebSnyanmisaka 
1404*437bfbebSnyanmisaka         if (usr_cfg->max_quality <= 0)
1405*437bfbebSnyanmisaka             usr_cfg->max_quality = usr_cfg->init_quality;
1406*437bfbebSnyanmisaka         if (usr_cfg->min_quality <= 0)
1407*437bfbebSnyanmisaka             usr_cfg->min_quality = usr_cfg->init_quality;
1408*437bfbebSnyanmisaka         if (usr_cfg->max_i_quality <= 0)
1409*437bfbebSnyanmisaka             usr_cfg->max_i_quality = usr_cfg->max_quality;
1410*437bfbebSnyanmisaka         if (usr_cfg->min_i_quality <= 0)
1411*437bfbebSnyanmisaka             usr_cfg->min_i_quality = usr_cfg->min_quality;
1412*437bfbebSnyanmisaka 
1413*437bfbebSnyanmisaka         if (frm->is_intra) {
1414*437bfbebSnyanmisaka             info->quality_max = usr_cfg->max_i_quality;
1415*437bfbebSnyanmisaka             info->quality_min = usr_cfg->min_i_quality;
1416*437bfbebSnyanmisaka             info->quality_target = usr_cfg->init_quality;
1417*437bfbebSnyanmisaka         } else {
1418*437bfbebSnyanmisaka             info->quality_max = usr_cfg->max_quality;
1419*437bfbebSnyanmisaka             info->quality_min = usr_cfg->min_quality;
1420*437bfbebSnyanmisaka             info->quality_target = usr_cfg->init_quality;
1421*437bfbebSnyanmisaka         }
1422*437bfbebSnyanmisaka 
1423*437bfbebSnyanmisaka         rc_dbg_rc("seq_idx %d intra %d\n", frm->seq_idx, frm->is_intra);
1424*437bfbebSnyanmisaka         rc_dbg_rc("bitrate [%d : %d : %d]\n", info->bit_min, info->bit_target, info->bit_max);
1425*437bfbebSnyanmisaka         rc_dbg_rc("quality [%d : %d : %d]\n", info->quality_min, info->quality_target, info->quality_max);
1426*437bfbebSnyanmisaka 
1427*437bfbebSnyanmisaka         return MPP_OK;
1428*437bfbebSnyanmisaka     }
1429*437bfbebSnyanmisaka 
1430*437bfbebSnyanmisaka     if (usr_cfg->fps.fps_out_flex) {
1431*437bfbebSnyanmisaka         fps_chg_update_mode(ctx);
1432*437bfbebSnyanmisaka     }
1433*437bfbebSnyanmisaka 
1434*437bfbebSnyanmisaka     info->frame_type = (frm->is_intra) ? (INTRA_FRAME) : (INTER_P_FRAME);
1435*437bfbebSnyanmisaka 
1436*437bfbebSnyanmisaka     if (frm->ref_mode == REF_TO_PREV_INTRA)
1437*437bfbebSnyanmisaka         info->frame_type = INTER_VI_FRAME;
1438*437bfbebSnyanmisaka 
1439*437bfbebSnyanmisaka     if (frm->is_i_refresh)
1440*437bfbebSnyanmisaka         info->frame_type = INTRA_RFH_FRAME;
1441*437bfbebSnyanmisaka 
1442*437bfbebSnyanmisaka     p->next_ratio = 0;
1443*437bfbebSnyanmisaka     if (p->last_frame_type == INTRA_FRAME) {
1444*437bfbebSnyanmisaka         calc_next_i_ratio(p);
1445*437bfbebSnyanmisaka     }
1446*437bfbebSnyanmisaka 
1447*437bfbebSnyanmisaka     if (!p->first_frm_flg) {
1448*437bfbebSnyanmisaka         if (p->calc_ratio)
1449*437bfbebSnyanmisaka             p->calc_ratio(p, info);
1450*437bfbebSnyanmisaka     } else {
1451*437bfbebSnyanmisaka         bits_model_alloc(p, info, p->gop_total_bits);
1452*437bfbebSnyanmisaka         /* quality determination */
1453*437bfbebSnyanmisaka         info->quality_target = (usr_cfg->init_quality <= 0) ? -1 : usr_cfg->init_quality;
1454*437bfbebSnyanmisaka     }
1455*437bfbebSnyanmisaka 
1456*437bfbebSnyanmisaka     if (frm->is_intra) {
1457*437bfbebSnyanmisaka         info->quality_max = usr_cfg->max_i_quality;
1458*437bfbebSnyanmisaka         info->quality_min = usr_cfg->min_i_quality;
1459*437bfbebSnyanmisaka     } else {
1460*437bfbebSnyanmisaka         info->quality_max = usr_cfg->max_quality;
1461*437bfbebSnyanmisaka         info->quality_min = usr_cfg->min_quality;
1462*437bfbebSnyanmisaka     }
1463*437bfbebSnyanmisaka 
1464*437bfbebSnyanmisaka     bits_model_preset(p, info);
1465*437bfbebSnyanmisaka 
1466*437bfbebSnyanmisaka     rc_dbg_rc("seq_idx %d intra %d\n", frm->seq_idx, frm->is_intra);
1467*437bfbebSnyanmisaka     rc_dbg_rc("bitrate [%d : %d : %d]\n", info->bit_min, info->bit_target, info->bit_max);
1468*437bfbebSnyanmisaka     rc_dbg_rc("quality [%d : %d : %d]\n", info->quality_min, info->quality_target, info->quality_max);
1469*437bfbebSnyanmisaka 
1470*437bfbebSnyanmisaka     p->reenc_cnt = 0;
1471*437bfbebSnyanmisaka     p->last_frame_type = info->frame_type;
1472*437bfbebSnyanmisaka 
1473*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
1474*437bfbebSnyanmisaka 
1475*437bfbebSnyanmisaka     return MPP_OK;
1476*437bfbebSnyanmisaka }
1477*437bfbebSnyanmisaka 
cal_first_i_start_qp(RK_S32 target_bit,RK_U32 total_mb)1478*437bfbebSnyanmisaka static RK_S32 cal_first_i_start_qp(RK_S32 target_bit, RK_U32 total_mb)
1479*437bfbebSnyanmisaka {
1480*437bfbebSnyanmisaka     static RK_U32 mb_num[9] = {
1481*437bfbebSnyanmisaka         0,     200,   700,   1200,
1482*437bfbebSnyanmisaka         2000,  4000,  8000,  16000,
1483*437bfbebSnyanmisaka         20000
1484*437bfbebSnyanmisaka     };
1485*437bfbebSnyanmisaka 
1486*437bfbebSnyanmisaka     static RK_U32 tab_bit[9] = {
1487*437bfbebSnyanmisaka         3780,  3570,  3150,  2940,
1488*437bfbebSnyanmisaka         2730,  3780,  2100,  1680,
1489*437bfbebSnyanmisaka         2100
1490*437bfbebSnyanmisaka     };
1491*437bfbebSnyanmisaka 
1492*437bfbebSnyanmisaka     static RK_U8 qscale2qp[96] = {
1493*437bfbebSnyanmisaka         15,  15,  15,  15,  15,  16,  18,  20,  21,  22,  23,  24,
1494*437bfbebSnyanmisaka         25,  25,  26,  27,  28,  28,  29,  29,  30,  30,  30,  31,
1495*437bfbebSnyanmisaka         31,  32,  32,  33,  33,  33,  34,  34,  34,  34,  35,  35,
1496*437bfbebSnyanmisaka         35,  36,  36,  36,  36,  36,  37,  37,  37,  37,  38,  38,
1497*437bfbebSnyanmisaka         38,  38,  38,  39,  39,  39,  39,  39,  39,  40,  40,  40,
1498*437bfbebSnyanmisaka         40,  41,  41,  41,  41,  41,  41,  41,  42,  42,  42,  42,
1499*437bfbebSnyanmisaka         42,  42,  42,  42,  43,  43,  43,  43,  43,  43,  43,  43,
1500*437bfbebSnyanmisaka         44,  44,  44,  44,  44,  44,  44,  44,  45,  45,  45,  45,
1501*437bfbebSnyanmisaka     };
1502*437bfbebSnyanmisaka 
1503*437bfbebSnyanmisaka     RK_S32 cnt = 0;
1504*437bfbebSnyanmisaka     RK_S32 index;
1505*437bfbebSnyanmisaka     RK_S32 i;
1506*437bfbebSnyanmisaka 
1507*437bfbebSnyanmisaka     for (i = 0; i < 8; i++) {
1508*437bfbebSnyanmisaka         if (mb_num[i] > total_mb)
1509*437bfbebSnyanmisaka             break;
1510*437bfbebSnyanmisaka         cnt++;
1511*437bfbebSnyanmisaka     }
1512*437bfbebSnyanmisaka 
1513*437bfbebSnyanmisaka     index = (total_mb * tab_bit[cnt] - 350) / target_bit; // qscale
1514*437bfbebSnyanmisaka     index = mpp_clip(index, 4, 95);
1515*437bfbebSnyanmisaka 
1516*437bfbebSnyanmisaka     return qscale2qp[index];
1517*437bfbebSnyanmisaka }
1518*437bfbebSnyanmisaka 
derive_min_qp_from_complexity(RcModelV2Ctx * ctx,EncRcTaskInfo * info,RK_U32 is_intra)1519*437bfbebSnyanmisaka static RK_S32 derive_min_qp_from_complexity(RcModelV2Ctx *ctx, EncRcTaskInfo *info, RK_U32 is_intra)
1520*437bfbebSnyanmisaka {
1521*437bfbebSnyanmisaka     RcCfg *usr_cfg = &ctx->usr_cfg;
1522*437bfbebSnyanmisaka     RcMode rc_mode = usr_cfg->mode;
1523*437bfbebSnyanmisaka     RK_S32 qp_min = info->quality_min;
1524*437bfbebSnyanmisaka     RK_S32 fqp_min_i = usr_cfg->fqp_min_i;
1525*437bfbebSnyanmisaka     RK_S32 fqp_min_p = usr_cfg->fqp_min_p;
1526*437bfbebSnyanmisaka     RK_S32 cplx = mpp_data_sum_v2(ctx->complex_level);
1527*437bfbebSnyanmisaka     RK_S32 md = mpp_data_sum_v2(ctx->motion_level);
1528*437bfbebSnyanmisaka     RK_S32 md3 = mpp_data_get_pre_val_v2(ctx->motion_level, 0) +
1529*437bfbebSnyanmisaka                  mpp_data_get_pre_val_v2(ctx->motion_level, 1) +
1530*437bfbebSnyanmisaka                  mpp_data_get_pre_val_v2(ctx->motion_level, 2);
1531*437bfbebSnyanmisaka 
1532*437bfbebSnyanmisaka     if (RC_AVBR == rc_mode || RC_VBR == rc_mode || RC_CBR == rc_mode) {
1533*437bfbebSnyanmisaka         if (md >= 700) {
1534*437bfbebSnyanmisaka             qp_min = is_intra ? fqp_min_i : fqp_min_p;
1535*437bfbebSnyanmisaka             if (md >= 1400)
1536*437bfbebSnyanmisaka                 qp_min += md3 > 300 ? 3 : 2;
1537*437bfbebSnyanmisaka             else
1538*437bfbebSnyanmisaka                 qp_min += md3 > 300 ? 2 : 1;
1539*437bfbebSnyanmisaka 
1540*437bfbebSnyanmisaka             if (cplx >= 15)
1541*437bfbebSnyanmisaka                 qp_min++;
1542*437bfbebSnyanmisaka         } else if (RC_CBR != rc_mode) {
1543*437bfbebSnyanmisaka             if (md > 100) {
1544*437bfbebSnyanmisaka                 if (cplx >= 16)
1545*437bfbebSnyanmisaka                     qp_min = (is_intra ? fqp_min_i : fqp_min_p) + 1;
1546*437bfbebSnyanmisaka                 else if (cplx >= 10)
1547*437bfbebSnyanmisaka                     qp_min = (is_intra ? fqp_min_i : fqp_min_p) + 0;
1548*437bfbebSnyanmisaka             } else {
1549*437bfbebSnyanmisaka                 qp_min = (is_intra ? fqp_min_i : fqp_min_p);
1550*437bfbebSnyanmisaka                 qp_min += (cplx >= 15) ? 3 : (cplx >= 10) ? 2 : (cplx >= 5) ? 1 : 0;
1551*437bfbebSnyanmisaka             }
1552*437bfbebSnyanmisaka         }
1553*437bfbebSnyanmisaka 
1554*437bfbebSnyanmisaka         qp_min = mpp_clip(qp_min, info->quality_min, info->quality_max);
1555*437bfbebSnyanmisaka 
1556*437bfbebSnyanmisaka         rc_dbg_rc("frame %d complex_level %d motion_level %d md3 %d qp_min %d\n",
1557*437bfbebSnyanmisaka                   ctx->frm_num, cplx, md, md3, qp_min);
1558*437bfbebSnyanmisaka     }
1559*437bfbebSnyanmisaka 
1560*437bfbebSnyanmisaka     return qp_min;
1561*437bfbebSnyanmisaka }
1562*437bfbebSnyanmisaka 
rc_model_v2_hal_start(void * ctx,EncRcTask * task)1563*437bfbebSnyanmisaka MPP_RET rc_model_v2_hal_start(void *ctx, EncRcTask *task)
1564*437bfbebSnyanmisaka {
1565*437bfbebSnyanmisaka     RcModelV2Ctx *p = (RcModelV2Ctx *)ctx;
1566*437bfbebSnyanmisaka     EncFrmStatus *frm = &task->frm;
1567*437bfbebSnyanmisaka     EncRcTaskInfo *info = &task->info;
1568*437bfbebSnyanmisaka     EncRcForceCfg *force = &task->force;
1569*437bfbebSnyanmisaka     RcCfg *usr_cfg = &p->usr_cfg;
1570*437bfbebSnyanmisaka     RK_S32 mb_w = MPP_ALIGN(usr_cfg->width, 16) / 16;
1571*437bfbebSnyanmisaka     RK_S32 mb_h = MPP_ALIGN(usr_cfg->height, 16) / 16;
1572*437bfbebSnyanmisaka     RK_S32 bit_min = info->bit_min;
1573*437bfbebSnyanmisaka     RK_S32 bit_max = info->bit_max;
1574*437bfbebSnyanmisaka     RK_S32 bit_target = info->bit_target;
1575*437bfbebSnyanmisaka     RK_S32 quality_min = info->quality_min;
1576*437bfbebSnyanmisaka     RK_S32 quality_max = info->quality_max;
1577*437bfbebSnyanmisaka     RK_S32 quality_target = info->quality_target;
1578*437bfbebSnyanmisaka 
1579*437bfbebSnyanmisaka     rc_dbg_func("enter p %p task %p\n", p, task);
1580*437bfbebSnyanmisaka     rc_dbg_rc("seq_idx %d intra %d\n", frm->seq_idx, frm->is_intra);
1581*437bfbebSnyanmisaka 
1582*437bfbebSnyanmisaka     if (force->force_flag & ENC_RC_FORCE_QP) {
1583*437bfbebSnyanmisaka         RK_S32 qp = force->force_qp;
1584*437bfbebSnyanmisaka         info->quality_target = qp;
1585*437bfbebSnyanmisaka         info->quality_max = qp;
1586*437bfbebSnyanmisaka         info->quality_min = qp;
1587*437bfbebSnyanmisaka         return MPP_OK;
1588*437bfbebSnyanmisaka     }
1589*437bfbebSnyanmisaka 
1590*437bfbebSnyanmisaka     if (usr_cfg->mode == RC_FIXQP) {
1591*437bfbebSnyanmisaka         RK_S32 i_quality_delta = usr_cfg->i_quality_delta;
1592*437bfbebSnyanmisaka 
1593*437bfbebSnyanmisaka         if (frm->is_intra && i_quality_delta)
1594*437bfbebSnyanmisaka             p->start_qp = quality_target - i_quality_delta;
1595*437bfbebSnyanmisaka         else
1596*437bfbebSnyanmisaka             p->start_qp = quality_target;
1597*437bfbebSnyanmisaka 
1598*437bfbebSnyanmisaka         info->quality_target = p->start_qp;
1599*437bfbebSnyanmisaka 
1600*437bfbebSnyanmisaka         return MPP_OK;
1601*437bfbebSnyanmisaka     }
1602*437bfbebSnyanmisaka 
1603*437bfbebSnyanmisaka     /* setup quality parameters */
1604*437bfbebSnyanmisaka     if (p->first_frm_flg && frm->is_intra) {
1605*437bfbebSnyanmisaka         RK_S32 i_quality_delta = usr_cfg->i_quality_delta;
1606*437bfbebSnyanmisaka         p->pre_target_bits_fix_count = 0;
1607*437bfbebSnyanmisaka         p->pre_real_bits_count = 0;
1608*437bfbebSnyanmisaka 
1609*437bfbebSnyanmisaka         if (info->quality_target < 0) {
1610*437bfbebSnyanmisaka             if (info->bit_target) {
1611*437bfbebSnyanmisaka                 info->quality_target = cal_first_i_start_qp(info->bit_target, mb_w * mb_h);
1612*437bfbebSnyanmisaka             } else {
1613*437bfbebSnyanmisaka                 mpp_log("init qp not set on fix qp mode, use default qp\n");
1614*437bfbebSnyanmisaka                 info->quality_target = 26;
1615*437bfbebSnyanmisaka             }
1616*437bfbebSnyanmisaka         }
1617*437bfbebSnyanmisaka 
1618*437bfbebSnyanmisaka         if (p->reenc_cnt) {
1619*437bfbebSnyanmisaka             p->cur_scale_qp += p->next_ratio;
1620*437bfbebSnyanmisaka             p->start_qp = (p->cur_scale_qp >> 6) - i_quality_delta;
1621*437bfbebSnyanmisaka         } else {
1622*437bfbebSnyanmisaka             p->start_qp = info->quality_target;
1623*437bfbebSnyanmisaka             p->cur_scale_qp = (info->quality_target + i_quality_delta) << 6;
1624*437bfbebSnyanmisaka         }
1625*437bfbebSnyanmisaka 
1626*437bfbebSnyanmisaka         rc_dbg_rc("qp: start %2d cur_scale %d next_ratio %d reenc %d\n",
1627*437bfbebSnyanmisaka                   p->start_qp, p->cur_scale_qp, p->next_ratio, p->reenc_cnt);
1628*437bfbebSnyanmisaka 
1629*437bfbebSnyanmisaka         p->cur_scale_qp = mpp_clip(p->cur_scale_qp, (info->quality_min << 6), (info->quality_max << 6));
1630*437bfbebSnyanmisaka     } else {
1631*437bfbebSnyanmisaka         RK_S32 qp_scale = p->cur_scale_qp + p->next_ratio;
1632*437bfbebSnyanmisaka         RK_S32 start_qp = 0;
1633*437bfbebSnyanmisaka         RK_S32 qpmin = derive_min_qp_from_complexity(p, info, frm->is_intra);
1634*437bfbebSnyanmisaka 
1635*437bfbebSnyanmisaka         if (frm->is_intra && !frm->is_i_refresh) {
1636*437bfbebSnyanmisaka             RK_S32 i_quality_delta = usr_cfg->i_quality_delta;
1637*437bfbebSnyanmisaka             RK_S32 qp_scale_t = qp_scale =
1638*437bfbebSnyanmisaka                                     mpp_clip(qp_scale, (info->quality_min << 6), (info->quality_max << 6));
1639*437bfbebSnyanmisaka 
1640*437bfbebSnyanmisaka             qp_scale_t = (qp_scale + p->next_i_ratio) >> 6;
1641*437bfbebSnyanmisaka             if (qp_scale_t >= 35 && p->pre_i_qp <= 33)
1642*437bfbebSnyanmisaka                 start_qp = (p->pre_i_qp * 307 + qp_scale_t * 717) >> 10;
1643*437bfbebSnyanmisaka             else
1644*437bfbebSnyanmisaka                 start_qp = (p->pre_i_qp + qp_scale_t) >> 1;
1645*437bfbebSnyanmisaka 
1646*437bfbebSnyanmisaka             if (i_quality_delta) {
1647*437bfbebSnyanmisaka                 RK_U32 index = mpp_clip(mpp_data_mean_v2(p->madi) / 4, 0, 7);
1648*437bfbebSnyanmisaka                 RK_S32 max_ip_delta = max_ip_qp_dealt[index];
1649*437bfbebSnyanmisaka 
1650*437bfbebSnyanmisaka                 if (i_quality_delta > max_ip_delta)
1651*437bfbebSnyanmisaka                     i_quality_delta = max_ip_delta;
1652*437bfbebSnyanmisaka 
1653*437bfbebSnyanmisaka                 rc_dbg_rc("qp prev %d:%d curr %d - %d (max %d) -> %d reenc %d\n",
1654*437bfbebSnyanmisaka                           p->pre_i_qp, qp_scale >> 6, start_qp,
1655*437bfbebSnyanmisaka                           usr_cfg->i_quality_delta, max_ip_delta,
1656*437bfbebSnyanmisaka                           start_qp - i_quality_delta, p->reenc_cnt);
1657*437bfbebSnyanmisaka 
1658*437bfbebSnyanmisaka                 //if (!p->reenc_cnt) {
1659*437bfbebSnyanmisaka                 start_qp -= i_quality_delta;
1660*437bfbebSnyanmisaka                 //}
1661*437bfbebSnyanmisaka             }
1662*437bfbebSnyanmisaka 
1663*437bfbebSnyanmisaka             start_qp = mpp_clip(start_qp, qpmin, usr_cfg->fqp_max_i);
1664*437bfbebSnyanmisaka             start_qp = mpp_clip(start_qp, info->quality_min, info->quality_max);
1665*437bfbebSnyanmisaka             p->start_qp = start_qp;
1666*437bfbebSnyanmisaka 
1667*437bfbebSnyanmisaka             if (!p->reenc_cnt) {
1668*437bfbebSnyanmisaka                 p->cur_scale_qp = qp_scale;
1669*437bfbebSnyanmisaka                 if (p->usr_cfg.debreath_cfg.enable) {
1670*437bfbebSnyanmisaka                     calc_debreath_qp(ctx);
1671*437bfbebSnyanmisaka                 }
1672*437bfbebSnyanmisaka             }
1673*437bfbebSnyanmisaka 
1674*437bfbebSnyanmisaka             p->gop_frm_cnt = 0;
1675*437bfbebSnyanmisaka             p->gop_qp_sum = 0;
1676*437bfbebSnyanmisaka         } else {
1677*437bfbebSnyanmisaka             qp_scale = mpp_clip(qp_scale, (qpmin << 6), (info->quality_max << 6));
1678*437bfbebSnyanmisaka             qp_scale = mpp_clip(qp_scale, (info->quality_min << 6), (info->quality_max << 6));
1679*437bfbebSnyanmisaka             p->cur_scale_qp = qp_scale;
1680*437bfbebSnyanmisaka             rc_dbg_rc("qp %d -> %d\n", p->start_qp, qp_scale >> 6);
1681*437bfbebSnyanmisaka             p->start_qp = qp_scale >> 6;
1682*437bfbebSnyanmisaka             if (frm->ref_mode == REF_TO_PREV_INTRA && usr_cfg->vi_quality_delta) {
1683*437bfbebSnyanmisaka                 rc_dbg_rc("qp %d -> %d (vi)\n", p->start_qp, p->start_qp - usr_cfg->vi_quality_delta);
1684*437bfbebSnyanmisaka                 p->start_qp -= usr_cfg->vi_quality_delta;
1685*437bfbebSnyanmisaka             }
1686*437bfbebSnyanmisaka             p->start_qp = mpp_clip(p->start_qp, qpmin, usr_cfg->fqp_max_p);
1687*437bfbebSnyanmisaka         }
1688*437bfbebSnyanmisaka         if (p->pre_target_bits_fix_count * 90 / 100 > p->pre_real_bits_count) {
1689*437bfbebSnyanmisaka             p->start_qp = mpp_clip(p->start_qp, info->quality_min, 35);
1690*437bfbebSnyanmisaka         } else if (p->pre_target_bits_fix_count * 100 / 100 > p->pre_real_bits_count) {
1691*437bfbebSnyanmisaka             p->start_qp = mpp_clip(p->start_qp, info->quality_min, 37);
1692*437bfbebSnyanmisaka         } else if (p->pre_target_bits_fix_count * 107 / 100 > p->pre_real_bits_count) {
1693*437bfbebSnyanmisaka             p->start_qp = mpp_clip(p->start_qp, info->quality_min, 39);
1694*437bfbebSnyanmisaka         }
1695*437bfbebSnyanmisaka         p->start_qp = mpp_clip(p->start_qp, qpmin, 51);
1696*437bfbebSnyanmisaka     }
1697*437bfbebSnyanmisaka 
1698*437bfbebSnyanmisaka     if (usr_cfg->hier_qp_cfg.hier_qp_en && !p->reenc_cnt) {
1699*437bfbebSnyanmisaka         rc_hier_calc_dealt_qp(p, info);
1700*437bfbebSnyanmisaka         if (p->qp_layer_id) {
1701*437bfbebSnyanmisaka             RK_S32 hier_qp_delta = usr_cfg->hier_qp_cfg.hier_qp_delta[p->qp_layer_id - 1];
1702*437bfbebSnyanmisaka 
1703*437bfbebSnyanmisaka             p->start_qp -= hier_qp_delta;
1704*437bfbebSnyanmisaka             rc_dbg_qp("hier_qp: layer %d delta %d", p->qp_layer_id, hier_qp_delta);
1705*437bfbebSnyanmisaka         }
1706*437bfbebSnyanmisaka     }
1707*437bfbebSnyanmisaka 
1708*437bfbebSnyanmisaka     if (frm->is_intra)
1709*437bfbebSnyanmisaka         p->start_qp = mpp_clip(p->start_qp, usr_cfg->fqp_min_i, usr_cfg->fqp_max_i);
1710*437bfbebSnyanmisaka     else
1711*437bfbebSnyanmisaka         p->start_qp = mpp_clip(p->start_qp, usr_cfg->fqp_min_p, usr_cfg->fqp_max_p);
1712*437bfbebSnyanmisaka     info->quality_target = p->start_qp;
1713*437bfbebSnyanmisaka 
1714*437bfbebSnyanmisaka     rc_dbg_rc("bitrate [%d : %d : %d] -> [%d : %d : %d]\n",
1715*437bfbebSnyanmisaka               bit_min, bit_target, bit_max,
1716*437bfbebSnyanmisaka               info->bit_min, info->bit_target, info->bit_max);
1717*437bfbebSnyanmisaka     rc_dbg_rc("quality [%d : %d : %d] -> [%d : %d : %d]\n",
1718*437bfbebSnyanmisaka               quality_min, quality_target, quality_max,
1719*437bfbebSnyanmisaka               info->quality_min, info->quality_target, info->quality_max);
1720*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", p);
1721*437bfbebSnyanmisaka     return MPP_OK;
1722*437bfbebSnyanmisaka }
1723*437bfbebSnyanmisaka 
rc_model_v2_hal_end(void * ctx,EncRcTask * task)1724*437bfbebSnyanmisaka MPP_RET rc_model_v2_hal_end(void *ctx, EncRcTask *task)
1725*437bfbebSnyanmisaka {
1726*437bfbebSnyanmisaka     RcModelV2Ctx *p = (RcModelV2Ctx *)ctx;
1727*437bfbebSnyanmisaka     EncFrmStatus *frm = &task->frm;
1728*437bfbebSnyanmisaka 
1729*437bfbebSnyanmisaka     rc_dbg_func("enter ctx %p task %p\n", ctx, task);
1730*437bfbebSnyanmisaka 
1731*437bfbebSnyanmisaka     if (frm->is_intra)
1732*437bfbebSnyanmisaka         p->pre_i_qp = p->cur_scale_qp >> 6;
1733*437bfbebSnyanmisaka     else
1734*437bfbebSnyanmisaka         p->pre_p_qp = p->cur_scale_qp >> 6;
1735*437bfbebSnyanmisaka 
1736*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
1737*437bfbebSnyanmisaka     return MPP_OK;
1738*437bfbebSnyanmisaka }
1739*437bfbebSnyanmisaka 
rc_model_v2_check_reenc(void * ctx,EncRcTask * task)1740*437bfbebSnyanmisaka MPP_RET rc_model_v2_check_reenc(void *ctx, EncRcTask *task)
1741*437bfbebSnyanmisaka {
1742*437bfbebSnyanmisaka     RcModelV2Ctx *p = (RcModelV2Ctx *)ctx;
1743*437bfbebSnyanmisaka     EncRcTaskInfo *cfg = (EncRcTaskInfo *)&task->info;
1744*437bfbebSnyanmisaka     EncFrmStatus *frm = &task->frm;
1745*437bfbebSnyanmisaka     RcCfg *usr_cfg = &p->usr_cfg;
1746*437bfbebSnyanmisaka 
1747*437bfbebSnyanmisaka     rc_dbg_func("enter ctx %p cfg %p\n", ctx, cfg);
1748*437bfbebSnyanmisaka 
1749*437bfbebSnyanmisaka     frm->reencode = 0;
1750*437bfbebSnyanmisaka 
1751*437bfbebSnyanmisaka     if ((usr_cfg->mode == RC_FIXQP) ||
1752*437bfbebSnyanmisaka         (task->force.force_flag & ENC_RC_FORCE_QP) ||
1753*437bfbebSnyanmisaka         p->on_drop || p->on_pskip)
1754*437bfbebSnyanmisaka         return MPP_OK;
1755*437bfbebSnyanmisaka 
1756*437bfbebSnyanmisaka     if (check_re_enc(p, cfg)) {
1757*437bfbebSnyanmisaka         MppEncRcDropFrmMode drop_mode = usr_cfg->drop_mode;
1758*437bfbebSnyanmisaka 
1759*437bfbebSnyanmisaka         if (frm->is_intra)
1760*437bfbebSnyanmisaka             drop_mode = MPP_ENC_RC_DROP_FRM_DISABLED;
1761*437bfbebSnyanmisaka 
1762*437bfbebSnyanmisaka         if (usr_cfg->drop_gap && p->drop_cnt >= usr_cfg->drop_gap)
1763*437bfbebSnyanmisaka             drop_mode = MPP_ENC_RC_DROP_FRM_DISABLED;
1764*437bfbebSnyanmisaka 
1765*437bfbebSnyanmisaka         rc_dbg_drop("reenc drop_mode %d drop_cnt %d\n", drop_mode, p->drop_cnt);
1766*437bfbebSnyanmisaka 
1767*437bfbebSnyanmisaka         switch (drop_mode) {
1768*437bfbebSnyanmisaka         case MPP_ENC_RC_DROP_FRM_NORMAL : {
1769*437bfbebSnyanmisaka             frm->drop = 1;
1770*437bfbebSnyanmisaka             frm->reencode = 1;
1771*437bfbebSnyanmisaka             p->on_drop = 1;
1772*437bfbebSnyanmisaka             p->drop_cnt++;
1773*437bfbebSnyanmisaka             rc_dbg_drop("drop\n");
1774*437bfbebSnyanmisaka         } break;
1775*437bfbebSnyanmisaka         case MPP_ENC_RC_DROP_FRM_PSKIP : {
1776*437bfbebSnyanmisaka             frm->force_pskip = 1;
1777*437bfbebSnyanmisaka             frm->reencode = 1;
1778*437bfbebSnyanmisaka             p->on_pskip = 1;
1779*437bfbebSnyanmisaka             p->drop_cnt++;
1780*437bfbebSnyanmisaka             rc_dbg_drop("force_pskip\n");
1781*437bfbebSnyanmisaka         } break;
1782*437bfbebSnyanmisaka         case MPP_ENC_RC_DROP_FRM_DISABLED :
1783*437bfbebSnyanmisaka         default : {
1784*437bfbebSnyanmisaka             if (p->re_calc_ratio)
1785*437bfbebSnyanmisaka                 p->re_calc_ratio(p, cfg);
1786*437bfbebSnyanmisaka 
1787*437bfbebSnyanmisaka             if (p->next_ratio != 0 && cfg->quality_target < cfg->quality_max) {
1788*437bfbebSnyanmisaka                 p->reenc_cnt++;
1789*437bfbebSnyanmisaka                 frm->reencode = 1;
1790*437bfbebSnyanmisaka             }
1791*437bfbebSnyanmisaka             p->drop_cnt = 0;
1792*437bfbebSnyanmisaka         } break;
1793*437bfbebSnyanmisaka         }
1794*437bfbebSnyanmisaka     }
1795*437bfbebSnyanmisaka 
1796*437bfbebSnyanmisaka     return MPP_OK;
1797*437bfbebSnyanmisaka }
1798*437bfbebSnyanmisaka 
rc_model_v2_end(void * ctx,EncRcTask * task)1799*437bfbebSnyanmisaka MPP_RET rc_model_v2_end(void *ctx, EncRcTask *task)
1800*437bfbebSnyanmisaka {
1801*437bfbebSnyanmisaka     RcModelV2Ctx *p = (RcModelV2Ctx *)ctx;
1802*437bfbebSnyanmisaka     EncRcTaskInfo *cfg = (EncRcTaskInfo *)&task->info;
1803*437bfbebSnyanmisaka     RcCfg *usr_cfg = &p->usr_cfg;
1804*437bfbebSnyanmisaka 
1805*437bfbebSnyanmisaka     rc_dbg_func("enter ctx %p cfg %p\n", ctx, cfg);
1806*437bfbebSnyanmisaka 
1807*437bfbebSnyanmisaka     rc_dbg_rc("bits_mode_update real_bit %d", cfg->bit_real);
1808*437bfbebSnyanmisaka 
1809*437bfbebSnyanmisaka     if (usr_cfg->mode == RC_FIXQP)
1810*437bfbebSnyanmisaka         goto DONE;
1811*437bfbebSnyanmisaka 
1812*437bfbebSnyanmisaka     rc_dbg_rc("motion_level %u, complex_level %u\n", cfg->motion_level, cfg->complex_level);
1813*437bfbebSnyanmisaka     mpp_data_update_v2(p->motion_level, cfg->motion_level);
1814*437bfbebSnyanmisaka     mpp_data_update_v2(p->complex_level, cfg->complex_level);
1815*437bfbebSnyanmisaka     cfg->rt_bits = p->ins_bps;
1816*437bfbebSnyanmisaka     p->last_inst_bps = p->ins_bps;
1817*437bfbebSnyanmisaka     p->first_frm_flg = 0;
1818*437bfbebSnyanmisaka 
1819*437bfbebSnyanmisaka     bits_model_update(p, cfg);
1820*437bfbebSnyanmisaka     if (usr_cfg->mode == RC_AVBR) {
1821*437bfbebSnyanmisaka         moving_judge_update(p, cfg);
1822*437bfbebSnyanmisaka         bit_statics_update(p, cfg->bit_real);
1823*437bfbebSnyanmisaka     }
1824*437bfbebSnyanmisaka 
1825*437bfbebSnyanmisaka     p->gop_frm_cnt++;
1826*437bfbebSnyanmisaka     p->gop_qp_sum += p->start_qp;
1827*437bfbebSnyanmisaka 
1828*437bfbebSnyanmisaka     p->pre_mean_qp = cfg->quality_real;
1829*437bfbebSnyanmisaka     p->pre_iblk4_prop = cfg->iblk4_prop;
1830*437bfbebSnyanmisaka     p->scale_qp = p->cur_scale_qp;
1831*437bfbebSnyanmisaka     p->prev_md_prop = 0;
1832*437bfbebSnyanmisaka     p->pre_target_bits = cfg->bit_target;
1833*437bfbebSnyanmisaka     p->pre_target_bits_fix = cfg->bit_target_fix;
1834*437bfbebSnyanmisaka     p->pre_real_bits = cfg->bit_real;
1835*437bfbebSnyanmisaka 
1836*437bfbebSnyanmisaka     p->on_drop = 0;
1837*437bfbebSnyanmisaka     p->on_pskip = 0;
1838*437bfbebSnyanmisaka 
1839*437bfbebSnyanmisaka DONE:
1840*437bfbebSnyanmisaka     rc_dbg_func("leave %p\n", ctx);
1841*437bfbebSnyanmisaka     return MPP_OK;
1842*437bfbebSnyanmisaka }
1843