• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
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         }
1859 
1860         i4_frame_qp = ihevce_get_cur_frame_qp(
1861             ps_rc_ctxt->i4_init_frame_qp_user,
1862             slice_type,
1863             ps_rc_lap_out->i4_rc_temporal_lyr_id,
1864             ps_rc_ctxt->i4_min_frame_qp,
1865             ps_rc_ctxt->i4_max_frame_qp,
1866             ps_rc_ctxt->ps_rc_quant_ctxt);
1867 
1868         return i4_frame_qp;
1869     }
1870     else
1871     {
1872         /*check scene type*/
1873         scene_type = ihevce_rc_lap_get_scene_type(ps_rc_lap_out);
1874 
1875         if(scene_type == SCENE_TYPE_SCENE_CUT)
1876         {
1877             i4_is_scd = 1;
1878             ps_rc_ctxt->i4_num_frms_from_reset = 0;
1879 #if USE_QP_OFFSET_POST_SCD
1880             ps_rc_ctxt->i4_use_qp_offset_pre_enc = 1;
1881 #else
1882             ps_rc_ctxt->i4_use_qp_offset_pre_enc = 0;
1883 #endif
1884         }
1885         ASSERT(
1886             ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_read_index].i4_is_qp_valid ==
1887                 1 ||
1888             ps_rc_lap_out->i4_rc_poc < 20);
1889 
1890         if(ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_read_index].i4_is_qp_valid ==
1891            1)
1892         {
1893             if(i4_is_scd || ps_rc_ctxt->i4_use_qp_offset_pre_enc)
1894             {
1895 #if 1  //The qp will be populated assuming the frame is I_PIC. Adjust according to current pic type
1896                 i4_frame_qp =
1897                     ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_read_index].i4_scd_qp;
1898                 if(rc_pic_type == P_PIC)
1899                     i4_frame_qp++;
1900                 else
1901                     i4_frame_qp = i4_frame_qp + ps_rc_lap_out->i4_rc_temporal_lyr_id;
1902 #endif
1903                 if(i4_use_offset_flag)
1904                 {
1905                     if(rc_pic_type > B2_PIC)
1906                         i4_frame_qp = ps_rc_ctxt->i4_L0_frame_qp + ai4_offsets[rc_pic_type - 4];
1907                     else
1908                         i4_frame_qp = ps_rc_ctxt->i4_L0_frame_qp + ai4_offsets[rc_pic_type];
1909                 }
1910             }
1911             else
1912             {
1913 #if DETERMINISTIC_RC
1914                 i4_frame_qp = ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_read_index]
1915                                   .ai4_quant[rc_pic_type];
1916 #else
1917                 /*read the latest qp updated by enc*/
1918                 i4_frame_qp =
1919                     ps_rc_ctxt
1920                         ->as_pre_enc_qp_queue
1921                             [(ps_rc_ctxt->i4_pre_enc_qp_write_index + MAX_PRE_ENC_RC_DELAY - 1) %
1922                              MAX_PRE_ENC_RC_DELAY]
1923                         .ai4_quant[rc_pic_type];
1924 #endif
1925             }
1926 
1927             ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_read_index].i4_is_qp_valid =
1928                 -1;
1929             /*once encoder starts reading from qp queue it should always read from qp queue*/
1930             //ps_rc_ctxt->i4_use_init_qp_for_pre_enc = 0;
1931         }
1932         else
1933         {
1934             i4_frame_qp = ps_rc_ctxt->ai4_init_pre_enc_qp[rc_pic_type];
1935         }
1936         {
1937             WORD32 i4_delay_l0_enc = ps_rc_ctxt->i4_pre_enc_rc_delay;
1938             ps_rc_ctxt->i4_pre_enc_qp_read_index =
1939                 (ps_rc_ctxt->i4_pre_enc_qp_read_index + 1) % i4_delay_l0_enc;
1940 
1941             if(ps_rc_ctxt->i4_num_frms_from_reset < i4_delay_l0_enc)
1942             {
1943                 ps_rc_ctxt->i4_num_frms_from_reset++;
1944                 if(ps_rc_ctxt->i4_num_frms_from_reset >= i4_delay_l0_enc)
1945                     ps_rc_ctxt->i4_use_qp_offset_pre_enc = 0;
1946             }
1947         }
1948 
1949         i4_frame_qp = CLIP3(i4_frame_qp, ps_rc_ctxt->i4_min_frame_qp, ps_rc_ctxt->i4_max_frame_qp);
1950         return i4_frame_qp;
1951     }
1952 }
1953 /**
1954 ******************************************************************************
1955 *
1956 *  @brief function to estimate L0 satd based on L1 satd. '
1957 *
1958 *
1959 *  @par   Description
1960 *
1961 *  @param[in]   pv_rc_ctxt
1962 *               void pointer to rc ctxt
1963 *  @param[in]   rc_lap_out_params_t *
1964 pointer to lap out structure
1965 *   @param[in]  i8_est_L0_satd_act
1966 *               estimated L0 satd/act based on L1 satd/act
1967 *  @return      void
1968 *
1969 ******************************************************************************
1970 */
ihevce_get_L0_satd_based_on_L1(LWORD64 i8_satd_by_act_L1,WORD32 i4_num_pixel,WORD32 i4_cur_q_scale)1971 LWORD64 ihevce_get_L0_satd_based_on_L1(
1972     LWORD64 i8_satd_by_act_L1, WORD32 i4_num_pixel, WORD32 i4_cur_q_scale)
1973 {
1974     LWORD64 est_L0_satd_by_act;
1975     float m, c;
1976     /** choose coeff based on resolution*/
1977     if(i4_num_pixel > 5184000)
1978     {
1979         m = (float)2.3911;
1980         c = (float)86329;
1981     }
1982     else if(i4_num_pixel > 1497600)
1983     {
1984         m = (float)2.7311;
1985         c = (float)-1218.9;
1986     }
1987     else if(i4_num_pixel > 633600)
1988     {
1989         m = (float)3.1454;
1990         c = (float)-5836.1;
1991     }
1992     else
1993     {
1994         m = (float)3.5311;
1995         c = (float)-2377.2;
1996     }
1997     /*due to qp difference between I and  P, For P pic for same */
1998     est_L0_satd_by_act = (LWORD64)(i8_satd_by_act_L1 / i4_cur_q_scale * m + c) * i4_cur_q_scale;
1999 
2000     {
2001         if(est_L0_satd_by_act < (i4_num_pixel >> 3))
2002             est_L0_satd_by_act = (i4_num_pixel >> 3);
2003     }
2004     return est_L0_satd_by_act;
2005 }
2006 /**
2007 ******************************************************************************
2008 *
2009 *  @name  ihevce_rc_register_L1_analysis_data
2010 *
2011 *  @par   Description
2012 *
2013 *  @param[in]   ps_rc_ctxt  - pointer to rc context
2014 *               ps_rc_lap_out
2015 *               i8_est_L0_satd_by_act
2016 *               i8_pre_intra_sad
2017 *               i8_l1_hme_sad
2018 *  @return      void
2019 *
2020 ******************************************************************************
2021 */
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)2022 void ihevce_rc_register_L1_analysis_data(
2023     void *pv_rc_ctxt,
2024     rc_lap_out_params_t *ps_rc_lap_out,
2025     LWORD64 i8_est_L0_satd_by_act,
2026     LWORD64 i8_pre_intra_sad,
2027     LWORD64 i8_l1_hme_sad)
2028 {
2029     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
2030     WORD32 i, data_available = 1;
2031     picture_type_e rc_pic_type = ihevce_rc_conv_pic_type(
2032         (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out->i4_rc_pic_type,
2033         ps_rc_ctxt->i4_field_pic,
2034         ps_rc_lap_out->i4_rc_temporal_lyr_id,
2035         ps_rc_lap_out->i4_is_bottom_field,
2036         ps_rc_ctxt->i4_top_field_first);
2037 
2038     //if( ps_rc_ctxt->u4_rc_scene_num_est_L0_intra_sad_available == ps_rc_lap_out->u4_rc_scene_num)
2039     {
2040         /*update current frame's data*/
2041         ps_rc_ctxt->ai8_prev_frame_est_L0_satd[rc_pic_type] = i8_est_L0_satd_by_act;
2042         ps_rc_ctxt->ai8_prev_frame_hme_sad[rc_pic_type] = i8_l1_hme_sad;
2043         ps_rc_ctxt->ai8_prev_frame_pre_intra_sad[rc_pic_type] = i8_pre_intra_sad;
2044     }
2045     /*check if data is available for all picture type*/
2046     if(!ps_rc_ctxt->i4_is_est_L0_intra_sad_available)
2047     {
2048         for(i = 0; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
2049         {
2050             data_available &= (ps_rc_ctxt->ai8_prev_frame_est_L0_satd[i] >= 0);
2051             if(ps_rc_ctxt->i4_field_pic == 1 && i != 0)
2052                 data_available &= (ps_rc_ctxt->ai8_prev_frame_est_L0_satd[i + FIELD_OFFSET] >= 0);
2053         }
2054         ps_rc_ctxt->i4_is_est_L0_intra_sad_available = data_available;
2055     }
2056 }
2057 
2058 /*#######################################################*/
2059 /******* END OF PRE-ENC QP QUERY FUNCTIONS **************/
2060 /*#####################################################*/
2061 
2062 /*##########################################################*/
2063 /******* START OF ENC THRD QP QUERY FUNCTIONS **************/
2064 /*########################################################*/
2065 
2066 /**
2067 ******************************************************************************
2068 *
2069 *  @brief function to get ihevce_rc_get_pic_quant
2070 *
2071 *  @par   Description
2072 *  @param[in]   i4_update_delay : The Delay in the update. This can happen for dist. case!
2073 *               All decision should consider this delay for updation!
2074 ******************************************************************************
2075 */
2076 
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)2077 WORD32 ihevce_rc_get_pic_quant(
2078     void *pv_ctxt,
2079     rc_lap_out_params_t *ps_rc_lap_out,
2080     IHEVCE_RC_CALL_TYPE call_type,
2081     WORD32 i4_enc_frm_id,
2082     WORD32 i4_update_delay,
2083     WORD32 *pi4_tot_bits_estimated)
2084 {
2085     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
2086     WORD32 i4_frame_qp, i4_frame_qp_q6, i4_hevc_frame_qp = -1, i4_deltaQP = 0;
2087     WORD32 i4_max_frame_bits = (1 << 30);
2088     rc_type_e e_rc_type = ps_rc_ctxt->e_rate_control_type;
2089     WORD32 slice_type, index, i4_num_frames_in_cur_gop, i4_cur_est_texture_bits;
2090     WORD32 temporal_layer_id = ps_rc_lap_out->i4_rc_temporal_lyr_id;
2091     IV_PICTURE_CODING_TYPE_T pic_type = (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out->i4_rc_pic_type;
2092     picture_type_e rc_pic_type = ihevce_rc_conv_pic_type(
2093         pic_type,
2094         ps_rc_ctxt->i4_field_pic,
2095         ps_rc_lap_out->i4_rc_temporal_lyr_id,
2096         ps_rc_lap_out->i4_is_bottom_field,
2097         ps_rc_ctxt->i4_top_field_first);
2098     float i_to_avg_bit_ratio;
2099     frame_info_t s_frame_info_temp;
2100     WORD32 i4_scene_num = ps_rc_lap_out->u4_rc_scene_num % MAX_SCENE_NUM;
2101     WORD32 i4_vbv_buf_max_bits;
2102     WORD32 i4_est_tex_bits;
2103     WORD32 i4_cur_est_header_bits, i4_fade_scene;
2104     WORD32 i4_model_available, i4_is_no_model_scd;
2105     WORD32 i4_estimate_to_calc_frm_error;
2106 
2107     /* The window for which your update is guaranteed */
2108     WORD32 updated_window = ps_rc_ctxt->i4_num_frame_in_lap_window - i4_update_delay;
2109 
2110     ps_rc_ctxt->i4_scene_num_latest = i4_scene_num;
2111 
2112     ps_rc_ctxt->s_rc_high_lvl_stat.i4_modelQP = INVALID_QP;
2113     ps_rc_ctxt->s_rc_high_lvl_stat.i4_finalQP = INVALID_QP;
2114     ps_rc_ctxt->s_rc_high_lvl_stat.i4_maxEbfQP = INVALID_QP;
2115 
2116     ps_rc_ctxt->i4_quality_preset = ps_rc_lap_out->i4_rc_quality_preset;
2117     ps_rc_ctxt->s_rc_high_lvl_stat.i4_finalQP = INVALID_QP;
2118 
2119     if(1 == ps_rc_ctxt->i4_bitrate_changed)
2120     {
2121         ps_rc_ctxt->i4_bitrate_changed = 0;
2122     }
2123     if(CONST_QP == e_rc_type)
2124     {
2125         switch(pic_type)
2126         {
2127         case IV_I_FRAME:
2128         case IV_IDR_FRAME:
2129         {
2130             slice_type = ISLICE;
2131             break;
2132         }
2133         case IV_P_FRAME:
2134         {
2135             slice_type = PSLICE;
2136             break;
2137         }
2138         case IV_B_FRAME:
2139         {
2140             slice_type = BSLICE;
2141             break;
2142         }
2143         }
2144 
2145         i4_frame_qp = ihevce_get_cur_frame_qp(
2146             ps_rc_ctxt->i4_init_frame_qp_user,
2147             slice_type,
2148             temporal_layer_id,
2149             ps_rc_ctxt->i4_min_frame_qp,
2150             ps_rc_ctxt->i4_max_frame_qp,
2151             ps_rc_ctxt->ps_rc_quant_ctxt);
2152         return i4_frame_qp;
2153     }
2154     else
2155     {
2156         WORD32 is_scd_ref_frame = 0, i4_num_scd_in_lap_window = 0, num_frames_b4_scd = 0,
2157                scene_type = 0, i;
2158         //ihevce_lap_output_params_t *ps_cur_rc_lap_out;
2159 
2160         if(ps_rc_ctxt->ai4_scene_num_last_pic[rc_pic_type] !=
2161            (WORD32)ps_rc_lap_out->u4_rc_scene_num)
2162         {
2163             rc_reset_pic_model(ps_rc_ctxt->rc_hdl, rc_pic_type);
2164             rc_reset_first_frame_coded_flag(ps_rc_ctxt->rc_hdl, rc_pic_type);
2165         }
2166         ps_rc_ctxt->ai4_scene_num_last_pic[rc_pic_type] = ps_rc_lap_out->u4_rc_scene_num;
2167 
2168         if(call_type == ENC_GET_QP)
2169         {
2170             i4_model_available = model_availability(ps_rc_ctxt->rc_hdl, rc_pic_type);
2171 
2172             ps_rc_lap_out->i8_est_text_bits = -1;
2173         }
2174 
2175         if((rc_pic_type == I_PIC) || (rc_pic_type == P_PIC) || (rc_pic_type == P1_PIC))
2176         {
2177             ps_rc_ctxt->i4_cur_scene_num = ps_rc_lap_out->u4_rc_scene_num;
2178         }
2179 
2180         {
2181             if(!(pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME))
2182             {
2183                 ps_rc_ctxt->ai8_cur_frame_coarse_ME_cost[i4_enc_frm_id] =
2184                     ps_rc_lap_out->i8_frame_acc_coarse_me_cost;
2185             }
2186             /*check if frame is scene cut*/
2187             /* If scd do not query the model. obtain qp from offline data model*/
2188             scene_type = ihevce_rc_lap_get_scene_type(ps_rc_lap_out);
2189 
2190             if(ps_rc_ctxt->ai4_scene_numbers[ps_rc_lap_out->u4_rc_scene_num] == 0 &&
2191                (scene_type != SCENE_TYPE_SCENE_CUT))
2192             {
2193                 scene_type = SCENE_TYPE_SCENE_CUT;
2194             }
2195 
2196             if(ps_rc_ctxt->ai4_scene_numbers[ps_rc_lap_out->u4_rc_scene_num] > 0 &&
2197                (scene_type == SCENE_TYPE_SCENE_CUT))
2198             {
2199                 scene_type = SCENE_TYPE_NORMAL;
2200             }
2201             if(scene_type == SCENE_TYPE_SCENE_CUT)
2202             {
2203                 if((ps_rc_lap_out->i4_rc_quality_preset == IHEVCE_QUALITY_P6) &&
2204                    (rc_pic_type > P_PIC))
2205                 {
2206                     is_scd_ref_frame = 0;
2207                 }
2208                 else
2209                 {
2210                     is_scd_ref_frame = 1;
2211                 }
2212             }
2213             else if(scene_type == SCENE_TYPE_PAUSE_TO_RESUME)
2214             {
2215                 /*pause to resume flag will only be set in layer 0 frames( I and P pic)*/
2216                 /*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*/
2217 
2218                 if(ps_rc_lap_out->i4_rc_quality_preset == IHEVCE_QUALITY_P6)
2219                 {
2220                     if(call_type == ENC_GET_QP && rc_pic_type == P_PIC)
2221                     {
2222                         ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] = 1;
2223                     }
2224                 }
2225                 else
2226                 {
2227                     if(call_type == ENC_GET_QP && rc_pic_type != I_PIC)
2228                     {
2229                         ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] = 1;
2230                     }
2231                 }
2232             }
2233 
2234             ps_rc_ctxt->ai4_is_cmplx_change_reset_model[i4_enc_frm_id] =
2235                 ps_rc_lap_out->i4_is_cmplx_change_reset_model;
2236             ps_rc_ctxt->ai4_is_cmplx_change_reset_bits[i4_enc_frm_id] =
2237                 ps_rc_lap_out->i4_is_cmplx_change_reset_bits;
2238 
2239             /*initialise the coeffs to 1 in case lap is not used */
2240             for(i = 0; i < MAX_PIC_TYPE; i++)
2241             {
2242                 ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][i][0] = 1.0;
2243                 ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][i][1] = 0.0;
2244                 ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][i][2] = 0.0;
2245             }
2246 
2247             /*treat even first frame as scd frame*/
2248             if(!ps_rc_ctxt->i4_is_first_frame_encoded)
2249             {
2250                 is_scd_ref_frame = 1;
2251             }
2252 
2253             /*special case SCD handling for Non-I pic*/
2254             if(!(pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME) && call_type == ENC_GET_QP)
2255             {
2256                 if(is_scd_ref_frame)
2257                 {
2258                     /*A non-I pic will only be marked as scene cut only if there is another SCD follows within another subgop*/
2259                     ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] = 1;
2260                 }
2261                 /*check if current sad is very different from previous SAD and */
2262                 else if(
2263                     !ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] &&
2264                     ps_rc_lap_out->i4_is_non_I_scd)
2265                 {
2266                     ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] = 1;
2267                     is_scd_ref_frame = 1;
2268                 }
2269             }
2270 
2271             if(call_type == PRE_ENC_GET_QP)
2272             {
2273                 /*Only I frames are considered as scd pic during pre-enc*/
2274                 is_scd_ref_frame &= (pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME);
2275             }
2276 
2277             /*special case SCD handling for I pic*/
2278             if((pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME) && !is_scd_ref_frame)
2279             {
2280                 /*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
2281                 happen during fade-in and fade-out where other picture types would have learnt. Reset is required only for I.*/
2282 
2283                 if(ps_rc_lap_out->i4_is_I_only_scd)
2284                 {
2285                     is_scd_ref_frame = 1;
2286                     ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id] = 1;
2287                 }
2288             }
2289             /*should be recalculated for every picture*/
2290             if((updated_window) > 0 && (call_type == ENC_GET_QP) && (ps_rc_ctxt->i4_rc_pass != 2))
2291             {
2292                 rc_lap_out_params_t *ps_cur_rc_lap_out;
2293 
2294                 UWORD32 u4_L1_based_lap_complexity_q7;
2295                 WORD32 i = 0, k = 0, i4_f_sim = 0, i4_h_sim = 0, i4_var_sum = 0,
2296                        i4_num_pic_metric_count = 0, i4_is_first_frm = 1,
2297                        i4_intra_frame_interval = 0;
2298                 LWORD64 i8_l1_analysis_lap_comp = 0;
2299                 LWORD64 nor_frm_hme_sad_q10;
2300                 picture_type_e curr_rc_pic_type;
2301                 WORD32 ai4_pic_dist[MAX_PIC_TYPE] = { 0 };
2302                 LWORD64 i8_sad_first_frame_pic_type[MAX_PIC_TYPE] = { 0 },
2303                         i8_total_sad_pic_type[MAX_PIC_TYPE] = { 0 };
2304                 LWORD64 i8_last_frame_pic_type[MAX_PIC_TYPE] = { 0 }, i8_esti_consum_bits = 0;
2305                 WORD32 i4_num_pic_type[MAX_PIC_TYPE] = { 0 }, i4_frames_in_lap_end = 0,
2306                        i4_first_frame_coded_flag, i4_gop_end_flag = 1, i4_num_frame_for_ebf = 0;
2307                 i4_first_frame_coded_flag = is_first_frame_coded(ps_rc_ctxt->rc_hdl);
2308 
2309                 /*Setting the next scene cut as well as pic distribution for the gop*/
2310 
2311                 ps_cur_rc_lap_out = (rc_lap_out_params_t *)ps_rc_lap_out;
2312                 i4_intra_frame_interval = rc_get_intra_frame_interval(ps_rc_ctxt->rc_hdl);
2313 
2314                 /*Set the rc sc i next*/
2315                 if(ps_cur_rc_lap_out != NULL)
2316                 {
2317                     WORD32 i4_count = 0;
2318                     do
2319                     {
2320                         if(((rc_lap_out_params_t *)ps_cur_rc_lap_out->ps_rc_lap_out_next_encode ==
2321                             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)))
2322                             break;
2323 
2324                         ps_cur_rc_lap_out =
2325                             (rc_lap_out_params_t *)ps_cur_rc_lap_out->ps_rc_lap_out_next_encode;
2326                         i4_count++;
2327 
2328                     } while((i4_count + 1) < updated_window);
2329 
2330                     rc_set_next_sc_i_in_rc_look_ahead(
2331                         ps_rc_ctxt->rc_hdl, ps_cur_rc_lap_out->i4_next_sc_i_in_rc_look_ahead);
2332                     rc_update_pic_distn_lap_to_rc(
2333                         ps_rc_ctxt->rc_hdl, ps_cur_rc_lap_out->ai4_num_pic_type);
2334 
2335                     ps_rc_ctxt->i4_next_sc_i_in_rc_look_ahead =
2336                         ps_cur_rc_lap_out->i4_next_sc_i_in_rc_look_ahead;
2337                 }
2338 
2339                 ps_cur_rc_lap_out = (rc_lap_out_params_t *)ps_rc_lap_out;
2340                 if(ps_cur_rc_lap_out != NULL)
2341                 {
2342                     /*initialise the coeffs to 1 in case lap is not used */
2343                     for(i = 0; i < MAX_PIC_TYPE; i++)
2344                     {
2345                         ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][i][0] = 0.0;
2346                         ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][i][1] = 0.0;
2347                         ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][i][2] = 0.0;
2348                     }
2349                     i = 0;
2350                     k = 0;
2351 
2352                     //ASSERT(ps_cur_rc_lap_out != NULL);
2353                     do
2354                     {
2355                         curr_rc_pic_type = ihevce_rc_conv_pic_type(
2356                             (IV_PICTURE_CODING_TYPE_T)ps_cur_rc_lap_out->i4_rc_pic_type,
2357                             ps_rc_ctxt->i4_field_pic,
2358                             ps_cur_rc_lap_out->i4_rc_temporal_lyr_id,
2359                             ps_cur_rc_lap_out->i4_is_bottom_field,
2360                             ps_rc_ctxt->i4_top_field_first);
2361                         if(ps_rc_ctxt->i4_is_first_frame_encoded || !i4_is_first_frm)
2362                         {
2363                             /*Ignore first frame Fsim as it is not valid for first frame*/
2364                             i4_f_sim += ps_cur_rc_lap_out->s_pic_metrics.i4_fsim;
2365                             i4_h_sim += ps_cur_rc_lap_out->s_pic_metrics.ai4_hsim[0];
2366                             i4_var_sum += (WORD32)ps_cur_rc_lap_out->s_pic_metrics.i8_8x8_var_lum;
2367                             i4_num_pic_metric_count++;
2368                             //DBG_PRINTF("\n fsim = %d i = %d",ps_cur_rc_lap_out->s_pic_metrics.i4_fsim,i);
2369                             //ASSERT(ps_cur_rc_lap_out->s_pic_metrics.i4_fsim <= 128);
2370                         }
2371 
2372                         /*accumulate complexity from LAP2*/
2373                         if(curr_rc_pic_type == I_PIC)
2374                         {
2375                             i8_l1_analysis_lap_comp +=
2376                                 (LWORD64)(1.17 * ps_cur_rc_lap_out->i8_raw_pre_intra_sad);
2377                         }
2378                         else
2379                         {
2380                             if(curr_rc_pic_type <= B2_PIC)
2381                                 i8_l1_analysis_lap_comp += (LWORD64)(
2382                                     (float)ps_cur_rc_lap_out->i8_raw_l1_coarse_me_sad /
2383                                     pow(1.125f, curr_rc_pic_type));
2384                             else
2385                                 i8_l1_analysis_lap_comp += (LWORD64)(
2386                                     (float)ps_cur_rc_lap_out->i8_raw_l1_coarse_me_sad /
2387                                     pow(1.125f, curr_rc_pic_type - B2_PIC));
2388                         }
2389                         i++;
2390                         i4_is_first_frm = 0;
2391 
2392                         /*CAll the function for predictting the ebf and stuffing condition check*/
2393                         /*rd model pass lapout l1 pass ebf return estimated ebf and signal*/
2394 
2395                         {
2396                             if(i4_first_frame_coded_flag && (i4_gop_end_flag != 0))
2397                             {
2398                                 if(curr_rc_pic_type == 0)
2399                                     i4_gop_end_flag = 0;
2400 
2401                                 if(i4_gop_end_flag)
2402                                 {
2403                                     WORD32 prev_frm_cl_sad =
2404                                         rc_get_prev_frame_sad(ps_rc_ctxt->rc_hdl, curr_rc_pic_type);
2405                                     WORD32 cur_frm_est_cl_sad = (WORD32)(
2406                                         (ps_cur_rc_lap_out->i8_frame_acc_coarse_me_cost *
2407                                          prev_frm_cl_sad) /
2408                                         ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[curr_rc_pic_type]);
2409                                     i8_esti_consum_bits += bit_alloc_get_estimated_bits_for_pic(
2410                                         ps_rc_ctxt->rc_hdl,
2411                                         cur_frm_est_cl_sad,
2412                                         prev_frm_cl_sad,
2413                                         curr_rc_pic_type);
2414                                     i4_num_frame_for_ebf++;
2415                                 }
2416                             }
2417                         }
2418                         ps_cur_rc_lap_out =
2419                             (rc_lap_out_params_t *)ps_cur_rc_lap_out->ps_rc_lap_out_next_encode;
2420                         /*The scene cut is lap window other than current frame is used to reduce bit alloc window for I pic*/
2421                         if(ps_cur_rc_lap_out != NULL &&
2422                            ps_cur_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_SCENE_CUT)
2423                         {
2424                             i4_num_scd_in_lap_window++;
2425                             if(i4_num_scd_in_lap_window == 1)
2426                             {
2427                                 /*Note how many frames are parsed before first scd is hit*/
2428                                 num_frames_b4_scd = i + 1;
2429                             }
2430                         }
2431 
2432                         if((ps_cur_rc_lap_out == NULL ||
2433                             (i >=
2434                              (updated_window -
2435                               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))))
2436                             break;
2437                         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)))
2438                         {
2439                             k++;
2440                             ps_cur_rc_lap_out =
2441                                 (rc_lap_out_params_t *)ps_cur_rc_lap_out->ps_rc_lap_out_next_encode;
2442                             if(ps_cur_rc_lap_out == NULL)
2443                                 break;
2444                             continue;
2445                         }
2446 
2447                     } while(1);
2448                     ;
2449                 }
2450                 /*For the first subgop we cant have underflow prevention logic
2451                 since once picture of each type is not encoded also happens for static contents thants high i_to avg_ratio */
2452                 if(i4_first_frame_coded_flag &&
2453                    (ps_rc_ctxt->ai_to_avg_bit_ratio[i4_enc_frm_id] > I_TO_REST_SLOW))
2454                 {
2455                     if(!(i4_num_frame_for_ebf < ps_rc_ctxt->i4_max_inter_frm_int))
2456                         rc_bit_alloc_detect_ebf_stuff_scenario(
2457                             ps_rc_ctxt->rc_hdl,
2458                             i4_num_frame_for_ebf,
2459                             i8_esti_consum_bits,
2460                             ps_rc_ctxt->i4_max_inter_frm_int);
2461                 }
2462 
2463                 k = 0;
2464 
2465                 i4_frames_in_lap_end = 0;
2466                 {
2467                     rc_lap_out_params_t *ps_cur_rc_lap_out1;
2468 
2469                     ps_cur_rc_lap_out1 = (rc_lap_out_params_t *)ps_rc_lap_out;
2470                     do
2471                     {
2472                         curr_rc_pic_type = ihevce_rc_conv_pic_type(
2473                             (IV_PICTURE_CODING_TYPE_T)ps_cur_rc_lap_out1->i4_rc_pic_type,
2474                             ps_rc_ctxt->i4_field_pic,
2475                             ps_cur_rc_lap_out1->i4_rc_temporal_lyr_id,
2476                             ps_cur_rc_lap_out1->i4_is_bottom_field,
2477                             ps_rc_ctxt->i4_top_field_first);
2478                         /*accumulate complexity from LAP2*/
2479 
2480                         if(curr_rc_pic_type == I_PIC)
2481                         {
2482                             i8_total_sad_pic_type[I_PIC] +=
2483                                 ps_cur_rc_lap_out1->i8_raw_pre_intra_sad;
2484                             i8_last_frame_pic_type[I_PIC] =
2485                                 ps_cur_rc_lap_out1->i8_raw_pre_intra_sad;
2486                         }
2487                         else
2488                         {
2489                             i8_total_sad_pic_type[curr_rc_pic_type] +=
2490                                 ps_cur_rc_lap_out1->i8_raw_l1_coarse_me_sad;
2491                             i8_last_frame_pic_type[curr_rc_pic_type] =
2492                                 ps_cur_rc_lap_out1->i8_raw_l1_coarse_me_sad;
2493                         }
2494                         if(i4_num_pic_type[curr_rc_pic_type] == 0)
2495                         {
2496                             if(curr_rc_pic_type == I_PIC)
2497                             {
2498                                 i8_sad_first_frame_pic_type[I_PIC] =
2499                                     ps_cur_rc_lap_out1->i8_raw_pre_intra_sad;
2500                             }
2501                             else
2502                             {
2503                                 i8_sad_first_frame_pic_type[curr_rc_pic_type] =
2504                                     ps_cur_rc_lap_out1->i8_raw_l1_coarse_me_sad;
2505                             }
2506                         }
2507                         i4_num_pic_type[curr_rc_pic_type]++;
2508 
2509                         i4_frames_in_lap_end++;
2510 
2511                         ps_cur_rc_lap_out1 =
2512                             (rc_lap_out_params_t *)ps_cur_rc_lap_out1->ps_rc_lap_out_next_encode;
2513                         if((ps_cur_rc_lap_out1 == NULL ||
2514                             (i4_frames_in_lap_end >=
2515                              (updated_window -
2516                               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))))
2517                         {
2518                             break;
2519                         }
2520                         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))))
2521                         {
2522                             k++;
2523                             ps_cur_rc_lap_out1 = (rc_lap_out_params_t *)
2524                                                      ps_cur_rc_lap_out1->ps_rc_lap_out_next_encode;
2525                             if(ps_cur_rc_lap_out1 == NULL)
2526                                 break;
2527                             continue;
2528                         }
2529 
2530                     } while(i4_frames_in_lap_end < (ps_rc_ctxt->i4_next_sc_i_in_rc_look_ahead - k));
2531                 }
2532 
2533                 /*get picture type distribution in LAP*/
2534                 rc_get_pic_distribution(ps_rc_ctxt->rc_hdl, &ai4_pic_dist[0]);
2535 
2536                 {
2537                     float f_prev_comp;
2538                     WORD32 j;
2539                     float af_sum_weigh[MAX_PIC_TYPE], af_nume_weight[MAX_PIC_TYPE];
2540                     float af_average_sad_pic_type[MAX_PIC_TYPE] = { 0 };
2541                     for(j = 0; j < MAX_PIC_TYPE; j++)
2542                     {
2543                         if(i4_num_pic_type[j] > 0)
2544                         {
2545                             af_average_sad_pic_type[j] =
2546                                 (float)i8_total_sad_pic_type[j] / i4_num_pic_type[j];
2547                         }
2548 
2549                         f_prev_comp = 1.;
2550 
2551                         i4_num_pic_type[j] = (i4_num_pic_type[j] > ai4_pic_dist[j])
2552                                                  ? ai4_pic_dist[j]
2553                                                  : i4_num_pic_type[j];
2554 
2555                         af_sum_weigh[j] = (float)i4_num_pic_type[j];
2556                         af_nume_weight[j] = 1.0;
2557 
2558                         if(i4_num_pic_type[j] > 1 && (af_average_sad_pic_type[j] > 0))
2559                         {
2560                             af_nume_weight[j] =
2561                                 (float)i8_sad_first_frame_pic_type[j] / af_average_sad_pic_type[j];
2562 
2563                             f_prev_comp =
2564                                 (float)i8_last_frame_pic_type[j] / af_average_sad_pic_type[j];
2565                         }
2566                         //if(rc_pic_type != I_PIC)
2567                         {
2568                             af_sum_weigh[j] += f_prev_comp * (ai4_pic_dist[j] - i4_num_pic_type[j]);
2569                         }
2570                         ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][j][0] = af_nume_weight[j];
2571                         ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][j][1] = af_sum_weigh[j];
2572                         ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][j][2] = af_average_sad_pic_type[j];
2573 
2574                         /*Disabling steady state complexity based bit movement*/
2575                         /*Enable it in CBR and not in VBR since VBR already has complexity based bit movement*/
2576 
2577                         if(0) /*i4_frames_in_lap_end < (updated_window) || ps_rc_ctxt->e_rate_control_type == VBR_STREAMING)*/
2578                         {
2579                             ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][j][0] = 1.0;
2580                             ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][j][1] =
2581                                 0;  //(float)ai4_pic_dist[j];
2582                         }
2583                     }
2584                     memmove(
2585                         ps_rc_lap_out->ps_frame_info->af_sum_weigh,
2586                         ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id],
2587                         sizeof(float) * MAX_PIC_TYPE * 3);
2588                 }
2589 
2590                 if(i4_num_pic_metric_count > 0)
2591                 {
2592                     i4_f_sim = i4_f_sim / i4_num_pic_metric_count;
2593                     i4_h_sim = i4_h_sim / i4_num_pic_metric_count;
2594                     i4_var_sum = i4_var_sum / i4_num_pic_metric_count;
2595                 }
2596                 else
2597                 {
2598                     i4_f_sim = MODERATE_FSIM_VALUE;
2599                     i4_h_sim = MODERATE_FSIM_VALUE;
2600                 }
2601 
2602                 if(i > 0)
2603                 {
2604                     float lap_L1_comp =
2605                         (float)i8_l1_analysis_lap_comp /
2606                         (i * ps_rc_ctxt->i4_frame_height *
2607                          ps_rc_ctxt->i4_frame_width);  //per frame per pixel complexity
2608 
2609                     lap_L1_comp = rc_get_offline_normalized_complexity(
2610                         ps_rc_ctxt->u4_intra_frame_interval,
2611                         ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width,
2612                         lap_L1_comp,
2613                         ps_rc_ctxt->i4_rc_pass);
2614 
2615                     u4_L1_based_lap_complexity_q7 = (WORD32)((lap_L1_comp * (1 << 7)) + .05f);
2616                 }
2617                 else
2618                 {
2619                     u4_L1_based_lap_complexity_q7 = 25;
2620                 }
2621                 ps_rc_ctxt->ai4_lap_complexity_q7[i4_enc_frm_id] =
2622                     (WORD32)u4_L1_based_lap_complexity_q7;
2623                 /*clip f_sim to 0.3 for better stability*/
2624                 if(i4_f_sim < 38)
2625                     i4_f_sim = 128 - MAX_LAP_COMPLEXITY_Q7;
2626                 ps_rc_ctxt->ai4_lap_f_sim[i4_enc_frm_id] = i4_f_sim;
2627 
2628                 /*calculate normalized per pixel sad*/
2629                 nor_frm_hme_sad_q10 = (ps_rc_lap_out->i8_frame_acc_coarse_me_cost << 10) /
2630                                       (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width);
2631                 /*if(rc_pic_type == P_PIC)
2632                 DBG_PRINTF("\n P frm hme sad = %f  ",((float)nor_frm_hme_sad_q10/ (1 << 10)));  */
2633                 rc_put_temp_comp_lap(
2634                     ps_rc_ctxt->rc_hdl, i4_f_sim, nor_frm_hme_sad_q10, rc_pic_type);
2635 
2636                 rc_set_num_scd_in_lap_window(
2637                     ps_rc_ctxt->rc_hdl, i4_num_scd_in_lap_window, num_frames_b4_scd);
2638 
2639                 if(rc_pic_type == I_PIC && updated_window > (ps_rc_ctxt->i4_max_inter_frm_int << 1))
2640                 {
2641                     float i_to_avg_bit_ratio = ihevce_get_i_to_avg_ratio(
2642                         (void *)ps_rc_ctxt,
2643                         ps_rc_lap_out,
2644                         1,
2645                         1,
2646                         1,
2647                         ps_rc_lap_out->ai4_offsets,
2648                         i4_update_delay);
2649                     i_to_avg_bit_ratio = i_to_avg_bit_ratio * 1;
2650                 }
2651 
2652                 /* accumulation of the hme sad over next sub gop to find the temporal comlexity of the sub GOP*/
2653                 if((rc_pic_type == I_PIC) || (rc_pic_type == P_PIC))
2654                 {
2655                     ihevce_compute_temporal_complexity_reset_Kp_Kb(
2656                         ps_rc_lap_out, (void *)ps_rc_ctxt, 1);
2657                 }
2658 
2659                 if(i4_var_sum > MAX_LAP_VAR)
2660                 {
2661                     i4_var_sum = MAX_LAP_VAR;
2662                 }
2663 
2664                 {
2665                     /*Filling for dumping data */
2666 
2667                     ps_rc_ctxt->ai4_num_scd_in_lap_window[i4_enc_frm_id] = i4_num_scd_in_lap_window;
2668                     ps_rc_ctxt->ai4_num_frames_b4_scd[i4_enc_frm_id] = num_frames_b4_scd;
2669                 }
2670             }
2671         }
2672 
2673         if((ps_rc_lap_out->i4_rc_quality_preset == IHEVCE_QUALITY_P6) && (rc_pic_type > P_PIC))
2674         {
2675             ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] = 0;
2676             is_scd_ref_frame = 0;
2677         }
2678         i4_fade_scene = 0;
2679         /*Scene type fade is marked only for P pics which are in fade regions*/
2680         if((ps_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_FADE_IN ||
2681             ps_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_FADE_OUT) &&
2682            (ps_rc_lap_out->i4_rc_temporal_lyr_id == 0))
2683         {
2684             is_scd_ref_frame = 1;
2685             i4_fade_scene = 1;
2686         }
2687 
2688         if((!(is_scd_ref_frame || ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id])) &&
2689            (((is_first_frame_coded(ps_rc_ctxt->rc_hdl)) && (pic_type == IV_I_FRAME)) ||
2690             (pic_type != IV_I_FRAME)))
2691         {
2692             WORD32 i4_is_first_frame_coded = is_first_frame_coded(ps_rc_ctxt->rc_hdl);
2693             i4_is_no_model_scd = 0;
2694             if(call_type == ENC_GET_QP)
2695             {
2696                 if(((0 == i4_model_available) || (!i4_is_first_frame_coded)))
2697                 {
2698                     /*No scene change but model not available*/
2699                     i4_is_no_model_scd = 1;
2700                 }
2701             }
2702         }
2703         else
2704         {
2705             /*actual scene changes*/
2706             i4_is_no_model_scd = 2;
2707         }
2708         /** Pre-enc thread as of now SCD handling is not present */
2709         if(!i4_is_no_model_scd)
2710         {
2711             WORD32 i4_is_first_frame_coded, i4_prev_I_frm_sad, i4_cur_I_frm_sad;
2712             /*Once first frame has been encoded use prev frame intra satd and cur frame satd to alter est intra sad for cur frame*/
2713             i4_is_first_frame_coded = is_first_frame_coded(ps_rc_ctxt->rc_hdl);
2714 
2715             /*prev I frame sad i changes only in enc stage. For pre enc cur and prev will be same*/
2716             if(ps_rc_ctxt->i8_prev_i_frm_cost > 0)
2717             {
2718                 if(i4_is_first_frame_coded && (pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME))
2719                 {
2720                     i4_prev_I_frm_sad = rc_get_prev_frame_intra_sad(ps_rc_ctxt->rc_hdl);
2721                     i4_cur_I_frm_sad = (WORD32)(
2722                         (ps_rc_ctxt->ai8_cur_frm_intra_cost[i4_enc_frm_id] * i4_prev_I_frm_sad) /
2723                         ps_rc_ctxt->i8_prev_i_frm_cost);
2724                     rc_update_prev_frame_intra_sad(ps_rc_ctxt->rc_hdl, i4_cur_I_frm_sad);
2725                 }
2726             }
2727             /*scale previous frame closed loop SAD with current frame HME SAD to be considered as current frame SAD*/
2728             if(i4_is_first_frame_coded && !(pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME) &&
2729                call_type == ENC_GET_QP)
2730             {
2731                 if(ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[rc_pic_type] > 0)
2732                 {
2733                     WORD32 prev_frm_cl_sad = rc_get_prev_frame_sad(ps_rc_ctxt->rc_hdl, rc_pic_type);
2734                     WORD32 cur_frm_est_cl_sad = (WORD32)(
2735                         (ps_rc_ctxt->ai8_cur_frame_coarse_ME_cost[i4_enc_frm_id] *
2736                          prev_frm_cl_sad) /
2737                         ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[rc_pic_type]);
2738                     rc_update_prev_frame_sad(ps_rc_ctxt->rc_hdl, cur_frm_est_cl_sad, rc_pic_type);
2739                 }
2740             }
2741 
2742             if(rc_pic_type == I_PIC && updated_window > (ps_rc_ctxt->i4_max_inter_frm_int << 1))
2743             {
2744                 ps_rc_ctxt->ai_to_avg_bit_ratio[i4_enc_frm_id] = ihevce_get_i_to_avg_ratio(
2745                     (void *)ps_rc_ctxt,
2746                     ps_rc_lap_out,
2747                     1,
2748                     0,
2749                     1,
2750                     ps_rc_lap_out->ai4_offsets,
2751                     i4_update_delay);
2752             }
2753 
2754             ps_rc_ctxt->s_rc_high_lvl_stat.i8_bits_from_finalQP = -1;
2755             i4_frame_qp_q6 = get_frame_level_qp(
2756                 ps_rc_ctxt->rc_hdl,
2757                 rc_pic_type,
2758                 i4_max_frame_bits,
2759                 &i4_cur_est_texture_bits,  //this value is returned by rc
2760                 ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id],
2761                 1,
2762                 ps_rc_ctxt->ai_to_avg_bit_ratio[i4_enc_frm_id],
2763                 ps_rc_lap_out->ps_frame_info,
2764                 ps_rc_lap_out->i4_complexity_bin,
2765                 i4_scene_num, /*no pause resume concept*/
2766                 pi4_tot_bits_estimated,
2767                 &ps_rc_lap_out->i4_is_model_valid,
2768                 &i4_vbv_buf_max_bits,
2769                 &i4_est_tex_bits,
2770                 &i4_cur_est_header_bits,
2771                 &ps_rc_ctxt->s_rc_high_lvl_stat.i4_maxEbfQP,
2772                 &ps_rc_ctxt->s_rc_high_lvl_stat.i4_modelQP,
2773                 &i4_estimate_to_calc_frm_error);
2774             ASSERT(*pi4_tot_bits_estimated != 0);
2775             /** 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
2776             low bitrate. Hence on the fly calculation is enabled*/
2777 
2778             i4_hevc_frame_qp =
2779                 ihevce_rc_get_scaled_hevce_qp_q6(i4_frame_qp_q6, ps_rc_ctxt->u1_bit_depth);
2780 
2781             if(1 == ps_rc_lap_out->i4_is_model_valid)
2782                 ps_rc_lap_out->i4_is_steady_state = 1;
2783             else
2784                 ps_rc_lap_out->i4_is_steady_state = 0;
2785 
2786             ps_rc_ctxt->s_rc_high_lvl_stat.i4_is_offline_model_used = 0;
2787             ps_rc_ctxt->i8_est_I_pic_header_bits = i4_cur_est_header_bits;
2788         }
2789         else
2790         {
2791             WORD32 i4_count = 0, i4_total_bits, i4_min_error_hevc_qp = 0;
2792             float f_percent_error = 0.0f, f_min_error = 10000.0f;
2793             WORD32 i4_current_bits_estimated = 0;
2794             float i4_i_to_rest_ratio_final;
2795             WORD32 i4_best_br_id = 0;
2796             float af_i_qs[2];
2797             LWORD64 ai8_i_tex_bits[2];
2798             WORD32 i4_ref_qscale = ihevce_rc_get_scaled_mpeg2_qp(
2799                 ps_rc_lap_out->i4_L0_qp, ps_rc_ctxt->ps_rc_quant_ctxt);
2800             WORD32 ai4_header_bits[2];
2801 
2802             ps_rc_lap_out->i4_is_steady_state = 0;
2803 
2804             if(ps_rc_lap_out->i4_L0_qp > 44)
2805                 ps_rc_lap_out->i4_L0_qp = 44;
2806             if(ps_rc_lap_out->i4_L0_qp < 7 - ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset)
2807                 ps_rc_lap_out->i4_L0_qp = 7 - ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset;
2808 
2809             ps_rc_lap_out->i4_L0_qp = ps_rc_lap_out->i4_L0_qp - 9;
2810             ps_rc_lap_out->i4_is_model_valid = 0;
2811             ps_rc_ctxt->s_rc_high_lvl_stat.i4_is_offline_model_used = 1;
2812             ps_rc_ctxt->s_rc_high_lvl_stat.i8_bits_from_finalQP = -1;
2813 
2814             ps_rc_ctxt->i4_normal_inter_pic = (i4_is_no_model_scd == 1);
2815             while(1)
2816             {
2817                 WORD32 i4_frame_qs_q3;
2818                 WORD32 i4_estimate_to_calc_frm_error_temp;
2819 
2820                 i_to_avg_bit_ratio = ihevce_get_i_to_avg_ratio(
2821                     (void *)ps_rc_ctxt,
2822                     ps_rc_lap_out,
2823                     1,
2824                     0,
2825                     1,
2826                     ps_rc_lap_out->ai4_offsets,
2827                     i4_update_delay);
2828 
2829                 ps_rc_ctxt->ai_to_avg_bit_ratio[i4_enc_frm_id] = i_to_avg_bit_ratio;
2830 
2831                 /** Use estimate of header bits from pre-enc*/
2832                 if(1 == i4_is_no_model_scd)
2833                 {
2834                     ps_rc_ctxt->i8_est_I_pic_header_bits =
2835                         get_est_hdr_bits(ps_rc_ctxt->rc_hdl, rc_pic_type);
2836                 }
2837                 else
2838                 {
2839                     WORD32 i4_curr_qscale = ihevce_rc_get_scaled_mpeg2_qp(
2840                         ps_rc_lap_out->i4_L0_qp, ps_rc_ctxt->ps_rc_quant_ctxt);
2841                     /*Assume that 30% of header bits are constant and remaining are dependent on Qp
2842                     and map them accordingly*/
2843                     ps_rc_ctxt->i8_est_I_pic_header_bits = (LWORD64)(
2844                         (.3 * ps_rc_lap_out->i8_est_I_pic_header_bits +
2845                          (1. - .3) * ps_rc_lap_out->i8_est_I_pic_header_bits * i4_ref_qscale) /
2846                         i4_curr_qscale);
2847                 }
2848 
2849                 /*get qp for scene cut frame based on offline data*/
2850                 index = ihevce_get_offline_index(
2851                     ps_rc_ctxt, ps_rc_lap_out->i4_num_pels_in_frame_considered);
2852 
2853                 /*Sub pic rC bits extraction */
2854                 i4_frame_qs_q3 = rc_get_qp_for_scd_frame(
2855                     ps_rc_ctxt->rc_hdl,
2856                     I_PIC,
2857                     ps_rc_lap_out->i8_frame_satd_act_accum,
2858                     ps_rc_lap_out->i4_num_pels_in_frame_considered,
2859                     (WORD32)ps_rc_ctxt->i8_est_I_pic_header_bits,
2860                     ps_rc_ctxt->ai4_lap_f_sim[i4_enc_frm_id],
2861                     (void *)&g_offline_i_model_coeff[index][0],
2862                     i_to_avg_bit_ratio,
2863                     1,
2864                     ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id],
2865                     ps_rc_lap_out->ps_frame_info,
2866                     ps_rc_ctxt->i4_rc_pass,
2867                     (rc_pic_type != I_PIC),
2868                     ((ps_rc_lap_out->i4_rc_temporal_lyr_id != ps_rc_ctxt->i4_max_temporal_lyr) ||
2869                      (!ps_rc_ctxt->i4_max_temporal_lyr)),
2870                     1,
2871                     &i4_total_bits,
2872                     &i4_current_bits_estimated,
2873                     ps_rc_lap_out->i4_use_offline_model_2pass,
2874                     ai8_i_tex_bits,
2875                     af_i_qs,
2876                     i4_best_br_id,
2877                     &i4_estimate_to_calc_frm_error_temp);
2878 
2879                 i4_hevc_frame_qp = ihevce_rc_get_scaled_hevc_qp_from_qs_q3(
2880                     i4_frame_qs_q3, ps_rc_ctxt->ps_rc_quant_ctxt);
2881 
2882                 /*Get corresponding q scale*/
2883                 i4_frame_qp =
2884                     ihevce_rc_get_scaled_mpeg2_qp(i4_hevc_frame_qp, ps_rc_ctxt->ps_rc_quant_ctxt);
2885 
2886                 if(i4_hevc_frame_qp > ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qp)
2887                     i4_hevc_frame_qp = ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qp;
2888 
2889                 {
2890                     WORD32 i4_init_qscale = ihevce_rc_get_scaled_mpeg2_qp(
2891                         ps_rc_lap_out->i4_L0_qp, ps_rc_ctxt->ps_rc_quant_ctxt);
2892                     f_percent_error = (float)(abs(i4_init_qscale - i4_frame_qp)) / i4_init_qscale;
2893                     if(f_percent_error < f_min_error)
2894                     {
2895                         f_min_error = f_percent_error;
2896                         i4_min_error_hevc_qp = i4_hevc_frame_qp;
2897                         i4_i_to_rest_ratio_final = i_to_avg_bit_ratio;
2898                         /*Get the bits estimated for least error*/
2899                         *pi4_tot_bits_estimated = i4_current_bits_estimated;
2900                         i4_estimate_to_calc_frm_error = i4_estimate_to_calc_frm_error_temp;
2901                     }
2902                     else
2903                     {}
2904                     ASSERT(*pi4_tot_bits_estimated != 0);
2905                 }
2906                 i4_count++;
2907                 if(/*(ps_rc_lap_out->i4_L0_qp == i4_hevc_frame_qp) ||*/ (i4_count > 17))
2908                     break;
2909                 ps_rc_lap_out->i4_L0_qp++;
2910             }
2911             ps_rc_lap_out->i4_L0_qp = i4_min_error_hevc_qp;
2912 
2913             i4_hevc_frame_qp = i4_min_error_hevc_qp;
2914             if(2 == i4_is_no_model_scd)
2915             {
2916                 /* SGI & Enc Loop Parallelism related changes*/
2917 
2918                 /*model reset not required if it is first frame*/
2919                 if(ps_rc_ctxt->i4_is_first_frame_encoded && !i4_fade_scene &&
2920                    !ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id] &&
2921                    !ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] &&
2922                    !ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] &&
2923                    !ps_rc_ctxt->ai4_is_cmplx_change_reset_model[i4_enc_frm_id])
2924                 {
2925                     ps_rc_ctxt->ai4_is_frame_scd[i4_enc_frm_id] = 1;
2926                     /*reset all pic type is first frame encoded flag*/
2927 
2928                     ASSERT(pic_type == IV_IDR_FRAME || pic_type == IV_I_FRAME);
2929                 }
2930                 else if(ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id])
2931                 {
2932                     rc_reset_first_frame_coded_flag(ps_rc_ctxt->rc_hdl, I_PIC);
2933                     ASSERT(rc_pic_type == I_PIC);
2934                     ASSERT(ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] == 0);
2935                 }
2936                 else if(
2937                     ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] ||
2938                     ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] ||
2939                     ps_rc_ctxt->ai4_is_cmplx_change_reset_model[i4_enc_frm_id] || i4_fade_scene)
2940                 {
2941                     /*Only when there are back to back scene cuts we need a non- Ipic will be marked as scene cut*/
2942                     /* Same path can also be followed during pause to resume detection to determine cur frame qp however handling during update is different*/
2943                     WORD32 i4_prev_qp, i, i4_new_qp_hevc_qp, I_hevc_qp, cur_hevc_qp;
2944 
2945                     /*both cannot be set at same time since lap cannot mark same frame as both scene cut and pause to resume flag*/
2946                     ASSERT(
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]) == 0);
2949 
2950                     I_hevc_qp = i4_hevc_frame_qp;
2951 
2952                     /*alter ai4_prev_pic_hevc_qp so that qp restriction ll not let even other pictures temporary scd are thrashed*/
2953                     //if(ps_rc_lap_out->i4_rc_temporal_lyr_id != ps_rc_ctxt->i4_max_temporal_lyr)
2954                     {
2955                         if(ps_rc_ctxt->i4_field_pic == 0)
2956                         {
2957                             for(i = 1; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
2958                             {
2959                                 i4_prev_qp = ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i];
2960                                 i4_new_qp_hevc_qp = I_hevc_qp + i;
2961                                 i4_new_qp_hevc_qp = ihevce_clip_min_max_qp(
2962                                     ps_rc_ctxt, i4_new_qp_hevc_qp, (picture_type_e)i, i - 1);
2963                                 if(i4_prev_qp < i4_new_qp_hevc_qp)
2964                                 {
2965                                     ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i] =
2966                                         i4_new_qp_hevc_qp;
2967                                 }
2968                             }
2969                         }
2970                         else
2971                         { /*field case*/
2972 
2973                             for(i = 1; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
2974                             {
2975                                 i4_prev_qp = ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i];
2976                                 i4_new_qp_hevc_qp = I_hevc_qp + i;
2977                                 i4_new_qp_hevc_qp = ihevce_clip_min_max_qp(
2978                                     ps_rc_ctxt, i4_new_qp_hevc_qp, (picture_type_e)i, i - 1);
2979                                 if(i4_prev_qp < i4_new_qp_hevc_qp)
2980                                 {
2981                                     ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i] =
2982                                         i4_new_qp_hevc_qp;
2983                                 }
2984 
2985                                 i4_prev_qp =
2986                                     ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i + FIELD_OFFSET];
2987                                 i4_new_qp_hevc_qp = I_hevc_qp + i;
2988                                 i4_new_qp_hevc_qp = ihevce_clip_min_max_qp(
2989                                     ps_rc_ctxt, i4_new_qp_hevc_qp, (picture_type_e)i, i - 1);
2990                                 if(i4_prev_qp < i4_new_qp_hevc_qp)
2991                                 {
2992                                     ps_rc_ctxt
2993                                         ->ai4_prev_pic_hevc_qp[i4_scene_num][i + FIELD_OFFSET] =
2994                                         i4_new_qp_hevc_qp;
2995                                 }
2996                             }
2997                         }
2998                     }
2999                     {
3000                         WORD32 i4_updated_qp = ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i];
3001                         WORD32 i4_scale;
3002 
3003                         if(I_hevc_qp == i4_updated_qp)
3004                             i4_scale = 16;
3005                         else if(I_hevc_qp == (i4_updated_qp - 1))
3006                             i4_scale = 14;
3007                         else if(I_hevc_qp == (i4_updated_qp - 2))
3008                             i4_scale = 12;
3009                         else
3010                             i4_scale = 10;
3011 
3012                         *pi4_tot_bits_estimated = (i4_scale * (*pi4_tot_bits_estimated)) >> 4;
3013                         i4_estimate_to_calc_frm_error =
3014                             (i4_scale * i4_estimate_to_calc_frm_error) >> 4;
3015                     }
3016                     if(call_type == ENC_GET_QP)
3017                     {
3018                         ps_rc_lap_out->i8_est_text_bits = *pi4_tot_bits_estimated;
3019                     }
3020                     ASSERT(*pi4_tot_bits_estimated != 0);
3021 
3022                     /*use previous frame qp of same pic type or SCD i frame qp with offset whichever is maximum*/
3023                     /*For field case adding of  grater than 4 results in the qp increasing greatly when compared to previous pics/fields*/
3024                     if(rc_pic_type <= FIELD_OFFSET)
3025                         cur_hevc_qp = I_hevc_qp + rc_pic_type;
3026                     else
3027                         cur_hevc_qp = I_hevc_qp + (rc_pic_type - FIELD_OFFSET);
3028 
3029                     i4_prev_qp = ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type];
3030 
3031                     if((cur_hevc_qp < i4_prev_qp) && (ps_rc_ctxt->i4_num_active_pic_type > 2) &&
3032                        (is_first_frame_coded(ps_rc_ctxt->rc_hdl)) && (!i4_fade_scene))
3033                     {
3034                         cur_hevc_qp = i4_prev_qp;
3035                     }
3036                     i4_frame_qp =
3037                         ihevce_rc_get_scaled_mpeg2_qp(cur_hevc_qp, ps_rc_ctxt->ps_rc_quant_ctxt);
3038                     i4_hevc_frame_qp = cur_hevc_qp;
3039                     //ps_rc_ctxt->i4_is_non_I_scd_pic = 0;
3040 
3041                     rc_reset_first_frame_coded_flag(ps_rc_ctxt->rc_hdl, rc_pic_type);
3042                 }
3043                 else
3044                 {}
3045             }
3046             if((1 == i4_is_no_model_scd) && (call_type == ENC_GET_QP))
3047             {
3048                 WORD32 i4_clip_QP;
3049                 i4_frame_qp_q6 =
3050                     clip_qp_based_on_prev_ref(ps_rc_ctxt->rc_hdl, rc_pic_type, 1, i4_scene_num);
3051                 i4_clip_QP =
3052                     ihevce_rc_get_scaled_hevce_qp_q6(i4_frame_qp_q6, ps_rc_ctxt->u1_bit_depth);
3053                 if(ps_rc_ctxt->i4_rc_pass != 2)
3054                 {
3055                     i4_hevc_frame_qp = i4_clip_QP;
3056                 }
3057                 if((rc_pic_type == P_PIC) || (rc_pic_type == P1_PIC))
3058                 {
3059                     *pi4_tot_bits_estimated = (*pi4_tot_bits_estimated * 11) >> 4; /* P picture*/
3060                     i4_estimate_to_calc_frm_error = (i4_estimate_to_calc_frm_error * 11) >> 4;
3061                 }
3062                 else if((rc_pic_type == B_PIC) || (rc_pic_type == BB_PIC))
3063                 {
3064                     *pi4_tot_bits_estimated = (*pi4_tot_bits_estimated * 9) >> 4; /* B layer 1*/
3065                     i4_estimate_to_calc_frm_error = (i4_estimate_to_calc_frm_error * 9) >> 4;
3066                 }
3067                 else if((rc_pic_type == B1_PIC) || (rc_pic_type == B11_PIC))
3068                 {
3069                     *pi4_tot_bits_estimated = (*pi4_tot_bits_estimated * 7) >> 4; /* B layer 2*/
3070                     i4_estimate_to_calc_frm_error = (i4_estimate_to_calc_frm_error * 7) >> 4;
3071                 }
3072                 else if((rc_pic_type == B2_PIC) || (rc_pic_type == B22_PIC))
3073                 {
3074                     *pi4_tot_bits_estimated = (*pi4_tot_bits_estimated * 5) >> 4; /* B layer 3*/
3075                     i4_estimate_to_calc_frm_error = (i4_estimate_to_calc_frm_error * 5) >> 4;
3076                 }
3077             }
3078             rc_add_est_tot(ps_rc_ctxt->rc_hdl, *pi4_tot_bits_estimated);
3079         }
3080 
3081         ASSERT(i4_hevc_frame_qp >= -ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset);
3082 
3083         /*constraint qp swing based on neighbour frames*/
3084         if(is_first_frame_coded(ps_rc_ctxt->rc_hdl))
3085         {
3086             if(ps_rc_ctxt->i4_field_pic == 0)
3087             {
3088                 /*In dissolve case the p frame comes before an I pic and ref b comes after then what
3089                 happens is b frame qp is restricted by the p frame qp so changed it to prev ref pic type*/
3090                 if(rc_pic_type != I_PIC && rc_pic_type != P_PIC)
3091                 {
3092                     if(ps_rc_lap_out->i4_rc_temporal_lyr_id == 1)
3093                     {
3094                         picture_type_e prev_ref_pic_type =
3095                             rc_getprev_ref_pic_type(ps_rc_ctxt->rc_hdl);
3096 
3097                         if(i4_hevc_frame_qp >
3098                            ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][prev_ref_pic_type] + 3)
3099                         {
3100                             if(ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][prev_ref_pic_type] >
3101                                0)
3102                                 i4_hevc_frame_qp =
3103                                     ps_rc_ctxt
3104                                         ->ai4_prev_pic_hevc_qp[i4_scene_num][prev_ref_pic_type] +
3105                                     3;
3106                         }
3107                     }
3108                     else if(
3109                         i4_hevc_frame_qp >
3110                         (ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type - 1] + 3))
3111                     {
3112                         /*allow max of +3 compared to previous frame*/
3113                         if(ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type - 1] > 0)
3114                             i4_hevc_frame_qp =
3115                                 ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type - 1] + 3;
3116                     }
3117                 }
3118 
3119                 if((rc_pic_type != I_PIC && rc_pic_type != P_PIC) &&
3120                    (i4_hevc_frame_qp <
3121                     ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type - 1]))
3122                 {
3123                     i4_hevc_frame_qp =
3124                         ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type - 1];
3125                 }
3126 
3127                 /** 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*/
3128                 if(temporal_layer_id == ps_rc_ctxt->i4_max_temporal_lyr &&
3129                    ps_rc_ctxt->i4_max_temporal_lyr > 1)
3130                 {
3131                     i4_hevc_frame_qp =
3132                         ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type - 1] + 1;
3133                 }
3134             }
3135             else /*for field case*/
3136             {
3137                 if(ps_rc_lap_out->i4_rc_temporal_lyr_id >= 1)
3138                 {
3139                     /*To make the comparison of qp with the top field's of previous layer tempor layer id matches with the pic type. */
3140                     if(i4_hevc_frame_qp >
3141                        ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num]
3142                                                        [ps_rc_lap_out->i4_rc_temporal_lyr_id] +
3143                            3)
3144                     {
3145                         /*allow max of +3 compared to previous frame*/
3146                         if(0 <
3147                            ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num]
3148                                                            [ps_rc_lap_out->i4_rc_temporal_lyr_id])
3149                             i4_hevc_frame_qp =
3150                                 ps_rc_ctxt
3151                                     ->ai4_prev_pic_hevc_qp[i4_scene_num]
3152                                                           [ps_rc_lap_out->i4_rc_temporal_lyr_id] +
3153                                 3;
3154                     }
3155                     if(i4_hevc_frame_qp <
3156                        ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num]
3157                                                        [ps_rc_lap_out->i4_rc_temporal_lyr_id])
3158                     {
3159                         i4_hevc_frame_qp =
3160                             ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num]
3161                                                             [ps_rc_lap_out->i4_rc_temporal_lyr_id];
3162                     }
3163 
3164                     /** 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*/
3165                     if(temporal_layer_id == ps_rc_ctxt->i4_max_temporal_lyr &&
3166                        ps_rc_ctxt->i4_max_temporal_lyr > 1)
3167                     {
3168                         i4_hevc_frame_qp =
3169                             ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num]
3170                                                             [ps_rc_lap_out->i4_rc_temporal_lyr_id] +
3171                             1;
3172                     }
3173                 }
3174                 /** At lower range qp swing for same pic type is also imposed to make sure
3175                     qp does not fall from 10 to 4 since they differ by only one q scale*/
3176             }
3177         }
3178 
3179         /**clip to min qp which is user configurable*/
3180         i4_hevc_frame_qp = ihevce_clip_min_max_qp(
3181             ps_rc_ctxt, i4_hevc_frame_qp, rc_pic_type, ps_rc_lap_out->i4_rc_temporal_lyr_id);
3182 
3183 #if 1  //FRAME_PARALLEL_LVL
3184         ps_rc_ctxt->i4_est_text_bits_ctr_get_qp++;  //ELP_RC
3185         ps_rc_ctxt->i4_est_text_bits_ctr_get_qp =
3186             (ps_rc_ctxt->i4_est_text_bits_ctr_get_qp % (ps_rc_ctxt->i4_num_frame_parallel));
3187 #endif
3188         /** the estimates are reset only duing enc call*/
3189 
3190 #if USE_USER_FIRST_FRAME_QP
3191         /*I_PIC check is necessary coz pre-enc can query for qp even before first frame update has happened*/
3192         if(!ps_rc_ctxt->i4_is_first_frame_encoded && rc_pic_type == I_PIC)
3193         {
3194             i4_hevc_frame_qp = ps_rc_ctxt->i4_init_frame_qp_user;
3195             DBG_PRINTF("FIXED START QP PATH *************************\n");
3196         }
3197 #endif
3198     }
3199 
3200     if(CONST_QP != e_rc_type)
3201     {
3202         ASSERT(*pi4_tot_bits_estimated != 0);
3203     }
3204 
3205     ps_rc_ctxt->s_rc_high_lvl_stat.i4_finalQP = i4_hevc_frame_qp;
3206     if(ps_rc_lap_out->i4_is_model_valid)
3207     {
3208         get_bits_for_final_qp(
3209             ps_rc_ctxt->rc_hdl,
3210             &ps_rc_ctxt->s_rc_high_lvl_stat.i4_modelQP,
3211             &ps_rc_ctxt->s_rc_high_lvl_stat.i4_maxEbfQP,
3212             &ps_rc_ctxt->s_rc_high_lvl_stat.i8_bits_from_finalQP,
3213             i4_hevc_frame_qp,
3214             ihevce_rc_get_scaled_mpeg2_qp_q6(
3215                 i4_hevc_frame_qp + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset,
3216                 ps_rc_ctxt->u1_bit_depth),
3217             i4_cur_est_header_bits,
3218             i4_est_tex_bits,
3219             i4_vbv_buf_max_bits,
3220             rc_pic_type,
3221             ps_rc_lap_out->i4_rc_display_num);
3222     }
3223     i4_deltaQP = ihevce_ebf_based_rc_correction_to_avoid_overflow(
3224         ps_rc_ctxt, ps_rc_lap_out, pi4_tot_bits_estimated);
3225     i4_hevc_frame_qp += i4_deltaQP;
3226 
3227     /**clip to min qp which is user configurable*/
3228     i4_hevc_frame_qp = ihevce_clip_min_max_qp(
3229         ps_rc_ctxt, i4_hevc_frame_qp, rc_pic_type, ps_rc_lap_out->i4_rc_temporal_lyr_id);
3230 
3231     /*set estimate status for frame level error calculation*/
3232     if(i4_estimate_to_calc_frm_error > 0)
3233     {
3234         rc_set_estimate_status(
3235             ps_rc_ctxt->rc_hdl,
3236             i4_estimate_to_calc_frm_error - ps_rc_ctxt->i8_est_I_pic_header_bits,
3237             ps_rc_ctxt->i8_est_I_pic_header_bits,
3238             ps_rc_ctxt->i4_est_text_bits_ctr_get_qp);
3239     }
3240     else
3241     {
3242         rc_set_estimate_status(
3243             ps_rc_ctxt->rc_hdl,
3244             -1,
3245             ps_rc_ctxt->i8_est_I_pic_header_bits,
3246             ps_rc_ctxt->i4_est_text_bits_ctr_get_qp);
3247     }
3248 
3249     ps_rc_lap_out->i8_est_text_bits = *pi4_tot_bits_estimated;
3250 
3251     /*B pictures which are in fades will take the highest QP of either side of P pics*/
3252     if(ps_rc_lap_out->i4_rc_pic_type == IV_B_FRAME &&
3253        (ps_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_FADE_IN ||
3254         ps_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_FADE_OUT))
3255     {
3256         i4_hevc_frame_qp =
3257             MAX(ps_rc_ctxt->ai4_last_tw0_lyr0_pic_qp[0], ps_rc_ctxt->ai4_last_tw0_lyr0_pic_qp[1]);
3258     }
3259 
3260     /*saving the last two pics of layer 0*/
3261     if(0 == ps_rc_lap_out->i4_rc_temporal_lyr_id)
3262     {
3263         ps_rc_ctxt->ai4_last_tw0_lyr0_pic_qp[1] = ps_rc_ctxt->ai4_last_tw0_lyr0_pic_qp[0];
3264         ps_rc_ctxt->ai4_last_tw0_lyr0_pic_qp[0] = i4_hevc_frame_qp;
3265     }
3266 
3267     return i4_hevc_frame_qp;
3268 }
3269 
3270 /*##########################################################*/
3271 /******* END OF ENC THRD QP QUERY FUNCTIONS ****************/
3272 /*########################################################*/
3273 
3274 /*####################################################*/
3275 /******* START OF I2AVG RATIO FUNCTIONS **************/
3276 /*##################################################*/
3277 
3278 /**
3279 ******************************************************************************
3280 *
3281 *  @brief function to get i_to_avg_rest at scene cut frame based on data available from LAP
3282 *
3283 *  @par   Description
3284 *
3285 *  @param[in]   pv_rc_ctxt
3286 *               void pointer to rc ctxt
3287 *  @param[in]   ps_rc_lap_out : pointer to lap out structure
3288 *  @param[in]   i4_update_delay : The Delay in the update. This can happen for dist. case!
3289 *               All decision should consider this delay for updation!
3290 *  @return      WORD32 i_to_rest bit ratio
3291 *
3292 ******************************************************************************
3293 */
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)3294 float ihevce_get_i_to_avg_ratio(
3295     void *pv_rc_ctxt,
3296     rc_lap_out_params_t *ps_rc_lap_out,
3297     WORD32 i_to_p_qp_offset,
3298     WORD32 i4_offset_flag,
3299     WORD32 i4_call_type,
3300     WORD32 ai4_qp_offsets[4],
3301     WORD32 i4_update_delay)
3302 {
3303     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
3304     WORD32 i = 0, k = 0, num_frames_in_lap[MAX_PIC_TYPE] = { 0 }, ai4_pic_dist[MAX_PIC_TYPE],
3305            ai4_pic_dist_in_cur_gop[MAX_PIC_TYPE] = { 0 };
3306     WORD32 i4_num_b, i4_num_frms_traversed_in_lap = 0, total_frms_considered = 0,
3307                      i4_flag_i_frame_exit = 0, u4_rc_scene_number;
3308     rc_lap_out_params_t *ps_cur_rc_lap_out = ps_rc_lap_out;
3309 
3310     rc_lap_out_params_t *ps_cur_rc_lap_out_I = ps_rc_lap_out;
3311     double complexity[MAX_PIC_TYPE] = { 0 }, d_first_i_complexity = 0, d_first_p_complexity = 0.0f,
3312            cur_lambda_modifer, den = 0, average_intra_complexity = 0;
3313     double i_frm_lambda_modifier;
3314     float i_to_rest_bit_ratio = 8.00;
3315     picture_type_e curr_rc_pic_type;
3316     LWORD64 i8_l1_analysis_lap_comp = 0;
3317     WORD32 i4_intra_frame_interval = rc_get_intra_frame_interval(ps_rc_ctxt->rc_hdl);
3318     UWORD32 u4_L1_based_lap_complexity_q7 = 0;
3319     WORD32 i4_frame_qp = 0, i4_I_frame_qp = 0;
3320 
3321     WORD32 ai4_lambda_offsets[5] = { -3, -2, 2, 6, 7 };
3322     /* The window for which your update is guaranteed */
3323     WORD32 updated_window = ps_rc_ctxt->i4_num_frame_in_lap_window - i4_update_delay;
3324 
3325     ASSERT(ps_rc_ctxt->i4_rc_pass != 2);
3326     rc_get_pic_distribution(ps_rc_ctxt->rc_hdl, &ai4_pic_dist[0]);
3327 
3328     if(ps_rc_ctxt->i4_max_temporal_lyr)
3329     {
3330         i4_num_b = ((WORD32)pow((float)2, ps_rc_ctxt->i4_max_temporal_lyr)) - 1;
3331     }
3332     else
3333     {
3334         i4_num_b = 0;
3335     }
3336     i_frm_lambda_modifier = ihevce_get_frame_lambda_modifier((WORD8)I_PIC, 0, 1, 1, i4_num_b);
3337     /* check should be wrt inter frame interval*/
3338     /*If lap frames are not sufficient return default ratio*/
3339     u4_rc_scene_number = ps_cur_rc_lap_out_I->u4_rc_scene_num;
3340 
3341     if(updated_window < 4)
3342     {
3343         return i_to_rest_bit_ratio;
3344     }
3345 
3346     k = 0;
3347     if(ps_cur_rc_lap_out != NULL)
3348     {
3349         WORD32 i4_temp_frame_qp;
3350 
3351         if(ps_cur_rc_lap_out->i4_L0_qp == -1)
3352         {
3353             i4_frame_qp = ps_cur_rc_lap_out->i4_L1_qp;
3354             i4_I_frame_qp = ps_cur_rc_lap_out->i4_L1_qp - 3;
3355         }
3356         else
3357         {
3358             i4_frame_qp = ps_cur_rc_lap_out->i4_L0_qp;
3359             i4_I_frame_qp = ps_cur_rc_lap_out->i4_L0_qp - 3;
3360         }
3361 
3362         do
3363         {
3364             curr_rc_pic_type = ihevce_rc_conv_pic_type(
3365                 (IV_PICTURE_CODING_TYPE_T)ps_cur_rc_lap_out->i4_rc_pic_type,
3366                 ps_rc_ctxt->i4_field_pic,
3367                 ps_cur_rc_lap_out->i4_rc_temporal_lyr_id,
3368                 ps_cur_rc_lap_out->i4_is_bottom_field,
3369                 ps_rc_ctxt->i4_top_field_first);
3370             cur_lambda_modifer = ihevce_get_frame_lambda_modifier(
3371                 (WORD8)curr_rc_pic_type,
3372                 ps_cur_rc_lap_out->i4_rc_temporal_lyr_id,
3373                 1,
3374                 ps_cur_rc_lap_out->i4_rc_is_ref_pic,
3375                 i4_num_b);
3376             if(curr_rc_pic_type == I_PIC)
3377             {
3378                 i4_temp_frame_qp = i4_frame_qp + ai4_lambda_offsets[curr_rc_pic_type];
3379             }
3380             else
3381             {
3382                 i4_temp_frame_qp =
3383                     i4_frame_qp + ai4_lambda_offsets[ps_cur_rc_lap_out->i4_rc_temporal_lyr_id + 1];
3384                 i4_temp_frame_qp =
3385                     i4_temp_frame_qp +
3386                     ps_cur_rc_lap_out->ai4_offsets[ps_cur_rc_lap_out->i4_rc_temporal_lyr_id + 1];
3387             }
3388 
3389             i4_temp_frame_qp = CLIP3(i4_temp_frame_qp, 1, 51);
3390             i4_I_frame_qp = CLIP3(i4_I_frame_qp, 1, 51);
3391 
3392             if(curr_rc_pic_type == I_PIC)
3393             {
3394                 complexity[I_PIC] += (double)ps_cur_rc_lap_out->ai8_pre_intra_sad[i4_I_frame_qp];
3395                 if(total_frms_considered == 0)
3396                     d_first_i_complexity =
3397                         (double)ps_cur_rc_lap_out->ai8_pre_intra_sad[i4_I_frame_qp];
3398 
3399                 num_frames_in_lap[I_PIC]++;
3400                 i8_l1_analysis_lap_comp +=
3401                     (LWORD64)(1.17 * ps_cur_rc_lap_out->i8_raw_pre_intra_sad);
3402             }
3403             else
3404             {
3405                 if((num_frames_in_lap[P_PIC] == 0) && (curr_rc_pic_type == P_PIC))
3406                     d_first_p_complexity =
3407                         (double)ps_cur_rc_lap_out->ai8_pre_intra_sad[i4_I_frame_qp];
3408 
3409                 if(total_frms_considered == 0)
3410                 {
3411                     num_frames_in_lap[I_PIC]++;
3412                     {
3413                         complexity[I_PIC] +=
3414                             (double)ps_cur_rc_lap_out->ai8_pre_intra_sad[i4_I_frame_qp];
3415                         d_first_i_complexity =
3416                             (double)ps_cur_rc_lap_out->ai8_pre_intra_sad[i4_I_frame_qp];
3417                     }
3418                 }
3419                 else
3420                 {
3421                     /*SAD is scaled according the lambda parametrs use to make it proportional to bits consumed in the end*/
3422 #if !USE_SQRT
3423                     //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*/))));
3424                     if((curr_rc_pic_type > P_PIC) &&
3425                        (ps_rc_lap_out->i4_rc_quality_preset == IHEVCE_QUALITY_P6))
3426                         complexity[curr_rc_pic_type] +=
3427                             (double)(ps_cur_rc_lap_out->ai8_frame_acc_coarse_me_sad
3428                                          [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*/))));
3429                     else
3430                         complexity[curr_rc_pic_type] += (double)(MIN(
3431                             ps_cur_rc_lap_out->ai8_frame_acc_coarse_me_sad[i4_temp_frame_qp],
3432                             ps_cur_rc_lap_out->ai8_pre_intra_sad
3433                                 [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*/))));
3434 
3435 #else
3436                     complexity[curr_rc_pic_type] +=
3437                         MIN(ps_cur_rc_lap_out->ai8_frame_acc_coarse_me_sad[i4_temp_frame_qp],
3438                             ps_cur_rc_lap_out->i8_pre_intra_sad) /
3439                         (sqrt(cur_lambda_modifer / i_frm_lambda_modifier) *
3440                          pow(1.125, (ps_rc_lap_out->i4_rc_temporal_lyr_id + 1)));
3441 #endif
3442                     num_frames_in_lap[curr_rc_pic_type]++;
3443                 }
3444                 i8_l1_analysis_lap_comp += (LWORD64)(
3445                     (float)ps_cur_rc_lap_out->i8_raw_l1_coarse_me_sad /
3446                     pow(1.125, curr_rc_pic_type));
3447             }
3448 
3449             if(ps_rc_lap_out->i4_rc_quality_preset == IHEVCE_QUALITY_P6)
3450             {
3451                 if(curr_rc_pic_type < B_PIC)
3452                 {
3453                     /*accumulate average intra sad*/
3454                     average_intra_complexity +=
3455                         ps_cur_rc_lap_out
3456                             ->ai8_pre_intra_sad[i4_I_frame_qp] /*/i_frm_lambda_modifier*/;
3457                     i4_num_frms_traversed_in_lap++;
3458                 }
3459             }
3460             else
3461             {
3462                 /*accumulate average intra sad*/
3463                 average_intra_complexity +=
3464                     ps_cur_rc_lap_out->ai8_pre_intra_sad[i4_I_frame_qp] /*/i_frm_lambda_modifier*/;
3465                 i4_num_frms_traversed_in_lap++;
3466             }
3467 
3468             ai4_pic_dist_in_cur_gop[curr_rc_pic_type]++;
3469             i++;
3470             total_frms_considered++;
3471             i4_num_frms_traversed_in_lap++;
3472             ps_cur_rc_lap_out = (rc_lap_out_params_t *)ps_cur_rc_lap_out->ps_rc_lap_out_next_encode;
3473 
3474             if((ps_cur_rc_lap_out == NULL) ||
3475                ((total_frms_considered + k) == i4_intra_frame_interval) || (i >= updated_window))
3476             {
3477                 break;
3478             }
3479 
3480             if((i >= (ps_rc_ctxt->i4_next_sc_i_in_rc_look_ahead - k) ||
3481                 (ps_cur_rc_lap_out->i4_rc_pic_type == IV_I_FRAME) ||
3482                 (ps_cur_rc_lap_out->i4_rc_pic_type == IV_IDR_FRAME)) &&
3483                (i4_offset_flag == 1))
3484             {
3485                 break;
3486             }
3487             /*If an I frame enters the lookahead it can cause bit allocation to go bad
3488             if corresponding p/b frames are absent*/
3489             if(((total_frms_considered + k) > (WORD32)(0.75f * i4_intra_frame_interval)) &&
3490                ((ps_cur_rc_lap_out->i4_rc_pic_type == IV_I_FRAME) ||
3491                 (ps_cur_rc_lap_out->i4_rc_pic_type == IV_IDR_FRAME)))
3492             {
3493                 i4_flag_i_frame_exit = 1;
3494                 break;
3495             }
3496 
3497         } while(1);
3498 
3499         if(total_frms_considered > 0)
3500         {
3501             float lap_L1_comp =
3502                 (float)i8_l1_analysis_lap_comp /
3503                 (total_frms_considered * ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width);
3504 
3505             lap_L1_comp = rc_get_offline_normalized_complexity(
3506                 ps_rc_ctxt->u4_intra_frame_interval,
3507                 ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width,
3508                 lap_L1_comp,
3509                 ps_rc_ctxt->i4_rc_pass);
3510 
3511             u4_L1_based_lap_complexity_q7 = (WORD32)((lap_L1_comp * (1 << 7)) + .05f);
3512         }
3513         else
3514         {
3515             u4_L1_based_lap_complexity_q7 = 25;
3516         }
3517 
3518         if(i4_call_type == 1)
3519         {
3520             if(num_frames_in_lap[0] > 0)
3521             {
3522                 float f_curr_i_to_sum = (float)(d_first_i_complexity / complexity[0]);
3523                 f_curr_i_to_sum = CLIP3(f_curr_i_to_sum, 0.1f, 100.0f);
3524                 rc_set_i_to_sum_api_ba(ps_rc_ctxt->rc_hdl, f_curr_i_to_sum);
3525             }
3526         }
3527 
3528         for(i = 0; i < MAX_PIC_TYPE; i++)
3529         {
3530             if(num_frames_in_lap[i] > 0)
3531             {
3532                 complexity[i] = complexity[i] / num_frames_in_lap[i];
3533             }
3534         }
3535         /*for non - I scd case it is possible that entire LAP window might not have intra picture. Consider average intra sad when
3536         atleast one I pic is not available*/
3537         if(num_frames_in_lap[I_PIC] == 0)
3538         {
3539             ASSERT(i4_num_frms_traversed_in_lap);
3540             complexity[I_PIC] = average_intra_complexity / i4_num_frms_traversed_in_lap;
3541         }
3542         /*get picture type distribution in LAP*/
3543         if(num_frames_in_lap[I_PIC] == 0)
3544         {
3545             rc_get_pic_distribution(ps_rc_ctxt->rc_hdl, &ai4_pic_dist[0]);
3546         }
3547         else
3548         {
3549             memmove(ai4_pic_dist, num_frames_in_lap, sizeof(WORD32) * MAX_PIC_TYPE);
3550         }
3551 
3552         {
3553             WORD32 num_inter_pic = 0;
3554             for(i = 1; i < MAX_PIC_TYPE; i++)
3555             {
3556                 den += complexity[i] * ai4_pic_dist[i];
3557             }
3558 
3559             for(i = 1; i < MAX_PIC_TYPE; i++)
3560             {
3561                 num_inter_pic += ai4_pic_dist[i];
3562             }
3563             if(num_inter_pic > 0)
3564                 den = den / num_inter_pic;
3565             else
3566                 den = 0.0;
3567         }
3568 
3569         if(den > 0)
3570             i_to_rest_bit_ratio = (float)((complexity[I_PIC]) / den);
3571         else
3572             i_to_rest_bit_ratio = 15;
3573 
3574         if((total_frms_considered < (WORD32)(0.75f * i4_intra_frame_interval)) &&
3575            (total_frms_considered < (updated_window - 1)) &&
3576            ((UWORD32)total_frms_considered < ((ps_rc_ctxt->u4_max_frame_rate / 1000))))
3577         {
3578             /*This GOP will only sustain for few frames hence have strict restriction for I to rest ratio*/
3579             if(i_to_rest_bit_ratio > 12)
3580                 i_to_rest_bit_ratio = 12;
3581 
3582             if(i_to_rest_bit_ratio > 8 &&
3583                total_frms_considered < (ps_rc_ctxt->i4_max_inter_frm_int * 2))
3584                 i_to_rest_bit_ratio = 8;
3585         }
3586     }
3587 
3588     if((i4_call_type == 1) && (i_to_rest_bit_ratio < I_TO_REST_VVFAST) && (i4_offset_flag == 1))
3589     {
3590         float f_p_to_i_ratio = (float)(d_first_p_complexity / d_first_i_complexity);
3591         if(ps_rc_lap_out->i8_frame_satd_act_accum <
3592            (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width * 1.5f))
3593             rc_set_p_to_i_complexity_ratio(ps_rc_ctxt->rc_hdl, f_p_to_i_ratio);
3594     }
3595 
3596     /*Reset the pic distribution if I frame exit was encountered*/
3597 
3598     if(ps_rc_ctxt->e_rate_control_type != CONST_QP)
3599     {
3600         rc_get_pic_distribution(ps_rc_ctxt->rc_hdl, &ai4_pic_dist[0]);
3601         if((ai4_pic_dist_in_cur_gop[I_PIC] > 1) && (ai4_pic_dist[0] == 1))
3602         {
3603             i4_flag_i_frame_exit = 1;
3604         }
3605         if(i4_flag_i_frame_exit && (i4_call_type == 1))
3606         {
3607             if(ai4_pic_dist_in_cur_gop[I_PIC] == 0)
3608                 memmove(ai4_pic_dist_in_cur_gop, num_frames_in_lap, sizeof(WORD32) * MAX_PIC_TYPE);
3609 
3610             rc_update_pic_distn_lap_to_rc(ps_rc_ctxt->rc_hdl, ai4_pic_dist_in_cur_gop);
3611             rc_set_bits_based_on_complexity(
3612                 ps_rc_ctxt->rc_hdl, u4_L1_based_lap_complexity_q7, total_frms_considered);
3613         }
3614     }
3615 
3616     return i_to_rest_bit_ratio;
3617 }
3618 
3619 /*##################################################*/
3620 /******* END OF I2AVG RATIO FUNCTIONS **************/
3621 /*################################################*/
3622 
3623 /*#########################################################*/
3624 /******* START OF QSCALE CONVERSION FUNCTIONS *************/
3625 /*########################################################*/
3626 
3627 /**
3628 ******************************************************************************
3629 *
3630 *  @brief function to convert from qscale to qp
3631 *
3632 *  @par   Description
3633 *  @param[in]   i4_frame_qs_q3 : QP value in qscale
3634 *   return      frame qp
3635 ******************************************************************************
3636 */
3637 
ihevce_rc_get_scaled_hevc_qp_from_qs_q3(WORD32 i4_frame_qs_q3,rc_quant_t * ps_rc_quant_ctxt)3638 WORD32 ihevce_rc_get_scaled_hevc_qp_from_qs_q3(WORD32 i4_frame_qs_q3, rc_quant_t *ps_rc_quant_ctxt)
3639 {
3640     if(i4_frame_qs_q3 > ps_rc_quant_ctxt->i2_max_qscale)
3641     {
3642         i4_frame_qs_q3 = ps_rc_quant_ctxt->i2_max_qscale;
3643     }
3644     else if(i4_frame_qs_q3 < ps_rc_quant_ctxt->i2_min_qscale)
3645     {
3646         i4_frame_qs_q3 = ps_rc_quant_ctxt->i2_min_qscale;
3647     }
3648 
3649     return (ps_rc_quant_ctxt->pi4_qscale_to_qp[i4_frame_qs_q3]);
3650 }
3651 
3652 /**
3653 ******************************************************************************
3654 *
3655 *  @brief function to convert from qp to qscale
3656 *
3657 *  @par   Description
3658 *  @param[in]   i4_frame_qp : QP value
3659 *   return      value in qscale
3660 ******************************************************************************
3661 */
ihevce_rc_get_scaled_mpeg2_qp(WORD32 i4_frame_qp,rc_quant_t * ps_rc_quant_ctxt)3662 WORD32 ihevce_rc_get_scaled_mpeg2_qp(WORD32 i4_frame_qp, rc_quant_t *ps_rc_quant_ctxt)
3663 {
3664     //i4_frame_qp = i4_frame_qp >> 3; // Q3 format is mantained for accuarate calc at lower qp
3665     WORD32 i4_qscale;
3666     if(i4_frame_qp > ps_rc_quant_ctxt->i2_max_qp)
3667     {
3668         i4_frame_qp = ps_rc_quant_ctxt->i2_max_qp;
3669     }
3670     else if(i4_frame_qp < ps_rc_quant_ctxt->i2_min_qp)
3671     {
3672         i4_frame_qp = ps_rc_quant_ctxt->i2_min_qp;
3673     }
3674 
3675     i4_qscale = (ps_rc_quant_ctxt->pi4_qp_to_qscale[i4_frame_qp + ps_rc_quant_ctxt->i1_qp_offset] +
3676                  (1 << (QSCALE_Q_FAC_3 - 1))) >>
3677                 QSCALE_Q_FAC_3;
3678     return i4_qscale;
3679 }
3680 
3681 /**
3682 ******************************************************************************
3683 *
3684 *  @brief function to convert from qp to qscale
3685 *
3686 *  @par Description : This function maps logarithmic QP values to linear QP
3687 *   values. The linear values are represented in Q6 format.
3688 *
3689 *  @param[in]   i4_frame_qp : QP value (log scale)
3690 *
3691 *  @return value in QP (linear scale)
3692 *
3693 ******************************************************************************
3694 */
ihevce_rc_get_scaled_mpeg2_qp_q6(WORD32 i4_frame_qp,UWORD8 u1_bit_depth)3695 WORD32 ihevce_rc_get_scaled_mpeg2_qp_q6(WORD32 i4_frame_qp, UWORD8 u1_bit_depth)
3696 {
3697     WORD32 i4_frame_qp_q6;
3698     number_t s_frame_qp;
3699     float f_qp;
3700 
3701     (void)u1_bit_depth;
3702     ASSERT(i4_frame_qp >= 0);
3703     ASSERT(i4_frame_qp <= 51 + ((u1_bit_depth - 8) * 6));
3704     f_qp = (float)pow((float)2, ((float)(i4_frame_qp - 4) / 6));
3705     convert_float_to_fix(f_qp, &s_frame_qp);
3706     convert_varq_to_fixq(s_frame_qp, &i4_frame_qp_q6, QSCALE_Q_FAC);
3707 
3708     if(i4_frame_qp_q6 < (1 << QSCALE_Q_FAC))
3709         i4_frame_qp_q6 = 1 << QSCALE_Q_FAC;
3710 
3711     return i4_frame_qp_q6;
3712 }
3713 
3714 /**
3715 ******************************************************************************
3716 *
3717 *  @brief function to convert from qscale to qp
3718 *
3719 *  @par   Description
3720 *  @param[in]   i4_frame_qp_q6 : QP value in qscale. the input is assumed to be in q6 format
3721 *   return      frame qp
3722 ******************************************************************************
3723 */
ihevce_rc_get_scaled_hevce_qp_q6(WORD32 i4_frame_qp_q6,UWORD8 u1_bit_depth)3724 WORD32 ihevce_rc_get_scaled_hevce_qp_q6(WORD32 i4_frame_qp_q6, UWORD8 u1_bit_depth)
3725 {
3726     WORD32 i4_hevce_qp;
3727     number_t s_hevce_qp, s_temp;
3728     float f_mpeg2_qp, f_hevce_qp;
3729     f_mpeg2_qp = (float)i4_frame_qp_q6 / (1 << QSCALE_Q_FAC);
3730     f_hevce_qp = (6 * ((float)log(f_mpeg2_qp) / (float)log((float)2))) + 4;
3731     convert_float_to_fix(f_hevce_qp, &s_hevce_qp);
3732 
3733     /*rounf off to nearest integer*/
3734     s_temp.sm = 1;
3735     s_temp.e = 1;
3736     add32_var_q(s_hevce_qp, s_temp, &s_hevce_qp);
3737     number_t_to_word32(s_hevce_qp, &i4_hevce_qp);
3738     if(i4_frame_qp_q6 == 0)
3739     {
3740         i4_hevce_qp = 0;
3741     }
3742 
3743     i4_hevce_qp -= ((u1_bit_depth - 8) * 6);
3744 
3745     return i4_hevce_qp;
3746 }
3747 
3748 /**
3749 ******************************************************************************
3750 *
3751 *  @brief function to convert from qp scale to qp
3752 *
3753 *  @par Description : This function maps linear QP values to logarithimic QP
3754 *   values. The linear values are represented in Q3 format.
3755 *
3756 *  @param[in]   i4_frame_qp : QP value (linear scale, Q3 mode)
3757 *
3758 *  @return value in QP (log scale)
3759 *
3760 ******************************************************************************
3761 */
ihevce_rc_get_scaled_hevce_qp_q3(WORD32 i4_frame_qp,UWORD8 u1_bit_depth)3762 WORD32 ihevce_rc_get_scaled_hevce_qp_q3(WORD32 i4_frame_qp, UWORD8 u1_bit_depth)
3763 {
3764     WORD32 i4_hevce_qp;
3765     number_t s_hevce_qp, s_temp;
3766 
3767     if(i4_frame_qp == 0)
3768     {
3769         i4_hevce_qp = 0;
3770     }
3771     else
3772     {
3773         float f_mpeg2_qp, f_hevce_qp;
3774 
3775         f_mpeg2_qp = (float)i4_frame_qp;
3776         f_hevce_qp = (6 * ((float)log(f_mpeg2_qp) / (float)log((float)2) - 3)) + 4;
3777         convert_float_to_fix(f_hevce_qp, &s_hevce_qp);
3778 
3779         /*rounf off to nearest integer*/
3780         s_temp.sm = 1;
3781         s_temp.e = 1;
3782         add32_var_q(s_hevce_qp, s_temp, &s_hevce_qp);
3783         number_t_to_word32(s_hevce_qp, &i4_hevce_qp);
3784     }
3785     i4_hevce_qp -= ((u1_bit_depth - 8) * 6);
3786 
3787     return i4_hevce_qp;
3788 }
3789 
3790 /*#######################################################*/
3791 /******* END OF QSCALE CONVERSION FUNCTIONS *************/
3792 /*######################################################*/
3793 
3794 /*###############################################*/
3795 /******* START OF SET,GET FUNCTIONS *************/
3796 /*#############################################*/
3797 
3798 /**
3799 ******************************************************************************
3800 *
3801 *  @brief Convert pic type to rc pic type
3802 *
3803 *  @par   Description
3804 *
3805 *
3806 *  @param[in]      pic_type
3807 *  Pic type
3808 *
3809 *  @return      rc_pic_type
3810 *
3811 ******************************************************************************
3812 */
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)3813 picture_type_e ihevce_rc_conv_pic_type(
3814     IV_PICTURE_CODING_TYPE_T pic_type,
3815     WORD32 i4_field_pic,
3816     WORD32 i4_temporal_layer_id,
3817     WORD32 i4_is_bottom_field,
3818     WORD32 i4_top_field_first)
3819 {
3820     picture_type_e rc_pic_type = pic_type;
3821     /*interlaced pictype are not supported*/
3822     if(pic_type > 9 && i4_temporal_layer_id > 3) /**/
3823     {
3824         DBG_PRINTF("unsupported picture type or temporal id\n");
3825         exit(0);
3826     }
3827 
3828     if(i4_field_pic == 0) /*Progressive Source*/
3829     {
3830         if(pic_type == IV_IDR_FRAME)
3831         {
3832             rc_pic_type = I_PIC;
3833         }
3834         else
3835         {
3836             rc_pic_type = (picture_type_e)pic_type;
3837 
3838             /*return different picture type based on temporal layer*/
3839             if(i4_temporal_layer_id > 1)
3840             {
3841                 rc_pic_type = (picture_type_e)(pic_type + (i4_temporal_layer_id - 1));
3842             }
3843         }
3844     }
3845 
3846     else if(i4_field_pic == 1)
3847     {
3848         if(pic_type == IV_IDR_FRAME || pic_type == IV_I_FRAME)
3849         {
3850             rc_pic_type = I_PIC;
3851         }
3852 
3853         else if(i4_top_field_first == 1)
3854         {
3855             rc_pic_type = (picture_type_e)pic_type;
3856 
3857             if(i4_temporal_layer_id <= 1)
3858 
3859             {
3860                 if(i4_is_bottom_field == 1)
3861                     rc_pic_type = (picture_type_e)(pic_type + 4);
3862             }
3863             /*return different picture type based on temporal layer*/
3864             if(i4_temporal_layer_id > 1)
3865             {
3866                 if(i4_is_bottom_field == 0)
3867                     rc_pic_type = (picture_type_e)(pic_type + (i4_temporal_layer_id - 1));
3868                 else
3869                     rc_pic_type = (picture_type_e)(
3870                         pic_type + (i4_temporal_layer_id - 1) +
3871                         4); /*Offset of 4 for the bottomfield*/
3872             }
3873         }
3874         else if(i4_top_field_first == 0)
3875         {
3876             rc_pic_type = (picture_type_e)pic_type;
3877 
3878             if(i4_temporal_layer_id <= 1)
3879             {
3880                 if(i4_is_bottom_field == 1)
3881                     rc_pic_type = (picture_type_e)(pic_type + 4);
3882             }
3883             /*return different picture type based on temporal layer*/
3884             if(i4_temporal_layer_id > 1)
3885             {
3886                 if(i4_is_bottom_field == 0)
3887                     rc_pic_type = (picture_type_e)(pic_type + (i4_temporal_layer_id - 1));
3888                 else
3889                     rc_pic_type = (picture_type_e)(
3890                         pic_type + (i4_temporal_layer_id - 1) + 4); /*Offset of 4 for the topfield*/
3891             }
3892         }
3893     }
3894 
3895     return rc_pic_type;
3896 }
3897 
3898 /**
3899 ******************************************************************************
3900 *
3901 *  @brief function to update current frame intra cost
3902 *
3903 *  @par   Description
3904 *  @param[inout] ps_rc_ctxt
3905 *  @param[in]    i8_cur_frm_intra_cost
3906 ******************************************************************************
3907 */
ihevce_rc_update_cur_frm_intra_satd(void * pv_ctxt,LWORD64 i8_cur_frm_intra_cost,WORD32 i4_enc_frm_id)3908 void ihevce_rc_update_cur_frm_intra_satd(
3909     void *pv_ctxt, LWORD64 i8_cur_frm_intra_cost, WORD32 i4_enc_frm_id)
3910 {
3911     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
3912     ps_rc_ctxt->ai8_cur_frm_intra_cost[i4_enc_frm_id] = i8_cur_frm_intra_cost;
3913 }
3914 /**
3915 ******************************************************************************
3916 *
3917 *  @brief function to return scene type
3918 *
3919 *  @par   Description
3920 *  @param[inout] ps_rc_lap_out
3921 *  @return       i4_rc_scene_type
3922 ******************************************************************************
3923 */
3924 /* Functions dependent on lap input*/
ihevce_rc_lap_get_scene_type(rc_lap_out_params_t * ps_rc_lap_out)3925 WORD32 ihevce_rc_lap_get_scene_type(rc_lap_out_params_t *ps_rc_lap_out)
3926 {
3927     return (WORD32)ps_rc_lap_out->i4_rc_scene_type;
3928 }
3929 
3930 /**
3931 ******************************************************************************
3932 *
3933 *  @name  ihevce_rc_get_pic_param
3934 *
3935 *  @par   Description
3936 *
3937 *  @param[in]   rc_pic_type
3938 *
3939 *  @return      void
3940 *
3941 ******************************************************************************
3942 */
ihevce_rc_get_pic_param(picture_type_e rc_pic_type,WORD32 * pi4_tem_lyr,WORD32 * pi4_is_bottom_field)3943 static void ihevce_rc_get_pic_param(
3944     picture_type_e rc_pic_type, WORD32 *pi4_tem_lyr, WORD32 *pi4_is_bottom_field)
3945 {
3946     /*bottom field determination*/
3947     if(rc_pic_type >= P1_PIC)
3948         *pi4_is_bottom_field = 1;
3949     else
3950         *pi4_is_bottom_field = 0;
3951 
3952     /*temporal lyr id determination*/
3953     if(rc_pic_type == I_PIC || rc_pic_type == P_PIC || rc_pic_type == P1_PIC)
3954     {
3955         *pi4_tem_lyr = 0;
3956     }
3957     else if(rc_pic_type == B_PIC || rc_pic_type == BB_PIC)
3958     {
3959         *pi4_tem_lyr = 1;
3960     }
3961     else if(rc_pic_type == B1_PIC || rc_pic_type == B11_PIC)
3962     {
3963         *pi4_tem_lyr = 2;
3964     }
3965     else if(rc_pic_type == B2_PIC || rc_pic_type == B22_PIC)
3966     {
3967         *pi4_tem_lyr = 3;
3968     }
3969     else
3970     {
3971         ASSERT(0);
3972     }
3973 }
3974 /**
3975 ******************************************************************************
3976 *
3977 *  @name  ihevce_get_offline_index
3978 *
3979 *  @par   Description
3980 *
3981 *  @param[in]   ps_rc_ctxt  - pointer to rc context
3982 *
3983 *  @return      index
3984 *
3985 ******************************************************************************
3986 */
ihevce_get_offline_index(rc_context_t * ps_rc_ctxt,WORD32 i4_num_pels_in_frame)3987 static WORD32 ihevce_get_offline_index(rc_context_t *ps_rc_ctxt, WORD32 i4_num_pels_in_frame)
3988 {
3989     WORD32 i4_rc_quality_preset = ps_rc_ctxt->i4_quality_preset;
3990     WORD32 base = 1;
3991     if(i4_num_pels_in_frame > 5000000) /*ultra HD*/
3992     {
3993         base = 0;
3994     }
3995     else if(i4_num_pels_in_frame > 1500000) /*Full HD*/
3996     {
3997         base = 5;
3998     }
3999     else if(i4_num_pels_in_frame > 600000) /*720p*/
4000     {
4001         base = 10;
4002     }
4003     else /*SD*/
4004     {
4005         base = 15;
4006     }
4007     /*based on preset choose coeff*/
4008     if(i4_rc_quality_preset == IHEVCE_QUALITY_P0) /*Pristine quality*/
4009     {
4010         return base;
4011     }
4012     else if(i4_rc_quality_preset == IHEVCE_QUALITY_P2) /*High quality*/
4013     {
4014         return base + 1;
4015     }
4016     else if(
4017         (i4_rc_quality_preset == IHEVCE_QUALITY_P5) ||
4018         (i4_rc_quality_preset == IHEVCE_QUALITY_P6)) /*Extreme speed */
4019     {
4020         return base + 4;
4021     }
4022     else if(i4_rc_quality_preset == IHEVCE_QUALITY_P4) /*High speed */
4023     {
4024         return base + 3;
4025     }
4026     else if(i4_rc_quality_preset == IHEVCE_QUALITY_P3) /*default assume Medium speed*/
4027     {
4028         return base + 2;
4029     }
4030     else
4031     {
4032         ASSERT(0);
4033     }
4034     return base + 2;
4035 }
4036 
4037 /**
4038 ******************************************************************************
4039 *
4040 *  @name  ihevce_get_frame_lambda_modifier
4041 *
4042 *  @par   Description
4043 *
4044 *  @param[in]   pic_type
4045 *               i4_rc_temporal_lyr_id
4046 *  @param[in]   i4_first_field
4047 *  @param[in]   i4_rc_is_ref_pic
4048 *  @return      lambda_modifier
4049 *
4050 ******************************************************************************
4051 */
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)4052 static double ihevce_get_frame_lambda_modifier(
4053     WORD8 pic_type,
4054     WORD32 i4_rc_temporal_lyr_id,
4055     WORD32 i4_first_field,
4056     WORD32 i4_rc_is_ref_pic,
4057     WORD32 i4_num_b_frms)
4058 {
4059     double lambda_modifier;
4060     WORD32 num_b_frms = i4_num_b_frms, first_field = i4_first_field;
4061 
4062     if(I_PIC == pic_type)
4063     {
4064         double temporal_correction_islice = 1.0 - 0.05 * num_b_frms;
4065         temporal_correction_islice = MAX(0.5, temporal_correction_islice);
4066 
4067         lambda_modifier = 0.57 * temporal_correction_islice;
4068     }
4069     else if(P_PIC == pic_type)
4070     {
4071         if(first_field)
4072             lambda_modifier = 0.442;  //0.442*0.8;
4073         else
4074             lambda_modifier = 0.442;
4075 
4076         //lambda_modifier *= pow(2.00,(double)(1.00/3.00));
4077     }
4078     else
4079     {
4080         /* BSLICE */
4081         if(1 == i4_rc_is_ref_pic)
4082         {
4083             lambda_modifier = 0.3536;
4084         }
4085         else if(2 == i4_rc_is_ref_pic)
4086         {
4087             lambda_modifier = 0.45;
4088         }
4089         else
4090         {
4091             lambda_modifier = 0.68;
4092         }
4093 
4094         /* TODO: Disable lambda modification for interlace encode to match HM runs */
4095         //if(0 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
4096         {
4097             /* modify b lambda further based on temporal id */
4098             if(i4_rc_temporal_lyr_id)
4099             {
4100                 lambda_modifier *= 3.00;
4101             }
4102         }
4103         //lambda_modifier *= pow(2.00,(double)((1.00/3.00) * (i4_rc_temporal_lyr_id + 1)));
4104     }
4105 
4106     /* modify the base lambda according to lambda modifier */
4107     lambda_modifier = sqrt(lambda_modifier);
4108     return lambda_modifier;
4109 }
4110 
4111 /*!
4112 ******************************************************************************
4113 * \if Function name : get_avg_bitrate_bufsize
4114 *
4115 * \brief
4116 *
4117 * \param[in] *pv_ctxt -> rc context
4118 *
4119 * \return
4120 *
4121 * \author
4122 *  Ittiam
4123 *
4124 *****************************************************************************
4125 */
get_avg_bitrate_bufsize(void * pv_ctxt,LWORD64 * pi8_bitrate,LWORD64 * pi8_ebf)4126 void get_avg_bitrate_bufsize(void *pv_ctxt, LWORD64 *pi8_bitrate, LWORD64 *pi8_ebf)
4127 {
4128     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
4129     *pi8_bitrate = rc_get_bit_rate(ps_rc_ctxt->rc_hdl);
4130     *pi8_ebf = rc_get_vbv_buf_size(ps_rc_ctxt->rc_hdl);
4131 }
4132 
4133 /**
4134 ******************************************************************************
4135 *
4136 *  @name  ihevce_get_dbf_buffer_size
4137 *
4138 *  @par   Description
4139 *
4140 *  @param[in]   ps_rc_ctxt  - pointer to rc context
4141 *
4142 *  @return      qp
4143 *
4144 ******************************************************************************
4145 */
ihevce_get_dbf_buffer_size(void * pv_rc_ctxt,UWORD32 * pi4_buffer_size,UWORD32 * pi4_dbf,UWORD32 * pi4_bit_rate)4146 void ihevce_get_dbf_buffer_size(
4147     void *pv_rc_ctxt, UWORD32 *pi4_buffer_size, UWORD32 *pi4_dbf, UWORD32 *pi4_bit_rate)
4148 {
4149     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
4150 
4151     pi4_buffer_size[0] = (WORD32)ps_rc_ctxt->s_vbv_compliance.f_buffer_size;
4152     pi4_dbf[0] = (WORD32)(ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level);
4153     ASSERT(
4154         ps_rc_ctxt->s_vbv_compliance.f_buffer_size >=
4155         ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level);
4156 
4157     pi4_bit_rate[0] = (WORD32)ps_rc_ctxt->s_vbv_compliance.f_bit_rate;
4158 }
4159 
4160 /*!
4161 ******************************************************************************
4162 * \if Function name : ihevce_set_L0_scd_qp
4163 *
4164 * \brief
4165 *
4166 * \param[in] *pv_ctxt -> rc context
4167 *
4168 * \return
4169 *
4170 * \author
4171 *  Ittiam
4172 *
4173 *****************************************************************************
4174 */
ihevce_set_L0_scd_qp(void * pv_rc_ctxt,WORD32 i4_scd_qp)4175 void ihevce_set_L0_scd_qp(void *pv_rc_ctxt, WORD32 i4_scd_qp)
4176 {
4177     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
4178 
4179     ps_rc_ctxt->i4_L0_frame_qp = i4_scd_qp;
4180 }
4181 
4182 /**
4183 ******************************************************************************
4184 *
4185 *  @name  rc_get_buffer_level_unclip
4186 *
4187 *  @par   Description
4188 *
4189 *  @param[in]      pv_rc_ctxt
4190 *
4191 *
4192 *  @return      void
4193 *
4194 ******************************************************************************
4195 */
rc_get_buffer_level_unclip(void * pv_rc_ctxt)4196 float rc_get_buffer_level_unclip(void *pv_rc_ctxt)
4197 {
4198     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
4199     return (ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip);
4200 }
4201 
4202 /**
4203 ******************************************************************************
4204 *
4205 *  @brief Clip QP based on min and max frame qp
4206 *
4207 *  @par   Description
4208 *
4209 *  @param[inout]   ps_rc_ctxt
4210 *  pointer to rc context
4211 *
4212 *  @param[in]      rc_pic_type
4213 *  Pic type
4214 *
4215 *  @return      i4_hevc_frame_qp
4216 *
4217 ******************************************************************************
4218 */
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)4219 static WORD32 ihevce_clip_min_max_qp(
4220     rc_context_t *ps_rc_ctxt,
4221     WORD32 i4_hevc_frame_qp,
4222     picture_type_e rc_pic_type,
4223     WORD32 i4_rc_temporal_lyr_id)
4224 {
4225     ASSERT(i4_rc_temporal_lyr_id >= 0);
4226     /**clip to min qp which is user configurable*/
4227     if(rc_pic_type == I_PIC && i4_hevc_frame_qp < ps_rc_ctxt->i4_min_frame_qp)
4228     {
4229         i4_hevc_frame_qp = ps_rc_ctxt->i4_min_frame_qp;
4230     }
4231     else if(rc_pic_type == P_PIC && i4_hevc_frame_qp < (ps_rc_ctxt->i4_min_frame_qp + 1))
4232     {
4233         i4_hevc_frame_qp = ps_rc_ctxt->i4_min_frame_qp + 1;
4234     }
4235     else if(i4_hevc_frame_qp < (ps_rc_ctxt->i4_min_frame_qp + i4_rc_temporal_lyr_id + 1))
4236     {
4237         /** For B frame max qp is set based on temporal reference*/
4238         i4_hevc_frame_qp = ps_rc_ctxt->i4_min_frame_qp + i4_rc_temporal_lyr_id + 1;
4239     }
4240     /* clip the Qp to MAX QP */
4241     if(i4_hevc_frame_qp < ps_rc_ctxt->ps_rc_quant_ctxt->i2_min_qp)
4242     {
4243         i4_hevc_frame_qp = ps_rc_ctxt->ps_rc_quant_ctxt->i2_min_qp;
4244     }
4245     /**clip to max qp based on pic type*/
4246     if(rc_pic_type == I_PIC && i4_hevc_frame_qp > ps_rc_ctxt->i4_max_frame_qp)
4247     {
4248         i4_hevc_frame_qp = ps_rc_ctxt->i4_max_frame_qp;
4249     }
4250     else if(rc_pic_type == P_PIC && i4_hevc_frame_qp > (ps_rc_ctxt->i4_max_frame_qp + 1))
4251     {
4252         i4_hevc_frame_qp = ps_rc_ctxt->i4_max_frame_qp + 1;
4253     }
4254     else if(i4_hevc_frame_qp > (ps_rc_ctxt->i4_max_frame_qp + i4_rc_temporal_lyr_id + 1))
4255     {
4256         /** For B frame max qp is set based on temporal reference*/
4257         i4_hevc_frame_qp = ps_rc_ctxt->i4_max_frame_qp + i4_rc_temporal_lyr_id + 1;
4258     }
4259     /* clip the Qp to MAX QP */
4260     if(i4_hevc_frame_qp > ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qp)
4261     {
4262         i4_hevc_frame_qp = ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qp;
4263     }
4264     return i4_hevc_frame_qp;
4265 }
4266 
4267 /*#############################################*/
4268 /******* END OF SET,GET FUNCTIONS *************/
4269 /*###########################################*/
4270 
4271 /*#################################################*/
4272 /******* START OF RC UPDATE FUNCTIONS **************/
4273 /*#################################################*/
4274 
4275 /**
4276 ******************************************************************************
4277 *
4278 *  @brief updates the picture level information like bits consumed and
4279 *
4280 *  @par   Description
4281 *
4282 *  @param[inout]   ps_mem_tab
4283 *  pointer to memory descriptors table
4284 *
4285 *  @param[in]      ps_init_prms
4286 *  Create time static parameters
4287 *
4288 *  @return      void
4289 *
4290 ******************************************************************************
4291 */
4292 
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)4293 void ihevce_rc_update_pic_info(
4294     void *pv_ctxt,
4295     UWORD32 u4_total_bits_consumed,
4296     UWORD32 u4_total_header_bits,
4297     UWORD32 u4_frame_sad,
4298     UWORD32 u4_frame_intra_sad,
4299     IV_PICTURE_CODING_TYPE_T pic_type,
4300     WORD32 i4_avg_frame_hevc_qp,
4301     WORD32 i4_suppress_bpic_update,
4302     WORD32 *pi4_qp_normalized_8x8_cu_sum,
4303     WORD32 *pi4_8x8_cu_sum,
4304     LWORD64 *pi8_sad_by_qscale,
4305     ihevce_lap_output_params_t *ps_lap_out,
4306     rc_lap_out_params_t *ps_rc_lap_out,
4307     WORD32 i4_buf_id,
4308     UWORD32 u4_open_loop_intra_sad,
4309     LWORD64 i8_total_ssd_frame,
4310     WORD32 i4_enc_frm_id)
4311 {
4312     LWORD64 a_mb_type_sad[2];
4313     WORD32 a_mb_type_tex_bits[2];
4314     /*dummy variables not used*/
4315     WORD32 a_mb_in_type[2] = { 0, 0 };
4316     LWORD64 a_mb_type_qp_q6[2] = { 0, 0 };
4317     /*qp accumulation at */
4318     WORD32 i4_avg_activity = 250;  //hardcoding to usual value
4319     WORD32 i4_intra_cost, i4_avg_frame_qp_q6, i;
4320     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
4321     WORD32 i4_frame_complexity, i4_bits_to_be_stuffed = 0, i4_is_last_frm_period = 0;
4322     picture_type_e rc_pic_type = ihevce_rc_conv_pic_type(
4323         pic_type,
4324         ps_rc_ctxt->i4_field_pic,
4325         ps_rc_lap_out->i4_rc_temporal_lyr_id,
4326         ps_rc_lap_out->i4_is_bottom_field,
4327         ps_rc_ctxt->i4_top_field_first);
4328     frame_info_t s_frame_info;
4329     WORD32 i4_ctr = -1, i4_i, i4_j;
4330     WORD32 i4_scene_num = ps_rc_lap_out->u4_rc_scene_num % MAX_SCENE_NUM;
4331 
4332     /*update bit consumption. used only in rdopt*/
4333     //ASSERT(ps_rc_ctxt->ai4_rdopt_bit_consumption_estimate[ps_rc_ctxt->i4_rdopt_bit_count] == -1);
4334     //ASSERT(i4_buf_id>=0);
4335     ps_rc_ctxt->ai4_rdopt_bit_consumption_estimate[ps_rc_ctxt->i4_rdopt_bit_count] =
4336         u4_total_bits_consumed;
4337     ps_rc_ctxt->ai4_rdopt_bit_consumption_buf_id[ps_rc_ctxt->i4_rdopt_bit_count] = i4_buf_id;
4338     ps_rc_ctxt->i4_rdopt_bit_count =
4339         (ps_rc_ctxt->i4_rdopt_bit_count + 1) % NUM_BUF_RDOPT_ENT_CORRECT;
4340 
4341     {
4342         LWORD64 i8_texture_bits = u4_total_bits_consumed - u4_total_header_bits;
4343         ps_rc_lap_out->i4_use_offline_model_2pass = 0;
4344 
4345         /*flag to guide whether 2nd pass can use offline model or not*/
4346         if((abs(ps_rc_lap_out->i4_orig_rc_qp - i4_avg_frame_hevc_qp) < 2) &&
4347            (i8_texture_bits <= (ps_rc_lap_out->i8_est_text_bits * 2.0f)) &&
4348            (i8_texture_bits >= (ps_rc_lap_out->i8_est_text_bits * 0.5f)))
4349 
4350         {
4351             ps_rc_lap_out->i4_use_offline_model_2pass = 1;
4352         }
4353     }
4354     /*Counter of number of bit alloction periods*/
4355     if(rc_pic_type == I_PIC)
4356         ps_rc_ctxt
4357             ->i8_num_bit_alloc_period++;  //Currently only I frame periods are considerd as bit allocation period (Ignoring non- I scd and complexity reset flag
4358     /*initialze frame info*/
4359     init_frame_info(&s_frame_info);
4360     s_frame_info.i4_rc_hevc_qp = i4_avg_frame_hevc_qp;
4361     s_frame_info.i4_num_entries++;
4362     s_frame_info.i8_L1_me_sad = ps_rc_lap_out->i8_raw_l1_coarse_me_sad;
4363     s_frame_info.i8_L1_ipe_raw_sad = ps_rc_lap_out->i8_raw_pre_intra_sad;
4364     s_frame_info.i4_num_entries++;
4365     s_frame_info.i4_num_entries++;
4366     s_frame_info.i8_L0_open_cost = (LWORD64)u4_open_loop_intra_sad;
4367     s_frame_info.i4_num_entries++;
4368 
4369     if(rc_pic_type == I_PIC)
4370         s_frame_info.i8_L1_me_or_ipe_raw_sad = ps_rc_lap_out->i8_raw_pre_intra_sad;
4371     else
4372         s_frame_info.i8_L1_me_or_ipe_raw_sad = ps_rc_lap_out->i8_raw_l1_coarse_me_sad;
4373     s_frame_info.i4_num_entries++;
4374     s_frame_info.i4_poc = ps_rc_lap_out->i4_rc_poc;
4375     s_frame_info.i4_num_entries++;
4376     s_frame_info.i4_scene_type = ps_rc_lap_out->i4_rc_scene_type;
4377     s_frame_info.i4_num_entries++;
4378     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;
4379     s_frame_info.i4_num_entries++;
4380     s_frame_info.i8_cl_sad = u4_frame_sad;
4381     s_frame_info.i4_num_entries++;
4382     s_frame_info.i8_header_bits = u4_total_header_bits;
4383     s_frame_info.i4_num_entries++;
4384     s_frame_info.i8_tex_bits = u4_total_bits_consumed - u4_total_header_bits;
4385     s_frame_info.i4_num_entries++;
4386     s_frame_info.e_pic_type = rc_pic_type;
4387     s_frame_info.i4_num_entries++;
4388     s_frame_info.i8_est_texture_bits = ps_rc_lap_out->i8_est_text_bits;
4389     s_frame_info.i4_num_entries++;
4390     s_frame_info.i4_lap_complexity_q7 = ps_rc_ctxt->ai4_lap_complexity_q7[i4_enc_frm_id];
4391     s_frame_info.i4_num_entries++;
4392     s_frame_info.i4_lap_f_sim = ps_rc_ctxt->ai4_lap_f_sim[i4_enc_frm_id];
4393     s_frame_info.i4_num_entries++;
4394     s_frame_info.i8_frame_acc_coarse_me_cost = ps_rc_lap_out->i8_frame_acc_coarse_me_cost;
4395     s_frame_info.i4_num_entries++;
4396     s_frame_info.i_to_avg_bit_ratio = ps_rc_ctxt->ai_to_avg_bit_ratio[i4_enc_frm_id];
4397     s_frame_info.i4_num_entries++;
4398     s_frame_info.i4_num_scd_in_lap_window = ps_rc_ctxt->ai4_num_scd_in_lap_window[i4_enc_frm_id];
4399     s_frame_info.i4_num_entries++;
4400     s_frame_info.i4_num_frames_b4_scd = ps_rc_ctxt->ai4_num_frames_b4_scd[i4_enc_frm_id];
4401     s_frame_info.i4_num_entries++;
4402     s_frame_info.i8_num_bit_alloc_period = ps_rc_ctxt->i8_num_bit_alloc_period;
4403     s_frame_info.i4_num_entries++;
4404     s_frame_info.i1_is_complexity_based_bits_reset =
4405         (WORD8)ps_rc_lap_out->i4_is_cmplx_change_reset_bits;
4406     s_frame_info.i4_num_entries++;
4407     /*For the complexity based movement in 2nd pass*/
4408     memmove(
4409         (void *)s_frame_info.af_sum_weigh,
4410         ps_rc_lap_out->ps_frame_info->af_sum_weigh,
4411         sizeof(float) * MAX_PIC_TYPE * 3);
4412     s_frame_info.i4_num_entries++;
4413 
4414     /*store frame qp to clip qp accordingly*/
4415     if(ps_rc_lap_out->i4_is_rc_model_needs_to_be_updated)
4416     {
4417         ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type] = i4_avg_frame_hevc_qp;
4418     }
4419 
4420     for(i4_i = 0; i4_i < MAX_NON_REF_B_PICS_IN_QUEUE_SGI; i4_i++)
4421     {
4422         if(ps_rc_lap_out->u4_rc_scene_num == ps_rc_ctxt->au4_prev_scene_num_multi_scene[i4_i])
4423         {
4424             i4_ctr = i4_i;
4425             break;
4426         }
4427     }
4428     if(-1 == i4_ctr)
4429     {
4430         ps_rc_ctxt->i4_prev_qp_ctr++;
4431         ps_rc_ctxt->i4_prev_qp_ctr = ps_rc_ctxt->i4_prev_qp_ctr % MAX_NON_REF_B_PICS_IN_QUEUE_SGI;
4432         i4_ctr = ps_rc_ctxt->i4_prev_qp_ctr;
4433         ps_rc_ctxt->au4_prev_scene_num_multi_scene[i4_ctr] = ps_rc_lap_out->u4_rc_scene_num;
4434         for(i4_j = 0; i4_j < MAX_PIC_TYPE; i4_j++)
4435         {
4436             ps_rc_ctxt->ai4_qp_for_previous_scene_multi_scene[i4_ctr][i4_j] = 0;
4437         }
4438     }
4439 
4440     {
4441         ps_rc_ctxt->ai4_qp_for_previous_scene_multi_scene[i4_ctr][rc_pic_type] =
4442             i4_avg_frame_hevc_qp;
4443     }
4444     if(i4_scene_num < HALF_MAX_SCENE_ARRAY_QP)
4445     {
4446         WORD32 i4_i;
4447         ps_rc_ctxt->ai4_scene_numbers[i4_scene_num + HALF_MAX_SCENE_ARRAY_QP] = 0;
4448         for(i4_i = 0; i4_i < MAX_PIC_TYPE; i4_i++)
4449             ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num + HALF_MAX_SCENE_ARRAY_QP][i4_i] =
4450                 INIT_HEVCE_QP_RC;
4451     }
4452     else
4453     {
4454         WORD32 i4_i;
4455         ps_rc_ctxt->ai4_scene_numbers[i4_scene_num - HALF_MAX_SCENE_ARRAY_QP] = 0;
4456         for(i4_i = 0; i4_i < MAX_PIC_TYPE; i4_i++)
4457             ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num - HALF_MAX_SCENE_ARRAY_QP][i4_i] =
4458                 INIT_HEVCE_QP_RC;
4459     }
4460 
4461     /*update will have HEVC qp, convert it back to mpeg2 range qp for all internal calculations of RC*/
4462 
4463     i4_avg_frame_qp_q6 = ps_rc_ctxt->ps_rc_quant_ctxt->pi4_qp_to_qscale_q_factor
4464                              [i4_avg_frame_hevc_qp + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset];
4465 
4466     if(pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME)
4467     {
4468         /*TODO : Take care of precision of a_mb_type_sad*/
4469         a_mb_type_sad[0] =
4470             (((pi8_sad_by_qscale[1] * i4_avg_frame_qp_q6) +
4471               (((LWORD64)1) << (SAD_BY_QSCALE_Q + QSCALE_Q_FAC - 1))) >>
4472              (SAD_BY_QSCALE_Q + QSCALE_Q_FAC));  //u4_frame_sad;
4473 
4474         a_mb_type_sad[1] =
4475             (((pi8_sad_by_qscale[0] * i4_avg_frame_qp_q6) +
4476               (((LWORD64)1) << (SAD_BY_QSCALE_Q + QSCALE_Q_FAC - 1))) >>
4477              (SAD_BY_QSCALE_Q + QSCALE_Q_FAC));
4478         a_mb_type_tex_bits[0] =
4479             u4_total_bits_consumed - u4_total_header_bits;  //(u4_total_bits_consumed >> 3);
4480         a_mb_type_tex_bits[1] = 0;
4481         a_mb_in_type[0] = (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) >> 8;
4482         a_mb_in_type[1] = 0;
4483     }
4484     else
4485     {
4486         /*TODO : Take care of precision of a_mb_type_sad*/
4487         a_mb_type_sad[1] =
4488             (((pi8_sad_by_qscale[0] * i4_avg_frame_qp_q6) +
4489               (((LWORD64)1) << (SAD_BY_QSCALE_Q + QSCALE_Q_FAC - 1))) >>
4490              (SAD_BY_QSCALE_Q + QSCALE_Q_FAC));
4491 
4492         a_mb_type_tex_bits[0] =
4493             u4_total_bits_consumed - u4_total_header_bits;  //(u4_total_bits_consumed >> 3);
4494         a_mb_type_sad[0] =
4495             (((pi8_sad_by_qscale[1] * i4_avg_frame_qp_q6) +
4496               (((LWORD64)1) << (SAD_BY_QSCALE_Q + QSCALE_Q_FAC - 1))) >>
4497              (SAD_BY_QSCALE_Q + QSCALE_Q_FAC));  //u4_frame_sad;
4498         a_mb_type_tex_bits[1] =
4499             u4_total_bits_consumed - u4_total_header_bits;  //(u4_total_bits_consumed >> 3);
4500         a_mb_type_tex_bits[0] = 0;
4501         a_mb_in_type[1] = (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) >> 8;
4502         a_mb_in_type[0] = 0;
4503     }
4504     ASSERT(a_mb_type_sad[0] >= 0);
4505     ASSERT(a_mb_type_sad[1] >= 0);
4506     /*THis calclates sum of Qps of all MBs as per the corresponding mb type*/
4507     /*THis is different from a_mb_in_type,a_mb_type_sad and a_mb_type_tex_bits*/
4508     a_mb_type_qp_q6[0] = ((LWORD64)i4_avg_frame_qp_q6) * a_mb_in_type[0];
4509     a_mb_type_qp_q6[1] = ((LWORD64)i4_avg_frame_qp_q6) * a_mb_in_type[1];
4510     {
4511         WORD32 i4_avg_qp_q6_without_offset = 0, i4_hevc_qp_rc = i4_avg_frame_hevc_qp;
4512         WORD32 i4_rc_pic_type_rc_for_offset = rc_pic_type;
4513         if(i4_rc_pic_type_rc_for_offset > B2_PIC)
4514             i4_rc_pic_type_rc_for_offset = i4_rc_pic_type_rc_for_offset - B2_PIC;
4515         i4_hevc_qp_rc = i4_hevc_qp_rc - ps_rc_lap_out->ai4_offsets[i4_rc_pic_type_rc_for_offset] +
4516                         ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset;
4517 
4518         i4_hevc_qp_rc =
4519             CLIP3(i4_hevc_qp_rc, 1, MAX_HEVC_QP + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset);
4520         i4_avg_qp_q6_without_offset =
4521             ps_rc_ctxt->ps_rc_quant_ctxt->pi4_qp_to_qscale_q_factor[i4_hevc_qp_rc];
4522 
4523         /*Store the HBD qscale with and without accounting for offset*/
4524         s_frame_info.f_hbd_q_scale_without_offset =
4525             (float)i4_avg_qp_q6_without_offset / (1 << QSCALE_Q_FAC);
4526         s_frame_info.f_hbd_q_scale = (float)i4_avg_frame_qp_q6 / (1 << QSCALE_Q_FAC);
4527         s_frame_info.i4_num_entries++;
4528         s_frame_info.i4_num_entries++;
4529 
4530         /*Store the 8 bit qscale with and without accounting for offset*/
4531         /*Can be useful for pre-enc stage*/
4532         if(ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset != 0)
4533         {
4534             s_frame_info.f_8bit_q_scale_without_offset =
4535                 s_frame_info.f_hbd_q_scale_without_offset / (1 << (ps_rc_ctxt->u1_bit_depth - 8));
4536             s_frame_info.f_8bit_q_scale =
4537                 s_frame_info.f_hbd_q_scale / (1 << (ps_rc_ctxt->u1_bit_depth - 8));
4538         }
4539         else
4540         {
4541             s_frame_info.f_8bit_q_scale_without_offset = s_frame_info.f_hbd_q_scale_without_offset;
4542             s_frame_info.f_8bit_q_scale = s_frame_info.f_hbd_q_scale;
4543         }
4544         s_frame_info.i4_num_entries++;
4545         s_frame_info.i4_num_entries++;
4546     }
4547 
4548     /*making intra cost same as ssd as of now*/
4549     i4_intra_cost = u4_frame_intra_sad;
4550 
4551     /* Handling bits stuffing and skips */
4552     {
4553         WORD32 i4_num_bits_to_prevent_vbv_underflow;
4554         vbv_buf_status_e vbv_buffer_status;
4555         vbv_buffer_status = get_buffer_status(
4556             ps_rc_ctxt->rc_hdl,
4557             u4_total_bits_consumed,
4558             rc_pic_type,  //the picture type convention is different in buffer handling
4559             &i4_num_bits_to_prevent_vbv_underflow);
4560 
4561         if(vbv_buffer_status == VBV_UNDERFLOW)
4562         {
4563         }
4564         if(vbv_buffer_status == VBV_OVERFLOW)
4565         {
4566             i4_bits_to_be_stuffed =
4567                 get_bits_to_stuff(ps_rc_ctxt->rc_hdl, u4_total_bits_consumed, rc_pic_type);
4568             //i4_bits_to_be_stuffed = 0;/*STORAGE_RC*/
4569         }
4570     }
4571     {
4572         WORD32 ai4_sad[MAX_PIC_TYPE], i4_valid_sad_entry = 0;
4573         UWORD32 u4_avg_sad = 0;
4574 
4575         /*calculate frame complexity. Given same content frame complexity should not vary across I,P and Bpic. Hence frame complexity is calculated
4576         based on average of all pic types SAD*/
4577         if(rc_pic_type == I_PIC)
4578         {
4579             ai4_sad[I_PIC] = u4_frame_intra_sad;
4580         }
4581         else
4582         {
4583             /*call to get previous I-PIC sad*/
4584             rc_get_sad(ps_rc_ctxt->rc_hdl, &ai4_sad[0]);
4585         }
4586 
4587         /*since intra sad is not available for every frame use previous I pic intra frame SAD*/
4588         rc_put_sad(ps_rc_ctxt->rc_hdl, ai4_sad[I_PIC], u4_frame_sad, rc_pic_type);
4589         rc_get_sad(ps_rc_ctxt->rc_hdl, &ai4_sad[0]);
4590         /*for first few frame valid SAD is not available. This will make sure invalid data is not used*/
4591         if(ps_rc_ctxt->i4_field_pic == 0)
4592         {
4593             for(i = 0; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
4594             {
4595                 if(ai4_sad[i] >= 0)
4596                 {
4597                     u4_avg_sad += ai4_sad[i];
4598                     i4_valid_sad_entry++;
4599                 }
4600             }
4601         }
4602         else /*for field case*/
4603         {
4604             if(ai4_sad[0] >= 0)
4605             {
4606                 u4_avg_sad += ai4_sad[0];
4607                 i4_valid_sad_entry++;
4608             }
4609 
4610             for(i = 1; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
4611             {
4612                 if(ai4_sad[i] >= 0)
4613                 {
4614                     u4_avg_sad += ai4_sad[i];
4615                     i4_valid_sad_entry++;
4616                 }
4617 
4618                 if(ai4_sad[i + FIELD_OFFSET] >= 0)
4619                 {
4620                     u4_avg_sad += ai4_sad[i + FIELD_OFFSET];
4621                     i4_valid_sad_entry++;
4622                 }
4623             }
4624         }
4625 
4626         if(i4_valid_sad_entry > 0)
4627         {
4628             i4_frame_complexity =
4629                 (u4_avg_sad) /
4630                 (i4_valid_sad_entry * (ps_rc_ctxt->i4_frame_width * ps_rc_ctxt->i4_frame_height));
4631         }
4632         else
4633         {
4634             i4_frame_complexity = 1;
4635         }
4636     }
4637     ASSERT(i4_frame_complexity >= 0);
4638     /*I_model only reset In case of fade-in and fade-out*/
4639     if(ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id])
4640     {
4641         ASSERT(rc_pic_type == I_PIC);
4642         rc_reset_pic_model(ps_rc_ctxt->rc_hdl, I_PIC);
4643         ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id] = 0;
4644     }
4645 
4646     /*check if next picture is I frame, both scene cuts and I pictures are treated as end of period*/
4647     {
4648         if(ps_rc_lap_out->i4_rc_pic_type != -1 && ps_rc_lap_out->i4_rc_scene_type != -1)
4649         {
4650             if(ps_rc_ctxt->u4_intra_frame_interval != 1)
4651             {
4652                 /*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*/
4653                 i4_is_last_frm_period = (WORD32)(
4654                     ps_rc_lap_out->i4_next_pic_type == IV_IDR_FRAME ||
4655                     ps_rc_lap_out->i4_next_pic_type == IV_I_FRAME);
4656             }
4657             else
4658             {
4659                 i4_is_last_frm_period =
4660                     (WORD32)(ps_rc_lap_out->i4_next_scene_type == SCENE_TYPE_SCENE_CUT);
4661             }
4662         }
4663 
4664         /*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*/
4665         if(ps_rc_ctxt->i4_rc_pass != 2)
4666             i4_is_last_frm_period = i4_is_last_frm_period ||
4667                                     ps_rc_ctxt->ai4_is_cmplx_change_reset_bits[i4_enc_frm_id];
4668     }
4669 
4670 #if 1  //FRAME_PARALLEL_LVL //ELP_RC
4671     ps_rc_ctxt->i4_est_text_bits_ctr_update_qp++;
4672     ps_rc_ctxt->i4_est_text_bits_ctr_update_qp =
4673         (ps_rc_ctxt->i4_est_text_bits_ctr_update_qp % (ps_rc_ctxt->i4_num_frame_parallel));
4674 #endif
4675 
4676     update_frame_level_info(
4677         ps_rc_ctxt->rc_hdl,
4678         rc_pic_type,
4679         a_mb_type_sad,
4680         u4_total_bits_consumed, /*total bits consumed by frame*/
4681         u4_total_header_bits,
4682         a_mb_type_tex_bits,
4683         a_mb_type_qp_q6, /*sum of qp of all mb in frame, since no ctb level modulation*/
4684         a_mb_in_type,
4685         i4_avg_activity,
4686         ps_rc_ctxt->ai4_is_frame_scd[i4_enc_frm_id], /*currenlty SCD is not enabled*/
4687         0, /*not a pre encode skip*/
4688         i4_intra_cost,
4689         0,
4690         ps_rc_lap_out
4691             ->i4_ignore_for_rc_update, /*HEVC_hierarchy: do not supress update for non-ref B pic*/
4692         i4_bits_to_be_stuffed,
4693         (ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] ||
4694          ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] ||
4695          ps_rc_ctxt->ai4_is_cmplx_change_reset_model[i4_enc_frm_id]),
4696         ps_rc_ctxt->ai4_lap_complexity_q7[i4_enc_frm_id],
4697         i4_is_last_frm_period,
4698         ps_rc_ctxt->ai4_is_cmplx_change_reset_bits[i4_enc_frm_id],
4699         &s_frame_info,
4700         ps_rc_lap_out->i4_is_rc_model_needs_to_be_updated,
4701         ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset,
4702         i4_scene_num,
4703         ps_rc_ctxt->ai4_scene_numbers[i4_scene_num],
4704         ps_rc_ctxt->i4_est_text_bits_ctr_update_qp);
4705     /** reset flags valid for only one frame*/
4706     ps_rc_ctxt->ai4_is_frame_scd[i4_enc_frm_id] = 0;
4707     ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] = 0;
4708     ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] = 0;
4709     ps_rc_ctxt->ai4_is_cmplx_change_reset_model[i4_enc_frm_id] = 0;
4710     ps_rc_ctxt->ai4_is_cmplx_change_reset_bits[i4_enc_frm_id] = 0;
4711 
4712     ps_rc_ctxt->i4_is_first_frame_encoded = 1;
4713 
4714     /** update the scene num for current frame*/
4715     ps_rc_ctxt->au4_scene_num_temp_id[ps_rc_lap_out->i4_rc_temporal_lyr_id] =
4716         ps_rc_lap_out->u4_rc_scene_num;
4717 
4718     if(ps_rc_ctxt->ai4_is_frame_scd[i4_enc_frm_id])
4719     {
4720         /*reset pre-enc SAD whenever SCD is detected so that it does not detect scene cut for other pictures*/
4721         for(i = 0; i < MAX_PIC_TYPE; i++)
4722         {
4723             ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[i] = -1;
4724         }
4725     }
4726 
4727     /*remember i frame's cost metric to scale SAD of next of I frame*/
4728     if(pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME)
4729     {
4730         ps_rc_ctxt->i8_prev_i_frm_cost = ps_rc_ctxt->ai8_cur_frm_intra_cost[i4_enc_frm_id];
4731         ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[rc_pic_type] =
4732             ps_rc_ctxt->ai8_cur_frm_intra_cost[i4_enc_frm_id];
4733     }
4734     /*for other picture types update hme cost*/
4735     else
4736     {
4737         ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[rc_pic_type] =
4738             ps_rc_ctxt->ai8_cur_frame_coarse_ME_cost[i4_enc_frm_id];
4739     }
4740 }
4741 /*!
4742 ******************************************************************************
4743 * \if Function name : ihevce_rc_interface_update \endif
4744 *
4745 * \brief
4746 *   Updating rate control interface parameters after the query call.
4747 *
4748 * \param[in] Rate control interface context,
4749 *            Picture Type
4750 *            Lap out structure pointer
4751 *
4752 *
4753 * \return
4754 *    None
4755 *
4756 * \author Ittiam
4757 *  Ittiam
4758 *
4759 *****************************************************************************
4760 */
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)4761 void ihevce_rc_interface_update(
4762     void *pv_ctxt,
4763     IV_PICTURE_CODING_TYPE_T pic_type,
4764     rc_lap_out_params_t *ps_rc_lap_out,
4765     WORD32 i4_avg_frame_hevc_qp,
4766     WORD32 i4_enc_frm_id)
4767 {
4768     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
4769     picture_type_e rc_pic_type = ihevce_rc_conv_pic_type(
4770         pic_type,
4771         ps_rc_ctxt->i4_field_pic,
4772         ps_rc_lap_out->i4_rc_temporal_lyr_id,
4773         ps_rc_lap_out->i4_is_bottom_field,
4774         ps_rc_ctxt->i4_top_field_first);
4775     WORD32 i;
4776     WORD32 i4_avg_frame_qp_q6, i4_ctr = -1, i4_i, i4_j;
4777     WORD32 i4_scene_num = ps_rc_lap_out->u4_rc_scene_num % MAX_SCENE_NUM;
4778 
4779     /*store frame qp to clip qp accordingly*/
4780     if(ps_rc_lap_out->i4_is_rc_model_needs_to_be_updated)
4781     {
4782         WORD32 i4_i, i4_temp_i_qp, i4_temp_qp;
4783         ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type] = i4_avg_frame_hevc_qp;
4784         ps_rc_ctxt->ai4_scene_numbers[i4_scene_num]++;
4785 
4786         if(rc_pic_type < P1_PIC)
4787             i4_temp_i_qp = i4_avg_frame_hevc_qp - rc_pic_type;
4788         else
4789             i4_temp_i_qp = i4_avg_frame_hevc_qp - rc_pic_type + 4;
4790 
4791         i4_temp_i_qp = ihevce_clip_min_max_qp(ps_rc_ctxt, i4_temp_i_qp, I_PIC, 0);
4792 
4793         if(ps_rc_ctxt->ai4_scene_numbers[i4_scene_num] == 1)
4794         {
4795             for(i4_i = 0; i4_i < 5; i4_i++)
4796             {
4797                 if(ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i4_i] == INIT_HEVCE_QP_RC)
4798                 {
4799                     i4_temp_qp = i4_temp_i_qp + i4_i;
4800                     i4_temp_qp = ihevce_clip_min_max_qp(
4801                         ps_rc_ctxt, i4_temp_qp, (picture_type_e)i4_i, MAX(i4_i - 1, 0));
4802                     ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i4_i] = i4_temp_qp;
4803 
4804                     if(i4_i > 0)
4805                         ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i4_i + 4] = i4_temp_qp;
4806                 }
4807             }
4808         }
4809     }
4810 
4811     for(i4_i = 0; i4_i < MAX_NON_REF_B_PICS_IN_QUEUE_SGI; i4_i++)
4812     {
4813         if(ps_rc_lap_out->u4_rc_scene_num == ps_rc_ctxt->au4_prev_scene_num_multi_scene[i4_i])
4814         {
4815             i4_ctr = i4_i;
4816             break;
4817         }
4818     }
4819     if(-1 == i4_ctr)
4820     {
4821         ps_rc_ctxt->i4_prev_qp_ctr++;
4822         ps_rc_ctxt->i4_prev_qp_ctr = ps_rc_ctxt->i4_prev_qp_ctr % MAX_NON_REF_B_PICS_IN_QUEUE_SGI;
4823         i4_ctr = ps_rc_ctxt->i4_prev_qp_ctr;
4824         ps_rc_ctxt->au4_prev_scene_num_multi_scene[i4_ctr] = ps_rc_lap_out->u4_rc_scene_num;
4825         for(i4_j = 0; i4_j < MAX_PIC_TYPE; i4_j++)
4826         {
4827             ps_rc_ctxt->ai4_qp_for_previous_scene_multi_scene[i4_ctr][i4_j] = 0;
4828         }
4829     }
4830 
4831     {
4832         ps_rc_ctxt->ai4_qp_for_previous_scene_multi_scene[i4_ctr][rc_pic_type] =
4833             i4_avg_frame_hevc_qp;
4834     }
4835 
4836     /*I_model only reset In case of fade-in and fade-out*/
4837     if(ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id])
4838     {
4839         ASSERT(rc_pic_type == I_PIC);
4840         rc_reset_pic_model(ps_rc_ctxt->rc_hdl, I_PIC);
4841         ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id] = 0;
4842     }
4843 
4844     i4_avg_frame_qp_q6 = ps_rc_ctxt->ps_rc_quant_ctxt->pi4_qp_to_qscale_q_factor
4845                              [i4_avg_frame_hevc_qp + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset];
4846 
4847     update_frame_rc_get_frame_qp_info(
4848         ps_rc_ctxt->rc_hdl,
4849         rc_pic_type,
4850         ps_rc_ctxt->ai4_is_frame_scd[i4_enc_frm_id],
4851         (ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] ||
4852          ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] ||
4853          ps_rc_ctxt->ai4_is_cmplx_change_reset_model[i4_enc_frm_id]),
4854         i4_avg_frame_qp_q6,
4855         ps_rc_lap_out->i4_ignore_for_rc_update,
4856         i4_scene_num,
4857         ps_rc_ctxt->ai4_scene_numbers[i4_scene_num]);
4858 
4859     /** update the scene num for current frame*/
4860     ps_rc_ctxt->au4_scene_num_temp_id[ps_rc_lap_out->i4_rc_temporal_lyr_id] =
4861         ps_rc_lap_out->u4_rc_scene_num;
4862 
4863     if(ps_rc_ctxt->ai4_is_frame_scd[i4_enc_frm_id])
4864     {
4865         /*reset pre-enc SAD whenever SCD is detected so that it does not detect scene cut for other pictures*/
4866         for(i = 0; i < MAX_PIC_TYPE; i++)
4867         {
4868             ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[i] = -1;
4869         }
4870     }
4871 
4872     /*remember i frame's cost metric to scale SAD of next of I frame*/
4873     if(pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME)
4874     {
4875         ps_rc_ctxt->i8_prev_i_frm_cost = ps_rc_ctxt->ai8_cur_frm_intra_cost[i4_enc_frm_id];
4876         ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[rc_pic_type] =
4877             ps_rc_ctxt->ai8_cur_frm_intra_cost[i4_enc_frm_id];
4878     }
4879     /*for other picture types update hme cost*/
4880     else
4881     {
4882         ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[rc_pic_type] =
4883             ps_rc_ctxt->ai8_cur_frame_coarse_ME_cost[i4_enc_frm_id];
4884     }
4885 
4886     ps_rc_ctxt->i4_is_first_frame_encoded = 1;
4887 }
4888 
4889 /****************************************************************************
4890 Function Name : ihevce_rc_store_retrive_update_info
4891 Description   : for storing and retrieving the data in case of the Enc Loop Parallelism.
4892 Inputs        :
4893 Globals       :
4894 Processing    :
4895 Outputs       :
4896 Returns       :
4897 Issues        :
4898 Revision History:
4899 DD MM YYYY   Author(s)       Changes (Describe the changes made)
4900 *****************************************************************************/
4901 
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)4902 void ihevce_rc_store_retrive_update_info(
4903     void *pv_ctxt,
4904     rc_bits_sad_t *ps_rc_frame_stat,
4905     WORD32 i4_enc_frm_id_rc,
4906     WORD32 bit_rate_id,
4907     WORD32 i4_store_retrive,
4908     WORD32 *pout_buf_id,
4909     WORD32 *pi4_rc_pic_type,
4910     WORD32 *pcur_qp,
4911     void *ps_lap_out,
4912     void *ps_rc_lap_out)
4913 {
4914     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
4915     if(1 == i4_store_retrive)
4916     {
4917         memcpy(
4918             &ps_rc_ctxt->as_rc_frame_stat_store[i4_enc_frm_id_rc][bit_rate_id],
4919             ps_rc_frame_stat,
4920             sizeof(rc_bits_sad_t));
4921         memcpy(&ps_rc_ctxt->out_buf_id[i4_enc_frm_id_rc][bit_rate_id], pout_buf_id, sizeof(WORD32));
4922         memcpy(&ps_rc_ctxt->i4_pic_type[i4_enc_frm_id_rc], pi4_rc_pic_type, sizeof(WORD32));
4923         memcpy(&ps_rc_ctxt->cur_qp[i4_enc_frm_id_rc][bit_rate_id], pcur_qp, sizeof(WORD32));
4924         memcpy(
4925             &ps_rc_ctxt->as_lap_out[i4_enc_frm_id_rc],
4926             ps_lap_out,
4927             sizeof(ihevce_lap_output_params_t));
4928         memcpy(
4929             &ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc],
4930             ps_rc_lap_out,
4931             sizeof(rc_lap_out_params_t));
4932         //BUG_FIX related to the releasing of the next lap out buffers and retrieving of the data for the delayed update.
4933 
4934         {
4935             rc_lap_out_params_t *ps_rc_lap_out_next_encode;
4936             ps_rc_lap_out_next_encode =
4937                 (rc_lap_out_params_t *)((rc_lap_out_params_t *)ps_rc_lap_out)
4938                     ->ps_rc_lap_out_next_encode;
4939 
4940             if(NULL != ps_rc_lap_out_next_encode)
4941             {
4942                 ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc].i4_next_pic_type =
4943                     ps_rc_lap_out_next_encode->i4_rc_pic_type;
4944                 ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc].i4_next_scene_type =
4945                     ps_rc_lap_out_next_encode->i4_rc_scene_type;
4946             }
4947             else
4948             {
4949                 ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc].i4_next_pic_type = -1;
4950                 ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc].i4_next_scene_type = -1;
4951             }
4952 
4953             ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc].ps_rc_lap_out_next_encode =
4954                 NULL;  //RC_BUG_FIX
4955         }
4956     }
4957     else if(2 == i4_store_retrive)
4958     {
4959         memcpy(
4960             ps_rc_frame_stat,
4961             &ps_rc_ctxt->as_rc_frame_stat_store[i4_enc_frm_id_rc][bit_rate_id],
4962             sizeof(rc_bits_sad_t));
4963         memcpy(pout_buf_id, &ps_rc_ctxt->out_buf_id[i4_enc_frm_id_rc][bit_rate_id], sizeof(WORD32));
4964         memcpy(pi4_rc_pic_type, &ps_rc_ctxt->i4_pic_type[i4_enc_frm_id_rc], sizeof(WORD32));
4965         memcpy(pcur_qp, &ps_rc_ctxt->cur_qp[i4_enc_frm_id_rc][bit_rate_id], sizeof(WORD32));
4966         memcpy(
4967             ps_lap_out,
4968             &ps_rc_ctxt->as_lap_out[i4_enc_frm_id_rc],
4969             sizeof(ihevce_lap_output_params_t));
4970         memcpy(
4971             ps_rc_lap_out,
4972             &ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc],
4973             sizeof(rc_lap_out_params_t));
4974     }
4975     else
4976     {
4977         ASSERT(0);
4978     }
4979 }
4980 
4981 /*###############################################*/
4982 /******* END OF RC UPDATE FUNCTIONS **************/
4983 /*###############################################*/
4984 
4985 /*#################################################*/
4986 /******* START OF RC UTILS FUNCTIONS **************/
4987 /*#################################################*/
4988 
4989 /**
4990 ******************************************************************************
4991 *
4992 *  @brief function to account for error correction between bits rdopt estimate
4993 *           and actual entropy bit generation
4994 *
4995 *  @par   Description
4996 *
4997 *  @param[in]   pv_rc_ctxt
4998 *               void pointer to rc ctxt
4999 *  @param[in]   i4_rdopt_bits_gen_error
5000 *               WODd32 variable with error correction between rdopt and entropy bytes gen
5001 *
5002 *  @return      void
5003 *
5004 ******************************************************************************
5005 */
5006 
ihevce_rc_rdopt_entropy_bit_correct(void * pv_rc_ctxt,WORD32 i4_cur_entropy_consumption,WORD32 i4_buf_id)5007 void ihevce_rc_rdopt_entropy_bit_correct(
5008     void *pv_rc_ctxt, WORD32 i4_cur_entropy_consumption, WORD32 i4_buf_id)
5009 {
5010     rc_context_t *ps_ctxt = (rc_context_t *)pv_rc_ctxt;
5011     WORD32 i4_error;
5012     WORD32 i, count = 0;
5013     ASSERT(i4_buf_id >= 0);
5014     ps_ctxt->ai4_entropy_bit_consumption[ps_ctxt->i4_entropy_bit_count] =
5015         i4_cur_entropy_consumption;
5016     ps_ctxt->ai4_entropy_bit_consumption_buf_id[ps_ctxt->i4_entropy_bit_count] = i4_buf_id;
5017     ps_ctxt->i4_entropy_bit_count = (ps_ctxt->i4_entropy_bit_count + 1) % NUM_BUF_RDOPT_ENT_CORRECT;
5018 
5019     for(i = 0; i < NUM_BUF_RDOPT_ENT_CORRECT; i++)
5020     {
5021         if(ps_ctxt->ai4_rdopt_bit_consumption_buf_id[i] >= 0 &&
5022            (ps_ctxt->ai4_rdopt_bit_consumption_buf_id[i] ==
5023             ps_ctxt->ai4_entropy_bit_consumption_buf_id[i]))
5024         {
5025             i4_error = ps_ctxt->ai4_rdopt_bit_consumption_estimate[i] -
5026                        ps_ctxt->ai4_entropy_bit_consumption[i];
5027             //DBG_PRINTF("entropy mismatch error = %d\n",i4_error/ps_ctxt->ai4_rdopt_bit_consumption_estimate[i]);
5028             ps_ctxt->ai4_rdopt_bit_consumption_estimate[i] = -1;
5029             ps_ctxt->ai4_rdopt_bit_consumption_buf_id[i] = -1;
5030             ps_ctxt->ai4_entropy_bit_consumption[i] = -1;
5031             ps_ctxt->ai4_entropy_bit_consumption_buf_id[i] = -1;
5032             /*accumulate mismatch along with gop level bit error that is propogated to next frame*/
5033             /*error = rdopt - entropy so it is expected to be negative*/
5034             rc_update_mismatch_error(ps_ctxt->rc_hdl, i4_error);
5035             count++;
5036         }
5037     }
5038 }
5039 
5040 /**
5041 ******************************************************************************
5042 *
5043 *  @name  ihevce_rc_check_non_lap_scd
5044 *
5045 *  @par   Description Detects SCD frames as I_only_scds or non_I_scds based
5046                       on intrasatd & ME costs. Updates scd flags
5047 *
5048 *  @param[in]   ps_rc_ctxt  - pointer to rc context
5049 *               ps_rc_lap_out
5050 *  @return      void
5051 *
5052 ******************************************************************************
5053 */
ihevce_rc_check_non_lap_scd(void * pv_rc_ctxt,rc_lap_out_params_t * ps_rc_lap_out)5054 void ihevce_rc_check_non_lap_scd(void *pv_rc_ctxt, rc_lap_out_params_t *ps_rc_lap_out)
5055 {
5056     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
5057     picture_type_e rc_pic_type = ihevce_rc_conv_pic_type(
5058         (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out->i4_rc_pic_type,
5059         ps_rc_ctxt->i4_field_pic,
5060         ps_rc_lap_out->i4_rc_temporal_lyr_id,
5061         ps_rc_lap_out->i4_is_bottom_field,
5062         ps_rc_ctxt->i4_top_field_first);
5063 
5064     /*Init to normal frames*/
5065     ps_rc_lap_out->i4_is_I_only_scd = 0;
5066     ps_rc_lap_out->i4_is_non_I_scd = 0;
5067 
5068     /*None of the above check is valid if marked as scene cut*/
5069     if(ps_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_SCENE_CUT)
5070     {
5071         WORD32 i;
5072         /*reset all older data*/
5073         for(i = 0; i < MAX_PIC_TYPE; i++)
5074         {
5075             ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[i] = -1;
5076             ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_cost[i] = -1;
5077             ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_sad[i] = -1;
5078         }
5079     }
5080     else
5081     {
5082         /*Check if it is I only reset case, lap_out is assumed to have latest data which is used to set the corresponding flags*/
5083         /*For I pic check for I only reset case and for other pictures check for non-I scd case*/
5084         if(rc_pic_type == I_PIC)
5085         {
5086             if(ps_rc_lap_out->i8_pre_intra_satd <
5087                    (ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[rc_pic_type] >> 1) ||
5088                ps_rc_lap_out->i8_pre_intra_satd >
5089                    (ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[rc_pic_type] << 1))
5090             {
5091                 /*Check if atleast one frame data is available*/
5092                 if(ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[rc_pic_type] >= 0)
5093                     ps_rc_lap_out->i4_is_I_only_scd = 1;
5094             }
5095         }
5096         else if(
5097             ((rc_pic_type == P_PIC) &&
5098              (ps_rc_lap_out->i4_rc_quality_preset == IHEVCE_QUALITY_P6)) ||
5099             (ps_rc_lap_out->i4_rc_quality_preset < IHEVCE_QUALITY_P6))
5100         {
5101 #define SAD_THREASHOLD_30FPS (2.5)
5102             /*Choose threshold as 2.5 for 30 fps content and 1.75 for 60 fps. Scale accordingly for intermediate framerate*/
5103             WORD32 i4_non_simple_repeat_prev_frame_detect = 0;
5104             float sad_change_threshold =
5105                 (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*/
5106             if(sad_change_threshold < 1.5f)
5107                 sad_change_threshold = 1.5f;
5108             if(sad_change_threshold > 3.0f)
5109                 sad_change_threshold = 3.0f;
5110             ASSERT(ps_rc_lap_out->i8_raw_l1_coarse_me_sad >= 0);
5111 
5112             /*block variance computed at 4x4 level in w/4*h/4,
5113                 percent dc blks is how many block's variance are less than or equal to 16*/
5114             if(ps_rc_lap_out->i4_perc_dc_blks < 85)
5115             {
5116                 /*me sad is expected to be zero for repeat frames*/
5117                 if((ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_sad[rc_pic_type] ==
5118                     0) &&
5119                    (ps_rc_lap_out->i4_rc_temporal_lyr_id == ps_rc_ctxt->i4_max_temporal_lyr))
5120                 {
5121                     i4_non_simple_repeat_prev_frame_detect = 1;
5122                 }
5123             }
5124             if(ps_rc_lap_out->i8_frame_acc_coarse_me_cost >
5125                    (sad_change_threshold *
5126                     ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_cost[rc_pic_type]) &&
5127                (ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_cost[rc_pic_type] >= 0) &&
5128                (!i4_non_simple_repeat_prev_frame_detect))
5129             {
5130                 WORD32 one_per_pixel_sad_L1;
5131                 /*per pixel sad has to be greater than 1 to avoid repeat frames influence non-I scd detection*/
5132                 if((ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) < 4000000)
5133                 {
5134                     /*1080*/
5135                     one_per_pixel_sad_L1 =
5136                         (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) >> 2;
5137                 }
5138                 else
5139                 {
5140                     /*4k*/
5141                     one_per_pixel_sad_L1 =
5142                         (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) >> 4;
5143                 }
5144                 if(ps_rc_lap_out->i8_frame_acc_coarse_me_cost > one_per_pixel_sad_L1)
5145                 {
5146                     {
5147                         ps_rc_lap_out->i4_is_non_I_scd = 1;
5148                     }
5149                 }
5150             }
5151 
5152             if(rc_pic_type == P_PIC)
5153             {
5154                 if(ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_cost[rc_pic_type] < 0)
5155                 {
5156                     if(ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[I_PIC] > 0)
5157                     {
5158                         if(ps_rc_lap_out->i8_pre_intra_satd >
5159                            ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[I_PIC] << 1)
5160                         {
5161                             ps_rc_lap_out->i4_is_non_I_scd = 1;
5162                         }
5163                     }
5164                 }
5165             }
5166         }
5167     }
5168 
5169     /*remember the previous frame stats*/
5170     ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[rc_pic_type] =
5171         ps_rc_lap_out->i8_pre_intra_satd;  //ps_rc_lap_out->i8_pre_intra_satd;
5172     ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_cost[rc_pic_type] =
5173         ps_rc_lap_out->i8_frame_acc_coarse_me_cost;  //ps_rc_lap_out->i8_frame_acc_coarse_me_sad;
5174     ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_sad[rc_pic_type] =
5175         ps_rc_lap_out->i8_raw_l1_coarse_me_sad;
5176 }
5177 
5178 /**
5179 ******************************************************************************
5180 *
5181 *  @name  ihevce_rc_check_is_pre_enc_qp_valid
5182 *
5183 *  @par   Description  checking whether enc thread has updated qp in reverse queue
5184 *
5185 *  @param[in]   ps_rc_ctxt  - pointer to rc context
5186 *
5187 *  @return      zero on success
5188 *
5189 ******************************************************************************
5190 */
5191 /**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)5192 WORD32 ihevce_rc_check_is_pre_enc_qp_valid(void *pv_rc_ctxt, volatile WORD32 *pi4_force_end_flag)
5193 {
5194     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
5195 
5196     volatile WORD32 i4_is_qp_valid;
5197     volatile WORD32 *pi4_is_qp_valid;
5198 
5199     pi4_is_qp_valid =
5200         (volatile WORD32 *)&ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_read_index]
5201             .i4_is_qp_valid;
5202     i4_is_qp_valid = *pi4_is_qp_valid;
5203 
5204     /*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
5205     since it will suddenly get stagger between L1 and L0 worth of free buffers. It could try to start L0 even before enc has
5206     populated qp for such frames. qp = -1 is returned in such case which implies encoder should wait for qp to be pop*/
5207 
5208     while(i4_is_qp_valid == -1)
5209     {
5210         /*this rate control call is outside mutex lock to avoid deadlock. If this acquires mutex lock enc will not be able to
5211         populate qp*/
5212         i4_is_qp_valid = *pi4_is_qp_valid;
5213 
5214         if(1 == (*pi4_force_end_flag))
5215         {
5216             *pi4_is_qp_valid = 1;
5217             i4_is_qp_valid = 1;
5218         }
5219     }
5220     return 0;
5221 }
5222 
5223 /*!
5224 ******************************************************************************
5225 * \if Function name : ihevce_compute_temporal_complexity_reset_Kp_Kb
5226 *
5227 * \brief
5228 *
5229 * \param[in] *pv_ctxt -> rc context
5230 *
5231 * \return
5232 *
5233 * \author
5234 *  Ittiam
5235 *
5236 *****************************************************************************
5237 */
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)5238 void ihevce_compute_temporal_complexity_reset_Kp_Kb(
5239     rc_lap_out_params_t *ps_rc_lap_out, void *pv_rc_ctxt, WORD32 i4_Kp_Kb_reset_flag)
5240 {
5241     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
5242     rc_lap_out_params_t *ps_cur_rc_lap_out_temporal_offset,
5243         *ps_cur_rc_lap_out_temporal_offset_scd_detect;
5244     picture_type_e curr_rc_pic_type;
5245     LWORD64 i8_total_acc_coarse_me_sad = 0, i8_avg_acc_coarse_me_sad = 0;
5246     WORD8 i1_num_frames_in_Sub_GOP = 0, i = 0, i1_no_reset = 0;
5247     WORD32 i4_inter_frame_interval = rc_get_inter_frame_interval(ps_rc_ctxt->rc_hdl);
5248     WORD32 i4_frame_qp = 0, i4_temp_frame_qp = 0;
5249     WORD32 ai4_offsets[5] = { -3, -2, 2, 6, 7 };
5250     ps_cur_rc_lap_out_temporal_offset = ps_rc_lap_out;
5251     ps_cur_rc_lap_out_temporal_offset_scd_detect = ps_rc_lap_out;
5252 
5253     curr_rc_pic_type = ihevce_rc_conv_pic_type(
5254         (IV_PICTURE_CODING_TYPE_T)ps_cur_rc_lap_out_temporal_offset->i4_rc_pic_type,
5255         ps_rc_ctxt->i4_field_pic,
5256         ps_cur_rc_lap_out_temporal_offset->i4_rc_temporal_lyr_id,
5257         ps_cur_rc_lap_out_temporal_offset->i4_is_bottom_field,
5258         ps_rc_ctxt->i4_top_field_first);
5259 
5260     if(curr_rc_pic_type == I_PIC)
5261     {
5262         ps_cur_rc_lap_out_temporal_offset_scd_detect =
5263             (rc_lap_out_params_t *)ps_cur_rc_lap_out_temporal_offset->ps_rc_lap_out_next_encode;
5264         ps_cur_rc_lap_out_temporal_offset =
5265             (rc_lap_out_params_t *)ps_cur_rc_lap_out_temporal_offset->ps_rc_lap_out_next_encode;
5266 
5267         if(NULL != ps_cur_rc_lap_out_temporal_offset)
5268         {
5269             curr_rc_pic_type = ihevce_rc_conv_pic_type(
5270                 (IV_PICTURE_CODING_TYPE_T)ps_cur_rc_lap_out_temporal_offset->i4_rc_pic_type,
5271                 ps_rc_ctxt->i4_field_pic,
5272                 ps_cur_rc_lap_out_temporal_offset->i4_rc_temporal_lyr_id,
5273                 ps_cur_rc_lap_out_temporal_offset->i4_is_bottom_field,
5274                 ps_rc_ctxt->i4_top_field_first);
5275         }
5276         else
5277             return;
5278     }
5279 
5280     if(ps_cur_rc_lap_out_temporal_offset->i4_L1_qp == -1)
5281         return;
5282 
5283     if(ps_cur_rc_lap_out_temporal_offset->i4_L0_qp == -1)
5284         i4_frame_qp = ps_cur_rc_lap_out_temporal_offset->i4_L1_qp;
5285     else
5286         i4_frame_qp = ps_cur_rc_lap_out_temporal_offset->i4_L0_qp;
5287 
5288     i1_num_frames_in_Sub_GOP = 0;
5289     i = 0;
5290 
5291     i1_no_reset = 0;
5292     do
5293     {
5294         if(ps_cur_rc_lap_out_temporal_offset != NULL)
5295         {
5296             if(curr_rc_pic_type != I_PIC)
5297                 i4_temp_frame_qp =
5298                     i4_frame_qp + ps_cur_rc_lap_out_temporal_offset->i4_rc_temporal_lyr_id + 1;
5299 
5300             i4_temp_frame_qp += ai4_offsets[curr_rc_pic_type];
5301             i4_temp_frame_qp = CLIP3(i4_temp_frame_qp, 1, 51);
5302 
5303             {
5304                 if(curr_rc_pic_type != I_PIC)
5305                 {
5306                     i8_total_acc_coarse_me_sad +=
5307                         ps_cur_rc_lap_out_temporal_offset
5308                             ->ai8_frame_acc_coarse_me_sad[i4_temp_frame_qp];
5309                     i1_num_frames_in_Sub_GOP++;
5310                     i++;
5311                 }
5312                 else
5313                 {
5314                     break;
5315                 }
5316             }
5317 
5318             ps_cur_rc_lap_out_temporal_offset =
5319                 (rc_lap_out_params_t *)ps_cur_rc_lap_out_temporal_offset->ps_rc_lap_out_next_encode;
5320 
5321             if(ps_cur_rc_lap_out_temporal_offset == NULL)
5322             {
5323                 break;
5324             }
5325             curr_rc_pic_type = ihevce_rc_conv_pic_type(
5326                 (IV_PICTURE_CODING_TYPE_T)ps_cur_rc_lap_out_temporal_offset->i4_rc_pic_type,
5327                 ps_rc_ctxt->i4_field_pic,
5328                 ps_cur_rc_lap_out_temporal_offset->i4_rc_temporal_lyr_id,
5329                 ps_cur_rc_lap_out_temporal_offset->i4_is_bottom_field,
5330                 ps_rc_ctxt->i4_top_field_first);
5331         }
5332         else
5333         {
5334             i1_num_frames_in_Sub_GOP = 0;
5335             break;
5336         }
5337     } while(
5338         ((((curr_rc_pic_type != P_PIC) && ((curr_rc_pic_type != I_PIC))) ||
5339           (curr_rc_pic_type == P_PIC)) &&
5340          (i1_num_frames_in_Sub_GOP < i4_inter_frame_interval)));
5341 
5342     if((i1_num_frames_in_Sub_GOP) && (i1_no_reset == 0))
5343     {
5344         float f_hme_sad_per_pixel;
5345         i8_avg_acc_coarse_me_sad = (i8_total_acc_coarse_me_sad / i1_num_frames_in_Sub_GOP);
5346         f_hme_sad_per_pixel =
5347             ((float)i8_avg_acc_coarse_me_sad /
5348              (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width));
5349         f_hme_sad_per_pixel = CLIP3(f_hme_sad_per_pixel, 0.01f, 5.0f);
5350         /*reset the QP offsets for the next sub GOP depending on the offline model based on the temporal complexity */
5351         if(i4_Kp_Kb_reset_flag)
5352         {
5353             WORD32 i4_bin;
5354 
5355             rc_reset_Kp_Kb(
5356                 ps_rc_ctxt->rc_hdl,
5357                 8.00,
5358                 ps_rc_ctxt->i4_num_active_pic_type,
5359                 f_hme_sad_per_pixel,
5360                 &i4_bin,
5361                 ps_rc_ctxt->i4_rc_pass);
5362         }
5363         else
5364         {
5365             rc_ba_get_qp_offset_offline_data(
5366                 ps_rc_ctxt->rc_hdl,
5367                 ps_rc_lap_out->ai4_offsets,
5368                 f_hme_sad_per_pixel,
5369                 ps_rc_ctxt->i4_num_active_pic_type,
5370                 &ps_rc_lap_out->i4_complexity_bin);
5371 
5372             ps_cur_rc_lap_out_temporal_offset = ps_rc_lap_out;
5373             ps_cur_rc_lap_out_temporal_offset->i4_offsets_set_flag = 1;
5374 
5375             curr_rc_pic_type = ihevce_rc_conv_pic_type(
5376                 (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out->i4_rc_pic_type,
5377                 ps_rc_ctxt->i4_field_pic,
5378                 ps_rc_lap_out->i4_rc_temporal_lyr_id,
5379                 ps_rc_lap_out->i4_is_bottom_field,
5380                 ps_rc_ctxt->i4_top_field_first);
5381 
5382             if((curr_rc_pic_type == I_PIC) &&
5383                ((rc_lap_out_params_t *)ps_cur_rc_lap_out_temporal_offset->ps_rc_lap_out_next_encode)
5384                        ->i4_rc_pic_type == P_PIC)
5385                 i1_num_frames_in_Sub_GOP++;
5386 
5387             for(i = 1; i < i1_num_frames_in_Sub_GOP; i++)
5388             {
5389                 ps_cur_rc_lap_out_temporal_offset =
5390                     (rc_lap_out_params_t *)
5391                         ps_cur_rc_lap_out_temporal_offset->ps_rc_lap_out_next_encode;
5392                 memmove(
5393                     ps_cur_rc_lap_out_temporal_offset->ai4_offsets,
5394                     ps_rc_lap_out->ai4_offsets,
5395                     sizeof(WORD32) * 5);
5396                 ps_cur_rc_lap_out_temporal_offset->i4_complexity_bin =
5397                     ps_rc_lap_out->i4_complexity_bin;
5398                 ps_cur_rc_lap_out_temporal_offset->i4_offsets_set_flag = 1;
5399             }
5400         }
5401     }
5402 }
5403 
5404 /**
5405 ******************************************************************************
5406 *
5407 *  @brief function to get delta QP or In frame RC bits estimate to avoid buffer underflow
5408 *
5409 *  @par   Description
5410 *  @param[in]
5411 ******************************************************************************
5412 */
5413 
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)5414 WORD32 ihevce_ebf_based_rc_correction_to_avoid_overflow(
5415     rc_context_t *ps_rc_ctxt, rc_lap_out_params_t *ps_rc_lap_out, WORD32 *pi4_tot_bits_estimated)
5416 {
5417     WORD32 i4_modelQP, i4_clipQP, i4_maxEbfQP, i4_diffQP, i4_is_model_valid, i4_deltaQP = 0;
5418     LWORD64 i8_bitsClipQP, i8_grwEbf;  // i8_bitsComp;
5419     WORD32 i4_is_offline_model_used;
5420     WORD32 i4_vbv_buffer_size, i4_drain_rate, i4_currEbf, i4_maxEbf;
5421     WORD32 i4_case = -1;
5422     float f_thrsh_i_pic_delta_qp_1, f_thrsh_i_pic_delta_qp_2, f_thrsh_p_pic_delta_qp_1,
5423         f_thrsh_p_pic_delta_qp_2;
5424     float f_thrsh_br_pic_delta_qp_1, f_thrsh_br_pic_delta_qp_2, f_thrsh_bnr_pic_delta_qp_1,
5425         f_thrsh_bnr_pic_delta_qp_2;
5426     float f_vbv_thrsh_delta_qp;
5427 
5428     /*initialization of all the variables*/
5429     rc_init_buffer_info(
5430         ps_rc_ctxt->rc_hdl, &i4_vbv_buffer_size, &i4_currEbf, &i4_maxEbf, &i4_drain_rate);
5431 
5432     i4_is_model_valid = ps_rc_lap_out->i4_is_model_valid;
5433     i4_modelQP = ps_rc_ctxt->s_rc_high_lvl_stat.i4_modelQP;
5434     i4_clipQP = ps_rc_ctxt->s_rc_high_lvl_stat.i4_finalQP;
5435     i4_maxEbfQP = ps_rc_ctxt->s_rc_high_lvl_stat.i4_maxEbfQP;
5436     i8_bitsClipQP = ps_rc_ctxt->s_rc_high_lvl_stat.i8_bits_from_finalQP;
5437     i4_is_offline_model_used = ps_rc_ctxt->s_rc_high_lvl_stat.i4_is_offline_model_used;
5438     ASSERT(i4_clipQP != INVALID_QP);
5439 
5440     if(ps_rc_ctxt->i4_num_frame_parallel > 1)
5441     {
5442         f_thrsh_i_pic_delta_qp_1 = (float)VBV_THRSH_FRM_PRLL_I_PIC_DELTA_QP_1;
5443         f_thrsh_i_pic_delta_qp_2 = (float)VBV_THRSH_FRM_PRLL_I_PIC_DELTA_QP_2;
5444         f_thrsh_p_pic_delta_qp_1 = (float)VBV_THRSH_FRM_PRLL_P_PIC_DELTA_QP_1;
5445         f_thrsh_p_pic_delta_qp_2 = (float)VBV_THRSH_FRM_PRLL_P_PIC_DELTA_QP_2;
5446         f_thrsh_br_pic_delta_qp_1 = (float)VBV_THRSH_FRM_PRLL_BR_PIC_DELTA_QP_1;
5447         f_thrsh_br_pic_delta_qp_2 = (float)VBV_THRSH_FRM_PRLL_BR_PIC_DELTA_QP_2;
5448         f_thrsh_bnr_pic_delta_qp_1 = (float)VBV_THRSH_FRM_PRLL_BNR_PIC_DELTA_QP_1;
5449         f_thrsh_bnr_pic_delta_qp_2 = (float)VBV_THRSH_FRM_PRLL_BNR_PIC_DELTA_QP_2;
5450         f_vbv_thrsh_delta_qp = (float)VBV_THRSH_FRM_PRLL_DELTA_QP;
5451     }
5452     else
5453     {
5454         f_thrsh_i_pic_delta_qp_1 = (float)VBV_THRSH_I_PIC_DELTA_QP_1;
5455         f_thrsh_i_pic_delta_qp_2 = (float)VBV_THRSH_I_PIC_DELTA_QP_2;
5456         f_thrsh_p_pic_delta_qp_1 = (float)VBV_THRSH_P_PIC_DELTA_QP_1;
5457         f_thrsh_p_pic_delta_qp_2 = (float)VBV_THRSH_P_PIC_DELTA_QP_2;
5458         f_thrsh_br_pic_delta_qp_1 = (float)VBV_THRSH_BR_PIC_DELTA_QP_1;
5459         f_thrsh_br_pic_delta_qp_2 = (float)VBV_THRSH_BR_PIC_DELTA_QP_2;
5460         f_thrsh_bnr_pic_delta_qp_1 = (float)VBV_THRSH_BNR_PIC_DELTA_QP_1;
5461         f_thrsh_bnr_pic_delta_qp_2 = (float)VBV_THRSH_BNR_PIC_DELTA_QP_2;
5462         f_vbv_thrsh_delta_qp = (float)VBV_THRSH_DELTA_QP;
5463     }
5464 
5465     /* function logic starts */
5466     if(i4_is_model_valid)
5467     {
5468         ASSERT(i4_modelQP != INVALID_QP);
5469         i8_grwEbf = i8_bitsClipQP - (LWORD64)i4_drain_rate;
5470         if(((i4_currEbf + i8_grwEbf) > (0.6*i4_vbv_buffer_size)) /*&&
5471                  i4_modelQP >= i4_clipQP*/)
5472         {
5473             /* part of existing scene (i.e. no new scene)
5474             In which case this is not first I/P/Bref/Bnref etc
5475             The models for I/P/Bref/Bnref are all valid*/
5476             if(((i4_currEbf + i8_grwEbf) <
5477                 i4_maxEbf)) /* does not matter whether this is 2pass, 1 pass, VBR, CBR etc*/
5478             {
5479                 /* clipQP has been determined keeping in view certain other quality constraints like pusling etc.
5480                 So better to honour it if possible*/
5481                 //if (i8_bitsClipQP > i8_drain_rate)
5482                 {
5483                     LWORD64 i8_thrsh_for_deltaQP_2 = i4_vbv_buffer_size,
5484                             i8_thrsh_for_deltaQP_1 = i4_vbv_buffer_size;
5485                     /*even when (modelQP - clipQP) = 0, we intend to QP increase as expected ebf is above 60%*/
5486                     i4_diffQP = MAX(i4_modelQP - i4_clipQP, 1);
5487                     switch(ps_rc_lap_out->i4_rc_pic_type)
5488                     {
5489                     case IV_I_FRAME:
5490                     case IV_IDR_FRAME:
5491                     {
5492                         i8_thrsh_for_deltaQP_1 =
5493                             (LWORD64)(f_thrsh_i_pic_delta_qp_1 * i4_vbv_buffer_size);
5494                         i8_thrsh_for_deltaQP_2 =
5495                             (LWORD64)(f_thrsh_i_pic_delta_qp_2 * i4_vbv_buffer_size);
5496                         break;
5497                     }
5498                     case IV_P_FRAME:
5499                     {
5500                         i8_thrsh_for_deltaQP_1 =
5501                             (LWORD64)(f_thrsh_p_pic_delta_qp_1 * i4_vbv_buffer_size);
5502                         i8_thrsh_for_deltaQP_2 =
5503                             (LWORD64)(f_thrsh_p_pic_delta_qp_2 * i4_vbv_buffer_size);
5504                         break;
5505                     }
5506                     case IV_B_FRAME:
5507                     {
5508                         if(ps_rc_lap_out->i4_rc_is_ref_pic)
5509                         {
5510                             i8_thrsh_for_deltaQP_1 =
5511                                 (LWORD64)(f_thrsh_br_pic_delta_qp_1 * i4_vbv_buffer_size);
5512                             i8_thrsh_for_deltaQP_2 =
5513                                 (LWORD64)(f_thrsh_br_pic_delta_qp_2 * i4_vbv_buffer_size);
5514                         }
5515                         else
5516                         {
5517                             /*as of now using the same thresholds as B reference, later may have to tune if required*/
5518                             i8_thrsh_for_deltaQP_1 =
5519                                 (LWORD64)(f_thrsh_bnr_pic_delta_qp_1 * i4_vbv_buffer_size);
5520                             i8_thrsh_for_deltaQP_2 =
5521                                 (LWORD64)(f_thrsh_bnr_pic_delta_qp_2 * i4_vbv_buffer_size);
5522                         }
5523                         break;
5524                     }
5525                     default:
5526                         break;
5527                     }
5528 
5529                     if((i4_currEbf + i8_grwEbf) > i8_thrsh_for_deltaQP_1)
5530                     {
5531                         /*For more than 2 QP chnage this means a larger scale issue and probably needs to be handled elsewhere ?*/
5532                         i4_deltaQP =
5533                             MIN(2, i4_diffQP); /* we dont intend to change QP by more than 2 */
5534                         i4_case = 0;
5535                     }
5536                     else if((i4_currEbf + i8_grwEbf) > i8_thrsh_for_deltaQP_2)
5537                     {
5538                         i4_deltaQP = MIN(1, i4_diffQP);
5539                         i4_case = 1;
5540                     }
5541                 }
5542                 /* else  if (i8_bitsClipQP > i8_drain_rate)
5543         {
5544                 we have no correection, buffer will be healthy after this.
5545                 However, there could be one problem if the currEbf is already close to say 80% of EBF.
5546                 This means we have not reacted well early - needs to be handled?
5547 
5548                 This could be the case where it is a simple scene immediately following a complex scene
5549                 and is the I picture (not the first I since model is valid).
5550                 Is this possible - maybe, what to do - dont know?
5551         }
5552                 */
5553             }
5554             else /*(i4_clipQP < i4_maxEbfQP)*/
5555             {
5556                 i4_deltaQP = 2;
5557                 i4_case = 2;
5558             }
5559         }
5560         if((i4_currEbf + i8_grwEbf) < (0.6 * i4_vbv_buffer_size))
5561         {
5562             *pi4_tot_bits_estimated = i8_bitsClipQP;
5563         }
5564     }
5565     else
5566     {
5567         if(i4_is_offline_model_used)
5568         {
5569             /* this can be only for non-I SCD, where we reset RC */
5570             WORD32 i4_bits_est_for_in_frm_rc = *pi4_tot_bits_estimated;
5571             i8_grwEbf = i4_bits_est_for_in_frm_rc - i4_drain_rate;
5572             if((i4_currEbf + i8_grwEbf) > (f_vbv_thrsh_delta_qp * i4_vbv_buffer_size))
5573             {
5574                 i4_bits_est_for_in_frm_rc =
5575                     i4_drain_rate + (WORD32)(0.85 * i4_vbv_buffer_size) - i4_currEbf;
5576                 /* 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 */
5577                 /* this needs a reaction */
5578                 if(i4_bits_est_for_in_frm_rc < i4_drain_rate)
5579                 {
5580                     *pi4_tot_bits_estimated =
5581                         MAX((i4_drain_rate + (WORD32)(0.95 * i4_vbv_buffer_size) - i4_currEbf),
5582                             i4_drain_rate);
5583                     i4_deltaQP = 2; /* this needs some review, needs to be handled well */
5584                 }
5585             }
5586             i4_case = 3;
5587         }
5588         else
5589         {
5590             i8_bitsClipQP = *pi4_tot_bits_estimated;
5591             i8_grwEbf = i8_bitsClipQP - i4_drain_rate;
5592 
5593             if(((i4_currEbf + i8_grwEbf) <
5594                 i4_maxEbf)) /* does not matter whether this is 2pass, 1 pass, VBR, CBR etc*/
5595             {
5596                 /* clipQP has been determined keeping in view certain other quality constraints like pusling etc.
5597                     So better to honour it if possible*/
5598                 //if (i8_bitsClipQP > i8_drain_rate)
5599                 {
5600                     LWORD64 i8_thrsh_for_deltaQP_2 = i4_vbv_buffer_size,
5601                             i8_thrsh_for_deltaQP_1 = i4_vbv_buffer_size;
5602 
5603                     switch(ps_rc_lap_out->i4_rc_pic_type)
5604                     {
5605                     case IV_I_FRAME:
5606                     case IV_IDR_FRAME:
5607                     {
5608                         i8_thrsh_for_deltaQP_1 =
5609                             (LWORD64)(f_thrsh_i_pic_delta_qp_1 * i4_vbv_buffer_size);
5610                         i8_thrsh_for_deltaQP_2 =
5611                             (LWORD64)(f_thrsh_i_pic_delta_qp_2 * i4_vbv_buffer_size);
5612                         break;
5613                     }
5614                     case IV_P_FRAME:
5615                     {
5616                         i8_thrsh_for_deltaQP_1 =
5617                             (LWORD64)(f_thrsh_p_pic_delta_qp_1 * i4_vbv_buffer_size);
5618                         i8_thrsh_for_deltaQP_2 =
5619                             (LWORD64)(f_thrsh_p_pic_delta_qp_2 * i4_vbv_buffer_size);
5620                         break;
5621                     }
5622                     case IV_B_FRAME:
5623                     {
5624                         if(ps_rc_lap_out->i4_rc_is_ref_pic)
5625                         {
5626                             i8_thrsh_for_deltaQP_1 =
5627                                 (LWORD64)(f_thrsh_br_pic_delta_qp_1 * i4_vbv_buffer_size);
5628                             i8_thrsh_for_deltaQP_2 =
5629                                 (LWORD64)(f_thrsh_br_pic_delta_qp_2 * i4_vbv_buffer_size);
5630                         }
5631                         else
5632                         {
5633                             /*as of now using the same thresholds as B reference, later may have to tune if required*/
5634                             i8_thrsh_for_deltaQP_1 =
5635                                 (LWORD64)(f_thrsh_bnr_pic_delta_qp_1 * i4_vbv_buffer_size);
5636                             i8_thrsh_for_deltaQP_2 =
5637                                 (LWORD64)(f_thrsh_bnr_pic_delta_qp_2 * i4_vbv_buffer_size);
5638                         }
5639                         break;
5640                     }
5641                     default:
5642                         break;
5643                     }
5644 
5645                     if((i4_currEbf + i8_grwEbf) > i8_thrsh_for_deltaQP_1)
5646                     {
5647                         /*For more than 2 QP chnage this means a larger scale issue and probably needs to be handled elsewhere ?*/
5648                         i4_deltaQP = 2; /* we dont intend to change QP by more than 2 */
5649                         i4_case = 5;
5650                     }
5651                     else if((i4_currEbf + i8_grwEbf) > i8_thrsh_for_deltaQP_2)
5652                     {
5653                         i4_deltaQP = 1;
5654                         i4_case = 6;
5655                     }
5656                 }
5657             }
5658             else
5659             {
5660                 i4_deltaQP = 2;
5661                 i4_case = 7;
5662             }
5663         }
5664     }
5665     return i4_deltaQP;
5666 }
5667 
5668 /*###############################################*/
5669 /******* END OF RC UTILS FUNCTIONS ***************/
5670 /*###############################################*/
5671 
5672 /*########################################################*/
5673 /******* START OF VBV COMPLIANCE FUNCTIONS ***************/
5674 /*#######################################################*/
5675 
5676 /*!
5677 ******************************************************************************
5678 * \if Function name : ihevce_vbv_compliance_frame_level_update
5679 *
5680 * \brief
5681 *    this function initializes the hrd buffer level to be used for vbv compliance testing using the parameters feeded in VUI parameters
5682 *
5683 * \param[in] *pv_ctxt -> rc context
5684 *           i4_bits_generated -> bits generated from entropy
5685 *           i4_resolution_id -> info needed for log Dump
5686 *           i4_appln_bitrate_inst -> info needed for log Dump
5687 *           u4_cur_cpb_removal_delay_minus1 -> cbp removal delay of present frame
5688 * \return
5689 *
5690 * \author
5691 *  Ittiam
5692 *
5693 *****************************************************************************
5694 */
5695 
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)5696 void ihevce_vbv_compliance_frame_level_update(
5697     void *pv_rc_ctxt,
5698     WORD32 i4_bits_generated,
5699     WORD32 i4_resolution_id,
5700     WORD32 i4_appln_bitrate_inst,
5701     UWORD32 u4_cur_cpb_removal_delay_minus1)
5702 {
5703     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
5704     float f_max_vbv_buff_size = (float)ps_rc_ctxt->s_vbv_compliance.f_buffer_size;
5705     WORD32 i4_cbp_removal_delay_diff = 1;
5706 
5707     if((ps_rc_ctxt->s_vbv_compliance.u4_prev_cpb_removal_delay_minus1 > 0) &&
5708        (u4_cur_cpb_removal_delay_minus1 >
5709         ps_rc_ctxt->s_vbv_compliance.u4_prev_cpb_removal_delay_minus1))
5710         i4_cbp_removal_delay_diff =
5711             (u4_cur_cpb_removal_delay_minus1 -
5712              ps_rc_ctxt->s_vbv_compliance.u4_prev_cpb_removal_delay_minus1);
5713 
5714     ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level =
5715         ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level - (float)i4_bits_generated +
5716         (i4_cbp_removal_delay_diff * ps_rc_ctxt->s_vbv_compliance.f_drain_rate);
5717 
5718     ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip =
5719         ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level;
5720 
5721     if(ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level < 0)
5722     {
5723         ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level = 0;
5724     }
5725 
5726     if(ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level >
5727        ps_rc_ctxt->s_vbv_compliance.f_buffer_size)
5728     {
5729         ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level =
5730             ps_rc_ctxt->s_vbv_compliance.f_buffer_size;
5731         ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip -=
5732             ps_rc_ctxt->s_vbv_compliance.f_buffer_size;
5733     }
5734     else if(ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip > 0)
5735     {
5736         ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip = 0;
5737     }
5738 
5739     if(ps_rc_ctxt->e_rate_control_type == VBR_STREAMING)
5740     {
5741         if(ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip > 0)
5742             ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip = 0;
5743     }
5744     ps_rc_ctxt->s_vbv_compliance.u4_prev_cpb_removal_delay_minus1 = u4_cur_cpb_removal_delay_minus1;
5745 }
5746 
5747 /*!
5748 ******************************************************************************
5749 * \if Function name : ihevce_vbv_complaince_init_level
5750 *
5751 * \brief
5752 *    this function initializes the hrd buffer level to be used for vbv compliance testing using the parameters feeded in VUI parameters
5753 *
5754 * \param[in] *pv_ctxt -> rc context
5755 *            *ps_vui      -> VUI parameters
5756 * \return
5757 *
5758 * \author
5759 *  Ittiam
5760 *
5761 *****************************************************************************
5762 */
5763 
ihevce_vbv_complaince_init_level(void * pv_ctxt,vui_t * ps_vui)5764 void ihevce_vbv_complaince_init_level(void *pv_ctxt, vui_t *ps_vui)
5765 {
5766     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
5767 
5768     ps_rc_ctxt->s_vbv_compliance.f_frame_rate =
5769         (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);
5770 
5771     if(1 == ps_vui->s_vui_hrd_parameters.u1_sub_pic_cpb_params_present_flag)
5772     {
5773         ASSERT(1 == ps_vui->s_vui_hrd_parameters.u1_sub_pic_cpb_params_present_flag);
5774 
5775         ps_rc_ctxt->s_vbv_compliance.f_bit_rate = (float)((
5776             (ps_vui->s_vui_hrd_parameters.as_sub_layer_hrd_params[0].au4_bit_rate_du_value_minus1[0] +
5777              1)
5778             << (6 + ps_vui->s_vui_hrd_parameters
5779                         .u4_bit_rate_scale)));  //rc_get_bit_rate(ps_rc_ctxt->rc_hdl);
5780 
5781         ps_rc_ctxt->s_vbv_compliance.f_buffer_size = (float)((
5782             (ps_vui->s_vui_hrd_parameters.as_sub_layer_hrd_params[0].au4_cpb_size_du_value_minus1[0] +
5783              1)
5784             << (4 + ps_vui->s_vui_hrd_parameters
5785                         .u4_cpb_size_du_scale)));  //ps_rc_ctxt->u4_max_vbv_buff_size;
5786     }
5787     else
5788     {
5789         ps_rc_ctxt->s_vbv_compliance.f_bit_rate = (float)((
5790             (ps_vui->s_vui_hrd_parameters.as_sub_layer_hrd_params[0].au4_bit_rate_value_minus1[0] +
5791              1)
5792             << (6 + ps_vui->s_vui_hrd_parameters
5793                         .u4_bit_rate_scale)));  //rc_get_bit_rate(ps_rc_ctxt->rc_hdl);
5794 
5795         ps_rc_ctxt->s_vbv_compliance.f_buffer_size = (float)((
5796             (ps_vui->s_vui_hrd_parameters.as_sub_layer_hrd_params[0].au4_cpb_size_value_minus1[0] +
5797              1)
5798             << (4 + ps_vui->s_vui_hrd_parameters
5799                         .u4_cpb_size_scale)));  //ps_rc_ctxt->u4_max_vbv_buff_size;
5800     }
5801     ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level =
5802         (float)ps_rc_ctxt->s_vbv_compliance.f_buffer_size;  //ps_rc_ctxt->u4_max_vbv_buff_size;
5803 
5804     ps_rc_ctxt->s_vbv_compliance.f_drain_rate =
5805         ((ps_rc_ctxt->s_vbv_compliance.f_bit_rate) / ps_rc_ctxt->s_vbv_compliance.f_frame_rate);
5806 
5807     ps_rc_ctxt->s_vbv_compliance.u4_prev_cpb_removal_delay_minus1 = 0;
5808 }
5809 
5810 /*########################################################*/
5811 /******* END OF VBV COMPLIANCE FUNCTIONS *****************/
5812 /*#######################################################*/
5813 
5814 /*################################################################*/
5815 /******* START OF DYN CHANGE iN BITRATE FUNCTIONS *****************/
5816 /*################################################################*/
5817 /*!
5818 ******************************************************************************
5819 * \if Function name : change_bitrate_vbv_complaince
5820 *
5821 * \brief
5822 *    this function updates the new bitrate and re calculates the drain rate
5823 *
5824 * \param[in] *pv_ctxt -> rc context
5825 * \return
5826 *
5827 * \author
5828 *  Ittiam
5829 *
5830 *****************************************************************************
5831 */
change_bitrate_vbv_complaince(void * pv_ctxt,LWORD64 i8_new_bitrate,LWORD64 i8_buffer_size)5832 void change_bitrate_vbv_complaince(void *pv_ctxt, LWORD64 i8_new_bitrate, LWORD64 i8_buffer_size)
5833 {
5834     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
5835     ps_rc_ctxt->s_vbv_compliance.f_buffer_size = (float)i8_buffer_size;
5836     ps_rc_ctxt->s_vbv_compliance.f_bit_rate = (float)i8_new_bitrate;
5837     if(ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level > i8_buffer_size)
5838         ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level = (float)i8_buffer_size;
5839     ps_rc_ctxt->s_vbv_compliance.f_drain_rate =
5840         ps_rc_ctxt->s_vbv_compliance.f_bit_rate / ps_rc_ctxt->s_vbv_compliance.f_frame_rate;
5841 }
5842 /*!
5843 ******************************************************************************
5844 * \if Function name : ihevce_rc_register_dyn_change_bitrate
5845 *
5846 * \brief
5847 *    this function registers call to change bitrate dynamically.
5848 *
5849 * \param[in] *pv_ctxt -> rc context
5850 *
5851 * \return
5852 *
5853 * \author
5854 *  Ittiam
5855 *
5856 *****************************************************************************
5857 */
5858 
ihevce_rc_register_dyn_change_bitrate(void * pv_ctxt,LWORD64 i8_new_bitrate,LWORD64 i8_new_peak_bitrate,WORD32 i4_new_rate_factor,WORD32 i4_rate_control_mode)5859 void ihevce_rc_register_dyn_change_bitrate(
5860     void *pv_ctxt,
5861     LWORD64 i8_new_bitrate,
5862     LWORD64 i8_new_peak_bitrate,
5863     WORD32 i4_new_rate_factor,
5864     WORD32 i4_rate_control_mode)
5865 {
5866     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
5867 
5868     /*Register new bitrate*/
5869     if(1 != i4_rate_control_mode)
5870     {
5871         if(i8_new_bitrate != -1)
5872         {
5873             ps_rc_ctxt->i8_new_bitrate = i8_new_bitrate;
5874             ps_rc_ctxt->i8_new_peak_bitrate = i8_new_peak_bitrate;
5875             ps_rc_ctxt->i4_bitrate_changed = 1;
5876         }
5877     }
5878     else
5879     {
5880         if(i4_new_rate_factor != -1)
5881         {
5882             ps_rc_ctxt->i8_new_bitrate = (i8_new_peak_bitrate * i4_new_rate_factor) / 1000;
5883             ps_rc_ctxt->i8_new_peak_bitrate = i8_new_peak_bitrate;
5884             ps_rc_ctxt->i4_bitrate_changed = 1;
5885         }
5886     }
5887 
5888     ASSERT(ps_rc_ctxt->i8_new_bitrate > 0);
5889     ASSERT(ps_rc_ctxt->i8_new_peak_bitrate > 0);
5890 }
5891 
5892 /*!
5893 ******************************************************************************
5894 * \if Function name : ihevce_rc_get_new_bitrate
5895 *
5896 * \brief
5897 *    get new bitrate
5898 *
5899 * \param[in] *pv_ctxt -> rc context
5900 *
5901 * \return
5902 *
5903 * \author
5904 *  Ittiam
5905 *
5906 *****************************************************************************
5907 */
ihevce_rc_get_new_bitrate(void * pv_ctxt)5908 LWORD64 ihevce_rc_get_new_bitrate(void *pv_ctxt)
5909 {
5910     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
5911     return ps_rc_ctxt->i8_new_bitrate;
5912 }
5913 /*!
5914 ******************************************************************************
5915 * \if Function name : ihevce_rc_get_new_peak_bitrate
5916 *
5917 * \brief
5918 *    get new peak rate
5919 *
5920 * \param[in] *pv_ctxt -> rc context
5921 *
5922 * \return
5923 *
5924 * \author
5925 *  Ittiam
5926 *
5927 *****************************************************************************
5928 */
ihevce_rc_get_new_peak_bitrate(void * pv_ctxt)5929 LWORD64 ihevce_rc_get_new_peak_bitrate(void *pv_ctxt)
5930 {
5931     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
5932     return ps_rc_ctxt->i8_new_peak_bitrate;
5933 }
5934 
5935 /*!
5936 ******************************************************************************
5937 * \if Function name : ihevce_rc_change_avg_bitrate
5938 *
5939 * \brief
5940 *    change average bitrate configured based on new bitrate
5941 *
5942 * \param[in] *pv_ctxt -> rc context
5943 *
5944 * \return
5945 *
5946 * \author
5947 *  Ittiam
5948 *
5949 *****************************************************************************
5950 */
ihevce_rc_change_avg_bitrate(void * pv_ctxt)5951 LWORD64 ihevce_rc_change_avg_bitrate(void *pv_ctxt)
5952 {
5953     rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
5954     LWORD64 vbv_buffer_level_b4_change;
5955 
5956     ASSERT(ps_rc_ctxt->i8_new_bitrate != -1);
5957     ASSERT(ps_rc_ctxt->i8_new_peak_bitrate != -1);
5958     /*Get the VBV buffer level just before forcing bitrate change*/
5959     vbv_buffer_level_b4_change = (LWORD64)rc_get_ebf(ps_rc_ctxt->rc_hdl);
5960 
5961     change_avg_bit_rate(
5962         ps_rc_ctxt->rc_hdl,
5963         (UWORD32)ps_rc_ctxt->i8_new_bitrate,
5964         (UWORD32)ps_rc_ctxt->i8_new_peak_bitrate);
5965     /*Once the request is serviced set new bitrate to -1*/
5966     ps_rc_ctxt->i8_new_bitrate = -1;
5967     ps_rc_ctxt->i8_new_peak_bitrate = -1;
5968     return vbv_buffer_level_b4_change;
5969 }
5970 
5971 /*##############################################################*/
5972 /******* END OF DYN CHNAGE iN BITRATE FUNCTIONS *****************/
5973 /*##############################################################*/
5974