xref: /aosp_15_r20/external/libhevc/encoder/ihevce_rc_interface.c (revision c83a76b084498d55f252f48b2e3786804cdf24b7)
1 /******************************************************************************
2  *
3  * Copyright (C) 2018 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 
21 /**
22 ******************************************************************************
23 * @file ihevce_rc_interface.c
24 *
25 * @brief
26 *  This file contains function definitions for rc api interface
27 *
28 * @author
29 *  Ittiam
30 *
31 * List of Functions
32 *  <TODO: Update this>
33 *
34 ******************************************************************************
35 */
36 
37 /*****************************************************************************/
38 /* File Includes                                                             */
39 /*****************************************************************************/
40 
41 /* System include files */
42 #include <stdio.h>
43 #include <string.h>
44 #include <stdlib.h>
45 #include <assert.h>
46 #include <stdarg.h>
47 #include <math.h>
48 
49 /* User include files */
50 #include "ihevc_typedefs.h"
51 #include "itt_video_api.h"
52 #include "ihevce_api.h"
53 
54 #include "rc_cntrl_param.h"
55 #include "rc_frame_info_collector.h"
56 #include "rc_look_ahead_params.h"
57 #include "mem_req_and_acq.h"
58 #include "rate_control_api.h"
59 #include "var_q_operator.h"
60 
61 #include "ihevc_defs.h"
62 #include "ihevc_debug.h"
63 #include "ihevc_macros.h"
64 #include "ihevc_structs.h"
65 #include "ihevc_platform_macros.h"
66 #include "ihevc_deblk.h"
67 #include "ihevc_itrans_recon.h"
68 #include "ihevc_chroma_itrans_recon.h"
69 #include "ihevc_chroma_intra_pred.h"
70 #include "ihevc_intra_pred.h"
71 #include "ihevc_inter_pred.h"
72 #include "ihevc_mem_fns.h"
73 #include "ihevc_padding.h"
74 #include "ihevc_weighted_pred.h"
75 #include "ihevc_sao.h"
76 #include "ihevc_resi_trans.h"
77 #include "ihevc_quant_iquant_ssd.h"
78 
79 #include "ihevce_defs.h"
80 #include "ihevce_hle_interface.h"
81 #include "ihevce_lap_enc_structs.h"
82 #include "ihevce_lap_interface.h"
83 #include "ihevce_multi_thrd_structs.h"
84 #include "ihevce_me_common_defs.h"
85 #include "ihevce_had_satd.h"
86 #include "ihevce_function_selector.h"
87 #include "ihevce_enc_structs.h"
88 #include "ihevce_cmn_utils_instr_set_router.h"
89 #include "hme_datatype.h"
90 #include "hme_interface.h"
91 #include "hme_common_defs.h"
92 #include "hme_defs.h"
93 #include "ihevce_rc_enc_structs.h"
94 #include "ihevce_rc_structs.h"
95 #include "ihevce_rc_interface.h"
96 #include "ihevce_frame_process_utils.h"
97 
98 /*****************************************************************************/
99 /* Constant Macros                                                           */
100 /*****************************************************************************/
101 #define USE_USER_FIRST_FRAME_QP 0
102 #define DEBUG_PRINT 0
103 #define DETERMINISTIC_RC 1
104 #define USE_QP_OFFSET_POST_SCD 1
105 #define USE_SQRT 0
106 #define K_SCALING_FACTOR 8
107 #define ENABLE_2_PASS_BIT_ALLOC_FRM_1ST 0
108 
109 #define VBV_THRSH_I_PIC_DELTA_QP_1 (0.85)
110 #define VBV_THRSH_I_PIC_DELTA_QP_2 (0.75)
111 #define VBV_THRSH_P_PIC_DELTA_QP_1 (0.80)
112 #define VBV_THRSH_P_PIC_DELTA_QP_2 (0.70)
113 #define VBV_THRSH_BR_PIC_DELTA_QP_1 (0.75)
114 #define VBV_THRSH_BR_PIC_DELTA_QP_2 (0.65)
115 #define VBV_THRSH_BNR_PIC_DELTA_QP_1 (0.75)
116 #define VBV_THRSH_BNR_PIC_DELTA_QP_2 (0.65)
117 #define VBV_THRSH_DELTA_QP (0.6)
118 
119 #define VBV_THRSH_FRM_PRLL_I_PIC_DELTA_QP_1 (0.70)
120 #define VBV_THRSH_FRM_PRLL_I_PIC_DELTA_QP_2 (0.60)
121 #define VBV_THRSH_FRM_PRLL_P_PIC_DELTA_QP_1 (0.65)
122 #define VBV_THRSH_FRM_PRLL_P_PIC_DELTA_QP_2 (0.55)
123 #define VBV_THRSH_FRM_PRLL_BR_PIC_DELTA_QP_1 (0.60)
124 #define VBV_THRSH_FRM_PRLL_BR_PIC_DELTA_QP_2 (0.50)
125 #define VBV_THRSH_FRM_PRLL_BNR_PIC_DELTA_QP_1 (0.60)
126 #define VBV_THRSH_FRM_PRLL_BNR_PIC_DELTA_QP_2 (0.50)
127 #define VBV_THRSH_FRM_PRLL_DELTA_QP (0.45)
128 
129 #define TRACE_SUPPORT 0
130 
131 /*****************************************************************************/
132 /* Globals                                                                   */
133 /*****************************************************************************/
134 
135 /*
136 Modified bpp vs nor satd/act/qp :
137 =================================
138 
139 Prestine Quality
140 -----------------
141 480p  y = -0.1331x3 - 0.0589x2 + 2.5091x - 0.0626
142 720p  y = -0.3603x3 + 0.4504x2 + 2.2056x - 0.0411
143 1080p y = -0.7085x3 + 0.9743x2 + 1.939x - 0.0238
144 2160p y = -1.2447x3 + 2.1218x2 + 1.4995x - 0.0108
145 
146 High Quality
147 -------------
148 480p  y = -0.1348x3 - 0.0557x2 + 2.5055x - 0.0655
149 720p  y = -0.0811x3 + 0.1988x2 + 1.246x - 0.0385
150 1080p y = -0.74x3 + 1.0552x2 + 1.8942x - 0.0251
151 2160p y = -1.3851x3 + 2.3372x2 + 1.4255x - 0.0113
152 
153 Medium Speed
154 -------------
155 480p  y = -0.143x3 - 0.0452x2 + 2.5581x - 0.0765
156 720p  y = -0.3997x3 + 0.542x2 + 2.201x - 0.0507
157 1080p y = -0.816x3 + 1.2048x2 + 1.8689x - 0.0298
158 2160p y = -1.5169x3 + 2.5857x2 + 1.3478x - 0.0126
159 
160 High Speed
161 -----------
162 480p  y = -0.1472x3 - 0.0341x2 + 2.5605x - 0.0755
163 720p  y = -0.3967x3 + 0.526x2 + 2.2228x - 0.0504
164 1080p y = -0.8008x3 + 1.1713x2 + 1.8897x - 0.0297
165 2160p y = -1.503x3 + 2.576x2 + 1.3476x - 0.0123
166 
167 Extreme Speed
168 --------------
169 480p  y = -0.1379x3 - 0.059x2 + 2.5716x - 0.0756
170 720p  y = -0.3938x3 + 0.521x2 + 2.2239x - 0.0505
171 1080p y = -0.8041x3 + 1.1725x2 + 1.8874x - 0.0293
172 2160p y = -1.4863x3 + 2.556x2 + 1.344x - 0.0122
173 
174 */
175 
176 const double g_offline_i_model_coeff[20][4] = {
177 
178     /*ultra_HD*/
179     { -1.2447, 2.1218, 1.4995, -0.0108 }, /*Prestine quality*/
180     { -1.3851, 2.3372, 1.4255, -0.0113 }, /*High quality*/
181     { -1.5169, 2.5857, 1.3478, -0.0126 }, /*Medium speed*/
182     { -1.503, 2.576, 1.3476, -0.0123 }, /*high speed*/
183     { -1.4863, 2.556, 1.344, -0.0122 }, /*Extreme Speed*/
184 
185     /*Full HD*/
186     { -0.7085, 0.9743, 1.939, -0.0238 }, /*Prestine quality*/
187     { -0.74, 1.0552, 1.8942, -0.0251 }, /*High quality*/
188     { -0.816, 1.2048, 1.8689, -0.0298 }, /*Medium speed*/
189     { -0.8008, 1.1713, 1.8897, -0.0297 }, /*high speed*/
190     { -0.8041, 1.1725, 1.8874, -0.0293 }, /*Extreme Speed*/
191 
192     /*720p*/
193     { -0.3603, 0.4504, 2.2056, -0.0411 }, /*Prestine quality*/
194     // {-0.0811, 0.1988, 1.246, - 0.0385},/*High quality*/
195     { -0.3997, 0.542, 2.201, -0.0507 },
196     { -0.3997, 0.542, 2.201, -0.0507 }, /*Medium speed*/
197     { -0.3967, 0.526, 2.2228, -0.0504 }, /*high speed*/
198     { -0.3938, 0.521, 2.2239, -0.0505 }, /*Extreme Speed*/
199 
200     /*SD*/
201     { -0.1331, -0.0589, 2.5091, -0.0626 }, /*Prestine quality*/
202     { -0.1348, -0.0557, 2.5055, -0.0655 }, /*High quality*/
203     { -0.143, -0.0452, 2.5581, -0.0765 }, /*Medium speed*/
204     { -0.1472, -0.0341, 2.5605, -0.0755 }, /*high speed*/
205     { -0.1379, -0.059, 2.5716, -0.0756 } /*Extreme Speed*/
206 
207 };
208 
209 /*****************************************************************************/
210 /* Function Declarations                                                     */
211 /*****************************************************************************/
212 
213 picture_type_e ihevce_rc_conv_pic_type(
214     IV_PICTURE_CODING_TYPE_T pic_type,
215     WORD32 i4_field_pic,
216     WORD32 i4_temporal_layer_id,
217     WORD32 i4_is_bottom_field,
218     WORD32 i4_top_field_first);
219 
220 WORD32 ihevce_rc_get_scaled_mpeg2_qp(WORD32 i4_frame_qp, rc_quant_t *ps_rc_quant_ctxt);
221 
222 static WORD32 ihevce_get_offline_index(rc_context_t *ps_rc_ctxt, WORD32 i4_num_pels_in_frame);
223 
224 static void ihevce_rc_get_pic_param(
225     picture_type_e rc_pic_type, WORD32 *pi4_tem_lyr, WORD32 *pi4_is_bottom_field);
226 
227 static double ihevce_get_frame_lambda_modifier(
228     WORD8 slice_type,
229     WORD32 i4_rc_temporal_lyr_id,
230     WORD32 i4_first_field,
231     WORD32 i4_rc_is_ref_pic,
232     WORD32 i4_num_b_frms);
233 
234 static WORD32 ihevce_clip_min_max_qp(
235     rc_context_t *ps_rc_ctxt,
236     WORD32 i4_hevc_frame_qp,
237     picture_type_e rc_pic_type,
238     WORD32 i4_rc_temporal_lyr_id);
239 
240 WORD32 ihevce_ebf_based_rc_correction_to_avoid_overflow(
241     rc_context_t *ps_rc_ctxt, rc_lap_out_params_t *ps_rc_lap_out, WORD32 *pi4_tot_bits_estimated);
242 
243 /*****************************************************************************/
244 /* Function Definitions                                                      */
245 /*****************************************************************************/
246 
247 /*!
248 ************************************************************************
249 * @brief
250 *    return number of records used by RC
251 ************************************************************************
252 */
ihevce_rc_get_num_mem_recs(void)253 WORD32 ihevce_rc_get_num_mem_recs(void)
254 {
255     WORD32 i4_num_rc_mem_tab = 0;
256 
257     /*get the number of memtab request from RC*/
258     rate_control_handle ps_rate_control_api;
259     itt_memtab_t *ps_memtab = NULL;
260     i4_num_rc_mem_tab =
261         rate_control_num_fill_use_free_memtab(&ps_rate_control_api, ps_memtab, GET_NUM_MEMTAB);
262 
263     return ((NUM_RC_MEM_RECS + i4_num_rc_mem_tab));
264 }
265 
266 /*!
267 ************************************************************************
268 * @brief
269 *    return each record attributes of RC
270 ************************************************************************
271 */
ihevce_rc_get_mem_recs(iv_mem_rec_t * ps_mem_tab,ihevce_static_cfg_params_t * ps_init_prms,WORD32 mem_space,ihevce_sys_api_t * ps_sys_api)272 WORD32 ihevce_rc_get_mem_recs(
273     iv_mem_rec_t *ps_mem_tab,
274     ihevce_static_cfg_params_t *ps_init_prms,
275     WORD32 mem_space,
276     ihevce_sys_api_t *ps_sys_api)
277 {
278     float f_temp;
279     WORD32 i4_temp_size;
280     WORD32 i4_num_memtab = 0;
281     WORD32 i4_num_rc_mem_tab, i;
282     rate_control_handle ps_rate_control_api;
283     itt_memtab_t *ps_itt_memtab = NULL;
284     itt_memtab_t as_rc_mem_tab[30];
285 
286     /*memory requirements to store RC context */
287     ps_mem_tab[RC_CTXT].i4_mem_size = sizeof(rc_context_t);
288     //DBG_PRINTF("size of RC context = %d\n",sizeof(rc_context_t));
289     ps_mem_tab[RC_CTXT].e_mem_type = (IV_MEM_TYPE_T)mem_space;
290 
291     ps_mem_tab[RC_CTXT].i4_mem_alignment = 64;
292 
293     (void)ps_sys_api;
294     //i4_temp_size = (51 + ((ps_init_prms->s_src_prms.i4_bit_depth - 8) * 6));
295     i4_temp_size = (51 + ((ps_init_prms->s_tgt_lyr_prms.i4_internal_bit_depth - 8) * 6));
296 
297     ps_mem_tab[RC_QP_TO_QSCALE].i4_mem_size = (i4_temp_size + 1) * 4;
298     ps_mem_tab[RC_QP_TO_QSCALE].e_mem_type = (IV_MEM_TYPE_T)mem_space;
299     ps_mem_tab[RC_QP_TO_QSCALE].i4_mem_alignment = 64;
300 
301     ps_mem_tab[RC_QP_TO_QSCALE_Q_FACTOR].i4_mem_size = (i4_temp_size + 1) * 4;
302     ps_mem_tab[RC_QP_TO_QSCALE_Q_FACTOR].e_mem_type = (IV_MEM_TYPE_T)mem_space;
303     ps_mem_tab[RC_QP_TO_QSCALE_Q_FACTOR].i4_mem_alignment = 64;
304 
305     f_temp = (float)(51 + ((ps_init_prms->s_tgt_lyr_prms.i4_internal_bit_depth - 8) * 6));
306     f_temp = ((float)(f_temp - 4) / 6);
307     i4_temp_size = (WORD32)((float)pow(2, f_temp) + 0.5);
308     i4_temp_size = (i4_temp_size << 3);  // Q3 format is mantained for accuarate calc at lower qp
309 
310     ps_mem_tab[RC_QSCALE_TO_QP].i4_mem_size = (i4_temp_size + 1) * sizeof(UWORD32);
311     ps_mem_tab[RC_QSCALE_TO_QP].e_mem_type = (IV_MEM_TYPE_T)mem_space;
312     ps_mem_tab[RC_QSCALE_TO_QP].i4_mem_alignment = 64;
313 
314     /*memory requirements to store RC context */
315     ps_mem_tab[RC_MULTI_PASS_GOP_STAT].i4_mem_size = sizeof(gop_level_stat_t);
316     ps_mem_tab[RC_MULTI_PASS_GOP_STAT].e_mem_type = (IV_MEM_TYPE_T)mem_space;
317     ps_mem_tab[RC_MULTI_PASS_GOP_STAT].i4_mem_alignment = 64;
318 
319     i4_num_rc_mem_tab =
320         rate_control_num_fill_use_free_memtab(&ps_rate_control_api, ps_itt_memtab, GET_NUM_MEMTAB);
321 
322     i4_num_memtab =
323         rate_control_num_fill_use_free_memtab(&ps_rate_control_api, as_rc_mem_tab, FILL_MEMTAB);
324 
325     for(i = 0; i < i4_num_memtab; i++)
326     {
327         ps_mem_tab[i + NUM_RC_MEM_RECS].i4_mem_size = as_rc_mem_tab[i].u4_size;
328         ps_mem_tab[i + NUM_RC_MEM_RECS].i4_mem_alignment = as_rc_mem_tab[i].i4_alignment;
329         ps_mem_tab[i + NUM_RC_MEM_RECS].e_mem_type = (IV_MEM_TYPE_T)mem_space;
330     }
331     return (i4_num_memtab + NUM_RC_MEM_RECS);
332 }
333 
334 /**
335 ******************************************************************************
336 *
337 *  @brief Initilizes the rate control module
338 *
339 *  @par   Description
340 *
341 *  @param[inout]   ps_mem_tab
342 *  pointer to memory descriptors table
343 *
344 *  @param[in]      ps_init_prms
345 *  Create time static parameters
346 *
347 *  @return      void
348 *
349 ******************************************************************************
350 */
ihevce_rc_mem_init(iv_mem_rec_t * ps_mem_tab,ihevce_static_cfg_params_t * ps_init_prms,WORD32 i4_bitrate_instance_id,rc_quant_t * ps_rc_quant,WORD32 i4_resolution_id,WORD32 i4_look_ahead_frames_in_first_pass)351 void *ihevce_rc_mem_init(
352     iv_mem_rec_t *ps_mem_tab,
353     ihevce_static_cfg_params_t *ps_init_prms,
354     WORD32 i4_bitrate_instance_id,
355     rc_quant_t *ps_rc_quant,
356     WORD32 i4_resolution_id,
357     WORD32 i4_look_ahead_frames_in_first_pass)
358 {
359     rc_context_t *ps_rc_ctxt;
360     WORD32 i4_num_memtab, i, j, i4_avg_bitrate, u4_buf_size;
361     WORD32 i4_cdr_period = 0, i4_idr_period = 0;
362     WORD32 i4_peak_bitrate_factor;
363     rate_control_handle ps_rate_control_api;
364     itt_memtab_t as_rc_mem_tab[30];
365     itt_memtab_t *ps_itt_memtab = NULL;
366     ps_rc_ctxt = (rc_context_t *)ps_mem_tab[RC_CTXT].pv_base;
367     memset(ps_rc_ctxt, 0, sizeof(rc_context_t));
368 
369     ps_rc_ctxt->i4_br_id_for_2pass = i4_bitrate_instance_id;
370     if(ps_init_prms->s_coding_tools_prms.i4_max_cra_open_gop_period)
371     {
372         i4_cdr_period = ps_init_prms->s_coding_tools_prms.i4_max_cra_open_gop_period;
373     }
374     if(ps_init_prms->s_coding_tools_prms.i4_max_i_open_gop_period)
375     {
376         i4_cdr_period = ps_init_prms->s_coding_tools_prms.i4_max_i_open_gop_period;
377     }
378     i4_idr_period = ps_init_prms->s_coding_tools_prms.i4_max_closed_gop_period;
379 
380     ps_rc_quant->pi4_qscale_to_qp = (WORD32 *)ps_mem_tab[RC_QSCALE_TO_QP].pv_base;
381 
382     ps_rc_quant->pi4_qp_to_qscale_q_factor = (WORD32 *)ps_mem_tab[RC_QP_TO_QSCALE_Q_FACTOR].pv_base;
383 
384     ps_rc_quant->pi4_qp_to_qscale = (WORD32 *)ps_mem_tab[RC_QP_TO_QSCALE].pv_base;
385 
386     ps_rc_ctxt->pv_gop_stat = (void *)ps_mem_tab[RC_MULTI_PASS_GOP_STAT].pv_base;
387 
388     /*assign memtabs to rc module*/
389     i4_num_memtab =
390         rate_control_num_fill_use_free_memtab(&ps_rate_control_api, ps_itt_memtab, GET_NUM_MEMTAB);
391 
392     i4_num_memtab =
393         rate_control_num_fill_use_free_memtab(&ps_rate_control_api, as_rc_mem_tab, FILL_MEMTAB);
394     for(i = 0; i < i4_num_memtab; i++)
395     {
396         as_rc_mem_tab[i].pv_base = ps_mem_tab[i + NUM_RC_MEM_RECS].pv_base;
397     }
398     i4_num_memtab =
399         rate_control_num_fill_use_free_memtab(&ps_rate_control_api, as_rc_mem_tab, USE_BASE);
400 
401     ps_rc_ctxt->rc_hdl =
402         ps_rate_control_api; /*handle to entire RC structure private to RC library*/
403     ps_rc_ctxt->i4_field_pic = ps_init_prms->s_src_prms.i4_field_pic;
404 
405     ps_rc_ctxt->i4_is_first_frame_encoded = 0;
406     /*added for field encoding*/
407     ps_rc_ctxt->i4_max_inter_frm_int =
408         1 << (ps_init_prms->s_coding_tools_prms.i4_max_temporal_layers + ps_rc_ctxt->i4_field_pic);
409     ps_rc_ctxt->i4_max_temporal_lyr = ps_init_prms->s_coding_tools_prms.i4_max_temporal_layers;
410     /*Number of picture types used if different models are used for hierarchial B frames*/
411 
412     if(i4_idr_period == 1 || i4_cdr_period == 1)
413         ps_rc_ctxt->i4_num_active_pic_type = 1;
414     else
415         ps_rc_ctxt->i4_num_active_pic_type =
416             2 + ps_init_prms->s_coding_tools_prms.i4_max_temporal_layers;
417 
418     ps_rc_ctxt->i4_quality_preset =
419         ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_quality_preset;
420 
421     if(ps_rc_ctxt->i4_quality_preset == IHEVCE_QUALITY_P7)
422     {
423         ps_rc_ctxt->i4_quality_preset = IHEVCE_QUALITY_P6;
424     }
425 
426     ps_rc_ctxt->i4_rc_pass = ps_init_prms->s_pass_prms.i4_pass;
427     ps_rc_ctxt->i8_num_gop_mem_alloc = 0;
428 
429     ps_rc_ctxt->u1_is_mb_level_rc_on = 0; /*no mb level RC*/
430 
431     ps_rc_ctxt->i4_is_infinite_gop = 0;
432     ps_rc_ctxt->u1_bit_depth = (UWORD8)ps_init_prms->s_tgt_lyr_prms.i4_internal_bit_depth;
433 
434     //ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset = ((ps_init_prms->s_src_prms.i4_bit_depth-8)*6);
435     ps_rc_quant->i1_qp_offset = ((ps_init_prms->s_tgt_lyr_prms.i4_internal_bit_depth - 8) * 6);
436 
437     ps_rc_quant->i2_max_qp = MIN(ps_init_prms->s_config_prms.i4_max_frame_qp,
438                                  51);  // FOR Encoder
439     ps_rc_quant->i2_min_qp =
440         MAX(-(ps_rc_quant->i1_qp_offset), ps_init_prms->s_config_prms.i4_min_frame_qp);
441 
442     if(ps_init_prms->s_lap_prms.i4_rc_look_ahead_pics)
443     {
444         ps_rc_ctxt->i4_num_frame_in_lap_window =
445             ps_init_prms->s_lap_prms.i4_rc_look_ahead_pics + MIN_L1_L0_STAGGER_NON_SEQ;
446     }
447     else
448         ps_rc_ctxt->i4_num_frame_in_lap_window = 0;
449 
450     if(i4_cdr_period > 0 && i4_idr_period > 0)
451     {
452         /*both IDR and CDR are positive*/
453         //WORD32 i4_rem;
454         ps_rc_ctxt->u4_intra_frame_interval = i4_cdr_period;
455         ps_rc_ctxt->u4_idr_period = i4_idr_period;
456 
457         /*Allow configuration where IDR period is multiple of CDR period. Though any configuiration is supported by LAP rate control
458         does not handle assymeteric GOPS, Bit-allocation is exposed to CDR or IDR. It treats everything as I pic*/
459     }
460     else if(!i4_idr_period && i4_cdr_period > 0)
461     {
462         ps_rc_ctxt->u4_intra_frame_interval = i4_cdr_period;
463         ps_rc_ctxt->u4_idr_period = 0;
464     }
465     else if(!i4_cdr_period && i4_idr_period > 0)
466     {
467         ps_rc_ctxt->u4_intra_frame_interval = i4_idr_period;
468         ps_rc_ctxt->u4_idr_period = i4_idr_period;
469     }
470     else
471     {
472         /*ASSERT(0);*/
473 
474         ps_rc_ctxt->u4_intra_frame_interval =
475             INFINITE_GOP_CDR_TIME_S *
476             ((ps_init_prms->s_src_prms.i4_frm_rate_num /
477               (ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_frm_rate_scale_factor *
478                ps_init_prms->s_src_prms.i4_frm_rate_denom)));
479         ps_rc_ctxt->u4_idr_period = 0;
480         ps_rc_ctxt->i4_is_infinite_gop = 1;
481     }
482 
483     /*If cdr period is 0 then only it is closed gop*/
484     ps_rc_ctxt->i4_is_gop_closed = 0;
485     if(i4_cdr_period == 0)
486     {
487         ps_rc_ctxt->i4_is_gop_closed = 1;
488     }
489     /*This is required because the intra sad returned by non I pic is not correct. Use only I pic sad for next I pic qp calculation*/
490     ps_rc_ctxt->i4_use_est_intra_sad = 0;
491     ps_rc_ctxt->u4_src_ticks = 1000;
492     ps_rc_ctxt->u4_tgt_ticks = 1000;
493     ps_rc_ctxt->i4_auto_generate_init_qp = 1;
494 
495     ps_rc_ctxt->i8_prev_i_frm_cost = 0;
496 
497     for(i = 0; i < MAX_PIC_TYPE; i++)
498     {
499         /* -1 cost indicates the picture type not been encoded*/
500         ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[i] = -1;
501         ps_rc_ctxt->ai8_prev_frame_est_L0_satd[i] = -1;
502         ps_rc_ctxt->ai8_prev_frame_hme_sad[i] = -1;
503         ps_rc_ctxt->ai8_prev_frame_pre_intra_sad[i] = -1;
504         /*L1 state metrics*/
505         ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[i] = -1;
506         ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_cost[i] = -1;
507         ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_sad[i] = -1;
508         /* SGI & Enc Loop Parallelism related changes*/
509         ps_rc_ctxt->s_l1_state_metric.au4_prev_scene_num[i] = 0;
510         ps_rc_ctxt->au4_prev_scene_num_pre_enc[i] = 0xFFFFFFFF;
511         ps_rc_ctxt->ai4_qp_for_previous_scene_pre_enc[i] = 0;
512     }
513     ps_rc_ctxt->u4_scene_num_est_L0_intra_sad_available = 0xFFFFFFFF;
514 
515     for(i = 0; i < MAX_NON_REF_B_PICS_IN_QUEUE_SGI; i++)
516     {
517         ps_rc_ctxt->as_non_ref_b_qp[i].i4_enc_order_num_rc = 0x7FFFFFFF;
518         ps_rc_ctxt->as_non_ref_b_qp[i].i4_non_ref_B_pic_qp = 0x7FFFFFFF;
519         ps_rc_ctxt->as_non_ref_b_qp[i].u4_scene_num_rc = MAX_SCENE_NUM + 1;
520     }
521     ps_rc_ctxt->i4_non_ref_B_ctr = 0;
522     ps_rc_ctxt->i4_prev_qp_ctr = 0;
523     ps_rc_ctxt->i4_cur_scene_num = 0;
524 
525     /*init = 0 set to 1 when atleast one frame of each picture type has completed L1 stage*/
526     ps_rc_ctxt->i4_is_est_L0_intra_sad_available = 0;
527 
528     /*Min and max qp from user*/
529     ps_rc_ctxt->i4_min_frame_qp = ps_init_prms->s_config_prms.i4_min_frame_qp;
530     ps_rc_ctxt->i4_max_frame_qp = ps_init_prms->s_config_prms.i4_max_frame_qp;
531     ASSERT(ps_rc_ctxt->i4_min_frame_qp >= ps_rc_quant->i2_min_qp);
532     ASSERT(ps_rc_ctxt->i4_max_frame_qp <= ps_rc_quant->i2_max_qp);
533     /*bitrate init*/
534     /*take average bitrate from comfig file*/
535     i4_avg_bitrate = ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
536                          .ai4_tgt_bitrate[i4_bitrate_instance_id];
537 
538     if((ps_init_prms->s_config_prms.i4_rate_control_mode == VBR_STREAMING) &&
539        (ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
540             .ai4_peak_bitrate[i4_bitrate_instance_id] < (1050 * (i4_avg_bitrate / 1000))))
541     {
542         ps_init_prms->s_config_prms.i4_rate_control_mode = CBR_NLDRC;
543     }
544 
545     ps_rc_ctxt->e_rate_control_type = (rc_type_e)ps_init_prms->s_config_prms.i4_rate_control_mode;
546     ps_rc_ctxt->i4_capped_vbr_flag = 0;
547     if(1 == ps_init_prms->s_config_prms.i4_rate_control_mode)
548     {
549         /* The path taken by capped vbr mode is same as normal VBR mode. Only a flag needs to be enabled
550            which tells the rc module that encoder is running in capped vbr mode */
551         ps_rc_ctxt->e_rate_control_type = VBR_STREAMING;
552         ps_rc_ctxt->i4_capped_vbr_flag = 1;
553     }
554     ASSERT(
555         (ps_rc_ctxt->e_rate_control_type == CBR_NLDRC) ||
556         (ps_rc_ctxt->e_rate_control_type == CONST_QP) ||
557         (ps_rc_ctxt->e_rate_control_type == VBR_STREAMING));
558 
559     ps_rc_ctxt->u4_avg_bit_rate = i4_avg_bitrate;
560     for(i = 0; i < MAX_PIC_TYPE; i++)
561     {
562         if(ps_rc_ctxt->e_rate_control_type == VBR_STREAMING)
563         {
564             ps_rc_ctxt->au4_peak_bit_rate[i] =
565                 ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
566                     .ai4_peak_bitrate[i4_bitrate_instance_id];
567         }
568         else
569         {
570             /*peak bitrate parameter is ignored in CBR*/
571             ps_rc_ctxt->au4_peak_bit_rate[i] = i4_avg_bitrate;
572         }
573     }
574     ps_rc_ctxt->u4_min_bit_rate = i4_avg_bitrate;
575 
576     /*buffer size init*/
577     u4_buf_size = (WORD32)(ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
578                                .ai4_max_vbv_buffer_size[i4_bitrate_instance_id]);
579     ps_rc_ctxt->u4_max_delay = (UWORD32)(
580         (float)u4_buf_size / i4_avg_bitrate * 1000); /*delay in milli-seconds based on buffer size*/
581     ps_rc_ctxt->u4_max_vbv_buff_size = u4_buf_size; /*buffer size should be in bits*/
582     /*This dictates the max deviaiton allowed for file size in VBR mode. */
583     ps_rc_ctxt->f_vbr_max_peak_sustain_dur =
584         ((float)ps_init_prms->s_config_prms.i4_vbr_max_peak_rate_dur) / 1000;
585     ps_rc_ctxt->i8_num_frms_to_encode = (WORD32)ps_init_prms->s_config_prms.i4_num_frms_to_encode;
586     i4_peak_bitrate_factor = (ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
587                                   .ai4_peak_bitrate[i4_bitrate_instance_id] /
588                               i4_avg_bitrate) *
589                              1000;
590     {
591         //float f_delay = ((float)ps_init_prms->s_config_prms.i4_max_vbv_buffer_size*1000)/i4_peak_bitrate_factor;
592         float f_delay = ((float)ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
593                              .ai4_max_vbv_buffer_size[i4_bitrate_instance_id] *
594                          1000) /
595                         ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
596                             .ai4_peak_bitrate[i4_bitrate_instance_id];
597         ps_rc_ctxt->i4_initial_decoder_delay_frames = (WORD32)(
598             ((f_delay) * (ps_init_prms->s_src_prms.i4_frm_rate_num /
599                           (ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
600                                .i4_frm_rate_scale_factor *
601                            ps_init_prms->s_src_prms.i4_frm_rate_denom))) /
602             1000);
603     }
604     /*Initial buffer fullness*/
605     ps_rc_ctxt->i4_init_vbv_fullness = ps_init_prms->s_config_prms.i4_init_vbv_fullness;
606 
607     /*Init Qp updation. This seems to be used for pre enc stage of second frame. Needs to be looked into*/
608     ps_rc_ctxt->i4_init_frame_qp_user = ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
609                                             .ai4_frame_qp[i4_bitrate_instance_id];
610 
611     for(i = 0; i < MAX_SCENE_NUM; i++)
612     {
613         for(j = 0; j < MAX_PIC_TYPE; j++)
614             ps_rc_ctxt->ai4_prev_pic_hevc_qp[i][j] = INIT_HEVCE_QP_RC;
615     }
616     memset(&ps_rc_ctxt->ai4_scene_numbers[0], 0, sizeof(ps_rc_ctxt->ai4_scene_numbers));
617     memset(&ps_rc_ctxt->ai4_scene_num_last_pic[0], 0, sizeof(ps_rc_ctxt->ai4_scene_num_last_pic));
618     ps_rc_ctxt->ai4_last_tw0_lyr0_pic_qp[0] = ps_rc_ctxt->i4_min_frame_qp - 1;
619     ps_rc_ctxt->ai4_last_tw0_lyr0_pic_qp[1] = ps_rc_ctxt->i4_min_frame_qp - 1;
620     /* SGI & Enc Loop Parallelism related changes*/
621     for(i = 0; i < MAX_NUM_ENC_LOOP_PARALLEL; i++)
622     {
623         ps_rc_ctxt->ai8_cur_frm_intra_cost[i] = 0;
624         ps_rc_ctxt->ai8_cur_frame_coarse_ME_cost[i] = 0;
625         ps_rc_ctxt->ai4_I_model_only_reset[i] = 0;
626         ps_rc_ctxt->ai4_is_non_I_scd_pic[i] = 0;
627         ps_rc_ctxt->ai4_is_pause_to_resume[i] = 0;
628         ps_rc_ctxt->ai4_is_cmplx_change_reset_model[i] = 0;
629         ps_rc_ctxt->ai4_is_cmplx_change_reset_bits[i] = 0;
630         /*initialize assuming 30 percent intra and 70 percent inter weightage*/
631         ps_rc_ctxt->ai4_lap_complexity_q7[i] = MODERATE_LAP2_COMPLEXITY_Q7;
632 
633         ps_rc_ctxt->ai4_lap_f_sim[i] = MODERATE_FSIM_VALUE;
634     }
635 
636     /*Init variables required to handle entropy and rdopt consumption mismatch*/
637     ps_rc_ctxt->i4_rdopt_bit_count = 0;
638     ps_rc_ctxt->i4_entropy_bit_count = 0;
639     for(i = 0; i < NUM_BUF_RDOPT_ENT_CORRECT; i++)
640     {
641         ps_rc_ctxt->ai4_rdopt_bit_consumption_estimate[i] =
642             -1; /*negative bit signifies that value is not populated*/
643         ps_rc_ctxt->ai4_rdopt_bit_consumption_buf_id[i] = -1;
644         ps_rc_ctxt->ai4_entropy_bit_consumption[i] = -1;
645         ps_rc_ctxt->ai4_entropy_bit_consumption_buf_id[i] = -1;
646     }
647 
648     /** scd model reset related param init*/
649     for(i = 0; i < MAX_NUM_TEMPORAL_LAYERS; i++)
650     {
651         ps_rc_ctxt->au4_scene_num_temp_id[i] = 0;
652     }
653     /* SGI & Enc Loop Parallelism related changes*/
654     for(i = 0; i < MAX_NUM_ENC_LOOP_PARALLEL; i++)
655     {
656         ps_rc_ctxt->ai4_is_frame_scd[i] = 0;
657     }
658 
659     /*Stat file pointer passed from applicaition*/
660     ps_rc_ctxt->pf_stat_file = NULL;
661     ps_rc_ctxt->i8_num_frame_read = 0;
662 
663     return ps_rc_ctxt;
664 }
665 
666 /*###############################################*/
667 /******* END OF RC MEM INIT FUNCTIONS **********/
668 /*###############################################*/
669 
670 /*###############################################*/
671 /******* START OF RC INIT FUNCTIONS **************/
672 /*###############################################*/
673 /**
674 ******************************************************************************
675 *
676 *  @brief Initialises teh Rate control ctxt
677 *
678 *  @par   Description
679 *
680 *  @param[inout]   pv_ctxt
681 *  pointer to memory descriptors table
682 *
683 *  @param[in]      ps_run_time_src_param
684 *  Create time static parameters
685 *
686 *  @return      void
687 *
688 ******************************************************************************
689 */
ihevce_rc_init(void * pv_ctxt,ihevce_src_params_t * ps_run_time_src_param,ihevce_tgt_params_t * ps_tgt_params,rc_quant_t * ps_rc_quant,ihevce_sys_api_t * ps_sys_api,ihevce_lap_params_t * ps_lap_prms,WORD32 i4_num_frame_parallel)690 void ihevce_rc_init(
691     void *pv_ctxt,
692     ihevce_src_params_t *ps_run_time_src_param,
693     ihevce_tgt_params_t *ps_tgt_params,
694     rc_quant_t *ps_rc_quant,
695     ihevce_sys_api_t *ps_sys_api,
696     ihevce_lap_params_t *ps_lap_prms,
697     WORD32 i4_num_frame_parallel)
698 {
699     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
700     WORD32 i, i_temp, j;
701     float f_temp;
702 
703     /*run time width and height has to considered*/
704     ps_rc_ctxt->i4_frame_height = ps_tgt_params->i4_height;
705     ps_rc_ctxt->i4_frame_width = ps_tgt_params->i4_width;
706     ps_rc_ctxt->i4_field_pic = ps_run_time_src_param->i4_field_pic;
707     ps_rc_ctxt->i8_num_bit_alloc_period = 0;
708     ps_rc_ctxt->i8_new_bitrate = -1; /*-1 indicates no dynamic change in bitrate request pending*/
709     ps_rc_ctxt->i8_new_peak_bitrate = -1;
710 
711     ps_rc_ctxt->i4_is_last_frame_scan = 0;
712 
713     memset(ps_rc_ctxt->ai4_offsets, 0, 5 * sizeof(WORD32));
714 
715     ps_rc_ctxt->i4_complexity_bin = 5;
716     ps_rc_ctxt->i4_last_p_or_i_frame_gop = 0;
717     ps_rc_ctxt->i4_qp_at_I_frame_for_skip_sad = 1;
718     ps_rc_ctxt->i4_denominator_i_to_avg = 1;
719     ps_rc_ctxt->i4_fp_bit_alloc_in_sp = 0;
720 
721     ps_rc_ctxt->ai4_offsets[0] = 0;
722     ps_rc_ctxt->ai4_offsets[1] = 1;
723     ps_rc_ctxt->ai4_offsets[2] = 2;
724     ps_rc_ctxt->ai4_offsets[3] = 3;
725     ps_rc_ctxt->ai4_offsets[4] = 4;
726 
727     ps_rc_ctxt->i4_num_frames_subgop = 0;
728     ps_rc_ctxt->i8_total_acc_coarse_me_sad = 0;
729 
730     ps_rc_ctxt->i4_L0_frame_qp = 1;
731 
732     ps_rc_ctxt->i4_est_text_bits_ctr_get_qp = 0;
733     ps_rc_ctxt->i4_est_text_bits_ctr_update_qp = 0;
734 
735     /*CAllback functions need to be copied for use inside RC*/
736     ps_rc_ctxt->ps_sys_rc_api = ps_sys_api;
737 
738     f_temp = ((float)(ps_rc_quant->i2_max_qp + ps_rc_quant->i1_qp_offset - 4) / 6);
739 
740     ps_rc_quant->i2_max_qscale = (WORD16)((float)pow(2, f_temp) + 0.5) << 3;
741 
742     f_temp = ((float)(ps_rc_quant->i2_min_qp + ps_rc_quant->i1_qp_offset - 4) / 6);
743 
744     ps_rc_quant->i2_min_qscale = (WORD16)((float)pow(2, f_temp) + 0.5);
745 
746     f_temp =
747         ((float)(51 + ps_rc_quant->i1_qp_offset - 4) /
748          6);  // default MPEG2 to HEVC and HEVC to MPEG2 Qp conversion tables
749     i_temp = (WORD16)((float)pow(2, f_temp) + 0.5);
750 
751     i_temp = (i_temp << 3);  // Q3 format is mantained for accuarate calc at lower qp
752 
753     for(i = 0; i <= i_temp; i++)
754     {
755         ps_rc_quant->pi4_qscale_to_qp[i] =
756             ihevce_rc_get_scaled_hevce_qp_q3(i, ps_rc_ctxt->u1_bit_depth);
757     }
758 
759     for(i = (0 - ps_rc_quant->i1_qp_offset); i <= 51; i++)
760     {
761         ps_rc_quant->pi4_qp_to_qscale_q_factor[i + ps_rc_quant->i1_qp_offset] =
762             ihevce_rc_get_scaled_mpeg2_qp_q6(
763                 i + ps_rc_quant->i1_qp_offset, ps_rc_ctxt->u1_bit_depth);
764         ps_rc_quant->pi4_qp_to_qscale[i + ps_rc_quant->i1_qp_offset] =
765             ((ps_rc_quant->pi4_qp_to_qscale_q_factor[i + ps_rc_quant->i1_qp_offset] +
766               (1 << (QSCALE_Q_FAC_3 - 1))) >>
767              QSCALE_Q_FAC_3);
768     }
769 
770     if(ps_rc_quant->i2_min_qscale < 1)
771     {
772         ps_rc_quant->i2_min_qscale = 1;
773     }
774 
775     ps_rc_ctxt->ps_rc_quant_ctxt = ps_rc_quant;
776 
777     /*Frame rate init*/
778     ps_rc_ctxt->u4_max_frame_rate =
779         ps_run_time_src_param->i4_frm_rate_num / ps_tgt_params->i4_frm_rate_scale_factor;
780     ps_rc_ctxt->i4_top_field_first = ps_run_time_src_param->i4_topfield_first; /**/
781     /*min and max qp initialization*/
782     if(ps_rc_ctxt->i4_field_pic == 0)
783     {
784         WORD32 i4_max_qp = 0;
785 
786         if(ps_rc_ctxt->u1_bit_depth == 10)
787         {
788             i4_max_qp = MAX_HEVC_QP_10bit;
789         }
790         else if(ps_rc_ctxt->u1_bit_depth == 12)
791         {
792             i4_max_qp = MAX_HEVC_QP_12bit;
793         }
794         else
795         {
796             i4_max_qp = MAX_HEVC_QP;
797         }
798 
799         for(i = 0; i < MAX_PIC_TYPE; i++)
800         {
801             if((ps_rc_ctxt->i4_init_frame_qp_user + (2 * i) +
802                 ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset) <=
803                i4_max_qp)  //BUG_FIX related to init QP allocation
804             {
805                 ps_rc_ctxt->ai4_init_qp[i] = (ps_rc_ctxt->ps_rc_quant_ctxt->pi4_qp_to_qscale
806                                                   [(ps_rc_ctxt->i4_init_frame_qp_user + (2 * i)) +
807                                                    ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset] +
808                                               (1 << (QSCALE_Q_FAC_3 - 1))) >>
809                                              QSCALE_Q_FAC_3;
810             }
811             else
812             {
813                 ps_rc_ctxt->ai4_init_qp[i] =
814                     (ps_rc_ctxt->ps_rc_quant_ctxt->pi4_qp_to_qscale[i4_max_qp] +
815                      (1 << (QSCALE_Q_FAC_3 - 1))) >>
816                     QSCALE_Q_FAC_3;  // + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset];
817             }
818             ps_rc_ctxt->ai4_min_max_qp[i * 2] =
819                 ps_rc_ctxt->ps_rc_quant_ctxt->i2_min_qscale; /*min qp for each picture type*/
820             ps_rc_ctxt->ai4_min_max_qp[i * 2 + 1] = ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qscale >>
821                                                     QSCALE_Q_FAC_3; /*max qp for each picture type*/
822         }
823     }
824     else
825     {
826         WORD32 i4_num_pic_types = MAX_PIC_TYPE;
827         WORD32 i4_max_qp = 0;
828 
829         if(ps_rc_ctxt->u1_bit_depth == 10)
830         {
831             i4_max_qp = MAX_HEVC_QP_10bit;
832         }
833         else if(ps_rc_ctxt->u1_bit_depth == 12)
834         {
835             i4_max_qp = MAX_HEVC_QP_12bit;
836         }
837         else
838         {
839             i4_max_qp = MAX_HEVC_QP;
840         }
841 
842         i4_num_pic_types >>= 1;
843 
844         for(i = 0; i < i4_num_pic_types; i++)
845         {
846             if((ps_rc_ctxt->i4_init_frame_qp_user + (2 * i) +
847                 ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset) <= i4_max_qp)
848             {
849                 ps_rc_ctxt->ai4_init_qp[i] = (ps_rc_ctxt->ps_rc_quant_ctxt->pi4_qp_to_qscale
850                                                   [(ps_rc_ctxt->i4_init_frame_qp_user + (2 * i)) +
851                                                    ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset] +
852                                               (1 << (QSCALE_Q_FAC_3 - 1))) >>
853                                              QSCALE_Q_FAC_3;
854 
855                 if(i != 0)
856                     ps_rc_ctxt->ai4_init_qp[i + FIELD_OFFSET] = ps_rc_ctxt->ai4_init_qp[i];
857             }
858             else
859             {
860                 ps_rc_ctxt->ai4_init_qp[i] =
861                     (ps_rc_ctxt->ps_rc_quant_ctxt->pi4_qp_to_qscale[i4_max_qp] +
862                      (1 << (QSCALE_Q_FAC_3 - 1))) >>
863                     QSCALE_Q_FAC_3;  // + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset];
864 
865                 if(i != 0)
866                     ps_rc_ctxt->ai4_init_qp[i + FIELD_OFFSET] = ps_rc_ctxt->ai4_init_qp[i];
867             }
868             ps_rc_ctxt->ai4_min_max_qp[i * 2] =
869                 ps_rc_ctxt->ps_rc_quant_ctxt->i2_min_qscale; /*min qp for each picture type*/
870             ps_rc_ctxt->ai4_min_max_qp[i * 2 + 1] = ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qscale >>
871                                                     QSCALE_Q_FAC_3; /*max qp for each picture type*/
872             if(i != 0)
873             {
874                 ps_rc_ctxt->ai4_min_max_qp[(i + FIELD_OFFSET) * 2] =
875                     ps_rc_ctxt->ps_rc_quant_ctxt->i2_min_qscale; /*min qp for each picture type*/
876                 ps_rc_ctxt->ai4_min_max_qp[(i + FIELD_OFFSET) * 2 + 1] =
877                     ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qscale; /*max qp for each picture type*/
878             }
879         }
880     }
881 
882     for(j = 0; i < MAX_NUM_ENC_LOOP_PARALLEL; i++)
883     {
884         /*initialise the coeffs to 1 in case lap is not used */
885         for(i = 0; i < MAX_PIC_TYPE; i++)
886         {
887             ps_rc_ctxt->af_sum_weigh[j][i][0] = 1.0;
888             ps_rc_ctxt->af_sum_weigh[j][i][1] = 0.0;
889             ps_rc_ctxt->af_sum_weigh[j][i][2] = 0.0;
890         }
891     }
892 
893     ps_rc_ctxt->i4_num_frame_parallel = i4_num_frame_parallel;  //ELP_RC
894     i4_num_frame_parallel = (i4_num_frame_parallel > 1) ? i4_num_frame_parallel : 0;
895 
896     if(ps_rc_ctxt->i4_num_frame_parallel > 1)
897     {
898         ps_rc_ctxt->i4_pre_enc_rc_delay = MAX_PRE_ENC_RC_DELAY;
899     }
900     else
901     {
902         ps_rc_ctxt->i4_pre_enc_rc_delay = MIN_PRE_ENC_RC_DELAY;
903     }
904     /*Bitrate and resolutioon based scene cut min qp*/
905     {
906         /*The min qp for scene cut frame is chosen based on bitrate*/
907         float i4_bpp = ((float)ps_rc_ctxt->u4_avg_bit_rate / ps_rc_ctxt->u4_max_frame_rate) * 1000 /
908                        (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width);
909         if(ps_rc_ctxt->u4_intra_frame_interval == 1)
910         {
911             /*Ultra High resolution)*/
912             if((ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) > 5000000)
913             {
914                 if(i4_bpp > 0.24)
915                 {
916                     ps_rc_ctxt->i4_min_scd_hevc_qp = SCD_MIN_HEVC_QP_VHBR;
917                 }
918                 else if(i4_bpp > 0.16)
919                     ps_rc_ctxt->i4_min_scd_hevc_qp =
920                         SCD_MIN_HEVC_QP_HBR; /*corresponds to bitrate greater than 40mbps for 4k 30p*/
921                 else
922                     ps_rc_ctxt->i4_min_scd_hevc_qp = SCD_MIN_HEVC_QP;
923             }
924             else
925             {
926                 if(i4_bpp > 0.32)
927                 {
928                     ps_rc_ctxt->i4_min_scd_hevc_qp = SCD_MIN_HEVC_QP_VHBR;
929                 }
930                 else if(i4_bpp > 0.24)
931                     ps_rc_ctxt->i4_min_scd_hevc_qp =
932                         SCD_MIN_HEVC_QP_HBR; /*corresponds to bitrate greater than 15mbps for 1080 30p*/
933                 else
934                     ps_rc_ctxt->i4_min_scd_hevc_qp = SCD_MIN_HEVC_QP;
935             }
936         }
937         else
938         {
939             /*Ultra High resolution)*/
940             if((ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) > 5000000)
941             {
942                 if(i4_bpp > 0.16)
943                 {
944                     ps_rc_ctxt->i4_min_scd_hevc_qp = SCD_MIN_HEVC_QP_VHBR;
945                 }
946                 else if(i4_bpp > 0.08)
947                     ps_rc_ctxt->i4_min_scd_hevc_qp =
948                         SCD_MIN_HEVC_QP_HBR; /*corresponds to bitrate greater than 20mbps for 4k 30p*/
949                 else
950                     ps_rc_ctxt->i4_min_scd_hevc_qp = SCD_MIN_HEVC_QP;
951             }
952             else
953             {
954                 /*Resolution lesser than full HD (including )*/
955                 if(i4_bpp > 0.24)
956                 {
957                     ps_rc_ctxt->i4_min_scd_hevc_qp = SCD_MIN_HEVC_QP_VHBR;
958                 }
959                 else if(i4_bpp > 0.16)
960                     ps_rc_ctxt->i4_min_scd_hevc_qp =
961                         SCD_MIN_HEVC_QP_HBR; /*corresponds to bitrate greater than 10mbps for 1080 30p*/
962                 else
963                     ps_rc_ctxt->i4_min_scd_hevc_qp = SCD_MIN_HEVC_QP;
964             }
965         }
966     }
967 
968     initialise_rate_control(
969         ps_rc_ctxt->rc_hdl,
970         ps_rc_ctxt->e_rate_control_type,
971         ps_rc_ctxt->u1_is_mb_level_rc_on,  //0,/*disabling MB level RC*/
972         ps_rc_ctxt->u4_avg_bit_rate,
973         ps_rc_ctxt->au4_peak_bit_rate,
974         ps_rc_ctxt->u4_min_bit_rate,
975         ps_rc_ctxt->u4_max_frame_rate,
976         ps_rc_ctxt->u4_max_delay, /*max delay in milli seconds based on buffer size*/
977         ps_rc_ctxt->u4_intra_frame_interval,
978         ps_rc_ctxt->u4_idr_period,
979         ps_rc_ctxt->ai4_init_qp,
980         ps_rc_ctxt->u4_max_vbv_buff_size,
981         ps_rc_ctxt->i4_max_inter_frm_int,
982         ps_rc_ctxt->i4_is_gop_closed,
983         ps_rc_ctxt->ai4_min_max_qp, /*min and max qp to be used for each of picture type*/
984         ps_rc_ctxt->i4_use_est_intra_sad,
985         ps_rc_ctxt->u4_src_ticks,
986         ps_rc_ctxt->u4_tgt_ticks,
987         ps_rc_ctxt->i4_frame_height, /*pels in frame considering 420 semi planar format*/
988         ps_rc_ctxt->i4_frame_width,
989         ps_rc_ctxt->i4_num_active_pic_type,
990         ps_rc_ctxt->i4_field_pic,
991         ps_rc_ctxt->i4_quality_preset,
992         ps_rc_ctxt->i4_num_frame_in_lap_window,
993         ps_rc_ctxt->i4_initial_decoder_delay_frames,
994         ps_rc_ctxt->f_vbr_max_peak_sustain_dur,
995         ps_rc_ctxt->i8_num_frms_to_encode,
996         ps_rc_ctxt->i4_min_scd_hevc_qp,
997         ps_rc_ctxt->u1_bit_depth,
998         ps_rc_ctxt->pf_stat_file,
999         ps_rc_ctxt->i4_rc_pass,
1000         ps_rc_ctxt->pv_gop_stat,
1001         ps_rc_ctxt->i8_num_gop_mem_alloc,
1002         ps_rc_ctxt->i4_is_infinite_gop,
1003         sizeof(ihevce_lap_output_params_t),
1004         sizeof(rc_lap_out_params_t),
1005         (void *)ps_sys_api,
1006         ps_rc_ctxt->i4_fp_bit_alloc_in_sp,
1007         i4_num_frame_parallel,
1008         ps_rc_ctxt->i4_capped_vbr_flag);
1009 
1010     //ps_rc_ctxt->i4_init_vbv_fullness = 500000;
1011     rc_init_set_ebf(ps_rc_ctxt->rc_hdl, ps_rc_ctxt->i4_init_vbv_fullness);
1012 
1013     /*get init qp based on ebf for rate control*/
1014     if(ps_rc_ctxt->e_rate_control_type != CONST_QP)
1015     {
1016         WORD32 I_frame_qp, I_frame_mpeg2_qp;
1017         /*assume moderate fsim*/
1018         WORD32 i4_fsim_global = MODERATE_FSIM_VALUE;
1019         I_frame_mpeg2_qp = rc_get_bpp_based_scene_cut_qp(
1020             ps_rc_ctxt->rc_hdl,
1021             I_PIC,
1022             ((3 * ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) >> 1),
1023             i4_fsim_global,
1024             ps_rc_ctxt->af_sum_weigh[0],
1025             1);
1026 
1027         I_frame_qp = ihevce_rc_get_scaled_hevc_qp_from_qs_q3(
1028             I_frame_mpeg2_qp << QSCALE_Q_FAC_3, ps_rc_ctxt->ps_rc_quant_ctxt);
1029 
1030         I_frame_qp = I_frame_qp + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset;
1031 
1032         if(I_frame_qp > 44)
1033             I_frame_qp = 44;
1034 
1035         ps_rc_ctxt->ai4_init_pre_enc_qp[I_PIC] = I_frame_qp;
1036         ps_rc_ctxt->ai4_init_pre_enc_qp[P_PIC] = I_frame_qp + 1;
1037         ps_rc_ctxt->ai4_init_pre_enc_qp[B_PIC] = I_frame_qp + 2;
1038         ps_rc_ctxt->ai4_init_pre_enc_qp[B1_PIC] = I_frame_qp + 3;
1039         ps_rc_ctxt->ai4_init_pre_enc_qp[B2_PIC] = I_frame_qp + 4;
1040         /*Bottom fields*/
1041         ps_rc_ctxt->ai4_init_pre_enc_qp[P1_PIC] = I_frame_qp + 1;
1042         ps_rc_ctxt->ai4_init_pre_enc_qp[BB_PIC] = I_frame_qp + 2;
1043         ps_rc_ctxt->ai4_init_pre_enc_qp[B11_PIC] = I_frame_qp + 3;
1044         ps_rc_ctxt->ai4_init_pre_enc_qp[B22_PIC] = I_frame_qp + 4;
1045 
1046         ps_rc_ctxt->i4_pre_enc_qp_read_index = 0;
1047         ps_rc_ctxt->i4_pre_enc_qp_write_index = ps_rc_ctxt->i4_pre_enc_rc_delay - 1;
1048         for(i = 0; i < ps_rc_ctxt->i4_pre_enc_rc_delay; i++)
1049         {
1050             /*initialize it to -1 to indicate it as not produced*/
1051             ps_rc_ctxt->as_pre_enc_qp_queue[i].i4_is_qp_valid = -1;
1052         }
1053         for(i = 0; i < (ps_rc_ctxt->i4_pre_enc_qp_write_index); i++)
1054         {
1055             WORD32 j;
1056             ps_rc_ctxt->as_pre_enc_qp_queue[i].i4_is_qp_valid = 1;
1057             for(j = 0; j < MAX_PIC_TYPE; j++)
1058             {
1059                 ps_rc_ctxt->as_pre_enc_qp_queue[i].ai4_quant[j] =
1060                     ps_rc_ctxt->ai4_init_pre_enc_qp[j];
1061                 ps_rc_ctxt->as_pre_enc_qp_queue[i].i4_scd_qp =
1062                     ps_rc_ctxt->ai4_init_pre_enc_qp[I_PIC];
1063             }
1064         }
1065 
1066         ps_rc_ctxt->i4_use_qp_offset_pre_enc = 1;
1067         ps_rc_ctxt->i4_num_frms_from_reset = 0;
1068         /* SGI & Enc Loop Parallelism related changes*/
1069         ps_rc_ctxt->u4_prev_scene_num = 0;
1070         //ps_rc_ctxt->i4_use_init_qp_for_pre_enc = 0;
1071         for(j = 0; j < MAX_NON_REF_B_PICS_IN_QUEUE_SGI; j++)
1072         {
1073             ps_rc_ctxt->au4_prev_scene_num_multi_scene[j] = 0x3FFFFFFF;
1074             for(i = 0; i < MAX_PIC_TYPE; i++)
1075             {
1076                 ps_rc_ctxt->ai4_qp_for_previous_scene_multi_scene[j][i] =
1077                     ps_rc_ctxt->ai4_init_pre_enc_qp[i];
1078             }
1079         }
1080 
1081         /* SGI & Enc Loop Parallelism related changes*/
1082         for(i = 0; i < MAX_PIC_TYPE; i++)
1083         {
1084             ps_rc_ctxt->ai4_qp_for_previous_scene[i] = ps_rc_ctxt->ai4_init_pre_enc_qp[i];
1085         }
1086     }
1087     else
1088     {
1089         for(i = 0; i < MAX_PIC_TYPE; i++)
1090         {
1091             ps_rc_ctxt->ai4_init_pre_enc_qp[i] = ps_rc_ctxt->i4_init_frame_qp_user;
1092             ps_rc_ctxt->ai4_qp_for_previous_scene[i] = ps_rc_ctxt->i4_init_frame_qp_user;
1093         }
1094     }
1095 }
1096 
1097 /**
1098 ******************************************************************************
1099 *
1100 *  @brief Populate common params from lap_out structure to rc_lap_out structure
1101 *         Also the init of some rc_lap_out params done here
1102 *  @par   Description
1103 *
1104 *  @param[in]   ps_lap_out
1105 *  pointer to lap_out structure
1106 *
1107 *  @param[out]      ps_rc_lap_out
1108 *  pointer to rc_lap_out structure
1109 *
1110 *  @return      void
1111 *
1112 ******************************************************************************
1113 */
1114 
ihevce_rc_populate_common_params(ihevce_lap_output_params_t * ps_lap_out,rc_lap_out_params_t * ps_rc_lap_out)1115 void ihevce_rc_populate_common_params(
1116     ihevce_lap_output_params_t *ps_lap_out, rc_lap_out_params_t *ps_rc_lap_out)
1117 {
1118     /* Update common params */
1119 
1120     ps_rc_lap_out->i4_rc_pic_type = ps_lap_out->i4_pic_type;
1121     ps_rc_lap_out->i4_rc_poc = ps_lap_out->i4_poc;
1122     ps_rc_lap_out->i4_rc_temporal_lyr_id = ps_lap_out->i4_temporal_lyr_id;
1123     ps_rc_lap_out->i4_rc_is_ref_pic = ps_lap_out->i4_is_ref_pic;
1124     ps_rc_lap_out->i4_rc_scene_type = ps_lap_out->i4_scene_type;
1125     ps_rc_lap_out->u4_rc_scene_num = ps_lap_out->u4_scene_num;
1126     ps_rc_lap_out->i4_rc_display_num = ps_lap_out->i4_display_num;
1127     ps_rc_lap_out->i4_rc_quality_preset = ps_lap_out->i4_quality_preset;
1128     ps_rc_lap_out->i4_rc_first_field = ps_lap_out->i4_first_field;
1129 
1130     /*params populated in LAP-2*/
1131     ps_rc_lap_out->i8_frame_acc_coarse_me_cost = -1;
1132     memset(ps_rc_lap_out->ai8_frame_acc_coarse_me_sad, -1, sizeof(WORD32) * 52);
1133 
1134     ps_rc_lap_out->i8_pre_intra_satd = -1;
1135 
1136     ps_rc_lap_out->i8_raw_pre_intra_sad = -1;
1137 
1138     ps_rc_lap_out->i8_raw_l1_coarse_me_sad = -1;
1139 
1140     ps_rc_lap_out->i4_is_rc_model_needs_to_be_updated = 1;
1141     /* SGI & Enc Loop Parallelism related changes*/
1142     ps_rc_lap_out->i4_ignore_for_rc_update = 0;
1143 
1144     /*For 1 pass HQ I frames*/
1145 
1146     ps_rc_lap_out->i4_complexity_bin = 5;
1147     {
1148         WORD32 ai4_offsets[5] = { 0, 1, 2, 3, 4 };
1149         memmove(ps_rc_lap_out->ai4_offsets, ai4_offsets, sizeof(WORD32) * 5);
1150         ps_rc_lap_out->i4_offsets_set_flag = -1;
1151     }
1152 
1153     ps_rc_lap_out->i4_L1_qp = -1;
1154     ps_rc_lap_out->i4_L0_qp = -1;
1155 }
1156 
1157 /*###############################################*/
1158 /******* END OF RC INIT FUNCTIONS **************/
1159 /*###############################################*/
1160 
1161 /*#########################################################*/
1162 /******* START OF PRE-ENC QP QUERY FUNCTIONS **************/
1163 /*#######################################################*/
1164 
1165 /**
1166 ******************************************************************************
1167 *
1168 *  @name  ihevce_rc_get_bpp_based_frame_qp
1169 *
1170 *  @par   Description
1171 *
1172 *  @param[in]   ps_rc_ctxt  - pointer to rc context
1173 *               ps_rc_lap_out
1174 *  @return      frame qp
1175 *
1176 ******************************************************************************
1177 */
ihevce_rc_get_bpp_based_frame_qp(void * pv_rc_ctxt,rc_lap_out_params_t * ps_rc_lap_out)1178 WORD32 ihevce_rc_get_bpp_based_frame_qp(void *pv_rc_ctxt, rc_lap_out_params_t *ps_rc_lap_out)
1179 {
1180     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
1181     WORD32 i4_frame_qs_q3, i4_hevc_frame_qp, i;
1182     frame_info_t *ps_frame_info;
1183     picture_type_e rc_pic_type = ihevce_rc_conv_pic_type(
1184         (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out->i4_rc_pic_type,
1185         ps_rc_ctxt->i4_field_pic,
1186         ps_rc_lap_out->i4_rc_temporal_lyr_id,
1187         ps_rc_lap_out->i4_is_bottom_field,
1188         ps_rc_ctxt->i4_top_field_first);
1189     /*initialise the coeffs to 1 in case lap is not used */
1190     for(i = 0; i < MAX_PIC_TYPE; i++)
1191     {
1192         ps_rc_ctxt->af_sum_weigh[0][i][0] = 1.0;
1193         ps_rc_ctxt->af_sum_weigh[0][i][1] = 0.0;
1194         ps_rc_ctxt->af_sum_weigh[0][i][2] = 0.0;
1195     }
1196     {
1197         /*scene cut handling during pre-enc stage*/
1198         /*assume lap fsim as 117. not used since ratio is direclt sent*/
1199         if(ps_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_SCENE_CUT)
1200         {
1201             for(i = 0; i < MAX_PIC_TYPE; i++)
1202             {
1203                 ps_rc_ctxt->ai8_prev_frame_est_L0_satd[i] = -1;
1204                 ps_rc_ctxt->ai8_prev_frame_hme_sad[i] = -1;
1205                 ps_rc_ctxt->ai8_prev_frame_pre_intra_sad[i] = -1;
1206             }
1207             ps_rc_ctxt->i4_is_est_L0_intra_sad_available = 0;
1208         }
1209 
1210         if(ps_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_SCENE_CUT ||
1211            !ps_rc_ctxt->i4_is_est_L0_intra_sad_available)
1212         {
1213             /*compute bpp based qp if current frame is scene cut or data is not sufficient*/
1214             i4_frame_qs_q3 = rc_get_bpp_based_scene_cut_qp(
1215                 ps_rc_ctxt->rc_hdl,
1216                 I_PIC,
1217                 ((3 * ps_rc_lap_out->i4_num_pels_in_frame_considered) >> 1),
1218                 117,
1219                 ps_rc_ctxt->af_sum_weigh[0],
1220                 0);
1221             i4_frame_qs_q3 = i4_frame_qs_q3 << QSCALE_Q_FAC_3;
1222         }
1223         else
1224         {
1225             /*using previous one sub-gop data calculate i to rest ratio and qp assuming it is I frame*/
1226             WORD32 i4_num_b, i, ai4_pic_dist[MAX_PIC_TYPE], index, i4_total_bits;
1227             LWORD64 i8_average_pre_intra_sad = 0, i8_average_est_l0_satd_by_act = 0;
1228             double lambda_modifier[MAX_PIC_TYPE], complexity[MAX_PIC_TYPE], den = 0.0f,
1229                                                                             i_to_rest_bit_ratio;
1230             WORD32 i4_curr_bits_estimated = 0;
1231 
1232             for(i = 0; i < MAX_PIC_TYPE; i++)
1233             {
1234                 complexity[i] = 0;
1235                 lambda_modifier[i] = 0;
1236                 ai4_pic_dist[i] = 0;
1237             }
1238 
1239             index = ihevce_get_offline_index(
1240                 ps_rc_ctxt, ps_rc_lap_out->i4_num_pels_in_frame_considered);
1241             if(ps_rc_ctxt->i4_max_temporal_lyr)
1242             {
1243                 i4_num_b = ((WORD32)pow((float)2, ps_rc_ctxt->i4_max_temporal_lyr)) - 1;
1244             }
1245             else
1246             {
1247                 i4_num_b = 0;
1248             }
1249 
1250             lambda_modifier[I_PIC] =
1251                 ihevce_get_frame_lambda_modifier((WORD8)I_PIC, 0, 1, 1, i4_num_b);
1252             lambda_modifier[P_PIC] =
1253                 ihevce_get_frame_lambda_modifier((WORD8)P_PIC, 0, 1, 1, i4_num_b) *
1254                 pow((float)1.125, 1);
1255             lambda_modifier[B_PIC] =
1256                 ihevce_get_frame_lambda_modifier(
1257                     (WORD8)B_PIC, 1, (ps_rc_ctxt->i4_max_temporal_lyr > 1), 1, i4_num_b) *
1258                 pow((float)1.125, 2);
1259             lambda_modifier[B1_PIC] =
1260                 ihevce_get_frame_lambda_modifier(
1261                     (WORD8)B1_PIC, 2, 1, (ps_rc_ctxt->i4_max_temporal_lyr > 2), i4_num_b) *
1262                 pow((float)1.125, 3);
1263             lambda_modifier[B2_PIC] =
1264                 ihevce_get_frame_lambda_modifier((WORD8)B2_PIC, 3, 1, 0, i4_num_b) *
1265                 pow((float)1.125, 4);
1266 
1267             /*consider average of one sub-gop for intra sad*/
1268 
1269             if(ps_rc_ctxt->i4_quality_preset == IHEVCE_QUALITY_P6)
1270             {
1271                 for(i = 0; i < 2; i++)
1272                 {
1273                     i8_average_pre_intra_sad += ps_rc_ctxt->ai8_prev_frame_pre_intra_sad[i];
1274                     i8_average_est_l0_satd_by_act += ps_rc_ctxt->ai8_prev_frame_est_L0_satd[i];
1275                     if(ps_rc_ctxt->i4_field_pic == 1 && i != 0)
1276                     {
1277                         i8_average_pre_intra_sad +=
1278                             ps_rc_ctxt->ai8_prev_frame_pre_intra_sad[i + FIELD_OFFSET];
1279                         i8_average_est_l0_satd_by_act +=
1280                             ps_rc_ctxt->ai8_prev_frame_est_L0_satd[i + FIELD_OFFSET];
1281                     }
1282                 }
1283                 if(ps_rc_ctxt->i4_field_pic == 1)
1284                 {
1285                     i8_average_pre_intra_sad /= 3;
1286                     i8_average_est_l0_satd_by_act /= 3;
1287                 }
1288                 else
1289                 {
1290                     i8_average_pre_intra_sad <<= 1;
1291                     i8_average_est_l0_satd_by_act <<= 1;
1292                 }
1293             }
1294             else
1295             {
1296                 for(i = 0; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
1297                 {
1298                     i8_average_pre_intra_sad += ps_rc_ctxt->ai8_prev_frame_pre_intra_sad[i];
1299                     i8_average_est_l0_satd_by_act += ps_rc_ctxt->ai8_prev_frame_est_L0_satd[i];
1300                     if(ps_rc_ctxt->i4_field_pic == 1 && i != 0)
1301                     {
1302                         i8_average_pre_intra_sad +=
1303                             ps_rc_ctxt->ai8_prev_frame_pre_intra_sad[i + FIELD_OFFSET];
1304                         i8_average_est_l0_satd_by_act +=
1305                             ps_rc_ctxt->ai8_prev_frame_est_L0_satd[i + FIELD_OFFSET];
1306                     }
1307                 }
1308                 if(ps_rc_ctxt->i4_field_pic == 1)
1309                 {
1310                     i8_average_pre_intra_sad /= ((i << 1) - 1);
1311                     i8_average_est_l0_satd_by_act /= ((i << 1) - 1);
1312                 }
1313                 else
1314                 {
1315                     i8_average_pre_intra_sad /= i;
1316                     i8_average_est_l0_satd_by_act /= i;
1317                 }
1318             }
1319 
1320             /*no lambda modifier is considered for I pic as other lambda are scaled according to I frame lambda*/
1321             complexity[I_PIC] = (double)i8_average_pre_intra_sad;
1322 
1323             for(i = 1; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
1324             {
1325 #if !USE_SQRT
1326                 complexity[i] = ps_rc_ctxt->ai8_prev_frame_hme_sad[i] / pow(1.125, i);
1327 
1328                 if(ps_rc_ctxt->i4_field_pic == 1)
1329                 {
1330                     complexity[i + FIELD_OFFSET] =
1331                         ps_rc_ctxt->ai8_prev_frame_hme_sad[i + FIELD_OFFSET] / pow(1.125, i);
1332                 }
1333 #else
1334                 complexity[i] = ps_rc_ctxt->ai8_prev_frame_hme_sad[i] /
1335                                 (sqrt(lambda_modifier[i] / lambda_modifier[I_PIC]) * pow(1.125, i));
1336 #endif
1337             }
1338             /*get picture type distribution in LAP*/
1339             rc_get_pic_distribution(ps_rc_ctxt->rc_hdl, &ai4_pic_dist[0]);
1340 
1341             for(i = 0; i < MAX_PIC_TYPE; i++)
1342             {
1343                 den += complexity[i] * ai4_pic_dist[i];
1344             }
1345             /*subtract I frame complexity to get I to rest ratio*/
1346             {
1347                 WORD32 num_inter_pic = 0;
1348                 for(i = 1; i < MAX_PIC_TYPE; i++)
1349                 {
1350                     num_inter_pic += ai4_pic_dist[i];
1351                 }
1352                 if(num_inter_pic > 0)
1353                     den = (den - (complexity[I_PIC] * ai4_pic_dist[I_PIC])) / num_inter_pic;
1354                 else
1355                     den = complexity[I_PIC];
1356             }
1357 
1358             if(den > 0)
1359                 i_to_rest_bit_ratio = (float)((complexity[I_PIC]) / den);
1360             else
1361                 i_to_rest_bit_ratio = 15;
1362 
1363             /*get qp for scene cut frame based on offline data*/
1364             i4_frame_qs_q3 = rc_get_qp_for_scd_frame(
1365                 ps_rc_ctxt->rc_hdl,
1366                 I_PIC,
1367                 i8_average_est_l0_satd_by_act,
1368                 ps_rc_lap_out->i4_num_pels_in_frame_considered,
1369                 -1,
1370                 MODERATE_FSIM_VALUE,
1371                 (void *)&g_offline_i_model_coeff[index][0],
1372                 (float)i_to_rest_bit_ratio,
1373                 0,
1374                 ps_rc_ctxt->af_sum_weigh[0],
1375                 ps_rc_lap_out->ps_frame_info,
1376                 ps_rc_ctxt->i4_rc_pass,
1377                 0,
1378                 0,
1379                 0,
1380                 &i4_total_bits,
1381                 &i4_curr_bits_estimated,
1382                 ps_rc_lap_out->i4_use_offline_model_2pass,
1383                 0,
1384                 0,
1385                 -1,
1386                 NULL);
1387         }
1388 
1389         i4_hevc_frame_qp =
1390             ihevce_rc_get_scaled_hevc_qp_from_qs_q3(i4_frame_qs_q3, ps_rc_ctxt->ps_rc_quant_ctxt);
1391 
1392         i4_hevc_frame_qp = i4_hevc_frame_qp + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset;
1393 
1394         if(i4_hevc_frame_qp > ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qp)
1395             i4_hevc_frame_qp = ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qp;
1396 
1397         /*offset depending on current picture type*/
1398         if(rc_pic_type != I_PIC)
1399             i4_hevc_frame_qp += ps_rc_lap_out->i4_rc_temporal_lyr_id + 1;
1400         /*clip min and max qp to be within range*/
1401         i4_hevc_frame_qp = ihevce_clip_min_max_qp(
1402             ps_rc_ctxt, i4_hevc_frame_qp, rc_pic_type, ps_rc_lap_out->i4_rc_temporal_lyr_id);
1403 
1404         ps_rc_ctxt->ai4_qp_for_previous_scene_pre_enc[rc_pic_type] = i4_hevc_frame_qp;
1405         ps_rc_ctxt->au4_prev_scene_num_pre_enc[rc_pic_type] = ps_rc_lap_out->u4_rc_scene_num;
1406     }
1407 
1408     return i4_hevc_frame_qp;
1409 }
1410 /**
1411 ******************************************************************************
1412 *
1413 *  @name  ihevce_rc_get_pre_enc_pic_quant
1414 *
1415 *  @par   Description - Called from ihevce_rc_cal_pre_enc_qp. updates frame qp
1416 *                       which will be used by next frame of same pic type in
1417 *                       pre-enc stage
1418 *
1419 *  @param[in]   ps_rc_ctxt  - pointer to rc context
1420 *  @return      void
1421 *
1422 ******************************************************************************
1423 */
1424 WORD32
ihevce_rc_get_pre_enc_pic_quant(void * pv_ctxt,picture_type_e rc_pic_type,WORD32 * pi4_scd_qp)1425     ihevce_rc_get_pre_enc_pic_quant(void *pv_ctxt, picture_type_e rc_pic_type, WORD32 *pi4_scd_qp)
1426 {
1427     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
1428     WORD32 i4_frame_qp, i4_frame_qp_q6, i4_hevc_frame_qp = -1;
1429     WORD32 i4_max_frame_bits = (1 << 30);
1430     WORD32 i4_temporal_layer_id, i4_is_bottom_field, i4_cur_est_texture_bits;
1431 
1432     ihevce_rc_get_pic_param(rc_pic_type, &i4_temporal_layer_id, &i4_is_bottom_field);
1433 
1434     {
1435         WORD32 is_scd_ref_frame = 0, i4_num_scd_in_lap_window = 0, num_frames_b4_scd = 0;
1436 
1437         /*treat even first frame as scd frame*/
1438         if(!ps_rc_ctxt->i4_is_first_frame_encoded)
1439         {
1440             is_scd_ref_frame = 1;
1441         }
1442 
1443         {
1444             /*Only I frames are considered as scd pic during pre-enc*/
1445             is_scd_ref_frame &= (rc_pic_type == I_PIC);
1446         }
1447 
1448         rc_set_num_scd_in_lap_window(
1449             ps_rc_ctxt->rc_hdl, i4_num_scd_in_lap_window, num_frames_b4_scd);
1450 
1451         /** Pre-enc thread as of now SCD handling is not present */
1452         //if(!(is_scd_ref_frame || ps_rc_ctxt->i4_is_pause_to_resume) || call_type == PRE_ENC_GET_QP)
1453         {
1454             WORD32 i4_is_first_frame_coded;
1455             /*Once first frame has been encoded use prev frame intra satd and cur frame satd to alter est intra sad for cur frame*/
1456             i4_is_first_frame_coded = is_first_frame_coded(ps_rc_ctxt->rc_hdl);
1457             {
1458                 int i;
1459                 WORD32 i4_curr_bits_estimated, i4_is_model_valid;
1460                 /*initialise the coeffs to 1 and 0in case lap is not used */
1461                 for(i = 0; i < MAX_PIC_TYPE; i++)
1462                 {
1463                     ps_rc_ctxt->af_sum_weigh[0][i][0] = 1.0;
1464                     ps_rc_ctxt->af_sum_weigh[0][i][1] = 0.0;
1465                 }
1466 
1467                 i4_frame_qp_q6 = get_frame_level_qp(
1468                     ps_rc_ctxt->rc_hdl,
1469                     rc_pic_type,
1470                     i4_max_frame_bits,
1471                     &i4_cur_est_texture_bits,  //this value is returned by rc
1472                     ps_rc_ctxt->af_sum_weigh[0],
1473                     0,
1474                     8.0f,
1475                     NULL,
1476                     ps_rc_ctxt->i4_complexity_bin,
1477                     ps_rc_ctxt->i4_scene_num_latest, /*no pause resume concept*/
1478                     &i4_curr_bits_estimated,
1479                     &i4_is_model_valid,
1480                     NULL,
1481                     NULL,
1482                     NULL,
1483                     NULL,
1484                     NULL,
1485                     NULL);
1486 
1487                 /** The usage of global table will truncate the input given as qp format and hence will not return very low qp values desirable at very
1488                 low bitrate. Hence on the fly calculation is enabled*/
1489                 i4_hevc_frame_qp =
1490                     ihevce_rc_get_scaled_hevce_qp_q6(i4_frame_qp_q6, ps_rc_ctxt->u1_bit_depth);
1491 
1492                 if(rc_pic_type == I_PIC)
1493                 {
1494                     /*scene cut handling during pre-enc stage*/
1495                     i4_frame_qp = rc_get_bpp_based_scene_cut_qp(
1496                         ps_rc_ctxt->rc_hdl,
1497                         rc_pic_type,
1498                         ((3 * ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) >> 1),
1499                         ps_rc_ctxt->ai4_lap_f_sim[0],
1500                         ps_rc_ctxt->af_sum_weigh[0],
1501                         0);
1502 
1503                     *pi4_scd_qp = ihevce_rc_get_scaled_hevc_qp_from_qs_q3(
1504                         i4_frame_qp << QSCALE_Q_FAC_3, ps_rc_ctxt->ps_rc_quant_ctxt);
1505                     *pi4_scd_qp = *pi4_scd_qp + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset;
1506                     if(*pi4_scd_qp > ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qp)
1507                         *pi4_scd_qp = ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qp;
1508                 }
1509                 else
1510                 {
1511                     /*scene cut qp is only valid when queried for I_PIC*/
1512                     *pi4_scd_qp = i4_hevc_frame_qp;
1513                 }
1514             }
1515         }
1516 
1517         ASSERT(i4_hevc_frame_qp >= (-ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset));
1518 
1519         /*constraint qp swing based on neighbour frames*/
1520         if(is_first_frame_coded(ps_rc_ctxt->rc_hdl))
1521         {
1522             if(ps_rc_ctxt->i4_field_pic == 0)
1523             {
1524                 if((rc_pic_type != I_PIC && rc_pic_type != P_PIC) &&
1525                    i4_hevc_frame_qp >
1526                        ps_rc_ctxt->ai4_prev_pic_hevc_qp[ps_rc_ctxt->i4_scene_num_latest]
1527                                                        [rc_pic_type - 1] +
1528                            3)
1529                 {
1530                     /*allow max of +3 compared to previous frame*/
1531                     i4_hevc_frame_qp =
1532                         ps_rc_ctxt->ai4_prev_pic_hevc_qp[ps_rc_ctxt->i4_scene_num_latest]
1533                                                         [rc_pic_type - 1] +
1534                         3;
1535                 }
1536                 if((rc_pic_type != I_PIC && rc_pic_type != P_PIC) &&
1537                    i4_hevc_frame_qp <
1538                        (ps_rc_ctxt->ai4_prev_pic_hevc_qp[ps_rc_ctxt->i4_scene_num_latest]
1539                                                         [rc_pic_type - 1]))
1540                 {
1541                     i4_hevc_frame_qp =
1542                         ps_rc_ctxt->ai4_prev_pic_hevc_qp[ps_rc_ctxt->i4_scene_num_latest]
1543                                                         [rc_pic_type - 1];
1544                 }
1545 
1546                 /** Force non-ref B pic qp to be ref_B_PIC_qp - 1. This is not valid for when max teporla later is less than 2*/
1547                 if(i4_temporal_layer_id == ps_rc_ctxt->i4_max_temporal_lyr &&
1548                    ps_rc_ctxt->i4_max_temporal_lyr > 1)
1549                 {
1550                     i4_hevc_frame_qp =
1551                         ps_rc_ctxt->ai4_prev_pic_hevc_qp[ps_rc_ctxt->i4_scene_num_latest]
1552                                                         [rc_pic_type - 1] +
1553                         1;
1554                 }
1555             }
1556             else /*for field case*/
1557             {
1558                 if(i4_temporal_layer_id >= 1)
1559                 {
1560                     /*To make the comparison of qp with the top field's of previous layer tempor layer id matches with the pic type. */
1561                     if(i4_hevc_frame_qp >
1562                        ps_rc_ctxt->ai4_prev_pic_hevc_qp[ps_rc_ctxt->i4_scene_num_latest]
1563                                                        [i4_temporal_layer_id] +
1564                            3)
1565                     {
1566                         /*allow max of +3 compared to previous frame*/
1567                         i4_hevc_frame_qp =
1568                             ps_rc_ctxt->ai4_prev_pic_hevc_qp[ps_rc_ctxt->i4_scene_num_latest]
1569                                                             [i4_temporal_layer_id] +
1570                             3;
1571                     }
1572                     if(i4_hevc_frame_qp <
1573                        ps_rc_ctxt->ai4_prev_pic_hevc_qp[ps_rc_ctxt->i4_scene_num_latest]
1574                                                        [i4_temporal_layer_id])
1575                     {
1576                         i4_hevc_frame_qp =
1577                             ps_rc_ctxt->ai4_prev_pic_hevc_qp[ps_rc_ctxt->i4_scene_num_latest]
1578                                                             [i4_temporal_layer_id];
1579                     }
1580                     /** Force non-ref B pic qp to be ref_B_PIC_qp - 1. This is not valid for when max teporla later is less than 2*/
1581                     if(i4_temporal_layer_id == ps_rc_ctxt->i4_max_temporal_lyr &&
1582                        ps_rc_ctxt->i4_max_temporal_lyr > 1)
1583                     {
1584                         i4_hevc_frame_qp =
1585                             ps_rc_ctxt->ai4_prev_pic_hevc_qp[ps_rc_ctxt->i4_scene_num_latest]
1586                                                             [i4_temporal_layer_id] +
1587                             1;
1588                     }
1589                 }
1590             }
1591         }
1592 
1593 #if USE_USER_FIRST_FRAME_QP
1594         /*I_PIC check is necessary coz pre-enc can query for qp even before first frame update has happened*/
1595         if(!ps_rc_ctxt->i4_is_first_frame_encoded && rc_pic_type == I_PIC)
1596         {
1597             i4_hevc_frame_qp = ps_rc_ctxt->i4_init_frame_qp_user;
1598             DBG_PRINTF("FIXED START QP PATH *************************\n");
1599         }
1600 #endif
1601         /**clip to min qp which is user configurable*/
1602         i4_hevc_frame_qp =
1603             ihevce_clip_min_max_qp(ps_rc_ctxt, i4_hevc_frame_qp, rc_pic_type, i4_temporal_layer_id);
1604 
1605         return i4_hevc_frame_qp;
1606     }
1607 }
1608 /**
1609 ******************************************************************************
1610 *
1611 *  @name  ihevce_rc_cal_pre_enc_qp
1612 *
1613 *  @par   Description - Called from enc_loop_init. updates frame qp which will
1614                         be used by next frame of same pic type in pre-enc stage
1615 *
1616 *  @param[in]   ps_rc_ctxt  - pointer to rc context
1617 *  @return      void
1618 *
1619 ******************************************************************************
1620 */
ihevce_rc_cal_pre_enc_qp(void * pv_rc_ctxt)1621 void ihevce_rc_cal_pre_enc_qp(void *pv_rc_ctxt)
1622 {
1623     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
1624     WORD32 i, i4_frame_qp, i4_scd_qp;
1625     WORD32 i4_delay_l0_enc = 0;
1626 
1627     i4_delay_l0_enc = ps_rc_ctxt->i4_pre_enc_rc_delay;
1628 
1629     if(ps_rc_ctxt->e_rate_control_type != CONST_QP)
1630     {
1631         //DBG_PRINTF("\ncheck query read = %d write = %d",ps_rc_ctxt->i4_pre_enc_qp_read_index,ps_rc_ctxt->i4_pre_enc_qp_write_index);
1632 #if DETERMINISTIC_RC
1633         ASSERT(
1634             ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_write_index].i4_is_qp_valid ==
1635             -1);
1636 #endif
1637         for(i = 0; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
1638         {
1639             i4_frame_qp =
1640                 ihevce_rc_get_pre_enc_pic_quant(ps_rc_ctxt, (picture_type_e)i, &i4_scd_qp);
1641 
1642             ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_write_index].ai4_quant[i] =
1643                 i4_frame_qp;
1644             /*returns valid scene cut qp only when queried as I_PIC*/
1645             if(i == 0)
1646             {
1647                 ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_write_index].i4_scd_qp =
1648                     i4_scd_qp;
1649             }
1650 
1651             if(ps_rc_ctxt->i4_field_pic && i > 0)
1652             {
1653                 i4_frame_qp = ihevce_rc_get_pre_enc_pic_quant(
1654                     ps_rc_ctxt, (picture_type_e)(i + FIELD_OFFSET), &i4_scd_qp);
1655 
1656                 ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_write_index]
1657                     .ai4_quant[i + FIELD_OFFSET] = i4_frame_qp;
1658             }
1659         }
1660         /*mark index as populated*/
1661         ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_write_index].i4_is_qp_valid = 1;
1662 
1663         ps_rc_ctxt->i4_pre_enc_qp_write_index =
1664             (ps_rc_ctxt->i4_pre_enc_qp_write_index + 1) % i4_delay_l0_enc;
1665     }
1666 }
1667 /**
1668 ******************************************************************************
1669 *
1670 *  @brief function to get updated qp after L1 analysis for L0. '
1671 *           This uses estimated L0 satd based on L1 satd/act
1672 *
1673 *  @par   Description
1674 *
1675 *  @param[in]   pv_rc_ctxt
1676 *               void pointer to rc ctxt
1677 *  @param[in]   rc_lap_out_params_t *
1678 pointer to lap out structure
1679 *   @param[in]  i8_est_L0_satd_act
1680 *               estimated L0 satd/act based on L1 satd/act
1681 *  @return      void
1682 *
1683 ******************************************************************************
1684 */
ihevce_get_L0_est_satd_based_scd_qp(void * pv_rc_ctxt,rc_lap_out_params_t * ps_rc_lap_out,LWORD64 i8_est_L0_satd_act,float i_to_avg_rest_ratio)1685 WORD32 ihevce_get_L0_est_satd_based_scd_qp(
1686     void *pv_rc_ctxt,
1687     rc_lap_out_params_t *ps_rc_lap_out,
1688     LWORD64 i8_est_L0_satd_act,
1689     float i_to_avg_rest_ratio)
1690 {
1691     rc_context_t *ps_ctxt = (rc_context_t *)pv_rc_ctxt;
1692     WORD32 i4_frame_qs_q3, i4_hevc_qp, i4_est_header_bits, index, i, i4_total_bits;
1693     picture_type_e rc_pic_type;
1694 
1695     rc_pic_type = ihevce_rc_conv_pic_type(
1696         (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out->i4_rc_pic_type,
1697         ps_ctxt->i4_field_pic,
1698         ps_rc_lap_out->i4_rc_temporal_lyr_id,
1699         ps_rc_lap_out->i4_is_bottom_field,
1700         ps_ctxt->i4_top_field_first);
1701 
1702     /*initialise the coeffs to 1 in case lap is not used */
1703 
1704     for(i = 0; i < MAX_PIC_TYPE; i++)
1705     {
1706         ps_ctxt->af_sum_weigh[0][i][0] = 1.0;
1707         ps_ctxt->af_sum_weigh[0][i][1] = 0.0;
1708     }
1709 
1710     /*get bits to find estimate of header bits*/
1711     i4_est_header_bits = rc_get_scene_change_est_header_bits(
1712         ps_ctxt->rc_hdl,
1713         ps_rc_lap_out->i4_num_pels_in_frame_considered,
1714         ps_ctxt->ai4_lap_f_sim[0],
1715         ps_ctxt->af_sum_weigh[0],
1716         i_to_avg_rest_ratio);
1717 
1718     index = ihevce_get_offline_index(ps_ctxt, ps_rc_lap_out->i4_num_pels_in_frame_considered);
1719     {
1720         WORD32 i4_true_scd = 0;
1721         WORD32 i4_curr_bits_estimated;
1722 
1723         i4_frame_qs_q3 = rc_get_qp_for_scd_frame(
1724             ps_ctxt->rc_hdl,
1725             I_PIC,
1726             i8_est_L0_satd_act,
1727             ps_rc_lap_out->i4_num_pels_in_frame_considered,
1728             i4_est_header_bits,
1729             ps_ctxt->ai4_lap_f_sim[0],
1730             (void *)&g_offline_i_model_coeff[index][0],
1731             i_to_avg_rest_ratio,
1732             i4_true_scd,
1733             ps_ctxt->af_sum_weigh[0],
1734             ps_rc_lap_out->ps_frame_info,
1735             ps_ctxt->i4_rc_pass,
1736             0,
1737             0,
1738             0,
1739             &i4_total_bits,
1740             &i4_curr_bits_estimated,
1741             ps_rc_lap_out->i4_use_offline_model_2pass,
1742             0,
1743             0,
1744             -1,
1745             NULL);
1746     }
1747     i4_hevc_qp = ihevce_rc_get_scaled_hevc_qp_from_qs_q3(i4_frame_qs_q3, ps_ctxt->ps_rc_quant_ctxt);
1748     i4_hevc_qp = i4_hevc_qp + ps_ctxt->ps_rc_quant_ctxt->i1_qp_offset;
1749 
1750     if(i4_hevc_qp > ps_ctxt->ps_rc_quant_ctxt->i2_max_qp)
1751         i4_hevc_qp = ps_ctxt->ps_rc_quant_ctxt->i2_max_qp;
1752 
1753     if(i4_hevc_qp < (SCD_MIN_HEVC_QP -
1754                      ps_ctxt->ps_rc_quant_ctxt
1755                          ->i1_qp_offset))  // since outside RC the QP range is -12 to 51 for 10 bit
1756     {
1757         i4_hevc_qp = (SCD_MIN_HEVC_QP - ps_ctxt->ps_rc_quant_ctxt->i1_qp_offset);
1758     }
1759     else if(i4_hevc_qp > SCD_MAX_HEVC_QP)
1760     {
1761         i4_hevc_qp = SCD_MAX_HEVC_QP;
1762     }
1763     /*this is done outside loop*/
1764 
1765     return i4_hevc_qp;
1766 }
1767 /**
1768 ******************************************************************************
1769 *
1770 *  @name  ihevce_rc_pre_enc_qp_query
1771 *
1772 *  @par   Description - Called from pre enc thrd for getting the qp of non scd
1773                         frames. updates frame qp from reverse queue from enc loop
1774                         when its available
1775 *
1776 *  @param[in]   ps_rc_ctxt  - pointer to rc context
1777 *  @param[in]   i4_update_delay : The Delay in the update. This can happen for dist. case!
1778 *               All decision should consider this delay for updation!
1779 *
1780 *  @return      void
1781 *
1782 ******************************************************************************
1783 */
1784 
ihevce_rc_pre_enc_qp_query(void * pv_rc_ctxt,rc_lap_out_params_t * ps_rc_lap_out,WORD32 i4_update_delay)1785 WORD32 ihevce_rc_pre_enc_qp_query(
1786     void *pv_rc_ctxt, rc_lap_out_params_t *ps_rc_lap_out, WORD32 i4_update_delay)
1787 {
1788     WORD32 scene_type, i4_is_scd = 0, i4_frame_qp, slice_type = ISLICE;
1789     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
1790     rc_type_e e_rc_type = ps_rc_ctxt->e_rate_control_type;
1791     IV_PICTURE_CODING_TYPE_T pic_type = (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out->i4_rc_pic_type;
1792     picture_type_e rc_pic_type = ihevce_rc_conv_pic_type(
1793         (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out->i4_rc_pic_type,
1794         ps_rc_ctxt->i4_field_pic,
1795         ps_rc_lap_out->i4_rc_temporal_lyr_id,
1796         ps_rc_lap_out->i4_is_bottom_field,
1797         ps_rc_ctxt->i4_top_field_first);
1798     WORD32 i4_use_offset_flag = 0, k = 0;
1799     WORD32 i4_inter_frame_interval = rc_get_inter_frame_interval(ps_rc_ctxt->rc_hdl);
1800     WORD32 ai4_offsets[5] = { 0, 1, 2, 3, 4 };
1801     rc_lap_out_params_t *ps_rc_lap_out_temp = ps_rc_lap_out;
1802 
1803     /* The window for which your update is guaranteed */
1804     WORD32 updated_window = ps_rc_ctxt->i4_num_frame_in_lap_window - i4_update_delay;
1805 
1806     k = 0;
1807     if((updated_window >= i4_inter_frame_interval) && (ps_rc_ctxt->i4_rc_pass != 2) &&
1808        ((rc_pic_type == I_PIC) || (rc_pic_type == P_PIC)))
1809     {
1810         WORD32 i4_count = 0;
1811 
1812         for(i4_count = 0; i4_count < updated_window; i4_count++)
1813         {
1814             picture_type_e rc_pic_type_temp = ihevce_rc_conv_pic_type(
1815                 (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out_temp->i4_rc_pic_type,
1816                 ps_rc_ctxt->i4_field_pic,
1817                 ps_rc_lap_out_temp->i4_rc_temporal_lyr_id,
1818                 ps_rc_lap_out_temp->i4_is_bottom_field,
1819                 ps_rc_ctxt->i4_top_field_first);
1820 
1821             if((rc_pic_type_temp == I_PIC) || (rc_pic_type_temp == P_PIC))
1822                 ihevce_compute_temporal_complexity_reset_Kp_Kb(ps_rc_lap_out_temp, pv_rc_ctxt, 0);
1823 
1824             ps_rc_lap_out_temp =
1825                 (rc_lap_out_params_t *)ps_rc_lap_out_temp->ps_rc_lap_out_next_encode;
1826 
1827             if(ps_rc_lap_out_temp == NULL)
1828                 break;
1829         }
1830     }
1831 
1832     if(updated_window >= i4_inter_frame_interval)
1833     {
1834         i4_use_offset_flag = 1;
1835         memmove(ai4_offsets, ps_rc_lap_out->ai4_offsets, sizeof(WORD32) * 5);
1836     }
1837 
1838     if(CONST_QP == e_rc_type)
1839     {
1840         switch(pic_type)
1841         {
1842         case IV_I_FRAME:
1843         case IV_IDR_FRAME:
1844         {
1845             slice_type = ISLICE;
1846             break;
1847         }
1848         case IV_P_FRAME:
1849         {
1850             slice_type = PSLICE;
1851             break;
1852         }
1853         case IV_B_FRAME:
1854         {
1855             slice_type = BSLICE;
1856             break;
1857         }
1858         default:
1859         {
1860             DBG_PRINTF("Invalid picture type %d\n", pic_type);
1861             break;
1862         }
1863         }
1864 
1865         i4_frame_qp = ihevce_get_cur_frame_qp(
1866             ps_rc_ctxt->i4_init_frame_qp_user,
1867             slice_type,
1868             ps_rc_lap_out->i4_rc_temporal_lyr_id,
1869             ps_rc_ctxt->i4_min_frame_qp,
1870             ps_rc_ctxt->i4_max_frame_qp,
1871             ps_rc_ctxt->ps_rc_quant_ctxt);
1872 
1873         return i4_frame_qp;
1874     }
1875     else
1876     {
1877         /*check scene type*/
1878         scene_type = ihevce_rc_lap_get_scene_type(ps_rc_lap_out);
1879 
1880         if(scene_type == SCENE_TYPE_SCENE_CUT)
1881         {
1882             i4_is_scd = 1;
1883             ps_rc_ctxt->i4_num_frms_from_reset = 0;
1884 #if USE_QP_OFFSET_POST_SCD
1885             ps_rc_ctxt->i4_use_qp_offset_pre_enc = 1;
1886 #else
1887             ps_rc_ctxt->i4_use_qp_offset_pre_enc = 0;
1888 #endif
1889         }
1890         ASSERT(
1891             ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_read_index].i4_is_qp_valid ==
1892                 1 ||
1893             ps_rc_lap_out->i4_rc_poc < 20);
1894 
1895         if(ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_read_index].i4_is_qp_valid ==
1896            1)
1897         {
1898             if(i4_is_scd || ps_rc_ctxt->i4_use_qp_offset_pre_enc)
1899             {
1900 #if 1  //The qp will be populated assuming the frame is I_PIC. Adjust according to current pic type
1901                 i4_frame_qp =
1902                     ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_read_index].i4_scd_qp;
1903                 if(rc_pic_type == P_PIC)
1904                     i4_frame_qp++;
1905                 else
1906                     i4_frame_qp = i4_frame_qp + ps_rc_lap_out->i4_rc_temporal_lyr_id;
1907 #endif
1908                 if(i4_use_offset_flag)
1909                 {
1910                     if(rc_pic_type > B2_PIC)
1911                         i4_frame_qp = ps_rc_ctxt->i4_L0_frame_qp + ai4_offsets[rc_pic_type - 4];
1912                     else
1913                         i4_frame_qp = ps_rc_ctxt->i4_L0_frame_qp + ai4_offsets[rc_pic_type];
1914                 }
1915             }
1916             else
1917             {
1918 #if DETERMINISTIC_RC
1919                 i4_frame_qp = ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_read_index]
1920                                   .ai4_quant[rc_pic_type];
1921 #else
1922                 /*read the latest qp updated by enc*/
1923                 i4_frame_qp =
1924                     ps_rc_ctxt
1925                         ->as_pre_enc_qp_queue
1926                             [(ps_rc_ctxt->i4_pre_enc_qp_write_index + MAX_PRE_ENC_RC_DELAY - 1) %
1927                              MAX_PRE_ENC_RC_DELAY]
1928                         .ai4_quant[rc_pic_type];
1929 #endif
1930             }
1931 
1932             ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_read_index].i4_is_qp_valid =
1933                 -1;
1934             /*once encoder starts reading from qp queue it should always read from qp queue*/
1935             //ps_rc_ctxt->i4_use_init_qp_for_pre_enc = 0;
1936         }
1937         else
1938         {
1939             i4_frame_qp = ps_rc_ctxt->ai4_init_pre_enc_qp[rc_pic_type];
1940         }
1941         {
1942             WORD32 i4_delay_l0_enc = ps_rc_ctxt->i4_pre_enc_rc_delay;
1943             ps_rc_ctxt->i4_pre_enc_qp_read_index =
1944                 (ps_rc_ctxt->i4_pre_enc_qp_read_index + 1) % i4_delay_l0_enc;
1945 
1946             if(ps_rc_ctxt->i4_num_frms_from_reset < i4_delay_l0_enc)
1947             {
1948                 ps_rc_ctxt->i4_num_frms_from_reset++;
1949                 if(ps_rc_ctxt->i4_num_frms_from_reset >= i4_delay_l0_enc)
1950                     ps_rc_ctxt->i4_use_qp_offset_pre_enc = 0;
1951             }
1952         }
1953 
1954         i4_frame_qp = CLIP3(i4_frame_qp, ps_rc_ctxt->i4_min_frame_qp, ps_rc_ctxt->i4_max_frame_qp);
1955         return i4_frame_qp;
1956     }
1957 }
1958 /**
1959 ******************************************************************************
1960 *
1961 *  @brief function to estimate L0 satd based on L1 satd. '
1962 *
1963 *
1964 *  @par   Description
1965 *
1966 *  @param[in]   pv_rc_ctxt
1967 *               void pointer to rc ctxt
1968 *  @param[in]   rc_lap_out_params_t *
1969 pointer to lap out structure
1970 *   @param[in]  i8_est_L0_satd_act
1971 *               estimated L0 satd/act based on L1 satd/act
1972 *  @return      void
1973 *
1974 ******************************************************************************
1975 */
ihevce_get_L0_satd_based_on_L1(LWORD64 i8_satd_by_act_L1,WORD32 i4_num_pixel,WORD32 i4_cur_q_scale)1976 LWORD64 ihevce_get_L0_satd_based_on_L1(
1977     LWORD64 i8_satd_by_act_L1, WORD32 i4_num_pixel, WORD32 i4_cur_q_scale)
1978 {
1979     LWORD64 est_L0_satd_by_act;
1980     float m, c;
1981     /** choose coeff based on resolution*/
1982     if(i4_num_pixel > 5184000)
1983     {
1984         m = (float)2.3911;
1985         c = (float)86329;
1986     }
1987     else if(i4_num_pixel > 1497600)
1988     {
1989         m = (float)2.7311;
1990         c = (float)-1218.9;
1991     }
1992     else if(i4_num_pixel > 633600)
1993     {
1994         m = (float)3.1454;
1995         c = (float)-5836.1;
1996     }
1997     else
1998     {
1999         m = (float)3.5311;
2000         c = (float)-2377.2;
2001     }
2002     /*due to qp difference between I and  P, For P pic for same */
2003     est_L0_satd_by_act = (LWORD64)(i8_satd_by_act_L1 / i4_cur_q_scale * m + c) * i4_cur_q_scale;
2004 
2005     {
2006         if(est_L0_satd_by_act < (i4_num_pixel >> 3))
2007             est_L0_satd_by_act = (i4_num_pixel >> 3);
2008     }
2009     return est_L0_satd_by_act;
2010 }
2011 /**
2012 ******************************************************************************
2013 *
2014 *  @name  ihevce_rc_register_L1_analysis_data
2015 *
2016 *  @par   Description
2017 *
2018 *  @param[in]   ps_rc_ctxt  - pointer to rc context
2019 *               ps_rc_lap_out
2020 *               i8_est_L0_satd_by_act
2021 *               i8_pre_intra_sad
2022 *               i8_l1_hme_sad
2023 *  @return      void
2024 *
2025 ******************************************************************************
2026 */
ihevce_rc_register_L1_analysis_data(void * pv_rc_ctxt,rc_lap_out_params_t * ps_rc_lap_out,LWORD64 i8_est_L0_satd_by_act,LWORD64 i8_pre_intra_sad,LWORD64 i8_l1_hme_sad)2027 void ihevce_rc_register_L1_analysis_data(
2028     void *pv_rc_ctxt,
2029     rc_lap_out_params_t *ps_rc_lap_out,
2030     LWORD64 i8_est_L0_satd_by_act,
2031     LWORD64 i8_pre_intra_sad,
2032     LWORD64 i8_l1_hme_sad)
2033 {
2034     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
2035     WORD32 i, data_available = 1;
2036     picture_type_e rc_pic_type = ihevce_rc_conv_pic_type(
2037         (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out->i4_rc_pic_type,
2038         ps_rc_ctxt->i4_field_pic,
2039         ps_rc_lap_out->i4_rc_temporal_lyr_id,
2040         ps_rc_lap_out->i4_is_bottom_field,
2041         ps_rc_ctxt->i4_top_field_first);
2042 
2043     //if( ps_rc_ctxt->u4_rc_scene_num_est_L0_intra_sad_available == ps_rc_lap_out->u4_rc_scene_num)
2044     {
2045         /*update current frame's data*/
2046         ps_rc_ctxt->ai8_prev_frame_est_L0_satd[rc_pic_type] = i8_est_L0_satd_by_act;
2047         ps_rc_ctxt->ai8_prev_frame_hme_sad[rc_pic_type] = i8_l1_hme_sad;
2048         ps_rc_ctxt->ai8_prev_frame_pre_intra_sad[rc_pic_type] = i8_pre_intra_sad;
2049     }
2050     /*check if data is available for all picture type*/
2051     if(!ps_rc_ctxt->i4_is_est_L0_intra_sad_available)
2052     {
2053         for(i = 0; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
2054         {
2055             data_available &= (ps_rc_ctxt->ai8_prev_frame_est_L0_satd[i] >= 0);
2056             if(ps_rc_ctxt->i4_field_pic == 1 && i != 0)
2057                 data_available &= (ps_rc_ctxt->ai8_prev_frame_est_L0_satd[i + FIELD_OFFSET] >= 0);
2058         }
2059         ps_rc_ctxt->i4_is_est_L0_intra_sad_available = data_available;
2060     }
2061 }
2062 
2063 /*#######################################################*/
2064 /******* END OF PRE-ENC QP QUERY FUNCTIONS **************/
2065 /*#####################################################*/
2066 
2067 /*##########################################################*/
2068 /******* START OF ENC THRD QP QUERY FUNCTIONS **************/
2069 /*########################################################*/
2070 
2071 /**
2072 ******************************************************************************
2073 *
2074 *  @brief function to get ihevce_rc_get_pic_quant
2075 *
2076 *  @par   Description
2077 *  @param[in]   i4_update_delay : The Delay in the update. This can happen for dist. case!
2078 *               All decision should consider this delay for updation!
2079 ******************************************************************************
2080 */
2081 
ihevce_rc_get_pic_quant(void * pv_ctxt,rc_lap_out_params_t * ps_rc_lap_out,IHEVCE_RC_CALL_TYPE call_type,WORD32 i4_enc_frm_id,WORD32 i4_update_delay,WORD32 * pi4_tot_bits_estimated)2082 WORD32 ihevce_rc_get_pic_quant(
2083     void *pv_ctxt,
2084     rc_lap_out_params_t *ps_rc_lap_out,
2085     IHEVCE_RC_CALL_TYPE call_type,
2086     WORD32 i4_enc_frm_id,
2087     WORD32 i4_update_delay,
2088     WORD32 *pi4_tot_bits_estimated)
2089 {
2090     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
2091     WORD32 i4_frame_qp, i4_frame_qp_q6, i4_hevc_frame_qp = -1, i4_deltaQP = 0;
2092     WORD32 i4_max_frame_bits = (1 << 30);
2093     rc_type_e e_rc_type = ps_rc_ctxt->e_rate_control_type;
2094     WORD32 slice_type = ISLICE, index, i4_num_frames_in_cur_gop, i4_cur_est_texture_bits;
2095     WORD32 temporal_layer_id = ps_rc_lap_out->i4_rc_temporal_lyr_id;
2096     IV_PICTURE_CODING_TYPE_T pic_type = (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out->i4_rc_pic_type;
2097     picture_type_e rc_pic_type = ihevce_rc_conv_pic_type(
2098         pic_type,
2099         ps_rc_ctxt->i4_field_pic,
2100         ps_rc_lap_out->i4_rc_temporal_lyr_id,
2101         ps_rc_lap_out->i4_is_bottom_field,
2102         ps_rc_ctxt->i4_top_field_first);
2103     float i_to_avg_bit_ratio;
2104     frame_info_t s_frame_info_temp;
2105     WORD32 i4_scene_num = ps_rc_lap_out->u4_rc_scene_num % MAX_SCENE_NUM;
2106     WORD32 i4_vbv_buf_max_bits;
2107     WORD32 i4_est_tex_bits;
2108     WORD32 i4_cur_est_header_bits, i4_fade_scene;
2109     WORD32 i4_model_available, i4_is_no_model_scd;
2110     WORD32 i4_estimate_to_calc_frm_error;
2111 
2112     /* The window for which your update is guaranteed */
2113     WORD32 updated_window = ps_rc_ctxt->i4_num_frame_in_lap_window - i4_update_delay;
2114 
2115     ps_rc_ctxt->i4_scene_num_latest = i4_scene_num;
2116 
2117     ps_rc_ctxt->s_rc_high_lvl_stat.i4_modelQP = INVALID_QP;
2118     ps_rc_ctxt->s_rc_high_lvl_stat.i4_finalQP = INVALID_QP;
2119     ps_rc_ctxt->s_rc_high_lvl_stat.i4_maxEbfQP = INVALID_QP;
2120 
2121     ps_rc_ctxt->i4_quality_preset = ps_rc_lap_out->i4_rc_quality_preset;
2122     ps_rc_ctxt->s_rc_high_lvl_stat.i4_finalQP = INVALID_QP;
2123 
2124     if(1 == ps_rc_ctxt->i4_bitrate_changed)
2125     {
2126         ps_rc_ctxt->i4_bitrate_changed = 0;
2127     }
2128     if(CONST_QP == e_rc_type)
2129     {
2130         switch(pic_type)
2131         {
2132         case IV_I_FRAME:
2133         case IV_IDR_FRAME:
2134         {
2135             slice_type = ISLICE;
2136             break;
2137         }
2138         case IV_P_FRAME:
2139         {
2140             slice_type = PSLICE;
2141             break;
2142         }
2143         case IV_B_FRAME:
2144         {
2145             slice_type = BSLICE;
2146             break;
2147         }
2148         default:
2149         {
2150             DBG_PRINTF("Invalid picture type %d\n", pic_type);
2151             break;
2152         }
2153         }
2154 
2155         i4_frame_qp = ihevce_get_cur_frame_qp(
2156             ps_rc_ctxt->i4_init_frame_qp_user,
2157             slice_type,
2158             temporal_layer_id,
2159             ps_rc_ctxt->i4_min_frame_qp,
2160             ps_rc_ctxt->i4_max_frame_qp,
2161             ps_rc_ctxt->ps_rc_quant_ctxt);
2162         return i4_frame_qp;
2163     }
2164     else
2165     {
2166         WORD32 is_scd_ref_frame = 0, i4_num_scd_in_lap_window = 0, num_frames_b4_scd = 0,
2167                scene_type = 0, i;
2168         //ihevce_lap_output_params_t *ps_cur_rc_lap_out;
2169 
2170         if(ps_rc_ctxt->ai4_scene_num_last_pic[rc_pic_type] !=
2171            (WORD32)ps_rc_lap_out->u4_rc_scene_num)
2172         {
2173             rc_reset_pic_model(ps_rc_ctxt->rc_hdl, rc_pic_type);
2174             rc_reset_first_frame_coded_flag(ps_rc_ctxt->rc_hdl, rc_pic_type);
2175         }
2176         ps_rc_ctxt->ai4_scene_num_last_pic[rc_pic_type] = ps_rc_lap_out->u4_rc_scene_num;
2177 
2178         if(call_type == ENC_GET_QP)
2179         {
2180             i4_model_available = model_availability(ps_rc_ctxt->rc_hdl, rc_pic_type);
2181 
2182             ps_rc_lap_out->i8_est_text_bits = -1;
2183         }
2184 
2185         if((rc_pic_type == I_PIC) || (rc_pic_type == P_PIC) || (rc_pic_type == P1_PIC))
2186         {
2187             ps_rc_ctxt->i4_cur_scene_num = ps_rc_lap_out->u4_rc_scene_num;
2188         }
2189 
2190         {
2191             if(!(pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME))
2192             {
2193                 ps_rc_ctxt->ai8_cur_frame_coarse_ME_cost[i4_enc_frm_id] =
2194                     ps_rc_lap_out->i8_frame_acc_coarse_me_cost;
2195             }
2196             /*check if frame is scene cut*/
2197             /* If scd do not query the model. obtain qp from offline data model*/
2198             scene_type = ihevce_rc_lap_get_scene_type(ps_rc_lap_out);
2199 
2200             if(ps_rc_ctxt->ai4_scene_numbers[ps_rc_lap_out->u4_rc_scene_num] == 0 &&
2201                (scene_type != SCENE_TYPE_SCENE_CUT))
2202             {
2203                 scene_type = SCENE_TYPE_SCENE_CUT;
2204             }
2205 
2206             if(ps_rc_ctxt->ai4_scene_numbers[ps_rc_lap_out->u4_rc_scene_num] > 0 &&
2207                (scene_type == SCENE_TYPE_SCENE_CUT))
2208             {
2209                 scene_type = SCENE_TYPE_NORMAL;
2210             }
2211             if(scene_type == SCENE_TYPE_SCENE_CUT)
2212             {
2213                 if((ps_rc_lap_out->i4_rc_quality_preset == IHEVCE_QUALITY_P6) &&
2214                    (rc_pic_type > P_PIC))
2215                 {
2216                     is_scd_ref_frame = 0;
2217                 }
2218                 else
2219                 {
2220                     is_scd_ref_frame = 1;
2221                 }
2222             }
2223             else if(scene_type == SCENE_TYPE_PAUSE_TO_RESUME)
2224             {
2225                 /*pause to resume flag will only be set in layer 0 frames( I and P pic)*/
2226                 /*I PIC can handle this by detecting I_only SCD which is based on open loop SATD hence explicit handling for pause to resume is required only for P_PIC*/
2227 
2228                 if(ps_rc_lap_out->i4_rc_quality_preset == IHEVCE_QUALITY_P6)
2229                 {
2230                     if(call_type == ENC_GET_QP && rc_pic_type == P_PIC)
2231                     {
2232                         ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] = 1;
2233                     }
2234                 }
2235                 else
2236                 {
2237                     if(call_type == ENC_GET_QP && rc_pic_type != I_PIC)
2238                     {
2239                         ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] = 1;
2240                     }
2241                 }
2242             }
2243 
2244             ps_rc_ctxt->ai4_is_cmplx_change_reset_model[i4_enc_frm_id] =
2245                 ps_rc_lap_out->i4_is_cmplx_change_reset_model;
2246             ps_rc_ctxt->ai4_is_cmplx_change_reset_bits[i4_enc_frm_id] =
2247                 ps_rc_lap_out->i4_is_cmplx_change_reset_bits;
2248 
2249             /*initialise the coeffs to 1 in case lap is not used */
2250             for(i = 0; i < MAX_PIC_TYPE; i++)
2251             {
2252                 ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][i][0] = 1.0;
2253                 ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][i][1] = 0.0;
2254                 ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][i][2] = 0.0;
2255             }
2256 
2257             /*treat even first frame as scd frame*/
2258             if(!ps_rc_ctxt->i4_is_first_frame_encoded)
2259             {
2260                 is_scd_ref_frame = 1;
2261             }
2262 
2263             /*special case SCD handling for Non-I pic*/
2264             if(!(pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME) && call_type == ENC_GET_QP)
2265             {
2266                 if(is_scd_ref_frame)
2267                 {
2268                     /*A non-I pic will only be marked as scene cut only if there is another SCD follows within another subgop*/
2269                     ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] = 1;
2270                 }
2271                 /*check if current sad is very different from previous SAD and */
2272                 else if(
2273                     !ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] &&
2274                     ps_rc_lap_out->i4_is_non_I_scd)
2275                 {
2276                     ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] = 1;
2277                     is_scd_ref_frame = 1;
2278                 }
2279             }
2280 
2281             if(call_type == PRE_ENC_GET_QP)
2282             {
2283                 /*Only I frames are considered as scd pic during pre-enc*/
2284                 is_scd_ref_frame &= (pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME);
2285             }
2286 
2287             /*special case SCD handling for I pic*/
2288             if((pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME) && !is_scd_ref_frame)
2289             {
2290                 /*If open loop SATD's of two I picture are very different then treat the I pic as SCD and reset only model as this can
2291                 happen during fade-in and fade-out where other picture types would have learnt. Reset is required only for I.*/
2292 
2293                 if(ps_rc_lap_out->i4_is_I_only_scd)
2294                 {
2295                     is_scd_ref_frame = 1;
2296                     ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id] = 1;
2297                 }
2298             }
2299             /*should be recalculated for every picture*/
2300             if((updated_window) > 0 && (call_type == ENC_GET_QP) && (ps_rc_ctxt->i4_rc_pass != 2))
2301             {
2302                 rc_lap_out_params_t *ps_cur_rc_lap_out;
2303 
2304                 UWORD32 u4_L1_based_lap_complexity_q7;
2305                 WORD32 i = 0, k = 0, i4_f_sim = 0, i4_h_sim = 0, i4_var_sum = 0,
2306                        i4_num_pic_metric_count = 0, i4_is_first_frm = 1,
2307                        i4_intra_frame_interval = 0;
2308                 LWORD64 i8_l1_analysis_lap_comp = 0;
2309                 LWORD64 nor_frm_hme_sad_q10;
2310                 picture_type_e curr_rc_pic_type;
2311                 WORD32 ai4_pic_dist[MAX_PIC_TYPE] = { 0 };
2312                 LWORD64 i8_sad_first_frame_pic_type[MAX_PIC_TYPE] = { 0 },
2313                         i8_total_sad_pic_type[MAX_PIC_TYPE] = { 0 };
2314                 LWORD64 i8_last_frame_pic_type[MAX_PIC_TYPE] = { 0 }, i8_esti_consum_bits = 0;
2315                 WORD32 i4_num_pic_type[MAX_PIC_TYPE] = { 0 }, i4_frames_in_lap_end = 0,
2316                        i4_first_frame_coded_flag, i4_gop_end_flag = 1, i4_num_frame_for_ebf = 0;
2317                 i4_first_frame_coded_flag = is_first_frame_coded(ps_rc_ctxt->rc_hdl);
2318 
2319                 /*Setting the next scene cut as well as pic distribution for the gop*/
2320 
2321                 ps_cur_rc_lap_out = (rc_lap_out_params_t *)ps_rc_lap_out;
2322                 i4_intra_frame_interval = rc_get_intra_frame_interval(ps_rc_ctxt->rc_hdl);
2323 
2324                 /*Set the rc sc i next*/
2325                 if(ps_cur_rc_lap_out != NULL)
2326                 {
2327                     WORD32 i4_count = 0;
2328                     do
2329                     {
2330                         if(((rc_lap_out_params_t *)ps_cur_rc_lap_out->ps_rc_lap_out_next_encode ==
2331                             NULL))  //||((( (ihevce_lap_output_params_t*)ps_cur_rc_lap_out->ps_lap_out_next)->i8_pre_intra_sad == -1) || (  ((ihevce_lap_output_params_t*)ps_cur_rc_lap_out->ps_lap_out_next)->i8_raw_pre_intra_sad == -1) ||(  ((ihevce_lap_output_params_t*)ps_cur_rc_lap_out->ps_lap_out_next)->i8_raw_l1_coarse_me_sad == -1) ||(((ihevce_lap_output_params_t*)ps_cur_rc_lap_out->ps_lap_out_next)->i8_frame_acc_coarse_me_sad == -1)))
2332                             break;
2333 
2334                         ps_cur_rc_lap_out =
2335                             (rc_lap_out_params_t *)ps_cur_rc_lap_out->ps_rc_lap_out_next_encode;
2336                         i4_count++;
2337 
2338                     } while((i4_count + 1) < updated_window);
2339 
2340                     rc_set_next_sc_i_in_rc_look_ahead(
2341                         ps_rc_ctxt->rc_hdl, ps_cur_rc_lap_out->i4_next_sc_i_in_rc_look_ahead);
2342                     rc_update_pic_distn_lap_to_rc(
2343                         ps_rc_ctxt->rc_hdl, ps_cur_rc_lap_out->ai4_num_pic_type);
2344 
2345                     ps_rc_ctxt->i4_next_sc_i_in_rc_look_ahead =
2346                         ps_cur_rc_lap_out->i4_next_sc_i_in_rc_look_ahead;
2347                 }
2348 
2349                 ps_cur_rc_lap_out = (rc_lap_out_params_t *)ps_rc_lap_out;
2350                 if(ps_cur_rc_lap_out != NULL)
2351                 {
2352                     /*initialise the coeffs to 1 in case lap is not used */
2353                     for(i = 0; i < MAX_PIC_TYPE; i++)
2354                     {
2355                         ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][i][0] = 0.0;
2356                         ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][i][1] = 0.0;
2357                         ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][i][2] = 0.0;
2358                     }
2359                     i = 0;
2360                     k = 0;
2361 
2362                     //ASSERT(ps_cur_rc_lap_out != NULL);
2363                     do
2364                     {
2365                         curr_rc_pic_type = ihevce_rc_conv_pic_type(
2366                             (IV_PICTURE_CODING_TYPE_T)ps_cur_rc_lap_out->i4_rc_pic_type,
2367                             ps_rc_ctxt->i4_field_pic,
2368                             ps_cur_rc_lap_out->i4_rc_temporal_lyr_id,
2369                             ps_cur_rc_lap_out->i4_is_bottom_field,
2370                             ps_rc_ctxt->i4_top_field_first);
2371                         if(ps_rc_ctxt->i4_is_first_frame_encoded || !i4_is_first_frm)
2372                         {
2373                             /*Ignore first frame Fsim as it is not valid for first frame*/
2374                             i4_f_sim += ps_cur_rc_lap_out->s_pic_metrics.i4_fsim;
2375                             i4_h_sim += ps_cur_rc_lap_out->s_pic_metrics.ai4_hsim[0];
2376                             i4_var_sum += (WORD32)ps_cur_rc_lap_out->s_pic_metrics.i8_8x8_var_lum;
2377                             i4_num_pic_metric_count++;
2378                             //DBG_PRINTF("\n fsim = %d i = %d",ps_cur_rc_lap_out->s_pic_metrics.i4_fsim,i);
2379                             //ASSERT(ps_cur_rc_lap_out->s_pic_metrics.i4_fsim <= 128);
2380                         }
2381 
2382                         /*accumulate complexity from LAP2*/
2383                         if(curr_rc_pic_type == I_PIC)
2384                         {
2385                             i8_l1_analysis_lap_comp +=
2386                                 (LWORD64)(1.17 * ps_cur_rc_lap_out->i8_raw_pre_intra_sad);
2387                         }
2388                         else
2389                         {
2390                             if(curr_rc_pic_type <= B2_PIC)
2391                                 i8_l1_analysis_lap_comp += (LWORD64)(
2392                                     (float)ps_cur_rc_lap_out->i8_raw_l1_coarse_me_sad /
2393                                     pow(1.125f, curr_rc_pic_type));
2394                             else
2395                                 i8_l1_analysis_lap_comp += (LWORD64)(
2396                                     (float)ps_cur_rc_lap_out->i8_raw_l1_coarse_me_sad /
2397                                     pow(1.125f, curr_rc_pic_type - B2_PIC));
2398                         }
2399                         i++;
2400                         i4_is_first_frm = 0;
2401 
2402                         /*CAll the function for predictting the ebf and stuffing condition check*/
2403                         /*rd model pass lapout l1 pass ebf return estimated ebf and signal*/
2404 
2405                         {
2406                             if(i4_first_frame_coded_flag && (i4_gop_end_flag != 0))
2407                             {
2408                                 if(curr_rc_pic_type == 0)
2409                                     i4_gop_end_flag = 0;
2410 
2411                                 if(i4_gop_end_flag)
2412                                 {
2413                                     WORD32 prev_frm_cl_sad =
2414                                         rc_get_prev_frame_sad(ps_rc_ctxt->rc_hdl, curr_rc_pic_type);
2415                                     WORD32 cur_frm_est_cl_sad = (WORD32)(
2416                                         (ps_cur_rc_lap_out->i8_frame_acc_coarse_me_cost *
2417                                          prev_frm_cl_sad) /
2418                                         ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[curr_rc_pic_type]);
2419                                     i8_esti_consum_bits += bit_alloc_get_estimated_bits_for_pic(
2420                                         ps_rc_ctxt->rc_hdl,
2421                                         cur_frm_est_cl_sad,
2422                                         prev_frm_cl_sad,
2423                                         curr_rc_pic_type);
2424                                     i4_num_frame_for_ebf++;
2425                                 }
2426                             }
2427                         }
2428                         ps_cur_rc_lap_out =
2429                             (rc_lap_out_params_t *)ps_cur_rc_lap_out->ps_rc_lap_out_next_encode;
2430                         /*The scene cut is lap window other than current frame is used to reduce bit alloc window for I pic*/
2431                         if(ps_cur_rc_lap_out != NULL &&
2432                            ps_cur_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_SCENE_CUT)
2433                         {
2434                             i4_num_scd_in_lap_window++;
2435                             if(i4_num_scd_in_lap_window == 1)
2436                             {
2437                                 /*Note how many frames are parsed before first scd is hit*/
2438                                 num_frames_b4_scd = i + 1;
2439                             }
2440                         }
2441 
2442                         if((ps_cur_rc_lap_out == NULL ||
2443                             (i >=
2444                              (updated_window -
2445                               k))))  //||((( -1 == ps_cur_rc_lap_out->i8_pre_intra_sad ) || ( -1 == ps_cur_rc_lap_out->i8_raw_pre_intra_sad ) ||( -1 == ps_cur_rc_lap_out->i8_raw_l1_coarse_me_sad) ||(-1 == ps_cur_rc_lap_out->i8_frame_acc_coarse_me_sad))))
2446                             break;
2447                         if(0)  //(( -1 == ps_cur_rc_lap_out->i8_pre_intra_sad ) || ( -1 == ps_cur_rc_lap_out->i8_raw_pre_intra_sad ) ||( -1 == ps_cur_rc_lap_out->i8_raw_l1_coarse_me_sad) ||(-1 == ps_cur_rc_lap_out->i8_frame_acc_coarse_me_sad)))
2448                         {
2449                             k++;
2450                             ps_cur_rc_lap_out =
2451                                 (rc_lap_out_params_t *)ps_cur_rc_lap_out->ps_rc_lap_out_next_encode;
2452                             if(ps_cur_rc_lap_out == NULL)
2453                                 break;
2454                             continue;
2455                         }
2456 
2457                     } while(1);
2458                     ;
2459                 }
2460                 /*For the first subgop we cant have underflow prevention logic
2461                 since once picture of each type is not encoded also happens for static contents thants high i_to avg_ratio */
2462                 if(i4_first_frame_coded_flag &&
2463                    (ps_rc_ctxt->ai_to_avg_bit_ratio[i4_enc_frm_id] > I_TO_REST_SLOW))
2464                 {
2465                     if(!(i4_num_frame_for_ebf < ps_rc_ctxt->i4_max_inter_frm_int))
2466                         rc_bit_alloc_detect_ebf_stuff_scenario(
2467                             ps_rc_ctxt->rc_hdl,
2468                             i4_num_frame_for_ebf,
2469                             i8_esti_consum_bits,
2470                             ps_rc_ctxt->i4_max_inter_frm_int);
2471                 }
2472 
2473                 k = 0;
2474 
2475                 i4_frames_in_lap_end = 0;
2476                 {
2477                     rc_lap_out_params_t *ps_cur_rc_lap_out1;
2478 
2479                     ps_cur_rc_lap_out1 = (rc_lap_out_params_t *)ps_rc_lap_out;
2480                     do
2481                     {
2482                         curr_rc_pic_type = ihevce_rc_conv_pic_type(
2483                             (IV_PICTURE_CODING_TYPE_T)ps_cur_rc_lap_out1->i4_rc_pic_type,
2484                             ps_rc_ctxt->i4_field_pic,
2485                             ps_cur_rc_lap_out1->i4_rc_temporal_lyr_id,
2486                             ps_cur_rc_lap_out1->i4_is_bottom_field,
2487                             ps_rc_ctxt->i4_top_field_first);
2488                         /*accumulate complexity from LAP2*/
2489 
2490                         if(curr_rc_pic_type == I_PIC)
2491                         {
2492                             i8_total_sad_pic_type[I_PIC] +=
2493                                 ps_cur_rc_lap_out1->i8_raw_pre_intra_sad;
2494                             i8_last_frame_pic_type[I_PIC] =
2495                                 ps_cur_rc_lap_out1->i8_raw_pre_intra_sad;
2496                         }
2497                         else
2498                         {
2499                             i8_total_sad_pic_type[curr_rc_pic_type] +=
2500                                 ps_cur_rc_lap_out1->i8_raw_l1_coarse_me_sad;
2501                             i8_last_frame_pic_type[curr_rc_pic_type] =
2502                                 ps_cur_rc_lap_out1->i8_raw_l1_coarse_me_sad;
2503                         }
2504                         if(i4_num_pic_type[curr_rc_pic_type] == 0)
2505                         {
2506                             if(curr_rc_pic_type == I_PIC)
2507                             {
2508                                 i8_sad_first_frame_pic_type[I_PIC] =
2509                                     ps_cur_rc_lap_out1->i8_raw_pre_intra_sad;
2510                             }
2511                             else
2512                             {
2513                                 i8_sad_first_frame_pic_type[curr_rc_pic_type] =
2514                                     ps_cur_rc_lap_out1->i8_raw_l1_coarse_me_sad;
2515                             }
2516                         }
2517                         i4_num_pic_type[curr_rc_pic_type]++;
2518 
2519                         i4_frames_in_lap_end++;
2520 
2521                         ps_cur_rc_lap_out1 =
2522                             (rc_lap_out_params_t *)ps_cur_rc_lap_out1->ps_rc_lap_out_next_encode;
2523                         if((ps_cur_rc_lap_out1 == NULL ||
2524                             (i4_frames_in_lap_end >=
2525                              (updated_window -
2526                               k))))  //||((( -1 == ps_cur_rc_lap_out1->i8_pre_intra_sad ) || ( -1 == ps_cur_rc_lap_out1->i8_raw_pre_intra_sad ) ||( -1 == ps_cur_rc_lap_out1->i8_raw_l1_coarse_me_sad) ||(-1 == ps_cur_rc_lap_out1->i8_frame_acc_coarse_me_sad))))
2527                         {
2528                             break;
2529                         }
2530                         if(0)  //((( -1 == ps_cur_rc_lap_out1->i8_pre_intra_sad ) || ( -1 == ps_cur_rc_lap_out1->i8_raw_pre_intra_sad ) ||( -1 == ps_cur_rc_lap_out1->i8_raw_l1_coarse_me_sad) ||(-1 == ps_cur_rc_lap_out1->i8_frame_acc_coarse_me_sad))))
2531                         {
2532                             k++;
2533                             ps_cur_rc_lap_out1 = (rc_lap_out_params_t *)
2534                                                      ps_cur_rc_lap_out1->ps_rc_lap_out_next_encode;
2535                             if(ps_cur_rc_lap_out1 == NULL)
2536                                 break;
2537                             continue;
2538                         }
2539 
2540                     } while(i4_frames_in_lap_end < (ps_rc_ctxt->i4_next_sc_i_in_rc_look_ahead - k));
2541                 }
2542 
2543                 /*get picture type distribution in LAP*/
2544                 rc_get_pic_distribution(ps_rc_ctxt->rc_hdl, &ai4_pic_dist[0]);
2545 
2546                 {
2547                     float f_prev_comp;
2548                     WORD32 j;
2549                     float af_sum_weigh[MAX_PIC_TYPE], af_nume_weight[MAX_PIC_TYPE];
2550                     float af_average_sad_pic_type[MAX_PIC_TYPE] = { 0 };
2551                     for(j = 0; j < MAX_PIC_TYPE; j++)
2552                     {
2553                         if(i4_num_pic_type[j] > 0)
2554                         {
2555                             af_average_sad_pic_type[j] =
2556                                 (float)i8_total_sad_pic_type[j] / i4_num_pic_type[j];
2557                         }
2558 
2559                         f_prev_comp = 1.;
2560 
2561                         i4_num_pic_type[j] = (i4_num_pic_type[j] > ai4_pic_dist[j])
2562                                                  ? ai4_pic_dist[j]
2563                                                  : i4_num_pic_type[j];
2564 
2565                         af_sum_weigh[j] = (float)i4_num_pic_type[j];
2566                         af_nume_weight[j] = 1.0;
2567 
2568                         if(i4_num_pic_type[j] > 1 && (af_average_sad_pic_type[j] > 0))
2569                         {
2570                             af_nume_weight[j] =
2571                                 (float)i8_sad_first_frame_pic_type[j] / af_average_sad_pic_type[j];
2572 
2573                             f_prev_comp =
2574                                 (float)i8_last_frame_pic_type[j] / af_average_sad_pic_type[j];
2575                         }
2576                         //if(rc_pic_type != I_PIC)
2577                         {
2578                             af_sum_weigh[j] += f_prev_comp * (ai4_pic_dist[j] - i4_num_pic_type[j]);
2579                         }
2580                         ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][j][0] = af_nume_weight[j];
2581                         ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][j][1] = af_sum_weigh[j];
2582                         ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][j][2] = af_average_sad_pic_type[j];
2583 
2584                         /*Disabling steady state complexity based bit movement*/
2585                         /*Enable it in CBR and not in VBR since VBR already has complexity based bit movement*/
2586 
2587                         if(0) /*i4_frames_in_lap_end < (updated_window) || ps_rc_ctxt->e_rate_control_type == VBR_STREAMING)*/
2588                         {
2589                             ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][j][0] = 1.0;
2590                             ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][j][1] =
2591                                 0;  //(float)ai4_pic_dist[j];
2592                         }
2593                     }
2594                     memmove(
2595                         ps_rc_lap_out->ps_frame_info->af_sum_weigh,
2596                         ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id],
2597                         sizeof(float) * MAX_PIC_TYPE * 3);
2598                 }
2599 
2600                 if(i4_num_pic_metric_count > 0)
2601                 {
2602                     i4_f_sim = i4_f_sim / i4_num_pic_metric_count;
2603                     i4_h_sim = i4_h_sim / i4_num_pic_metric_count;
2604                     i4_var_sum = i4_var_sum / i4_num_pic_metric_count;
2605                 }
2606                 else
2607                 {
2608                     i4_f_sim = MODERATE_FSIM_VALUE;
2609                     i4_h_sim = MODERATE_FSIM_VALUE;
2610                 }
2611 
2612                 if(i > 0)
2613                 {
2614                     float lap_L1_comp =
2615                         (float)i8_l1_analysis_lap_comp /
2616                         (i * ps_rc_ctxt->i4_frame_height *
2617                          ps_rc_ctxt->i4_frame_width);  //per frame per pixel complexity
2618 
2619                     lap_L1_comp = rc_get_offline_normalized_complexity(
2620                         ps_rc_ctxt->u4_intra_frame_interval,
2621                         ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width,
2622                         lap_L1_comp,
2623                         ps_rc_ctxt->i4_rc_pass);
2624 
2625                     u4_L1_based_lap_complexity_q7 = (WORD32)((lap_L1_comp * (1 << 7)) + .05f);
2626                 }
2627                 else
2628                 {
2629                     u4_L1_based_lap_complexity_q7 = 25;
2630                 }
2631                 ps_rc_ctxt->ai4_lap_complexity_q7[i4_enc_frm_id] =
2632                     (WORD32)u4_L1_based_lap_complexity_q7;
2633                 /*clip f_sim to 0.3 for better stability*/
2634                 if(i4_f_sim < 38)
2635                     i4_f_sim = 128 - MAX_LAP_COMPLEXITY_Q7;
2636                 ps_rc_ctxt->ai4_lap_f_sim[i4_enc_frm_id] = i4_f_sim;
2637 
2638                 /*calculate normalized per pixel sad*/
2639                 nor_frm_hme_sad_q10 = (ps_rc_lap_out->i8_frame_acc_coarse_me_cost << 10) /
2640                                       (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width);
2641                 /*if(rc_pic_type == P_PIC)
2642                 DBG_PRINTF("\n P frm hme sad = %f  ",((float)nor_frm_hme_sad_q10/ (1 << 10)));  */
2643                 rc_put_temp_comp_lap(
2644                     ps_rc_ctxt->rc_hdl, i4_f_sim, nor_frm_hme_sad_q10, rc_pic_type);
2645 
2646                 rc_set_num_scd_in_lap_window(
2647                     ps_rc_ctxt->rc_hdl, i4_num_scd_in_lap_window, num_frames_b4_scd);
2648 
2649                 if(rc_pic_type == I_PIC && updated_window > (ps_rc_ctxt->i4_max_inter_frm_int << 1))
2650                 {
2651                     float i_to_avg_bit_ratio = ihevce_get_i_to_avg_ratio(
2652                         (void *)ps_rc_ctxt,
2653                         ps_rc_lap_out,
2654                         1,
2655                         1,
2656                         1,
2657                         ps_rc_lap_out->ai4_offsets,
2658                         i4_update_delay);
2659                     i_to_avg_bit_ratio = i_to_avg_bit_ratio * 1;
2660                 }
2661 
2662                 /* accumulation of the hme sad over next sub gop to find the temporal comlexity of the sub GOP*/
2663                 if((rc_pic_type == I_PIC) || (rc_pic_type == P_PIC))
2664                 {
2665                     ihevce_compute_temporal_complexity_reset_Kp_Kb(
2666                         ps_rc_lap_out, (void *)ps_rc_ctxt, 1);
2667                 }
2668 
2669                 if(i4_var_sum > MAX_LAP_VAR)
2670                 {
2671                     i4_var_sum = MAX_LAP_VAR;
2672                 }
2673 
2674                 {
2675                     /*Filling for dumping data */
2676 
2677                     ps_rc_ctxt->ai4_num_scd_in_lap_window[i4_enc_frm_id] = i4_num_scd_in_lap_window;
2678                     ps_rc_ctxt->ai4_num_frames_b4_scd[i4_enc_frm_id] = num_frames_b4_scd;
2679                 }
2680             }
2681         }
2682 
2683         if((ps_rc_lap_out->i4_rc_quality_preset == IHEVCE_QUALITY_P6) && (rc_pic_type > P_PIC))
2684         {
2685             ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] = 0;
2686             is_scd_ref_frame = 0;
2687         }
2688         i4_fade_scene = 0;
2689         /*Scene type fade is marked only for P pics which are in fade regions*/
2690         if((ps_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_FADE_IN ||
2691             ps_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_FADE_OUT) &&
2692            (ps_rc_lap_out->i4_rc_temporal_lyr_id == 0))
2693         {
2694             is_scd_ref_frame = 1;
2695             i4_fade_scene = 1;
2696         }
2697 
2698         if((!(is_scd_ref_frame || ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id])) &&
2699            (((is_first_frame_coded(ps_rc_ctxt->rc_hdl)) && (pic_type == IV_I_FRAME)) ||
2700             (pic_type != IV_I_FRAME)))
2701         {
2702             WORD32 i4_is_first_frame_coded = is_first_frame_coded(ps_rc_ctxt->rc_hdl);
2703             i4_is_no_model_scd = 0;
2704             if(call_type == ENC_GET_QP)
2705             {
2706                 if(((0 == i4_model_available) || (!i4_is_first_frame_coded)))
2707                 {
2708                     /*No scene change but model not available*/
2709                     i4_is_no_model_scd = 1;
2710                 }
2711             }
2712         }
2713         else
2714         {
2715             /*actual scene changes*/
2716             i4_is_no_model_scd = 2;
2717         }
2718         /** Pre-enc thread as of now SCD handling is not present */
2719         if(!i4_is_no_model_scd)
2720         {
2721             WORD32 i4_is_first_frame_coded, i4_prev_I_frm_sad, i4_cur_I_frm_sad;
2722             /*Once first frame has been encoded use prev frame intra satd and cur frame satd to alter est intra sad for cur frame*/
2723             i4_is_first_frame_coded = is_first_frame_coded(ps_rc_ctxt->rc_hdl);
2724 
2725             /*prev I frame sad i changes only in enc stage. For pre enc cur and prev will be same*/
2726             if(ps_rc_ctxt->i8_prev_i_frm_cost > 0)
2727             {
2728                 if(i4_is_first_frame_coded && (pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME))
2729                 {
2730                     i4_prev_I_frm_sad = rc_get_prev_frame_intra_sad(ps_rc_ctxt->rc_hdl);
2731                     i4_cur_I_frm_sad = (WORD32)(
2732                         (ps_rc_ctxt->ai8_cur_frm_intra_cost[i4_enc_frm_id] * i4_prev_I_frm_sad) /
2733                         ps_rc_ctxt->i8_prev_i_frm_cost);
2734                     rc_update_prev_frame_intra_sad(ps_rc_ctxt->rc_hdl, i4_cur_I_frm_sad);
2735                 }
2736             }
2737             /*scale previous frame closed loop SAD with current frame HME SAD to be considered as current frame SAD*/
2738             if(i4_is_first_frame_coded && !(pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME) &&
2739                call_type == ENC_GET_QP)
2740             {
2741                 if(ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[rc_pic_type] > 0)
2742                 {
2743                     WORD32 prev_frm_cl_sad = rc_get_prev_frame_sad(ps_rc_ctxt->rc_hdl, rc_pic_type);
2744                     WORD32 cur_frm_est_cl_sad = (WORD32)(
2745                         (ps_rc_ctxt->ai8_cur_frame_coarse_ME_cost[i4_enc_frm_id] *
2746                          prev_frm_cl_sad) /
2747                         ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[rc_pic_type]);
2748                     rc_update_prev_frame_sad(ps_rc_ctxt->rc_hdl, cur_frm_est_cl_sad, rc_pic_type);
2749                 }
2750             }
2751 
2752             if(rc_pic_type == I_PIC && updated_window > (ps_rc_ctxt->i4_max_inter_frm_int << 1))
2753             {
2754                 ps_rc_ctxt->ai_to_avg_bit_ratio[i4_enc_frm_id] = ihevce_get_i_to_avg_ratio(
2755                     (void *)ps_rc_ctxt,
2756                     ps_rc_lap_out,
2757                     1,
2758                     0,
2759                     1,
2760                     ps_rc_lap_out->ai4_offsets,
2761                     i4_update_delay);
2762             }
2763 
2764             ps_rc_ctxt->s_rc_high_lvl_stat.i8_bits_from_finalQP = -1;
2765             i4_frame_qp_q6 = get_frame_level_qp(
2766                 ps_rc_ctxt->rc_hdl,
2767                 rc_pic_type,
2768                 i4_max_frame_bits,
2769                 &i4_cur_est_texture_bits,  //this value is returned by rc
2770                 ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id],
2771                 1,
2772                 ps_rc_ctxt->ai_to_avg_bit_ratio[i4_enc_frm_id],
2773                 ps_rc_lap_out->ps_frame_info,
2774                 ps_rc_lap_out->i4_complexity_bin,
2775                 i4_scene_num, /*no pause resume concept*/
2776                 pi4_tot_bits_estimated,
2777                 &ps_rc_lap_out->i4_is_model_valid,
2778                 &i4_vbv_buf_max_bits,
2779                 &i4_est_tex_bits,
2780                 &i4_cur_est_header_bits,
2781                 &ps_rc_ctxt->s_rc_high_lvl_stat.i4_maxEbfQP,
2782                 &ps_rc_ctxt->s_rc_high_lvl_stat.i4_modelQP,
2783                 &i4_estimate_to_calc_frm_error);
2784             ASSERT(*pi4_tot_bits_estimated != 0);
2785             /** The usage of global table will truncate the input given as qp format and hence will not return very low qp values desirable at very
2786             low bitrate. Hence on the fly calculation is enabled*/
2787 
2788             i4_hevc_frame_qp =
2789                 ihevce_rc_get_scaled_hevce_qp_q6(i4_frame_qp_q6, ps_rc_ctxt->u1_bit_depth);
2790 
2791             if(1 == ps_rc_lap_out->i4_is_model_valid)
2792                 ps_rc_lap_out->i4_is_steady_state = 1;
2793             else
2794                 ps_rc_lap_out->i4_is_steady_state = 0;
2795 
2796             ps_rc_ctxt->s_rc_high_lvl_stat.i4_is_offline_model_used = 0;
2797             ps_rc_ctxt->i8_est_I_pic_header_bits = i4_cur_est_header_bits;
2798         }
2799         else
2800         {
2801             WORD32 i4_count = 0, i4_total_bits, i4_min_error_hevc_qp = 0;
2802             float f_percent_error = 0.0f, f_min_error = 10000.0f;
2803             WORD32 i4_current_bits_estimated = 0;
2804             float i4_i_to_rest_ratio_final;
2805             WORD32 i4_best_br_id = 0;
2806             float af_i_qs[2];
2807             LWORD64 ai8_i_tex_bits[2];
2808             WORD32 i4_ref_qscale = ihevce_rc_get_scaled_mpeg2_qp(
2809                 ps_rc_lap_out->i4_L0_qp, ps_rc_ctxt->ps_rc_quant_ctxt);
2810             WORD32 ai4_header_bits[2];
2811 
2812             ps_rc_lap_out->i4_is_steady_state = 0;
2813 
2814             if(ps_rc_lap_out->i4_L0_qp > 44)
2815                 ps_rc_lap_out->i4_L0_qp = 44;
2816             if(ps_rc_lap_out->i4_L0_qp < 7 - ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset)
2817                 ps_rc_lap_out->i4_L0_qp = 7 - ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset;
2818 
2819             ps_rc_lap_out->i4_L0_qp = ps_rc_lap_out->i4_L0_qp - 9;
2820             ps_rc_lap_out->i4_is_model_valid = 0;
2821             ps_rc_ctxt->s_rc_high_lvl_stat.i4_is_offline_model_used = 1;
2822             ps_rc_ctxt->s_rc_high_lvl_stat.i8_bits_from_finalQP = -1;
2823 
2824             ps_rc_ctxt->i4_normal_inter_pic = (i4_is_no_model_scd == 1);
2825             while(1)
2826             {
2827                 WORD32 i4_frame_qs_q3;
2828                 WORD32 i4_estimate_to_calc_frm_error_temp;
2829 
2830                 i_to_avg_bit_ratio = ihevce_get_i_to_avg_ratio(
2831                     (void *)ps_rc_ctxt,
2832                     ps_rc_lap_out,
2833                     1,
2834                     0,
2835                     1,
2836                     ps_rc_lap_out->ai4_offsets,
2837                     i4_update_delay);
2838 
2839                 ps_rc_ctxt->ai_to_avg_bit_ratio[i4_enc_frm_id] = i_to_avg_bit_ratio;
2840 
2841                 /** Use estimate of header bits from pre-enc*/
2842                 if(1 == i4_is_no_model_scd)
2843                 {
2844                     ps_rc_ctxt->i8_est_I_pic_header_bits =
2845                         get_est_hdr_bits(ps_rc_ctxt->rc_hdl, rc_pic_type);
2846                 }
2847                 else
2848                 {
2849                     WORD32 i4_curr_qscale = ihevce_rc_get_scaled_mpeg2_qp(
2850                         ps_rc_lap_out->i4_L0_qp, ps_rc_ctxt->ps_rc_quant_ctxt);
2851                     /*Assume that 30% of header bits are constant and remaining are dependent on Qp
2852                     and map them accordingly*/
2853                     ps_rc_ctxt->i8_est_I_pic_header_bits = (LWORD64)(
2854                         (.3 * ps_rc_lap_out->i8_est_I_pic_header_bits +
2855                          (1. - .3) * ps_rc_lap_out->i8_est_I_pic_header_bits * i4_ref_qscale) /
2856                         i4_curr_qscale);
2857                 }
2858 
2859                 /*get qp for scene cut frame based on offline data*/
2860                 index = ihevce_get_offline_index(
2861                     ps_rc_ctxt, ps_rc_lap_out->i4_num_pels_in_frame_considered);
2862 
2863                 /*Sub pic rC bits extraction */
2864                 i4_frame_qs_q3 = rc_get_qp_for_scd_frame(
2865                     ps_rc_ctxt->rc_hdl,
2866                     I_PIC,
2867                     ps_rc_lap_out->i8_frame_satd_act_accum,
2868                     ps_rc_lap_out->i4_num_pels_in_frame_considered,
2869                     (WORD32)ps_rc_ctxt->i8_est_I_pic_header_bits,
2870                     ps_rc_ctxt->ai4_lap_f_sim[i4_enc_frm_id],
2871                     (void *)&g_offline_i_model_coeff[index][0],
2872                     i_to_avg_bit_ratio,
2873                     1,
2874                     ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id],
2875                     ps_rc_lap_out->ps_frame_info,
2876                     ps_rc_ctxt->i4_rc_pass,
2877                     (rc_pic_type != I_PIC),
2878                     ((ps_rc_lap_out->i4_rc_temporal_lyr_id != ps_rc_ctxt->i4_max_temporal_lyr) ||
2879                      (!ps_rc_ctxt->i4_max_temporal_lyr)),
2880                     1,
2881                     &i4_total_bits,
2882                     &i4_current_bits_estimated,
2883                     ps_rc_lap_out->i4_use_offline_model_2pass,
2884                     ai8_i_tex_bits,
2885                     af_i_qs,
2886                     i4_best_br_id,
2887                     &i4_estimate_to_calc_frm_error_temp);
2888 
2889                 i4_hevc_frame_qp = ihevce_rc_get_scaled_hevc_qp_from_qs_q3(
2890                     i4_frame_qs_q3, ps_rc_ctxt->ps_rc_quant_ctxt);
2891 
2892                 /*Get corresponding q scale*/
2893                 i4_frame_qp =
2894                     ihevce_rc_get_scaled_mpeg2_qp(i4_hevc_frame_qp, ps_rc_ctxt->ps_rc_quant_ctxt);
2895 
2896                 if(i4_hevc_frame_qp > ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qp)
2897                     i4_hevc_frame_qp = ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qp;
2898 
2899                 {
2900                     WORD32 i4_init_qscale = ihevce_rc_get_scaled_mpeg2_qp(
2901                         ps_rc_lap_out->i4_L0_qp, ps_rc_ctxt->ps_rc_quant_ctxt);
2902                     f_percent_error = (float)(abs(i4_init_qscale - i4_frame_qp)) / i4_init_qscale;
2903                     if(f_percent_error < f_min_error)
2904                     {
2905                         f_min_error = f_percent_error;
2906                         i4_min_error_hevc_qp = i4_hevc_frame_qp;
2907                         i4_i_to_rest_ratio_final = i_to_avg_bit_ratio;
2908                         /*Get the bits estimated for least error*/
2909                         *pi4_tot_bits_estimated = i4_current_bits_estimated;
2910                         i4_estimate_to_calc_frm_error = i4_estimate_to_calc_frm_error_temp;
2911                     }
2912                     else
2913                     {}
2914                     ASSERT(*pi4_tot_bits_estimated != 0);
2915                 }
2916                 i4_count++;
2917                 if(/*(ps_rc_lap_out->i4_L0_qp == i4_hevc_frame_qp) ||*/ (i4_count > 17))
2918                     break;
2919                 ps_rc_lap_out->i4_L0_qp++;
2920             }
2921             ps_rc_lap_out->i4_L0_qp = i4_min_error_hevc_qp;
2922 
2923             i4_hevc_frame_qp = i4_min_error_hevc_qp;
2924             if(2 == i4_is_no_model_scd)
2925             {
2926                 /* SGI & Enc Loop Parallelism related changes*/
2927 
2928                 /*model reset not required if it is first frame*/
2929                 if(ps_rc_ctxt->i4_is_first_frame_encoded && !i4_fade_scene &&
2930                    !ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id] &&
2931                    !ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] &&
2932                    !ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] &&
2933                    !ps_rc_ctxt->ai4_is_cmplx_change_reset_model[i4_enc_frm_id])
2934                 {
2935                     ps_rc_ctxt->ai4_is_frame_scd[i4_enc_frm_id] = 1;
2936                     /*reset all pic type is first frame encoded flag*/
2937 
2938                     ASSERT(pic_type == IV_IDR_FRAME || pic_type == IV_I_FRAME);
2939                 }
2940                 else if(ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id])
2941                 {
2942                     rc_reset_first_frame_coded_flag(ps_rc_ctxt->rc_hdl, I_PIC);
2943                     ASSERT(rc_pic_type == I_PIC);
2944                     ASSERT(ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] == 0);
2945                 }
2946                 else if(
2947                     ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] ||
2948                     ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] ||
2949                     ps_rc_ctxt->ai4_is_cmplx_change_reset_model[i4_enc_frm_id] || i4_fade_scene)
2950                 {
2951                     /*Only when there are back to back scene cuts we need a non- Ipic will be marked as scene cut*/
2952                     /* Same path can also be followed during pause to resume detection to determine cur frame qp however handling during update is different*/
2953                     WORD32 i4_prev_qp, i, i4_new_qp_hevc_qp, I_hevc_qp, cur_hevc_qp;
2954 
2955                     /*both cannot be set at same time since lap cannot mark same frame as both scene cut and pause to resume flag*/
2956                     ASSERT(
2957                         (ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] &&
2958                          ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id]) == 0);
2959 
2960                     I_hevc_qp = i4_hevc_frame_qp;
2961 
2962                     /*alter ai4_prev_pic_hevc_qp so that qp restriction ll not let even other pictures temporary scd are thrashed*/
2963                     //if(ps_rc_lap_out->i4_rc_temporal_lyr_id != ps_rc_ctxt->i4_max_temporal_lyr)
2964                     {
2965                         if(ps_rc_ctxt->i4_field_pic == 0)
2966                         {
2967                             for(i = 1; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
2968                             {
2969                                 i4_prev_qp = ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i];
2970                                 i4_new_qp_hevc_qp = I_hevc_qp + i;
2971                                 i4_new_qp_hevc_qp = ihevce_clip_min_max_qp(
2972                                     ps_rc_ctxt, i4_new_qp_hevc_qp, (picture_type_e)i, i - 1);
2973                                 if(i4_prev_qp < i4_new_qp_hevc_qp)
2974                                 {
2975                                     ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i] =
2976                                         i4_new_qp_hevc_qp;
2977                                 }
2978                             }
2979                         }
2980                         else
2981                         { /*field case*/
2982 
2983                             for(i = 1; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
2984                             {
2985                                 i4_prev_qp = ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i];
2986                                 i4_new_qp_hevc_qp = I_hevc_qp + i;
2987                                 i4_new_qp_hevc_qp = ihevce_clip_min_max_qp(
2988                                     ps_rc_ctxt, i4_new_qp_hevc_qp, (picture_type_e)i, i - 1);
2989                                 if(i4_prev_qp < i4_new_qp_hevc_qp)
2990                                 {
2991                                     ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i] =
2992                                         i4_new_qp_hevc_qp;
2993                                 }
2994 
2995                                 i4_prev_qp =
2996                                     ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i + FIELD_OFFSET];
2997                                 i4_new_qp_hevc_qp = I_hevc_qp + i;
2998                                 i4_new_qp_hevc_qp = ihevce_clip_min_max_qp(
2999                                     ps_rc_ctxt, i4_new_qp_hevc_qp, (picture_type_e)i, i - 1);
3000                                 if(i4_prev_qp < i4_new_qp_hevc_qp)
3001                                 {
3002                                     ps_rc_ctxt
3003                                         ->ai4_prev_pic_hevc_qp[i4_scene_num][i + FIELD_OFFSET] =
3004                                         i4_new_qp_hevc_qp;
3005                                 }
3006                             }
3007                         }
3008                     }
3009                     {
3010                         WORD32 i4_updated_qp = ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i];
3011                         WORD32 i4_scale;
3012 
3013                         if(I_hevc_qp == i4_updated_qp)
3014                             i4_scale = 16;
3015                         else if(I_hevc_qp == (i4_updated_qp - 1))
3016                             i4_scale = 14;
3017                         else if(I_hevc_qp == (i4_updated_qp - 2))
3018                             i4_scale = 12;
3019                         else
3020                             i4_scale = 10;
3021 
3022                         *pi4_tot_bits_estimated = (i4_scale * (*pi4_tot_bits_estimated)) >> 4;
3023                         i4_estimate_to_calc_frm_error =
3024                             (i4_scale * i4_estimate_to_calc_frm_error) >> 4;
3025                     }
3026                     if(call_type == ENC_GET_QP)
3027                     {
3028                         ps_rc_lap_out->i8_est_text_bits = *pi4_tot_bits_estimated;
3029                     }
3030                     ASSERT(*pi4_tot_bits_estimated != 0);
3031 
3032                     /*use previous frame qp of same pic type or SCD i frame qp with offset whichever is maximum*/
3033                     /*For field case adding of  grater than 4 results in the qp increasing greatly when compared to previous pics/fields*/
3034                     if(rc_pic_type <= FIELD_OFFSET)
3035                         cur_hevc_qp = I_hevc_qp + rc_pic_type;
3036                     else
3037                         cur_hevc_qp = I_hevc_qp + (rc_pic_type - FIELD_OFFSET);
3038 
3039                     i4_prev_qp = ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type];
3040 
3041                     if((cur_hevc_qp < i4_prev_qp) && (ps_rc_ctxt->i4_num_active_pic_type > 2) &&
3042                        (is_first_frame_coded(ps_rc_ctxt->rc_hdl)) && (!i4_fade_scene))
3043                     {
3044                         cur_hevc_qp = i4_prev_qp;
3045                     }
3046                     i4_frame_qp =
3047                         ihevce_rc_get_scaled_mpeg2_qp(cur_hevc_qp, ps_rc_ctxt->ps_rc_quant_ctxt);
3048                     i4_hevc_frame_qp = cur_hevc_qp;
3049                     //ps_rc_ctxt->i4_is_non_I_scd_pic = 0;
3050 
3051                     rc_reset_first_frame_coded_flag(ps_rc_ctxt->rc_hdl, rc_pic_type);
3052                 }
3053                 else
3054                 {}
3055             }
3056             if((1 == i4_is_no_model_scd) && (call_type == ENC_GET_QP))
3057             {
3058                 WORD32 i4_clip_QP;
3059                 i4_frame_qp_q6 =
3060                     clip_qp_based_on_prev_ref(ps_rc_ctxt->rc_hdl, rc_pic_type, 1, i4_scene_num);
3061                 i4_clip_QP =
3062                     ihevce_rc_get_scaled_hevce_qp_q6(i4_frame_qp_q6, ps_rc_ctxt->u1_bit_depth);
3063                 if(ps_rc_ctxt->i4_rc_pass != 2)
3064                 {
3065                     i4_hevc_frame_qp = i4_clip_QP;
3066                 }
3067                 if((rc_pic_type == P_PIC) || (rc_pic_type == P1_PIC))
3068                 {
3069                     *pi4_tot_bits_estimated = (*pi4_tot_bits_estimated * 11) >> 4; /* P picture*/
3070                     i4_estimate_to_calc_frm_error = (i4_estimate_to_calc_frm_error * 11) >> 4;
3071                 }
3072                 else if((rc_pic_type == B_PIC) || (rc_pic_type == BB_PIC))
3073                 {
3074                     *pi4_tot_bits_estimated = (*pi4_tot_bits_estimated * 9) >> 4; /* B layer 1*/
3075                     i4_estimate_to_calc_frm_error = (i4_estimate_to_calc_frm_error * 9) >> 4;
3076                 }
3077                 else if((rc_pic_type == B1_PIC) || (rc_pic_type == B11_PIC))
3078                 {
3079                     *pi4_tot_bits_estimated = (*pi4_tot_bits_estimated * 7) >> 4; /* B layer 2*/
3080                     i4_estimate_to_calc_frm_error = (i4_estimate_to_calc_frm_error * 7) >> 4;
3081                 }
3082                 else if((rc_pic_type == B2_PIC) || (rc_pic_type == B22_PIC))
3083                 {
3084                     *pi4_tot_bits_estimated = (*pi4_tot_bits_estimated * 5) >> 4; /* B layer 3*/
3085                     i4_estimate_to_calc_frm_error = (i4_estimate_to_calc_frm_error * 5) >> 4;
3086                 }
3087             }
3088             rc_add_est_tot(ps_rc_ctxt->rc_hdl, *pi4_tot_bits_estimated);
3089         }
3090 
3091         ASSERT(i4_hevc_frame_qp >= -ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset);
3092 
3093         /*constraint qp swing based on neighbour frames*/
3094         if(is_first_frame_coded(ps_rc_ctxt->rc_hdl))
3095         {
3096             if(ps_rc_ctxt->i4_field_pic == 0)
3097             {
3098                 /*In dissolve case the p frame comes before an I pic and ref b comes after then what
3099                 happens is b frame qp is restricted by the p frame qp so changed it to prev ref pic type*/
3100                 if(rc_pic_type != I_PIC && rc_pic_type != P_PIC)
3101                 {
3102                     if(ps_rc_lap_out->i4_rc_temporal_lyr_id == 1)
3103                     {
3104                         picture_type_e prev_ref_pic_type =
3105                             rc_getprev_ref_pic_type(ps_rc_ctxt->rc_hdl);
3106 
3107                         if(i4_hevc_frame_qp >
3108                            ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][prev_ref_pic_type] + 3)
3109                         {
3110                             if(ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][prev_ref_pic_type] >
3111                                0)
3112                                 i4_hevc_frame_qp =
3113                                     ps_rc_ctxt
3114                                         ->ai4_prev_pic_hevc_qp[i4_scene_num][prev_ref_pic_type] +
3115                                     3;
3116                         }
3117                     }
3118                     else if(
3119                         i4_hevc_frame_qp >
3120                         (ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type - 1] + 3))
3121                     {
3122                         /*allow max of +3 compared to previous frame*/
3123                         if(ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type - 1] > 0)
3124                             i4_hevc_frame_qp =
3125                                 ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type - 1] + 3;
3126                     }
3127                 }
3128 
3129                 if((rc_pic_type != I_PIC && rc_pic_type != P_PIC) &&
3130                    (i4_hevc_frame_qp <
3131                     ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type - 1]))
3132                 {
3133                     i4_hevc_frame_qp =
3134                         ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type - 1];
3135                 }
3136 
3137                 /** Force non-ref B pic qp to be ref_B_PIC_qp - 1. This is not valid for when max teporla later is less than 2*/
3138                 if(temporal_layer_id == ps_rc_ctxt->i4_max_temporal_lyr &&
3139                    ps_rc_ctxt->i4_max_temporal_lyr > 1)
3140                 {
3141                     i4_hevc_frame_qp =
3142                         ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type - 1] + 1;
3143                 }
3144             }
3145             else /*for field case*/
3146             {
3147                 if(ps_rc_lap_out->i4_rc_temporal_lyr_id >= 1)
3148                 {
3149                     /*To make the comparison of qp with the top field's of previous layer tempor layer id matches with the pic type. */
3150                     if(i4_hevc_frame_qp >
3151                        ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num]
3152                                                        [ps_rc_lap_out->i4_rc_temporal_lyr_id] +
3153                            3)
3154                     {
3155                         /*allow max of +3 compared to previous frame*/
3156                         if(0 <
3157                            ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num]
3158                                                            [ps_rc_lap_out->i4_rc_temporal_lyr_id])
3159                             i4_hevc_frame_qp =
3160                                 ps_rc_ctxt
3161                                     ->ai4_prev_pic_hevc_qp[i4_scene_num]
3162                                                           [ps_rc_lap_out->i4_rc_temporal_lyr_id] +
3163                                 3;
3164                     }
3165                     if(i4_hevc_frame_qp <
3166                        ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num]
3167                                                        [ps_rc_lap_out->i4_rc_temporal_lyr_id])
3168                     {
3169                         i4_hevc_frame_qp =
3170                             ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num]
3171                                                             [ps_rc_lap_out->i4_rc_temporal_lyr_id];
3172                     }
3173 
3174                     /** Force non-ref B pic qp to be ref_B_PIC_qp - 1. This is not valid for when max teporla later is less than 2*/
3175                     if(temporal_layer_id == ps_rc_ctxt->i4_max_temporal_lyr &&
3176                        ps_rc_ctxt->i4_max_temporal_lyr > 1)
3177                     {
3178                         i4_hevc_frame_qp =
3179                             ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num]
3180                                                             [ps_rc_lap_out->i4_rc_temporal_lyr_id] +
3181                             1;
3182                     }
3183                 }
3184                 /** At lower range qp swing for same pic type is also imposed to make sure
3185                     qp does not fall from 10 to 4 since they differ by only one q scale*/
3186             }
3187         }
3188 
3189         /**clip to min qp which is user configurable*/
3190         i4_hevc_frame_qp = ihevce_clip_min_max_qp(
3191             ps_rc_ctxt, i4_hevc_frame_qp, rc_pic_type, ps_rc_lap_out->i4_rc_temporal_lyr_id);
3192 
3193 #if 1  //FRAME_PARALLEL_LVL
3194         ps_rc_ctxt->i4_est_text_bits_ctr_get_qp++;  //ELP_RC
3195         ps_rc_ctxt->i4_est_text_bits_ctr_get_qp =
3196             (ps_rc_ctxt->i4_est_text_bits_ctr_get_qp % (ps_rc_ctxt->i4_num_frame_parallel));
3197 #endif
3198         /** the estimates are reset only duing enc call*/
3199 
3200 #if USE_USER_FIRST_FRAME_QP
3201         /*I_PIC check is necessary coz pre-enc can query for qp even before first frame update has happened*/
3202         if(!ps_rc_ctxt->i4_is_first_frame_encoded && rc_pic_type == I_PIC)
3203         {
3204             i4_hevc_frame_qp = ps_rc_ctxt->i4_init_frame_qp_user;
3205             DBG_PRINTF("FIXED START QP PATH *************************\n");
3206         }
3207 #endif
3208     }
3209 
3210     if(CONST_QP != e_rc_type)
3211     {
3212         ASSERT(*pi4_tot_bits_estimated != 0);
3213     }
3214 
3215     ps_rc_ctxt->s_rc_high_lvl_stat.i4_finalQP = i4_hevc_frame_qp;
3216     if(ps_rc_lap_out->i4_is_model_valid)
3217     {
3218         get_bits_for_final_qp(
3219             ps_rc_ctxt->rc_hdl,
3220             &ps_rc_ctxt->s_rc_high_lvl_stat.i4_modelQP,
3221             &ps_rc_ctxt->s_rc_high_lvl_stat.i4_maxEbfQP,
3222             &ps_rc_ctxt->s_rc_high_lvl_stat.i8_bits_from_finalQP,
3223             i4_hevc_frame_qp,
3224             ihevce_rc_get_scaled_mpeg2_qp_q6(
3225                 i4_hevc_frame_qp + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset,
3226                 ps_rc_ctxt->u1_bit_depth),
3227             i4_cur_est_header_bits,
3228             i4_est_tex_bits,
3229             i4_vbv_buf_max_bits,
3230             rc_pic_type,
3231             ps_rc_lap_out->i4_rc_display_num);
3232     }
3233     i4_deltaQP = ihevce_ebf_based_rc_correction_to_avoid_overflow(
3234         ps_rc_ctxt, ps_rc_lap_out, pi4_tot_bits_estimated);
3235     i4_hevc_frame_qp += i4_deltaQP;
3236 
3237     /**clip to min qp which is user configurable*/
3238     i4_hevc_frame_qp = ihevce_clip_min_max_qp(
3239         ps_rc_ctxt, i4_hevc_frame_qp, rc_pic_type, ps_rc_lap_out->i4_rc_temporal_lyr_id);
3240 
3241     /*set estimate status for frame level error calculation*/
3242     if(i4_estimate_to_calc_frm_error > 0)
3243     {
3244         rc_set_estimate_status(
3245             ps_rc_ctxt->rc_hdl,
3246             i4_estimate_to_calc_frm_error - ps_rc_ctxt->i8_est_I_pic_header_bits,
3247             ps_rc_ctxt->i8_est_I_pic_header_bits,
3248             ps_rc_ctxt->i4_est_text_bits_ctr_get_qp);
3249     }
3250     else
3251     {
3252         rc_set_estimate_status(
3253             ps_rc_ctxt->rc_hdl,
3254             -1,
3255             ps_rc_ctxt->i8_est_I_pic_header_bits,
3256             ps_rc_ctxt->i4_est_text_bits_ctr_get_qp);
3257     }
3258 
3259     ps_rc_lap_out->i8_est_text_bits = *pi4_tot_bits_estimated;
3260 
3261     /*B pictures which are in fades will take the highest QP of either side of P pics*/
3262     if(ps_rc_lap_out->i4_rc_pic_type == IV_B_FRAME &&
3263        (ps_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_FADE_IN ||
3264         ps_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_FADE_OUT))
3265     {
3266         i4_hevc_frame_qp =
3267             MAX(ps_rc_ctxt->ai4_last_tw0_lyr0_pic_qp[0], ps_rc_ctxt->ai4_last_tw0_lyr0_pic_qp[1]);
3268     }
3269 
3270     /*saving the last two pics of layer 0*/
3271     if(0 == ps_rc_lap_out->i4_rc_temporal_lyr_id)
3272     {
3273         ps_rc_ctxt->ai4_last_tw0_lyr0_pic_qp[1] = ps_rc_ctxt->ai4_last_tw0_lyr0_pic_qp[0];
3274         ps_rc_ctxt->ai4_last_tw0_lyr0_pic_qp[0] = i4_hevc_frame_qp;
3275     }
3276 
3277     return i4_hevc_frame_qp;
3278 }
3279 
3280 /*##########################################################*/
3281 /******* END OF ENC THRD QP QUERY FUNCTIONS ****************/
3282 /*########################################################*/
3283 
3284 /*####################################################*/
3285 /******* START OF I2AVG RATIO FUNCTIONS **************/
3286 /*##################################################*/
3287 
3288 /**
3289 ******************************************************************************
3290 *
3291 *  @brief function to get i_to_avg_rest at scene cut frame based on data available from LAP
3292 *
3293 *  @par   Description
3294 *
3295 *  @param[in]   pv_rc_ctxt
3296 *               void pointer to rc ctxt
3297 *  @param[in]   ps_rc_lap_out : pointer to lap out structure
3298 *  @param[in]   i4_update_delay : The Delay in the update. This can happen for dist. case!
3299 *               All decision should consider this delay for updation!
3300 *  @return      WORD32 i_to_rest bit ratio
3301 *
3302 ******************************************************************************
3303 */
ihevce_get_i_to_avg_ratio(void * pv_rc_ctxt,rc_lap_out_params_t * ps_rc_lap_out,WORD32 i_to_p_qp_offset,WORD32 i4_offset_flag,WORD32 i4_call_type,WORD32 ai4_qp_offsets[4],WORD32 i4_update_delay)3304 float ihevce_get_i_to_avg_ratio(
3305     void *pv_rc_ctxt,
3306     rc_lap_out_params_t *ps_rc_lap_out,
3307     WORD32 i_to_p_qp_offset,
3308     WORD32 i4_offset_flag,
3309     WORD32 i4_call_type,
3310     WORD32 ai4_qp_offsets[4],
3311     WORD32 i4_update_delay)
3312 {
3313     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
3314     WORD32 i = 0, k = 0, num_frames_in_lap[MAX_PIC_TYPE] = { 0 }, ai4_pic_dist[MAX_PIC_TYPE],
3315            ai4_pic_dist_in_cur_gop[MAX_PIC_TYPE] = { 0 };
3316     WORD32 i4_num_b, i4_num_frms_traversed_in_lap = 0, total_frms_considered = 0,
3317                      i4_flag_i_frame_exit = 0, u4_rc_scene_number;
3318     rc_lap_out_params_t *ps_cur_rc_lap_out = ps_rc_lap_out;
3319 
3320     rc_lap_out_params_t *ps_cur_rc_lap_out_I = ps_rc_lap_out;
3321     double complexity[MAX_PIC_TYPE] = { 0 }, d_first_i_complexity = 0, d_first_p_complexity = 0.0f,
3322            cur_lambda_modifer, den = 0, average_intra_complexity = 0;
3323     double i_frm_lambda_modifier;
3324     float i_to_rest_bit_ratio = 8.00;
3325     picture_type_e curr_rc_pic_type;
3326     LWORD64 i8_l1_analysis_lap_comp = 0;
3327     WORD32 i4_intra_frame_interval = rc_get_intra_frame_interval(ps_rc_ctxt->rc_hdl);
3328     UWORD32 u4_L1_based_lap_complexity_q7 = 0;
3329     WORD32 i4_frame_qp = 0, i4_I_frame_qp = 0;
3330 
3331     WORD32 ai4_lambda_offsets[5] = { -3, -2, 2, 6, 7 };
3332     /* The window for which your update is guaranteed */
3333     WORD32 updated_window = ps_rc_ctxt->i4_num_frame_in_lap_window - i4_update_delay;
3334 
3335     ASSERT(ps_rc_ctxt->i4_rc_pass != 2);
3336     rc_get_pic_distribution(ps_rc_ctxt->rc_hdl, &ai4_pic_dist[0]);
3337 
3338     if(ps_rc_ctxt->i4_max_temporal_lyr)
3339     {
3340         i4_num_b = ((WORD32)pow((float)2, ps_rc_ctxt->i4_max_temporal_lyr)) - 1;
3341     }
3342     else
3343     {
3344         i4_num_b = 0;
3345     }
3346     i_frm_lambda_modifier = ihevce_get_frame_lambda_modifier((WORD8)I_PIC, 0, 1, 1, i4_num_b);
3347     /* check should be wrt inter frame interval*/
3348     /*If lap frames are not sufficient return default ratio*/
3349     u4_rc_scene_number = ps_cur_rc_lap_out_I->u4_rc_scene_num;
3350 
3351     if(updated_window < 4)
3352     {
3353         return i_to_rest_bit_ratio;
3354     }
3355 
3356     k = 0;
3357     if(ps_cur_rc_lap_out != NULL)
3358     {
3359         WORD32 i4_temp_frame_qp;
3360 
3361         if(ps_cur_rc_lap_out->i4_L0_qp == -1)
3362         {
3363             i4_frame_qp = ps_cur_rc_lap_out->i4_L1_qp;
3364             i4_I_frame_qp = ps_cur_rc_lap_out->i4_L1_qp - 3;
3365         }
3366         else
3367         {
3368             i4_frame_qp = ps_cur_rc_lap_out->i4_L0_qp;
3369             i4_I_frame_qp = ps_cur_rc_lap_out->i4_L0_qp - 3;
3370         }
3371 
3372         do
3373         {
3374             curr_rc_pic_type = ihevce_rc_conv_pic_type(
3375                 (IV_PICTURE_CODING_TYPE_T)ps_cur_rc_lap_out->i4_rc_pic_type,
3376                 ps_rc_ctxt->i4_field_pic,
3377                 ps_cur_rc_lap_out->i4_rc_temporal_lyr_id,
3378                 ps_cur_rc_lap_out->i4_is_bottom_field,
3379                 ps_rc_ctxt->i4_top_field_first);
3380             cur_lambda_modifer = ihevce_get_frame_lambda_modifier(
3381                 (WORD8)curr_rc_pic_type,
3382                 ps_cur_rc_lap_out->i4_rc_temporal_lyr_id,
3383                 1,
3384                 ps_cur_rc_lap_out->i4_rc_is_ref_pic,
3385                 i4_num_b);
3386             if(curr_rc_pic_type == I_PIC)
3387             {
3388                 i4_temp_frame_qp = i4_frame_qp + ai4_lambda_offsets[curr_rc_pic_type];
3389             }
3390             else
3391             {
3392                 i4_temp_frame_qp =
3393                     i4_frame_qp + ai4_lambda_offsets[ps_cur_rc_lap_out->i4_rc_temporal_lyr_id + 1];
3394                 i4_temp_frame_qp =
3395                     i4_temp_frame_qp +
3396                     ps_cur_rc_lap_out->ai4_offsets[ps_cur_rc_lap_out->i4_rc_temporal_lyr_id + 1];
3397             }
3398 
3399             i4_temp_frame_qp = CLIP3(i4_temp_frame_qp, 1, 51);
3400             i4_I_frame_qp = CLIP3(i4_I_frame_qp, 1, 51);
3401 
3402             if(curr_rc_pic_type == I_PIC)
3403             {
3404                 complexity[I_PIC] += (double)ps_cur_rc_lap_out->ai8_pre_intra_sad[i4_I_frame_qp];
3405                 if(total_frms_considered == 0)
3406                     d_first_i_complexity =
3407                         (double)ps_cur_rc_lap_out->ai8_pre_intra_sad[i4_I_frame_qp];
3408 
3409                 num_frames_in_lap[I_PIC]++;
3410                 i8_l1_analysis_lap_comp +=
3411                     (LWORD64)(1.17 * ps_cur_rc_lap_out->i8_raw_pre_intra_sad);
3412             }
3413             else
3414             {
3415                 if((num_frames_in_lap[P_PIC] == 0) && (curr_rc_pic_type == P_PIC))
3416                     d_first_p_complexity =
3417                         (double)ps_cur_rc_lap_out->ai8_pre_intra_sad[i4_I_frame_qp];
3418 
3419                 if(total_frms_considered == 0)
3420                 {
3421                     num_frames_in_lap[I_PIC]++;
3422                     {
3423                         complexity[I_PIC] +=
3424                             (double)ps_cur_rc_lap_out->ai8_pre_intra_sad[i4_I_frame_qp];
3425                         d_first_i_complexity =
3426                             (double)ps_cur_rc_lap_out->ai8_pre_intra_sad[i4_I_frame_qp];
3427                     }
3428                 }
3429                 else
3430                 {
3431                     /*SAD is scaled according the lambda parametrs use to make it proportional to bits consumed in the end*/
3432 #if !USE_SQRT
3433                     //complexity[curr_rc_pic_type] += (double)(MIN(ps_cur_rc_lap_out->ai8_frame_acc_coarse_me_sad[i4_temp_frame_qp],ps_cur_rc_lap_out->i8_pre_intra_sad)/(/*(cur_lambda_modifer/i_frm_lambda_modifier) * */pow(1.125,(ps_rc_lap_out->i4_rc_temporal_lyr_id + 1/*i_to_p_qp_offset*/))));
3434                     if((curr_rc_pic_type > P_PIC) &&
3435                        (ps_rc_lap_out->i4_rc_quality_preset == IHEVCE_QUALITY_P6))
3436                         complexity[curr_rc_pic_type] +=
3437                             (double)(ps_cur_rc_lap_out->ai8_frame_acc_coarse_me_sad
3438                                          [i4_temp_frame_qp]);  // /(/*(cur_lambda_modifer/i_frm_lambda_modifier) * */pow(1.125,(ps_rc_lap_out->i4_rc_temporal_lyr_id + 1/*i_to_p_qp_offset*/))));
3439                     else
3440                         complexity[curr_rc_pic_type] += (double)(MIN(
3441                             ps_cur_rc_lap_out->ai8_frame_acc_coarse_me_sad[i4_temp_frame_qp],
3442                             ps_cur_rc_lap_out->ai8_pre_intra_sad
3443                                 [i4_temp_frame_qp]));  ///(/*(cur_lambda_modifer/i_frm_lambda_modifier) * */pow(1.125,(ps_rc_lap_out->i4_rc_temporal_lyr_id + 1/*i_to_p_qp_offset*/))));
3444 
3445 #else
3446                     complexity[curr_rc_pic_type] +=
3447                         MIN(ps_cur_rc_lap_out->ai8_frame_acc_coarse_me_sad[i4_temp_frame_qp],
3448                             ps_cur_rc_lap_out->i8_pre_intra_sad) /
3449                         (sqrt(cur_lambda_modifer / i_frm_lambda_modifier) *
3450                          pow(1.125, (ps_rc_lap_out->i4_rc_temporal_lyr_id + 1)));
3451 #endif
3452                     num_frames_in_lap[curr_rc_pic_type]++;
3453                 }
3454                 i8_l1_analysis_lap_comp += (LWORD64)(
3455                     (float)ps_cur_rc_lap_out->i8_raw_l1_coarse_me_sad /
3456                     pow(1.125, curr_rc_pic_type));
3457             }
3458 
3459             if(ps_rc_lap_out->i4_rc_quality_preset == IHEVCE_QUALITY_P6)
3460             {
3461                 if(curr_rc_pic_type < B_PIC)
3462                 {
3463                     /*accumulate average intra sad*/
3464                     average_intra_complexity +=
3465                         ps_cur_rc_lap_out
3466                             ->ai8_pre_intra_sad[i4_I_frame_qp] /*/i_frm_lambda_modifier*/;
3467                     i4_num_frms_traversed_in_lap++;
3468                 }
3469             }
3470             else
3471             {
3472                 /*accumulate average intra sad*/
3473                 average_intra_complexity +=
3474                     ps_cur_rc_lap_out->ai8_pre_intra_sad[i4_I_frame_qp] /*/i_frm_lambda_modifier*/;
3475                 i4_num_frms_traversed_in_lap++;
3476             }
3477 
3478             ai4_pic_dist_in_cur_gop[curr_rc_pic_type]++;
3479             i++;
3480             total_frms_considered++;
3481             i4_num_frms_traversed_in_lap++;
3482             ps_cur_rc_lap_out = (rc_lap_out_params_t *)ps_cur_rc_lap_out->ps_rc_lap_out_next_encode;
3483 
3484             if((ps_cur_rc_lap_out == NULL) ||
3485                ((total_frms_considered + k) == i4_intra_frame_interval) || (i >= updated_window))
3486             {
3487                 break;
3488             }
3489 
3490             if((i >= (ps_rc_ctxt->i4_next_sc_i_in_rc_look_ahead - k) ||
3491                 (ps_cur_rc_lap_out->i4_rc_pic_type == IV_I_FRAME) ||
3492                 (ps_cur_rc_lap_out->i4_rc_pic_type == IV_IDR_FRAME)) &&
3493                (i4_offset_flag == 1))
3494             {
3495                 break;
3496             }
3497             /*If an I frame enters the lookahead it can cause bit allocation to go bad
3498             if corresponding p/b frames are absent*/
3499             if(((total_frms_considered + k) > (WORD32)(0.75f * i4_intra_frame_interval)) &&
3500                ((ps_cur_rc_lap_out->i4_rc_pic_type == IV_I_FRAME) ||
3501                 (ps_cur_rc_lap_out->i4_rc_pic_type == IV_IDR_FRAME)))
3502             {
3503                 i4_flag_i_frame_exit = 1;
3504                 break;
3505             }
3506 
3507         } while(1);
3508 
3509         if(total_frms_considered > 0)
3510         {
3511             float lap_L1_comp =
3512                 (float)i8_l1_analysis_lap_comp /
3513                 (total_frms_considered * ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width);
3514 
3515             lap_L1_comp = rc_get_offline_normalized_complexity(
3516                 ps_rc_ctxt->u4_intra_frame_interval,
3517                 ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width,
3518                 lap_L1_comp,
3519                 ps_rc_ctxt->i4_rc_pass);
3520 
3521             u4_L1_based_lap_complexity_q7 = (WORD32)((lap_L1_comp * (1 << 7)) + .05f);
3522         }
3523         else
3524         {
3525             u4_L1_based_lap_complexity_q7 = 25;
3526         }
3527 
3528         if(i4_call_type == 1)
3529         {
3530             if(num_frames_in_lap[0] > 0)
3531             {
3532                 float f_curr_i_to_sum = (float)(d_first_i_complexity / complexity[0]);
3533                 f_curr_i_to_sum = CLIP3(f_curr_i_to_sum, 0.1f, 100.0f);
3534                 rc_set_i_to_sum_api_ba(ps_rc_ctxt->rc_hdl, f_curr_i_to_sum);
3535             }
3536         }
3537 
3538         for(i = 0; i < MAX_PIC_TYPE; i++)
3539         {
3540             if(num_frames_in_lap[i] > 0)
3541             {
3542                 complexity[i] = complexity[i] / num_frames_in_lap[i];
3543             }
3544         }
3545         /*for non - I scd case it is possible that entire LAP window might not have intra picture. Consider average intra sad when
3546         atleast one I pic is not available*/
3547         if(num_frames_in_lap[I_PIC] == 0)
3548         {
3549             ASSERT(i4_num_frms_traversed_in_lap);
3550             complexity[I_PIC] = average_intra_complexity / i4_num_frms_traversed_in_lap;
3551         }
3552         /*get picture type distribution in LAP*/
3553         if(num_frames_in_lap[I_PIC] == 0)
3554         {
3555             rc_get_pic_distribution(ps_rc_ctxt->rc_hdl, &ai4_pic_dist[0]);
3556         }
3557         else
3558         {
3559             memmove(ai4_pic_dist, num_frames_in_lap, sizeof(WORD32) * MAX_PIC_TYPE);
3560         }
3561 
3562         {
3563             WORD32 num_inter_pic = 0;
3564             for(i = 1; i < MAX_PIC_TYPE; i++)
3565             {
3566                 den += complexity[i] * ai4_pic_dist[i];
3567             }
3568 
3569             for(i = 1; i < MAX_PIC_TYPE; i++)
3570             {
3571                 num_inter_pic += ai4_pic_dist[i];
3572             }
3573             if(num_inter_pic > 0)
3574                 den = den / num_inter_pic;
3575             else
3576                 den = 0.0;
3577         }
3578 
3579         if(den > 0)
3580             i_to_rest_bit_ratio = (float)((complexity[I_PIC]) / den);
3581         else
3582             i_to_rest_bit_ratio = 15;
3583 
3584         if((total_frms_considered < (WORD32)(0.75f * i4_intra_frame_interval)) &&
3585            (total_frms_considered < (updated_window - 1)) &&
3586            ((UWORD32)total_frms_considered < ((ps_rc_ctxt->u4_max_frame_rate / 1000))))
3587         {
3588             /*This GOP will only sustain for few frames hence have strict restriction for I to rest ratio*/
3589             if(i_to_rest_bit_ratio > 12)
3590                 i_to_rest_bit_ratio = 12;
3591 
3592             if(i_to_rest_bit_ratio > 8 &&
3593                total_frms_considered < (ps_rc_ctxt->i4_max_inter_frm_int * 2))
3594                 i_to_rest_bit_ratio = 8;
3595         }
3596     }
3597 
3598     if((i4_call_type == 1) && (i_to_rest_bit_ratio < I_TO_REST_VVFAST) && (i4_offset_flag == 1))
3599     {
3600         float f_p_to_i_ratio = (float)(d_first_p_complexity / d_first_i_complexity);
3601         if(ps_rc_lap_out->i8_frame_satd_act_accum <
3602            (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width * 1.5f))
3603             rc_set_p_to_i_complexity_ratio(ps_rc_ctxt->rc_hdl, f_p_to_i_ratio);
3604     }
3605 
3606     /*Reset the pic distribution if I frame exit was encountered*/
3607 
3608     if(ps_rc_ctxt->e_rate_control_type != CONST_QP)
3609     {
3610         rc_get_pic_distribution(ps_rc_ctxt->rc_hdl, &ai4_pic_dist[0]);
3611         if((ai4_pic_dist_in_cur_gop[I_PIC] > 1) && (ai4_pic_dist[0] == 1))
3612         {
3613             i4_flag_i_frame_exit = 1;
3614         }
3615         if(i4_flag_i_frame_exit && (i4_call_type == 1))
3616         {
3617             if(ai4_pic_dist_in_cur_gop[I_PIC] == 0)
3618                 memmove(ai4_pic_dist_in_cur_gop, num_frames_in_lap, sizeof(WORD32) * MAX_PIC_TYPE);
3619 
3620             rc_update_pic_distn_lap_to_rc(ps_rc_ctxt->rc_hdl, ai4_pic_dist_in_cur_gop);
3621             rc_set_bits_based_on_complexity(
3622                 ps_rc_ctxt->rc_hdl, u4_L1_based_lap_complexity_q7, total_frms_considered);
3623         }
3624     }
3625 
3626     return i_to_rest_bit_ratio;
3627 }
3628 
3629 /*##################################################*/
3630 /******* END OF I2AVG RATIO FUNCTIONS **************/
3631 /*################################################*/
3632 
3633 /*#########################################################*/
3634 /******* START OF QSCALE CONVERSION FUNCTIONS *************/
3635 /*########################################################*/
3636 
3637 /**
3638 ******************************************************************************
3639 *
3640 *  @brief function to convert from qscale to qp
3641 *
3642 *  @par   Description
3643 *  @param[in]   i4_frame_qs_q3 : QP value in qscale
3644 *   return      frame qp
3645 ******************************************************************************
3646 */
3647 
ihevce_rc_get_scaled_hevc_qp_from_qs_q3(WORD32 i4_frame_qs_q3,rc_quant_t * ps_rc_quant_ctxt)3648 WORD32 ihevce_rc_get_scaled_hevc_qp_from_qs_q3(WORD32 i4_frame_qs_q3, rc_quant_t *ps_rc_quant_ctxt)
3649 {
3650     if(i4_frame_qs_q3 > ps_rc_quant_ctxt->i2_max_qscale)
3651     {
3652         i4_frame_qs_q3 = ps_rc_quant_ctxt->i2_max_qscale;
3653     }
3654     else if(i4_frame_qs_q3 < ps_rc_quant_ctxt->i2_min_qscale)
3655     {
3656         i4_frame_qs_q3 = ps_rc_quant_ctxt->i2_min_qscale;
3657     }
3658 
3659     return (ps_rc_quant_ctxt->pi4_qscale_to_qp[i4_frame_qs_q3]);
3660 }
3661 
3662 /**
3663 ******************************************************************************
3664 *
3665 *  @brief function to convert from qp to qscale
3666 *
3667 *  @par   Description
3668 *  @param[in]   i4_frame_qp : QP value
3669 *   return      value in qscale
3670 ******************************************************************************
3671 */
ihevce_rc_get_scaled_mpeg2_qp(WORD32 i4_frame_qp,rc_quant_t * ps_rc_quant_ctxt)3672 WORD32 ihevce_rc_get_scaled_mpeg2_qp(WORD32 i4_frame_qp, rc_quant_t *ps_rc_quant_ctxt)
3673 {
3674     //i4_frame_qp = i4_frame_qp >> 3; // Q3 format is mantained for accuarate calc at lower qp
3675     WORD32 i4_qscale;
3676     if(i4_frame_qp > ps_rc_quant_ctxt->i2_max_qp)
3677     {
3678         i4_frame_qp = ps_rc_quant_ctxt->i2_max_qp;
3679     }
3680     else if(i4_frame_qp < ps_rc_quant_ctxt->i2_min_qp)
3681     {
3682         i4_frame_qp = ps_rc_quant_ctxt->i2_min_qp;
3683     }
3684 
3685     i4_qscale = (ps_rc_quant_ctxt->pi4_qp_to_qscale[i4_frame_qp + ps_rc_quant_ctxt->i1_qp_offset] +
3686                  (1 << (QSCALE_Q_FAC_3 - 1))) >>
3687                 QSCALE_Q_FAC_3;
3688     return i4_qscale;
3689 }
3690 
3691 /**
3692 ******************************************************************************
3693 *
3694 *  @brief function to convert from qp to qscale
3695 *
3696 *  @par Description : This function maps logarithmic QP values to linear QP
3697 *   values. The linear values are represented in Q6 format.
3698 *
3699 *  @param[in]   i4_frame_qp : QP value (log scale)
3700 *
3701 *  @return value in QP (linear scale)
3702 *
3703 ******************************************************************************
3704 */
ihevce_rc_get_scaled_mpeg2_qp_q6(WORD32 i4_frame_qp,UWORD8 u1_bit_depth)3705 WORD32 ihevce_rc_get_scaled_mpeg2_qp_q6(WORD32 i4_frame_qp, UWORD8 u1_bit_depth)
3706 {
3707     WORD32 i4_frame_qp_q6;
3708     number_t s_frame_qp;
3709     float f_qp;
3710 
3711     (void)u1_bit_depth;
3712     ASSERT(i4_frame_qp >= 0);
3713     ASSERT(i4_frame_qp <= 51 + ((u1_bit_depth - 8) * 6));
3714     f_qp = (float)pow((float)2, ((float)(i4_frame_qp - 4) / 6));
3715     convert_float_to_fix(f_qp, &s_frame_qp);
3716     convert_varq_to_fixq(s_frame_qp, &i4_frame_qp_q6, QSCALE_Q_FAC);
3717 
3718     if(i4_frame_qp_q6 < (1 << QSCALE_Q_FAC))
3719         i4_frame_qp_q6 = 1 << QSCALE_Q_FAC;
3720 
3721     return i4_frame_qp_q6;
3722 }
3723 
3724 /**
3725 ******************************************************************************
3726 *
3727 *  @brief function to convert from qscale to qp
3728 *
3729 *  @par   Description
3730 *  @param[in]   i4_frame_qp_q6 : QP value in qscale. the input is assumed to be in q6 format
3731 *   return      frame qp
3732 ******************************************************************************
3733 */
ihevce_rc_get_scaled_hevce_qp_q6(WORD32 i4_frame_qp_q6,UWORD8 u1_bit_depth)3734 WORD32 ihevce_rc_get_scaled_hevce_qp_q6(WORD32 i4_frame_qp_q6, UWORD8 u1_bit_depth)
3735 {
3736     WORD32 i4_hevce_qp;
3737     number_t s_hevce_qp, s_temp;
3738     float f_mpeg2_qp, f_hevce_qp;
3739     f_mpeg2_qp = (float)i4_frame_qp_q6 / (1 << QSCALE_Q_FAC);
3740     f_hevce_qp = (6 * ((float)log(f_mpeg2_qp) / (float)log((float)2))) + 4;
3741     convert_float_to_fix(f_hevce_qp, &s_hevce_qp);
3742 
3743     /*rounf off to nearest integer*/
3744     s_temp.sm = 1;
3745     s_temp.e = 1;
3746     add32_var_q(s_hevce_qp, s_temp, &s_hevce_qp);
3747     number_t_to_word32(s_hevce_qp, &i4_hevce_qp);
3748     if(i4_frame_qp_q6 == 0)
3749     {
3750         i4_hevce_qp = 0;
3751     }
3752 
3753     i4_hevce_qp -= ((u1_bit_depth - 8) * 6);
3754 
3755     return i4_hevce_qp;
3756 }
3757 
3758 /**
3759 ******************************************************************************
3760 *
3761 *  @brief function to convert from qp scale to qp
3762 *
3763 *  @par Description : This function maps linear QP values to logarithimic QP
3764 *   values. The linear values are represented in Q3 format.
3765 *
3766 *  @param[in]   i4_frame_qp : QP value (linear scale, Q3 mode)
3767 *
3768 *  @return value in QP (log scale)
3769 *
3770 ******************************************************************************
3771 */
ihevce_rc_get_scaled_hevce_qp_q3(WORD32 i4_frame_qp,UWORD8 u1_bit_depth)3772 WORD32 ihevce_rc_get_scaled_hevce_qp_q3(WORD32 i4_frame_qp, UWORD8 u1_bit_depth)
3773 {
3774     WORD32 i4_hevce_qp;
3775     number_t s_hevce_qp, s_temp;
3776 
3777     if(i4_frame_qp == 0)
3778     {
3779         i4_hevce_qp = 0;
3780     }
3781     else
3782     {
3783         float f_mpeg2_qp, f_hevce_qp;
3784 
3785         f_mpeg2_qp = (float)i4_frame_qp;
3786         f_hevce_qp = (6 * ((float)log(f_mpeg2_qp) / (float)log((float)2) - 3)) + 4;
3787         convert_float_to_fix(f_hevce_qp, &s_hevce_qp);
3788 
3789         /*rounf off to nearest integer*/
3790         s_temp.sm = 1;
3791         s_temp.e = 1;
3792         add32_var_q(s_hevce_qp, s_temp, &s_hevce_qp);
3793         number_t_to_word32(s_hevce_qp, &i4_hevce_qp);
3794     }
3795     i4_hevce_qp -= ((u1_bit_depth - 8) * 6);
3796 
3797     return i4_hevce_qp;
3798 }
3799 
3800 /*#######################################################*/
3801 /******* END OF QSCALE CONVERSION FUNCTIONS *************/
3802 /*######################################################*/
3803 
3804 /*###############################################*/
3805 /******* START OF SET,GET FUNCTIONS *************/
3806 /*#############################################*/
3807 
3808 /**
3809 ******************************************************************************
3810 *
3811 *  @brief Convert pic type to rc pic type
3812 *
3813 *  @par   Description
3814 *
3815 *
3816 *  @param[in]      pic_type
3817 *  Pic type
3818 *
3819 *  @return      rc_pic_type
3820 *
3821 ******************************************************************************
3822 */
ihevce_rc_conv_pic_type(IV_PICTURE_CODING_TYPE_T pic_type,WORD32 i4_field_pic,WORD32 i4_temporal_layer_id,WORD32 i4_is_bottom_field,WORD32 i4_top_field_first)3823 picture_type_e ihevce_rc_conv_pic_type(
3824     IV_PICTURE_CODING_TYPE_T pic_type,
3825     WORD32 i4_field_pic,
3826     WORD32 i4_temporal_layer_id,
3827     WORD32 i4_is_bottom_field,
3828     WORD32 i4_top_field_first)
3829 {
3830     picture_type_e rc_pic_type = (picture_type_e)pic_type;
3831     /*interlaced pictype are not supported*/
3832     if(pic_type > 9 && i4_temporal_layer_id > 3) /**/
3833     {
3834         DBG_PRINTF("unsupported picture type or temporal id\n");
3835         exit(0);
3836     }
3837 
3838     if(i4_field_pic == 0) /*Progressive Source*/
3839     {
3840         if(pic_type == IV_IDR_FRAME)
3841         {
3842             rc_pic_type = I_PIC;
3843         }
3844         else
3845         {
3846             rc_pic_type = (picture_type_e)pic_type;
3847 
3848             /*return different picture type based on temporal layer*/
3849             if(i4_temporal_layer_id > 1)
3850             {
3851                 rc_pic_type = (picture_type_e)(pic_type + (i4_temporal_layer_id - 1));
3852             }
3853         }
3854     }
3855 
3856     else if(i4_field_pic == 1)
3857     {
3858         if(pic_type == IV_IDR_FRAME || pic_type == IV_I_FRAME)
3859         {
3860             rc_pic_type = I_PIC;
3861         }
3862 
3863         else if(i4_top_field_first == 1)
3864         {
3865             rc_pic_type = (picture_type_e)pic_type;
3866 
3867             if(i4_temporal_layer_id <= 1)
3868 
3869             {
3870                 if(i4_is_bottom_field == 1)
3871                     rc_pic_type = (picture_type_e)(pic_type + 4);
3872             }
3873             /*return different picture type based on temporal layer*/
3874             if(i4_temporal_layer_id > 1)
3875             {
3876                 if(i4_is_bottom_field == 0)
3877                     rc_pic_type = (picture_type_e)(pic_type + (i4_temporal_layer_id - 1));
3878                 else
3879                     rc_pic_type = (picture_type_e)(
3880                         pic_type + (i4_temporal_layer_id - 1) +
3881                         4); /*Offset of 4 for the bottomfield*/
3882             }
3883         }
3884         else if(i4_top_field_first == 0)
3885         {
3886             rc_pic_type = (picture_type_e)pic_type;
3887 
3888             if(i4_temporal_layer_id <= 1)
3889             {
3890                 if(i4_is_bottom_field == 1)
3891                     rc_pic_type = (picture_type_e)(pic_type + 4);
3892             }
3893             /*return different picture type based on temporal layer*/
3894             if(i4_temporal_layer_id > 1)
3895             {
3896                 if(i4_is_bottom_field == 0)
3897                     rc_pic_type = (picture_type_e)(pic_type + (i4_temporal_layer_id - 1));
3898                 else
3899                     rc_pic_type = (picture_type_e)(
3900                         pic_type + (i4_temporal_layer_id - 1) + 4); /*Offset of 4 for the topfield*/
3901             }
3902         }
3903     }
3904 
3905     return rc_pic_type;
3906 }
3907 
3908 /**
3909 ******************************************************************************
3910 *
3911 *  @brief function to update current frame intra cost
3912 *
3913 *  @par   Description
3914 *  @param[inout] ps_rc_ctxt
3915 *  @param[in]    i8_cur_frm_intra_cost
3916 ******************************************************************************
3917 */
ihevce_rc_update_cur_frm_intra_satd(void * pv_ctxt,LWORD64 i8_cur_frm_intra_cost,WORD32 i4_enc_frm_id)3918 void ihevce_rc_update_cur_frm_intra_satd(
3919     void *pv_ctxt, LWORD64 i8_cur_frm_intra_cost, WORD32 i4_enc_frm_id)
3920 {
3921     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
3922     ps_rc_ctxt->ai8_cur_frm_intra_cost[i4_enc_frm_id] = i8_cur_frm_intra_cost;
3923 }
3924 /**
3925 ******************************************************************************
3926 *
3927 *  @brief function to return scene type
3928 *
3929 *  @par   Description
3930 *  @param[inout] ps_rc_lap_out
3931 *  @return       i4_rc_scene_type
3932 ******************************************************************************
3933 */
3934 /* Functions dependent on lap input*/
ihevce_rc_lap_get_scene_type(rc_lap_out_params_t * ps_rc_lap_out)3935 WORD32 ihevce_rc_lap_get_scene_type(rc_lap_out_params_t *ps_rc_lap_out)
3936 {
3937     return (WORD32)ps_rc_lap_out->i4_rc_scene_type;
3938 }
3939 
3940 /**
3941 ******************************************************************************
3942 *
3943 *  @name  ihevce_rc_get_pic_param
3944 *
3945 *  @par   Description
3946 *
3947 *  @param[in]   rc_pic_type
3948 *
3949 *  @return      void
3950 *
3951 ******************************************************************************
3952 */
ihevce_rc_get_pic_param(picture_type_e rc_pic_type,WORD32 * pi4_tem_lyr,WORD32 * pi4_is_bottom_field)3953 static void ihevce_rc_get_pic_param(
3954     picture_type_e rc_pic_type, WORD32 *pi4_tem_lyr, WORD32 *pi4_is_bottom_field)
3955 {
3956     /*bottom field determination*/
3957     if(rc_pic_type >= P1_PIC)
3958         *pi4_is_bottom_field = 1;
3959     else
3960         *pi4_is_bottom_field = 0;
3961 
3962     /*temporal lyr id determination*/
3963     if(rc_pic_type == I_PIC || rc_pic_type == P_PIC || rc_pic_type == P1_PIC)
3964     {
3965         *pi4_tem_lyr = 0;
3966     }
3967     else if(rc_pic_type == B_PIC || rc_pic_type == BB_PIC)
3968     {
3969         *pi4_tem_lyr = 1;
3970     }
3971     else if(rc_pic_type == B1_PIC || rc_pic_type == B11_PIC)
3972     {
3973         *pi4_tem_lyr = 2;
3974     }
3975     else if(rc_pic_type == B2_PIC || rc_pic_type == B22_PIC)
3976     {
3977         *pi4_tem_lyr = 3;
3978     }
3979     else
3980     {
3981         ASSERT(0);
3982     }
3983 }
3984 /**
3985 ******************************************************************************
3986 *
3987 *  @name  ihevce_get_offline_index
3988 *
3989 *  @par   Description
3990 *
3991 *  @param[in]   ps_rc_ctxt  - pointer to rc context
3992 *
3993 *  @return      index
3994 *
3995 ******************************************************************************
3996 */
ihevce_get_offline_index(rc_context_t * ps_rc_ctxt,WORD32 i4_num_pels_in_frame)3997 static WORD32 ihevce_get_offline_index(rc_context_t *ps_rc_ctxt, WORD32 i4_num_pels_in_frame)
3998 {
3999     WORD32 i4_rc_quality_preset = ps_rc_ctxt->i4_quality_preset;
4000     WORD32 base = 1;
4001     if(i4_num_pels_in_frame > 5000000) /*ultra HD*/
4002     {
4003         base = 0;
4004     }
4005     else if(i4_num_pels_in_frame > 1500000) /*Full HD*/
4006     {
4007         base = 5;
4008     }
4009     else if(i4_num_pels_in_frame > 600000) /*720p*/
4010     {
4011         base = 10;
4012     }
4013     else /*SD*/
4014     {
4015         base = 15;
4016     }
4017     /*based on preset choose coeff*/
4018     if(i4_rc_quality_preset == IHEVCE_QUALITY_P0) /*Pristine quality*/
4019     {
4020         return base;
4021     }
4022     else if(i4_rc_quality_preset == IHEVCE_QUALITY_P2) /*High quality*/
4023     {
4024         return base + 1;
4025     }
4026     else if(
4027         (i4_rc_quality_preset == IHEVCE_QUALITY_P5) ||
4028         (i4_rc_quality_preset == IHEVCE_QUALITY_P6) ||
4029         (i4_rc_quality_preset == IHEVCE_QUALITY_P7)) /*Extreme speed */
4030     {
4031         return base + 4;
4032     }
4033     else if(i4_rc_quality_preset == IHEVCE_QUALITY_P4) /*High speed */
4034     {
4035         return base + 3;
4036     }
4037     else if(i4_rc_quality_preset == IHEVCE_QUALITY_P3) /*default assume Medium speed*/
4038     {
4039         return base + 2;
4040     }
4041     else
4042     {
4043         ASSERT(0);
4044     }
4045     return base + 2;
4046 }
4047 
4048 /**
4049 ******************************************************************************
4050 *
4051 *  @name  ihevce_get_frame_lambda_modifier
4052 *
4053 *  @par   Description
4054 *
4055 *  @param[in]   pic_type
4056 *               i4_rc_temporal_lyr_id
4057 *  @param[in]   i4_first_field
4058 *  @param[in]   i4_rc_is_ref_pic
4059 *  @return      lambda_modifier
4060 *
4061 ******************************************************************************
4062 */
ihevce_get_frame_lambda_modifier(WORD8 pic_type,WORD32 i4_rc_temporal_lyr_id,WORD32 i4_first_field,WORD32 i4_rc_is_ref_pic,WORD32 i4_num_b_frms)4063 static double ihevce_get_frame_lambda_modifier(
4064     WORD8 pic_type,
4065     WORD32 i4_rc_temporal_lyr_id,
4066     WORD32 i4_first_field,
4067     WORD32 i4_rc_is_ref_pic,
4068     WORD32 i4_num_b_frms)
4069 {
4070     double lambda_modifier;
4071     WORD32 num_b_frms = i4_num_b_frms, first_field = i4_first_field;
4072 
4073     if(I_PIC == pic_type)
4074     {
4075         double temporal_correction_islice = 1.0 - 0.05 * num_b_frms;
4076         temporal_correction_islice = MAX(0.5, temporal_correction_islice);
4077 
4078         lambda_modifier = 0.57 * temporal_correction_islice;
4079     }
4080     else if(P_PIC == pic_type)
4081     {
4082         if(first_field)
4083             lambda_modifier = 0.442;  //0.442*0.8;
4084         else
4085             lambda_modifier = 0.442;
4086 
4087         //lambda_modifier *= pow(2.00,(double)(1.00/3.00));
4088     }
4089     else
4090     {
4091         /* BSLICE */
4092         if(1 == i4_rc_is_ref_pic)
4093         {
4094             lambda_modifier = 0.3536;
4095         }
4096         else if(2 == i4_rc_is_ref_pic)
4097         {
4098             lambda_modifier = 0.45;
4099         }
4100         else
4101         {
4102             lambda_modifier = 0.68;
4103         }
4104 
4105         /* TODO: Disable lambda modification for interlace encode to match HM runs */
4106         //if(0 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
4107         {
4108             /* modify b lambda further based on temporal id */
4109             if(i4_rc_temporal_lyr_id)
4110             {
4111                 lambda_modifier *= 3.00;
4112             }
4113         }
4114         //lambda_modifier *= pow(2.00,(double)((1.00/3.00) * (i4_rc_temporal_lyr_id + 1)));
4115     }
4116 
4117     /* modify the base lambda according to lambda modifier */
4118     lambda_modifier = sqrt(lambda_modifier);
4119     return lambda_modifier;
4120 }
4121 
4122 /*!
4123 ******************************************************************************
4124 * \if Function name : get_avg_bitrate_bufsize
4125 *
4126 * \brief
4127 *
4128 * \param[in] *pv_ctxt -> rc context
4129 *
4130 * \return
4131 *
4132 * \author
4133 *  Ittiam
4134 *
4135 *****************************************************************************
4136 */
get_avg_bitrate_bufsize(void * pv_ctxt,LWORD64 * pi8_bitrate,LWORD64 * pi8_ebf)4137 void get_avg_bitrate_bufsize(void *pv_ctxt, LWORD64 *pi8_bitrate, LWORD64 *pi8_ebf)
4138 {
4139     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
4140     *pi8_bitrate = rc_get_bit_rate(ps_rc_ctxt->rc_hdl);
4141     *pi8_ebf = rc_get_vbv_buf_size(ps_rc_ctxt->rc_hdl);
4142 }
4143 
4144 /**
4145 ******************************************************************************
4146 *
4147 *  @name  ihevce_get_dbf_buffer_size
4148 *
4149 *  @par   Description
4150 *
4151 *  @param[in]   ps_rc_ctxt  - pointer to rc context
4152 *
4153 *  @return      qp
4154 *
4155 ******************************************************************************
4156 */
ihevce_get_dbf_buffer_size(void * pv_rc_ctxt,UWORD32 * pi4_buffer_size,UWORD32 * pi4_dbf,UWORD32 * pi4_bit_rate)4157 void ihevce_get_dbf_buffer_size(
4158     void *pv_rc_ctxt, UWORD32 *pi4_buffer_size, UWORD32 *pi4_dbf, UWORD32 *pi4_bit_rate)
4159 {
4160     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
4161 
4162     pi4_buffer_size[0] = (WORD32)ps_rc_ctxt->s_vbv_compliance.f_buffer_size;
4163     pi4_dbf[0] = (WORD32)(ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level);
4164     ASSERT(
4165         ps_rc_ctxt->s_vbv_compliance.f_buffer_size >=
4166         ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level);
4167 
4168     pi4_bit_rate[0] = (WORD32)ps_rc_ctxt->s_vbv_compliance.f_bit_rate;
4169 }
4170 
4171 /*!
4172 ******************************************************************************
4173 * \if Function name : ihevce_set_L0_scd_qp
4174 *
4175 * \brief
4176 *
4177 * \param[in] *pv_ctxt -> rc context
4178 *
4179 * \return
4180 *
4181 * \author
4182 *  Ittiam
4183 *
4184 *****************************************************************************
4185 */
ihevce_set_L0_scd_qp(void * pv_rc_ctxt,WORD32 i4_scd_qp)4186 void ihevce_set_L0_scd_qp(void *pv_rc_ctxt, WORD32 i4_scd_qp)
4187 {
4188     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
4189 
4190     ps_rc_ctxt->i4_L0_frame_qp = i4_scd_qp;
4191 }
4192 
4193 /**
4194 ******************************************************************************
4195 *
4196 *  @name  rc_get_buffer_level_unclip
4197 *
4198 *  @par   Description
4199 *
4200 *  @param[in]      pv_rc_ctxt
4201 *
4202 *
4203 *  @return      void
4204 *
4205 ******************************************************************************
4206 */
rc_get_buffer_level_unclip(void * pv_rc_ctxt)4207 float rc_get_buffer_level_unclip(void *pv_rc_ctxt)
4208 {
4209     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
4210     return (ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip);
4211 }
4212 
4213 /**
4214 ******************************************************************************
4215 *
4216 *  @brief Clip QP based on min and max frame qp
4217 *
4218 *  @par   Description
4219 *
4220 *  @param[inout]   ps_rc_ctxt
4221 *  pointer to rc context
4222 *
4223 *  @param[in]      rc_pic_type
4224 *  Pic type
4225 *
4226 *  @return      i4_hevc_frame_qp
4227 *
4228 ******************************************************************************
4229 */
ihevce_clip_min_max_qp(rc_context_t * ps_rc_ctxt,WORD32 i4_hevc_frame_qp,picture_type_e rc_pic_type,WORD32 i4_rc_temporal_lyr_id)4230 static WORD32 ihevce_clip_min_max_qp(
4231     rc_context_t *ps_rc_ctxt,
4232     WORD32 i4_hevc_frame_qp,
4233     picture_type_e rc_pic_type,
4234     WORD32 i4_rc_temporal_lyr_id)
4235 {
4236     ASSERT(i4_rc_temporal_lyr_id >= 0);
4237     /**clip to min qp which is user configurable*/
4238     if(rc_pic_type == I_PIC && i4_hevc_frame_qp < ps_rc_ctxt->i4_min_frame_qp)
4239     {
4240         i4_hevc_frame_qp = ps_rc_ctxt->i4_min_frame_qp;
4241     }
4242     else if(rc_pic_type == P_PIC && i4_hevc_frame_qp < (ps_rc_ctxt->i4_min_frame_qp + 1))
4243     {
4244         i4_hevc_frame_qp = ps_rc_ctxt->i4_min_frame_qp + 1;
4245     }
4246     else if(i4_hevc_frame_qp < (ps_rc_ctxt->i4_min_frame_qp + i4_rc_temporal_lyr_id + 1))
4247     {
4248         /** For B frame max qp is set based on temporal reference*/
4249         i4_hevc_frame_qp = ps_rc_ctxt->i4_min_frame_qp + i4_rc_temporal_lyr_id + 1;
4250     }
4251     /* clip the Qp to MAX QP */
4252     if(i4_hevc_frame_qp < ps_rc_ctxt->ps_rc_quant_ctxt->i2_min_qp)
4253     {
4254         i4_hevc_frame_qp = ps_rc_ctxt->ps_rc_quant_ctxt->i2_min_qp;
4255     }
4256     /**clip to max qp based on pic type*/
4257     if(rc_pic_type == I_PIC && i4_hevc_frame_qp > ps_rc_ctxt->i4_max_frame_qp)
4258     {
4259         i4_hevc_frame_qp = ps_rc_ctxt->i4_max_frame_qp;
4260     }
4261     else if(rc_pic_type == P_PIC && i4_hevc_frame_qp > (ps_rc_ctxt->i4_max_frame_qp + 1))
4262     {
4263         i4_hevc_frame_qp = ps_rc_ctxt->i4_max_frame_qp + 1;
4264     }
4265     else if(i4_hevc_frame_qp > (ps_rc_ctxt->i4_max_frame_qp + i4_rc_temporal_lyr_id + 1))
4266     {
4267         /** For B frame max qp is set based on temporal reference*/
4268         i4_hevc_frame_qp = ps_rc_ctxt->i4_max_frame_qp + i4_rc_temporal_lyr_id + 1;
4269     }
4270     /* clip the Qp to MAX QP */
4271     if(i4_hevc_frame_qp > ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qp)
4272     {
4273         i4_hevc_frame_qp = ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qp;
4274     }
4275     return i4_hevc_frame_qp;
4276 }
4277 
4278 /*#############################################*/
4279 /******* END OF SET,GET FUNCTIONS *************/
4280 /*###########################################*/
4281 
4282 /*#################################################*/
4283 /******* START OF RC UPDATE FUNCTIONS **************/
4284 /*#################################################*/
4285 
4286 /**
4287 ******************************************************************************
4288 *
4289 *  @brief updates the picture level information like bits consumed and
4290 *
4291 *  @par   Description
4292 *
4293 *  @param[inout]   ps_mem_tab
4294 *  pointer to memory descriptors table
4295 *
4296 *  @param[in]      ps_init_prms
4297 *  Create time static parameters
4298 *
4299 *  @return      void
4300 *
4301 ******************************************************************************
4302 */
4303 
ihevce_rc_update_pic_info(void * pv_ctxt,UWORD32 u4_total_bits_consumed,UWORD32 u4_total_header_bits,UWORD32 u4_frame_sad,UWORD32 u4_frame_intra_sad,IV_PICTURE_CODING_TYPE_T pic_type,WORD32 i4_avg_frame_hevc_qp,WORD32 i4_suppress_bpic_update,WORD32 * pi4_qp_normalized_8x8_cu_sum,WORD32 * pi4_8x8_cu_sum,LWORD64 * pi8_sad_by_qscale,ihevce_lap_output_params_t * ps_lap_out,rc_lap_out_params_t * ps_rc_lap_out,WORD32 i4_buf_id,UWORD32 u4_open_loop_intra_sad,LWORD64 i8_total_ssd_frame,WORD32 i4_enc_frm_id)4304 void ihevce_rc_update_pic_info(
4305     void *pv_ctxt,
4306     UWORD32 u4_total_bits_consumed,
4307     UWORD32 u4_total_header_bits,
4308     UWORD32 u4_frame_sad,
4309     UWORD32 u4_frame_intra_sad,
4310     IV_PICTURE_CODING_TYPE_T pic_type,
4311     WORD32 i4_avg_frame_hevc_qp,
4312     WORD32 i4_suppress_bpic_update,
4313     WORD32 *pi4_qp_normalized_8x8_cu_sum,
4314     WORD32 *pi4_8x8_cu_sum,
4315     LWORD64 *pi8_sad_by_qscale,
4316     ihevce_lap_output_params_t *ps_lap_out,
4317     rc_lap_out_params_t *ps_rc_lap_out,
4318     WORD32 i4_buf_id,
4319     UWORD32 u4_open_loop_intra_sad,
4320     LWORD64 i8_total_ssd_frame,
4321     WORD32 i4_enc_frm_id)
4322 {
4323     LWORD64 a_mb_type_sad[2];
4324     WORD32 a_mb_type_tex_bits[2];
4325     /*dummy variables not used*/
4326     WORD32 a_mb_in_type[2] = { 0, 0 };
4327     LWORD64 a_mb_type_qp_q6[2] = { 0, 0 };
4328     /*qp accumulation at */
4329     WORD32 i4_avg_activity = 250;  //hardcoding to usual value
4330     WORD32 i4_intra_cost, i4_avg_frame_qp_q6, i;
4331     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
4332     WORD32 i4_frame_complexity, i4_bits_to_be_stuffed = 0, i4_is_last_frm_period = 0;
4333     picture_type_e rc_pic_type = ihevce_rc_conv_pic_type(
4334         pic_type,
4335         ps_rc_ctxt->i4_field_pic,
4336         ps_rc_lap_out->i4_rc_temporal_lyr_id,
4337         ps_rc_lap_out->i4_is_bottom_field,
4338         ps_rc_ctxt->i4_top_field_first);
4339     frame_info_t s_frame_info;
4340     WORD32 i4_ctr = -1, i4_i, i4_j;
4341     WORD32 i4_scene_num = ps_rc_lap_out->u4_rc_scene_num % MAX_SCENE_NUM;
4342 
4343     /*update bit consumption. used only in rdopt*/
4344     //ASSERT(ps_rc_ctxt->ai4_rdopt_bit_consumption_estimate[ps_rc_ctxt->i4_rdopt_bit_count] == -1);
4345     //ASSERT(i4_buf_id>=0);
4346     ps_rc_ctxt->ai4_rdopt_bit_consumption_estimate[ps_rc_ctxt->i4_rdopt_bit_count] =
4347         u4_total_bits_consumed;
4348     ps_rc_ctxt->ai4_rdopt_bit_consumption_buf_id[ps_rc_ctxt->i4_rdopt_bit_count] = i4_buf_id;
4349     ps_rc_ctxt->i4_rdopt_bit_count =
4350         (ps_rc_ctxt->i4_rdopt_bit_count + 1) % NUM_BUF_RDOPT_ENT_CORRECT;
4351 
4352     {
4353         LWORD64 i8_texture_bits = u4_total_bits_consumed - u4_total_header_bits;
4354         ps_rc_lap_out->i4_use_offline_model_2pass = 0;
4355 
4356         /*flag to guide whether 2nd pass can use offline model or not*/
4357         if((abs(ps_rc_lap_out->i4_orig_rc_qp - i4_avg_frame_hevc_qp) < 2) &&
4358            (i8_texture_bits <= (ps_rc_lap_out->i8_est_text_bits * 2.0f)) &&
4359            (i8_texture_bits >= (ps_rc_lap_out->i8_est_text_bits * 0.5f)))
4360 
4361         {
4362             ps_rc_lap_out->i4_use_offline_model_2pass = 1;
4363         }
4364     }
4365     /*Counter of number of bit alloction periods*/
4366     if(rc_pic_type == I_PIC)
4367         ps_rc_ctxt
4368             ->i8_num_bit_alloc_period++;  //Currently only I frame periods are considerd as bit allocation period (Ignoring non- I scd and complexity reset flag
4369     /*initialze frame info*/
4370     init_frame_info(&s_frame_info);
4371     s_frame_info.i4_rc_hevc_qp = i4_avg_frame_hevc_qp;
4372     s_frame_info.i4_num_entries++;
4373     s_frame_info.i8_L1_me_sad = ps_rc_lap_out->i8_raw_l1_coarse_me_sad;
4374     s_frame_info.i8_L1_ipe_raw_sad = ps_rc_lap_out->i8_raw_pre_intra_sad;
4375     s_frame_info.i4_num_entries++;
4376     s_frame_info.i4_num_entries++;
4377     s_frame_info.i8_L0_open_cost = (LWORD64)u4_open_loop_intra_sad;
4378     s_frame_info.i4_num_entries++;
4379 
4380     if(rc_pic_type == I_PIC)
4381         s_frame_info.i8_L1_me_or_ipe_raw_sad = ps_rc_lap_out->i8_raw_pre_intra_sad;
4382     else
4383         s_frame_info.i8_L1_me_or_ipe_raw_sad = ps_rc_lap_out->i8_raw_l1_coarse_me_sad;
4384     s_frame_info.i4_num_entries++;
4385     s_frame_info.i4_poc = ps_rc_lap_out->i4_rc_poc;
4386     s_frame_info.i4_num_entries++;
4387     s_frame_info.i4_scene_type = ps_rc_lap_out->i4_rc_scene_type;
4388     s_frame_info.i4_num_entries++;
4389     s_frame_info.i4_non_i_scd = ps_rc_lap_out->i4_is_non_I_scd || ps_rc_lap_out->i4_is_I_only_scd;
4390     s_frame_info.i4_num_entries++;
4391     s_frame_info.i8_cl_sad = u4_frame_sad;
4392     s_frame_info.i4_num_entries++;
4393     s_frame_info.i8_header_bits = u4_total_header_bits;
4394     s_frame_info.i4_num_entries++;
4395     s_frame_info.i8_tex_bits = u4_total_bits_consumed - u4_total_header_bits;
4396     s_frame_info.i4_num_entries++;
4397     s_frame_info.e_pic_type = rc_pic_type;
4398     s_frame_info.i4_num_entries++;
4399     s_frame_info.i8_est_texture_bits = ps_rc_lap_out->i8_est_text_bits;
4400     s_frame_info.i4_num_entries++;
4401     s_frame_info.i4_lap_complexity_q7 = ps_rc_ctxt->ai4_lap_complexity_q7[i4_enc_frm_id];
4402     s_frame_info.i4_num_entries++;
4403     s_frame_info.i4_lap_f_sim = ps_rc_ctxt->ai4_lap_f_sim[i4_enc_frm_id];
4404     s_frame_info.i4_num_entries++;
4405     s_frame_info.i8_frame_acc_coarse_me_cost = ps_rc_lap_out->i8_frame_acc_coarse_me_cost;
4406     s_frame_info.i4_num_entries++;
4407     s_frame_info.i_to_avg_bit_ratio = ps_rc_ctxt->ai_to_avg_bit_ratio[i4_enc_frm_id];
4408     s_frame_info.i4_num_entries++;
4409     s_frame_info.i4_num_scd_in_lap_window = ps_rc_ctxt->ai4_num_scd_in_lap_window[i4_enc_frm_id];
4410     s_frame_info.i4_num_entries++;
4411     s_frame_info.i4_num_frames_b4_scd = ps_rc_ctxt->ai4_num_frames_b4_scd[i4_enc_frm_id];
4412     s_frame_info.i4_num_entries++;
4413     s_frame_info.i8_num_bit_alloc_period = ps_rc_ctxt->i8_num_bit_alloc_period;
4414     s_frame_info.i4_num_entries++;
4415     s_frame_info.i1_is_complexity_based_bits_reset =
4416         (WORD8)ps_rc_lap_out->i4_is_cmplx_change_reset_bits;
4417     s_frame_info.i4_num_entries++;
4418     /*For the complexity based movement in 2nd pass*/
4419     memmove(
4420         (void *)s_frame_info.af_sum_weigh,
4421         ps_rc_lap_out->ps_frame_info->af_sum_weigh,
4422         sizeof(float) * MAX_PIC_TYPE * 3);
4423     s_frame_info.i4_num_entries++;
4424 
4425     /*store frame qp to clip qp accordingly*/
4426     if(ps_rc_lap_out->i4_is_rc_model_needs_to_be_updated)
4427     {
4428         ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type] = i4_avg_frame_hevc_qp;
4429     }
4430 
4431     for(i4_i = 0; i4_i < MAX_NON_REF_B_PICS_IN_QUEUE_SGI; i4_i++)
4432     {
4433         if(ps_rc_lap_out->u4_rc_scene_num == ps_rc_ctxt->au4_prev_scene_num_multi_scene[i4_i])
4434         {
4435             i4_ctr = i4_i;
4436             break;
4437         }
4438     }
4439     if(-1 == i4_ctr)
4440     {
4441         ps_rc_ctxt->i4_prev_qp_ctr++;
4442         ps_rc_ctxt->i4_prev_qp_ctr = ps_rc_ctxt->i4_prev_qp_ctr % MAX_NON_REF_B_PICS_IN_QUEUE_SGI;
4443         i4_ctr = ps_rc_ctxt->i4_prev_qp_ctr;
4444         ps_rc_ctxt->au4_prev_scene_num_multi_scene[i4_ctr] = ps_rc_lap_out->u4_rc_scene_num;
4445         for(i4_j = 0; i4_j < MAX_PIC_TYPE; i4_j++)
4446         {
4447             ps_rc_ctxt->ai4_qp_for_previous_scene_multi_scene[i4_ctr][i4_j] = 0;
4448         }
4449     }
4450 
4451     {
4452         ps_rc_ctxt->ai4_qp_for_previous_scene_multi_scene[i4_ctr][rc_pic_type] =
4453             i4_avg_frame_hevc_qp;
4454     }
4455     if(i4_scene_num < HALF_MAX_SCENE_ARRAY_QP)
4456     {
4457         WORD32 i4_i;
4458         ps_rc_ctxt->ai4_scene_numbers[i4_scene_num + HALF_MAX_SCENE_ARRAY_QP] = 0;
4459         for(i4_i = 0; i4_i < MAX_PIC_TYPE; i4_i++)
4460             ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num + HALF_MAX_SCENE_ARRAY_QP][i4_i] =
4461                 INIT_HEVCE_QP_RC;
4462     }
4463     else
4464     {
4465         WORD32 i4_i;
4466         ps_rc_ctxt->ai4_scene_numbers[i4_scene_num - HALF_MAX_SCENE_ARRAY_QP] = 0;
4467         for(i4_i = 0; i4_i < MAX_PIC_TYPE; i4_i++)
4468             ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num - HALF_MAX_SCENE_ARRAY_QP][i4_i] =
4469                 INIT_HEVCE_QP_RC;
4470     }
4471 
4472     /*update will have HEVC qp, convert it back to mpeg2 range qp for all internal calculations of RC*/
4473 
4474     i4_avg_frame_qp_q6 = ps_rc_ctxt->ps_rc_quant_ctxt->pi4_qp_to_qscale_q_factor
4475                              [i4_avg_frame_hevc_qp + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset];
4476 
4477     if(pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME)
4478     {
4479         /*TODO : Take care of precision of a_mb_type_sad*/
4480         a_mb_type_sad[0] =
4481             (((pi8_sad_by_qscale[1] * i4_avg_frame_qp_q6) +
4482               (((LWORD64)1) << (SAD_BY_QSCALE_Q + QSCALE_Q_FAC - 1))) >>
4483              (SAD_BY_QSCALE_Q + QSCALE_Q_FAC));  //u4_frame_sad;
4484 
4485         a_mb_type_sad[1] =
4486             (((pi8_sad_by_qscale[0] * i4_avg_frame_qp_q6) +
4487               (((LWORD64)1) << (SAD_BY_QSCALE_Q + QSCALE_Q_FAC - 1))) >>
4488              (SAD_BY_QSCALE_Q + QSCALE_Q_FAC));
4489         a_mb_type_tex_bits[0] =
4490             u4_total_bits_consumed - u4_total_header_bits;  //(u4_total_bits_consumed >> 3);
4491         a_mb_type_tex_bits[1] = 0;
4492         a_mb_in_type[0] = (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) >> 8;
4493         a_mb_in_type[1] = 0;
4494     }
4495     else
4496     {
4497         /*TODO : Take care of precision of a_mb_type_sad*/
4498         a_mb_type_sad[1] =
4499             (((pi8_sad_by_qscale[0] * i4_avg_frame_qp_q6) +
4500               (((LWORD64)1) << (SAD_BY_QSCALE_Q + QSCALE_Q_FAC - 1))) >>
4501              (SAD_BY_QSCALE_Q + QSCALE_Q_FAC));
4502 
4503         a_mb_type_tex_bits[0] =
4504             u4_total_bits_consumed - u4_total_header_bits;  //(u4_total_bits_consumed >> 3);
4505         a_mb_type_sad[0] =
4506             (((pi8_sad_by_qscale[1] * i4_avg_frame_qp_q6) +
4507               (((LWORD64)1) << (SAD_BY_QSCALE_Q + QSCALE_Q_FAC - 1))) >>
4508              (SAD_BY_QSCALE_Q + QSCALE_Q_FAC));  //u4_frame_sad;
4509         a_mb_type_tex_bits[1] =
4510             u4_total_bits_consumed - u4_total_header_bits;  //(u4_total_bits_consumed >> 3);
4511         a_mb_type_tex_bits[0] = 0;
4512         a_mb_in_type[1] = (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) >> 8;
4513         a_mb_in_type[0] = 0;
4514     }
4515     ASSERT(a_mb_type_sad[0] >= 0);
4516     ASSERT(a_mb_type_sad[1] >= 0);
4517     /*THis calclates sum of Qps of all MBs as per the corresponding mb type*/
4518     /*THis is different from a_mb_in_type,a_mb_type_sad and a_mb_type_tex_bits*/
4519     a_mb_type_qp_q6[0] = ((LWORD64)i4_avg_frame_qp_q6) * a_mb_in_type[0];
4520     a_mb_type_qp_q6[1] = ((LWORD64)i4_avg_frame_qp_q6) * a_mb_in_type[1];
4521     {
4522         WORD32 i4_avg_qp_q6_without_offset = 0, i4_hevc_qp_rc = i4_avg_frame_hevc_qp;
4523         WORD32 i4_rc_pic_type_rc_for_offset = rc_pic_type;
4524         if(i4_rc_pic_type_rc_for_offset > B2_PIC)
4525             i4_rc_pic_type_rc_for_offset = i4_rc_pic_type_rc_for_offset - B2_PIC;
4526         i4_hevc_qp_rc = i4_hevc_qp_rc - ps_rc_lap_out->ai4_offsets[i4_rc_pic_type_rc_for_offset] +
4527                         ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset;
4528 
4529         i4_hevc_qp_rc =
4530             CLIP3(i4_hevc_qp_rc, 1, MAX_HEVC_QP + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset);
4531         i4_avg_qp_q6_without_offset =
4532             ps_rc_ctxt->ps_rc_quant_ctxt->pi4_qp_to_qscale_q_factor[i4_hevc_qp_rc];
4533 
4534         /*Store the HBD qscale with and without accounting for offset*/
4535         s_frame_info.f_hbd_q_scale_without_offset =
4536             (float)i4_avg_qp_q6_without_offset / (1 << QSCALE_Q_FAC);
4537         s_frame_info.f_hbd_q_scale = (float)i4_avg_frame_qp_q6 / (1 << QSCALE_Q_FAC);
4538         s_frame_info.i4_num_entries++;
4539         s_frame_info.i4_num_entries++;
4540 
4541         /*Store the 8 bit qscale with and without accounting for offset*/
4542         /*Can be useful for pre-enc stage*/
4543         if(ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset != 0)
4544         {
4545             s_frame_info.f_8bit_q_scale_without_offset =
4546                 s_frame_info.f_hbd_q_scale_without_offset / (1 << (ps_rc_ctxt->u1_bit_depth - 8));
4547             s_frame_info.f_8bit_q_scale =
4548                 s_frame_info.f_hbd_q_scale / (1 << (ps_rc_ctxt->u1_bit_depth - 8));
4549         }
4550         else
4551         {
4552             s_frame_info.f_8bit_q_scale_without_offset = s_frame_info.f_hbd_q_scale_without_offset;
4553             s_frame_info.f_8bit_q_scale = s_frame_info.f_hbd_q_scale;
4554         }
4555         s_frame_info.i4_num_entries++;
4556         s_frame_info.i4_num_entries++;
4557     }
4558 
4559     /*making intra cost same as ssd as of now*/
4560     i4_intra_cost = u4_frame_intra_sad;
4561 
4562     /* Handling bits stuffing and skips */
4563     {
4564         WORD32 i4_num_bits_to_prevent_vbv_underflow;
4565         vbv_buf_status_e vbv_buffer_status;
4566         vbv_buffer_status = get_buffer_status(
4567             ps_rc_ctxt->rc_hdl,
4568             u4_total_bits_consumed,
4569             rc_pic_type,  //the picture type convention is different in buffer handling
4570             &i4_num_bits_to_prevent_vbv_underflow);
4571 
4572         if(vbv_buffer_status == VBV_UNDERFLOW)
4573         {
4574         }
4575         if(vbv_buffer_status == VBV_OVERFLOW)
4576         {
4577             i4_bits_to_be_stuffed =
4578                 get_bits_to_stuff(ps_rc_ctxt->rc_hdl, u4_total_bits_consumed, rc_pic_type);
4579             //i4_bits_to_be_stuffed = 0;/*STORAGE_RC*/
4580         }
4581     }
4582     {
4583         WORD32 ai4_sad[MAX_PIC_TYPE], i4_valid_sad_entry = 0;
4584         UWORD32 u4_avg_sad = 0;
4585 
4586         /*calculate frame complexity. Given same content frame complexity should not vary across I,P and Bpic. Hence frame complexity is calculated
4587         based on average of all pic types SAD*/
4588         if(rc_pic_type == I_PIC)
4589         {
4590             ai4_sad[I_PIC] = u4_frame_intra_sad;
4591         }
4592         else
4593         {
4594             /*call to get previous I-PIC sad*/
4595             rc_get_sad(ps_rc_ctxt->rc_hdl, &ai4_sad[0]);
4596         }
4597 
4598         /*since intra sad is not available for every frame use previous I pic intra frame SAD*/
4599         rc_put_sad(ps_rc_ctxt->rc_hdl, ai4_sad[I_PIC], u4_frame_sad, rc_pic_type);
4600         rc_get_sad(ps_rc_ctxt->rc_hdl, &ai4_sad[0]);
4601         /*for first few frame valid SAD is not available. This will make sure invalid data is not used*/
4602         if(ps_rc_ctxt->i4_field_pic == 0)
4603         {
4604             for(i = 0; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
4605             {
4606                 if(ai4_sad[i] >= 0)
4607                 {
4608                     u4_avg_sad += ai4_sad[i];
4609                     i4_valid_sad_entry++;
4610                 }
4611             }
4612         }
4613         else /*for field case*/
4614         {
4615             if(ai4_sad[0] >= 0)
4616             {
4617                 u4_avg_sad += ai4_sad[0];
4618                 i4_valid_sad_entry++;
4619             }
4620 
4621             for(i = 1; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
4622             {
4623                 if(ai4_sad[i] >= 0)
4624                 {
4625                     u4_avg_sad += ai4_sad[i];
4626                     i4_valid_sad_entry++;
4627                 }
4628 
4629                 if(ai4_sad[i + FIELD_OFFSET] >= 0)
4630                 {
4631                     u4_avg_sad += ai4_sad[i + FIELD_OFFSET];
4632                     i4_valid_sad_entry++;
4633                 }
4634             }
4635         }
4636 
4637         if(i4_valid_sad_entry > 0)
4638         {
4639             i4_frame_complexity =
4640                 (u4_avg_sad) /
4641                 (i4_valid_sad_entry * (ps_rc_ctxt->i4_frame_width * ps_rc_ctxt->i4_frame_height));
4642         }
4643         else
4644         {
4645             i4_frame_complexity = 1;
4646         }
4647     }
4648     ASSERT(i4_frame_complexity >= 0);
4649     /*I_model only reset In case of fade-in and fade-out*/
4650     if(ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id])
4651     {
4652         ASSERT(rc_pic_type == I_PIC);
4653         rc_reset_pic_model(ps_rc_ctxt->rc_hdl, I_PIC);
4654         ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id] = 0;
4655     }
4656 
4657     /*check if next picture is I frame, both scene cuts and I pictures are treated as end of period*/
4658     {
4659         if(ps_rc_lap_out->i4_rc_pic_type != -1 && ps_rc_lap_out->i4_rc_scene_type != -1)
4660         {
4661             if(ps_rc_ctxt->u4_intra_frame_interval != 1)
4662             {
4663                 /*TBD: For second pass this should be only criteria, While merging to latest verison make sure non - I SCD is not considered as one of the condition*/
4664                 i4_is_last_frm_period = (WORD32)(
4665                     ps_rc_lap_out->i4_next_pic_type == IV_IDR_FRAME ||
4666                     ps_rc_lap_out->i4_next_pic_type == IV_I_FRAME);
4667             }
4668             else
4669             {
4670                 i4_is_last_frm_period =
4671                     (WORD32)(ps_rc_lap_out->i4_next_scene_type == SCENE_TYPE_SCENE_CUT);
4672             }
4673         }
4674 
4675         /*In two pass only I frame ending should be considered end of period, otherwise complexity changes should be allowed to reset model in CBR and VBR modes*/
4676         if(ps_rc_ctxt->i4_rc_pass != 2)
4677             i4_is_last_frm_period = i4_is_last_frm_period ||
4678                                     ps_rc_ctxt->ai4_is_cmplx_change_reset_bits[i4_enc_frm_id];
4679     }
4680 
4681 #if 1  //FRAME_PARALLEL_LVL //ELP_RC
4682     ps_rc_ctxt->i4_est_text_bits_ctr_update_qp++;
4683     ps_rc_ctxt->i4_est_text_bits_ctr_update_qp =
4684         (ps_rc_ctxt->i4_est_text_bits_ctr_update_qp % (ps_rc_ctxt->i4_num_frame_parallel));
4685 #endif
4686 
4687     update_frame_level_info(
4688         ps_rc_ctxt->rc_hdl,
4689         rc_pic_type,
4690         a_mb_type_sad,
4691         u4_total_bits_consumed, /*total bits consumed by frame*/
4692         u4_total_header_bits,
4693         a_mb_type_tex_bits,
4694         a_mb_type_qp_q6, /*sum of qp of all mb in frame, since no ctb level modulation*/
4695         a_mb_in_type,
4696         i4_avg_activity,
4697         ps_rc_ctxt->ai4_is_frame_scd[i4_enc_frm_id], /*currenlty SCD is not enabled*/
4698         0, /*not a pre encode skip*/
4699         i4_intra_cost,
4700         0,
4701         ps_rc_lap_out
4702             ->i4_ignore_for_rc_update, /*HEVC_hierarchy: do not supress update for non-ref B pic*/
4703         i4_bits_to_be_stuffed,
4704         (ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] ||
4705          ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] ||
4706          ps_rc_ctxt->ai4_is_cmplx_change_reset_model[i4_enc_frm_id]),
4707         ps_rc_ctxt->ai4_lap_complexity_q7[i4_enc_frm_id],
4708         i4_is_last_frm_period,
4709         ps_rc_ctxt->ai4_is_cmplx_change_reset_bits[i4_enc_frm_id],
4710         &s_frame_info,
4711         ps_rc_lap_out->i4_is_rc_model_needs_to_be_updated,
4712         ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset,
4713         i4_scene_num,
4714         ps_rc_ctxt->ai4_scene_numbers[i4_scene_num],
4715         ps_rc_ctxt->i4_est_text_bits_ctr_update_qp);
4716     /** reset flags valid for only one frame*/
4717     ps_rc_ctxt->ai4_is_frame_scd[i4_enc_frm_id] = 0;
4718     ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] = 0;
4719     ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] = 0;
4720     ps_rc_ctxt->ai4_is_cmplx_change_reset_model[i4_enc_frm_id] = 0;
4721     ps_rc_ctxt->ai4_is_cmplx_change_reset_bits[i4_enc_frm_id] = 0;
4722 
4723     ps_rc_ctxt->i4_is_first_frame_encoded = 1;
4724 
4725     /** update the scene num for current frame*/
4726     ps_rc_ctxt->au4_scene_num_temp_id[ps_rc_lap_out->i4_rc_temporal_lyr_id] =
4727         ps_rc_lap_out->u4_rc_scene_num;
4728 
4729     if(ps_rc_ctxt->ai4_is_frame_scd[i4_enc_frm_id])
4730     {
4731         /*reset pre-enc SAD whenever SCD is detected so that it does not detect scene cut for other pictures*/
4732         for(i = 0; i < MAX_PIC_TYPE; i++)
4733         {
4734             ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[i] = -1;
4735         }
4736     }
4737 
4738     /*remember i frame's cost metric to scale SAD of next of I frame*/
4739     if(pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME)
4740     {
4741         ps_rc_ctxt->i8_prev_i_frm_cost = ps_rc_ctxt->ai8_cur_frm_intra_cost[i4_enc_frm_id];
4742         ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[rc_pic_type] =
4743             ps_rc_ctxt->ai8_cur_frm_intra_cost[i4_enc_frm_id];
4744     }
4745     /*for other picture types update hme cost*/
4746     else
4747     {
4748         ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[rc_pic_type] =
4749             ps_rc_ctxt->ai8_cur_frame_coarse_ME_cost[i4_enc_frm_id];
4750     }
4751 }
4752 /*!
4753 ******************************************************************************
4754 * \if Function name : ihevce_rc_interface_update \endif
4755 *
4756 * \brief
4757 *   Updating rate control interface parameters after the query call.
4758 *
4759 * \param[in] Rate control interface context,
4760 *            Picture Type
4761 *            Lap out structure pointer
4762 *
4763 *
4764 * \return
4765 *    None
4766 *
4767 * \author Ittiam
4768 *  Ittiam
4769 *
4770 *****************************************************************************
4771 */
ihevce_rc_interface_update(void * pv_ctxt,IV_PICTURE_CODING_TYPE_T pic_type,rc_lap_out_params_t * ps_rc_lap_out,WORD32 i4_avg_frame_hevc_qp,WORD32 i4_enc_frm_id)4772 void ihevce_rc_interface_update(
4773     void *pv_ctxt,
4774     IV_PICTURE_CODING_TYPE_T pic_type,
4775     rc_lap_out_params_t *ps_rc_lap_out,
4776     WORD32 i4_avg_frame_hevc_qp,
4777     WORD32 i4_enc_frm_id)
4778 {
4779     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
4780     picture_type_e rc_pic_type = ihevce_rc_conv_pic_type(
4781         pic_type,
4782         ps_rc_ctxt->i4_field_pic,
4783         ps_rc_lap_out->i4_rc_temporal_lyr_id,
4784         ps_rc_lap_out->i4_is_bottom_field,
4785         ps_rc_ctxt->i4_top_field_first);
4786     WORD32 i;
4787     WORD32 i4_avg_frame_qp_q6, i4_ctr = -1, i4_i, i4_j;
4788     WORD32 i4_scene_num = ps_rc_lap_out->u4_rc_scene_num % MAX_SCENE_NUM;
4789 
4790     /*store frame qp to clip qp accordingly*/
4791     if(ps_rc_lap_out->i4_is_rc_model_needs_to_be_updated)
4792     {
4793         WORD32 i4_i, i4_temp_i_qp, i4_temp_qp;
4794         ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type] = i4_avg_frame_hevc_qp;
4795         ps_rc_ctxt->ai4_scene_numbers[i4_scene_num]++;
4796 
4797         if(rc_pic_type < P1_PIC)
4798             i4_temp_i_qp = i4_avg_frame_hevc_qp - rc_pic_type;
4799         else
4800             i4_temp_i_qp = i4_avg_frame_hevc_qp - rc_pic_type + 4;
4801 
4802         i4_temp_i_qp = ihevce_clip_min_max_qp(ps_rc_ctxt, i4_temp_i_qp, I_PIC, 0);
4803 
4804         if(ps_rc_ctxt->ai4_scene_numbers[i4_scene_num] == 1)
4805         {
4806             for(i4_i = 0; i4_i < 5; i4_i++)
4807             {
4808                 if(ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i4_i] == INIT_HEVCE_QP_RC)
4809                 {
4810                     i4_temp_qp = i4_temp_i_qp + i4_i;
4811                     i4_temp_qp = ihevce_clip_min_max_qp(
4812                         ps_rc_ctxt, i4_temp_qp, (picture_type_e)i4_i, MAX(i4_i - 1, 0));
4813                     ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i4_i] = i4_temp_qp;
4814 
4815                     if(i4_i > 0)
4816                         ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i4_i + 4] = i4_temp_qp;
4817                 }
4818             }
4819         }
4820     }
4821 
4822     for(i4_i = 0; i4_i < MAX_NON_REF_B_PICS_IN_QUEUE_SGI; i4_i++)
4823     {
4824         if(ps_rc_lap_out->u4_rc_scene_num == ps_rc_ctxt->au4_prev_scene_num_multi_scene[i4_i])
4825         {
4826             i4_ctr = i4_i;
4827             break;
4828         }
4829     }
4830     if(-1 == i4_ctr)
4831     {
4832         ps_rc_ctxt->i4_prev_qp_ctr++;
4833         ps_rc_ctxt->i4_prev_qp_ctr = ps_rc_ctxt->i4_prev_qp_ctr % MAX_NON_REF_B_PICS_IN_QUEUE_SGI;
4834         i4_ctr = ps_rc_ctxt->i4_prev_qp_ctr;
4835         ps_rc_ctxt->au4_prev_scene_num_multi_scene[i4_ctr] = ps_rc_lap_out->u4_rc_scene_num;
4836         for(i4_j = 0; i4_j < MAX_PIC_TYPE; i4_j++)
4837         {
4838             ps_rc_ctxt->ai4_qp_for_previous_scene_multi_scene[i4_ctr][i4_j] = 0;
4839         }
4840     }
4841 
4842     {
4843         ps_rc_ctxt->ai4_qp_for_previous_scene_multi_scene[i4_ctr][rc_pic_type] =
4844             i4_avg_frame_hevc_qp;
4845     }
4846 
4847     /*I_model only reset In case of fade-in and fade-out*/
4848     if(ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id])
4849     {
4850         ASSERT(rc_pic_type == I_PIC);
4851         rc_reset_pic_model(ps_rc_ctxt->rc_hdl, I_PIC);
4852         ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id] = 0;
4853     }
4854 
4855     i4_avg_frame_qp_q6 = ps_rc_ctxt->ps_rc_quant_ctxt->pi4_qp_to_qscale_q_factor
4856                              [i4_avg_frame_hevc_qp + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset];
4857 
4858     update_frame_rc_get_frame_qp_info(
4859         ps_rc_ctxt->rc_hdl,
4860         rc_pic_type,
4861         ps_rc_ctxt->ai4_is_frame_scd[i4_enc_frm_id],
4862         (ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] ||
4863          ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] ||
4864          ps_rc_ctxt->ai4_is_cmplx_change_reset_model[i4_enc_frm_id]),
4865         i4_avg_frame_qp_q6,
4866         ps_rc_lap_out->i4_ignore_for_rc_update,
4867         i4_scene_num,
4868         ps_rc_ctxt->ai4_scene_numbers[i4_scene_num]);
4869 
4870     /** update the scene num for current frame*/
4871     ps_rc_ctxt->au4_scene_num_temp_id[ps_rc_lap_out->i4_rc_temporal_lyr_id] =
4872         ps_rc_lap_out->u4_rc_scene_num;
4873 
4874     if(ps_rc_ctxt->ai4_is_frame_scd[i4_enc_frm_id])
4875     {
4876         /*reset pre-enc SAD whenever SCD is detected so that it does not detect scene cut for other pictures*/
4877         for(i = 0; i < MAX_PIC_TYPE; i++)
4878         {
4879             ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[i] = -1;
4880         }
4881     }
4882 
4883     /*remember i frame's cost metric to scale SAD of next of I frame*/
4884     if(pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME)
4885     {
4886         ps_rc_ctxt->i8_prev_i_frm_cost = ps_rc_ctxt->ai8_cur_frm_intra_cost[i4_enc_frm_id];
4887         ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[rc_pic_type] =
4888             ps_rc_ctxt->ai8_cur_frm_intra_cost[i4_enc_frm_id];
4889     }
4890     /*for other picture types update hme cost*/
4891     else
4892     {
4893         ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[rc_pic_type] =
4894             ps_rc_ctxt->ai8_cur_frame_coarse_ME_cost[i4_enc_frm_id];
4895     }
4896 
4897     ps_rc_ctxt->i4_is_first_frame_encoded = 1;
4898 }
4899 
4900 /****************************************************************************
4901 Function Name : ihevce_rc_store_retrive_update_info
4902 Description   : for storing and retrieving the data in case of the Enc Loop Parallelism.
4903 Inputs        :
4904 Globals       :
4905 Processing    :
4906 Outputs       :
4907 Returns       :
4908 Issues        :
4909 Revision History:
4910 DD MM YYYY   Author(s)       Changes (Describe the changes made)
4911 *****************************************************************************/
4912 
ihevce_rc_store_retrive_update_info(void * pv_ctxt,rc_bits_sad_t * ps_rc_frame_stat,WORD32 i4_enc_frm_id_rc,WORD32 bit_rate_id,WORD32 i4_store_retrive,WORD32 * pout_buf_id,WORD32 * pi4_rc_pic_type,WORD32 * pcur_qp,void * ps_lap_out,void * ps_rc_lap_out)4913 void ihevce_rc_store_retrive_update_info(
4914     void *pv_ctxt,
4915     rc_bits_sad_t *ps_rc_frame_stat,
4916     WORD32 i4_enc_frm_id_rc,
4917     WORD32 bit_rate_id,
4918     WORD32 i4_store_retrive,
4919     WORD32 *pout_buf_id,
4920     WORD32 *pi4_rc_pic_type,
4921     WORD32 *pcur_qp,
4922     void *ps_lap_out,
4923     void *ps_rc_lap_out)
4924 {
4925     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
4926     if(1 == i4_store_retrive)
4927     {
4928         memcpy(
4929             &ps_rc_ctxt->as_rc_frame_stat_store[i4_enc_frm_id_rc][bit_rate_id],
4930             ps_rc_frame_stat,
4931             sizeof(rc_bits_sad_t));
4932         memcpy(&ps_rc_ctxt->out_buf_id[i4_enc_frm_id_rc][bit_rate_id], pout_buf_id, sizeof(WORD32));
4933         memcpy(&ps_rc_ctxt->i4_pic_type[i4_enc_frm_id_rc], pi4_rc_pic_type, sizeof(WORD32));
4934         memcpy(&ps_rc_ctxt->cur_qp[i4_enc_frm_id_rc][bit_rate_id], pcur_qp, sizeof(WORD32));
4935         memcpy(
4936             &ps_rc_ctxt->as_lap_out[i4_enc_frm_id_rc],
4937             ps_lap_out,
4938             sizeof(ihevce_lap_output_params_t));
4939         memcpy(
4940             &ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc],
4941             ps_rc_lap_out,
4942             sizeof(rc_lap_out_params_t));
4943 
4944         {
4945             rc_lap_out_params_t *ps_rc_lap_out_curr = (rc_lap_out_params_t *)ps_rc_lap_out;
4946             rc_lap_out_params_t *ps_rc_lap_out_next_encode =
4947                 (rc_lap_out_params_t *)ps_rc_lap_out_curr->ps_rc_lap_out_next_encode;
4948 
4949             if(NULL != ps_rc_lap_out_next_encode)
4950             {
4951                 ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc].i4_next_pic_type =
4952                     ps_rc_lap_out_next_encode->i4_rc_pic_type;
4953                 ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc].i4_next_scene_type =
4954                     ps_rc_lap_out_next_encode->i4_rc_scene_type;
4955             }
4956             else
4957             {
4958                 if(ps_rc_ctxt->u4_intra_frame_interval <= 1 ||
4959                    (ps_rc_lap_out_curr->i4_rc_display_num &&
4960                     (ps_rc_lap_out_curr->i4_rc_display_num %
4961                      (ps_rc_ctxt->u4_intra_frame_interval - 1)) == 0))
4962                 {
4963                     ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc].i4_next_pic_type = IV_I_FRAME;
4964                 }
4965                 else
4966                 {
4967                     ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc].i4_next_pic_type = -1;
4968                 }
4969                 ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc].i4_next_scene_type = -1;
4970             }
4971             ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc].ps_rc_lap_out_next_encode = NULL;
4972         }
4973     }
4974     else if(2 == i4_store_retrive)
4975     {
4976         memcpy(
4977             ps_rc_frame_stat,
4978             &ps_rc_ctxt->as_rc_frame_stat_store[i4_enc_frm_id_rc][bit_rate_id],
4979             sizeof(rc_bits_sad_t));
4980         memcpy(pout_buf_id, &ps_rc_ctxt->out_buf_id[i4_enc_frm_id_rc][bit_rate_id], sizeof(WORD32));
4981         memcpy(pi4_rc_pic_type, &ps_rc_ctxt->i4_pic_type[i4_enc_frm_id_rc], sizeof(WORD32));
4982         memcpy(pcur_qp, &ps_rc_ctxt->cur_qp[i4_enc_frm_id_rc][bit_rate_id], sizeof(WORD32));
4983         memcpy(
4984             ps_lap_out,
4985             &ps_rc_ctxt->as_lap_out[i4_enc_frm_id_rc],
4986             sizeof(ihevce_lap_output_params_t));
4987         memcpy(
4988             ps_rc_lap_out,
4989             &ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc],
4990             sizeof(rc_lap_out_params_t));
4991     }
4992     else
4993     {
4994         ASSERT(0);
4995     }
4996 }
4997 
4998 /*###############################################*/
4999 /******* END OF RC UPDATE FUNCTIONS **************/
5000 /*###############################################*/
5001 
5002 /*#################################################*/
5003 /******* START OF RC UTILS FUNCTIONS **************/
5004 /*#################################################*/
5005 
5006 /**
5007 ******************************************************************************
5008 *
5009 *  @brief function to account for error correction between bits rdopt estimate
5010 *           and actual entropy bit generation
5011 *
5012 *  @par   Description
5013 *
5014 *  @param[in]   pv_rc_ctxt
5015 *               void pointer to rc ctxt
5016 *  @param[in]   i4_rdopt_bits_gen_error
5017 *               WODd32 variable with error correction between rdopt and entropy bytes gen
5018 *
5019 *  @return      void
5020 *
5021 ******************************************************************************
5022 */
5023 
ihevce_rc_rdopt_entropy_bit_correct(void * pv_rc_ctxt,WORD32 i4_cur_entropy_consumption,WORD32 i4_buf_id)5024 void ihevce_rc_rdopt_entropy_bit_correct(
5025     void *pv_rc_ctxt, WORD32 i4_cur_entropy_consumption, WORD32 i4_buf_id)
5026 {
5027     rc_context_t *ps_ctxt = (rc_context_t *)pv_rc_ctxt;
5028     WORD32 i4_error;
5029     WORD32 i, count = 0;
5030     ASSERT(i4_buf_id >= 0);
5031     ps_ctxt->ai4_entropy_bit_consumption[ps_ctxt->i4_entropy_bit_count] =
5032         i4_cur_entropy_consumption;
5033     ps_ctxt->ai4_entropy_bit_consumption_buf_id[ps_ctxt->i4_entropy_bit_count] = i4_buf_id;
5034     ps_ctxt->i4_entropy_bit_count = (ps_ctxt->i4_entropy_bit_count + 1) % NUM_BUF_RDOPT_ENT_CORRECT;
5035 
5036     for(i = 0; i < NUM_BUF_RDOPT_ENT_CORRECT; i++)
5037     {
5038         if(ps_ctxt->ai4_rdopt_bit_consumption_buf_id[i] >= 0 &&
5039            (ps_ctxt->ai4_rdopt_bit_consumption_buf_id[i] ==
5040             ps_ctxt->ai4_entropy_bit_consumption_buf_id[i]))
5041         {
5042             i4_error = ps_ctxt->ai4_rdopt_bit_consumption_estimate[i] -
5043                        ps_ctxt->ai4_entropy_bit_consumption[i];
5044             //DBG_PRINTF("entropy mismatch error = %d\n",i4_error/ps_ctxt->ai4_rdopt_bit_consumption_estimate[i]);
5045             ps_ctxt->ai4_rdopt_bit_consumption_estimate[i] = -1;
5046             ps_ctxt->ai4_rdopt_bit_consumption_buf_id[i] = -1;
5047             ps_ctxt->ai4_entropy_bit_consumption[i] = -1;
5048             ps_ctxt->ai4_entropy_bit_consumption_buf_id[i] = -1;
5049             /*accumulate mismatch along with gop level bit error that is propogated to next frame*/
5050             /*error = rdopt - entropy so it is expected to be negative*/
5051             rc_update_mismatch_error(ps_ctxt->rc_hdl, i4_error);
5052             count++;
5053         }
5054     }
5055 }
5056 
5057 /**
5058 ******************************************************************************
5059 *
5060 *  @name  ihevce_rc_check_non_lap_scd
5061 *
5062 *  @par   Description Detects SCD frames as I_only_scds or non_I_scds based
5063                       on intrasatd & ME costs. Updates scd flags
5064 *
5065 *  @param[in]   ps_rc_ctxt  - pointer to rc context
5066 *               ps_rc_lap_out
5067 *  @return      void
5068 *
5069 ******************************************************************************
5070 */
ihevce_rc_check_non_lap_scd(void * pv_rc_ctxt,rc_lap_out_params_t * ps_rc_lap_out)5071 void ihevce_rc_check_non_lap_scd(void *pv_rc_ctxt, rc_lap_out_params_t *ps_rc_lap_out)
5072 {
5073     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
5074     picture_type_e rc_pic_type = ihevce_rc_conv_pic_type(
5075         (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out->i4_rc_pic_type,
5076         ps_rc_ctxt->i4_field_pic,
5077         ps_rc_lap_out->i4_rc_temporal_lyr_id,
5078         ps_rc_lap_out->i4_is_bottom_field,
5079         ps_rc_ctxt->i4_top_field_first);
5080 
5081     /*Init to normal frames*/
5082     ps_rc_lap_out->i4_is_I_only_scd = 0;
5083     ps_rc_lap_out->i4_is_non_I_scd = 0;
5084 
5085     /*None of the above check is valid if marked as scene cut*/
5086     if(ps_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_SCENE_CUT)
5087     {
5088         WORD32 i;
5089         /*reset all older data*/
5090         for(i = 0; i < MAX_PIC_TYPE; i++)
5091         {
5092             ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[i] = -1;
5093             ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_cost[i] = -1;
5094             ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_sad[i] = -1;
5095         }
5096     }
5097     else
5098     {
5099         /*Check if it is I only reset case, lap_out is assumed to have latest data which is used to set the corresponding flags*/
5100         /*For I pic check for I only reset case and for other pictures check for non-I scd case*/
5101         if(rc_pic_type == I_PIC)
5102         {
5103             if(ps_rc_lap_out->i8_pre_intra_satd <
5104                    (ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[rc_pic_type] >> 1) ||
5105                ps_rc_lap_out->i8_pre_intra_satd >
5106                    (ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[rc_pic_type] << 1))
5107             {
5108                 /*Check if atleast one frame data is available*/
5109                 if(ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[rc_pic_type] >= 0)
5110                     ps_rc_lap_out->i4_is_I_only_scd = 1;
5111             }
5112         }
5113         else if(
5114             ((rc_pic_type == P_PIC) &&
5115              (ps_rc_lap_out->i4_rc_quality_preset == IHEVCE_QUALITY_P6)) ||
5116             (ps_rc_lap_out->i4_rc_quality_preset < IHEVCE_QUALITY_P6))
5117         {
5118 #define SAD_THREASHOLD_30FPS (2.5)
5119             /*Choose threshold as 2.5 for 30 fps content and 1.75 for 60 fps. Scale accordingly for intermediate framerate*/
5120             WORD32 i4_non_simple_repeat_prev_frame_detect = 0;
5121             float sad_change_threshold =
5122                 (float)(-0.8f * ((float)ps_rc_ctxt->u4_max_frame_rate / 30000) + 3.05f); /*Change of SAD threshold for 30 fps content, this should be lowered for 60 fps*/
5123             if(sad_change_threshold < 1.5f)
5124                 sad_change_threshold = 1.5f;
5125             if(sad_change_threshold > 3.0f)
5126                 sad_change_threshold = 3.0f;
5127             ASSERT(ps_rc_lap_out->i8_raw_l1_coarse_me_sad >= 0);
5128 
5129             /*block variance computed at 4x4 level in w/4*h/4,
5130                 percent dc blks is how many block's variance are less than or equal to 16*/
5131             if(ps_rc_lap_out->i4_perc_dc_blks < 85)
5132             {
5133                 /*me sad is expected to be zero for repeat frames*/
5134                 if((ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_sad[rc_pic_type] ==
5135                     0) &&
5136                    (ps_rc_lap_out->i4_rc_temporal_lyr_id == ps_rc_ctxt->i4_max_temporal_lyr))
5137                 {
5138                     i4_non_simple_repeat_prev_frame_detect = 1;
5139                 }
5140             }
5141             if(ps_rc_lap_out->i8_frame_acc_coarse_me_cost >
5142                    (sad_change_threshold *
5143                     ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_cost[rc_pic_type]) &&
5144                (ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_cost[rc_pic_type] >= 0) &&
5145                (!i4_non_simple_repeat_prev_frame_detect))
5146             {
5147                 WORD32 one_per_pixel_sad_L1;
5148                 /*per pixel sad has to be greater than 1 to avoid repeat frames influence non-I scd detection*/
5149                 if((ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) < 4000000)
5150                 {
5151                     /*1080*/
5152                     one_per_pixel_sad_L1 =
5153                         (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) >> 2;
5154                 }
5155                 else
5156                 {
5157                     /*4k*/
5158                     one_per_pixel_sad_L1 =
5159                         (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) >> 4;
5160                 }
5161                 if(ps_rc_lap_out->i8_frame_acc_coarse_me_cost > one_per_pixel_sad_L1)
5162                 {
5163                     {
5164                         ps_rc_lap_out->i4_is_non_I_scd = 1;
5165                     }
5166                 }
5167             }
5168 
5169             if(rc_pic_type == P_PIC)
5170             {
5171                 if(ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_cost[rc_pic_type] < 0)
5172                 {
5173                     if(ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[I_PIC] > 0)
5174                     {
5175                         if(ps_rc_lap_out->i8_pre_intra_satd >
5176                            ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[I_PIC] << 1)
5177                         {
5178                             ps_rc_lap_out->i4_is_non_I_scd = 1;
5179                         }
5180                     }
5181                 }
5182             }
5183         }
5184     }
5185 
5186     /*remember the previous frame stats*/
5187     ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[rc_pic_type] =
5188         ps_rc_lap_out->i8_pre_intra_satd;  //ps_rc_lap_out->i8_pre_intra_satd;
5189     ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_cost[rc_pic_type] =
5190         ps_rc_lap_out->i8_frame_acc_coarse_me_cost;  //ps_rc_lap_out->i8_frame_acc_coarse_me_sad;
5191     ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_sad[rc_pic_type] =
5192         ps_rc_lap_out->i8_raw_l1_coarse_me_sad;
5193 }
5194 
5195 /**
5196 ******************************************************************************
5197 *
5198 *  @name  ihevce_rc_check_is_pre_enc_qp_valid
5199 *
5200 *  @par   Description  checking whether enc thread has updated qp in reverse queue
5201 *
5202 *  @param[in]   ps_rc_ctxt  - pointer to rc context
5203 *
5204 *  @return      zero on success
5205 *
5206 ******************************************************************************
5207 */
5208 /**only function accessed by encoder without using mutex lock*/
ihevce_rc_check_is_pre_enc_qp_valid(void * pv_rc_ctxt,volatile WORD32 * pi4_force_end_flag)5209 WORD32 ihevce_rc_check_is_pre_enc_qp_valid(void *pv_rc_ctxt, volatile WORD32 *pi4_force_end_flag)
5210 {
5211     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
5212 
5213     volatile WORD32 i4_is_qp_valid;
5214     volatile WORD32 *pi4_is_qp_valid;
5215 
5216     pi4_is_qp_valid =
5217         (volatile WORD32 *)&ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_read_index]
5218             .i4_is_qp_valid;
5219     i4_is_qp_valid = *pi4_is_qp_valid;
5220 
5221     /*Due to stagger between L1 IPE and L0 IPE, towards the end (when encoder is in flush mode) L0 IPE can race ahead of enc
5222     since it will suddenly get stagger between L1 and L0 worth of free buffers. It could try to start L0 even before enc has
5223     populated qp for such frames. qp = -1 is returned in such case which implies encoder should wait for qp to be pop*/
5224 
5225     while(i4_is_qp_valid == -1)
5226     {
5227         /*this rate control call is outside mutex lock to avoid deadlock. If this acquires mutex lock enc will not be able to
5228         populate qp*/
5229         i4_is_qp_valid = *pi4_is_qp_valid;
5230 
5231         if(1 == (*pi4_force_end_flag))
5232         {
5233             *pi4_is_qp_valid = 1;
5234             i4_is_qp_valid = 1;
5235         }
5236     }
5237     return 0;
5238 }
5239 
5240 /*!
5241 ******************************************************************************
5242 * \if Function name : ihevce_compute_temporal_complexity_reset_Kp_Kb
5243 *
5244 * \brief
5245 *
5246 * \param[in] *pv_ctxt -> rc context
5247 *
5248 * \return
5249 *
5250 * \author
5251 *  Ittiam
5252 *
5253 *****************************************************************************
5254 */
ihevce_compute_temporal_complexity_reset_Kp_Kb(rc_lap_out_params_t * ps_rc_lap_out,void * pv_rc_ctxt,WORD32 i4_Kp_Kb_reset_flag)5255 void ihevce_compute_temporal_complexity_reset_Kp_Kb(
5256     rc_lap_out_params_t *ps_rc_lap_out, void *pv_rc_ctxt, WORD32 i4_Kp_Kb_reset_flag)
5257 {
5258     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
5259     rc_lap_out_params_t *ps_cur_rc_lap_out_temporal_offset,
5260         *ps_cur_rc_lap_out_temporal_offset_scd_detect;
5261     picture_type_e curr_rc_pic_type;
5262     LWORD64 i8_total_acc_coarse_me_sad = 0, i8_avg_acc_coarse_me_sad = 0;
5263     WORD8 i1_num_frames_in_Sub_GOP = 0, i = 0, i1_no_reset = 0;
5264     WORD32 i4_inter_frame_interval = rc_get_inter_frame_interval(ps_rc_ctxt->rc_hdl);
5265     WORD32 i4_frame_qp = 0, i4_temp_frame_qp = 0;
5266     WORD32 ai4_offsets[5] = { -3, -2, 2, 6, 7 };
5267     ps_cur_rc_lap_out_temporal_offset = ps_rc_lap_out;
5268     ps_cur_rc_lap_out_temporal_offset_scd_detect = ps_rc_lap_out;
5269 
5270     curr_rc_pic_type = ihevce_rc_conv_pic_type(
5271         (IV_PICTURE_CODING_TYPE_T)ps_cur_rc_lap_out_temporal_offset->i4_rc_pic_type,
5272         ps_rc_ctxt->i4_field_pic,
5273         ps_cur_rc_lap_out_temporal_offset->i4_rc_temporal_lyr_id,
5274         ps_cur_rc_lap_out_temporal_offset->i4_is_bottom_field,
5275         ps_rc_ctxt->i4_top_field_first);
5276 
5277     if(curr_rc_pic_type == I_PIC)
5278     {
5279         ps_cur_rc_lap_out_temporal_offset_scd_detect =
5280             (rc_lap_out_params_t *)ps_cur_rc_lap_out_temporal_offset->ps_rc_lap_out_next_encode;
5281         ps_cur_rc_lap_out_temporal_offset =
5282             (rc_lap_out_params_t *)ps_cur_rc_lap_out_temporal_offset->ps_rc_lap_out_next_encode;
5283 
5284         if(NULL != ps_cur_rc_lap_out_temporal_offset)
5285         {
5286             curr_rc_pic_type = ihevce_rc_conv_pic_type(
5287                 (IV_PICTURE_CODING_TYPE_T)ps_cur_rc_lap_out_temporal_offset->i4_rc_pic_type,
5288                 ps_rc_ctxt->i4_field_pic,
5289                 ps_cur_rc_lap_out_temporal_offset->i4_rc_temporal_lyr_id,
5290                 ps_cur_rc_lap_out_temporal_offset->i4_is_bottom_field,
5291                 ps_rc_ctxt->i4_top_field_first);
5292         }
5293         else
5294             return;
5295     }
5296 
5297     if(ps_cur_rc_lap_out_temporal_offset->i4_L1_qp == -1)
5298         return;
5299 
5300     if(ps_cur_rc_lap_out_temporal_offset->i4_L0_qp == -1)
5301         i4_frame_qp = ps_cur_rc_lap_out_temporal_offset->i4_L1_qp;
5302     else
5303         i4_frame_qp = ps_cur_rc_lap_out_temporal_offset->i4_L0_qp;
5304 
5305     i1_num_frames_in_Sub_GOP = 0;
5306     i = 0;
5307 
5308     i1_no_reset = 0;
5309     do
5310     {
5311         if(ps_cur_rc_lap_out_temporal_offset != NULL)
5312         {
5313             if(curr_rc_pic_type != I_PIC)
5314                 i4_temp_frame_qp =
5315                     i4_frame_qp + ps_cur_rc_lap_out_temporal_offset->i4_rc_temporal_lyr_id + 1;
5316 
5317             i4_temp_frame_qp += ai4_offsets[curr_rc_pic_type];
5318             i4_temp_frame_qp = CLIP3(i4_temp_frame_qp, 1, 51);
5319 
5320             {
5321                 if(curr_rc_pic_type != I_PIC)
5322                 {
5323                     i8_total_acc_coarse_me_sad +=
5324                         ps_cur_rc_lap_out_temporal_offset
5325                             ->ai8_frame_acc_coarse_me_sad[i4_temp_frame_qp];
5326                     i1_num_frames_in_Sub_GOP++;
5327                     i++;
5328                 }
5329                 else
5330                 {
5331                     break;
5332                 }
5333             }
5334 
5335             ps_cur_rc_lap_out_temporal_offset =
5336                 (rc_lap_out_params_t *)ps_cur_rc_lap_out_temporal_offset->ps_rc_lap_out_next_encode;
5337 
5338             if(ps_cur_rc_lap_out_temporal_offset == NULL)
5339             {
5340                 break;
5341             }
5342             curr_rc_pic_type = ihevce_rc_conv_pic_type(
5343                 (IV_PICTURE_CODING_TYPE_T)ps_cur_rc_lap_out_temporal_offset->i4_rc_pic_type,
5344                 ps_rc_ctxt->i4_field_pic,
5345                 ps_cur_rc_lap_out_temporal_offset->i4_rc_temporal_lyr_id,
5346                 ps_cur_rc_lap_out_temporal_offset->i4_is_bottom_field,
5347                 ps_rc_ctxt->i4_top_field_first);
5348         }
5349         else
5350         {
5351             i1_num_frames_in_Sub_GOP = 0;
5352             break;
5353         }
5354     } while(
5355         ((((curr_rc_pic_type != P_PIC) && ((curr_rc_pic_type != I_PIC))) ||
5356           (curr_rc_pic_type == P_PIC)) &&
5357          (i1_num_frames_in_Sub_GOP < i4_inter_frame_interval)));
5358 
5359     if((i1_num_frames_in_Sub_GOP) && (i1_no_reset == 0))
5360     {
5361         float f_hme_sad_per_pixel;
5362         i8_avg_acc_coarse_me_sad = (i8_total_acc_coarse_me_sad / i1_num_frames_in_Sub_GOP);
5363         f_hme_sad_per_pixel =
5364             ((float)i8_avg_acc_coarse_me_sad /
5365              (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width));
5366         f_hme_sad_per_pixel = CLIP3(f_hme_sad_per_pixel, 0.01f, 5.0f);
5367         /*reset the QP offsets for the next sub GOP depending on the offline model based on the temporal complexity */
5368         if(i4_Kp_Kb_reset_flag)
5369         {
5370             WORD32 i4_bin;
5371 
5372             rc_reset_Kp_Kb(
5373                 ps_rc_ctxt->rc_hdl,
5374                 8.00,
5375                 ps_rc_ctxt->i4_num_active_pic_type,
5376                 f_hme_sad_per_pixel,
5377                 &i4_bin,
5378                 ps_rc_ctxt->i4_rc_pass);
5379         }
5380         else
5381         {
5382             rc_ba_get_qp_offset_offline_data(
5383                 ps_rc_ctxt->rc_hdl,
5384                 ps_rc_lap_out->ai4_offsets,
5385                 f_hme_sad_per_pixel,
5386                 ps_rc_ctxt->i4_num_active_pic_type,
5387                 &ps_rc_lap_out->i4_complexity_bin);
5388 
5389             ps_cur_rc_lap_out_temporal_offset = ps_rc_lap_out;
5390             ps_cur_rc_lap_out_temporal_offset->i4_offsets_set_flag = 1;
5391 
5392             curr_rc_pic_type = ihevce_rc_conv_pic_type(
5393                 (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out->i4_rc_pic_type,
5394                 ps_rc_ctxt->i4_field_pic,
5395                 ps_rc_lap_out->i4_rc_temporal_lyr_id,
5396                 ps_rc_lap_out->i4_is_bottom_field,
5397                 ps_rc_ctxt->i4_top_field_first);
5398 
5399             if((curr_rc_pic_type == I_PIC) &&
5400                ((rc_lap_out_params_t *)ps_cur_rc_lap_out_temporal_offset->ps_rc_lap_out_next_encode)
5401                        ->i4_rc_pic_type == P_PIC)
5402                 i1_num_frames_in_Sub_GOP++;
5403 
5404             for(i = 1; i < i1_num_frames_in_Sub_GOP; i++)
5405             {
5406                 ps_cur_rc_lap_out_temporal_offset =
5407                     (rc_lap_out_params_t *)
5408                         ps_cur_rc_lap_out_temporal_offset->ps_rc_lap_out_next_encode;
5409                 memmove(
5410                     ps_cur_rc_lap_out_temporal_offset->ai4_offsets,
5411                     ps_rc_lap_out->ai4_offsets,
5412                     sizeof(WORD32) * 5);
5413                 ps_cur_rc_lap_out_temporal_offset->i4_complexity_bin =
5414                     ps_rc_lap_out->i4_complexity_bin;
5415                 ps_cur_rc_lap_out_temporal_offset->i4_offsets_set_flag = 1;
5416             }
5417         }
5418     }
5419 }
5420 
5421 /**
5422 ******************************************************************************
5423 *
5424 *  @brief function to get delta QP or In frame RC bits estimate to avoid buffer underflow
5425 *
5426 *  @par   Description
5427 *  @param[in]
5428 ******************************************************************************
5429 */
5430 
ihevce_ebf_based_rc_correction_to_avoid_overflow(rc_context_t * ps_rc_ctxt,rc_lap_out_params_t * ps_rc_lap_out,WORD32 * pi4_tot_bits_estimated)5431 WORD32 ihevce_ebf_based_rc_correction_to_avoid_overflow(
5432     rc_context_t *ps_rc_ctxt, rc_lap_out_params_t *ps_rc_lap_out, WORD32 *pi4_tot_bits_estimated)
5433 {
5434     WORD32 i4_modelQP, i4_clipQP, i4_maxEbfQP, i4_diffQP, i4_is_model_valid, i4_deltaQP = 0;
5435     LWORD64 i8_bitsClipQP, i8_grwEbf;  // i8_bitsComp;
5436     WORD32 i4_is_offline_model_used;
5437     WORD32 i4_vbv_buffer_size, i4_drain_rate, i4_currEbf, i4_maxEbf;
5438     WORD32 i4_case = -1;
5439     float f_thrsh_i_pic_delta_qp_1, f_thrsh_i_pic_delta_qp_2, f_thrsh_p_pic_delta_qp_1,
5440         f_thrsh_p_pic_delta_qp_2;
5441     float f_thrsh_br_pic_delta_qp_1, f_thrsh_br_pic_delta_qp_2, f_thrsh_bnr_pic_delta_qp_1,
5442         f_thrsh_bnr_pic_delta_qp_2;
5443     float f_vbv_thrsh_delta_qp;
5444 
5445     /*initialization of all the variables*/
5446     rc_init_buffer_info(
5447         ps_rc_ctxt->rc_hdl, &i4_vbv_buffer_size, &i4_currEbf, &i4_maxEbf, &i4_drain_rate);
5448 
5449     i4_is_model_valid = ps_rc_lap_out->i4_is_model_valid;
5450     i4_modelQP = ps_rc_ctxt->s_rc_high_lvl_stat.i4_modelQP;
5451     i4_clipQP = ps_rc_ctxt->s_rc_high_lvl_stat.i4_finalQP;
5452     i4_maxEbfQP = ps_rc_ctxt->s_rc_high_lvl_stat.i4_maxEbfQP;
5453     i8_bitsClipQP = ps_rc_ctxt->s_rc_high_lvl_stat.i8_bits_from_finalQP;
5454     i4_is_offline_model_used = ps_rc_ctxt->s_rc_high_lvl_stat.i4_is_offline_model_used;
5455     ASSERT(i4_clipQP != INVALID_QP);
5456 
5457     if(ps_rc_ctxt->i4_num_frame_parallel > 1)
5458     {
5459         f_thrsh_i_pic_delta_qp_1 = (float)VBV_THRSH_FRM_PRLL_I_PIC_DELTA_QP_1;
5460         f_thrsh_i_pic_delta_qp_2 = (float)VBV_THRSH_FRM_PRLL_I_PIC_DELTA_QP_2;
5461         f_thrsh_p_pic_delta_qp_1 = (float)VBV_THRSH_FRM_PRLL_P_PIC_DELTA_QP_1;
5462         f_thrsh_p_pic_delta_qp_2 = (float)VBV_THRSH_FRM_PRLL_P_PIC_DELTA_QP_2;
5463         f_thrsh_br_pic_delta_qp_1 = (float)VBV_THRSH_FRM_PRLL_BR_PIC_DELTA_QP_1;
5464         f_thrsh_br_pic_delta_qp_2 = (float)VBV_THRSH_FRM_PRLL_BR_PIC_DELTA_QP_2;
5465         f_thrsh_bnr_pic_delta_qp_1 = (float)VBV_THRSH_FRM_PRLL_BNR_PIC_DELTA_QP_1;
5466         f_thrsh_bnr_pic_delta_qp_2 = (float)VBV_THRSH_FRM_PRLL_BNR_PIC_DELTA_QP_2;
5467         f_vbv_thrsh_delta_qp = (float)VBV_THRSH_FRM_PRLL_DELTA_QP;
5468     }
5469     else
5470     {
5471         f_thrsh_i_pic_delta_qp_1 = (float)VBV_THRSH_I_PIC_DELTA_QP_1;
5472         f_thrsh_i_pic_delta_qp_2 = (float)VBV_THRSH_I_PIC_DELTA_QP_2;
5473         f_thrsh_p_pic_delta_qp_1 = (float)VBV_THRSH_P_PIC_DELTA_QP_1;
5474         f_thrsh_p_pic_delta_qp_2 = (float)VBV_THRSH_P_PIC_DELTA_QP_2;
5475         f_thrsh_br_pic_delta_qp_1 = (float)VBV_THRSH_BR_PIC_DELTA_QP_1;
5476         f_thrsh_br_pic_delta_qp_2 = (float)VBV_THRSH_BR_PIC_DELTA_QP_2;
5477         f_thrsh_bnr_pic_delta_qp_1 = (float)VBV_THRSH_BNR_PIC_DELTA_QP_1;
5478         f_thrsh_bnr_pic_delta_qp_2 = (float)VBV_THRSH_BNR_PIC_DELTA_QP_2;
5479         f_vbv_thrsh_delta_qp = (float)VBV_THRSH_DELTA_QP;
5480     }
5481 
5482     /* function logic starts */
5483     if(i4_is_model_valid)
5484     {
5485         ASSERT(i4_modelQP != INVALID_QP);
5486         i8_grwEbf = i8_bitsClipQP - (LWORD64)i4_drain_rate;
5487         if(((i4_currEbf + i8_grwEbf) > (0.6*i4_vbv_buffer_size)) /*&&
5488                  i4_modelQP >= i4_clipQP*/)
5489         {
5490             /* part of existing scene (i.e. no new scene)
5491             In which case this is not first I/P/Bref/Bnref etc
5492             The models for I/P/Bref/Bnref are all valid*/
5493             if(((i4_currEbf + i8_grwEbf) <
5494                 i4_maxEbf)) /* does not matter whether this is 2pass, 1 pass, VBR, CBR etc*/
5495             {
5496                 /* clipQP has been determined keeping in view certain other quality constraints like pusling etc.
5497                 So better to honour it if possible*/
5498                 //if (i8_bitsClipQP > i8_drain_rate)
5499                 {
5500                     LWORD64 i8_thrsh_for_deltaQP_2 = i4_vbv_buffer_size,
5501                             i8_thrsh_for_deltaQP_1 = i4_vbv_buffer_size;
5502                     /*even when (modelQP - clipQP) = 0, we intend to QP increase as expected ebf is above 60%*/
5503                     i4_diffQP = MAX(i4_modelQP - i4_clipQP, 1);
5504                     switch(ps_rc_lap_out->i4_rc_pic_type)
5505                     {
5506                     case IV_I_FRAME:
5507                     case IV_IDR_FRAME:
5508                     {
5509                         i8_thrsh_for_deltaQP_1 =
5510                             (LWORD64)(f_thrsh_i_pic_delta_qp_1 * i4_vbv_buffer_size);
5511                         i8_thrsh_for_deltaQP_2 =
5512                             (LWORD64)(f_thrsh_i_pic_delta_qp_2 * i4_vbv_buffer_size);
5513                         break;
5514                     }
5515                     case IV_P_FRAME:
5516                     {
5517                         i8_thrsh_for_deltaQP_1 =
5518                             (LWORD64)(f_thrsh_p_pic_delta_qp_1 * i4_vbv_buffer_size);
5519                         i8_thrsh_for_deltaQP_2 =
5520                             (LWORD64)(f_thrsh_p_pic_delta_qp_2 * i4_vbv_buffer_size);
5521                         break;
5522                     }
5523                     case IV_B_FRAME:
5524                     {
5525                         if(ps_rc_lap_out->i4_rc_is_ref_pic)
5526                         {
5527                             i8_thrsh_for_deltaQP_1 =
5528                                 (LWORD64)(f_thrsh_br_pic_delta_qp_1 * i4_vbv_buffer_size);
5529                             i8_thrsh_for_deltaQP_2 =
5530                                 (LWORD64)(f_thrsh_br_pic_delta_qp_2 * i4_vbv_buffer_size);
5531                         }
5532                         else
5533                         {
5534                             /*as of now using the same thresholds as B reference, later may have to tune if required*/
5535                             i8_thrsh_for_deltaQP_1 =
5536                                 (LWORD64)(f_thrsh_bnr_pic_delta_qp_1 * i4_vbv_buffer_size);
5537                             i8_thrsh_for_deltaQP_2 =
5538                                 (LWORD64)(f_thrsh_bnr_pic_delta_qp_2 * i4_vbv_buffer_size);
5539                         }
5540                         break;
5541                     }
5542                     default:
5543                         break;
5544                     }
5545 
5546                     if((i4_currEbf + i8_grwEbf) > i8_thrsh_for_deltaQP_1)
5547                     {
5548                         /*For more than 2 QP chnage this means a larger scale issue and probably needs to be handled elsewhere ?*/
5549                         i4_deltaQP =
5550                             MIN(2, i4_diffQP); /* we dont intend to change QP by more than 2 */
5551                         i4_case = 0;
5552                     }
5553                     else if((i4_currEbf + i8_grwEbf) > i8_thrsh_for_deltaQP_2)
5554                     {
5555                         i4_deltaQP = MIN(1, i4_diffQP);
5556                         i4_case = 1;
5557                     }
5558                 }
5559                 /* else  if (i8_bitsClipQP > i8_drain_rate)
5560         {
5561                 we have no correection, buffer will be healthy after this.
5562                 However, there could be one problem if the currEbf is already close to say 80% of EBF.
5563                 This means we have not reacted well early - needs to be handled?
5564 
5565                 This could be the case where it is a simple scene immediately following a complex scene
5566                 and is the I picture (not the first I since model is valid).
5567                 Is this possible - maybe, what to do - dont know?
5568         }
5569                 */
5570             }
5571             else /*(i4_clipQP < i4_maxEbfQP)*/
5572             {
5573                 i4_deltaQP = 2;
5574                 i4_case = 2;
5575             }
5576         }
5577         if((i4_currEbf + i8_grwEbf) < (0.6 * i4_vbv_buffer_size))
5578         {
5579             *pi4_tot_bits_estimated = i8_bitsClipQP;
5580         }
5581     }
5582     else
5583     {
5584         if(i4_is_offline_model_used)
5585         {
5586             /* this can be only for non-I SCD, where we reset RC */
5587             WORD32 i4_bits_est_for_in_frm_rc = *pi4_tot_bits_estimated;
5588             i8_grwEbf = i4_bits_est_for_in_frm_rc - i4_drain_rate;
5589             if((i4_currEbf + i8_grwEbf) > (f_vbv_thrsh_delta_qp * i4_vbv_buffer_size))
5590             {
5591                 i4_bits_est_for_in_frm_rc =
5592                     i4_drain_rate + (WORD32)(0.85 * i4_vbv_buffer_size) - i4_currEbf;
5593                 /* if pi4_tot_bits_estimated becomes less than zero or less than drain rate this indiactes that we are near or above 85% of the buffer */
5594                 /* this needs a reaction */
5595                 if(i4_bits_est_for_in_frm_rc < i4_drain_rate)
5596                 {
5597                     *pi4_tot_bits_estimated =
5598                         MAX((i4_drain_rate + (WORD32)(0.95 * i4_vbv_buffer_size) - i4_currEbf),
5599                             i4_drain_rate);
5600                     i4_deltaQP = 2; /* this needs some review, needs to be handled well */
5601                 }
5602             }
5603             i4_case = 3;
5604         }
5605         else
5606         {
5607             i8_bitsClipQP = *pi4_tot_bits_estimated;
5608             i8_grwEbf = i8_bitsClipQP - i4_drain_rate;
5609 
5610             if(((i4_currEbf + i8_grwEbf) <
5611                 i4_maxEbf)) /* does not matter whether this is 2pass, 1 pass, VBR, CBR etc*/
5612             {
5613                 /* clipQP has been determined keeping in view certain other quality constraints like pusling etc.
5614                     So better to honour it if possible*/
5615                 //if (i8_bitsClipQP > i8_drain_rate)
5616                 {
5617                     LWORD64 i8_thrsh_for_deltaQP_2 = i4_vbv_buffer_size,
5618                             i8_thrsh_for_deltaQP_1 = i4_vbv_buffer_size;
5619 
5620                     switch(ps_rc_lap_out->i4_rc_pic_type)
5621                     {
5622                     case IV_I_FRAME:
5623                     case IV_IDR_FRAME:
5624                     {
5625                         i8_thrsh_for_deltaQP_1 =
5626                             (LWORD64)(f_thrsh_i_pic_delta_qp_1 * i4_vbv_buffer_size);
5627                         i8_thrsh_for_deltaQP_2 =
5628                             (LWORD64)(f_thrsh_i_pic_delta_qp_2 * i4_vbv_buffer_size);
5629                         break;
5630                     }
5631                     case IV_P_FRAME:
5632                     {
5633                         i8_thrsh_for_deltaQP_1 =
5634                             (LWORD64)(f_thrsh_p_pic_delta_qp_1 * i4_vbv_buffer_size);
5635                         i8_thrsh_for_deltaQP_2 =
5636                             (LWORD64)(f_thrsh_p_pic_delta_qp_2 * i4_vbv_buffer_size);
5637                         break;
5638                     }
5639                     case IV_B_FRAME:
5640                     {
5641                         if(ps_rc_lap_out->i4_rc_is_ref_pic)
5642                         {
5643                             i8_thrsh_for_deltaQP_1 =
5644                                 (LWORD64)(f_thrsh_br_pic_delta_qp_1 * i4_vbv_buffer_size);
5645                             i8_thrsh_for_deltaQP_2 =
5646                                 (LWORD64)(f_thrsh_br_pic_delta_qp_2 * i4_vbv_buffer_size);
5647                         }
5648                         else
5649                         {
5650                             /*as of now using the same thresholds as B reference, later may have to tune if required*/
5651                             i8_thrsh_for_deltaQP_1 =
5652                                 (LWORD64)(f_thrsh_bnr_pic_delta_qp_1 * i4_vbv_buffer_size);
5653                             i8_thrsh_for_deltaQP_2 =
5654                                 (LWORD64)(f_thrsh_bnr_pic_delta_qp_2 * i4_vbv_buffer_size);
5655                         }
5656                         break;
5657                     }
5658                     default:
5659                         break;
5660                     }
5661 
5662                     if((i4_currEbf + i8_grwEbf) > i8_thrsh_for_deltaQP_1)
5663                     {
5664                         /*For more than 2 QP chnage this means a larger scale issue and probably needs to be handled elsewhere ?*/
5665                         i4_deltaQP = 2; /* we dont intend to change QP by more than 2 */
5666                         i4_case = 5;
5667                     }
5668                     else if((i4_currEbf + i8_grwEbf) > i8_thrsh_for_deltaQP_2)
5669                     {
5670                         i4_deltaQP = 1;
5671                         i4_case = 6;
5672                     }
5673                 }
5674             }
5675             else
5676             {
5677                 i4_deltaQP = 2;
5678                 i4_case = 7;
5679             }
5680         }
5681     }
5682     return i4_deltaQP;
5683 }
5684 
5685 /*###############################################*/
5686 /******* END OF RC UTILS FUNCTIONS ***************/
5687 /*###############################################*/
5688 
5689 /*########################################################*/
5690 /******* START OF VBV COMPLIANCE FUNCTIONS ***************/
5691 /*#######################################################*/
5692 
5693 /*!
5694 ******************************************************************************
5695 * \if Function name : ihevce_vbv_compliance_frame_level_update
5696 *
5697 * \brief
5698 *    this function initializes the hrd buffer level to be used for vbv compliance testing using the parameters feeded in VUI parameters
5699 *
5700 * \param[in] *pv_ctxt -> rc context
5701 *           i4_bits_generated -> bits generated from entropy
5702 *           i4_resolution_id -> info needed for log Dump
5703 *           i4_appln_bitrate_inst -> info needed for log Dump
5704 *           u4_cur_cpb_removal_delay_minus1 -> cbp removal delay of present frame
5705 * \return
5706 *
5707 * \author
5708 *  Ittiam
5709 *
5710 *****************************************************************************
5711 */
5712 
ihevce_vbv_compliance_frame_level_update(void * pv_rc_ctxt,WORD32 i4_bits_generated,WORD32 i4_resolution_id,WORD32 i4_appln_bitrate_inst,UWORD32 u4_cur_cpb_removal_delay_minus1)5713 void ihevce_vbv_compliance_frame_level_update(
5714     void *pv_rc_ctxt,
5715     WORD32 i4_bits_generated,
5716     WORD32 i4_resolution_id,
5717     WORD32 i4_appln_bitrate_inst,
5718     UWORD32 u4_cur_cpb_removal_delay_minus1)
5719 {
5720     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
5721     float f_max_vbv_buff_size = (float)ps_rc_ctxt->s_vbv_compliance.f_buffer_size;
5722     WORD32 i4_cbp_removal_delay_diff = 1;
5723 
5724     if((ps_rc_ctxt->s_vbv_compliance.u4_prev_cpb_removal_delay_minus1 > 0) &&
5725        (u4_cur_cpb_removal_delay_minus1 >
5726         ps_rc_ctxt->s_vbv_compliance.u4_prev_cpb_removal_delay_minus1))
5727         i4_cbp_removal_delay_diff =
5728             (u4_cur_cpb_removal_delay_minus1 -
5729              ps_rc_ctxt->s_vbv_compliance.u4_prev_cpb_removal_delay_minus1);
5730 
5731     ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level =
5732         ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level - (float)i4_bits_generated +
5733         (i4_cbp_removal_delay_diff * ps_rc_ctxt->s_vbv_compliance.f_drain_rate);
5734 
5735     ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip =
5736         ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level;
5737 
5738     if(ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level < 0)
5739     {
5740         ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level = 0;
5741     }
5742 
5743     if(ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level >
5744        ps_rc_ctxt->s_vbv_compliance.f_buffer_size)
5745     {
5746         ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level =
5747             ps_rc_ctxt->s_vbv_compliance.f_buffer_size;
5748         ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip -=
5749             ps_rc_ctxt->s_vbv_compliance.f_buffer_size;
5750     }
5751     else if(ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip > 0)
5752     {
5753         ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip = 0;
5754     }
5755 
5756     if(ps_rc_ctxt->e_rate_control_type == VBR_STREAMING)
5757     {
5758         if(ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip > 0)
5759             ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip = 0;
5760     }
5761     ps_rc_ctxt->s_vbv_compliance.u4_prev_cpb_removal_delay_minus1 = u4_cur_cpb_removal_delay_minus1;
5762 }
5763 
5764 /*!
5765 ******************************************************************************
5766 * \if Function name : ihevce_vbv_complaince_init_level
5767 *
5768 * \brief
5769 *    this function initializes the hrd buffer level to be used for vbv compliance testing using the parameters feeded in VUI parameters
5770 *
5771 * \param[in] *pv_ctxt -> rc context
5772 *            *ps_vui      -> VUI parameters
5773 * \return
5774 *
5775 * \author
5776 *  Ittiam
5777 *
5778 *****************************************************************************
5779 */
5780 
ihevce_vbv_complaince_init_level(void * pv_ctxt,vui_t * ps_vui)5781 void ihevce_vbv_complaince_init_level(void *pv_ctxt, vui_t *ps_vui)
5782 {
5783     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
5784 
5785     ps_rc_ctxt->s_vbv_compliance.f_frame_rate =
5786         (float)((float)ps_vui->u4_vui_time_scale / ps_vui->u4_vui_num_units_in_tick);  //rc_get_frame_rate(ps_rc_ctxt->rc_hdl);
5787 
5788     if(1 == ps_vui->s_vui_hrd_parameters.u1_sub_pic_cpb_params_present_flag)
5789     {
5790         ASSERT(1 == ps_vui->s_vui_hrd_parameters.u1_sub_pic_cpb_params_present_flag);
5791 
5792         ps_rc_ctxt->s_vbv_compliance.f_bit_rate = (float)((
5793             (ps_vui->s_vui_hrd_parameters.as_sub_layer_hrd_params[0].au4_bit_rate_du_value_minus1[0] +
5794              1)
5795             << (6 + ps_vui->s_vui_hrd_parameters
5796                         .u4_bit_rate_scale)));  //rc_get_bit_rate(ps_rc_ctxt->rc_hdl);
5797 
5798         ps_rc_ctxt->s_vbv_compliance.f_buffer_size = (float)((
5799             (ps_vui->s_vui_hrd_parameters.as_sub_layer_hrd_params[0].au4_cpb_size_du_value_minus1[0] +
5800              1)
5801             << (4 + ps_vui->s_vui_hrd_parameters
5802                         .u4_cpb_size_du_scale)));  //ps_rc_ctxt->u4_max_vbv_buff_size;
5803     }
5804     else
5805     {
5806         ps_rc_ctxt->s_vbv_compliance.f_bit_rate = (float)((
5807             (ps_vui->s_vui_hrd_parameters.as_sub_layer_hrd_params[0].au4_bit_rate_value_minus1[0] +
5808              1)
5809             << (6 + ps_vui->s_vui_hrd_parameters
5810                         .u4_bit_rate_scale)));  //rc_get_bit_rate(ps_rc_ctxt->rc_hdl);
5811 
5812         ps_rc_ctxt->s_vbv_compliance.f_buffer_size = (float)((
5813             (ps_vui->s_vui_hrd_parameters.as_sub_layer_hrd_params[0].au4_cpb_size_value_minus1[0] +
5814              1)
5815             << (4 + ps_vui->s_vui_hrd_parameters
5816                         .u4_cpb_size_scale)));  //ps_rc_ctxt->u4_max_vbv_buff_size;
5817     }
5818     ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level =
5819         (float)ps_rc_ctxt->s_vbv_compliance.f_buffer_size;  //ps_rc_ctxt->u4_max_vbv_buff_size;
5820 
5821     ps_rc_ctxt->s_vbv_compliance.f_drain_rate =
5822         ((ps_rc_ctxt->s_vbv_compliance.f_bit_rate) / ps_rc_ctxt->s_vbv_compliance.f_frame_rate);
5823 
5824     ps_rc_ctxt->s_vbv_compliance.u4_prev_cpb_removal_delay_minus1 = 0;
5825 }
5826 
5827 /*########################################################*/
5828 /******* END OF VBV COMPLIANCE FUNCTIONS *****************/
5829 /*#######################################################*/
5830 
5831 /*################################################################*/
5832 /******* START OF DYN CHANGE iN BITRATE FUNCTIONS *****************/
5833 /*################################################################*/
5834 /*!
5835 ******************************************************************************
5836 * \if Function name : change_bitrate_vbv_complaince
5837 *
5838 * \brief
5839 *    this function updates the new bitrate and re calculates the drain rate
5840 *
5841 * \param[in] *pv_ctxt -> rc context
5842 * \return
5843 *
5844 * \author
5845 *  Ittiam
5846 *
5847 *****************************************************************************
5848 */
change_bitrate_vbv_complaince(void * pv_ctxt,LWORD64 i8_new_bitrate,LWORD64 i8_buffer_size)5849 void change_bitrate_vbv_complaince(void *pv_ctxt, LWORD64 i8_new_bitrate, LWORD64 i8_buffer_size)
5850 {
5851     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
5852     ps_rc_ctxt->s_vbv_compliance.f_buffer_size = (float)i8_buffer_size;
5853     ps_rc_ctxt->s_vbv_compliance.f_bit_rate = (float)i8_new_bitrate;
5854     if(ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level > i8_buffer_size)
5855         ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level = (float)i8_buffer_size;
5856     ps_rc_ctxt->s_vbv_compliance.f_drain_rate =
5857         ps_rc_ctxt->s_vbv_compliance.f_bit_rate / ps_rc_ctxt->s_vbv_compliance.f_frame_rate;
5858 }
5859 /*!
5860 ******************************************************************************
5861 * \if Function name : ihevce_rc_register_dyn_change_bitrate
5862 *
5863 * \brief
5864 *    this function registers call to change bitrate dynamically.
5865 *
5866 * \param[in] *pv_ctxt -> rc context
5867 *
5868 * \return
5869 *
5870 * \author
5871 *  Ittiam
5872 *
5873 *****************************************************************************
5874 */
5875 
ihevce_rc_register_dyn_change_bitrate(void * pv_ctxt,LWORD64 i8_new_bitrate,LWORD64 i8_new_peak_bitrate)5876 void ihevce_rc_register_dyn_change_bitrate(
5877     void *pv_ctxt, LWORD64 i8_new_bitrate, LWORD64 i8_new_peak_bitrate)
5878 {
5879     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
5880     ps_rc_ctxt->i8_new_bitrate = i8_new_bitrate;
5881     ps_rc_ctxt->i8_new_peak_bitrate = i8_new_peak_bitrate;
5882     ps_rc_ctxt->i4_bitrate_changed = 1;
5883     ASSERT(ps_rc_ctxt->i8_new_bitrate > 0);
5884     ASSERT(ps_rc_ctxt->i8_new_peak_bitrate > 0);
5885 }
5886 
5887 /*!
5888 ******************************************************************************
5889 * \if Function name : ihevce_rc_get_new_bitrate
5890 *
5891 * \brief
5892 *    get new bitrate
5893 *
5894 * \param[in] *pv_ctxt -> rc context
5895 *
5896 * \return
5897 *
5898 * \author
5899 *  Ittiam
5900 *
5901 *****************************************************************************
5902 */
ihevce_rc_get_new_bitrate(void * pv_ctxt)5903 LWORD64 ihevce_rc_get_new_bitrate(void *pv_ctxt)
5904 {
5905     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
5906     return ps_rc_ctxt->i8_new_bitrate;
5907 }
5908 /*!
5909 ******************************************************************************
5910 * \if Function name : ihevce_rc_get_new_peak_bitrate
5911 *
5912 * \brief
5913 *    get new peak rate
5914 *
5915 * \param[in] *pv_ctxt -> rc context
5916 *
5917 * \return
5918 *
5919 * \author
5920 *  Ittiam
5921 *
5922 *****************************************************************************
5923 */
ihevce_rc_get_new_peak_bitrate(void * pv_ctxt)5924 LWORD64 ihevce_rc_get_new_peak_bitrate(void *pv_ctxt)
5925 {
5926     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
5927     return ps_rc_ctxt->i8_new_peak_bitrate;
5928 }
5929 
5930 /*!
5931 ******************************************************************************
5932 * \if Function name : ihevce_rc_change_avg_bitrate
5933 *
5934 * \brief
5935 *    change average bitrate configured based on new bitrate
5936 *
5937 * \param[in] *pv_ctxt -> rc context
5938 *
5939 * \return
5940 *
5941 * \author
5942 *  Ittiam
5943 *
5944 *****************************************************************************
5945 */
ihevce_rc_change_avg_bitrate(void * pv_ctxt)5946 LWORD64 ihevce_rc_change_avg_bitrate(void *pv_ctxt)
5947 {
5948     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
5949     LWORD64 vbv_buffer_level_b4_change;
5950 
5951     ASSERT(ps_rc_ctxt->i8_new_bitrate != -1);
5952     ASSERT(ps_rc_ctxt->i8_new_peak_bitrate != -1);
5953     /*Get the VBV buffer level just before forcing bitrate change*/
5954     vbv_buffer_level_b4_change = (LWORD64)rc_get_ebf(ps_rc_ctxt->rc_hdl);
5955 
5956     change_avg_bit_rate(
5957         ps_rc_ctxt->rc_hdl,
5958         (UWORD32)ps_rc_ctxt->i8_new_bitrate,
5959         (UWORD32)ps_rc_ctxt->i8_new_peak_bitrate);
5960     /*Once the request is serviced set new bitrate to -1*/
5961     ps_rc_ctxt->i8_new_bitrate = -1;
5962     ps_rc_ctxt->i8_new_peak_bitrate = -1;
5963     return vbv_buffer_level_b4_change;
5964 }
5965 
5966 /*##############################################################*/
5967 /******* END OF DYN CHNAGE iN BITRATE FUNCTIONS *****************/
5968 /*##############################################################*/
5969