• 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_frame_process.c
24 *
25 * \brief
26 *    This file contains top level functions related Frame processing
27 *
28 * \date
29 *    18/09/2012
30 *
31 * \author
32 *    Ittiam
33 *
34 *
35 * List of Functions
36 *
37 *
38 ******************************************************************************
39 */
40 
41 /*****************************************************************************/
42 /* File Includes                                                             */
43 /*****************************************************************************/
44 /* System include files */
45 #include <stdio.h>
46 #include <string.h>
47 #include <stdlib.h>
48 #include <assert.h>
49 #include <stdarg.h>
50 #include <math.h>
51 #include <time.h>
52 
53 /* User include files */
54 #include "ihevc_typedefs.h"
55 #include "itt_video_api.h"
56 #include "ihevce_api.h"
57 
58 #include "rc_cntrl_param.h"
59 #include "rc_frame_info_collector.h"
60 #include "rc_look_ahead_params.h"
61 
62 #include "ihevc_defs.h"
63 #include "ihevc_debug.h"
64 #include "ihevc_macros.h"
65 #include "ihevc_structs.h"
66 #include "ihevc_platform_macros.h"
67 #include "ihevc_deblk.h"
68 #include "ihevc_itrans_recon.h"
69 #include "ihevc_chroma_itrans_recon.h"
70 #include "ihevc_chroma_intra_pred.h"
71 #include "ihevc_intra_pred.h"
72 #include "ihevc_inter_pred.h"
73 #include "ihevc_mem_fns.h"
74 #include "ihevc_padding.h"
75 #include "ihevc_weighted_pred.h"
76 #include "ihevc_sao.h"
77 #include "ihevc_resi_trans.h"
78 #include "ihevc_quant_iquant_ssd.h"
79 #include "ihevc_cabac_tables.h"
80 #include "ihevc_common_tables.h"
81 
82 #include "ihevce_defs.h"
83 #include "ihevce_buffer_que_interface.h"
84 #include "ihevce_hle_interface.h"
85 #include "ihevce_hle_q_func.h"
86 #include "ihevce_lap_enc_structs.h"
87 #include "ihevce_lap_interface.h"
88 #include "ihevce_multi_thrd_structs.h"
89 #include "ihevce_multi_thrd_funcs.h"
90 #include "ihevce_me_common_defs.h"
91 #include "ihevce_had_satd.h"
92 #include "ihevce_error_checks.h"
93 #include "ihevce_error_codes.h"
94 #include "ihevce_bitstream.h"
95 #include "ihevce_cabac.h"
96 #include "ihevce_rdoq_macros.h"
97 #include "ihevce_function_selector.h"
98 #include "ihevce_enc_structs.h"
99 #include "ihevce_global_tables.h"
100 #include "ihevce_cmn_utils_instr_set_router.h"
101 #include "ihevce_ipe_instr_set_router.h"
102 #include "ihevce_entropy_structs.h"
103 #include "ihevce_enc_loop_structs.h"
104 #include "ihevce_enc_loop_utils.h"
105 #include "ihevce_inter_pred.h"
106 #include "ihevce_common_utils.h"
107 #include "ihevce_sub_pic_rc.h"
108 #include "hme_datatype.h"
109 #include "hme_interface.h"
110 #include "hme_common_defs.h"
111 #include "hme_defs.h"
112 #include "ihevce_enc_loop_pass.h"
113 #include "ihevce_trace.h"
114 #include "ihevce_encode_header.h"
115 #include "ihevce_encode_header_sei_vui.h"
116 #include "ihevce_ipe_structs.h"
117 #include "ihevce_ipe_pass.h"
118 #include "ihevce_dep_mngr_interface.h"
119 #include "ihevce_rc_enc_structs.h"
120 #include "hme_globals.h"
121 #include "ihevce_me_pass.h"
122 #include "ihevce_coarse_me_pass.h"
123 #include "ihevce_frame_process.h"
124 #include "ihevce_rc_interface.h"
125 #include "ihevce_profile.h"
126 #include "ihevce_decomp_pre_intra_structs.h"
127 #include "ihevce_decomp_pre_intra_pass.h"
128 #include "ihevce_frame_process_utils.h"
129 
130 #include "cast_types.h"
131 #include "osal.h"
132 #include "osal_defaults.h"
133 
134 /*****************************************************************************/
135 /* Constant Macros                                                           */
136 /*****************************************************************************/
137 
138 #define REF_MOD_STRENGTH 1.0
139 #define REF_MAX_STRENGTH 1.4f
140 
141 /*****************************************************************************/
142 /* Extern variables                                                          */
143 /*****************************************************************************/
144 
145 /**
146 * @var   QP2QUANT_MD[]
147 *
148 * @brief Direct Cost Comoparision Table
149 *
150 * @param Comments: Direct cost is compared with 16 * QP2QUANT_MD[Qp]
151 *                  If direct cost is less  than 16 * QP2QUANT_MD[Qp]
152 *                  than direct cost is assumed to be zero
153 */
154 const WORD16 QP2QUANT_MD[52] = { 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
155                                  1,  1,  1,  2,  2,  2,  2,  3,  3,  3,  4,  4,  4,
156                                  5,  6,  6,  7,  8,  9,  10, 11, 13, 14, 16, 18, 20,
157                                  23, 25, 29, 32, 36, 40, 45, 51, 57, 64, 72, 81, 91 };
158 
159 /*
160 Gaussian 11x11 window with a sigma of 1.5 - values multiplied by 2048
161 Window made into 9x9 window as most entries were zero
162 The center weight has been reduced by 1 after dropping first row/col and last row/col
163 */
164 UWORD8 g_u1_win_size = 9;
165 UWORD8 g_u1_win_q_shift = 11;
166 UWORD8 au1_g_win[81] = { 0,  1,  2, 3,  4,  3,   2,   1,   0,  1,  3, 8,  16, 20, 16,  8,   3,
167                          1,  2,  8, 24, 48, 60,  48,  24,  8,  2,  3, 16, 48, 93, 116, 93,  48,
168                          16, 3,  4, 20, 60, 116, 144, 116, 60, 20, 4, 3,  16, 48, 93,  116, 93,
169                          48, 16, 3, 2,  8,  24,  48,  60,  48, 24, 8, 2,  1,  3,  8,   16,  20,
170                          16, 8,  3, 1,  0,  1,   2,   3,   4,  3,  2, 1,  0 };
171 
172 /* lagrange params */
173 const double lamda_modifier_for_I_pic[8] = { 0.85,   0.7471, 0.6646, 0.5913,
174                                              0.5261, 0.4680, 0.4164, 0.3705 };
175 
176 /*****************************************************************************/
177 /* Function Definitions                                                      */
178 /*****************************************************************************/
179 
180 /*!
181 ******************************************************************************
182 * \if Function name : ihevce_mbr_quality_tool_set_configuration \endif
183 *
184 * \brief
185 *   tool set selection for auxilary bitrate. currently only num intra and inter
186 *       candidates for auxilary bitrates are controlled
187 *
188 * \param[in] ps_enc_loop_thrd_ctxt : enc ctxt
189 * \param[in] ps_stat_prms: static parameters
190 * \return
191 *    None
192 *
193 * \author
194 *  Ittiam
195 *
196 *****************************************************************************
197 */
ihevce_mbr_quality_tool_set_configuration(ihevce_enc_loop_ctxt_t * ps_enc_loop_thrd_ctxt,ihevce_static_cfg_params_t * ps_stat_prms)198 void ihevce_mbr_quality_tool_set_configuration(
199     ihevce_enc_loop_ctxt_t *ps_enc_loop_thrd_ctxt, ihevce_static_cfg_params_t *ps_stat_prms)
200 {
201     /* for single bitrate encoder*/
202     switch(ps_stat_prms->s_tgt_lyr_prms.i4_mbr_quality_setting)
203     {
204     case IHEVCE_MBR_HIGH_QUALITY:
205         ps_enc_loop_thrd_ctxt->i4_num_modes_to_evaluate_intra = 3;
206         ps_enc_loop_thrd_ctxt->i4_num_modes_to_evaluate_inter = 4;
207         break;
208 
209     case IHEVCE_MBR_MEDIUM_SPEED:
210         ps_enc_loop_thrd_ctxt->i4_num_modes_to_evaluate_intra = 3;
211         ps_enc_loop_thrd_ctxt->i4_num_modes_to_evaluate_inter = 3;
212         break;
213 
214     case IHEVCE_MBR_HIGH_SPEED:
215         ps_enc_loop_thrd_ctxt->i4_num_modes_to_evaluate_intra = 2;
216         ps_enc_loop_thrd_ctxt->i4_num_modes_to_evaluate_inter = 2;
217         break;
218 
219     case IHEVCE_MBR_EXTREME_SPEED:
220         ps_enc_loop_thrd_ctxt->i4_num_modes_to_evaluate_intra = 1;
221         ps_enc_loop_thrd_ctxt->i4_num_modes_to_evaluate_inter = 1;
222         break;
223 
224     default:
225         assert(0);
226         break;
227     }
228 }
229 
230 /*!
231 ******************************************************************************
232 * \if Function name : ihevce_find_free_indx \endif
233 *
234 * \brief
235 *    Pre encode Frame processing slave thread entry point function
236 *
237 * \param[in] Frame processing thread context pointer
238 *
239 * \return
240 *    None
241 *
242 * \author
243 *  Ittiam
244 *
245 *****************************************************************************
246 */
ihevce_find_free_indx(recon_pic_buf_t ** pps_recon_buf_q,WORD32 i4_num_buf)247 WORD32 ihevce_find_free_indx(recon_pic_buf_t **pps_recon_buf_q, WORD32 i4_num_buf)
248 {
249     WORD32 i4_ctr;
250     WORD32 i4_is_full = 1;
251     WORD32 i4_least_POC = 0x7FFFFFFF;
252     WORD32 i4_least_POC_idx = -1;
253     WORD32 i4_least_GOP_num = 0x7FFFFFFF;
254 
255     for(i4_ctr = 0; i4_ctr < i4_num_buf; i4_ctr++)
256     {
257         if(pps_recon_buf_q[i4_ctr]->i4_is_free == 1)
258         {
259             i4_is_full = 0;
260             break;
261         }
262     }
263     if(i4_is_full)
264     {
265         /* remove if any non-reference pictures are present */
266         for(i4_ctr = 0; i4_ctr < i4_num_buf; i4_ctr++)
267         {
268             if(!pps_recon_buf_q[i4_ctr]->i4_is_reference &&
269                pps_recon_buf_q[i4_ctr]->i4_non_ref_free_flag)
270             {
271                 i4_least_POC_idx = i4_ctr;
272                 break;
273             }
274         }
275         /* if all non reference pictures are removed, then find the least poc
276         in the least gop number*/
277         if(i4_least_POC_idx == -1)
278         {
279             for(i4_ctr = 0; i4_ctr < i4_num_buf; i4_ctr++)
280             {
281                 if(i4_least_GOP_num > pps_recon_buf_q[i4_ctr]->i4_idr_gop_num)
282                 {
283                     i4_least_GOP_num = pps_recon_buf_q[i4_ctr]->i4_idr_gop_num;
284                 }
285             }
286             for(i4_ctr = 0; i4_ctr < i4_num_buf; i4_ctr++)
287             {
288                 if(i4_least_POC > pps_recon_buf_q[i4_ctr]->i4_poc &&
289                    i4_least_GOP_num == pps_recon_buf_q[i4_ctr]->i4_idr_gop_num)
290                 {
291                     i4_least_POC = pps_recon_buf_q[i4_ctr]->i4_poc;
292                     i4_least_POC_idx = i4_ctr;
293                 }
294             }
295         }
296     }
297     return i4_least_POC_idx;
298 }
299 
300 /*!
301 ******************************************************************************
302 * \if Function name : complexity_RC_reset_marking \endif
303 *
304 * \brief
305 *   this function the complexity variation and set the complexity change flag for
306 *   rate control to reset the model
307 *
308 * \param[in] ps_enc_loop_thrd_ctxt : enc ctxt
309 * \param[in] ps_stat_prms: static parameters
310 * \return
311 *    None
312 *
313 * \author
314 *  Ittiam
315 *
316 *****************************************************************************
317 */
complexity_RC_reset_marking(enc_ctxt_t * ps_enc_ctxt,WORD32 i4_cur_ipe_idx,WORD32 i4_end_flag)318 void complexity_RC_reset_marking(enc_ctxt_t *ps_enc_ctxt, WORD32 i4_cur_ipe_idx, WORD32 i4_end_flag)
319 {
320     rc_lap_out_params_t *ps_cur_ipe_lap_out;
321     rc_lap_out_params_t *ps_lap_out_temp;
322     WORD32 i4_max_temporal_layers;
323 
324     ps_cur_ipe_lap_out =
325         &ps_enc_ctxt->s_multi_thrd.aps_curr_inp_pre_enc[i4_cur_ipe_idx]->s_rc_lap_out;
326     ps_cur_ipe_lap_out->i4_is_cmplx_change_reset_model = 0;
327     ps_cur_ipe_lap_out->i4_is_cmplx_change_reset_bits = 0;
328 
329     i4_max_temporal_layers = ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_max_temporal_layers;
330 
331     /*reset the RC_reset counter at reset points*/
332     if(ps_cur_ipe_lap_out->i4_is_I_only_scd || ps_cur_ipe_lap_out->i4_is_non_I_scd ||
333        ps_cur_ipe_lap_out->i4_rc_scene_type == SCENE_TYPE_SCENE_CUT)
334     {
335         ps_enc_ctxt->i4_past_RC_reset_count = 0;
336     }
337 
338     if(ps_cur_ipe_lap_out->i4_rc_scene_type == SCENE_TYPE_SCENE_CUT)
339     {
340         ps_enc_ctxt->i4_past_RC_scd_reset_count = 0;
341     }
342     ps_enc_ctxt->i4_past_RC_reset_count++;
343     ps_enc_ctxt->i4_past_RC_scd_reset_count++;
344 
345     /*complexity based rate control reset */
346 
347     if((ps_cur_ipe_lap_out->i4_rc_pic_type == IV_P_FRAME ||
348         ps_cur_ipe_lap_out->i4_rc_pic_type == IV_I_FRAME) &&
349        (i4_max_temporal_layers > 1) && (!i4_end_flag) &&
350        (ps_enc_ctxt->s_multi_thrd.i4_delay_pre_me_btw_l0_ipe > (2 * (1 << i4_max_temporal_layers))))
351     {
352         WORD32 i4_is_cur_pic_high_complex_region =
353             ps_enc_ctxt->s_multi_thrd.aps_curr_out_pre_enc[i4_cur_ipe_idx]
354                 ->i4_is_high_complex_region;
355         WORD32 i4_next_ipe_idx;
356         WORD32 i4_next_next_ipe_idx;
357         WORD32 i4_temp_ipe_idx;
358         WORD32 i;
359 
360         ps_enc_ctxt->i4_future_RC_reset = 0;
361         ps_enc_ctxt->i4_future_RC_scd_reset = 0;
362         ASSERT(i4_is_cur_pic_high_complex_region != -1);
363 
364         /*get the next idx of p/i picture */
365         i4_next_ipe_idx = (i4_cur_ipe_idx + 1);
366         if(i4_next_ipe_idx >= ps_enc_ctxt->s_multi_thrd.i4_max_delay_pre_me_btw_l0_ipe)
367         {
368             i4_next_ipe_idx = 0;
369         }
370         i4_temp_ipe_idx = i4_next_ipe_idx;
371         for(i = 0; i < (1 << i4_max_temporal_layers); i++)
372         {
373             ps_lap_out_temp =
374                 &ps_enc_ctxt->s_multi_thrd.aps_curr_inp_pre_enc[i4_next_ipe_idx]->s_rc_lap_out;
375 
376             if(ps_lap_out_temp->i4_rc_pic_type == IV_P_FRAME ||
377                ps_lap_out_temp->i4_rc_pic_type == IV_I_FRAME)
378             {
379                 break;
380             }
381             i4_next_ipe_idx++;
382             if(i4_next_ipe_idx >= ps_enc_ctxt->s_multi_thrd.i4_max_delay_pre_me_btw_l0_ipe)
383             {
384                 i4_next_ipe_idx = 0;
385             }
386         }
387         /* get the next idx of next p/i picture*/
388         i4_next_next_ipe_idx = (i4_next_ipe_idx + 1);
389         if(i4_next_next_ipe_idx >= ps_enc_ctxt->s_multi_thrd.i4_max_delay_pre_me_btw_l0_ipe)
390         {
391             i4_next_next_ipe_idx = 0;
392         }
393         for(i = 0; i < (1 << i4_max_temporal_layers); i++)
394         {
395             ps_lap_out_temp =
396                 &ps_enc_ctxt->s_multi_thrd.aps_curr_inp_pre_enc[i4_next_next_ipe_idx]->s_rc_lap_out;
397 
398             if(ps_lap_out_temp->i4_rc_pic_type == IV_P_FRAME ||
399                ps_lap_out_temp->i4_rc_pic_type == IV_I_FRAME)
400             {
401                 break;
402             }
403             i4_next_next_ipe_idx++;
404             if(i4_next_next_ipe_idx >= ps_enc_ctxt->s_multi_thrd.i4_max_delay_pre_me_btw_l0_ipe)
405             {
406                 i4_next_next_ipe_idx = 0;
407             }
408         }
409 
410         /*check for any possible RC reset in the future 8 frames*/
411         for(i = 0; i < 8; i++)
412         {
413             ps_lap_out_temp =
414                 &ps_enc_ctxt->s_multi_thrd.aps_curr_inp_pre_enc[i4_temp_ipe_idx]->s_rc_lap_out;
415 
416             if(ps_lap_out_temp->i4_is_I_only_scd || ps_lap_out_temp->i4_is_non_I_scd ||
417                ps_lap_out_temp->i4_rc_scene_type == SCENE_TYPE_SCENE_CUT)
418             {
419                 ps_enc_ctxt->i4_future_RC_reset = 1;
420             }
421             if(ps_cur_ipe_lap_out->i4_rc_scene_type == SCENE_TYPE_SCENE_CUT)
422             {
423                 ps_enc_ctxt->i4_future_RC_scd_reset = 1;
424             }
425             i4_temp_ipe_idx++;
426             if(i4_temp_ipe_idx >= ps_enc_ctxt->s_multi_thrd.i4_max_delay_pre_me_btw_l0_ipe)
427             {
428                 i4_temp_ipe_idx = 0;
429             }
430         }
431 
432         if((!ps_enc_ctxt->i4_future_RC_reset) && (ps_enc_ctxt->i4_past_RC_reset_count > 8))
433         {
434             /*if the prev two P/I pic is not in high complex region
435             then enable reset RC flag*/
436             if((!ps_enc_ctxt->ai4_is_past_pic_complex[0]) &&
437                (!ps_enc_ctxt->ai4_is_past_pic_complex[1]))
438             {
439                 if(i4_is_cur_pic_high_complex_region)
440                 {
441                     ps_cur_ipe_lap_out->i4_is_cmplx_change_reset_model = 1;
442                     ps_cur_ipe_lap_out->i4_is_cmplx_change_reset_bits = 1;
443                     ps_enc_ctxt->i4_is_I_reset_done = 0;
444                 }
445             }
446 
447             /*if the next two P/I pic is not in high complex region
448             then enable reset RC flag*/
449             if((!ps_enc_ctxt->s_multi_thrd.aps_curr_out_pre_enc[i4_next_ipe_idx]
450                      ->i4_is_high_complex_region) &&
451                (!ps_enc_ctxt->s_multi_thrd.aps_curr_out_pre_enc[i4_next_next_ipe_idx]
452                      ->i4_is_high_complex_region))
453             {
454                 if(i4_is_cur_pic_high_complex_region)
455                 {
456                     ps_cur_ipe_lap_out->i4_is_cmplx_change_reset_model = 1;
457                     ps_cur_ipe_lap_out->i4_is_cmplx_change_reset_bits = 1;
458                     ps_enc_ctxt->i4_is_I_reset_done = 0;
459                 }
460             }
461         }
462         else if((!ps_enc_ctxt->i4_future_RC_scd_reset) && (ps_enc_ctxt->i4_past_RC_scd_reset_count > 8))
463         {
464             /*if the prev two P/I pic is not in high complex region
465             then enable reset RC flag*/
466             if((!ps_enc_ctxt->ai4_is_past_pic_complex[0]) &&
467                (!ps_enc_ctxt->ai4_is_past_pic_complex[1]))
468             {
469                 if(i4_is_cur_pic_high_complex_region)
470                 {
471                     ps_cur_ipe_lap_out->i4_is_cmplx_change_reset_bits = 1;
472                 }
473             }
474 
475             /*if the next two P/I pic is not in high complex region
476             then enable reset RC flag*/
477             if((!ps_enc_ctxt->s_multi_thrd.aps_curr_out_pre_enc[i4_next_ipe_idx]
478                      ->i4_is_high_complex_region) &&
479                (!ps_enc_ctxt->s_multi_thrd.aps_curr_out_pre_enc[i4_next_next_ipe_idx]
480                      ->i4_is_high_complex_region))
481             {
482                 if(i4_is_cur_pic_high_complex_region)
483                 {
484                     ps_cur_ipe_lap_out->i4_is_cmplx_change_reset_bits = 1;
485                 }
486             }
487         }
488 
489         /* forcing I frame reset after complexity change is disable as it gives gain, could be due to that
490         required i reset is already happening on pre Intra SAD*/
491         /*if(!ps_enc_ctxt->i4_is_I_reset_done && (ps_cur_ipe_lap_out->i4_pic_type
492         == IV_I_FRAME))
493         {
494             ps_cur_ipe_lap_out->i4_is_I_only_scd = 1;
495             ps_enc_ctxt->i4_is_I_reset_done = 1;
496         }*/
497 
498         ps_enc_ctxt->ai4_is_past_pic_complex[0] = i4_is_cur_pic_high_complex_region;
499 
500         ps_enc_ctxt->ai4_is_past_pic_complex[1] = ps_enc_ctxt->ai4_is_past_pic_complex[0];
501     }
502     return;
503 }
504 /*!
505 ******************************************************************************
506 * \if Function name : ihevce_manage_ref_pics \endif
507 *
508 * \brief
509 *    Reference picture management based on delta poc array given by LAP
510 *    Populates the reference list after removing non used reference pictures
511 *    populates the delta poc of reference pics to be signalled in slice header
512 *
513 * \param[in] encoder context pointer
514 * \param[in] current LAP Encoder buffer pointer
515 * \param[in] current frame process and entropy buffer pointer
516 *
517 * \return
518 *    None
519 *
520 * \author
521 *  Ittiam
522 *
523 *****************************************************************************
524 */
ihevce_pre_enc_manage_ref_pics(enc_ctxt_t * ps_enc_ctxt,ihevce_lap_enc_buf_t * ps_curr_inp,pre_enc_me_ctxt_t * ps_curr_out,WORD32 i4_ping_pong)525 void ihevce_pre_enc_manage_ref_pics(
526     enc_ctxt_t *ps_enc_ctxt,
527     ihevce_lap_enc_buf_t *ps_curr_inp,
528     pre_enc_me_ctxt_t *ps_curr_out,
529     WORD32 i4_ping_pong)
530 {
531     /* local variables */
532     WORD32 ctr;
533     WORD32 ref_pics;
534     WORD32 ai4_buf_status[HEVCE_MAX_DPB_PICS] = { 0 };
535     WORD32 curr_poc;
536     WORD32 wp_flag = 0;
537     WORD32 num_ref_pics_list0 = 0;
538     WORD32 num_ref_pics_list1 = 0;
539     WORD32 cra_poc = ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc;
540     WORD32 slice_type = ps_curr_out->s_slice_hdr.i1_slice_type;
541     recon_pic_buf_t *(*aps_pre_enc_ref_pic_list)[HEVCE_MAX_REF_PICS * 2];
542     WORD32 i4_inc_L1_active_ref_pic = 0;
543     WORD32 i4_inc_L0_active_ref_pic = 0;
544 
545     (void)ps_curr_out;
546     curr_poc = ps_curr_inp->s_lap_out.i4_poc;
547 
548     /* Number of reference pics given by LAP should not be greater than max */
549     ASSERT(HEVCE_MAX_REF_PICS >= ps_curr_inp->s_lap_out.i4_num_ref_pics);
550 
551     /*derive ref_pic_list based on ping_pong instance */
552     aps_pre_enc_ref_pic_list = ps_enc_ctxt->aps_pre_enc_ref_lists[i4_ping_pong];
553 
554     /* derive the weighted prediction enable flag based on slice type */
555     if(BSLICE == slice_type)
556     {
557         wp_flag = ps_curr_inp->s_lap_out.i1_weighted_bipred_flag;
558     }
559     else if(PSLICE == slice_type)
560     {
561         wp_flag = ps_curr_inp->s_lap_out.i1_weighted_pred_flag;
562     }
563     else
564     {
565         wp_flag = 0;
566     }
567 
568     /*to support diplicate pics*/
569     {
570         WORD32 i, j;
571         for(i = 0; i < 2; i++)
572         {
573             for(j = 0; j < HEVCE_MAX_REF_PICS * 2; j++)
574             {
575                 aps_pre_enc_ref_pic_list[i][j] =
576                     &ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][i][j];
577             }
578         }
579     }
580 
581     /* run a loop over the number of reference pics given by LAP */
582     for(ref_pics = 0; ref_pics < ps_curr_inp->s_lap_out.i4_num_ref_pics; ref_pics++)
583     {
584         WORD32 ref_poc;
585         WORD32 i4_loop = 1;
586         WORD32 i4_temp_list;
587 
588         ref_poc = curr_poc + ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_ref_pic_delta_poc;
589 
590         /* run a loop to check the poc based on delta poc array */
591         for(ctr = 0; ctr < ps_enc_ctxt->i4_pre_enc_num_buf_recon_q; ctr++)
592         {
593             /* if the POC is matching with current ref picture*/
594             if((ref_poc == ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr]->i4_poc) &&
595                (0 == ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr]->i4_is_free))
596             {
597                 /* mark the buf status as used */
598                 ai4_buf_status[ctr] = 1;
599 
600                 /* populate the reference lists based on delta poc array */
601                 if((ref_poc < curr_poc) || (0 == curr_poc))
602                 {
603                     /* list 0 */
604                     memcpy(
605                         &ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_0][num_ref_pics_list0],
606                         ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr],
607                         sizeof(recon_pic_buf_t));
608                     i4_temp_list = num_ref_pics_list0;
609 
610                     /*duplicate pics added to the list*/
611                     while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
612                                          .i4_num_duplicate_entries_in_ref_list)
613                     {
614                         /* list 0 */
615                         i4_temp_list++;
616                         memcpy(
617                             &ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_0][i4_temp_list],
618                             ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr],
619                             sizeof(recon_pic_buf_t));
620                         i4_loop++;
621                     }
622 
623                     /* populate weights and offsets corresponding to this ref pic */
624                     memcpy(
625                         &ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_0][num_ref_pics_list0]
626                              .s_weight_offset,
627                         &ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].as_wght_off[0],
628                         sizeof(ihevce_wght_offst_t));
629 
630                     /* Store the used as ref for current pic flag  */
631                     ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_0][num_ref_pics_list0]
632                         .i4_used_by_cur_pic_flag =
633                         ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_used_by_cur_pic_flag;
634 
635                     num_ref_pics_list0++;
636                     i4_loop = 1;
637                     /*duplicate pics added to the list*/
638                     while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
639                                          .i4_num_duplicate_entries_in_ref_list)
640                     {
641                         /* populate weights and offsets corresponding to this ref pic */
642                         memcpy(
643                             &ps_enc_ctxt
644                                  ->as_pre_enc_ref_lists[i4_ping_pong][LIST_0][num_ref_pics_list0]
645                                  .s_weight_offset,
646                             &ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].as_wght_off[i4_loop],
647                             sizeof(ihevce_wght_offst_t));
648 
649                         /* Store the used as ref for current pic flag  */
650                         ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_0][num_ref_pics_list0]
651                             .i4_used_by_cur_pic_flag =
652                             ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_used_by_cur_pic_flag;
653 
654                         num_ref_pics_list0++;
655                         i4_loop++;
656                     }
657                 }
658                 else
659                 {
660                     /* list 1 */
661                     memcpy(
662                         &ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_1][num_ref_pics_list1],
663                         ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr],
664                         sizeof(recon_pic_buf_t));
665 
666                     i4_temp_list = num_ref_pics_list1;
667                     /*duplicate pics added to the list*/
668                     while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
669                                          .i4_num_duplicate_entries_in_ref_list)
670                     {
671                         /* list 1 */
672                         i4_temp_list++;
673                         memcpy(
674                             &ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_1][i4_temp_list],
675                             ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr],
676                             sizeof(recon_pic_buf_t));
677                         i4_loop++;
678                     }
679 
680                     /* populate weights and offsets corresponding to this ref pic */
681                     memcpy(
682                         &ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_1][num_ref_pics_list1]
683                              .s_weight_offset,
684                         &ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].as_wght_off[0],
685                         sizeof(ihevce_wght_offst_t));
686 
687                     /* Store the used as ref for current pic flag  */
688                     ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_1][num_ref_pics_list1]
689                         .i4_used_by_cur_pic_flag =
690                         ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_used_by_cur_pic_flag;
691 
692                     num_ref_pics_list1++;
693                     i4_loop = 1;
694                     /*duplicate pics added to the list*/
695                     while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
696                                          .i4_num_duplicate_entries_in_ref_list)
697                     {
698                         /* populate weights and offsets corresponding to this ref pic */
699                         memcpy(
700                             &ps_enc_ctxt
701                                  ->as_pre_enc_ref_lists[i4_ping_pong][LIST_1][num_ref_pics_list1]
702                                  .s_weight_offset,
703                             &ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].as_wght_off[i4_loop],
704                             sizeof(ihevce_wght_offst_t));
705 
706                         /* Store the used as ref for current pic flag  */
707                         ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_1][num_ref_pics_list1]
708                             .i4_used_by_cur_pic_flag =
709                             ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_used_by_cur_pic_flag;
710 
711                         num_ref_pics_list1++;
712                         i4_loop++;
713                     }
714                 }
715                 break;
716             }
717         }
718 
719         /* if the reference picture is not found then error */
720         ASSERT(ctr != ps_enc_ctxt->i4_pre_enc_num_buf_recon_q);
721     }
722     /* sort the reference pics in List0 in descending order POC */
723     if(num_ref_pics_list0 > 1)
724     {
725         /* run a loop for num ref pics -1 */
726         for(ctr = 0; ctr < num_ref_pics_list0 - 1; ctr++)
727         {
728             WORD32 max_idx = ctr;
729             recon_pic_buf_t *ps_temp;
730             WORD32 i;
731 
732             for(i = (ctr + 1); i < num_ref_pics_list0; i++)
733             {
734                 /* check for poc greater than current ref poc */
735                 if(aps_pre_enc_ref_pic_list[LIST_0][i]->i4_poc >
736                    aps_pre_enc_ref_pic_list[LIST_0][max_idx]->i4_poc)
737                 {
738                     max_idx = i;
739                 }
740             }
741 
742             /* if max of remaining is not current, swap the pointers */
743             if(max_idx != ctr)
744             {
745                 ps_temp = aps_pre_enc_ref_pic_list[LIST_0][max_idx];
746                 aps_pre_enc_ref_pic_list[LIST_0][max_idx] = aps_pre_enc_ref_pic_list[LIST_0][ctr];
747                 aps_pre_enc_ref_pic_list[LIST_0][ctr] = ps_temp;
748             }
749         }
750     }
751 
752     /* sort the reference pics in List1 in ascending order POC */
753     if(num_ref_pics_list1 > 1)
754     {
755         /* run a loop for num ref pics -1 */
756         for(ctr = 0; ctr < num_ref_pics_list1 - 1; ctr++)
757         {
758             WORD32 min_idx = ctr;
759             recon_pic_buf_t *ps_temp;
760             WORD32 i;
761 
762             for(i = (ctr + 1); i < num_ref_pics_list1; i++)
763             {
764                 /* check for p[oc less than current ref poc */
765                 if(aps_pre_enc_ref_pic_list[LIST_1][i]->i4_poc <
766                    aps_pre_enc_ref_pic_list[LIST_1][min_idx]->i4_poc)
767                 {
768                     min_idx = i;
769                 }
770             }
771 
772             /* if min of remaining is not current, swap the pointers */
773             if(min_idx != ctr)
774             {
775                 ps_temp = aps_pre_enc_ref_pic_list[LIST_1][min_idx];
776                 aps_pre_enc_ref_pic_list[LIST_1][min_idx] = aps_pre_enc_ref_pic_list[LIST_1][ctr];
777                 aps_pre_enc_ref_pic_list[LIST_1][ctr] = ps_temp;
778             }
779         }
780     }
781 
782     /* call the ME API to update the DPB of HME pyramids coarse layers */
783     ihevce_coarse_me_frame_dpb_update(
784         ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
785         num_ref_pics_list0,
786         num_ref_pics_list1,
787         &aps_pre_enc_ref_pic_list[LIST_0][0],
788         &aps_pre_enc_ref_pic_list[LIST_1][0]);
789 
790     /* Default list creation based on uses as ref pic for current pic flag */
791     {
792         WORD32 num_ref_pics_list_final = 0;
793         WORD32 list_idx = 0;
794 
795         /* LIST 0 */
796         /* run a loop for num ref pics in list 0 */
797         for(ctr = 0; ctr < num_ref_pics_list0; ctr++)
798         {
799             /* check for used as reference flag */
800             if(1 == aps_pre_enc_ref_pic_list[LIST_0][ctr]->i4_used_by_cur_pic_flag)
801             {
802                 /* copy the pointer to the actual valid list idx */
803                 aps_pre_enc_ref_pic_list[LIST_0][list_idx] = aps_pre_enc_ref_pic_list[LIST_0][ctr];
804 
805                 /* increment the valid pic counters and idx */
806                 list_idx++;
807                 num_ref_pics_list_final++;
808             }
809         }
810 
811         /* finally store the number of pictures in List0 */
812         num_ref_pics_list0 = num_ref_pics_list_final;
813         /* LIST 1 */
814         num_ref_pics_list_final = 0;
815         list_idx = 0;
816 
817         /* run a loop for num ref pics in list 1 */
818         for(ctr = 0; ctr < num_ref_pics_list1; ctr++)
819         {
820             /* check for used as reference flag */
821             if(1 == aps_pre_enc_ref_pic_list[LIST_1][ctr]->i4_used_by_cur_pic_flag)
822             {
823                 /* copy the pointer to the actual valid list idx */
824                 aps_pre_enc_ref_pic_list[LIST_1][list_idx] = aps_pre_enc_ref_pic_list[LIST_1][ctr];
825 
826                 /* increment the valid pic counters and idx */
827                 list_idx++;
828                 num_ref_pics_list_final++;
829             }
830         }
831 
832         /* finally store the number of pictures in List1 */
833         num_ref_pics_list1 = num_ref_pics_list_final;
834     }
835     /*in case of single active ref picture on L0 and L1, then consider one of them weighted
836     and another non-weighted*/
837     if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
838     {
839         if(num_ref_pics_list0 > 2)
840         {
841             if(aps_pre_enc_ref_pic_list[LIST_0][0]->i4_poc ==
842                aps_pre_enc_ref_pic_list[LIST_0][1]->i4_poc)
843             {
844                 i4_inc_L0_active_ref_pic = 1;
845             }
846         }
847     }
848     else
849     {
850         if(num_ref_pics_list0 >= 2 && num_ref_pics_list1 >= 2)
851         {
852             if(aps_pre_enc_ref_pic_list[LIST_0][0]->i4_poc ==
853                aps_pre_enc_ref_pic_list[LIST_0][1]->i4_poc)
854             {
855                 i4_inc_L0_active_ref_pic = 1;
856             }
857             if(aps_pre_enc_ref_pic_list[LIST_1][0]->i4_poc ==
858                aps_pre_enc_ref_pic_list[LIST_1][1]->i4_poc)
859             {
860                 i4_inc_L1_active_ref_pic = 1;
861             }
862         }
863     }
864 
865     /* append the reference pics in List1 and end of list0 */
866     for(ctr = 0; ctr < num_ref_pics_list1; ctr++)
867     {
868         aps_pre_enc_ref_pic_list[LIST_0][num_ref_pics_list0 + ctr] =
869             aps_pre_enc_ref_pic_list[LIST_1][ctr];
870     }
871 
872     /* append the reference pics in List0 and end of list1 */
873     for(ctr = 0; ctr < num_ref_pics_list0; ctr++)
874     {
875         aps_pre_enc_ref_pic_list[LIST_1][num_ref_pics_list1 + ctr] =
876             aps_pre_enc_ref_pic_list[LIST_0][ctr];
877     }
878 
879     /* reference list modification for adding duplicate reference */
880     {
881 
882     }
883 
884     /* popluate the default weights and offsets for disabled cases */
885     {
886         WORD32 i;
887 
888         /* populate the weights and offsets for all pics in L0 + L1 */
889         for(i = 0; i < (num_ref_pics_list0 + num_ref_pics_list1); i++)
890         {
891             /* populate the weights and offsets if weighted prediction is disabled */
892             if(1 == wp_flag)
893             {
894                 /* if weights are disabled then populate default values */
895                 if(0 ==
896                    aps_pre_enc_ref_pic_list[LIST_0][i]->s_weight_offset.u1_luma_weight_enable_flag)
897                 {
898                     /* set to default values */
899                     aps_pre_enc_ref_pic_list[LIST_0][i]->s_weight_offset.i2_luma_weight =
900                         (1 << ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom);
901 
902                     aps_pre_enc_ref_pic_list[LIST_0][i]->s_weight_offset.i2_luma_offset = 0;
903                 }
904             }
905         }
906 
907         for(i = 0; i < (num_ref_pics_list0 + num_ref_pics_list1); i++)
908         {
909             /* populate the weights and offsets if weighted prediction is enabled */
910             if(1 == wp_flag)
911             {
912                 /* if weights are disabled then populate default values */
913                 if(0 ==
914                    aps_pre_enc_ref_pic_list[LIST_1][i]->s_weight_offset.u1_luma_weight_enable_flag)
915                 {
916                     /* set to default values */
917                     aps_pre_enc_ref_pic_list[LIST_1][i]->s_weight_offset.i2_luma_weight =
918                         (1 << ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom);
919 
920                     aps_pre_enc_ref_pic_list[LIST_1][i]->s_weight_offset.i2_luma_offset = 0;
921                 }
922             }
923         }
924     }
925 
926     /* run a loop to free the non used reference pics */
927     for(ctr = 0; ctr < ps_enc_ctxt->i4_pre_enc_num_buf_recon_q; ctr++)
928     {
929         /* if not used as reference */
930         if(0 == ai4_buf_status[ctr])
931         {
932             ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr]->i4_is_free = 1;
933             ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr]->i4_poc = -1;
934         }
935     }
936 
937     /* store the number of reference pics in the list for ME/MC etc */
938     ps_enc_ctxt->i4_pre_enc_num_ref_l0 = num_ref_pics_list0;
939     ps_enc_ctxt->i4_pre_enc_num_ref_l1 = num_ref_pics_list1;
940 
941 #define HME_USE_ONLY_2REF
942 #ifndef HME_USE_ONLY_2REF
943     ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = num_ref_pics_list0;
944     ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = num_ref_pics_list1;
945 #else
946 #if MULTI_REF_ENABLE == 1
947     if(ps_curr_inp->s_lap_out.i4_quality_preset >= IHEVCE_QUALITY_P3)
948     {
949         if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
950         {
951             if(IHEVCE_QUALITY_P6 == ps_curr_inp->s_lap_out.i4_quality_preset)
952             {
953                 if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
954                 {
955                     ps_enc_ctxt->i4_pre_enc_num_ref_l0_active =
956                         MIN(MAX_NUM_REFS_IN_PPICS_IN_XS25 + 1, num_ref_pics_list0);
957                 }
958                 else
959                 {
960                     ps_enc_ctxt->i4_pre_enc_num_ref_l0_active =
961                         MIN(MAX_NUM_REFS_IN_PPICS_IN_XS25, num_ref_pics_list0);
962                     ps_enc_ctxt->i4_pre_enc_num_ref_l0_active += i4_inc_L0_active_ref_pic;
963                 }
964 
965                 ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = 0;
966             }
967             else
968             {
969                 if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
970                 {
971                     ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(3, num_ref_pics_list0);
972                 }
973                 else
974                 {
975                     ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(2, num_ref_pics_list0);
976                     ps_enc_ctxt->i4_pre_enc_num_ref_l0_active += i4_inc_L0_active_ref_pic;
977                 }
978 
979                 ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = 0;
980             }
981         }
982         else
983         {
984             if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
985             {
986                 ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(2, num_ref_pics_list0);
987                 ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = MIN(1, num_ref_pics_list1);
988                 ps_enc_ctxt->i4_pre_enc_num_ref_l1_active += i4_inc_L1_active_ref_pic;
989             }
990             else
991             {
992                 ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(1, num_ref_pics_list0);
993                 ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = MIN(1, num_ref_pics_list1);
994                 ps_enc_ctxt->i4_pre_enc_num_ref_l1_active += i4_inc_L1_active_ref_pic;
995                 ps_enc_ctxt->i4_pre_enc_num_ref_l0_active += i4_inc_L0_active_ref_pic;
996             }
997         }
998     }
999     else
1000     {
1001         if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
1002         {
1003             if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1004                 ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(4, num_ref_pics_list0);
1005             else
1006                 ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(4, num_ref_pics_list0);
1007 
1008             ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = 0;
1009         }
1010         else
1011         {
1012             if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1013             {
1014                 ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(4, num_ref_pics_list0);
1015                 ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = MIN(4, num_ref_pics_list1);
1016             }
1017             else
1018             {
1019                 ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(4, num_ref_pics_list0);
1020                 ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = MIN(4, num_ref_pics_list1);
1021             }
1022         }
1023     }
1024 #else
1025     {
1026         if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
1027         {
1028             if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1029                 ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(3, num_ref_pics_list0);
1030             else
1031                 ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(2, num_ref_pics_list0);
1032 
1033             ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = 0;
1034         }
1035         else
1036         {
1037             if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1038             {
1039                 ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(2, num_ref_pics_list0);
1040                 ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = MIN(1, num_ref_pics_list1);
1041             }
1042             else
1043             {
1044                 ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(1, num_ref_pics_list0);
1045                 ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = MIN(1, num_ref_pics_list1);
1046             }
1047         }
1048     }
1049 #endif
1050 #endif
1051 
1052     return;
1053 }
1054 
1055 /*!
1056 ******************************************************************************
1057 * \if Function name : ihevce_manage_ref_pics \endif
1058 *
1059 * \brief
1060 *    Reference picture management based on delta poc array given by LAP
1061 *    Populates the reference list after removing non used reference pictures
1062 *    populates the delta poc of reference pics to be signalled in slice header
1063 *
1064 * \param[in] encoder context pointer
1065 * \param[in] current LAP Encoder buffer pointer
1066 * \param[in] current frame process and entropy buffer pointer
1067 *
1068 * \return
1069 *    None
1070 *
1071 * \author
1072 *  Ittiam
1073 *
1074 *****************************************************************************
1075 */
ihevce_manage_ref_pics(enc_ctxt_t * ps_enc_ctxt,ihevce_lap_enc_buf_t * ps_curr_inp,slice_header_t * ps_slice_header,WORD32 i4_me_frm_id,WORD32 i4_thrd_id,WORD32 i4_bitrate_instance_id)1076 void ihevce_manage_ref_pics(
1077     enc_ctxt_t *ps_enc_ctxt,
1078     ihevce_lap_enc_buf_t *ps_curr_inp,
1079     slice_header_t *ps_slice_header,
1080     WORD32 i4_me_frm_id,
1081     WORD32 i4_thrd_id,
1082     WORD32 i4_bitrate_instance_id)
1083 {
1084     WORD32 ctr;
1085     WORD32 ref_pics;
1086     WORD32 curr_poc, curr_idr_gop_num;
1087     WORD32 wp_flag;
1088     WORD32 num_ref_pics_list0 = 0;
1089     WORD32 num_ref_pics_list1 = 0;
1090     WORD32 cra_poc = ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc;
1091     WORD32 slice_type = ps_slice_header->i1_slice_type;
1092     recon_pic_buf_t *(*aps_ref_list)[HEVCE_MAX_REF_PICS * 2];
1093     recon_pic_buf_t(*aps_ref_list_temp)[HEVCE_MAX_REF_PICS * 2];
1094     WORD32 i4_num_rpics_l0_excl_dup;
1095     WORD32 i4_num_rpics_l1_excl_dup;
1096     WORD32 i4_inc_L1_active_ref_pic = 0;
1097     WORD32 i4_inc_L0_active_ref_pic = 0;
1098     WORD32 i4_bridx = i4_bitrate_instance_id;  //bitrate instance index
1099     WORD32 i4_resolution_id = ps_enc_ctxt->i4_resolution_id;
1100     me_enc_rdopt_ctxt_t *ps_cur_out_me_prms;
1101     recon_pic_buf_t ***ppps_recon_bufs = ps_enc_ctxt->pps_recon_buf_q;
1102     WORD32 i4_num_recon_bufs = ps_enc_ctxt->ai4_num_buf_recon_q[i4_bridx];
1103 
1104     ps_cur_out_me_prms = ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id];
1105 
1106     /*to support diplicate pics*/
1107     {
1108         WORD32 i, j;
1109         for(i = 0; i < NUM_REF_LISTS; i++)
1110         {
1111             for(j = 0; j < HEVCE_MAX_REF_PICS * 2; j++)
1112             {
1113                 ps_cur_out_me_prms->aps_ref_list[i4_bridx][i][j] =
1114                     &ps_cur_out_me_prms->as_ref_list[i4_bridx][i][j];
1115             }
1116         }
1117     }
1118 
1119     aps_ref_list = ps_cur_out_me_prms->aps_ref_list[i4_bridx];
1120     aps_ref_list_temp = ps_cur_out_me_prms->as_ref_list[i4_bridx];
1121 
1122     curr_poc = ps_curr_inp->s_lap_out.i4_poc;
1123     curr_idr_gop_num = ps_curr_inp->s_lap_out.i4_idr_gop_num;
1124 
1125     /* Number of reference pics given by LAP should not be greater than max */
1126     ASSERT(HEVCE_MAX_REF_PICS >= ps_curr_inp->s_lap_out.i4_num_ref_pics);
1127 
1128     /* derive the weighted prediction enable flag based on slice type */
1129     if(BSLICE == slice_type)
1130     {
1131         wp_flag = ps_curr_inp->s_lap_out.i1_weighted_bipred_flag;
1132     }
1133     else if(PSLICE == slice_type)
1134     {
1135         wp_flag = ps_curr_inp->s_lap_out.i1_weighted_pred_flag;
1136     }
1137     else
1138     {
1139         wp_flag = 0;
1140     }
1141 
1142     ps_slice_header->s_rplm.i1_ref_pic_list_modification_flag_l0 = 0;
1143     ps_slice_header->s_rplm.i1_ref_pic_list_modification_flag_l1 = 0;
1144     ASSERT(curr_poc != INVALID_POC);
1145 
1146     /* run a loop over the number of reference pics given by LAP */
1147     for(ref_pics = 0; ref_pics < ps_curr_inp->s_lap_out.i4_num_ref_pics; ref_pics++)
1148     {
1149         WORD32 ref_poc;
1150         WORD32 i4_loop = 1;
1151         WORD32 i4_temp_list;
1152 
1153         ref_poc = curr_poc + ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_ref_pic_delta_poc;
1154         if((0 == curr_poc) && curr_idr_gop_num)
1155         {
1156             curr_idr_gop_num -= 1;
1157         }
1158         ASSERT(ref_poc != INVALID_POC);
1159         /* run a loop to check the poc based on delta poc array */
1160         for(ctr = 0; ctr < i4_num_recon_bufs; ctr++)
1161         {
1162             /* if the POC is matching with current ref picture*/
1163             if((ref_poc == ppps_recon_bufs[i4_bridx][ctr]->i4_poc) &&
1164                (0 == ppps_recon_bufs[i4_bridx][ctr]->i4_is_free) &&
1165                (curr_idr_gop_num == ppps_recon_bufs[i4_bridx][ctr]->i4_idr_gop_num))
1166             {
1167                 /* populate the reference lists based on delta poc array */
1168                 if((ref_poc < curr_poc) || (0 == curr_poc))
1169                 {
1170                     /* list 0 */
1171                     memcpy(
1172                         &aps_ref_list_temp[LIST_0][num_ref_pics_list0],
1173                         ppps_recon_bufs[i4_bridx][ctr],
1174                         sizeof(recon_pic_buf_t));
1175 
1176                     i4_temp_list = num_ref_pics_list0;
1177 
1178                     /*duplicate pics added to the list*/
1179                     while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
1180                                          .i4_num_duplicate_entries_in_ref_list)
1181                     {
1182                         i4_temp_list++;
1183                         /* list 0 */
1184                         memcpy(
1185                             &aps_ref_list_temp[LIST_0][i4_temp_list],
1186                             ppps_recon_bufs[i4_bridx][ctr],
1187                             sizeof(recon_pic_buf_t));
1188                         i4_loop++;
1189                     }
1190 
1191                     /* populate weights and offsets corresponding to this ref pic */
1192                     memcpy(
1193                         &aps_ref_list_temp[LIST_0][num_ref_pics_list0].s_weight_offset,
1194                         &ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].as_wght_off[0],
1195                         sizeof(ihevce_wght_offst_t));
1196 
1197                     /* Store the used as ref for current pic flag  */
1198                     aps_ref_list_temp[LIST_0][num_ref_pics_list0].i4_used_by_cur_pic_flag =
1199                         ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_used_by_cur_pic_flag;
1200 
1201                     if(wp_flag)
1202                     {
1203                         WORD16 i2_luma_weight = (aps_ref_list[LIST_0][num_ref_pics_list0]
1204                                                      ->s_weight_offset.i2_luma_weight);
1205 
1206                         aps_ref_list[LIST_0][num_ref_pics_list0]->i4_inv_luma_wt =
1207                             ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1208 
1209                         aps_ref_list[LIST_0][num_ref_pics_list0]->i4_log2_wt_denom =
1210                             ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1211                     }
1212                     else
1213                     {
1214                         WORD16 i2_luma_weight =
1215                             (1 << ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom);
1216 
1217                         aps_ref_list[LIST_0][num_ref_pics_list0]->s_weight_offset.i2_luma_weight =
1218                             i2_luma_weight;
1219 
1220                         aps_ref_list[LIST_0][num_ref_pics_list0]->i4_inv_luma_wt =
1221                             ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1222 
1223                         aps_ref_list[LIST_0][num_ref_pics_list0]->i4_log2_wt_denom =
1224                             ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1225                     }
1226 
1227                     num_ref_pics_list0++;
1228                     i4_loop = 1;
1229 
1230                     /*duplicate pics added to the list*/
1231                     while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
1232                                          .i4_num_duplicate_entries_in_ref_list)
1233                     {
1234                         /* populate weights and offsets corresponding to this ref pic */
1235                         memcpy(
1236                             &aps_ref_list_temp[LIST_0][num_ref_pics_list0].s_weight_offset,
1237                             &ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].as_wght_off[i4_loop],
1238                             sizeof(ihevce_wght_offst_t));
1239 
1240                         /* Store the used as ref for current pic flag  */
1241                         aps_ref_list_temp[LIST_0][num_ref_pics_list0].i4_used_by_cur_pic_flag =
1242                             ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_used_by_cur_pic_flag;
1243 
1244                         if(wp_flag)
1245                         {
1246                             WORD16 i2_luma_weight = (aps_ref_list[LIST_0][num_ref_pics_list0]
1247                                                          ->s_weight_offset.i2_luma_weight);
1248 
1249                             aps_ref_list[LIST_0][num_ref_pics_list0]->i4_inv_luma_wt =
1250                                 ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1251 
1252                             aps_ref_list[LIST_0][num_ref_pics_list0]->i4_log2_wt_denom =
1253                                 ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1254                         }
1255                         else
1256                         {
1257                             WORD16 i2_luma_weight =
1258                                 (1 << ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom);
1259 
1260                             aps_ref_list[LIST_0][num_ref_pics_list0]
1261                                 ->s_weight_offset.i2_luma_weight = i2_luma_weight;
1262 
1263                             aps_ref_list[LIST_0][num_ref_pics_list0]->i4_inv_luma_wt =
1264                                 ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1265 
1266                             aps_ref_list[LIST_0][num_ref_pics_list0]->i4_log2_wt_denom =
1267                                 ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1268                         }
1269 
1270                         num_ref_pics_list0++;
1271                         i4_loop++;
1272                         ps_slice_header->s_rplm.i1_ref_pic_list_modification_flag_l0 = 1;
1273                         ps_slice_header->s_rplm.i1_ref_pic_list_modification_flag_l1 = 1;
1274                     }
1275                 }
1276                 else
1277                 {
1278                     /* list 1 */
1279                     memcpy(
1280                         &aps_ref_list_temp[LIST_1][num_ref_pics_list1],
1281                         ppps_recon_bufs[i4_bridx][ctr],
1282                         sizeof(recon_pic_buf_t));
1283                     i4_temp_list = num_ref_pics_list1;
1284                     /*duplicate pics added to the list*/
1285                     while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
1286                                          .i4_num_duplicate_entries_in_ref_list)
1287                     {
1288                         i4_temp_list++;
1289                         /* list 1 */
1290                         memcpy(
1291                             &aps_ref_list_temp[LIST_1][i4_temp_list],
1292                             ppps_recon_bufs[i4_bridx][ctr],
1293                             sizeof(recon_pic_buf_t));
1294                         i4_loop++;
1295                     }
1296 
1297                     /* populate weights and offsets corresponding to this ref pic */
1298                     memcpy(
1299                         &aps_ref_list_temp[LIST_1][num_ref_pics_list1].s_weight_offset,
1300                         &ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].as_wght_off[0],
1301                         sizeof(ihevce_wght_offst_t));
1302 
1303                     /* Store the used as ref for current pic flag  */
1304                     aps_ref_list_temp[LIST_1][num_ref_pics_list1].i4_used_by_cur_pic_flag =
1305                         ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_used_by_cur_pic_flag;
1306 
1307                     if(wp_flag)
1308                     {
1309                         WORD16 i2_luma_weight = (aps_ref_list[LIST_1][num_ref_pics_list1]
1310                                                      ->s_weight_offset.i2_luma_weight);
1311 
1312                         aps_ref_list[LIST_1][num_ref_pics_list1]->i4_inv_luma_wt =
1313                             ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1314 
1315                         aps_ref_list[LIST_1][num_ref_pics_list1]->i4_log2_wt_denom =
1316                             ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1317                     }
1318                     else
1319                     {
1320                         WORD16 i2_luma_weight =
1321                             (1 << ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom);
1322 
1323                         aps_ref_list[LIST_1][num_ref_pics_list1]->s_weight_offset.i2_luma_weight =
1324                             i2_luma_weight;
1325 
1326                         aps_ref_list[LIST_1][num_ref_pics_list1]->i4_inv_luma_wt =
1327                             ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1328 
1329                         aps_ref_list[LIST_1][num_ref_pics_list1]->i4_log2_wt_denom =
1330                             ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1331                     }
1332 
1333                     num_ref_pics_list1++;
1334                     i4_loop = 1;
1335                     /*duplicate pics added to the list*/
1336                     while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
1337                                          .i4_num_duplicate_entries_in_ref_list)
1338                     {
1339                         /* populate weights and offsets corresponding to this ref pic */
1340                         memcpy(
1341                             &aps_ref_list_temp[LIST_1][num_ref_pics_list1].s_weight_offset,
1342                             &ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].as_wght_off[i4_loop],
1343                             sizeof(ihevce_wght_offst_t));
1344 
1345                         /* Store the used as ref for current pic flag  */
1346                         aps_ref_list_temp[LIST_1][num_ref_pics_list1].i4_used_by_cur_pic_flag =
1347                             ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_used_by_cur_pic_flag;
1348 
1349                         if(wp_flag)
1350                         {
1351                             WORD16 i2_luma_weight = (aps_ref_list[LIST_1][num_ref_pics_list1]
1352                                                          ->s_weight_offset.i2_luma_weight);
1353 
1354                             aps_ref_list[LIST_1][num_ref_pics_list1]->i4_inv_luma_wt =
1355                                 ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1356 
1357                             aps_ref_list[LIST_1][num_ref_pics_list1]->i4_log2_wt_denom =
1358                                 ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1359                         }
1360                         else
1361                         {
1362                             WORD16 i2_luma_weight =
1363                                 (1 << ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom);
1364 
1365                             aps_ref_list[LIST_1][num_ref_pics_list1]
1366                                 ->s_weight_offset.i2_luma_weight = i2_luma_weight;
1367 
1368                             aps_ref_list[LIST_1][num_ref_pics_list1]->i4_inv_luma_wt =
1369                                 ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1370 
1371                             aps_ref_list[LIST_1][num_ref_pics_list1]->i4_log2_wt_denom =
1372                                 ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1373                         }
1374 
1375                         num_ref_pics_list1++;
1376                         i4_loop++;
1377                         ps_slice_header->s_rplm.i1_ref_pic_list_modification_flag_l1 = 1;
1378                         ps_slice_header->s_rplm.i1_ref_pic_list_modification_flag_l0 = 1;
1379                     }
1380                 }
1381                 break;
1382             }
1383         }
1384 
1385         /* if the reference picture is not found then error */
1386         ASSERT(ctr != i4_num_recon_bufs);
1387     }
1388 
1389     i4_num_rpics_l0_excl_dup = num_ref_pics_list0;
1390     i4_num_rpics_l1_excl_dup = num_ref_pics_list1;
1391 
1392     /* sort the reference pics in List0 in descending order POC */
1393     if(num_ref_pics_list0 > 1)
1394     {
1395         /* run a loop for num ref pics -1 */
1396         for(ctr = 0; ctr < num_ref_pics_list0 - 1; ctr++)
1397         {
1398             WORD32 max_idx = ctr;
1399             recon_pic_buf_t *ps_temp;
1400             WORD32 i;
1401 
1402             for(i = (ctr + 1); i < num_ref_pics_list0; i++)
1403             {
1404                 /* check for poc greater than current ref poc */
1405                 if(aps_ref_list[LIST_0][i]->i4_poc > aps_ref_list[LIST_0][max_idx]->i4_poc)
1406                 {
1407                     max_idx = i;
1408                 }
1409             }
1410 
1411             /* if max of remaining is not current, swap the pointers */
1412             if(max_idx != ctr)
1413             {
1414                 ps_temp = aps_ref_list[LIST_0][max_idx];
1415                 aps_ref_list[LIST_0][max_idx] = aps_ref_list[LIST_0][ctr];
1416                 aps_ref_list[LIST_0][ctr] = ps_temp;
1417             }
1418         }
1419     }
1420 
1421     /* sort the reference pics in List1 in ascending order POC */
1422     if(num_ref_pics_list1 > 1)
1423     {
1424         /* run a loop for num ref pics -1 */
1425         for(ctr = 0; ctr < num_ref_pics_list1 - 1; ctr++)
1426         {
1427             WORD32 min_idx = ctr;
1428             recon_pic_buf_t *ps_temp;
1429             WORD32 i;
1430 
1431             for(i = (ctr + 1); i < num_ref_pics_list1; i++)
1432             {
1433                 /* check for p[oc less than current ref poc */
1434                 if(aps_ref_list[LIST_1][i]->i4_poc < aps_ref_list[LIST_1][min_idx]->i4_poc)
1435                 {
1436                     min_idx = i;
1437                 }
1438             }
1439 
1440             /* if min of remaining is not current, swap the pointers */
1441             if(min_idx != ctr)
1442             {
1443                 ps_temp = aps_ref_list[LIST_1][min_idx];
1444                 aps_ref_list[LIST_1][min_idx] = aps_ref_list[LIST_1][ctr];
1445                 aps_ref_list[LIST_1][ctr] = ps_temp;
1446             }
1447         }
1448     }
1449 
1450     /* popluate the slice header parameters to signal delta POCs and use flags */
1451     {
1452         WORD32 i;
1453         WORD32 prev_poc = curr_poc;
1454 
1455         ps_slice_header->s_stref_picset.i1_inter_ref_pic_set_prediction_flag = 0;
1456 
1457         ps_slice_header->s_stref_picset.i1_num_neg_pics = num_ref_pics_list0;
1458 
1459         ps_slice_header->s_stref_picset.i1_num_pos_pics = num_ref_pics_list1;
1460 
1461         ps_slice_header->s_stref_picset.i1_num_ref_idc = -1;
1462 
1463         /* populate the delta POCs of reference pics */
1464         i = 0;
1465 
1466         for(ctr = 0; ctr < i4_num_rpics_l0_excl_dup; ctr++)
1467         {
1468             WORD32 ref_poc_l0 = aps_ref_list[LIST_0][i]->i4_poc;
1469 
1470             ps_slice_header->s_stref_picset.ai2_delta_poc[ctr] = prev_poc - ref_poc_l0;
1471             ps_slice_header->s_stref_picset.ai1_used[ctr] =
1472                 aps_ref_list[LIST_0][i]->i4_used_by_cur_pic_flag;
1473 
1474             /* check if this picture has to be used as reference */
1475             if(1 == ps_slice_header->s_stref_picset.ai1_used[ctr])
1476             {
1477                 /* check for CRA poc related use flag signalling */
1478                 ps_slice_header->s_stref_picset.ai1_used[ctr] =
1479                     (curr_poc > cra_poc) ? (ref_poc_l0 >= cra_poc) : (slice_type != ISLICE);
1480             }
1481             if(!(prev_poc - ref_poc_l0))
1482             {
1483                 ctr -= 1;
1484                 i4_num_rpics_l0_excl_dup -= 1;
1485             }
1486             prev_poc = ref_poc_l0;
1487 
1488             i++;
1489         }
1490 
1491         i = 0;
1492         prev_poc = curr_poc;
1493         for(; ctr < (i4_num_rpics_l0_excl_dup + i4_num_rpics_l1_excl_dup); ctr++)
1494         {
1495             WORD32 ref_poc_l1 = aps_ref_list[LIST_1][i]->i4_poc;
1496 
1497             ps_slice_header->s_stref_picset.ai2_delta_poc[ctr] = ref_poc_l1 - prev_poc;
1498 
1499             ps_slice_header->s_stref_picset.ai1_used[ctr] =
1500                 aps_ref_list[LIST_1][i]->i4_used_by_cur_pic_flag;
1501 
1502             /* check if this picture has to be used as reference */
1503             if(1 == ps_slice_header->s_stref_picset.ai1_used[ctr])
1504             {
1505                 /* check for CRA poc related use flag signalling */
1506                 ps_slice_header->s_stref_picset.ai1_used[ctr] =
1507                     (curr_poc > cra_poc) ? (ref_poc_l1 >= cra_poc) : (slice_type != ISLICE);
1508                 /* (slice_type != ISLICE); */
1509             }
1510             if(!(ref_poc_l1 - prev_poc))
1511             {
1512                 ctr -= 1;
1513                 i4_num_rpics_l1_excl_dup -= 1;
1514             }
1515             prev_poc = ref_poc_l1;
1516             i++;
1517         }
1518         ps_slice_header->s_stref_picset.i1_num_neg_pics = i4_num_rpics_l0_excl_dup;
1519 
1520         ps_slice_header->s_stref_picset.i1_num_pos_pics = i4_num_rpics_l1_excl_dup;
1521 
1522         if(IV_IDR_FRAME == ps_curr_inp->s_lap_out.i4_pic_type)
1523         {
1524             ps_slice_header->s_stref_picset.i1_num_neg_pics = 0;
1525             ps_slice_header->s_stref_picset.i1_num_pos_pics = 0;
1526         }
1527 
1528         /* not used so set to -1 */
1529         memset(&ps_slice_header->s_stref_picset.ai1_ref_idc[0], -1, MAX_DPB_SIZE);
1530     }
1531     /* call the ME API to update the DPB of HME pyramids
1532     Upadate list for reference bit-rate only */
1533     if(0 == i4_bridx)
1534     {
1535         ihevce_me_frame_dpb_update(
1536             ps_enc_ctxt->s_module_ctxt.pv_me_ctxt,
1537             num_ref_pics_list0,
1538             num_ref_pics_list1,
1539             &aps_ref_list[LIST_0][0],
1540             &aps_ref_list[LIST_1][0],
1541             i4_thrd_id);
1542     }
1543 
1544     /* Default list creation based on uses as ref pic for current pic flag */
1545     {
1546         WORD32 num_ref_pics_list_final = 0;
1547         WORD32 list_idx = 0;
1548 
1549         /* LIST 0 */
1550         /* run a loop for num ref pics in list 0 */
1551         for(ctr = 0; ctr < num_ref_pics_list0; ctr++)
1552         {
1553             /* check for used as reference flag */
1554             if(1 == aps_ref_list[LIST_0][ctr]->i4_used_by_cur_pic_flag)
1555             {
1556                 /* copy the pointer to the actual valid list idx */
1557                 aps_ref_list[LIST_0][list_idx] = aps_ref_list[LIST_0][ctr];
1558 
1559                 /* increment the valid pic counters and idx */
1560                 list_idx++;
1561                 num_ref_pics_list_final++;
1562             }
1563         }
1564 
1565         /* finally store the number of pictures in List0 */
1566         num_ref_pics_list0 = num_ref_pics_list_final;
1567 
1568         /* LIST 1 */
1569         num_ref_pics_list_final = 0;
1570         list_idx = 0;
1571 
1572         /* run a loop for num ref pics in list 1 */
1573         for(ctr = 0; ctr < num_ref_pics_list1; ctr++)
1574         {
1575             /* check for used as reference flag */
1576             if(1 == aps_ref_list[LIST_1][ctr]->i4_used_by_cur_pic_flag)
1577             {
1578                 /* copy the pointer to the actual valid list idx */
1579                 aps_ref_list[LIST_1][list_idx] = aps_ref_list[LIST_1][ctr];
1580 
1581                 /* increment the valid pic counters and idx */
1582                 list_idx++;
1583                 num_ref_pics_list_final++;
1584             }
1585         }
1586 
1587         /* finally store the number of pictures in List1 */
1588         num_ref_pics_list1 = num_ref_pics_list_final;
1589     }
1590     /*in case of single active ref picture on L0 and L1, then consider one of them weighted
1591     and another non-weighted*/
1592     if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
1593     {
1594         if(num_ref_pics_list0 > 2)
1595         {
1596             if(aps_ref_list[LIST_0][0]->i4_poc == aps_ref_list[LIST_0][1]->i4_poc)
1597             {
1598                 i4_inc_L0_active_ref_pic = 1;
1599             }
1600         }
1601     }
1602     else
1603     {
1604         if(num_ref_pics_list0 >= 2 && num_ref_pics_list1 >= 2)
1605         {
1606             if(aps_ref_list[LIST_0][0]->i4_poc == aps_ref_list[LIST_0][1]->i4_poc)
1607             {
1608                 i4_inc_L0_active_ref_pic = 1;
1609             }
1610 
1611             if(aps_ref_list[LIST_1][0]->i4_poc == aps_ref_list[LIST_1][1]->i4_poc)
1612             {
1613                 i4_inc_L1_active_ref_pic = 1;
1614             }
1615         }
1616     }
1617     /* append the reference pics in List1 and end of list0 */
1618     for(ctr = 0; ctr < num_ref_pics_list1; ctr++)
1619     {
1620         aps_ref_list[LIST_0][num_ref_pics_list0 + ctr] = aps_ref_list[LIST_1][ctr];
1621     }
1622 
1623     /* append the reference pics in List0 and end of list1 */
1624     for(ctr = 0; ctr < num_ref_pics_list0; ctr++)
1625     {
1626         aps_ref_list[LIST_1][num_ref_pics_list1 + ctr] = aps_ref_list[LIST_0][ctr];
1627     }
1628 
1629     /* reference list modification for adding duplicate reference */
1630     {
1631         WORD32 i4_latest_idx = 0;
1632         recon_pic_buf_t *ps_ref_list_cur;
1633         recon_pic_buf_t *ps_ref_list_prev;
1634         /*List 0*/
1635         ps_ref_list_cur = aps_ref_list[LIST_0][0];
1636         ps_ref_list_prev = ps_ref_list_cur;
1637         for(ctr = 0; ctr < (num_ref_pics_list0 + num_ref_pics_list1); ctr++)
1638         {
1639             if(ps_ref_list_cur->i4_poc != ps_ref_list_prev->i4_poc)
1640             {
1641                 i4_latest_idx++;
1642             }
1643             ps_ref_list_prev = ps_ref_list_cur;
1644             ps_slice_header->s_rplm.i4_ref_poc_l0[ctr] = ps_ref_list_cur->i4_poc;
1645             ps_slice_header->s_rplm.i1_list_entry_l0[ctr] = i4_latest_idx;
1646             if((ctr + 1) < (num_ref_pics_list0 + num_ref_pics_list1))
1647             {
1648                 ps_ref_list_cur = aps_ref_list[LIST_0][ctr + 1];
1649             }
1650         } /*end for*/
1651 
1652         /*LIST 1*/
1653         i4_latest_idx = 0;
1654         ps_ref_list_cur = aps_ref_list[LIST_1][0];
1655         ps_ref_list_prev = ps_ref_list_cur;
1656         for(ctr = 0; ctr < (num_ref_pics_list0 + num_ref_pics_list1); ctr++)
1657         {
1658             if(ps_ref_list_cur->i4_poc != ps_ref_list_prev->i4_poc)
1659             {
1660                 i4_latest_idx++;
1661             }
1662             ps_ref_list_prev = ps_ref_list_cur;
1663             ps_slice_header->s_rplm.i4_ref_poc_l1[ctr] = ps_ref_list_cur->i4_poc;
1664             ps_slice_header->s_rplm.i1_list_entry_l1[ctr] = i4_latest_idx;
1665             if((ctr + 1) < (num_ref_pics_list0 + num_ref_pics_list1))
1666             {
1667                 ps_ref_list_cur = aps_ref_list[LIST_1][ctr + 1];
1668             }
1669         } /*end for*/
1670     }
1671 
1672     /* set number of active references used for l0 and l1 in slice hdr */
1673     ps_slice_header->i1_num_ref_idx_active_override_flag = 1;
1674     ps_slice_header->i1_num_ref_idx_l0_active = num_ref_pics_list0 + num_ref_pics_list1;
1675     if(BSLICE == slice_type)
1676     {
1677         /* i1_num_ref_idx_l1_active applicable only for B pics */
1678         ps_slice_header->i1_num_ref_idx_l1_active = num_ref_pics_list0 + num_ref_pics_list1;
1679     }
1680     /* popluate the slice header parameters with weights and offsets */
1681     {
1682         WORD32 i;
1683 
1684         /* populate the log 2 weight denom if weighted prediction is enabled */
1685         if(1 == wp_flag)
1686         {
1687             ps_slice_header->s_wt_ofst.i1_chroma_log2_weight_denom =
1688                 ps_curr_inp->s_lap_out.i4_log2_chroma_wght_denom;
1689             ps_slice_header->s_wt_ofst.i1_luma_log2_weight_denom =
1690                 ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1691         }
1692 
1693         /* populate the weights and offsets for all pics in L0 + L1 */
1694         for(i = 0; i < (num_ref_pics_list0 + num_ref_pics_list1); i++)
1695         {
1696             /* populate the weights and offsets if weighted prediction is enabled */
1697             if(1 == wp_flag)
1698             {
1699                 ps_slice_header->s_wt_ofst.i1_luma_weight_l0_flag[i] =
1700                     aps_ref_list[LIST_0][i]->s_weight_offset.u1_luma_weight_enable_flag;
1701 
1702                 /* if weights are enabled then copy to slice header */
1703                 if(1 == ps_slice_header->s_wt_ofst.i1_luma_weight_l0_flag[i])
1704                 {
1705                     ps_slice_header->s_wt_ofst.i2_luma_weight_l0[i] =
1706                         aps_ref_list[LIST_0][i]->s_weight_offset.i2_luma_weight;
1707                     ps_slice_header->s_wt_ofst.i2_luma_offset_l0[i] =
1708                         aps_ref_list[LIST_0][i]->s_weight_offset.i2_luma_offset;
1709 
1710                     {
1711                         WORD16 i2_luma_weight =
1712                             (aps_ref_list[LIST_0][i]->s_weight_offset.i2_luma_weight);
1713 
1714                         aps_ref_list[LIST_0][i]->i4_inv_luma_wt =
1715                             ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1716 
1717                         aps_ref_list[LIST_0][i]->i4_log2_wt_denom =
1718                             ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1719                     }
1720                 }
1721                 else
1722                 {
1723                     WORD16 i2_luma_weight = (1 << ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom);
1724 
1725                     /* set to default values */
1726                     aps_ref_list[LIST_0][i]->s_weight_offset.i2_luma_weight = (i2_luma_weight);
1727 
1728                     aps_ref_list[LIST_0][i]->s_weight_offset.i2_luma_offset = 0;
1729 
1730                     aps_ref_list[LIST_0][i]->i4_inv_luma_wt =
1731                         ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1732 
1733                     aps_ref_list[LIST_0][i]->i4_log2_wt_denom =
1734                         ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1735                 }
1736 
1737                 ps_slice_header->s_wt_ofst.i1_chroma_weight_l0_flag[i] =
1738                     aps_ref_list[LIST_0][i]->s_weight_offset.u1_chroma_weight_enable_flag;
1739 
1740                 /* if weights are enabled then copy to slice header */
1741                 if(1 == ps_slice_header->s_wt_ofst.i1_chroma_weight_l0_flag[i])
1742                 {
1743                     ps_slice_header->s_wt_ofst.i2_chroma_weight_l0_cb[i] =
1744                         aps_ref_list[LIST_0][i]->s_weight_offset.i2_cb_weight;
1745                     ps_slice_header->s_wt_ofst.i2_chroma_offset_l0_cb[i] =
1746                         aps_ref_list[LIST_0][i]->s_weight_offset.i2_cb_offset;
1747 
1748                     ps_slice_header->s_wt_ofst.i2_chroma_weight_l0_cr[i] =
1749                         aps_ref_list[LIST_0][i]->s_weight_offset.i2_cr_weight;
1750                     ps_slice_header->s_wt_ofst.i2_chroma_offset_l0_cr[i] =
1751                         aps_ref_list[LIST_0][i]->s_weight_offset.i2_cr_offset;
1752                 }
1753                 else
1754                 {
1755                     /* set to default values */
1756                     aps_ref_list[LIST_0][i]->s_weight_offset.i2_cb_weight =
1757                         (1 << ps_curr_inp->s_lap_out.i4_log2_chroma_wght_denom);
1758                     aps_ref_list[LIST_0][i]->s_weight_offset.i2_cr_weight =
1759                         (1 << ps_curr_inp->s_lap_out.i4_log2_chroma_wght_denom);
1760                     aps_ref_list[LIST_0][i]->s_weight_offset.i2_cb_offset = 0;
1761                     aps_ref_list[LIST_0][i]->s_weight_offset.i2_cr_offset = 0;
1762                 }
1763             }
1764         }
1765 
1766         for(i = 0; i < (num_ref_pics_list0 + num_ref_pics_list1); i++)
1767         {
1768             /* populate the weights and offsets if weighted prediction is enabled */
1769             if(1 == wp_flag)
1770             {
1771                 ps_slice_header->s_wt_ofst.i1_luma_weight_l1_flag[i] =
1772                     aps_ref_list[LIST_1][i]->s_weight_offset.u1_luma_weight_enable_flag;
1773 
1774                 /* if weights are enabled then copy to slice header */
1775                 if(1 == ps_slice_header->s_wt_ofst.i1_luma_weight_l1_flag[i])
1776                 {
1777                     ps_slice_header->s_wt_ofst.i2_luma_weight_l1[i] =
1778                         aps_ref_list[LIST_1][i]->s_weight_offset.i2_luma_weight;
1779                     ps_slice_header->s_wt_ofst.i2_luma_offset_l1[i] =
1780                         aps_ref_list[LIST_1][i]->s_weight_offset.i2_luma_offset;
1781 
1782                     {
1783                         WORD16 i2_luma_weight =
1784                             (aps_ref_list[LIST_1][i]->s_weight_offset.i2_luma_weight);
1785 
1786                         aps_ref_list[LIST_1][i]->i4_inv_luma_wt =
1787                             ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1788 
1789                         aps_ref_list[LIST_1][i]->i4_log2_wt_denom =
1790                             ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1791                     }
1792                 }
1793                 else
1794                 {
1795                     WORD16 i2_luma_weight = (1 << ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom);
1796 
1797                     /* set to default values */
1798                     aps_ref_list[LIST_1][i]->s_weight_offset.i2_luma_weight = (i2_luma_weight);
1799 
1800                     aps_ref_list[LIST_1][i]->s_weight_offset.i2_luma_offset = 0;
1801 
1802                     aps_ref_list[LIST_1][i]->i4_inv_luma_wt =
1803                         ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1804 
1805                     aps_ref_list[LIST_1][i]->i4_log2_wt_denom =
1806                         ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1807                 }
1808 
1809                 ps_slice_header->s_wt_ofst.i1_chroma_weight_l1_flag[i] =
1810                     aps_ref_list[LIST_1][i]->s_weight_offset.u1_chroma_weight_enable_flag;
1811 
1812                 /* if weights are enabled then copy to slice header */
1813                 if(1 == ps_slice_header->s_wt_ofst.i1_chroma_weight_l1_flag[i])
1814                 {
1815                     ps_slice_header->s_wt_ofst.i2_chroma_weight_l1_cb[i] =
1816                         aps_ref_list[LIST_1][i]->s_weight_offset.i2_cb_weight;
1817                     ps_slice_header->s_wt_ofst.i2_chroma_offset_l1_cb[i] =
1818                         aps_ref_list[LIST_1][i]->s_weight_offset.i2_cb_offset;
1819 
1820                     ps_slice_header->s_wt_ofst.i2_chroma_weight_l1_cr[i] =
1821                         aps_ref_list[LIST_1][i]->s_weight_offset.i2_cr_weight;
1822                     ps_slice_header->s_wt_ofst.i2_chroma_offset_l1_cr[i] =
1823                         aps_ref_list[LIST_1][i]->s_weight_offset.i2_cr_offset;
1824                 }
1825                 else
1826                 {
1827                     /* set to default values */
1828                     aps_ref_list[LIST_1][i]->s_weight_offset.i2_cb_weight =
1829                         (1 << ps_curr_inp->s_lap_out.i4_log2_chroma_wght_denom);
1830                     aps_ref_list[LIST_1][i]->s_weight_offset.i2_cr_weight =
1831                         (1 << ps_curr_inp->s_lap_out.i4_log2_chroma_wght_denom);
1832                     aps_ref_list[LIST_1][i]->s_weight_offset.i2_cb_offset = 0;
1833                     aps_ref_list[LIST_1][i]->s_weight_offset.i2_cr_offset = 0;
1834                 }
1835             }
1836         }
1837     }
1838 
1839     /* store the number of reference pics in the list for ME/MC etc */
1840     ps_enc_ctxt->i4_num_ref_l0 = num_ref_pics_list0;
1841     ps_enc_ctxt->i4_num_ref_l1 = num_ref_pics_list1;
1842 
1843 #define HME_USE_ONLY_2REF
1844 #ifndef HME_USE_ONLY_2REF
1845     ps_enc_ctxt->i4_num_ref_l0_active = num_ref_pics_list0;
1846     ps_enc_ctxt->i4_num_ref_l1_active = num_ref_pics_list1;
1847 #else
1848 #if MULTI_REF_ENABLE == 1
1849     if(ps_curr_inp->s_lap_out.i4_quality_preset >= IHEVCE_QUALITY_P3)
1850     {
1851         if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
1852         {
1853             if(ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6)
1854             {
1855                 if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1856                 {
1857                     ps_enc_ctxt->i4_num_ref_l0_active =
1858                         MIN(MAX_NUM_REFS_IN_PPICS_IN_XS25 + 1, num_ref_pics_list0);
1859                 }
1860                 else
1861                 {
1862                     ps_enc_ctxt->i4_num_ref_l0_active =
1863                         MIN(MAX_NUM_REFS_IN_PPICS_IN_XS25, num_ref_pics_list0);
1864 
1865                     ps_enc_ctxt->i4_num_ref_l0_active += i4_inc_L0_active_ref_pic;
1866                 }
1867             }
1868             else
1869             {
1870                 if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1871                 {
1872                     ps_enc_ctxt->i4_num_ref_l0_active = MIN(3, num_ref_pics_list0);
1873                 }
1874                 else
1875                 {
1876                     ps_enc_ctxt->i4_num_ref_l0_active = MIN(2, num_ref_pics_list0);
1877                     ps_enc_ctxt->i4_num_ref_l0_active += i4_inc_L0_active_ref_pic;
1878                 }
1879             }
1880 
1881             ps_enc_ctxt->i4_num_ref_l1_active = 0;
1882         }
1883         else
1884         {
1885             if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1886             {
1887                 ps_enc_ctxt->i4_num_ref_l0_active = MIN(2, num_ref_pics_list0);
1888                 ps_enc_ctxt->i4_num_ref_l1_active = MIN(1, num_ref_pics_list1);
1889                 ps_enc_ctxt->i4_num_ref_l1_active += i4_inc_L1_active_ref_pic;
1890             }
1891             else
1892             {
1893                 ps_enc_ctxt->i4_num_ref_l0_active = MIN(1, num_ref_pics_list0);
1894                 ps_enc_ctxt->i4_num_ref_l1_active = MIN(1, num_ref_pics_list1);
1895 
1896                 ps_enc_ctxt->i4_num_ref_l1_active += i4_inc_L1_active_ref_pic;
1897                 ps_enc_ctxt->i4_num_ref_l0_active += i4_inc_L0_active_ref_pic;
1898             }
1899         }
1900     }
1901     else
1902     {
1903         if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
1904         {
1905             if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1906                 ps_enc_ctxt->i4_num_ref_l0_active = MIN(4, num_ref_pics_list0);
1907             else
1908                 ps_enc_ctxt->i4_num_ref_l0_active = MIN(4, num_ref_pics_list0);
1909 
1910             ps_enc_ctxt->i4_num_ref_l1_active = 0;
1911         }
1912         else
1913         {
1914             if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1915             {
1916                 ps_enc_ctxt->i4_num_ref_l0_active = MIN(4, num_ref_pics_list0);
1917                 ps_enc_ctxt->i4_num_ref_l1_active = MIN(4, num_ref_pics_list1);
1918             }
1919             else
1920             {
1921                 ps_enc_ctxt->i4_num_ref_l0_active = MIN(4, num_ref_pics_list0);
1922                 ps_enc_ctxt->i4_num_ref_l1_active = MIN(4, num_ref_pics_list1);
1923             }
1924         }
1925     }
1926 #else
1927     if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
1928     {
1929         if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1930             ps_enc_ctxt->i4_num_ref_l0_active = MIN(3, num_ref_pics_list0);
1931         else
1932             ps_enc_ctxt->i4_num_ref_l0_active = MIN(2, num_ref_pics_list0);
1933 
1934         ps_enc_ctxt->i4_num_ref_l1_active = 0;
1935     }
1936     else
1937     {
1938         if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1939         {
1940             ps_enc_ctxt->i4_num_ref_l0_active = MIN(2, num_ref_pics_list0);
1941             ps_enc_ctxt->i4_num_ref_l1_active = MIN(1, num_ref_pics_list1);
1942         }
1943         else
1944         {
1945             ps_enc_ctxt->i4_num_ref_l0_active = MIN(1, num_ref_pics_list0);
1946             ps_enc_ctxt->i4_num_ref_l1_active = MIN(1, num_ref_pics_list1);
1947         }
1948     }
1949 #endif
1950 
1951 #endif
1952 
1953     ps_slice_header->i1_num_ref_idx_l0_active = MAX(1, ps_enc_ctxt->i4_num_ref_l0_active);
1954     if(BSLICE == slice_type)
1955     {
1956         /* i1_num_ref_idx_l1_active applicable only for B pics */
1957         ps_slice_header->i1_num_ref_idx_l1_active = MAX(1, ps_enc_ctxt->i4_num_ref_l1_active);
1958     }
1959     if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1960     {
1961         /* If Interlace field is enabled,  p field following an cra I field should have only one ref frame */
1962         WORD32 cra_second_poc = cra_poc + 1;
1963 
1964         if(curr_poc == cra_second_poc)
1965         {
1966             /*   set number of active references used for l0 and l1 for me  */
1967             ps_enc_ctxt->i4_num_ref_l0_active = 1;
1968             ps_enc_ctxt->i4_num_ref_l1_active = 0;
1969 
1970             /*   set number of active references used for l0 and l1 in slice hdr */
1971             ps_slice_header->i1_num_ref_idx_active_override_flag = 1;
1972             ps_slice_header->i1_num_ref_idx_l0_active =
1973                 ps_enc_ctxt->i4_num_ref_l0 + ps_enc_ctxt->i4_num_ref_l1;
1974         }
1975     }
1976     return;
1977 }
1978 
1979 /*!
1980 ******************************************************************************
1981 * \if Function name : ihevce_get_frame_lambda_prms \endif
1982 *
1983 * \brief
1984 *    Function whihc calculates the Lambda params for current picture
1985 *
1986 * \param[in] ps_enc_ctxt : encoder ctxt pointer
1987 * \param[in] ps_cur_pic_ctxt : current pic ctxt
1988 * \param[in] i4_cur_frame_qp : current pic QP
1989 * \param[in] first_field : is first field flag
1990 * \param[in] i4_temporal_lyr_id : Current picture layer id
1991 *
1992 * \return
1993 *    None
1994 *
1995 * \author
1996 *  Ittiam
1997 *
1998 *****************************************************************************
1999 */
ihevce_get_frame_lambda_prms(enc_ctxt_t * ps_enc_ctxt,pre_enc_me_ctxt_t * ps_cur_pic_ctxt,WORD32 i4_cur_frame_qp,WORD32 first_field,WORD32 i4_is_ref_pic,WORD32 i4_temporal_lyr_id,double f_i_pic_lamda_modifier,WORD32 i4_inst_id,WORD32 i4_lambda_type)2000 void ihevce_get_frame_lambda_prms(
2001     enc_ctxt_t *ps_enc_ctxt,
2002     pre_enc_me_ctxt_t *ps_cur_pic_ctxt,
2003     WORD32 i4_cur_frame_qp,
2004     WORD32 first_field,
2005     WORD32 i4_is_ref_pic,
2006     WORD32 i4_temporal_lyr_id,
2007     double f_i_pic_lamda_modifier,
2008     WORD32 i4_inst_id,
2009     WORD32 i4_lambda_type)
2010 {
2011     double lambda_modifier = CONST_LAMDA_MOD_VAL;
2012     double lambda_uv_modifier = CONST_LAMDA_MOD_VAL;
2013     double lambda = 0;
2014     double lambda_uv;
2015     WORD32 i4_use_const_lamda_modifier;
2016 
2017     /* initialize lambda based on frm qp, slice type, num b and temporal id */
2018     /* This lamba calculation mimics the jctvc doc (TODO add doc number     */
2019 
2020     WORD32 num_b_frms =
2021         (1 << ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_max_temporal_layers) - 1;
2022     WORD32 chroma_qp = (ps_enc_ctxt->ps_stat_prms->s_src_prms.i4_chr_format == IV_YUV_422SP_UV)
2023                            ? MIN(i4_cur_frame_qp, 51)
2024                            : gai1_ihevc_chroma_qp_scale[i4_cur_frame_qp + MAX_QP_BD_OFFSET];
2025 
2026     WORD32 i4_qp_bdoffset =
2027         6 * (ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.i4_internal_bit_depth - 8);
2028     WORD32 slice_type = ps_cur_pic_ctxt->s_slice_hdr.i1_slice_type;
2029 
2030     (void)first_field;
2031     (void)i4_is_ref_pic;
2032     (void)i4_temporal_lyr_id;
2033     i4_use_const_lamda_modifier = USE_CONSTANT_LAMBDA_MODIFIER;
2034     i4_use_const_lamda_modifier = i4_use_const_lamda_modifier ||
2035                                   ((ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_vqet &
2036                                     (1 << BITPOS_IN_VQ_TOGGLE_FOR_CONTROL_TOGGLER)) &&
2037                                    ((ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_vqet &
2038                                      (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_NOISE_PRESERVATION)) ||
2039                                     (ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_vqet &
2040                                      (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_PSYRDOPT_1)) ||
2041                                     (ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_vqet &
2042                                      (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_PSYRDOPT_2)) ||
2043                                     (ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_vqet &
2044                                      (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_PSYRDOPT_3))));
2045 
2046     /* lambda modifier is the dependent on slice type and temporal id  */
2047     if(ISLICE == slice_type)
2048     {
2049         double temporal_correction_islice = 1.0 - 0.05 * num_b_frms;
2050         temporal_correction_islice = MAX(0.5, temporal_correction_islice);
2051 
2052         lambda_modifier = 0.57 * temporal_correction_islice;
2053         lambda_uv_modifier = lambda_modifier;
2054         if(i4_use_const_lamda_modifier)
2055         {
2056             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_modifier = f_i_pic_lamda_modifier;
2057             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_uv_modifier = f_i_pic_lamda_modifier;
2058         }
2059         else
2060         {
2061             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_modifier = lambda_modifier;
2062             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_uv_modifier = lambda_uv_modifier;
2063         }
2064     }
2065     else if(PSLICE == slice_type)
2066     {
2067         if(first_field)
2068             lambda_modifier = 0.442;  //0.442*0.8;
2069         else
2070             lambda_modifier = 0.442;
2071         lambda_uv_modifier = lambda_modifier;
2072         if(i4_use_const_lamda_modifier)
2073         {
2074             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_modifier = CONST_LAMDA_MOD_VAL;
2075             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_uv_modifier = CONST_LAMDA_MOD_VAL;
2076         }
2077         else
2078         {
2079             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_modifier = lambda_modifier;
2080             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_uv_modifier = lambda_uv_modifier;
2081         }
2082     }
2083     else
2084     {
2085         /* BSLICE */
2086         if(1 == i4_is_ref_pic)
2087         {
2088             lambda_modifier = 0.3536;
2089         }
2090         else if(2 == i4_is_ref_pic)
2091         {
2092             lambda_modifier = 0.45;
2093         }
2094         else
2095         {
2096             lambda_modifier = 0.68;
2097         }
2098         lambda_uv_modifier = lambda_modifier;
2099         if(i4_use_const_lamda_modifier)
2100         {
2101             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_modifier = CONST_LAMDA_MOD_VAL;
2102             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_uv_modifier = CONST_LAMDA_MOD_VAL;
2103         }
2104         else
2105         {
2106             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_modifier = lambda_modifier;
2107             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_uv_modifier = lambda_uv_modifier;
2108         }
2109         /* TODO: Disable lambda modification for interlace encode to match HM runs */
2110         //if(0 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
2111         {
2112             /* modify b lambda further based on temporal id */
2113             if(i4_temporal_lyr_id)
2114             {
2115                 lambda_modifier *= CLIP3((((double)(i4_cur_frame_qp - 12)) / 6.0), 2.00, 4.00);
2116                 lambda_uv_modifier *= CLIP3((((double)(chroma_qp - 12)) / 6.0), 2.00, 4.00);
2117             }
2118         }
2119     }
2120     if(i4_use_const_lamda_modifier)
2121     {
2122         if(ISLICE == slice_type)
2123         {
2124             lambda_modifier = f_i_pic_lamda_modifier;
2125             lambda_uv_modifier = f_i_pic_lamda_modifier;
2126         }
2127         else
2128         {
2129             lambda_modifier = CONST_LAMDA_MOD_VAL;
2130             lambda_uv_modifier = CONST_LAMDA_MOD_VAL;
2131         }
2132     }
2133 
2134     switch(i4_lambda_type)
2135     {
2136     case 0:
2137     {
2138         i4_qp_bdoffset = 0;
2139 
2140         lambda = pow(2.0, (((double)(i4_cur_frame_qp + i4_qp_bdoffset - 12)) / 3.0));
2141         lambda_uv = pow(2.0, (((double)(chroma_qp + i4_qp_bdoffset - 12)) / 3.0));
2142 
2143         /* modify the base lambda according to lambda modifier */
2144         lambda *= lambda_modifier;
2145         lambda_uv *= lambda_uv_modifier;
2146 
2147         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].u4_chroma_cost_weighing_factor =
2148             (UWORD32)((lambda / lambda_uv) * (1 << CHROMA_COST_WEIGHING_FACTOR_Q_SHIFT));
2149 
2150         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_qf =
2151             (LWORD64)(lambda * (1 << LAMBDA_Q_SHIFT));
2152 
2153         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_chroma_qf =
2154             (LWORD64)(lambda_uv * (1 << LAMBDA_Q_SHIFT));
2155 
2156         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_lambda_qf =
2157             (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2158         if(i4_use_const_lamda_modifier)
2159         {
2160             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_lambda_qf =
2161                 (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
2162 
2163             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf =
2164                 (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2165 
2166             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf =
2167                 (WORD32)((sqrt(lambda)) * (1 << (LAMBDA_Q_SHIFT)));
2168         }
2169         else
2170         {
2171             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_lambda_qf =
2172                 (WORD32)((sqrt(lambda) / 1.5) * (1 << LAMBDA_Q_SHIFT));
2173 
2174             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf =
2175                 (WORD32)(sqrt(lambda * 1.5) * (1 << LAMBDA_Q_SHIFT));
2176 
2177             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf =
2178                 (WORD32)((sqrt(lambda * 1.5)) * (1 << (LAMBDA_Q_SHIFT)));
2179         }
2180         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_type2_lambda_qf =
2181             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_qf;
2182 
2183         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_type2_lambda_chroma_qf =
2184             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_chroma_qf;
2185 
2186         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_type2_lambda_qf =
2187             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_lambda_qf;
2188 
2189         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_type2_lambda_qf =
2190             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_lambda_qf;
2191 
2192         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_type2_lambda_qf =
2193             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf;
2194 
2195         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_type2_lambda_qf =
2196             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf;
2197 
2198         break;
2199     }
2200     case 1:
2201     {
2202         lambda = pow(2.0, (((double)(i4_cur_frame_qp + i4_qp_bdoffset - 12)) / 3.0));
2203         lambda_uv = pow(2.0, (((double)(chroma_qp + i4_qp_bdoffset - 12)) / 3.0));
2204 
2205         /* modify the base lambda according to lambda modifier */
2206         lambda *= lambda_modifier;
2207         lambda_uv *= lambda_uv_modifier;
2208 
2209         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].u4_chroma_cost_weighing_factor =
2210             (UWORD32)((lambda / lambda_uv) * (1 << CHROMA_COST_WEIGHING_FACTOR_Q_SHIFT));
2211 
2212         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_qf =
2213             (LWORD64)(lambda * (1 << LAMBDA_Q_SHIFT));
2214 
2215         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_chroma_qf =
2216             (LWORD64)(lambda_uv * (1 << LAMBDA_Q_SHIFT));
2217 
2218         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_lambda_qf =
2219             (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2220         if(i4_use_const_lamda_modifier)
2221         {
2222             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_lambda_qf =
2223                 (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
2224 
2225             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf =
2226                 (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2227 
2228             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf =
2229                 (WORD32)((sqrt(lambda)) * (1 << (LAMBDA_Q_SHIFT)));
2230         }
2231         else
2232         {
2233             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_lambda_qf =
2234                 (WORD32)((sqrt(lambda) / 1.5) * (1 << LAMBDA_Q_SHIFT));
2235 
2236             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf =
2237                 (WORD32)(sqrt(lambda * 1.5) * (1 << LAMBDA_Q_SHIFT));
2238 
2239             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf =
2240                 (WORD32)((sqrt(lambda * 1.5)) * (1 << (LAMBDA_Q_SHIFT)));
2241         }
2242         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_type2_lambda_qf =
2243             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_qf;
2244 
2245         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_type2_lambda_chroma_qf =
2246             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_chroma_qf;
2247 
2248         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_type2_lambda_qf =
2249             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_lambda_qf;
2250 
2251         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_type2_lambda_qf =
2252             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_lambda_qf;
2253 
2254         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_type2_lambda_qf =
2255             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf;
2256 
2257         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_type2_lambda_qf =
2258             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf;
2259 
2260         break;
2261     }
2262     case 2:
2263     {
2264         lambda = pow(2.0, (((double)(i4_cur_frame_qp + i4_qp_bdoffset - 12)) / 3.0));
2265         lambda_uv = pow(2.0, (((double)(chroma_qp + i4_qp_bdoffset - 12)) / 3.0));
2266 
2267         /* modify the base lambda according to lambda modifier */
2268         lambda *= lambda_modifier;
2269         lambda_uv *= lambda_uv_modifier;
2270 
2271         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].u4_chroma_cost_weighing_factor =
2272             (UWORD32)((lambda / lambda_uv) * (1 << CHROMA_COST_WEIGHING_FACTOR_Q_SHIFT));
2273 
2274         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_qf =
2275             (LWORD64)(lambda * (1 << LAMBDA_Q_SHIFT));
2276 
2277         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_chroma_qf =
2278             (LWORD64)(lambda_uv * (1 << LAMBDA_Q_SHIFT));
2279 
2280         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_lambda_qf =
2281             (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2282 
2283         if(i4_use_const_lamda_modifier)
2284         {
2285             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_lambda_qf =
2286                 (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
2287 
2288             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf =
2289                 (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2290 
2291             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf =
2292                 (WORD32)((sqrt(lambda)) * (1 << (LAMBDA_Q_SHIFT)));
2293         }
2294         else
2295         {
2296             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_lambda_qf =
2297                 (WORD32)((sqrt(lambda) / 1.5) * (1 << LAMBDA_Q_SHIFT));
2298 
2299             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf =
2300                 (WORD32)(sqrt(lambda * 1.5) * (1 << LAMBDA_Q_SHIFT));
2301 
2302             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf =
2303                 (WORD32)((sqrt(lambda * 1.5)) * (1 << (LAMBDA_Q_SHIFT)));
2304         }
2305         /* lambda corresponding to 8- bit, for metrics based on 8- bit ( Example 8bit SAD in encloop)*/
2306 
2307         lambda = pow(2.0, (((double)(i4_cur_frame_qp - 12)) / 3.0));
2308         lambda_uv = pow(2.0, (((double)(chroma_qp - 12)) / 3.0));
2309 
2310         /* modify the base lambda according to lambda modifier */
2311         lambda *= lambda_modifier;
2312         lambda_uv *= lambda_uv_modifier;
2313 
2314         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].u4_chroma_cost_weighing_factor =
2315             (UWORD32)((lambda / lambda_uv) * (1 << CHROMA_COST_WEIGHING_FACTOR_Q_SHIFT));
2316 
2317         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_type2_lambda_qf =
2318             (LWORD64)(lambda * (1 << LAMBDA_Q_SHIFT));
2319 
2320         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_type2_lambda_chroma_qf =
2321             (LWORD64)(lambda_uv * (1 << LAMBDA_Q_SHIFT));
2322 
2323         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_type2_lambda_qf =
2324             (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2325         if(i4_use_const_lamda_modifier)
2326         {
2327             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_type2_lambda_qf =
2328                 (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
2329 
2330             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_type2_lambda_qf =
2331                 (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2332 
2333             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_type2_lambda_qf =
2334                 (WORD32)((sqrt(lambda)) * (1 << (LAMBDA_Q_SHIFT)));
2335         }
2336         else
2337         {
2338             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_type2_lambda_qf =
2339                 (WORD32)((sqrt(lambda) / 1.5) * (1 << LAMBDA_Q_SHIFT));
2340 
2341             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_type2_lambda_qf =
2342                 (WORD32)(sqrt(lambda * 1.5) * (1 << LAMBDA_Q_SHIFT));
2343 
2344             ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_type2_lambda_qf =
2345                 (WORD32)((sqrt(lambda * 1.5)) * (1 << (LAMBDA_Q_SHIFT)));
2346         }
2347 
2348         break;
2349     }
2350     default:
2351     {
2352         /* Intended to be a barren wasteland! */
2353         ASSERT(0);
2354     }
2355     }
2356 
2357     /* Assign the final lambdas after up shifting to its q format */
2358 
2359     /* closed loop ssd lambda is same as final lambda */
2360 
2361     /* --- Initialized the lambda for SATD computations --- */
2362     if(i4_use_const_lamda_modifier)
2363     {
2364         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf =
2365             (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2366 
2367         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf =
2368             (WORD32)((sqrt(lambda)) * (1 << (LAMBDA_Q_SHIFT)));
2369     }
2370     else
2371     {
2372         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf =
2373             (WORD32)(sqrt(lambda * 1.5) * (1 << LAMBDA_Q_SHIFT));
2374 
2375         ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf =
2376             (WORD32)((sqrt(lambda * 1.5)) * (1 << (LAMBDA_Q_SHIFT)));
2377     }
2378 }
2379 
2380 /*!
2381 ******************************************************************************
2382 * \if Function name : ihevce_update_qp_L1_sad_based \endif
2383 *
2384 * \brief
2385 *    Function which recalculates qp in case of scene cut based on L1 satd/act
2386 *
2387 * \param[in] ps_enc_ctxt : encoder ctxt pointer
2388 * \param[in] ps_cur_pic_ctxt : current pic ctxt
2389 * \param[in] i4_cur_frame_qp : current pic QP
2390 * \param[in] first_field : is first field flag
2391 * \param[in] i4_temporal_lyr_id : Current picture layer id
2392 *
2393 * \return
2394 *    None
2395 *
2396 * \author
2397 *  Ittiam
2398 *
2399 *****************************************************************************
2400 */
ihevce_update_qp_L1_sad_based(enc_ctxt_t * ps_enc_ctxt,ihevce_lap_enc_buf_t * ps_curr_inp,ihevce_lap_enc_buf_t * ps_prev_inp,pre_enc_me_ctxt_t * ps_curr_out,WORD32 i4_is_last_thread)2401 void ihevce_update_qp_L1_sad_based(
2402     enc_ctxt_t *ps_enc_ctxt,
2403     ihevce_lap_enc_buf_t *ps_curr_inp,
2404     ihevce_lap_enc_buf_t *ps_prev_inp,
2405     pre_enc_me_ctxt_t *ps_curr_out,
2406     WORD32 i4_is_last_thread)
2407 {
2408     WORD32 i4_l1_ht, i4_l1_wd;
2409     ihevce_ed_blk_t *ps_ed_4x4 = ps_curr_out->ps_layer1_buf;
2410     WORD32 best_satd_16x16;
2411     //LWORD64 acc_satd = 0;
2412     LWORD64 acc_sad = 0; /*SAD accumulated to compare with coarse me sad*/
2413     WORD32 i4_tot_4x4block_l1_x, i4_tot_4x4block_l1_y;
2414     WORD32 i4_tot_ctb_l1_x, i4_tot_ctb_l1_y;
2415     WORD32 i;
2416     WORD32 i4_act_factor;
2417     UWORD8 u1_cu_possible_qp;
2418     WORD32 i4_q_scale_mod;
2419     LWORD64 i8_best_satd_16x16;
2420     LWORD64 i8_frame_satd_by_act_L1_accum;
2421     LWORD64 i8_frame_acc_sadt_L1, i8_frame_acc_sadt_L1_squared;
2422     WORD32 i4_new_frame_qp = 0, i4_qp_for_I_pic = 0;
2423     LWORD64 pre_intra_satd_act_evaluated = 0;
2424     ihevce_ed_ctb_l1_t *ps_ed_ctb_l1 = ps_curr_out->ps_ed_ctb_l1;
2425     WORD32 i4_j;
2426     double scale_factor_cmplx_change_detection;
2427     WORD32 i4_cmplx_change_detection_thrsh;
2428     long double ld_frame_avg_satd_L1;
2429 
2430     if(i4_is_last_thread)
2431     {
2432         ihevce_decomp_pre_intra_master_ctxt_t *ps_master_ctxt =
2433             (ihevce_decomp_pre_intra_master_ctxt_t *)
2434                 ps_enc_ctxt->s_module_ctxt.pv_decomp_pre_intra_ctxt;
2435         ihevce_decomp_pre_intra_ctxt_t *ps_ctxt = ps_master_ctxt->aps_decomp_pre_intra_thrd_ctxt[0];
2436 
2437         i4_l1_wd = ps_ctxt->as_layers[1].i4_actual_wd;
2438         i4_l1_ht = ps_ctxt->as_layers[1].i4_actual_ht;
2439 
2440         if((ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6) &&
2441            (ps_curr_inp->s_lap_out.i4_temporal_lyr_id > TEMPORAL_LAYER_DISABLE))
2442         {
2443             i8_frame_acc_sadt_L1 = -1;
2444         }
2445         else
2446         {
2447             /*the accumulation of intra satd and calculation of new qp happens for all thread
2448     It must be made sure every thread returns same value of intra satd and qp*/
2449             i8_frame_acc_sadt_L1 = ihevce_decomp_pre_intra_get_frame_satd(
2450                 ps_enc_ctxt->s_module_ctxt.pv_decomp_pre_intra_ctxt, &i4_l1_wd, &i4_l1_ht);
2451         }
2452 
2453 #if USE_SQRT_AVG_OF_SATD_SQR
2454         if((ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6) &&
2455            (ps_curr_inp->s_lap_out.i4_temporal_lyr_id > TEMPORAL_LAYER_DISABLE))
2456         {
2457             i8_frame_acc_sadt_L1_squared = 0x7fffffff;
2458         }
2459         else
2460         {
2461             i8_frame_acc_sadt_L1_squared = ihevce_decomp_pre_intra_get_frame_satd_squared(
2462                 ps_enc_ctxt->s_module_ctxt.pv_decomp_pre_intra_ctxt, &i4_l1_wd, &i4_l1_ht);
2463         }
2464 #else
2465         i8_frame_acc_sadt_L1_squared = i8_frame_acc_sadt_L1;
2466 #endif
2467         if((i4_l1_wd * i4_l1_ht) > (245760 /*640 * 384*/))
2468         {
2469             scale_factor_cmplx_change_detection =
2470                 (double)0.12 * ((i4_l1_wd * i4_l1_ht) / (640.0 * 384.0));
2471             i4_cmplx_change_detection_thrsh =
2472                 (WORD32)(HME_HIGH_SAD_BLK_THRESH * (1 - scale_factor_cmplx_change_detection));
2473         }
2474         else
2475         {
2476             scale_factor_cmplx_change_detection =
2477                 (double)0.12 * ((640.0 * 384.0) / (i4_l1_wd * i4_l1_ht));
2478             i4_cmplx_change_detection_thrsh =
2479                 (WORD32)(HME_HIGH_SAD_BLK_THRESH * (1 + scale_factor_cmplx_change_detection));
2480         }
2481         i4_tot_4x4block_l1_x =
2482             ((i4_l1_wd + ((MAX_CTB_SIZE >> 1) - 1)) & 0xFFFFFFE0) /
2483             4;  //((i4_l1_wd + 31) & 0xFFFFFFE0)/4;//(i4_l1_wd + (i4_l1_wd % 32 )) / 4;
2484         i4_tot_4x4block_l1_y =
2485             ((i4_l1_ht + ((MAX_CTB_SIZE >> 1) - 1)) & 0xFFFFFFE0) /
2486             4;  //((i4_l1_ht + 31) & 0xFFFFFFE0)/4;//(i4_l1_ht + (i4_l1_ht % 32 )) / 4;
2487         ld_frame_avg_satd_L1 =
2488             (WORD32)log(
2489                 1 + (long double)i8_frame_acc_sadt_L1_squared /
2490                         ((long double)((i4_tot_4x4block_l1_x * i4_tot_4x4block_l1_y) >> 2))) /
2491             log(2.0);
2492         /* L1 satd accumalated for computing qp */
2493         i8_frame_satd_by_act_L1_accum = 0;
2494         i4_tot_ctb_l1_x =
2495             ((i4_l1_wd + ((MAX_CTB_SIZE >> 1) - 1)) & 0xFFFFFFE0) / (MAX_CTB_SIZE >> 1);
2496         i4_tot_ctb_l1_y =
2497             ((i4_l1_ht + ((MAX_CTB_SIZE >> 1) - 1)) & 0xFFFFFFE0) / (MAX_CTB_SIZE >> 1);
2498 
2499         for(i = 0; i < (i4_tot_ctb_l1_x * i4_tot_ctb_l1_y); i += 1)
2500         {
2501             for(i4_j = 0; i4_j < 16; i4_j++)
2502             {
2503                 if(ps_ed_ctb_l1->i4_best_satd_8x8[i4_j] != -1)
2504                 {
2505                     ASSERT(ps_ed_ctb_l1->i4_best_satd_8x8[i4_j] >= 0);
2506                     ASSERT(ps_ed_ctb_l1->i4_best_sad_8x8_l1_ipe[i4_j] >= 0);
2507 
2508                     if((ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6) &&
2509                        (ps_curr_inp->s_lap_out.i4_temporal_lyr_id > TEMPORAL_LAYER_DISABLE))
2510                     {
2511                         best_satd_16x16 = 0;
2512                     }
2513                     else
2514                     {
2515                         best_satd_16x16 = ps_ed_ctb_l1->i4_best_satd_8x8[i4_j];
2516                     }
2517 
2518                     acc_sad += (WORD32)ps_ed_ctb_l1->i4_best_sad_8x8_l1_ipe[i4_j];
2519                     //acc_satd += (WORD32)best_satd_16x16;
2520                     u1_cu_possible_qp = ihevce_cu_level_qp_mod(
2521                         32,
2522                         best_satd_16x16,
2523                         ld_frame_avg_satd_L1,
2524                         REF_MOD_STRENGTH,  // To be changed later
2525                         &i4_act_factor,
2526                         &i4_q_scale_mod,
2527                         &ps_enc_ctxt->s_rc_quant);
2528                     i8_best_satd_16x16 = best_satd_16x16 << QP_LEVEL_MOD_ACT_FACTOR;
2529 
2530                     if((ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6) &&
2531                        (ps_curr_inp->s_lap_out.i4_temporal_lyr_id > TEMPORAL_LAYER_DISABLE))
2532                     {
2533                         i4_act_factor = (1 << QP_LEVEL_MOD_ACT_FACTOR);
2534                     }
2535 
2536                     if(0 != i4_act_factor)
2537                     {
2538                         i8_frame_satd_by_act_L1_accum +=
2539                             ((WORD32)(i8_best_satd_16x16 / i4_act_factor));
2540                         /*Accumulate SAD for those regions which will undergo evaluation in L0 stage*/
2541                         if(ps_ed_4x4->intra_or_inter != 2)
2542                             pre_intra_satd_act_evaluated +=
2543                                 ((WORD32)(i8_best_satd_16x16 / i4_act_factor));
2544                     }
2545                 }
2546                 ps_ed_4x4 += 4;
2547             }
2548             ps_ed_ctb_l1 += 1;
2549         }
2550         /** store the L1 satd in context struct
2551     Note: this variable is common across all thread. it must be made sure all threads write same value*/
2552         if((ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6) &&
2553            (ps_curr_inp->s_lap_out.i4_temporal_lyr_id > TEMPORAL_LAYER_DISABLE))
2554         {
2555             i8_frame_satd_by_act_L1_accum = ps_prev_inp->s_rc_lap_out.i8_frame_satd_by_act_L1_accum;
2556             ps_curr_inp->s_rc_lap_out.i8_frame_satd_by_act_L1_accum = i8_frame_satd_by_act_L1_accum;
2557             ps_curr_inp->s_rc_lap_out.i8_satd_by_act_L1_accum_evaluated = -1;
2558         }
2559         else
2560         {
2561             ps_curr_inp->s_rc_lap_out.i8_frame_satd_by_act_L1_accum = i8_frame_satd_by_act_L1_accum;
2562             ps_curr_inp->s_rc_lap_out.i8_satd_by_act_L1_accum_evaluated =
2563                 pre_intra_satd_act_evaluated;
2564         }
2565 
2566         ps_curr_inp->s_rc_lap_out.i8_pre_intra_satd = i8_frame_acc_sadt_L1;
2567         /*accumulate raw intra sad without subtracting non coded sad*/
2568         ps_curr_inp->s_rc_lap_out.i8_raw_pre_intra_sad = acc_sad;
2569     }
2570     /*update pre-enc qp using data from L1 to use better qp in L0 in case of cbr mode*/
2571     if(i4_is_last_thread)
2572     {
2573         /* acquire mutex lock for rate control calls */
2574         osal_mutex_lock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
2575         {
2576             LWORD64 i8_est_L0_satd_by_act;
2577             WORD32 i4_cur_q_scale;
2578             if(ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_rate_control_mode != CONST_QP)
2579             {
2580                 /*RCTODO :This needs to be reviewed in the context of 10/12 bit encoding as the Qp seems to be sub-optimal*/
2581                 if(ps_enc_ctxt->ps_stat_prms->s_pass_prms.i4_pass != 2)
2582                     i4_cur_q_scale =
2583                         ps_enc_ctxt->s_rc_quant.pi4_qp_to_qscale
2584                             [ps_curr_out->i4_curr_frm_qp];  // + ps_enc_ctxt->s_rc_quant.i1_qp_offset];
2585                 else
2586                     i4_cur_q_scale = ps_enc_ctxt->s_rc_quant
2587                                          .pi4_qp_to_qscale[MAX(ps_curr_out->i4_curr_frm_qp, 0)];
2588             }
2589             else
2590                 i4_cur_q_scale =
2591                     ps_enc_ctxt->s_rc_quant.pi4_qp_to_qscale
2592                         [ps_curr_out->i4_curr_frm_qp + ps_enc_ctxt->s_rc_quant.i1_qp_offset];
2593 
2594             i4_cur_q_scale = (i4_cur_q_scale + (1 << (QSCALE_Q_FAC_3 - 1))) >> QSCALE_Q_FAC_3;
2595 
2596             i8_est_L0_satd_by_act = ihevce_get_L0_satd_based_on_L1(
2597                 i8_frame_satd_by_act_L1_accum,
2598                 ps_curr_inp->s_rc_lap_out.i4_num_pels_in_frame_considered,
2599                 i4_cur_q_scale);
2600             /*HEVC_RC query rate control for qp*/
2601             if(ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_rate_control_mode != 3)
2602             {
2603                 i4_new_frame_qp = ihevce_get_L0_est_satd_based_scd_qp(
2604                     ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
2605                     &ps_curr_inp->s_rc_lap_out,
2606                     i8_est_L0_satd_by_act,
2607                     8.00);
2608             }
2609             else
2610                 i4_new_frame_qp = ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms
2611                                       .as_tgt_params[ps_enc_ctxt->i4_resolution_id]
2612                                       .ai4_frame_qp[0];
2613             i4_new_frame_qp = CLIP3(i4_new_frame_qp, 1, 51);
2614             i4_qp_for_I_pic = CLIP3(i4_qp_for_I_pic, 1, 51);
2615             ps_curr_inp->s_rc_lap_out.i4_L1_qp = i4_new_frame_qp;
2616             /*I frame qp = qp-3 due to effect of lambda modifier*/
2617             i4_qp_for_I_pic = i4_new_frame_qp - 3;
2618 
2619             /*use new qp get possible qp even for inter pictures assuming default offset*/
2620             if(ps_curr_inp->s_lap_out.i4_pic_type != IV_IDR_FRAME &&
2621                ps_curr_inp->s_lap_out.i4_pic_type != IV_I_FRAME)
2622             {
2623                 i4_new_frame_qp += ps_curr_inp->s_lap_out.i4_temporal_lyr_id + 1;
2624             }
2625 
2626             /*accumulate the L1 ME sad using skip sad value based on qp*/
2627             /*accumulate this only for last thread as it ll be guranteed that L1 ME sad is completely populated*/
2628             /*The lambda modifier in encoder is tuned in such a way that the qp offsets according to lambda modifer are as follows
2629                 Note: These qp offset only account for lambda modifier, Hence this should be applied over qp offset that is already there due to picture type
2630                 relative lambda scale(these lambda diff are mapped into qp difference which is applied over and obove the qp offset)
2631                 Qi =  Iqp                         1
2632                 Qp =  Iqp                         1
2633                 Qb =  Iqp + 1.55                  1.48
2634                 Qb1 = Iqp + 3.1                   2.05
2635                 Qb2 = Iqp + 3.1                   2.05*/
2636 
2637             /*ihevce_compute_offsets_from_rc(ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],ai4_offsets,&ps_curr_inp->s_lap_out);*/
2638 
2639             if(ps_curr_inp->s_lap_out.i4_pic_type == IV_I_FRAME ||
2640                ps_curr_inp->s_lap_out.i4_pic_type == IV_IDR_FRAME)
2641             {
2642                 i4_new_frame_qp = i4_new_frame_qp - 3;
2643             }
2644             else if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
2645             {
2646                 i4_new_frame_qp = i4_new_frame_qp - 2;
2647             }
2648             if(ps_curr_inp->s_lap_out.i4_pic_type == IV_B_FRAME &&
2649                ps_curr_inp->s_lap_out.i4_temporal_lyr_id == 1)
2650             {
2651                 i4_new_frame_qp = i4_new_frame_qp + 2;
2652             }
2653             else if(
2654                 ps_curr_inp->s_lap_out.i4_pic_type == IV_B_FRAME &&
2655                 ps_curr_inp->s_lap_out.i4_temporal_lyr_id == 2)
2656             {
2657                 i4_new_frame_qp = i4_new_frame_qp + 6;
2658             }
2659             else if(
2660                 ps_curr_inp->s_lap_out.i4_pic_type == IV_B_FRAME &&
2661                 ps_curr_inp->s_lap_out.i4_temporal_lyr_id == 3)
2662             {
2663                 i4_new_frame_qp = i4_new_frame_qp + 7;
2664             }
2665 
2666             i4_new_frame_qp = CLIP3(i4_new_frame_qp, 1, 51);
2667             i4_qp_for_I_pic = CLIP3(i4_qp_for_I_pic, 1, 51);
2668 
2669             {
2670                 calc_l1_level_hme_intra_sad_different_qp(
2671                     ps_enc_ctxt, ps_curr_out, ps_curr_inp, i4_tot_ctb_l1_x, i4_tot_ctb_l1_y);
2672 
2673                 /** frame accumulated SAD over entire frame after accounting for dead zone SAD, this is least of intra or inter*/
2674                 /*ihevce_accum_hme_sad_subgop_rc(ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],&ps_curr_inp->s_lap_out);    */
2675                 ihevce_rc_register_L1_analysis_data(
2676                     ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
2677                     &ps_curr_inp->s_rc_lap_out,
2678                     i8_est_L0_satd_by_act,
2679                     ps_curr_inp->s_rc_lap_out.ai8_pre_intra_sad
2680                         [i4_new_frame_qp],  //since the sad passed will be used to calc complexity it should be non coded sad subtracted sad
2681                     ps_curr_inp->s_rc_lap_out.ai8_frame_acc_coarse_me_sad[i4_new_frame_qp]);
2682 
2683                 ihevce_coarse_me_get_rc_param(
2684                     ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
2685                     &ps_curr_out->i8_acc_frame_coarse_me_cost,
2686                     &ps_curr_out->i8_acc_frame_coarse_me_sad,
2687                     &ps_curr_out->i8_acc_num_blks_high_sad,
2688                     &ps_curr_out->i8_total_blks,
2689                     ps_curr_inp->s_lap_out.i4_is_prev_pic_in_Tid0_same_scene);
2690 
2691                 if(ps_curr_out->i8_total_blks)
2692                 {
2693                     ps_curr_out->i4_complexity_percentage = (WORD32)(
2694                         (ps_curr_out->i8_acc_num_blks_high_sad * 100) /
2695                         (ps_curr_out->i8_total_blks));
2696                 }
2697                 /*not for Const QP mode*/
2698                 if(ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_rate_control_mode != 3)
2699                 {
2700                     if(ps_curr_inp->s_lap_out.i4_is_prev_pic_in_Tid0_same_scene &&
2701                        ps_curr_out->i8_total_blks &&
2702                        (((float)(ps_curr_out->i8_acc_num_blks_high_sad * 100) /
2703                          (ps_curr_out->i8_total_blks)) > (i4_cmplx_change_detection_thrsh)))
2704                     {
2705                         ps_curr_out->i4_is_high_complex_region = 1;
2706                     }
2707                     else
2708                     {
2709                         ps_curr_out->i4_is_high_complex_region = 0;
2710                     }
2711                 }
2712                 ps_curr_inp->s_rc_lap_out.i8_frame_acc_coarse_me_cost =
2713                     ps_curr_out->i8_acc_frame_coarse_me_cost;
2714                 /*check for I only reset case and Non I SCD*/
2715                 ihevce_rc_check_non_lap_scd(
2716                     ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0], &ps_curr_inp->s_rc_lap_out);
2717             }
2718         }
2719         /* release mutex lock after rate control calls */
2720         osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
2721     }
2722 }
2723 
2724 /*!
2725 ******************************************************************************
2726 * \if Function name : ihevce_frame_init \endif
2727 *
2728 * \brief
2729 *    Pre encode Frame processing slave thread entry point function
2730 *
2731 * \param[in] Frame processing thread context pointer
2732 *
2733 * \return
2734 *    None
2735 *
2736 * \author
2737 *  Ittiam
2738 *
2739 *****************************************************************************
2740 */
ihevce_frame_init(enc_ctxt_t * ps_enc_ctxt,pre_enc_me_ctxt_t * ps_curr_inp_prms,me_enc_rdopt_ctxt_t * ps_cur_out_me_prms,WORD32 i4_cur_frame_qp,WORD32 i4_me_frm_id,WORD32 i4_thrd_id)2741 void ihevce_frame_init(
2742     enc_ctxt_t *ps_enc_ctxt,
2743     pre_enc_me_ctxt_t *ps_curr_inp_prms,
2744     me_enc_rdopt_ctxt_t *ps_cur_out_me_prms,
2745     WORD32 i4_cur_frame_qp,
2746     WORD32 i4_me_frm_id,
2747     WORD32 i4_thrd_id)
2748 {
2749     ihevce_lap_enc_buf_t *ps_curr_inp;
2750     WORD32 first_field = 1;
2751     me_master_ctxt_t *ps_master_ctxt;
2752 
2753     (void)i4_thrd_id;
2754     (void)ps_cur_out_me_prms;
2755     ps_curr_inp = ps_curr_inp_prms->ps_curr_inp;
2756 
2757     ps_master_ctxt = (me_master_ctxt_t *)ps_enc_ctxt->s_module_ctxt.pv_me_ctxt;
2758 
2759     /* get frame level lambda params */
2760     ihevce_get_frame_lambda_prms(
2761         ps_enc_ctxt,
2762         ps_curr_inp_prms,
2763         i4_cur_frame_qp,
2764         first_field,
2765         ps_curr_inp->s_lap_out.i4_is_ref_pic,
2766         ps_curr_inp->s_lap_out.i4_temporal_lyr_id,
2767         ps_curr_inp->s_lap_out.f_i_pic_lamda_modifier,
2768         0,
2769         ENC_LAMBDA_TYPE);
2770 
2771     if(1 == ps_curr_inp_prms->i4_frm_proc_valid_flag)
2772     {
2773         UWORD8 i1_cu_qp_delta_enabled_flag =
2774             ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_cu_level_rc;
2775 
2776         /* picture level init of ME */
2777         ihevce_me_frame_init(
2778             ps_enc_ctxt->s_module_ctxt.pv_me_ctxt,
2779             ps_cur_out_me_prms,
2780             ps_enc_ctxt->ps_stat_prms,
2781             &ps_enc_ctxt->s_frm_ctb_prms,
2782             &ps_curr_inp_prms->as_lambda_prms[0],
2783             ps_enc_ctxt->i4_num_ref_l0,
2784             ps_enc_ctxt->i4_num_ref_l1,
2785             ps_enc_ctxt->i4_num_ref_l0_active,
2786             ps_enc_ctxt->i4_num_ref_l1_active,
2787             &ps_cur_out_me_prms->aps_ref_list[0][LIST_0][0],
2788             &ps_cur_out_me_prms->aps_ref_list[0][LIST_1][0],
2789             ps_cur_out_me_prms->aps_ref_list[0],
2790             &ps_enc_ctxt->s_func_selector,
2791             ps_curr_inp,
2792             ps_curr_inp_prms->pv_me_lyr_ctxt,
2793             i4_me_frm_id,
2794             i4_thrd_id,
2795             i4_cur_frame_qp,
2796             ps_curr_inp->s_lap_out.i4_temporal_lyr_id,
2797             i1_cu_qp_delta_enabled_flag,
2798             ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id]->pv_dep_mngr_encloop_dep_me);
2799 
2800         /* -------------------------------------------------------- */
2801         /* Preparing Job Queue for ME and each instance of enc_loop */
2802         /* -------------------------------------------------------- */
2803         ihevce_prepare_job_queue(ps_enc_ctxt, ps_curr_inp, i4_me_frm_id);
2804 
2805         /* Dep. Mngr : Reset the num ctb processed in every row  for ENC sync */
2806         ihevce_dmgr_rst_row_row_sync(
2807             ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id]->pv_dep_mngr_encloop_dep_me);
2808     }
2809 }
2810 
2811 /****************************************************************************
2812 Function Name : ihevce_rc_close
2813 Description   : closing the Rate control by passing the stored data in to the stat file for 2 pass encoding.
2814 Inputs        :
2815 Globals       :
2816 Processing    :
2817 Outputs       :
2818 Returns       :
2819 Issues        :
2820 Revision History:
2821 DD MM YYYY   Author(s)       Changes (Describe the changes made)
2822 *****************************************************************************/
2823 
ihevce_rc_close(enc_ctxt_t * ps_enc_ctxt,WORD32 i4_enc_frm_id_rc,WORD32 i4_store_retrive,WORD32 i4_update_cnt,WORD32 i4_bit_rate_idx)2824 void ihevce_rc_close(
2825     enc_ctxt_t *ps_enc_ctxt,
2826     WORD32 i4_enc_frm_id_rc,
2827     WORD32 i4_store_retrive,
2828     WORD32 i4_update_cnt,
2829     WORD32 i4_bit_rate_idx)
2830 {
2831     rc_bits_sad_t s_rc_frame_stat;
2832     WORD32 out_buf_id;
2833     WORD32 i4_pic_type, k;
2834     WORD32 cur_qp;
2835     ihevce_lap_output_params_t s_lap_out;
2836     rc_lap_out_params_t s_rc_lap_out;
2837 
2838     for(k = 0; k < i4_update_cnt; k++)  //ELP_RC
2839     {
2840         ihevce_rc_store_retrive_update_info(
2841             (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i4_bit_rate_idx],
2842             &s_rc_frame_stat,
2843             i4_enc_frm_id_rc,
2844             i4_bit_rate_idx,
2845             2,
2846             &out_buf_id,
2847             &i4_pic_type,
2848             &cur_qp,
2849             (void *)&s_lap_out,
2850             (void *)&s_rc_lap_out);
2851 
2852         ihevce_rc_update_pic_info(
2853             (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i4_bit_rate_idx],
2854             (s_rc_frame_stat.u4_total_texture_bits +
2855              s_rc_frame_stat.u4_total_header_bits),  //pass total bits
2856             s_rc_frame_stat.u4_total_header_bits,
2857             s_rc_frame_stat.u4_total_sad,
2858             s_rc_frame_stat.u4_total_intra_sad,
2859             (IV_PICTURE_CODING_TYPE_T)i4_pic_type,
2860             cur_qp,
2861             0,
2862             s_rc_frame_stat.i4_qp_normalized_8x8_cu_sum,
2863             s_rc_frame_stat.i4_8x8_cu_sum,
2864             s_rc_frame_stat.i8_sad_by_qscale,
2865             &s_lap_out,
2866             &s_rc_lap_out,
2867             out_buf_id,
2868             s_rc_frame_stat.u4_open_loop_intra_sad,
2869             s_rc_frame_stat.i8_total_ssd_frame,
2870             i4_enc_frm_id_rc);  //ps_curr_out->i4_inp_timestamp_low)
2871         i4_enc_frm_id_rc++;
2872         i4_enc_frm_id_rc = (i4_enc_frm_id_rc % ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc);
2873     }
2874 }
2875 
2876 /*!
2877 ******************************************************************************
2878 * \if Function name : ihevce_enc_frm_proc_slave_thrd \endif
2879 *
2880 * \brief
2881 *    Enocde Frame processing slave thread entry point function
2882 *
2883 * \param[in] Frame processing thread context pointer
2884 *
2885 * \return
2886 *    None
2887 *
2888 * \author
2889 *  Ittiam
2890 *
2891 *****************************************************************************
2892 */
ihevce_enc_frm_proc_slave_thrd(void * pv_frm_proc_thrd_ctxt)2893 WORD32 ihevce_enc_frm_proc_slave_thrd(void *pv_frm_proc_thrd_ctxt)
2894 {
2895     frm_proc_thrd_ctxt_t *ps_thrd_ctxt;
2896     enc_ctxt_t *ps_enc_ctxt;
2897     WORD32 i4_me_end_flag, i4_enc_end_flag;
2898     WORD32 i4_thrd_id;
2899     ihevce_hle_ctxt_t *ps_hle_ctxt;
2900     WORD32 i4_num_bitrates;  //number of bit-rates instances running
2901     WORD32 i;  //ctr
2902     void *pv_dep_mngr_prev_frame_me_done;
2903     void *pv_dep_mngr_prev_frame_done;
2904     WORD32 i4_resolution_id;
2905     WORD32 i4_enc_frm_id_rc = 0;
2906     WORD32 i4_enc_frm_id = 0;
2907     WORD32 i4_me_frm_id = 0;
2908 
2909     ps_thrd_ctxt = (frm_proc_thrd_ctxt_t *)pv_frm_proc_thrd_ctxt;
2910     ps_hle_ctxt = ps_thrd_ctxt->ps_hle_ctxt;
2911     ps_enc_ctxt = (enc_ctxt_t *)ps_thrd_ctxt->pv_enc_ctxt; /*Changed for mres*/
2912     i4_thrd_id = ps_thrd_ctxt->i4_thrd_id;
2913     i4_me_end_flag = 0;
2914     i4_enc_end_flag = 0;
2915     i4_num_bitrates = ps_enc_ctxt->i4_num_bitrates;
2916     i4_resolution_id = ps_enc_ctxt->i4_resolution_id;
2917 
2918     /*pv_dep_mngr_prev_frame_me_done  =
2919         ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_me_done;*/
2920 
2921     while((0 == i4_me_end_flag) && (0 == i4_enc_end_flag))
2922     {
2923         WORD32 result;
2924         WORD32 ai4_in_buf_id[MAX_NUM_ME_PARALLEL];
2925         me_enc_rdopt_ctxt_t *ps_curr_out_me;
2926 
2927         if(1 == ps_enc_ctxt->s_multi_thrd.i4_num_me_frm_pllel)
2928         {
2929             pv_dep_mngr_prev_frame_me_done =
2930                 ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_me_done[0];
2931         }
2932         else
2933         {
2934             pv_dep_mngr_prev_frame_me_done =
2935                 ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_me_done[i4_me_frm_id];
2936         }
2937 
2938         /* Wait till the previous frame ME is completly done*/
2939         {
2940             ihevce_dmgr_chk_frm_frm_sync(pv_dep_mngr_prev_frame_me_done, ps_thrd_ctxt->i4_thrd_id);
2941         }
2942 
2943         /****** Lock the critical section ******/
2944         if(NULL != ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i4_me_frm_id])
2945         {
2946             result = osal_mutex_lock(ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i4_me_frm_id]);
2947 
2948             if(OSAL_SUCCESS != result)
2949                 return 0;
2950         }
2951 
2952         {
2953             /************************************/
2954             /****** ENTER CRITICAL SECTION ******/
2955             /************************************/
2956 
2957             /* First slave getting the mutex lock will act as master and does ME init
2958             * of current frame and other slaves skip it
2959             */
2960             if(ps_enc_ctxt->s_multi_thrd.ai4_me_master_done_flag[i4_me_frm_id] == 0)
2961             {
2962                 WORD32 i4_ref_cur_qp;  //current frame Qp for reference bit-rate instance
2963                 ihevce_lap_enc_buf_t *ps_curr_inp = NULL;
2964 
2965                 if(0 == i4_me_end_flag)
2966                 {
2967                     /* ------- get the input prms buffer from pre encode que ------------ */
2968                     ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id] =
2969                         (pre_enc_me_ctxt_t *)ihevce_q_get_filled_buff(
2970                             (void *)ps_enc_ctxt,
2971                             IHEVCE_PRE_ENC_ME_Q,
2972                             &ai4_in_buf_id[i4_me_frm_id],
2973                             BUFF_QUE_BLOCKING_MODE);
2974                     /*always buffer must be available*/
2975                     ASSERT(ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id] != NULL);
2976 
2977                     ps_enc_ctxt->s_multi_thrd.is_in_buf_freed[i4_enc_frm_id] = 0;
2978 
2979                     /* ------- get the input prms buffer from L0 IPE queue ------------ */
2980                     ps_enc_ctxt->s_multi_thrd.aps_cur_L0_ipe_inp_prms[i4_me_frm_id] =
2981                         (pre_enc_L0_ipe_encloop_ctxt_t *)ihevce_q_get_filled_buff(
2982                             (void *)ps_enc_ctxt,
2983                             IHEVCE_L0_IPE_ENC_Q,
2984                             &ps_enc_ctxt->s_multi_thrd.ai4_in_frm_l0_ipe_id[i4_me_frm_id],
2985                             BUFF_QUE_BLOCKING_MODE);
2986 
2987                     /*always buffer must be available*/
2988                     ASSERT(ps_enc_ctxt->s_multi_thrd.aps_cur_L0_ipe_inp_prms[i4_me_frm_id] != NULL);
2989 
2990                     /* ------- get the free buffer from me_enc que ------------ */
2991                     ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id] =
2992                         (me_enc_rdopt_ctxt_t *)ihevce_q_get_free_buff(
2993                             ps_enc_ctxt,
2994                             IHEVCE_ME_ENC_RDOPT_Q,
2995                             &ps_enc_ctxt->s_multi_thrd.ai4_me_out_buf_id[i4_me_frm_id],
2996                             BUFF_QUE_BLOCKING_MODE);
2997 
2998                     /*always buffer must be available*/
2999                     ASSERT(ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id] != NULL);
3000                 }
3001                 if(NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id] &&
3002                    NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id] &&
3003                    NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_L0_ipe_inp_prms[i4_me_frm_id])
3004                 {
3005                     ps_curr_inp =
3006                         ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->ps_curr_inp;
3007 
3008                     ps_curr_out_me = ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id];
3009 
3010                     ps_curr_out_me->ps_curr_inp_from_l0_ipe_prms =
3011                         ps_enc_ctxt->s_multi_thrd.aps_cur_L0_ipe_inp_prms[i4_me_frm_id];
3012 
3013                     /*initialization of curr out me*/
3014                     ps_curr_out_me->ps_curr_inp_from_me_prms =
3015                         ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id];
3016 
3017                     ps_curr_out_me->curr_inp_from_me_buf_id = ai4_in_buf_id[i4_me_frm_id];
3018 
3019                     ps_curr_out_me->i4_buf_id =
3020                         ps_enc_ctxt->s_multi_thrd.ai4_me_out_buf_id[i4_me_frm_id];
3021 
3022                     ps_curr_out_me->ps_curr_inp =
3023                         ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->ps_curr_inp;
3024 
3025                     ps_curr_out_me->curr_inp_buf_id =
3026                         ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->curr_inp_buf_id;
3027 
3028                     ps_curr_out_me->curr_inp_from_l0_ipe_buf_id =
3029                         ps_enc_ctxt->s_multi_thrd.ai4_in_frm_l0_ipe_id[i4_me_frm_id];
3030 
3031                     ps_curr_out_me->i4_frm_proc_valid_flag =
3032                         ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]
3033                             ->i4_frm_proc_valid_flag;
3034 
3035                     ps_curr_out_me->i4_end_flag =
3036                         ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->i4_end_flag;
3037 
3038                     /* do the processing if input frm data is valid */
3039                     if(1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag)
3040                     {
3041                         /* slice header will be populated in pre-enocde stage */
3042                         memcpy(
3043                             &ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id]
3044                                  ->s_slice_hdr,
3045                             &ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]
3046                                  ->s_slice_hdr,
3047                             sizeof(slice_header_t));
3048 
3049                         if(ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]
3050                                ->i4_frm_proc_valid_flag)
3051                         {
3052                             WORD32 ctr;
3053                             recon_pic_buf_t *ps_frm_recon;
3054                             for(i = 0; i < i4_num_bitrates; i++)
3055                             {
3056                                 /* run a loop to free the non used reference pics */
3057                                 /* This is done here because its assured that recon buf
3058                                 * between app and encode loop is set as produced
3059                                 */
3060                                 {
3061                                     WORD32 i4_free_id;
3062                                     i4_free_id = ihevce_find_free_indx(
3063                                         ps_enc_ctxt->pps_recon_buf_q[i],
3064                                         ps_enc_ctxt->ai4_num_buf_recon_q[i]);
3065 
3066                                     if(i4_free_id != -1)
3067                                     {
3068                                         ps_enc_ctxt->pps_recon_buf_q[i][i4_free_id]->i4_is_free = 1;
3069                                         ps_enc_ctxt->pps_recon_buf_q[i][i4_free_id]->i4_poc = -1;
3070                                     }
3071                                 }
3072 
3073                                 ps_frm_recon = NULL;
3074                                 for(ctr = 0; ctr < ps_enc_ctxt->ai4_num_buf_recon_q[i]; ctr++)
3075                                 {
3076                                     if(ps_enc_ctxt->pps_recon_buf_q[i][ctr]->i4_is_free)
3077                                     {
3078                                         ps_frm_recon = ps_enc_ctxt->pps_recon_buf_q[i][ctr];
3079                                         break;
3080                                     }
3081                                 }
3082                                 ASSERT(ps_frm_recon != NULL);
3083 
3084                                 ps_frm_recon->i4_is_free = 0;
3085                                 ps_frm_recon->i4_non_ref_free_flag = 0;
3086                                 ps_frm_recon->i4_topfield_first =
3087                                     ps_curr_inp->s_input_buf.i4_topfield_first;
3088                                 ps_frm_recon->i4_poc = ps_curr_inp->s_lap_out.i4_poc;
3089                                 ps_frm_recon->i4_pic_type = ps_curr_inp->s_lap_out.i4_pic_type;
3090                                 ps_frm_recon->i4_display_num =
3091                                     ps_curr_inp->s_lap_out.i4_display_num;
3092                                 ps_frm_recon->i4_idr_gop_num =
3093                                     ps_curr_inp->s_lap_out.i4_idr_gop_num;
3094                                 ps_frm_recon->i4_bottom_field =
3095                                     ps_curr_inp->s_input_buf.i4_bottom_field;
3096                                 ps_frm_recon->i4_is_reference =
3097                                     ps_curr_inp->s_lap_out.i4_is_ref_pic;
3098 
3099                                 {
3100                                     WORD32 sei_hash_enabled =
3101                                         (ps_enc_ctxt->ps_stat_prms->s_out_strm_prms
3102                                              .i4_sei_enable_flag == 1) &&
3103                                         (ps_enc_ctxt->ps_stat_prms->s_out_strm_prms
3104                                              .i4_decoded_pic_hash_sei_flag != 0);
3105 
3106                                     /* Deblock a picture for all reference frames unconditionally. */
3107                                     /* Deblock non ref if psnr compute or save recon is enabled    */
3108                                     ps_frm_recon->i4_deblk_pad_hpel_cur_pic =
3109                                         ps_frm_recon->i4_is_reference ||
3110                                         (ps_enc_ctxt->ps_stat_prms->i4_save_recon) ||
3111                                         (1 == sei_hash_enabled);
3112                                 }
3113 
3114                                 ps_frm_recon->s_yuv_buf_desc.i4_y_ht =
3115                                     ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht;
3116                                 ps_frm_recon->s_yuv_buf_desc.i4_uv_ht =
3117                                     ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht >>
3118                                     ((ps_enc_ctxt->s_runtime_src_prms.i4_chr_format ==
3119                                       IV_YUV_422SP_UV)
3120                                          ? 0
3121                                          : 1);
3122                                 ps_frm_recon->s_yuv_buf_desc.i4_y_wd =
3123                                     ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd;
3124                                 ps_frm_recon->s_yuv_buf_desc.i4_uv_wd =
3125                                     ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd;
3126                                 ps_frm_recon->s_yuv_buf_desc.i4_y_strd =
3127                                     ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd +
3128                                     (PAD_HORZ << 1);
3129                                 ps_frm_recon->s_yuv_buf_desc.i4_uv_strd =
3130                                     ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd +
3131                                     (PAD_HORZ << 1);
3132 
3133                                 /* reset the row_frm dep mngr for ME reverse sync for reference bitrate */
3134                                 if(i == 0)
3135                                 {
3136                                     ihevce_dmgr_map_rst_sync(ps_frm_recon->pv_dep_mngr_recon);
3137                                 }
3138 
3139                                 ps_enc_ctxt->s_multi_thrd.ps_frm_recon[i4_enc_frm_id][i] =
3140                                     ps_frm_recon;
3141                             }
3142                         }
3143                         /* Reference buffer management and reference list creation */
3144                         /* This needs to be created for each bit-rate since the reconstructed output is
3145                         different for all bit-rates. ME uses only 0th instnace ref list */
3146                         for(i = i4_num_bitrates - 1; i >= 0; i--)
3147                         {
3148                             ihevce_manage_ref_pics(
3149                                 ps_enc_ctxt,
3150                                 ps_curr_inp,
3151                                 &ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id]
3152                                      ->s_slice_hdr,
3153                                 i4_me_frm_id,
3154                                 i4_thrd_id,
3155                                 i); /* bitrate instance ID */
3156                         }
3157                         /*query of qp to be moved just before encoding starts*/
3158                         i4_ref_cur_qp = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]
3159                                             ->i4_curr_frm_qp;
3160                         /* The Qp populated in Pre enc stage needs to overwritten with Qp
3161                         queried from rate control*/
3162                     }
3163                     else
3164                     {
3165                         i4_ref_cur_qp = 0;
3166                     }
3167 
3168                     /* call the core encoding loop */
3169                     ihevce_frame_init(
3170                         ps_enc_ctxt,
3171                         ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id],
3172                         ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id],
3173                         i4_ref_cur_qp,
3174                         i4_me_frm_id,
3175                         i4_thrd_id);
3176                 }
3177 
3178                 ps_enc_ctxt->s_multi_thrd.ai4_me_master_done_flag[i4_me_frm_id] = 1;
3179             }
3180         }
3181 
3182         /************************************/
3183         /******  EXIT CRITICAL SECTION ******/
3184         /************************************/
3185 
3186         /****** Unlock the critical section ******/
3187         if(NULL != ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i4_me_frm_id])
3188         {
3189             result = osal_mutex_unlock(ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i4_me_frm_id]);
3190             if(OSAL_SUCCESS != result)
3191                 return 0;
3192         }
3193 
3194         if((1 == ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.i4_mres_single_out) &&
3195            (1 == ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]
3196                      ->ps_curr_inp->s_lap_out.i4_first_frm_new_res))
3197         {
3198             /* Reset the enc frame rc id whenver change in resolution happens */
3199             i4_enc_frm_id_rc = 0;
3200         }
3201 
3202         /*update end flag for each thread */
3203         i4_me_end_flag = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->i4_end_flag;
3204         if(NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id] &&
3205            NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id] &&
3206            NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_L0_ipe_inp_prms[i4_me_frm_id])
3207         {
3208             pre_enc_me_ctxt_t *ps_curr_inp_prms;
3209             pre_enc_L0_ipe_encloop_ctxt_t *ps_curr_L0_IPE_inp_prms;
3210             ihevce_lap_enc_buf_t *ps_curr_inp;
3211 
3212             /* get the current  buffer pointer  */
3213             ps_curr_inp_prms = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id];
3214             ps_curr_L0_IPE_inp_prms =
3215                 ps_enc_ctxt->s_multi_thrd.aps_cur_L0_ipe_inp_prms[i4_me_frm_id];
3216             ps_curr_inp = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->ps_curr_inp;
3217             if(i4_thrd_id == 0)
3218             {
3219                 PROFILE_START(&ps_hle_ctxt->profile_enc_me[ps_enc_ctxt->i4_resolution_id]);
3220             }
3221 
3222             /* -------------------------------------------------- */
3223             /*    Motion estimation (enc layer) of entire frame   */
3224             /* -------------------------------------------------- */
3225             if((i4_me_end_flag == 0) &&
3226                (1 ==
3227                 ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->i4_frm_proc_valid_flag))
3228             {
3229                 /* Init i4_is_prev_frame_reference for the next P-frame */
3230                 me_master_ctxt_t *ps_master_ctxt =
3231                     (me_master_ctxt_t *)ps_enc_ctxt->s_module_ctxt.pv_me_ctxt;
3232 
3233                 /* get the current thread ctxt pointer */
3234                 me_ctxt_t *ps_ctxt = ps_master_ctxt->aps_me_ctxt[i4_thrd_id];
3235 
3236                 me_frm_ctxt_t *ps_frm_ctxt = ps_ctxt->aps_me_frm_prms[i4_me_frm_id];
3237 
3238                 if(ISLICE != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]
3239                                  ->s_slice_hdr.i1_slice_type)
3240                 {
3241                     ihevce_me_process(
3242                         ps_enc_ctxt->s_module_ctxt.pv_me_ctxt,
3243                         ps_curr_inp,
3244                         ps_curr_inp_prms->ps_ctb_analyse,
3245                         ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id],
3246                         ps_curr_inp_prms->plf_intra_8x8_cost,
3247                         ps_curr_L0_IPE_inp_prms->ps_ipe_analyse_ctb,
3248                         ps_curr_L0_IPE_inp_prms,
3249                         ps_curr_inp_prms->pv_me_lyr_ctxt,
3250                         &ps_enc_ctxt->s_multi_thrd,
3251                         ((ps_enc_ctxt->s_multi_thrd.i4_num_me_frm_pllel == 1) ? 0 : 1),
3252                         i4_thrd_id,
3253                         i4_me_frm_id);
3254                 }
3255                 else
3256                 {
3257                     /* Init i4_is_prev_frame_reference for the next P-frame */
3258                     me_master_ctxt_t *ps_master_ctxt =
3259                         (me_master_ctxt_t *)ps_enc_ctxt->s_module_ctxt.pv_me_ctxt;
3260 
3261                     /* get the current thread ctxt pointer */
3262                     me_ctxt_t *ps_ctxt = ps_master_ctxt->aps_me_ctxt[i4_thrd_id];
3263 
3264                     me_frm_ctxt_t *ps_frm_ctxt = ps_ctxt->aps_me_frm_prms[i4_me_frm_id];
3265 
3266                     multi_thrd_ctxt_t *ps_multi_thrd_ctxt = &ps_enc_ctxt->s_multi_thrd;
3267 
3268                     if(ps_enc_ctxt->s_multi_thrd.i4_num_me_frm_pllel != 1)
3269                     {
3270                         ps_frm_ctxt->i4_is_prev_frame_reference = 0;
3271                     }
3272                     else
3273                     {
3274                         ps_frm_ctxt->i4_is_prev_frame_reference =
3275                             ps_multi_thrd_ctxt->aps_cur_inp_me_prms[i4_me_frm_id]
3276                                 ->ps_curr_inp->s_lap_out.i4_is_ref_pic;
3277                     }
3278                 }
3279             }
3280             if(i4_thrd_id == 0)
3281             {
3282                 PROFILE_STOP(&ps_hle_ctxt->profile_enc_me[ps_enc_ctxt->i4_resolution_id], NULL);
3283             }
3284         }
3285         /************************************/
3286         /******  ENTER CRITICAL SECTION *****/
3287         /************************************/
3288         {
3289             WORD32 result_frame_init;
3290             void *pv_mutex_handle_frame_init;
3291 
3292             /* Create mutex for locking non-reentrant sections      */
3293             pv_mutex_handle_frame_init =
3294                 ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_me_end[i4_me_frm_id];
3295 
3296             /****** Lock the critical section ******/
3297             if(NULL != pv_mutex_handle_frame_init)
3298             {
3299                 result_frame_init = osal_mutex_lock(pv_mutex_handle_frame_init);
3300 
3301                 if(OSAL_SUCCESS != result_frame_init)
3302                     return 0;
3303             }
3304         }
3305 
3306         if(0 == ps_enc_ctxt->s_multi_thrd.ai4_me_enc_buff_prod_flag[i4_me_frm_id])
3307         {
3308             /* ------- set buffer produced from me_enc que ------------ */
3309             ihevce_q_set_buff_prod(
3310                 ps_enc_ctxt,
3311                 IHEVCE_ME_ENC_RDOPT_Q,
3312                 ps_enc_ctxt->s_multi_thrd.ai4_me_out_buf_id[i4_me_frm_id]);
3313 
3314             ps_enc_ctxt->s_multi_thrd.ai4_me_enc_buff_prod_flag[i4_me_frm_id] = 1;
3315         }
3316         if(NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id] &&
3317            NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id])
3318         {
3319             ihevce_lap_enc_buf_t *ps_curr_inp;
3320 
3321             WORD32 first_field = 1;
3322 
3323             /* Increment the counter to keep track of no of threads exiting the current mutex*/
3324             ps_enc_ctxt->s_multi_thrd.me_num_thrds_exited[i4_me_frm_id]++;
3325 
3326             ps_curr_inp = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->ps_curr_inp;
3327             /* Last slave thread will reset the master done frame init flag and set the prev
3328             * frame me done flag for curr frame
3329             */
3330             if(ps_enc_ctxt->s_multi_thrd.me_num_thrds_exited[i4_me_frm_id] ==
3331                ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds)
3332             {
3333                 ps_enc_ctxt->s_multi_thrd.me_num_thrds_exited[i4_me_frm_id] = 0;
3334 
3335                 ps_enc_ctxt->s_multi_thrd.ai4_me_master_done_flag[i4_me_frm_id] = 0;
3336 
3337                 /* Update Dyn. Vert. Search prms for P Pic. */
3338                 if(IV_P_FRAME == ps_curr_inp->s_lap_out.i4_pic_type)
3339                 {
3340                     WORD32 i4_idx_dvsr_p = ps_enc_ctxt->s_multi_thrd.i4_idx_dvsr_p;
3341                     /* Sanity Check */
3342                     ASSERT(ps_curr_inp->s_lap_out.i4_pic_type < IV_IP_FRAME);
3343 
3344                     /*  Frame END processing for Dynamic Vertival Search    */
3345                     ihevce_l0_me_frame_end(
3346                         ps_enc_ctxt->s_module_ctxt.pv_me_ctxt,
3347                         i4_idx_dvsr_p,
3348                         ps_curr_inp->s_lap_out.i4_display_num,
3349                         i4_me_frm_id);
3350 
3351                     ps_enc_ctxt->s_multi_thrd.i4_idx_dvsr_p++;
3352                     if(ps_enc_ctxt->s_multi_thrd.i4_idx_dvsr_p == NUM_SG_INTERLEAVED)
3353                     {
3354                         ps_enc_ctxt->s_multi_thrd.i4_idx_dvsr_p = 0;
3355                     }
3356                 }
3357                 if(1 == ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]
3358                             ->i4_frm_proc_valid_flag)
3359                 {
3360                     /* Init i4_is_prev_frame_reference for the next P-frame */
3361                     me_master_ctxt_t *ps_master_ctxt =
3362                         (me_master_ctxt_t *)ps_enc_ctxt->s_module_ctxt.pv_me_ctxt;
3363 
3364                     /* get the current thread ctxt pointer */
3365                     me_ctxt_t *ps_ctxt = ps_master_ctxt->aps_me_ctxt[i4_thrd_id];
3366 
3367                     me_frm_ctxt_t *ps_frm_ctxt = ps_ctxt->aps_me_frm_prms[i4_me_frm_id];
3368 
3369                     ps_frm_ctxt->ps_curr_descr->aps_layers[0]->i4_non_ref_free = 1;
3370                 }
3371                 ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id] = NULL;
3372                 ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id] = NULL;
3373                 ps_enc_ctxt->s_multi_thrd.aps_cur_L0_ipe_inp_prms[i4_me_frm_id] = NULL;
3374                 ps_enc_ctxt->s_multi_thrd.ai4_me_enc_buff_prod_flag[i4_me_frm_id] = 0;
3375                 ps_enc_ctxt->s_multi_thrd.ai4_me_master_done_flag[i4_me_frm_id] = 0;
3376 
3377                 /* Set me processing done for curr frame in the dependency manager */
3378                 ihevce_dmgr_update_frm_frm_sync(pv_dep_mngr_prev_frame_me_done);
3379             }
3380         }
3381         /************************************/
3382         /******  EXIT CRITICAL SECTION ******/
3383         /************************************/
3384 
3385         {
3386             void *pv_mutex_handle_frame_init;
3387 
3388             /* Create mutex for locking non-reentrant sections      */
3389             pv_mutex_handle_frame_init =
3390                 ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_me_end[i4_me_frm_id];
3391             /****** Unlock the critical section ******/
3392             if(NULL != pv_mutex_handle_frame_init)
3393             {
3394                 result = osal_mutex_unlock(pv_mutex_handle_frame_init);
3395                 if(OSAL_SUCCESS != result)
3396                     return 0;
3397             }
3398         }
3399         /* -------------------------------------------- */
3400         /*        Encode Loop of entire frame           */
3401         /* -------------------------------------------- */
3402         ASSERT(ps_enc_ctxt->s_multi_thrd.i4_num_enc_loop_frm_pllel <= MAX_NUM_ENC_LOOP_PARALLEL);
3403 
3404         if(1 == ps_enc_ctxt->s_multi_thrd.i4_num_enc_loop_frm_pllel)
3405         {
3406             pv_dep_mngr_prev_frame_done = ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_done[0];
3407         }
3408         else
3409         {
3410             pv_dep_mngr_prev_frame_done =
3411                 ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_done[i4_enc_frm_id];
3412         }
3413         /* Wait till the prev frame enc loop is completed*/
3414         {
3415             ihevce_dmgr_chk_frm_frm_sync(pv_dep_mngr_prev_frame_done, ps_thrd_ctxt->i4_thrd_id);
3416         }
3417 
3418         /************************************/
3419         /****** ENTER CRITICAL SECTION ******/
3420         /************************************/
3421         {
3422             WORD32 result_frame_init;
3423             void *pv_mutex_handle_frame_init;
3424 
3425             /* Create mutex for locking non-reentrant sections      */
3426             pv_mutex_handle_frame_init =
3427                 ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_frame_init[i4_enc_frm_id];
3428 
3429             /****** Lock the critical section ******/
3430             if(NULL != pv_mutex_handle_frame_init)
3431             {
3432                 result_frame_init = osal_mutex_lock(pv_mutex_handle_frame_init);
3433 
3434                 if(OSAL_SUCCESS != result_frame_init)
3435                     return 0;
3436             }
3437         }
3438 
3439         {
3440             ihevce_lap_enc_buf_t *ps_curr_inp = NULL;
3441             pre_enc_me_ctxt_t *ps_curr_inp_from_me = NULL;
3442             me_enc_rdopt_ctxt_t *ps_curr_inp_enc = NULL;
3443             pre_enc_L0_ipe_encloop_ctxt_t *ps_curr_L0_IPE_inp_prms = NULL;
3444             recon_pic_buf_t *(*aps_ref_list)[HEVCE_MAX_REF_PICS * 2];
3445             WORD32 ai4_cur_qp[IHEVCE_MAX_NUM_BITRATES] = { 0 };
3446             WORD32 i4_field_pic = ps_enc_ctxt->s_runtime_src_prms.i4_field_pic;
3447             WORD32 first_field = 1;
3448             WORD32 result_frame_init;
3449             void *pv_mutex_handle_frame_init;
3450 
3451             /* Create mutex for locking non-reentrant sections      */
3452             pv_mutex_handle_frame_init =
3453                 ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_frame_init[i4_enc_frm_id];
3454 
3455             //aquire and initialize -> output and recon buffers
3456             if(ps_enc_ctxt->s_multi_thrd.enc_master_done_frame_init[i4_enc_frm_id] == 0)
3457             {
3458                 WORD32
3459                     i4_bitrate_ctr;  //bit-rate instance counter (for loop variable) [0->reference bit-rate, 1,2->auxiliarty bit-rates]
3460                 /* ------- get the input prms buffer from me que ------------ */
3461                 ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id] =
3462                     (me_enc_rdopt_ctxt_t *)ihevce_q_get_filled_buff(
3463                         ps_enc_ctxt,
3464                         IHEVCE_ME_ENC_RDOPT_Q,
3465                         &ps_enc_ctxt->s_multi_thrd.i4_enc_in_buf_id[i4_enc_frm_id],
3466                         BUFF_QUE_BLOCKING_MODE);
3467                 i4_enc_end_flag =
3468                     ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]->i4_end_flag;
3469 
3470                 ASSERT(ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id] != NULL);
3471 
3472                 if(ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id] != NULL)
3473                 {
3474                     ps_curr_inp =
3475                         ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]->ps_curr_inp;
3476                     ps_curr_inp_from_me =
3477                         ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3478                             ->ps_curr_inp_from_me_prms;
3479                     ps_curr_inp_enc = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id];
3480                     ps_curr_L0_IPE_inp_prms =
3481                         ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3482                             ->ps_curr_inp_from_l0_ipe_prms;
3483 
3484                     for(i4_bitrate_ctr = 0; i4_bitrate_ctr < i4_num_bitrates; i4_bitrate_ctr++)
3485                     {
3486                         iv_enc_recon_data_buffs_t
3487                             *ps_recon_out[MAX_NUM_ENC_LOOP_PARALLEL][IHEVCE_MAX_NUM_BITRATES] = {
3488                                 { NULL }
3489                             };
3490                         frm_proc_ent_cod_ctxt_t *ps_curr_out[MAX_NUM_ENC_LOOP_PARALLEL]
3491                                                             [IHEVCE_MAX_NUM_BITRATES] = { { NULL } };
3492 
3493                         /* ------- get free output buffer from Frame buffer que ---------- */
3494                         /* There is a separate queue for each bit-rate instnace. The output
3495                     buffer is acquired from the corresponding queue based on the
3496                     bitrate instnace */
3497                         ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr] =
3498                             (frm_proc_ent_cod_ctxt_t *)ihevce_q_get_free_buff(
3499                                 (void *)ps_enc_ctxt,
3500                                 IHEVCE_FRM_PRS_ENT_COD_Q +
3501                                     i4_bitrate_ctr, /*decides the buffer queue */
3502                                 &ps_enc_ctxt->s_multi_thrd.out_buf_id[i4_enc_frm_id][i4_bitrate_ctr],
3503                                 BUFF_QUE_BLOCKING_MODE);
3504                         ps_enc_ctxt->s_multi_thrd.is_out_buf_freed[i4_enc_frm_id][i4_bitrate_ctr] =
3505                             0;
3506                         ps_enc_ctxt->s_multi_thrd
3507                             .ps_curr_out_enc_grp[i4_enc_frm_id][i4_bitrate_ctr] =
3508                             ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr];
3509                         //ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_enc_order_num = ps_curr_inp->s_lap_out.i4_enc_order_num;
3510                         /*registered User Data Call*/
3511                         if(ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_sei_payload_enable_flag)
3512                         {
3513                             ihevce_fill_sei_payload(
3514                                 ps_enc_ctxt,
3515                                 ps_curr_inp,
3516                                 ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]);
3517                         }
3518 
3519                         /*derive end flag and input valid flag in output buffer */
3520                         if(NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id])
3521                         {
3522                             ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_end_flag =
3523                                 ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3524                                     ->i4_end_flag;
3525                             ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_frm_proc_valid_flag =
3526                                 ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3527                                     ->i4_frm_proc_valid_flag;
3528 
3529                             ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_out_flush_flag =
3530                                 ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3531                                     ->ps_curr_inp->s_lap_out.i4_out_flush_flag;
3532                         }
3533 
3534                         /*derive other parameters in output buffer */
3535                         if(NULL != ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr] &&
3536                            (NULL != ps_curr_inp_from_me) &&
3537                            (1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag) &&
3538                            (i4_enc_end_flag == 0))
3539                         {
3540                             /* copy the time stamps from inp to entropy inp */
3541                             ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_inp_timestamp_low =
3542                                 ps_curr_inp_from_me->i4_inp_timestamp_low;
3543                             ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_inp_timestamp_high =
3544                                 ps_curr_inp_from_me->i4_inp_timestamp_high;
3545                             ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->pv_app_frm_ctxt =
3546                                 ps_curr_inp_from_me->pv_app_frm_ctxt;
3547 
3548                             /*copy slice header params from temp structure to output buffer */
3549                             memcpy(
3550                                 &ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->s_slice_hdr,
3551                                 &ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3552                                      ->s_slice_hdr,
3553                                 sizeof(slice_header_t));
3554 
3555                             ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]
3556                                 ->s_slice_hdr.pu4_entry_point_offset =
3557                                 &ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]
3558                                      ->ai4_entry_point_offset[0];
3559 
3560                             ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_slice_nal_type =
3561                                 ps_curr_inp_from_me->i4_slice_nal_type;
3562 
3563                             /* populate sps, vps and pps pointers for the entropy input params */
3564                             ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->ps_pps =
3565                                 &ps_enc_ctxt->as_pps[i4_bitrate_ctr];
3566                             ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->ps_sps =
3567                                 &ps_enc_ctxt->as_sps[i4_bitrate_ctr];
3568                             ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->ps_vps =
3569                                 &ps_enc_ctxt->as_vps[i4_bitrate_ctr];
3570 
3571                             /* SEI header will be populated in pre-enocde stage */
3572                             memcpy(
3573                                 &ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->s_sei,
3574                                 &ps_curr_inp_from_me->s_sei,
3575                                 sizeof(sei_params_t));
3576 
3577                             /*AUD and EOS presnt flags are populated*/
3578                             ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i1_aud_present_flag =
3579                                 ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_aud_enable_flags;
3580 
3581                             ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i1_eos_present_flag =
3582                                 ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_eos_enable_flags;
3583 
3584                             /* Information required for SEI Picture timing info */
3585                             {
3586                                 ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_display_num =
3587                                     ps_curr_inp->s_lap_out.i4_display_num;
3588                             }
3589 
3590                             /* The Qp populated in Pre enc stage needs to overwritten with Qp
3591                         queried from rate control*/
3592                             ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]
3593                                 ->s_slice_hdr.i1_slice_qp_delta =
3594                                 (WORD8)ps_curr_inp_from_me->i4_curr_frm_qp -
3595                                 ps_enc_ctxt->as_pps[i4_bitrate_ctr].i1_pic_init_qp;
3596                         }
3597 
3598                         /* ------- get a filled descriptor from output Que ------------ */
3599                         if(/*(1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag) &&*/
3600                            (ps_enc_ctxt->ps_stat_prms->i4_save_recon != 0))
3601                         {
3602                             /*swaping of buf_id for 0th and reference bitrate location, as encoder
3603                         assumes always 0th loc for reference bitrate and app must receive in
3604                         the configured order*/
3605                             WORD32 i4_recon_buf_id = i4_bitrate_ctr;
3606                             if(i4_bitrate_ctr == 0)
3607                             {
3608                                 i4_recon_buf_id = ps_enc_ctxt->i4_ref_mbr_id;
3609                             }
3610                             else if(i4_bitrate_ctr == ps_enc_ctxt->i4_ref_mbr_id)
3611                             {
3612                                 i4_recon_buf_id = 0;
3613                             }
3614 
3615                             /* ------- get free Recon buffer from Frame buffer que ---------- */
3616                             /* There is a separate queue for each bit-rate instnace. The recon
3617                         buffer is acquired from the corresponding queue based on the
3618                         bitrate instnace */
3619                             ps_enc_ctxt->s_multi_thrd.ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr] =
3620                                 (iv_enc_recon_data_buffs_t *)ihevce_q_get_filled_buff(
3621                                     (void *)ps_enc_ctxt,
3622                                     IHEVCE_RECON_DATA_Q +
3623                                         i4_recon_buf_id, /*decides the buffer queue */
3624                                     &ps_enc_ctxt->s_multi_thrd
3625                                          .recon_buf_id[i4_enc_frm_id][i4_bitrate_ctr],
3626                                     BUFF_QUE_BLOCKING_MODE);
3627 
3628                             ps_enc_ctxt->s_multi_thrd
3629                                 .is_recon_dumped[i4_enc_frm_id][i4_bitrate_ctr] = 0;
3630                             ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr] =
3631                                 ps_enc_ctxt->s_multi_thrd
3632                                     .ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr];
3633 
3634                             ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_end_flag =
3635                                 ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3636                                     ->i4_end_flag;
3637                         }
3638 
3639                     }  //bitrate ctr
3640                 }
3641             }
3642             if(ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id] != NULL)
3643             {
3644                 ps_curr_inp =
3645                     ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]->ps_curr_inp;
3646                 ps_curr_inp_from_me = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3647                                           ->ps_curr_inp_from_me_prms;
3648                 ps_curr_inp_enc = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id];
3649                 ps_curr_L0_IPE_inp_prms =
3650                     ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3651                         ->ps_curr_inp_from_l0_ipe_prms;
3652             }
3653             if((NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]) &&
3654                ((1 == ps_curr_inp_enc->i4_frm_proc_valid_flag) &&
3655                 (ps_enc_ctxt->s_multi_thrd.enc_master_done_frame_init[i4_enc_frm_id] == 0)))
3656             {
3657                 for(i = 0; i < i4_num_bitrates; i++)
3658                 {
3659                     aps_ref_list = ps_curr_inp_enc->aps_ref_list[i];
3660                     /* acquire mutex lock for rate control calls */
3661                     osal_mutex_lock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
3662 
3663                     /*utlize the satd data from pre enc stage to get more accurate estimate SAD for I pic*/
3664                     if(ps_curr_inp->s_lap_out.i4_pic_type == IV_I_FRAME ||
3665                        ps_curr_inp->s_lap_out.i4_pic_type == IV_IDR_FRAME)
3666                     {
3667                         ihevce_rc_update_cur_frm_intra_satd(
3668                             (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
3669                             ps_curr_inp_from_me->i8_frame_acc_satd_cost,
3670                             ps_enc_ctxt->i4_active_enc_frame_id);
3671                     }
3672 
3673                     /*pels assuming satd/act is obtained for entire frame*/
3674                     ps_curr_inp->s_rc_lap_out.i4_num_pels_in_frame_considered =
3675                         ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht *
3676                         ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd;
3677 
3678                     /*Service pending request to change average bitrate if any*/
3679                     {
3680                         LWORD64 i8_new_bitrate =
3681                             ihevce_rc_get_new_bitrate(ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0]);
3682                         LWORD64 i8_new_peak_bitrate = ihevce_rc_get_new_peak_bitrate(
3683                             ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0]);
3684                         ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3685                             ->i8_buf_level_bitrate_change = -1;
3686                         if((i8_new_bitrate != -1) &&
3687                            (i8_new_peak_bitrate != -1)) /*-1 indicates no pending request*/
3688                         {
3689                             LWORD64 buffer_level = ihevce_rc_change_avg_bitrate(
3690                                 ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0]);
3691                             ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3692                                 ->i8_buf_level_bitrate_change = buffer_level;
3693                         }
3694                     }
3695 
3696                     if((1 == ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.i4_mres_single_out) &&
3697                        (1 == ps_curr_inp->s_lap_out.i4_first_frm_new_res))
3698                     {
3699                         /* Whenver change in resolution happens change the buffer level */
3700                         ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3701                             ->i8_buf_level_bitrate_change = 0;
3702                     }
3703 #if 1  //KISH ELP
3704                     {
3705                         rc_bits_sad_t as_rc_frame_stat[IHEVCE_MAX_NUM_BITRATES];
3706 
3707                         if(ps_enc_ctxt->ai4_rc_query[i] ==
3708                            ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc)  //KISH
3709                         {
3710                             WORD32 out_buf_id[IHEVCE_MAX_NUM_BITRATES];
3711                             WORD32 i4_pic_type;
3712                             WORD32 cur_qp[IHEVCE_MAX_NUM_BITRATES];
3713                             ihevce_lap_output_params_t s_lap_out;
3714 
3715                             rc_lap_out_params_t s_rc_lap_out;
3716                             WORD32 i4_suppress_bpic_update;
3717 
3718                             ihevce_rc_store_retrive_update_info(
3719                                 (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
3720                                 &as_rc_frame_stat[i],
3721                                 ps_enc_ctxt->i4_active_enc_frame_id,
3722                                 i,
3723                                 2,
3724                                 &out_buf_id[i],
3725                                 &i4_pic_type,
3726                                 &cur_qp[i],
3727                                 (void *)&s_lap_out,
3728                                 (void *)&s_rc_lap_out);
3729 
3730                             i4_suppress_bpic_update =
3731                                 (WORD32)(s_rc_lap_out.i4_rc_temporal_lyr_id > 1);
3732                             /*RC inter face update before update to happen only for ELP disabled */
3733                             if(1 == ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc)
3734                             {
3735                                 /* SGI & Enc Loop Parallelism related changes*/
3736                                 ihevce_rc_interface_update(
3737                                     (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
3738                                     (IV_PICTURE_CODING_TYPE_T)s_rc_lap_out.i4_rc_pic_type,
3739                                     &s_rc_lap_out,
3740                                     cur_qp[i],
3741                                     i4_enc_frm_id_rc);
3742                             }
3743 
3744                             ihevce_rc_update_pic_info(
3745                                 (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
3746                                 (as_rc_frame_stat[i].u4_total_texture_bits +
3747                                  as_rc_frame_stat[i].u4_total_header_bits),  //pass total bits
3748                                 as_rc_frame_stat[i].u4_total_header_bits,
3749                                 as_rc_frame_stat[i].u4_total_sad,
3750                                 as_rc_frame_stat[i].u4_total_intra_sad,
3751                                 (IV_PICTURE_CODING_TYPE_T)i4_pic_type,
3752                                 cur_qp[i],
3753                                 i4_suppress_bpic_update,
3754                                 as_rc_frame_stat[i].i4_qp_normalized_8x8_cu_sum,
3755                                 as_rc_frame_stat[i].i4_8x8_cu_sum,
3756                                 as_rc_frame_stat[i].i8_sad_by_qscale,
3757                                 &s_lap_out,
3758                                 &s_rc_lap_out,
3759                                 out_buf_id[i],
3760                                 as_rc_frame_stat[i].u4_open_loop_intra_sad,
3761                                 as_rc_frame_stat[i].i8_total_ssd_frame,
3762                                 ps_enc_ctxt
3763                                     ->i4_active_enc_frame_id);  //ps_curr_out->i4_inp_timestamp_low)
3764 
3765                             //DBG_PRINTF("\n Sad = %d \t total bits = %d ", s_rc_frame_stat.u4_total_sad, (s_rc_frame_stat.u4_total_texture_bits + s_rc_frame_stat.u4_total_header_bits));
3766                             /*populate qp for pre enc*/
3767 
3768                             //g_count--;
3769                             ps_enc_ctxt->ai4_rc_query[i]--;
3770 
3771                             if(i == (i4_num_bitrates - 1))
3772                             {
3773                                 ihevce_rc_cal_pre_enc_qp(
3774                                     (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0]);
3775 
3776                                 ps_enc_ctxt->i4_active_enc_frame_id++;
3777                                 ps_enc_ctxt->i4_active_enc_frame_id =
3778                                     (ps_enc_ctxt->i4_active_enc_frame_id %
3779                                      ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc);
3780                             }
3781                         }
3782                     }
3783 #endif
3784                     if(ps_enc_ctxt->ai4_rc_query[i] < ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc)
3785                     {
3786                         /*HEVC_RC query rate control for qp*/
3787                         ai4_cur_qp[i] = ihevce_rc_get_pic_quant(
3788                             (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
3789                             &ps_curr_inp->s_rc_lap_out,
3790                             ENC_GET_QP,
3791                             i4_enc_frm_id_rc,
3792                             0,
3793                             &ps_curr_inp->s_lap_out.ai4_frame_bits_estimated[i]);
3794 
3795                         ps_curr_inp->s_rc_lap_out.i4_orig_rc_qp = ai4_cur_qp[i];
3796 
3797                         ps_enc_ctxt->s_multi_thrd.i4_in_frame_rc_enabled = 0;
3798                         ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3799                             ->i4_sub_pic_level_rc = 0;
3800                         ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3801                             ->ai4_frame_bits_estimated =
3802                             ps_curr_inp->s_lap_out.ai4_frame_bits_estimated[i];
3803 
3804                         {
3805                             ps_enc_ctxt->ai4_rc_query[i]++;
3806                         }
3807                     }
3808 
3809                     /* SGI & Enc Loop Parallelism related changes*/
3810                     ihevce_rc_interface_update(
3811                         (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
3812                         (IV_PICTURE_CODING_TYPE_T)ps_curr_inp->s_lap_out.i4_pic_type,
3813                         &ps_curr_inp->s_rc_lap_out,
3814                         ai4_cur_qp[i],
3815                         i4_enc_frm_id_rc);
3816 
3817                     //DBG_PRINTF("HEVC_QP = %d  MPEG2_QP = %d\n",cur_qp,gu1_HEVCToMpeg2Quant[cur_qp]);//i_model_print
3818 
3819                     /* release mutex lock after rate control calls */
3820                     osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
3821 
3822                     ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3823                         ->s_slice_hdr.i1_slice_qp_delta =
3824                         (WORD8)ai4_cur_qp[i] - ps_enc_ctxt->as_pps[i].i1_pic_init_qp;
3825 
3826                     ps_enc_ctxt->s_multi_thrd.cur_qp[i4_enc_frm_id][i] = ai4_cur_qp[i];
3827 
3828                     /* For interlace pictures, first_field depends on topfield_first and bottom field */
3829                     if(i4_field_pic)
3830                     {
3831                         first_field =
3832                             (ps_curr_inp->s_input_buf.i4_topfield_first ^
3833                              ps_curr_inp->s_input_buf.i4_bottom_field);
3834                     }
3835                     /* get frame level lambda params */
3836                     ihevce_get_frame_lambda_prms(
3837                         ps_enc_ctxt,
3838                         ps_curr_inp_from_me,
3839                         ai4_cur_qp[i],
3840                         first_field,
3841                         ps_curr_inp->s_lap_out.i4_is_ref_pic,
3842                         ps_curr_inp->s_lap_out.i4_temporal_lyr_id,
3843                         ps_curr_inp->s_lap_out.f_i_pic_lamda_modifier,
3844                         i,
3845                         ENC_LOOP_LAMBDA_TYPE);
3846 
3847 #if ADAPT_COLOCATED_FROM_L0_FLAG
3848                     ps_enc_ctxt->s_multi_thrd.ps_frm_recon[i4_enc_frm_id][i]->i4_frame_qp =
3849                         ai4_cur_qp[i];
3850 #endif
3851                 }  //bitrate counter ends
3852 
3853                 /* Reset the Dependency Mngrs local to EncLoop., ie CU_TopRight and Dblk */
3854                 ihevce_enc_loop_dep_mngr_frame_reset(
3855                     ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt, i4_enc_frm_id);
3856             }
3857 
3858             {
3859                 /*Set the master done flag for frame init so that other
3860                 * threads can skip it
3861                 */
3862                 ps_enc_ctxt->s_multi_thrd.enc_master_done_frame_init[i4_enc_frm_id] = 1;
3863             }
3864 
3865             /************************************/
3866             /******  EXIT CRITICAL SECTION ******/
3867             /************************************/
3868 
3869             /****** Unlock the critical section ******/
3870             if(NULL != pv_mutex_handle_frame_init)
3871             {
3872                 result_frame_init = osal_mutex_unlock(pv_mutex_handle_frame_init);
3873                 if(OSAL_SUCCESS != result_frame_init)
3874                     return 0;
3875             }
3876             ps_enc_ctxt->s_multi_thrd.i4_encode = 1;
3877             ps_enc_ctxt->s_multi_thrd.i4_num_re_enc = 0;
3878             /************************************/
3879             /******  Do Enc loop process   ******/
3880             /************************************/
3881             /* Each thread will run the enc-loop.
3882             Each thread will initialize it's own enc_loop context and do the processing.
3883             Each thread will run all the bit-rate instances one after another */
3884             if((i4_enc_end_flag == 0) &&
3885                (NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]) &&
3886                (1 == ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3887                          ->i4_frm_proc_valid_flag))
3888             {
3889                 while(1)
3890                 {
3891                     ctb_enc_loop_out_t *ps_ctb_enc_loop_frm[IHEVCE_MAX_NUM_BITRATES];
3892                     cu_enc_loop_out_t *ps_cu_enc_loop_frm[IHEVCE_MAX_NUM_BITRATES];
3893                     tu_enc_loop_out_t *ps_tu_frm[IHEVCE_MAX_NUM_BITRATES];
3894                     pu_t *ps_pu_frm[IHEVCE_MAX_NUM_BITRATES];
3895                     UWORD8 *pu1_frm_coeffs[IHEVCE_MAX_NUM_BITRATES];
3896                     me_master_ctxt_t *ps_master_me_ctxt =
3897                         (me_master_ctxt_t *)ps_enc_ctxt->s_module_ctxt.pv_me_ctxt;
3898                     ihevce_enc_loop_master_ctxt_t *ps_master_ctxt =
3899                         (ihevce_enc_loop_master_ctxt_t *)ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt;
3900 
3901                     for(i = 0; i < i4_num_bitrates; i++)
3902                     {
3903                         if(i4_thrd_id == 0)
3904                         {
3905                             PROFILE_START(
3906                                 &ps_hle_ctxt->profile_enc[ps_enc_ctxt->i4_resolution_id][i]);
3907                         }
3908                         if(NULL != ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id])
3909                         {
3910                             ps_ctb_enc_loop_frm[i] =
3911                                 ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3912                                     ->ps_frm_ctb_data;
3913                             ps_cu_enc_loop_frm[i] =
3914                                 ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3915                                     ->ps_frm_cu_data;
3916                             ps_tu_frm[i] =
3917                                 ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3918                                     ->ps_frm_tu_data;
3919                             ps_pu_frm[i] =
3920                                 ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3921                                     ->ps_frm_pu_data;
3922                             pu1_frm_coeffs[i] = (UWORD8 *)ps_enc_ctxt->s_multi_thrd
3923                                                     .ps_curr_out_enc_grp[i4_enc_frm_id][i]
3924                                                     ->pv_coeff_data;
3925                         }
3926                         /*derive reference picture list based on ping or pong instnace */
3927                         aps_ref_list = ps_curr_inp_enc->aps_ref_list[i];
3928 
3929                         /* Always consider chroma cost when computing cost for derived instance */
3930                         ps_master_ctxt->aps_enc_loop_thrd_ctxt[i4_thrd_id]->i4_consider_chroma_cost =
3931                             1;
3932 
3933                         /*************************
3934                         * MULTI BITRATE CODE START
3935                         **************************/
3936                         if(i4_num_bitrates > 1)
3937                         {
3938                             ihevce_mbr_quality_tool_set_configuration(
3939                                 ps_master_ctxt->aps_enc_loop_thrd_ctxt[i4_thrd_id],
3940                                 ps_enc_ctxt->ps_stat_prms);
3941                         }
3942                         /************************
3943                         * MULTI BITRATE CODE END
3944                         *************************/
3945                         /* picture level init of Encode loop module */
3946                         ihevce_enc_loop_frame_init(
3947                             ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt,
3948                             ps_enc_ctxt->s_multi_thrd.cur_qp[i4_enc_frm_id][i],
3949                             aps_ref_list,
3950                             ps_enc_ctxt->s_multi_thrd.ps_frm_recon[i4_enc_frm_id][i],
3951                             &ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3952                                  ->s_slice_hdr,
3953                             ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]->ps_pps,
3954                             ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]->ps_sps,
3955                             ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]->ps_vps,
3956                             ps_curr_inp_enc->ps_curr_inp->s_lap_out.i1_weighted_pred_flag,
3957                             ps_curr_inp_enc->ps_curr_inp->s_lap_out.i1_weighted_bipred_flag,
3958                             ps_curr_inp_enc->ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom,
3959                             ps_curr_inp_enc->ps_curr_inp->s_lap_out.i4_log2_chroma_wght_denom,
3960                             ps_curr_inp_enc->ps_curr_inp->s_lap_out.i4_poc,
3961                             ps_curr_inp_enc->ps_curr_inp->s_lap_out.i4_display_num,
3962                             ps_enc_ctxt,
3963                             ps_curr_inp_enc,
3964                             i,
3965                             i4_thrd_id,
3966                             i4_enc_frm_id,  // update this to enc_loop_ctxt struct
3967                             i4_num_bitrates,
3968                             ps_curr_inp_enc->ps_curr_inp->s_lap_out.i4_quality_preset,
3969                             ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3970                                 ->pv_dep_mngr_encloop_dep_me);
3971 
3972                         ihevce_enc_loop_process(
3973                             ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt,
3974                             ps_curr_inp,
3975                             ps_curr_inp_from_me->ps_ctb_analyse,
3976                             ps_curr_L0_IPE_inp_prms->ps_ipe_analyse_ctb,
3977                             ps_enc_ctxt->s_multi_thrd.ps_frm_recon[i4_enc_frm_id][i],
3978                             ps_curr_inp_enc->ps_cur_ctb_cu_tree,
3979                             ps_ctb_enc_loop_frm[i],
3980                             ps_cu_enc_loop_frm[i],
3981                             ps_tu_frm[i],
3982                             ps_pu_frm[i],
3983                             pu1_frm_coeffs[i],
3984                             &ps_enc_ctxt->s_frm_ctb_prms,
3985                             &ps_curr_inp_from_me->as_lambda_prms[i],
3986                             &ps_enc_ctxt->s_multi_thrd,
3987                             i4_thrd_id,
3988                             i4_enc_frm_id,
3989                             ps_enc_ctxt->ps_stat_prms->s_pass_prms.i4_pass);
3990                         if(i4_thrd_id == 0)
3991                         {
3992                             PROFILE_STOP(
3993                                 &ps_hle_ctxt->profile_enc[ps_enc_ctxt->i4_resolution_id][i], NULL);
3994                         }
3995                     }  //loop over bitrate ends
3996                     {
3997                         break;
3998                     }
3999                 } /*end of while(ps_enc_ctxt->s_multi_thrd.ai4_encode[i4_enc_frm_id] == 1)*/
4000             }
4001 
4002             /************************************/
4003             /****** ENTER CRITICAL SECTION ******/
4004             /************************************/
4005 
4006             /****** Lock the critical section ******/
4007             if(NULL != ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id])
4008             {
4009                 result = osal_mutex_lock(
4010                     ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id]);
4011 
4012                 if(OSAL_SUCCESS != result)
4013                     return 0;
4014             }
4015             if(ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id] != NULL)
4016             {
4017                 /* Increment the counter to keep track of no of threads exiting the current mutex*/
4018                 ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_enc_frm_id]++;
4019 
4020                 /* If the end frame is reached force the last slave to enter the next critical section*/
4021                 if(i4_enc_end_flag == 1)
4022                 {
4023                     if(ps_enc_ctxt->s_multi_thrd.num_thrds_done ==
4024                        ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds - 1)
4025                     {
4026                         ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_enc_frm_id] =
4027                             ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds;
4028                     }
4029                 }
4030 
4031                 {
4032                     /*Last slave thread comming out of enc loop will execute next critical section*/
4033                     if(ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_enc_frm_id] ==
4034                        ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds)
4035                     {
4036                         iv_enc_recon_data_buffs_t *ps_recon_out_temp = NULL;
4037                         recon_pic_buf_t *ps_frm_recon_temp = NULL;
4038                         ihevce_lap_enc_buf_t *ps_curr_inp;
4039                         rc_lap_out_params_t *ps_rc_lap_out_next_encode;
4040 
4041                         WORD32 ai4_act_qp[IHEVCE_MAX_NUM_BITRATES];
4042                         ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_enc_frm_id] = 0;
4043 
4044                         ps_curr_inp = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
4045                                           ->ps_curr_inp;
4046 
4047                         for(i = 0; i < i4_num_bitrates; i++)
4048                         {
4049                             {
4050                                 WORD32 j, i4_avg_QP;
4051                                 ihevce_enc_loop_master_ctxt_t *ps_master_ctxt =
4052                                     (ihevce_enc_loop_master_ctxt_t *)
4053                                         ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt;
4054                                 ihevce_enc_loop_ctxt_t *ps_ctxt, *ps_ctxt_temp;
4055                                 ihevce_enc_loop_ctxt_t *ps_ctxt_last_thrd;
4056                                 LWORD64 i8_total_cu_bits_into_qscale = 0, i8_total_cu_bits = 0;
4057                                 UWORD32 total_frame_intra_sad = 0;
4058                                 UWORD32 total_frame_inter_sad = 0;
4059                                 UWORD32 total_frame_sad = 0;
4060 
4061                                 LWORD64 total_frame_intra_cost = 0;
4062                                 LWORD64 total_frame_inter_cost = 0;
4063                                 LWORD64 total_frame_cost = 0;
4064 
4065                                 ps_ctxt_last_thrd =
4066                                     ps_master_ctxt->aps_enc_loop_thrd_ctxt[i4_thrd_id];
4067                                 if(ps_enc_ctxt->s_multi_thrd.i4_in_frame_rc_enabled)
4068                                 {
4069                                     WORD32 i4_total_ctb =
4070                                         ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz *
4071                                         ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_vert;
4072 
4073                                     ai4_act_qp[i] =
4074                                         ps_enc_ctxt->s_multi_thrd
4075                                             .ai4_curr_qp_acc[ps_ctxt_last_thrd->i4_enc_frm_id][i] /
4076                                         i4_total_ctb;
4077                                 }
4078                                 else
4079                                 {
4080                                     ai4_act_qp[i] =
4081                                         ps_enc_ctxt->s_multi_thrd.cur_qp[i4_enc_frm_id][i];
4082                                 }
4083 
4084                                 ps_enc_ctxt->s_multi_thrd
4085                                     .ai4_curr_qp_acc[ps_ctxt_last_thrd->i4_enc_frm_id][i] = 0;
4086 
4087                                 /*Reset all the values of sub pic rc to default after the frame is completed */
4088                                 {
4089                                     ps_enc_ctxt->s_multi_thrd
4090                                         .ai4_acc_ctb_ctr[ps_ctxt_last_thrd->i4_enc_frm_id][i] = 0;
4091                                     ps_enc_ctxt->s_multi_thrd
4092                                         .ai4_ctb_ctr[ps_ctxt_last_thrd->i4_enc_frm_id][i] = 0;
4093 
4094                                     ps_enc_ctxt->s_multi_thrd
4095                                         .ai4_threshold_reached[ps_ctxt_last_thrd->i4_enc_frm_id][i] =
4096                                         0;
4097 
4098                                     ps_enc_ctxt->s_multi_thrd
4099                                         .ai4_curr_qp_estimated[ps_ctxt_last_thrd->i4_enc_frm_id][i] =
4100                                         (1 << QP_LEVEL_MOD_ACT_FACTOR);
4101 
4102                                     ps_enc_ctxt->s_multi_thrd
4103                                         .af_acc_hdr_bits_scale_err[ps_ctxt_last_thrd->i4_enc_frm_id]
4104                                                                   [i] = 0;
4105                                 }
4106                                 for(j = 0; j < ps_master_ctxt->i4_num_proc_thrds; j++)
4107                                 {
4108                                     /* ENC_LOOP state structure */
4109                                     ps_ctxt = ps_master_ctxt->aps_enc_loop_thrd_ctxt[j];
4110 
4111                                     total_frame_intra_sad +=
4112                                         ps_ctxt
4113                                             ->aaps_enc_loop_rc_params[ps_ctxt_last_thrd
4114                                                                           ->i4_enc_frm_id][i]
4115                                             ->u4_frame_intra_sad_acc;
4116                                     total_frame_inter_sad +=
4117                                         ps_ctxt
4118                                             ->aaps_enc_loop_rc_params[ps_ctxt_last_thrd
4119                                                                           ->i4_enc_frm_id][i]
4120                                             ->u4_frame_inter_sad_acc;
4121                                     total_frame_sad +=
4122                                         ps_ctxt
4123                                             ->aaps_enc_loop_rc_params[ps_ctxt_last_thrd
4124                                                                           ->i4_enc_frm_id][i]
4125                                             ->u4_frame_sad_acc;
4126 
4127                                     total_frame_intra_cost +=
4128                                         ps_ctxt
4129                                             ->aaps_enc_loop_rc_params[ps_ctxt_last_thrd
4130                                                                           ->i4_enc_frm_id][i]
4131                                             ->i8_frame_intra_cost_acc;
4132                                     total_frame_inter_cost +=
4133                                         ps_ctxt
4134                                             ->aaps_enc_loop_rc_params[ps_ctxt_last_thrd
4135                                                                           ->i4_enc_frm_id][i]
4136                                             ->i8_frame_inter_cost_acc;
4137                                     total_frame_cost +=
4138                                         ps_ctxt
4139                                             ->aaps_enc_loop_rc_params[ps_ctxt_last_thrd
4140                                                                           ->i4_enc_frm_id][i]
4141                                             ->i8_frame_cost_acc;
4142                                     /*Reset thrd id flag once the frame is completed */
4143                                     ps_enc_ctxt->s_multi_thrd
4144                                         .ai4_thrd_id_valid_flag[ps_ctxt_last_thrd->i4_enc_frm_id][i]
4145                                                                [j] = -1;
4146                                 }
4147                                 ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4148                                     ->s_pic_level_info.u4_frame_sad = total_frame_sad;
4149                                 ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4150                                     ->s_pic_level_info.u4_frame_intra_sad = total_frame_intra_sad;
4151                                 ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4152                                     ->s_pic_level_info.u4_frame_inter_sad = total_frame_inter_sad;
4153 
4154                                 ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4155                                     ->s_pic_level_info.i8_frame_cost = total_frame_cost;
4156                                 ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4157                                     ->s_pic_level_info.i8_frame_intra_cost = total_frame_intra_cost;
4158                                 ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4159                                     ->s_pic_level_info.i8_frame_inter_cost = total_frame_inter_cost;
4160                             }
4161                             ps_enc_ctxt->s_multi_thrd.ai4_produce_outbuf[i4_enc_frm_id][i] = 1;
4162                             ps_recon_out_temp =
4163                                 ps_enc_ctxt->s_multi_thrd.ps_recon_out[i4_enc_frm_id][i];
4164                             ps_frm_recon_temp =
4165                                 ps_enc_ctxt->s_multi_thrd.ps_frm_recon[i4_enc_frm_id][i];
4166 
4167                             /* end of frame processing only if current input is valid */
4168                             if(1 == ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
4169                                         ->i4_frm_proc_valid_flag)
4170                             {
4171                                 /* Calculate the SEI Hash if enabled */
4172                                 if(0 !=
4173                                    ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4174                                        ->s_sei.i1_decoded_pic_hash_sei_flag)
4175                                 {
4176                                     void *pv_y_buf;
4177                                     void *pv_u_buf;
4178 
4179                                     {
4180                                         pv_y_buf = ps_frm_recon_temp->s_yuv_buf_desc.pv_y_buf;
4181                                         pv_u_buf = ps_frm_recon_temp->s_yuv_buf_desc.pv_u_buf;
4182                                     }
4183 
4184                                     ihevce_populate_hash_sei(
4185                                         &ps_enc_ctxt->s_multi_thrd
4186                                              .ps_curr_out_enc_grp[i4_enc_frm_id][i]
4187                                              ->s_sei,
4188                                         ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms
4189                                             .i4_internal_bit_depth,
4190                                         pv_y_buf,
4191                                         ps_frm_recon_temp->s_yuv_buf_desc.i4_y_wd,
4192                                         ps_frm_recon_temp->s_yuv_buf_desc.i4_y_ht,
4193                                         ps_frm_recon_temp->s_yuv_buf_desc.i4_y_strd,
4194                                         pv_u_buf,
4195                                         ps_frm_recon_temp->s_yuv_buf_desc.i4_uv_wd,
4196                                         ps_frm_recon_temp->s_yuv_buf_desc.i4_uv_ht,
4197                                         ps_frm_recon_temp->s_yuv_buf_desc.i4_uv_strd,
4198                                         0,
4199                                         0);
4200                                 }
4201                                 /* Sending qp, poc and pic-type to entropy thread for printing on console */
4202                                 if(ps_enc_ctxt->ps_stat_prms->i4_log_dump_level != 0)
4203                                 {
4204                                     ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4205                                         ->i4_qp =
4206                                         ps_enc_ctxt->s_multi_thrd.cur_qp[i4_enc_frm_id][i];
4207                                     ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4208                                         ->i4_poc = ps_curr_inp->s_lap_out.i4_poc;
4209                                     ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4210                                         ->i4_pic_type = ps_curr_inp->s_lap_out.i4_pic_type;
4211                                 }
4212 
4213                                 ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4214                                     ->i4_is_I_scenecut =
4215                                     ((ps_curr_inp->s_lap_out.i4_scene_type == 1) &&
4216                                      (ps_curr_inp->s_lap_out.i4_pic_type == IV_IDR_FRAME ||
4217                                       ps_curr_inp->s_lap_out.i4_pic_type == IV_I_FRAME));
4218 
4219                                 ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4220                                     ->i4_is_non_I_scenecut =
4221                                     ((ps_curr_inp->s_lap_out.i4_scene_type ==
4222                                       SCENE_TYPE_SCENE_CUT) &&
4223                                      (ps_enc_ctxt->s_multi_thrd
4224                                           .ps_curr_out_enc_grp[i4_enc_frm_id][i]
4225                                           ->i4_is_I_scenecut == 0));
4226 
4227                                 /*ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]->i4_is_I_only_scd   = ps_curr_inp->s_lap_out.i4_is_I_only_scd;
4228                                 ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]->i4_is_non_I_scd    = ps_curr_inp->s_lap_out.i4_is_non_I_scd;
4229 
4230                                 ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]->i4_is_model_valid    = ps_curr_inp->s_lap_out.i4_is_model_valid;*/
4231 
4232                                 /* -------------------------------------------- */
4233                                 /*        MSE Computation for PSNR              */
4234                                 /* -------------------------------------------- */
4235                                 if(ps_enc_ctxt->ps_stat_prms->i4_log_dump_level != 0)
4236                                 {
4237                                     ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4238                                         ->i4_qp =
4239                                         ps_enc_ctxt->s_multi_thrd.cur_qp[i4_enc_frm_id][i];
4240                                     ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4241                                         ->i4_poc = ps_curr_inp->s_lap_out.i4_poc;
4242                                     ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4243                                         ->i4_pic_type = ps_curr_inp->s_lap_out.i4_pic_type;
4244                                 }
4245 
4246                                 /* if non reference B picture */
4247                                 if(0 == ps_frm_recon_temp->i4_is_reference)
4248                                 {
4249                                     ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4250                                         ->i4_pic_type += 2;
4251                                 }
4252 
4253 #define FORCE_EXT_REF_PIC 0
4254 
4255                                 /* -------------------------------------------- */
4256                                 /*        Dumping of recon to App Queue         */
4257                                 /* -------------------------------------------- */
4258                                 if(1 == ps_enc_ctxt->ps_stat_prms->i4_save_recon)
4259                                 {
4260                                     {
4261                                         WORD32 i, j;
4262                                         UWORD8 *pu1_recon;
4263                                         UWORD8 *pu1_chrm_buf_u;
4264                                         UWORD8 *pu1_chrm_buf_v;
4265                                         UWORD8 *pu1_curr_recon;
4266 
4267                                         pu1_recon =
4268                                             (UWORD8 *)ps_frm_recon_temp->s_yuv_buf_desc.pv_y_buf;
4269 
4270                                         /** Copying Luma into recon buffer  **/
4271                                         pu1_curr_recon = (UWORD8 *)ps_recon_out_temp->pv_y_buf;
4272 
4273                                         for(j = 0; j < ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht;
4274                                             j++)
4275                                         {
4276                                             memcpy(
4277                                                 pu1_curr_recon,
4278                                                 pu1_recon,
4279                                                 ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd);
4280 
4281                                             pu1_recon +=
4282                                                 ps_frm_recon_temp->s_yuv_buf_desc.i4_y_strd;
4283                                             pu1_curr_recon +=
4284                                                 ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd;
4285                                         }
4286 
4287                                         /* recon chroma is converted from Semiplanar to Planar for dumping */
4288                                         pu1_recon =
4289                                             (UWORD8 *)ps_frm_recon_temp->s_yuv_buf_desc.pv_u_buf;
4290                                         pu1_chrm_buf_u = (UWORD8 *)ps_recon_out_temp->pv_cb_buf;
4291                                         pu1_chrm_buf_v =
4292                                             pu1_chrm_buf_u +
4293                                             ((ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd >> 1) *
4294                                              ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht);
4295 
4296                                         for(j = 0; j < ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht;
4297                                             j++)
4298                                         {
4299                                             for(i = 0;
4300                                                 i<ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd>> 1;
4301                                                 i++)
4302                                             {
4303                                                 *pu1_chrm_buf_u++ = *pu1_recon++;
4304                                                 *pu1_chrm_buf_v++ = *pu1_recon++;
4305                                             }
4306 
4307                                             pu1_recon -=
4308                                                 ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd;
4309                                             pu1_recon +=
4310                                                 ps_frm_recon_temp->s_yuv_buf_desc.i4_uv_strd;
4311                                         }
4312 
4313                                         /* set the POC and number of bytes in Y & UV buf */
4314                                         ps_recon_out_temp->i4_poc = ps_frm_recon_temp->i4_poc;
4315                                         ps_recon_out_temp->i4_y_pixels =
4316                                             ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht *
4317                                             ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd;
4318                                         ps_recon_out_temp->i4_uv_pixels =
4319                                             ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd *
4320                                             ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht;
4321                                     }
4322                                 }
4323                                 ps_frm_recon_temp->i4_non_ref_free_flag = 1;
4324                                 /* -------------------------------------------- */
4325                                 /*        End of picture updates                */
4326                                 /* -------------------------------------------- */
4327                             }
4328 
4329                             /* After the MSE (or PSNR) computation is done we will update
4330                     these data in output buffer structure and then signal entropy
4331                     thread that the buffer is produced. */
4332                             if(ps_enc_ctxt->s_multi_thrd.ai4_produce_outbuf[i4_enc_frm_id][i] == 1)
4333                             {
4334                                 /* set the output buffer as produced */
4335                                 ihevce_q_set_buff_prod(
4336                                     (void *)ps_enc_ctxt,
4337                                     IHEVCE_FRM_PRS_ENT_COD_Q + i,
4338                                     ps_enc_ctxt->s_multi_thrd.out_buf_id[i4_enc_frm_id][i]);
4339 
4340                                 ps_enc_ctxt->s_multi_thrd.is_out_buf_freed[i4_enc_frm_id][i] = 1;
4341                                 ps_enc_ctxt->s_multi_thrd.ai4_produce_outbuf[i4_enc_frm_id][i] = 0;
4342                             }
4343 
4344                         }  //bit-rate counter ends
4345                         /* -------------------------------------------- */
4346                         /*        Frame level RC update                 */
4347                         /* -------------------------------------------- */
4348                         /* Query enc_loop to get the Parameters for Rate control */
4349                         if(1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag)
4350                         {
4351                             frm_proc_ent_cod_ctxt_t *ps_curr_out = NULL;
4352                             /*HEVC_RC*/
4353                             rc_bits_sad_t as_rc_frame_stat[IHEVCE_MAX_NUM_BITRATES];
4354                             osal_mutex_lock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
4355 
4356                             for(i = 0; i < i4_num_bitrates; i++)
4357                             {
4358                                 /*each bit-rate RC params are collated by master thread */
4359                                 ihevce_enc_loop_get_frame_rc_prms(
4360                                     ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt,
4361                                     &as_rc_frame_stat[i],
4362                                     i,
4363                                     i4_enc_frm_id);
4364 
4365                                 /*update bits estimate on rd opt thread so that mismatch between rdopt and entropy can be taken care of*/
4366                                 ps_curr_out =
4367                                     ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i];
4368 
4369                                 ps_rc_lap_out_next_encode =
4370                                     (rc_lap_out_params_t *)
4371                                         ps_curr_inp->s_rc_lap_out.ps_rc_lap_out_next_encode;
4372 
4373                                 ps_curr_out->i4_is_end_of_idr_gop = 0;
4374 
4375                                 if(NULL != ps_rc_lap_out_next_encode)
4376                                 {
4377                                     if(ps_rc_lap_out_next_encode->i4_rc_pic_type == IV_IDR_FRAME)
4378                                     {
4379                                         /*If the next pic is IDR, then signal end of gopf for current frame*/
4380                                         ps_curr_out->i4_is_end_of_idr_gop = 1;
4381                                     }
4382                                 }
4383                                 else if(NULL == ps_rc_lap_out_next_encode)
4384                                 {
4385                                     /*If the lap out next is NULL, then end of sequence reached*/
4386                                     ps_curr_out->i4_is_end_of_idr_gop = 1;
4387                                 }
4388 
4389                                 if(NULL == ps_curr_out)
4390                                 {
4391                                     DBG_PRINTF("error in getting curr out in encode loop\n");
4392                                 }
4393 
4394                                 //DBG_PRINTF("\nRDOPT head = %d RDOPT text = %d\n",s_rc_frame_stat.u4_total_header_bits,s_rc_frame_stat.u4_total_texture_bits);
4395                                 /* acquire mutex lock for rate control calls */
4396 
4397                                 /* Note : u4_total_intra_sad coming out of enc_loop */
4398                                 /* will not be accurate becos of intra gating       */
4399                                 /* need to access the importance of this sad in RC  */
4400 
4401                                 //Store the rc update parameters for deterministic Enc loop parallelism
4402 
4403                                 {
4404                                     ihevce_rc_store_retrive_update_info(
4405                                         (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
4406                                         &as_rc_frame_stat[i],
4407                                         i4_enc_frm_id_rc,
4408                                         i,
4409                                         1,
4410                                         &ps_enc_ctxt->s_multi_thrd.out_buf_id[i4_enc_frm_id][i],
4411                                         &ps_curr_inp->s_lap_out.i4_pic_type,
4412                                         &ai4_act_qp[i],
4413                                         (void *)&ps_curr_inp->s_lap_out,
4414                                         (void *)&ps_curr_inp->s_rc_lap_out);  // STORE
4415                                 }
4416                             }
4417 
4418                             /* release mutex lock after rate control calls */
4419                             osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
4420                         }
4421                         if((ps_enc_ctxt->ps_stat_prms->i4_save_recon != 0) /*&&
4422                                                                    (1 == ps_curr_inp->s_input_buf.s_input_buf.i4_inp_frm_data_valid_flag)*/)
4423                         {
4424                             WORD32 i4_bitrate_ctr;
4425                             for(i4_bitrate_ctr = 0; i4_bitrate_ctr < i4_num_bitrates;
4426                                 i4_bitrate_ctr++)
4427                             {
4428                                 /*swaping of buf_id for 0th and reference bitrate location, as encoder
4429                         assumes always 0th loc for reference bitrate and app must receive in
4430                         the configured order*/
4431                                 WORD32 i4_recon_buf_id = i4_bitrate_ctr;
4432                                 if(i4_bitrate_ctr == 0)
4433                                 {
4434                                     i4_recon_buf_id = ps_enc_ctxt->i4_ref_mbr_id;
4435                                 }
4436                                 else if(i4_bitrate_ctr == ps_enc_ctxt->i4_ref_mbr_id)
4437                                 {
4438                                     i4_recon_buf_id = 0;
4439                                 }
4440 
4441                                 /* Call back to Apln. saying recon buffer is produced */
4442                                 ps_hle_ctxt->ihevce_output_recon_fill_done(
4443                                     ps_hle_ctxt->pv_recon_cb_handle,
4444                                     ps_enc_ctxt->s_multi_thrd
4445                                         .ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr],
4446                                     i4_recon_buf_id, /* br instance */
4447                                     i4_resolution_id /* res_intance */);
4448 
4449                                 /* --- release the current recon buffer ---- */
4450                                 ihevce_q_rel_buf(
4451                                     (void *)ps_enc_ctxt,
4452                                     (IHEVCE_RECON_DATA_Q + i4_recon_buf_id),
4453                                     ps_enc_ctxt->s_multi_thrd
4454                                         .recon_buf_id[i4_enc_frm_id][i4_bitrate_ctr]);
4455 
4456                                 ps_enc_ctxt->s_multi_thrd
4457                                     .is_recon_dumped[i4_enc_frm_id][i4_bitrate_ctr] = 1;
4458                             }
4459                         }
4460 
4461                         if(i4_enc_end_flag == 1)
4462                         {
4463                             if(ps_enc_ctxt->s_multi_thrd.is_in_buf_freed[i4_enc_frm_id] == 0)
4464                             {
4465                                 /* release the pre_enc/enc queue buffer */
4466                                 ihevce_q_rel_buf(
4467                                     (void *)ps_enc_ctxt,
4468                                     IHEVCE_PRE_ENC_ME_Q,
4469                                     ps_curr_inp_enc->curr_inp_from_me_buf_id);
4470 
4471                                 ps_enc_ctxt->s_multi_thrd.is_in_buf_freed[i4_enc_frm_id] = 1;
4472                             }
4473                         }
4474                         /* release encoder owned input buffer*/
4475                         ihevce_q_rel_buf(
4476                             (void *)ps_enc_ctxt,
4477                             IHEVCE_INPUT_DATA_CTRL_Q,
4478                             ps_curr_inp_enc->curr_inp_buf_id);
4479                         /* release the pre_enc/enc queue buffer */
4480                         ihevce_q_rel_buf(
4481                             ps_enc_ctxt,
4482                             IHEVCE_PRE_ENC_ME_Q,
4483                             ps_curr_inp_enc->curr_inp_from_me_buf_id);
4484 
4485                         ps_enc_ctxt->s_multi_thrd.is_in_buf_freed[i4_enc_frm_id] = 1;
4486 
4487                         /* release the pre_enc/enc queue buffer */
4488                         ihevce_q_rel_buf(
4489                             ps_enc_ctxt,
4490                             IHEVCE_L0_IPE_ENC_Q,
4491                             ps_curr_inp_enc->curr_inp_from_l0_ipe_buf_id);
4492 
4493                         ps_enc_ctxt->s_multi_thrd.is_L0_ipe_in_buf_freed[i4_enc_frm_id] = 1;
4494                         /* release the me/enc queue buffer */
4495                         ihevce_q_rel_buf(
4496                             ps_enc_ctxt,
4497                             IHEVCE_ME_ENC_RDOPT_Q,
4498                             ps_enc_ctxt->s_multi_thrd.i4_enc_in_buf_id[i4_enc_frm_id]);
4499 
4500                         /* reset the pointers to NULL */
4501                         ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id] = NULL;
4502                         ps_enc_ctxt->s_multi_thrd.enc_master_done_frame_init[i4_enc_frm_id] = 0;
4503                         for(i = 0; i < i4_num_bitrates; i++)
4504                             ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i] = NULL;
4505 
4506                         /* Set the prev_frame_done variable to 1 to indicate that
4507                 *prev frame is done */
4508                         ihevce_dmgr_update_frm_frm_sync(pv_dep_mngr_prev_frame_done);
4509                     }
4510                 }
4511             }
4512             else
4513             {
4514                 /* Increment the counter to keep track of no of threads exiting the current mutex*/
4515                 ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_enc_frm_id]++;
4516                 /*Last slave thread comming out of enc loop will execute next critical section*/
4517                 if(ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_enc_frm_id] ==
4518                    ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds)
4519                 {
4520                     ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_enc_frm_id] = 0;
4521 
4522                     /* reset the pointers to NULL */
4523                     ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id] = NULL;
4524 
4525                     ps_enc_ctxt->s_multi_thrd.enc_master_done_frame_init[i4_enc_frm_id] = 0;
4526 
4527                     for(i = 0; i < i4_num_bitrates; i++)
4528                         ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i] = NULL;
4529 
4530                     /* Set the prev_frame_done variable to 1 to indicate that
4531                         *prev frame is done
4532                         */
4533                     ihevce_dmgr_update_frm_frm_sync(pv_dep_mngr_prev_frame_done);
4534                 }
4535             }
4536 
4537             /* Toggle the ping pong flag of the thread exiting curr frame*/
4538             /*ps_enc_ctxt->s_multi_thrd.ping_pong[ps_thrd_ctxt->i4_thrd_id] =
4539                 !ps_enc_ctxt->s_multi_thrd.ping_pong[ps_thrd_ctxt->i4_thrd_id];*/
4540         }
4541 
4542         /************************************/
4543         /******  EXIT CRITICAL SECTION ******/
4544         /************************************/
4545         /****** Unlock the critical section ******/
4546         if(NULL != ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id])
4547         {
4548             result = osal_mutex_unlock(
4549                 ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id]);
4550             if(OSAL_SUCCESS != result)
4551                 return 0;
4552         }
4553 
4554         if((0 == i4_me_end_flag) && (0 == i4_enc_end_flag))
4555         {
4556             i4_enc_frm_id++;
4557             i4_enc_frm_id_rc++;
4558 
4559             if(i4_enc_frm_id == NUM_ME_ENC_BUFS)
4560             {
4561                 i4_enc_frm_id = 0;
4562             }
4563 
4564             if(i4_enc_frm_id_rc == ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc)
4565             {
4566                 i4_enc_frm_id_rc = 0;
4567             }
4568             i4_me_frm_id++;
4569 
4570             if(i4_me_frm_id == NUM_ME_ENC_BUFS)
4571                 i4_me_frm_id = 0;
4572         }
4573         if(1 == ps_enc_ctxt->s_multi_thrd.i4_force_end_flag)
4574         {
4575             i4_me_end_flag = 1;
4576             i4_enc_end_flag = 1;
4577         }
4578     }
4579 
4580     /****** Lock the critical section ******/
4581 
4582     if(NULL != ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id])
4583     {
4584         WORD32 result;
4585 
4586         result =
4587             osal_mutex_lock(ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id]);
4588 
4589         if(OSAL_SUCCESS != result)
4590             return 0;
4591     }
4592 
4593     if(ps_enc_ctxt->s_multi_thrd.num_thrds_done ==
4594        (ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds - 1))
4595     {
4596         if(1 != ps_enc_ctxt->s_multi_thrd.i4_force_end_flag)
4597         {
4598             osal_mutex_lock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
4599             for(i = 0; i < ps_enc_ctxt->i4_num_bitrates; i++)
4600             {
4601                 ihevce_rc_close(
4602                     ps_enc_ctxt,
4603                     ps_enc_ctxt->i4_active_enc_frame_id,
4604                     2,
4605                     MIN(ps_enc_ctxt->ai4_rc_query[i], ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc),
4606                     i);
4607             }
4608             osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
4609         }
4610     }
4611 
4612     ps_enc_ctxt->s_multi_thrd.num_thrds_done++;
4613 
4614     /****** UnLock the critical section ******/
4615     if(NULL != ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id])
4616     {
4617         WORD32 result;
4618 
4619         result =
4620             osal_mutex_unlock(ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id]);
4621 
4622         if(OSAL_SUCCESS != result)
4623             return 0;
4624     }
4625 
4626     /****** Lock the critical section ******/
4627     if(NULL != ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id])
4628     {
4629         WORD32 result;
4630         result =
4631             osal_mutex_lock(ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id]);
4632 
4633         if(OSAL_SUCCESS != result)
4634             return 0;
4635     }
4636     if((ps_enc_ctxt->s_multi_thrd.num_thrds_done ==
4637         ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds) &&
4638        (ps_enc_ctxt->s_multi_thrd.i4_force_end_flag))
4639     {
4640         WORD32 num_bufs_preenc_me_que, num_bufs_L0_ipe_enc;
4641         WORD32 buf_id_ctr, frm_id_ctr;
4642         frm_proc_ent_cod_ctxt_t *ps_curr_out_enc_ent[IHEVCE_MAX_NUM_BITRATES];
4643         WORD32 out_buf_id_enc_ent[IHEVCE_MAX_NUM_BITRATES];
4644 
4645         if(ps_enc_ctxt->s_multi_thrd.i4_num_enc_loop_frm_pllel > 1)
4646         {
4647             num_bufs_preenc_me_que = (MAX_L0_IPE_ENC_STAGGER - 1) + MIN_L1_L0_STAGGER_NON_SEQ +
4648                                      NUM_BUFS_DECOMP_HME +
4649                                      ps_enc_ctxt->ps_stat_prms->s_lap_prms.i4_rc_look_ahead_pics;
4650 
4651             num_bufs_L0_ipe_enc = MAX_L0_IPE_ENC_STAGGER;
4652         }
4653         else
4654         {
4655             num_bufs_preenc_me_que = (MIN_L0_IPE_ENC_STAGGER - 1) + MIN_L1_L0_STAGGER_NON_SEQ +
4656                                      NUM_BUFS_DECOMP_HME +
4657                                      ps_enc_ctxt->ps_stat_prms->s_lap_prms.i4_rc_look_ahead_pics;
4658 
4659             num_bufs_L0_ipe_enc = MIN_L0_IPE_ENC_STAGGER;
4660         }
4661         for(buf_id_ctr = 0; buf_id_ctr < num_bufs_preenc_me_que; buf_id_ctr++)
4662         {
4663             /* release encoder owned input buffer*/
4664             ihevce_q_rel_buf((void *)ps_enc_ctxt, IHEVCE_PRE_ENC_ME_Q, buf_id_ctr);
4665         }
4666         for(buf_id_ctr = 0; buf_id_ctr < num_bufs_L0_ipe_enc; buf_id_ctr++)
4667         {
4668             /* release encoder owned input buffer*/
4669             ihevce_q_rel_buf((void *)ps_enc_ctxt, IHEVCE_L0_IPE_ENC_Q, buf_id_ctr);
4670         }
4671         for(frm_id_ctr = 0; frm_id_ctr < NUM_ME_ENC_BUFS; frm_id_ctr++)
4672         {
4673             for(i = 0; i < ps_enc_ctxt->i4_num_bitrates; i++)
4674             {
4675                 if(NULL != ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[frm_id_ctr][i])
4676                 {
4677                     ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[frm_id_ctr][i]
4678                         ->i4_frm_proc_valid_flag = 0;
4679                     ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[frm_id_ctr][i]->i4_end_flag = 1;
4680                     /* set the output buffer as produced */
4681                     ihevce_q_set_buff_prod(
4682                         (void *)ps_enc_ctxt,
4683                         IHEVCE_FRM_PRS_ENT_COD_Q + i,
4684                         ps_enc_ctxt->s_multi_thrd.out_buf_id[frm_id_ctr][i]);
4685                 }
4686             }
4687         }
4688         for(buf_id_ctr = 0; buf_id_ctr < NUM_FRMPROC_ENTCOD_BUFS;
4689             buf_id_ctr++) /*** Set buffer produced for NUM_FRMPROC_ENTCOD_BUFS buffers for entropy to exit ***/
4690         {
4691             for(i = 0; i < ps_enc_ctxt->i4_num_bitrates; i++)
4692             {
4693                 ps_curr_out_enc_ent[i] = (frm_proc_ent_cod_ctxt_t *)ihevce_q_get_free_buff(
4694                     (void *)ps_enc_ctxt,
4695                     IHEVCE_FRM_PRS_ENT_COD_Q + i, /*decides the buffer queue */
4696                     &out_buf_id_enc_ent[i],
4697                     BUFF_QUE_NON_BLOCKING_MODE);
4698                 if(NULL != ps_curr_out_enc_ent[i])
4699                 {
4700                     ps_curr_out_enc_ent[i]->i4_frm_proc_valid_flag = 0;
4701                     ps_curr_out_enc_ent[i]->i4_end_flag = 1;
4702                     /* set the output buffer as produced */
4703                     ihevce_q_set_buff_prod(
4704                         (void *)ps_enc_ctxt, IHEVCE_FRM_PRS_ENT_COD_Q + i, out_buf_id_enc_ent[i]);
4705                 }
4706             }
4707         }
4708     }
4709 
4710     /* The last thread coming out of Enc. Proc. */
4711     /* Release all the Recon buffers the application might have queued in */
4712     if((ps_enc_ctxt->s_multi_thrd.num_thrds_done ==
4713         ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds) &&
4714        (ps_enc_ctxt->ps_stat_prms->i4_save_recon != 0) &&
4715        (ps_enc_ctxt->s_multi_thrd.i4_is_recon_free_done == 0))
4716     {
4717         WORD32 i4_bitrate_ctr;
4718 
4719         for(i4_bitrate_ctr = 0; i4_bitrate_ctr < i4_num_bitrates; i4_bitrate_ctr++)
4720         {
4721             WORD32 end_flag = 0;
4722             while(0 == end_flag)
4723             {
4724                 /*swaping of buf_id for 0th and reference bitrate location, as encoder
4725                 assumes always 0th loc for reference bitrate and app must receive in
4726                 the configured order*/
4727                 WORD32 i4_recon_buf_id = i4_bitrate_ctr;
4728                 if(i4_bitrate_ctr == 0)
4729                 {
4730                     i4_recon_buf_id = ps_enc_ctxt->i4_ref_mbr_id;
4731                 }
4732                 else if(i4_bitrate_ctr == ps_enc_ctxt->i4_ref_mbr_id)
4733                 {
4734                     i4_recon_buf_id = 0;
4735                 }
4736 
4737                 /* ------- get free Recon buffer from Frame buffer que ---------- */
4738                 /* There is a separate queue for each bit-rate instnace. The recon
4739                 buffer is acquired from the corresponding queue based on the
4740                 bitrate instnace */
4741                 ps_enc_ctxt->s_multi_thrd.ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr] =
4742                     (iv_enc_recon_data_buffs_t *)ihevce_q_get_filled_buff(
4743                         (void *)ps_enc_ctxt,
4744                         IHEVCE_RECON_DATA_Q + i4_recon_buf_id, /*decides the buffer queue */
4745                         &ps_enc_ctxt->s_multi_thrd.recon_buf_id[i4_enc_frm_id][i4_bitrate_ctr],
4746                         BUFF_QUE_BLOCKING_MODE);
4747 
4748                 /* Update the end_flag from application */
4749                 end_flag = ps_enc_ctxt->s_multi_thrd.ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr]
4750                                ->i4_is_last_buf;
4751 
4752                 ps_enc_ctxt->s_multi_thrd.ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_end_flag =
4753                     1;
4754                 ps_enc_ctxt->s_multi_thrd.ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_y_pixels =
4755                     0;
4756                 ps_enc_ctxt->s_multi_thrd.ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_uv_pixels =
4757                     0;
4758 
4759                 /* Call back to Apln. saying recon buffer is produced */
4760                 ps_hle_ctxt->ihevce_output_recon_fill_done(
4761                     ps_hle_ctxt->pv_recon_cb_handle,
4762                     ps_enc_ctxt->s_multi_thrd.ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr],
4763                     i4_recon_buf_id, /* br instance */
4764                     i4_resolution_id /* res_intance */);
4765 
4766                 /* --- release the current recon buffer ---- */
4767                 ihevce_q_rel_buf(
4768                     (void *)ps_enc_ctxt,
4769                     (IHEVCE_RECON_DATA_Q + i4_recon_buf_id),
4770                     ps_enc_ctxt->s_multi_thrd.recon_buf_id[i4_enc_frm_id][i4_bitrate_ctr]);
4771             }
4772         }
4773         /* Set the recon free done flag */
4774         ps_enc_ctxt->s_multi_thrd.i4_is_recon_free_done = 1;
4775     }
4776 
4777     /****** UnLock the critical section ******/
4778     if(NULL != ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id])
4779     {
4780         WORD32 result;
4781         result =
4782             osal_mutex_unlock(ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id]);
4783 
4784         if(OSAL_SUCCESS != result)
4785             return 0;
4786     }
4787 
4788     return (0);
4789 }
4790 
4791 /*!
4792 ******************************************************************************
4793 * \if Function name : ihevce_set_pre_enc_prms \endif
4794 *
4795 * \brief
4796 *    Set CTB parameters
4797 *    Set ME params
4798 *    Set pps, sps, vps, vui params
4799 *    Do RC init
4800 *
4801 * \param[in] Encoder context pointer
4802 *
4803 * \return
4804 *    None
4805 *
4806 * \author
4807 *  Ittiam
4808 *
4809 *****************************************************************************
4810 */
ihevce_set_pre_enc_prms(enc_ctxt_t * ps_enc_ctxt)4811 void ihevce_set_pre_enc_prms(enc_ctxt_t *ps_enc_ctxt)
4812 {
4813     WORD32 i;
4814     WORD32 i4_num_instance,
4815         i4_resolution_id = ps_enc_ctxt->i4_resolution_id;  //number of bit-rate instances
4816 
4817     i4_num_instance = ps_enc_ctxt->i4_num_bitrates;
4818 
4819 #if PIC_ALIGN_CTB_SIZE
4820 
4821     ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd =
4822         ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_width +
4823         SET_CTB_ALIGN(
4824             ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_width,
4825             ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size);
4826 
4827     ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz =
4828         ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd / ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size;
4829 
4830     ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht =
4831         ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_height +
4832         SET_CTB_ALIGN(
4833             ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_height,
4834             ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size);
4835 
4836     ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_vert =
4837         ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht / ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size;
4838 #else  // PIC_ALIGN_CTB_SIZE
4839     /* Allign the frame width to min CU size */
4840     ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd =
4841         ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_width +
4842         SET_CTB_ALIGN(
4843             ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_width,
4844             ps_enc_ctxt->s_frm_ctb_prms.i4_min_cu_size);
4845 
4846     ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz =
4847         ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd / ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size;
4848 
4849     if((ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd %
4850         ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size) != 0)
4851         ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz =
4852             ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz + 1;
4853 
4854     /* Allign the frame hieght to min CU size */
4855     ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht =
4856         ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_height +
4857         SET_CTB_ALIGN(
4858             ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_height,
4859             ps_enc_ctxt->s_frm_ctb_prms.i4_min_cu_size);
4860 
4861     ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_vert =
4862         ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht / ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size;
4863 
4864     if((ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht %
4865         ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size) != 0)
4866         ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_vert =
4867             ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_vert + 1;
4868 
4869 #endif  // PIC_ALIGN_CTB_SIZE
4870 
4871     ps_enc_ctxt->s_frm_ctb_prms.i4_max_cus_in_row = ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz *
4872                                                     ps_enc_ctxt->s_frm_ctb_prms.i4_num_cus_in_ctb;
4873 
4874     ps_enc_ctxt->s_frm_ctb_prms.i4_max_pus_in_row = ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz *
4875                                                     ps_enc_ctxt->s_frm_ctb_prms.i4_num_pus_in_ctb;
4876 
4877     ps_enc_ctxt->s_frm_ctb_prms.i4_max_tus_in_row = ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz *
4878                                                     ps_enc_ctxt->s_frm_ctb_prms.i4_num_tus_in_ctb;
4879     ihevce_coarse_me_set_resolution(
4880         ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
4881         1,
4882         &ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd,
4883         &ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht);
4884 
4885     /*if Resolution need to be changed dynamically then needs to go to encode group */
4886     ihevce_me_set_resolution(
4887         ps_enc_ctxt->s_module_ctxt.pv_me_ctxt,
4888         1,
4889         &ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd,
4890         &ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht);
4891     i4_num_instance = ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
4892                           .i4_num_bitrate_instances;
4893     for(i = 0; i < i4_num_instance; i++)
4894     {
4895         WORD32 i4_id;
4896         /*swaping of buf_id for 0th and reference bitrate location, as encoder
4897         assumes always 0th loc for reference bitrate and app must receive in
4898         the configured order*/
4899         if(i == 0)
4900         {
4901             i4_id = ps_enc_ctxt->i4_ref_mbr_id;
4902         }
4903         else if(i == ps_enc_ctxt->i4_ref_mbr_id)
4904         {
4905             i4_id = 0;
4906         }
4907         else
4908         {
4909             i4_id = i;
4910         }
4911         /* populate vps based on encoder configuration and tools */
4912         ihevce_populate_vps(
4913             ps_enc_ctxt,
4914             &ps_enc_ctxt->as_vps[i],
4915             &ps_enc_ctxt->s_runtime_src_prms,
4916             &ps_enc_ctxt->ps_stat_prms->s_out_strm_prms,
4917             &ps_enc_ctxt->s_runtime_coding_prms,
4918             &ps_enc_ctxt->ps_stat_prms->s_config_prms,
4919             ps_enc_ctxt->ps_stat_prms,
4920             i4_resolution_id);
4921 
4922         /* populate sps based on encoder configuration and tools */
4923         ihevce_populate_sps(
4924             ps_enc_ctxt,
4925             &ps_enc_ctxt->as_sps[i],
4926             &ps_enc_ctxt->as_vps[i],
4927             &ps_enc_ctxt->s_runtime_src_prms,
4928             &ps_enc_ctxt->ps_stat_prms->s_out_strm_prms,
4929             &ps_enc_ctxt->s_runtime_coding_prms,
4930             &ps_enc_ctxt->ps_stat_prms->s_config_prms,
4931             &ps_enc_ctxt->s_frm_ctb_prms,
4932             ps_enc_ctxt->ps_stat_prms,
4933             i4_resolution_id);
4934 
4935         /* populate pps based on encoder configuration and tools */
4936         ihevce_populate_pps(
4937             &ps_enc_ctxt->as_pps[i],
4938             &ps_enc_ctxt->as_sps[i],
4939             &ps_enc_ctxt->s_runtime_src_prms,
4940             &ps_enc_ctxt->ps_stat_prms->s_out_strm_prms,
4941             &ps_enc_ctxt->s_runtime_coding_prms,
4942             &ps_enc_ctxt->ps_stat_prms->s_config_prms,
4943             ps_enc_ctxt->ps_stat_prms,
4944             i4_id,
4945             i4_resolution_id,
4946             ps_enc_ctxt->ps_tile_params_base,
4947             &ps_enc_ctxt->ai4_column_width_array[0],
4948             &ps_enc_ctxt->ai4_row_height_array[0]);
4949 
4950         // if(ps_enc_ctxt->as_sps[i].i1_vui_parameters_present_flag == 1)
4951         {
4952             ihevce_populate_vui(
4953                 &ps_enc_ctxt->as_sps[i].s_vui_parameters,
4954                 &ps_enc_ctxt->as_sps[i],
4955                 &ps_enc_ctxt->s_runtime_src_prms,
4956                 &ps_enc_ctxt->ps_stat_prms->s_vui_sei_prms,
4957                 i4_resolution_id,
4958                 &ps_enc_ctxt->s_runtime_tgt_params,
4959                 ps_enc_ctxt->ps_stat_prms,
4960                 i4_id);
4961         }
4962     }
4963 
4964     osal_mutex_lock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
4965     /* run the loop over all bit-rate instnaces */
4966     for(i = 0; i < i4_num_instance; i++)
4967     {
4968         /*HEVC_RC Do one time initialization of rate control*/
4969         ihevce_rc_init(
4970             (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
4971             &ps_enc_ctxt->s_runtime_src_prms,
4972             &ps_enc_ctxt->s_runtime_tgt_params,
4973             &ps_enc_ctxt->s_rc_quant,
4974             &ps_enc_ctxt->ps_stat_prms->s_sys_api,
4975             &ps_enc_ctxt->ps_stat_prms->s_lap_prms,
4976             ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc);
4977 
4978         ihevce_vbv_complaince_init_level(
4979             (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
4980             &ps_enc_ctxt->as_sps[i].s_vui_parameters);
4981     }
4982     osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
4983 }
4984 
4985 /*!
4986 ******************************************************************************
4987 * \if Function name : ihevce_pre_enc_init \endif
4988 *
4989 * \brief
4990 *   set out_buf params
4991 *   Calculate end_flag if flushmode on
4992 *   Slice initialization
4993 *   Populate SIE params
4994 *   reference list creation
4995 *
4996 * \param[in] Encoder context pointer
4997 *
4998 * \return
4999 *    None
5000 *
5001 * \author
5002 *  Ittiam
5003 *
5004 *****************************************************************************
5005 */
ihevce_pre_enc_init(enc_ctxt_t * ps_enc_ctxt,ihevce_lap_enc_buf_t * ps_curr_inp,pre_enc_me_ctxt_t * ps_curr_out,WORD32 * pi4_end_flag_ret,WORD32 * pi4_cur_qp_ret,WORD32 * pi4_decomp_lyr_idx,WORD32 i4_ping_pong)5006 void ihevce_pre_enc_init(
5007     enc_ctxt_t *ps_enc_ctxt,
5008     ihevce_lap_enc_buf_t *ps_curr_inp,
5009     pre_enc_me_ctxt_t *ps_curr_out,
5010     WORD32 *pi4_end_flag_ret,
5011     WORD32 *pi4_cur_qp_ret,
5012     WORD32 *pi4_decomp_lyr_idx,
5013     WORD32 i4_ping_pong)
5014 {
5015     WORD32 end_flag = 0;
5016     WORD32 cur_qp;
5017     //recon_pic_buf_t *ps_frm_recon;
5018     WORD32 first_field = 1;
5019     WORD32 i4_field_pic = ps_enc_ctxt->s_runtime_src_prms.i4_field_pic;
5020     WORD32 i4_decomp_lyrs_idx = 0;
5021     WORD32 i4_resolution_id = ps_enc_ctxt->i4_resolution_id;
5022     WORD32 slice_type = ISLICE;
5023     WORD32 nal_type;
5024     WORD32 min_cu_size;
5025 
5026     WORD32 stasino_enabled;
5027 
5028     /* copy the time stamps from inp to entropy inp */
5029     ps_curr_out->i4_inp_timestamp_low = ps_curr_inp->s_input_buf.i4_inp_timestamp_low;
5030     ps_curr_out->i4_inp_timestamp_high = ps_curr_inp->s_input_buf.i4_inp_timestamp_high;
5031     ps_curr_out->pv_app_frm_ctxt = ps_curr_inp->s_input_buf.pv_app_frm_ctxt;
5032 
5033     /* get the min cu size from config params */
5034     min_cu_size = ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_min_log2_cu_size;
5035 
5036     min_cu_size = 1 << min_cu_size;
5037 
5038     ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd =
5039         ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd +
5040         SET_CTB_ALIGN(ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd, min_cu_size);
5041 
5042     ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht =
5043         ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht +
5044         SET_CTB_ALIGN(ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht, min_cu_size);
5045 
5046     ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd =
5047         ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd +
5048         SET_CTB_ALIGN(ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd, min_cu_size);
5049 
5050     if(IV_YUV_420SP_UV == ps_enc_ctxt->ps_stat_prms->s_src_prms.i4_chr_format)
5051     {
5052         ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht =
5053             ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht +
5054             SET_CTB_ALIGN(ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht, (min_cu_size >> 1));
5055     }
5056     else if(IV_YUV_422SP_UV == ps_enc_ctxt->ps_stat_prms->s_src_prms.i4_chr_format)
5057     {
5058         ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht =
5059             ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht +
5060             SET_CTB_ALIGN(ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht, min_cu_size);
5061     }
5062 
5063     /* update the END flag from LAP out */
5064     end_flag = ps_curr_inp->s_lap_out.i4_end_flag;
5065     ps_curr_out->i4_end_flag = end_flag;
5066     ps_enc_ctxt->s_multi_thrd.i4_last_pic_flag = end_flag;
5067 
5068     /* ----------------------------------------------------------------------*/
5069     /*  Slice initialization for current frame; Required for entropy context */
5070     /* ----------------------------------------------------------------------*/
5071     {
5072         WORD32 cur_poc = ps_curr_inp->s_lap_out.i4_poc;
5073 
5074         /* max merge candidates derived based on quality preset for now */
5075         WORD32 max_merge_candidates = 2;
5076 
5077         /* pocs less than random acess poc tagged for discard as they */
5078         /* could be refering to pics before the cra.                  */
5079 
5080         /* CRA case: as the leading pictures can refer the picture precedes the associated
5081         IRAP(CRA) in decoding order, hence make it Random access skipped leading pictures (RASL)*/
5082 
5083         if((1 == ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.i4_enable_temporal_scalability) &&
5084            (ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_max_temporal_layers ==
5085             ps_curr_inp->s_lap_out.i4_temporal_lyr_id))  //TEMPORALA_SCALABILITY CHANGES
5086         {
5087             if(ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc)
5088             {
5089                 nal_type = (cur_poc < ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc)
5090                                ? (ps_curr_inp->s_lap_out.i4_is_ref_pic ? NAL_RASL_R : NAL_RASL_N)
5091                                : (ps_curr_inp->s_lap_out.i4_is_ref_pic ? NAL_TSA_R : NAL_TSA_N);
5092             }
5093             /* IDR case: as the leading pictures can't refer the picture precedes the associated
5094             IRAP(IDR) in decoding order, hence make it Random access decodable leading pictures (RADL)*/
5095             else
5096             {
5097                 nal_type = (cur_poc < ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc)
5098                                ? (ps_curr_inp->s_lap_out.i4_is_ref_pic ? NAL_RADL_R : NAL_RADL_N)
5099                                : (ps_curr_inp->s_lap_out.i4_is_ref_pic ? NAL_TSA_R : NAL_TSA_N);
5100             }
5101         }
5102         else
5103         {
5104             if(ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc)
5105             {
5106                 nal_type = (cur_poc < ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc)
5107                                ? (ps_curr_inp->s_lap_out.i4_is_ref_pic ? NAL_RASL_R : NAL_RASL_N)
5108                                : (ps_curr_inp->s_lap_out.i4_is_ref_pic ? NAL_TRAIL_R : NAL_TRAIL_N);
5109             }
5110             /* IDR case: as the leading pictures can't refer the picture precedes the associated
5111             IRAP(IDR) in decoding order, hence make it Random access decodable leading pictures (RADL)*/
5112             else
5113             {
5114                 nal_type = (cur_poc < ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc)
5115                                ? (ps_curr_inp->s_lap_out.i4_is_ref_pic ? NAL_RADL_R : NAL_RADL_N)
5116                                : (ps_curr_inp->s_lap_out.i4_is_ref_pic ? NAL_TRAIL_R : NAL_TRAIL_N);
5117             }
5118         }
5119 
5120         switch(ps_curr_inp->s_lap_out.i4_pic_type)
5121         {
5122         case IV_IDR_FRAME:
5123             /*  IDR pic */
5124             slice_type = ISLICE;
5125             nal_type = NAL_IDR_W_LP;
5126             cur_poc = 0;
5127             ps_enc_ctxt->i4_cra_poc = cur_poc;
5128             break;
5129 
5130         case IV_I_FRAME:
5131             slice_type = ISLICE;
5132 
5133             if(ps_curr_inp->s_lap_out.i4_is_cra_pic)
5134             {
5135                 nal_type = NAL_CRA;
5136             }
5137 
5138             ps_enc_ctxt->i4_cra_poc = cur_poc;
5139             break;
5140 
5141         case IV_P_FRAME:
5142             slice_type = PSLICE;
5143             break;
5144 
5145         case IV_B_FRAME:
5146             /* TODO : Mark the nal type as NAL_TRAIL_N for non ref pics */
5147             slice_type = BSLICE;
5148             break;
5149 
5150         default:
5151             /* This should never occur */
5152             ASSERT(0);
5153         }
5154 
5155         /* number of merge candidates and error metric chosen based on quality preset */
5156         switch(ps_curr_inp->s_lap_out.i4_quality_preset)
5157         {
5158         case IHEVCE_QUALITY_P0:
5159             max_merge_candidates = 5;
5160             break;
5161 
5162         case IHEVCE_QUALITY_P2:
5163             max_merge_candidates = 5;
5164             break;
5165 
5166         case IHEVCE_QUALITY_P3:
5167             max_merge_candidates = 3;
5168             break;
5169 
5170         case IHEVCE_QUALITY_P4:
5171         case IHEVCE_QUALITY_P5:
5172         case IHEVCE_QUALITY_P6:
5173             max_merge_candidates = 2;
5174             break;
5175 
5176         default:
5177             ASSERT(0);
5178         }
5179 
5180         /* acquire mutex lock for rate control calls */
5181         osal_mutex_lock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
5182         {
5183             ps_curr_inp->s_rc_lap_out.i4_num_pels_in_frame_considered =
5184                 ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht *
5185                 ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd;
5186 
5187             /*initialize the frame info stat inside LAP out, Data inside this will be populated in ihevce_rc_get_bpp_based_frame_qp call*/
5188             ps_curr_inp->s_rc_lap_out.ps_frame_info = &ps_curr_inp->s_frame_info;
5189 
5190             ps_curr_inp->s_rc_lap_out.i4_is_bottom_field = ps_curr_inp->s_input_buf.i4_bottom_field;
5191             if(ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_rate_control_mode == 3)
5192             {
5193                 /*for constant qp use same qp*/
5194                 /*HEVC_RC query rate control for qp*/
5195                 cur_qp = ihevce_rc_pre_enc_qp_query(
5196                     (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
5197                     &ps_curr_inp->s_rc_lap_out,
5198                     0);
5199             }
5200             else
5201             {
5202                 cur_qp = ihevce_rc_get_bpp_based_frame_qp(
5203                     (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0], &ps_curr_inp->s_rc_lap_out);
5204             }
5205         }
5206         /* release mutex lock after rate control calls */
5207         osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
5208 
5209         /* store the QP in output prms */
5210         /* The same qp is also used in enc thread only for ME*/
5211         ps_curr_out->i4_curr_frm_qp = cur_qp;
5212 
5213         /* slice header entropy syn memory is not valid in pre encode stage */
5214         ps_curr_out->s_slice_hdr.pu4_entry_point_offset = NULL;
5215 
5216         /* derive the flag which indicates if stasino is enabled */
5217         stasino_enabled = (ps_enc_ctxt->s_runtime_coding_prms.i4_vqet &
5218                            (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_NOISE_PRESERVATION)) &&
5219                           (ps_enc_ctxt->s_runtime_coding_prms.i4_vqet &
5220                            (1 << BITPOS_IN_VQ_TOGGLE_FOR_CONTROL_TOGGLER));
5221 
5222         /* initialize the slice header */
5223         ihevce_populate_slice_header(
5224             &ps_curr_out->s_slice_hdr,
5225             &ps_enc_ctxt->as_pps[0],
5226             &ps_enc_ctxt->as_sps[0],
5227             nal_type,
5228             slice_type,
5229             0,
5230             0,
5231             ps_curr_inp->s_lap_out.i4_poc,
5232             cur_qp,
5233             max_merge_candidates,
5234             ps_enc_ctxt->ps_stat_prms->s_pass_prms.i4_pass,
5235             ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
5236                 .i4_quality_preset,
5237             stasino_enabled);
5238 
5239         ps_curr_out->i4_slice_nal_type = nal_type;
5240 
5241         ps_curr_out->s_slice_hdr.u4_nuh_temporal_id = 0;
5242 
5243         if(1 == ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.i4_enable_temporal_scalability)
5244         {
5245             ps_curr_out->s_slice_hdr.u4_nuh_temporal_id =
5246                 (ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_max_temporal_layers ==
5247                  ps_curr_inp->s_lap_out.i4_temporal_lyr_id);  //TEMPORALA_SCALABILITY CHANGES
5248         }
5249 
5250         /* populate sps, vps and pps pointers for the entropy input params */
5251         ps_curr_out->ps_pps = &ps_enc_ctxt->as_pps[0];
5252         ps_curr_out->ps_sps = &ps_enc_ctxt->as_sps[0];
5253         ps_curr_out->ps_vps = &ps_enc_ctxt->as_vps[0];
5254     }
5255 
5256     /* By default, Sei messages are set to 0, to avoid unintialised memory access */
5257     memset(&ps_curr_out->s_sei, 0, sizeof(sei_params_t));
5258 
5259     /* VUI, SEI flags reset */
5260     ps_curr_out->s_sei.i1_sei_parameters_present_flag = 0;
5261     ps_curr_out->s_sei.i1_buf_period_params_present_flag = 0;
5262     ps_curr_out->s_sei.i1_pic_timing_params_present_flag = 0;
5263     ps_curr_out->s_sei.i1_recovery_point_params_present_flag = 0;
5264     ps_curr_out->s_sei.i1_decoded_pic_hash_sei_flag = 0;
5265     ps_curr_out->s_sei.i4_sei_mastering_disp_colour_vol_params_present_flags = 0;
5266 
5267     if(ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_sei_enable_flag == 1)
5268     {
5269         /* insert buffering period, display volume, recovery point only at irap points */
5270         WORD32 insert_per_irap =
5271             ((slice_type == ISLICE) &&
5272              (((NAL_IDR_N_LP == nal_type) || (NAL_CRA == nal_type)) || (NAL_IDR_W_LP == nal_type)));
5273 
5274         ps_curr_out->s_sei.i1_sei_parameters_present_flag = 1;
5275 
5276         /* populate Sei buffering period based on encoder configuration and tools */
5277         if(ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_sei_buffer_period_flags == 1)
5278         {
5279             ihevce_populate_buffering_period_sei(
5280                 &ps_curr_out->s_sei,
5281                 &ps_enc_ctxt->as_sps[0].s_vui_parameters,
5282                 &ps_enc_ctxt->as_sps[0],
5283                 &ps_enc_ctxt->ps_stat_prms->s_vui_sei_prms);
5284 
5285             ps_curr_out->s_sei.i1_buf_period_params_present_flag = insert_per_irap;
5286 
5287             ihevce_populate_active_parameter_set_sei(
5288                 &ps_curr_out->s_sei, &ps_enc_ctxt->as_vps[0], &ps_enc_ctxt->as_sps[0]);
5289         }
5290 
5291         /* populate Sei picture timing based on encoder configuration and tools */
5292         if(ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_sei_pic_timing_flags == 1)
5293         {
5294             ihevce_populate_picture_timing_sei(
5295                 &ps_curr_out->s_sei,
5296                 &ps_enc_ctxt->as_sps[0].s_vui_parameters,
5297                 &ps_enc_ctxt->s_runtime_src_prms,
5298                 ps_curr_inp->s_input_buf.i4_bottom_field);
5299             ps_curr_out->s_sei.i1_pic_timing_params_present_flag = 1;
5300         }
5301 
5302         /* populate Sei recovery point based on encoder configuration and tools */
5303         if(ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_sei_recovery_point_flags == 1)
5304         {
5305             ihevce_populate_recovery_point_sei(
5306                 &ps_curr_out->s_sei, &ps_enc_ctxt->ps_stat_prms->s_vui_sei_prms);
5307             ps_curr_out->s_sei.i1_recovery_point_params_present_flag = insert_per_irap;
5308         }
5309 
5310         /* populate mastering_display_colour_volume parameters */
5311         if(ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_sei_mastering_disp_colour_vol_flags == 1)
5312         {
5313             ihevce_populate_mastering_disp_col_vol_sei(
5314                 &ps_curr_out->s_sei, &ps_enc_ctxt->ps_stat_prms->s_out_strm_prms);
5315 
5316             ps_curr_out->s_sei.i4_sei_mastering_disp_colour_vol_params_present_flags =
5317                 insert_per_irap;
5318         }
5319 
5320         /* populate SEI Hash Flag based on encoder configuration */
5321         if(0 != ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_decoded_pic_hash_sei_flag)
5322         {
5323             /* Sanity checks */
5324             ASSERT(0 != ps_enc_ctxt->as_sps[0].i1_chroma_format_idc);
5325 
5326             ASSERT(
5327                 (0 < ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_decoded_pic_hash_sei_flag) &&
5328                 (4 > ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_decoded_pic_hash_sei_flag));
5329 
5330             /* MD5 is not supported now! picture_md5[cIdx][i] pblm */
5331             ASSERT(1 != ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_decoded_pic_hash_sei_flag);
5332 
5333             ps_curr_out->s_sei.i1_decoded_pic_hash_sei_flag =
5334                 ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_decoded_pic_hash_sei_flag;
5335         }
5336     }
5337 
5338     /* For interlace pictures, first_field depends on topfield_first and bottom field */
5339     if(i4_field_pic)
5340     {
5341         first_field =
5342             (ps_curr_inp->s_input_buf.i4_topfield_first ^ ps_curr_inp->s_input_buf.i4_bottom_field);
5343     }
5344 
5345     /* get frame level lambda params */
5346     ihevce_get_frame_lambda_prms(
5347         ps_enc_ctxt,
5348         ps_curr_out,
5349         cur_qp,
5350         first_field,
5351         ps_curr_inp->s_lap_out.i4_is_ref_pic,
5352         ps_curr_inp->s_lap_out.i4_temporal_lyr_id,
5353         lamda_modifier_for_I_pic[4] /*mean TRF*/,
5354         0,
5355         PRE_ENC_LAMBDA_TYPE);
5356     /* Coarse ME and Decomp buffers sharing */
5357     {
5358         UWORD8 *apu1_lyr_bufs[MAX_NUM_HME_LAYERS];
5359         WORD32 ai4_lyr_buf_strd[MAX_NUM_HME_LAYERS];
5360 
5361         /* get the Decomposition frame buffer from ME */
5362         i4_decomp_lyrs_idx = ihevce_coarse_me_get_lyr_buf_desc(
5363             ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt, &apu1_lyr_bufs[0], &ai4_lyr_buf_strd[0]);
5364         /* register the buffers with decomp module along with frame init */
5365         ihevce_decomp_pre_intra_frame_init(
5366             ps_enc_ctxt->s_module_ctxt.pv_decomp_pre_intra_ctxt,
5367             &apu1_lyr_bufs[0],
5368             &ai4_lyr_buf_strd[0],
5369             ps_curr_out->ps_layer1_buf,
5370             ps_curr_out->ps_layer2_buf,
5371             ps_curr_out->ps_ed_ctb_l1,
5372             ps_curr_out->as_lambda_prms[0].i4_ol_sad_lambda_qf,
5373             ps_curr_out->ps_ctb_analyse);
5374     }
5375 
5376     /* -------------------------------------------------------- */
5377     /*   Preparing Pre encode Passes Job Queue                  */
5378     /* -------------------------------------------------------- */
5379     ihevce_prepare_pre_enc_job_queue(ps_enc_ctxt, ps_curr_inp, i4_ping_pong);
5380 
5381     /*assign return variables */
5382     *pi4_end_flag_ret = end_flag;
5383     *pi4_cur_qp_ret = cur_qp;
5384     *pi4_decomp_lyr_idx = i4_decomp_lyrs_idx;
5385     //*pps_frm_recon_ret = ps_frm_recon;
5386 }
5387 
5388 /*!
5389 ******************************************************************************
5390 * \if Function name : ihevce_pre_enc_coarse_me_init \endif
5391 *
5392 * \brief
5393 *   set out_buf params
5394 *   Calculate end_flag if flushmode on
5395 *   Slice initialization
5396 *   Populate SIE params
5397 *   reference list creation
5398 *
5399 * \param[in] Encoder context pointer
5400 *
5401 * \return
5402 *    None
5403 *
5404 * \author
5405 *  Ittiam
5406 *
5407 *****************************************************************************
5408 */
ihevce_pre_enc_coarse_me_init(enc_ctxt_t * ps_enc_ctxt,ihevce_lap_enc_buf_t * ps_curr_inp,pre_enc_me_ctxt_t * ps_curr_out,recon_pic_buf_t ** pps_frm_recon_ret,WORD32 i4_decomp_lyrs_idx,WORD32 i4_cur_qp,WORD32 i4_ping_pong)5409 void ihevce_pre_enc_coarse_me_init(
5410     enc_ctxt_t *ps_enc_ctxt,
5411     ihevce_lap_enc_buf_t *ps_curr_inp,
5412     pre_enc_me_ctxt_t *ps_curr_out,
5413     recon_pic_buf_t **pps_frm_recon_ret,
5414     WORD32 i4_decomp_lyrs_idx,
5415     WORD32 i4_cur_qp,
5416     WORD32 i4_ping_pong)
5417 
5418 {
5419     /* local variables */
5420     recon_pic_buf_t *ps_frm_recon;
5421     coarse_me_master_ctxt_t *ps_ctxt = NULL;
5422     ps_ctxt = (coarse_me_master_ctxt_t *)ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt;
5423     /* Reference buffer management and reference list creation for pre enc group */
5424     ihevce_pre_enc_manage_ref_pics(ps_enc_ctxt, ps_curr_inp, ps_curr_out, i4_ping_pong);
5425 
5426     /* get a free recon buffer for current picture  */
5427     {
5428         WORD32 ctr;
5429 
5430         ps_frm_recon = NULL;
5431         for(ctr = 0; ctr < ps_enc_ctxt->i4_pre_enc_num_buf_recon_q; ctr++)
5432         {
5433             if(1 == ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr]->i4_is_free)
5434             {
5435                 ps_frm_recon = ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr];
5436                 break;
5437             }
5438         }
5439     }
5440     /* should not be NULL */
5441     ASSERT(ps_frm_recon != NULL);
5442 
5443     /* populate reference /recon params based on LAP output */
5444     ps_frm_recon->i4_is_free = 0;
5445     /* top first field is set to 1 by application */
5446     ps_frm_recon->i4_topfield_first = ps_curr_inp->s_input_buf.i4_topfield_first;
5447     ps_frm_recon->i4_poc = ps_curr_inp->s_lap_out.i4_poc;
5448     ps_frm_recon->i4_pic_type = ps_curr_inp->s_lap_out.i4_pic_type;
5449     ps_frm_recon->i4_display_num = ps_curr_inp->s_lap_out.i4_display_num;
5450     /* bottom field is toggled for every field by application */
5451     ps_frm_recon->i4_bottom_field = ps_curr_inp->s_input_buf.i4_bottom_field;
5452 
5453     /* Reference picture property is given by LAP */
5454     ps_frm_recon->i4_is_reference = ps_curr_inp->s_lap_out.i4_is_ref_pic;
5455 
5456     /* Deblock a picture for all reference frames unconditionally. */
5457     /* Deblock non ref if psnr compute or save recon is enabled    */
5458     ps_frm_recon->i4_deblk_pad_hpel_cur_pic = ps_frm_recon->i4_is_reference ||
5459                                               (ps_enc_ctxt->ps_stat_prms->i4_save_recon);
5460 
5461     /* set the width, height and stride to defalut values */
5462     ps_frm_recon->s_yuv_buf_desc.i4_y_ht = 0;
5463     ps_frm_recon->s_yuv_buf_desc.i4_uv_ht = 0;
5464     ps_frm_recon->s_yuv_buf_desc.i4_y_wd = 0;
5465     ps_frm_recon->s_yuv_buf_desc.i4_uv_wd = 0;
5466     ps_frm_recon->s_yuv_buf_desc.i4_y_strd = 0;
5467     ps_frm_recon->s_yuv_buf_desc.i4_uv_strd = 0;
5468 
5469     /* register the Layer1 MV bank pointer with ME module */
5470     ihevce_coarse_me_set_lyr1_mv_bank(
5471         ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
5472         ps_curr_inp,
5473         ps_curr_out->pv_me_mv_bank,
5474         ps_curr_out->pv_me_ref_idx,
5475         i4_decomp_lyrs_idx);
5476 
5477     /* Coarse picture level init of ME */
5478     ihevce_coarse_me_frame_init(
5479         ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
5480         ps_enc_ctxt->ps_stat_prms,
5481         &ps_enc_ctxt->s_frm_ctb_prms,
5482         &ps_curr_out->as_lambda_prms[0],
5483         ps_enc_ctxt->i4_pre_enc_num_ref_l0,
5484         ps_enc_ctxt->i4_pre_enc_num_ref_l1,
5485         ps_enc_ctxt->i4_pre_enc_num_ref_l0_active,
5486         ps_enc_ctxt->i4_pre_enc_num_ref_l1_active,
5487         &ps_enc_ctxt->aps_pre_enc_ref_lists[i4_ping_pong][LIST_0][0],
5488         &ps_enc_ctxt->aps_pre_enc_ref_lists[i4_ping_pong][LIST_1][0],
5489         ps_curr_inp,
5490         i4_cur_qp,
5491         ps_curr_out->ps_layer1_buf,
5492         ps_curr_out->ps_ed_ctb_l1,
5493         ps_curr_out->pu1_me_reverse_map_info,
5494         ps_curr_inp->s_lap_out.i4_temporal_lyr_id);
5495 
5496     /*assign return variables */
5497     *pps_frm_recon_ret = ps_frm_recon;
5498 }
5499 
5500 /*!
5501 ******************************************************************************
5502 * \brief
5503 *  Function to calculate modulation based on spatial variance across lap period
5504 *
5505 *****************************************************************************
5506 */
ihevce_variance_calc_acc_activity(enc_ctxt_t * ps_enc_ctxt,WORD32 i4_cur_ipe_idx)5507 void ihevce_variance_calc_acc_activity(enc_ctxt_t *ps_enc_ctxt, WORD32 i4_cur_ipe_idx)
5508 {
5509     pre_enc_me_ctxt_t *ps_curr_out = ps_enc_ctxt->s_multi_thrd.aps_curr_out_pre_enc[i4_cur_ipe_idx];
5510     WORD32 is_curr_bslice = (ps_curr_out->s_slice_hdr.i1_slice_type == BSLICE);
5511 #if MODULATION_OVER_LAP
5512     WORD32 loop_lap2 = MAX(1, ps_enc_ctxt->s_multi_thrd.i4_delay_pre_me_btw_l0_ipe - 1);
5513 #else
5514     WORD32 loop_lap2 = 1;
5515 #endif
5516     WORD32 i4_delay_loop = ps_enc_ctxt->s_multi_thrd.i4_max_delay_pre_me_btw_l0_ipe;
5517     WORD32 i, j;
5518 
5519     ps_curr_out->i8_acc_frame_8x8_sum_act_sqr = 0;
5520     ps_curr_out->i8_acc_frame_8x8_sum_act_for_strength = 0;
5521     for(i = 0; i < 2; i++)
5522     {
5523         ps_curr_out->i8_acc_frame_8x8_sum_act[i] = 0;
5524         ps_curr_out->i4_acc_frame_8x8_num_blks[i] = 0;
5525         ps_curr_out->i8_acc_frame_16x16_sum_act[i] = 0;
5526         ps_curr_out->i4_acc_frame_16x16_num_blks[i] = 0;
5527         ps_curr_out->i8_acc_frame_32x32_sum_act[i] = 0;
5528         ps_curr_out->i4_acc_frame_32x32_num_blks[i] = 0;
5529     }
5530     ps_curr_out->i8_acc_frame_16x16_sum_act[i] = 0;
5531     ps_curr_out->i4_acc_frame_16x16_num_blks[i] = 0;
5532     ps_curr_out->i8_acc_frame_32x32_sum_act[i] = 0;
5533     ps_curr_out->i4_acc_frame_32x32_num_blks[i] = 0;
5534 
5535     if(!is_curr_bslice)
5536     {
5537         for(i = 0; i < loop_lap2; i++)
5538         {
5539             WORD32 ipe_idx_tmp = (i4_cur_ipe_idx + i) % i4_delay_loop;
5540             ihevce_lap_enc_buf_t *ps_in = ps_enc_ctxt->s_multi_thrd.aps_curr_inp_pre_enc[ipe_idx_tmp];
5541             pre_enc_me_ctxt_t *ps_out = ps_enc_ctxt->s_multi_thrd.aps_curr_out_pre_enc[ipe_idx_tmp];
5542             UWORD8 is_bslice = (ps_out->s_slice_hdr.i1_slice_type == BSLICE);
5543 
5544             if(!is_bslice)
5545             {
5546                 ps_curr_out->i8_acc_frame_8x8_sum_act_sqr += ps_out->u8_curr_frame_8x8_sum_act_sqr;
5547                 ps_curr_out->i8_acc_frame_8x8_sum_act_for_strength += ps_out->i4_curr_frame_8x8_sum_act_for_strength[0];
5548                 for(j = 0; j < 2; j++)
5549                 {
5550                     ps_curr_out->i8_acc_frame_8x8_sum_act[j] += ps_out->i8_curr_frame_8x8_sum_act[j];
5551                     ps_curr_out->i4_acc_frame_8x8_num_blks[j] += ps_out->i4_curr_frame_8x8_num_blks[j];
5552                     ps_curr_out->i8_acc_frame_16x16_sum_act[j] += ps_out->i8_curr_frame_16x16_sum_act[j];
5553                     ps_curr_out->i4_acc_frame_16x16_num_blks[j] += ps_out->i4_curr_frame_16x16_num_blks[j];
5554                     ps_curr_out->i8_acc_frame_32x32_sum_act[j] += ps_out->i8_curr_frame_32x32_sum_act[j];
5555                     ps_curr_out->i4_acc_frame_32x32_num_blks[j] += ps_out->i4_curr_frame_32x32_num_blks[j];
5556                 }
5557                 ps_curr_out->i8_acc_frame_16x16_sum_act[j] += ps_out->i8_curr_frame_16x16_sum_act[j];
5558                 ps_curr_out->i4_acc_frame_16x16_num_blks[j] += ps_out->i4_curr_frame_16x16_num_blks[j];
5559                 ps_curr_out->i8_acc_frame_32x32_sum_act[j] += ps_out->i8_curr_frame_32x32_sum_act[j];
5560                 ps_curr_out->i4_acc_frame_32x32_num_blks[j] += ps_out->i4_curr_frame_32x32_num_blks[j];
5561             }
5562             if(NULL == ps_in->s_rc_lap_out.ps_rc_lap_out_next_encode)
5563                 break;
5564         }
5565 
5566         for(j = 0; j < 3; j++)
5567         {
5568             if(j < 2)
5569                 ASSERT(0 != ps_curr_out->i4_acc_frame_8x8_num_blks[j]);
5570             ASSERT(0 != ps_curr_out->i4_acc_frame_16x16_num_blks[j]);
5571             ASSERT(0 != ps_curr_out->i4_acc_frame_32x32_num_blks[j]);
5572 
5573 #define AVG_ACTIVITY(a, b, c) a = ((b + (c >> 1)) / c)
5574 
5575             if(j < 2)
5576             {
5577                 if(0 == ps_curr_out->i4_acc_frame_8x8_num_blks[j])
5578                 {
5579                     ps_curr_out->i8_curr_frame_8x8_avg_act[j] = 0;
5580                 }
5581                 else
5582                 {
5583                     AVG_ACTIVITY(ps_curr_out->i8_curr_frame_8x8_sum_act_for_strength,
5584                                  ps_curr_out->i8_acc_frame_8x8_sum_act_for_strength,
5585                                  ps_curr_out->i4_acc_frame_8x8_num_blks[j]);
5586                     AVG_ACTIVITY(ps_curr_out->i8_curr_frame_8x8_avg_act[j],
5587                                  ps_curr_out->i8_acc_frame_8x8_sum_act[j],
5588                                  ps_curr_out->i4_acc_frame_8x8_num_blks[j]);
5589                     ps_curr_out->ld_curr_frame_8x8_log_avg[j] =
5590                         fast_log2(1 + ps_curr_out->i8_curr_frame_8x8_avg_act[j]);
5591                 }
5592             }
5593 
5594             if(0 == ps_curr_out->i4_acc_frame_16x16_num_blks[j])
5595             {
5596                 ps_curr_out->i8_curr_frame_16x16_avg_act[j] = 0;
5597             }
5598             else
5599             {
5600                 AVG_ACTIVITY(ps_curr_out->i8_curr_frame_16x16_avg_act[j],
5601                              ps_curr_out->i8_acc_frame_16x16_sum_act[j],
5602                              ps_curr_out->i4_acc_frame_16x16_num_blks[j]);
5603                 ps_curr_out->ld_curr_frame_16x16_log_avg[j] =
5604                     fast_log2(1 + ps_curr_out->i8_curr_frame_16x16_avg_act[j]);
5605             }
5606 
5607             if(0 == ps_curr_out->i4_acc_frame_32x32_num_blks[j])
5608             {
5609                 ps_curr_out->i8_curr_frame_32x32_avg_act[j] = 0;
5610             }
5611             else
5612             {
5613                 AVG_ACTIVITY(ps_curr_out->i8_curr_frame_32x32_avg_act[j],
5614                              ps_curr_out->i8_acc_frame_32x32_sum_act[j],
5615                              ps_curr_out->i4_acc_frame_32x32_num_blks[j]);
5616                 ps_curr_out->ld_curr_frame_32x32_log_avg[j] =
5617                     fast_log2(1 + ps_curr_out->i8_curr_frame_32x32_avg_act[j]);
5618             }
5619         }
5620 
5621         /* store the avg activity for B pictures */
5622 #if POW_OPT
5623         ps_enc_ctxt->ald_lap2_8x8_log_avg_act_from_T0[0] = ps_curr_out->ld_curr_frame_8x8_log_avg[0];
5624         ps_enc_ctxt->ald_lap2_8x8_log_avg_act_from_T0[1] = ps_curr_out->ld_curr_frame_8x8_log_avg[1];
5625         ps_enc_ctxt->ald_lap2_16x16_log_avg_act_from_T0[0] = ps_curr_out->ld_curr_frame_16x16_log_avg[0];
5626         ps_enc_ctxt->ald_lap2_16x16_log_avg_act_from_T0[1] = ps_curr_out->ld_curr_frame_16x16_log_avg[1];
5627         ps_enc_ctxt->ald_lap2_16x16_log_avg_act_from_T0[2] = ps_curr_out->ld_curr_frame_16x16_log_avg[2];
5628         ps_enc_ctxt->ald_lap2_32x32_log_avg_act_from_T0[0] = ps_curr_out->ld_curr_frame_32x32_log_avg[0];
5629         ps_enc_ctxt->ald_lap2_32x32_log_avg_act_from_T0[1] = ps_curr_out->ld_curr_frame_32x32_log_avg[1];
5630         ps_enc_ctxt->ald_lap2_32x32_log_avg_act_from_T0[2] = ps_curr_out->ld_curr_frame_32x32_log_avg[2];
5631 #else
5632         ps_enc_ctxt->ai8_lap2_8x8_avg_act_from_T0[0] = ps_curr_out->i8_curr_frame_8x8_avg_act[0];
5633         ps_enc_ctxt->ai8_lap2_8x8_avg_act_from_T0[1] = ps_curr_out->i8_curr_frame_8x8_avg_act[1];
5634         ps_enc_ctxt->ai8_lap2_16x16_avg_act_from_T0[0] = ps_curr_out->i8_curr_frame_16x16_avg_act[0];
5635         ps_enc_ctxt->ai8_lap2_16x16_avg_act_from_T0[1] = ps_curr_out->i8_curr_frame_16x16_avg_act[1];
5636         ps_enc_ctxt->ai8_lap2_16x16_avg_act_from_T0[2] = ps_curr_out->i8_curr_frame_16x16_avg_act[2];
5637         ps_enc_ctxt->ai8_lap2_32x32_avg_act_from_T0[0] = ps_curr_out->i8_curr_frame_32x32_avg_act[0];
5638         ps_enc_ctxt->ai8_lap2_32x32_avg_act_from_T0[1] = ps_curr_out->i8_curr_frame_32x32_avg_act[1];
5639         ps_enc_ctxt->ai8_lap2_32x32_avg_act_from_T0[2] = ps_curr_out->i8_curr_frame_32x32_avg_act[2];
5640 #endif
5641 
5642         /* calculate modulation index */
5643         {
5644             LWORD64 i8_mean, i8_mean_sqr, i8_variance;
5645             LWORD64 i8_deviation;
5646             WORD32 i4_mod_factor;
5647             float f_strength;
5648 
5649             if(ps_curr_out->i4_acc_frame_8x8_num_blks[0] > 0)
5650             {
5651 #if STRENGTH_BASED_ON_CURR_FRM
5652                 AVG_ACTIVITY(i8_mean_sqr, ps_curr_out->i8_curr_frame_8x8_sum_act_sqr,
5653                              ps_curr_out->i4_curr_frame_8x8_num_blks[0]);
5654 #else
5655                 AVG_ACTIVITY(i8_mean_sqr, ps_curr_out->i8_acc_frame_8x8_sum_act_sqr,
5656                              ps_curr_out->i4_acc_frame_8x8_num_blks[0]);
5657 #endif
5658                 i8_mean = ps_curr_out->i8_curr_frame_8x8_sum_act_for_strength;
5659                 i8_variance = i8_mean_sqr - (i8_mean * i8_mean);
5660                 i8_deviation = sqrt(i8_variance);
5661 
5662 #if STRENGTH_BASED_ON_DEVIATION
5663                 if(i8_deviation <= REF_MOD_DEVIATION)
5664                 {
5665                     f_strength = ((i8_deviation - BELOW_REF_DEVIATION) * REF_MOD_STRENGTH) / (REF_MOD_DEVIATION - BELOW_REF_DEVIATION);
5666                 }
5667                 else
5668                 {
5669                     f_strength = ((i8_deviation - ABOVE_REF_DEVIATION) * REF_MOD_STRENGTH) / (REF_MOD_DEVIATION - ABOVE_REF_DEVIATION);
5670                 }
5671 #else
5672                 f_strength = ((i8_mean_sqr / (float)(i8_mean * i8_mean)) - 1.0) * REF_MOD_STRENGTH / REF_MOD_VARIANCE;
5673 #endif
5674                 i4_mod_factor = (WORD32)(i8_deviation / 60);
5675                 f_strength = CLIP3(f_strength, 0.0, REF_MAX_STRENGTH);
5676             }
5677             else
5678             {
5679                 /* If not sufficient blocks are present, turn modulation index to 1  */
5680                 i4_mod_factor = 1;
5681                 f_strength = 0;
5682             }
5683             ps_curr_out->ai4_mod_factor_derived_by_variance[0] = i4_mod_factor;
5684             ps_curr_out->ai4_mod_factor_derived_by_variance[1] = i4_mod_factor;
5685             ps_curr_out->f_strength = f_strength;
5686 
5687             ps_enc_ctxt->ai4_mod_factor_derived_by_variance[0] = i4_mod_factor;
5688             ps_enc_ctxt->ai4_mod_factor_derived_by_variance[1] = i4_mod_factor;
5689             ps_enc_ctxt->f_strength = f_strength;
5690         }
5691     }
5692     else
5693     {
5694         ps_curr_out->ai4_mod_factor_derived_by_variance[0] = ps_enc_ctxt->ai4_mod_factor_derived_by_variance[0];
5695         ps_curr_out->ai4_mod_factor_derived_by_variance[1] = ps_enc_ctxt->ai4_mod_factor_derived_by_variance[1];
5696         ps_curr_out->f_strength = ps_enc_ctxt->f_strength;
5697 
5698         /* copy the prev avg activity from Tid 0 for B pictures*/
5699 #if POW_OPT
5700         ps_curr_out->ld_curr_frame_8x8_log_avg[0] = ps_enc_ctxt->ald_lap2_8x8_log_avg_act_from_T0[0];
5701         ps_curr_out->ld_curr_frame_8x8_log_avg[1] = ps_enc_ctxt->ald_lap2_8x8_log_avg_act_from_T0[1];
5702         ps_curr_out->ld_curr_frame_16x16_log_avg[0] = ps_enc_ctxt->ald_lap2_16x16_log_avg_act_from_T0[0];
5703         ps_curr_out->ld_curr_frame_16x16_log_avg[1] = ps_enc_ctxt->ald_lap2_16x16_log_avg_act_from_T0[1];
5704         ps_curr_out->ld_curr_frame_16x16_log_avg[2] = ps_enc_ctxt->ald_lap2_16x16_log_avg_act_from_T0[2];
5705         ps_curr_out->ld_curr_frame_32x32_log_avg[0] = ps_enc_ctxt->ald_lap2_32x32_log_avg_act_from_T0[0];
5706         ps_curr_out->ld_curr_frame_32x32_log_avg[1] = ps_enc_ctxt->ald_lap2_32x32_log_avg_act_from_T0[1];
5707         ps_curr_out->ld_curr_frame_32x32_log_avg[2] = ps_enc_ctxt->ald_lap2_32x32_log_avg_act_from_T0[2];
5708 #else
5709         ps_curr_out->i8_curr_frame_8x8_avg_act[0] = ps_enc_ctxt->ai8_lap2_8x8_avg_act_from_T0[0];
5710         ps_curr_out->i8_curr_frame_8x8_avg_act[1] = ps_enc_ctxt->ai8_lap2_8x8_avg_act_from_T0[1];
5711         ps_curr_out->i8_curr_frame_16x16_avg_act[0] = ps_enc_ctxt->ai8_lap2_16x16_avg_act_from_T0[0];
5712         ps_curr_out->i8_curr_frame_16x16_avg_act[1] = ps_enc_ctxt->ai8_lap2_16x16_avg_act_from_T0[1];
5713         ps_curr_out->i8_curr_frame_16x16_avg_act[2] = ps_enc_ctxt->ai8_lap2_16x16_avg_act_from_T0[2];
5714         ps_curr_out->i8_curr_frame_32x32_avg_act[0] = ps_enc_ctxt->ai8_lap2_32x32_avg_act_from_T0[0];
5715         ps_curr_out->i8_curr_frame_32x32_avg_act[1] = ps_enc_ctxt->ai8_lap2_32x32_avg_act_from_T0[1];
5716         ps_curr_out->i8_curr_frame_32x32_avg_act[2] = ps_enc_ctxt->ai8_lap2_32x32_avg_act_from_T0[2];
5717 #endif
5718     }
5719 #undef AVG_ACTIVITY
5720 }
5721 
5722 /*!
5723 ******************************************************************************
5724 * \if Function name : ihevce_pre_enc_process_frame_thrd \endif
5725 *
5726 * \brief
5727 *    Pre-Encode Frame processing thread interface function
5728 *
5729 * \param[in] High level encoder context pointer
5730 *
5731 * \return
5732 *    None
5733 *
5734 * \author
5735 *  Ittiam
5736 *
5737 *****************************************************************************
5738 */
ihevce_pre_enc_process_frame_thrd(void * pv_frm_proc_thrd_ctxt)5739 WORD32 ihevce_pre_enc_process_frame_thrd(void *pv_frm_proc_thrd_ctxt)
5740 {
5741     frm_proc_thrd_ctxt_t *ps_thrd_ctxt = (frm_proc_thrd_ctxt_t *)pv_frm_proc_thrd_ctxt;
5742     ihevce_hle_ctxt_t *ps_hle_ctxt = ps_thrd_ctxt->ps_hle_ctxt;
5743     enc_ctxt_t *ps_enc_ctxt = (enc_ctxt_t *)ps_thrd_ctxt->pv_enc_ctxt;
5744     multi_thrd_ctxt_t *ps_multi_thrd = &ps_enc_ctxt->s_multi_thrd;
5745     WORD32 i4_thrd_id = ps_thrd_ctxt->i4_thrd_id;
5746     WORD32 i4_resolution_id = ps_enc_ctxt->i4_resolution_id;
5747     WORD32 i4_end_flag = 0;
5748     WORD32 i4_out_flush_flag = 0;
5749     WORD32 i4_cur_decomp_idx = 0;
5750     WORD32 i4_cur_coarse_me_idx = 0;
5751     WORD32 i4_cur_ipe_idx = 0;
5752     ihevce_lap_enc_buf_t *ps_lap_inp_buf = NULL;
5753     void *pv_dep_mngr_prev_frame_pre_enc_l1 = ps_multi_thrd->pv_dep_mngr_prev_frame_pre_enc_l1;
5754     void *pv_dep_mngr_prev_frame_pre_enc_l0 = ps_multi_thrd->pv_dep_mngr_prev_frame_pre_enc_l0;
5755     void *pv_dep_mngr_prev_frame_pre_enc_coarse_me =
5756         ps_multi_thrd->pv_dep_mngr_prev_frame_pre_enc_coarse_me;
5757     WORD32 i4_num_buf_prod_for_l0_ipe = 0;
5758     WORD32 i4_decomp_end_flag = 0;
5759 
5760     (void)ps_hle_ctxt;
5761     (void)i4_resolution_id;
5762 
5763     /* ---------- Processing Loop until Flush command is received --------- */
5764     while(0 == i4_end_flag)
5765     {
5766         /* Wait till previous frame(instance)'s decomp_intra is processed */
5767         {
5768             ihevce_dmgr_chk_frm_frm_sync(pv_dep_mngr_prev_frame_pre_enc_l1, i4_thrd_id);
5769         }
5770 
5771         /* ----------------------------------------------------------- */
5772         /*     decomp pre_intra init                                   */
5773         /* ----------------------------------------------------------- */
5774 
5775         /****** Lock the critical section for decomp pre_intra init ******/
5776         {
5777             WORD32 i4_status;
5778 
5779             i4_status = osal_mutex_lock(ps_multi_thrd->pv_mutex_hdl_pre_enc_init);
5780             if(OSAL_SUCCESS != i4_status)
5781                 return 0;
5782         }
5783 
5784         ps_multi_thrd->ai4_decomp_coarse_me_complete_flag[i4_cur_decomp_idx] = 0;
5785 
5786         /* init */
5787         if((ps_multi_thrd->ai4_pre_enc_init_done[i4_cur_decomp_idx] == 0) &&
5788            (0 == i4_decomp_end_flag))
5789         {
5790             ihevce_lap_enc_buf_t *ps_curr_inp = NULL;
5791             pre_enc_me_ctxt_t *ps_curr_out = NULL;
5792             WORD32 in_buf_id;
5793             WORD32 out_buf_id;
5794 
5795             do
5796             {
5797                 ps_lap_inp_buf = NULL;
5798                 if(0 == ps_multi_thrd->i4_last_inp_buf)
5799                 {
5800                     /* ------- get input buffer input data que ---------- */
5801                     ps_lap_inp_buf = (ihevce_lap_enc_buf_t *)ihevce_q_get_filled_buff(
5802                         (void *)ps_enc_ctxt,
5803                         IHEVCE_INPUT_DATA_CTRL_Q,
5804                         &in_buf_id,
5805                         BUFF_QUE_BLOCKING_MODE);
5806                     ps_multi_thrd->i4_last_inp_buf = ihevce_check_last_inp_buf(
5807                         (WORD32 *)ps_lap_inp_buf->s_input_buf.pv_synch_ctrl_bufs);
5808                 }
5809 
5810                 ps_curr_inp =
5811                     ihevce_lap_process(ps_enc_ctxt->pv_lap_interface_ctxt, ps_lap_inp_buf);
5812 
5813             } while(NULL == ps_curr_inp);
5814 
5815             /* set the flag saying init is done so that other cores dont do it */
5816             ps_multi_thrd->ai4_pre_enc_init_done[i4_cur_decomp_idx] = 1;
5817 
5818             ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_decomp_idx] = ps_curr_inp;
5819             ps_multi_thrd->ai4_in_buf_id_pre_enc[i4_cur_decomp_idx] =
5820                 ps_curr_inp->s_input_buf.i4_buf_id;
5821 
5822             /* ------- get free output buffer from pre-enc/enc buffer que ---------- */
5823             ps_curr_out = (pre_enc_me_ctxt_t *)ihevce_q_get_free_buff(
5824                 (void *)ps_enc_ctxt, IHEVCE_PRE_ENC_ME_Q, &out_buf_id, BUFF_QUE_BLOCKING_MODE);
5825             ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_decomp_idx] = ps_curr_out;
5826             ps_multi_thrd->ai4_out_buf_id_pre_enc[i4_cur_decomp_idx] = out_buf_id;
5827 
5828             if((NULL != ps_curr_inp) && (NULL != ps_curr_out))
5829             {
5830                 /* by default last picture to be encoded flag is set to 0      */
5831                 /* this flag will be used by slave threads to exit at the end */
5832                 ps_multi_thrd->i4_last_pic_flag = 0;
5833 
5834                 /* store the buffer id */
5835                 ps_curr_out->i4_buf_id = out_buf_id;
5836 
5837                 ps_curr_out->i8_acc_num_blks_high_sad = 0;
5838                 ps_curr_out->i8_total_blks = 0;
5839                 ps_curr_out->i4_is_high_complex_region = -1;
5840 
5841                 /* set the parameters for sync b/w pre-encode and encode threads */
5842                 ps_curr_out->i4_end_flag = ps_curr_inp->s_lap_out.i4_end_flag;
5843                 ps_curr_out->i4_frm_proc_valid_flag = 1;
5844                 if(ps_curr_out->i4_end_flag)
5845                 {
5846                     ps_curr_out->i4_frm_proc_valid_flag =
5847                         ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag;
5848                     ps_multi_thrd->i4_last_pic_flag = 1;
5849                     ps_multi_thrd->ai4_end_flag_pre_enc[i4_cur_decomp_idx] = 1;
5850                 }
5851                 if(ps_curr_inp->s_lap_out.i4_out_flush_flag)
5852                 {
5853                     ps_curr_out->i4_frm_proc_valid_flag =
5854                         ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag;
5855                 }
5856 
5857                 /* do the init processing if input frm data is valid */
5858                 if(1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag)
5859                 {
5860                     WORD32 end_flag = ps_multi_thrd->ai4_end_flag_pre_enc[i4_cur_decomp_idx];
5861                     WORD32 cur_qp = 0, count;
5862 
5863                     ihevce_pre_enc_init(
5864                         ps_enc_ctxt,
5865                         ps_curr_inp,
5866                         ps_curr_out,
5867                         &end_flag,
5868                         &cur_qp,
5869                         &ps_multi_thrd->ai4_decomp_lyr_buf_idx[i4_cur_decomp_idx],
5870                         i4_cur_decomp_idx);
5871 
5872                     ps_multi_thrd->ai4_end_flag_pre_enc[i4_cur_decomp_idx] = end_flag;
5873                     ps_multi_thrd->ai4_cur_frame_qp_pre_enc[i4_cur_decomp_idx] = cur_qp;
5874 
5875                     for(count = 0; count < ((HEVCE_MAX_HEIGHT >> 1) / 8); count++)
5876                     {
5877                         ps_multi_thrd->aai4_l1_pre_intra_done[i4_cur_decomp_idx][count] = 0;
5878                     }
5879                 }
5880             }
5881         }
5882         else if(1 == i4_decomp_end_flag)
5883         {
5884             /* Once end is reached all subsequent flags are set to 1 to indicate end */
5885             ps_multi_thrd->ai4_end_flag_pre_enc[i4_cur_decomp_idx] = 1;
5886         }
5887 
5888         /****** UnLock the critical section after decomp pre_intra init ******/
5889         {
5890             WORD32 i4_status;
5891             i4_status = osal_mutex_unlock(ps_multi_thrd->pv_mutex_hdl_pre_enc_init);
5892 
5893             if(OSAL_SUCCESS != i4_status)
5894                 return 0;
5895         }
5896         if(i4_thrd_id == 0)
5897         {
5898             PROFILE_START(&ps_hle_ctxt->profile_pre_enc_l1l2[i4_resolution_id]);
5899         }
5900         /* ------------------------------------------------------------ */
5901         /*        Layer Decomp and Pre Intra Analysis                   */
5902         /* ------------------------------------------------------------ */
5903         if(0 == i4_decomp_end_flag)
5904         {
5905             pre_enc_me_ctxt_t *ps_curr_out = ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_decomp_idx];
5906 
5907             if(1 == ps_curr_out->i4_frm_proc_valid_flag)
5908             {
5909                 ihevce_decomp_pre_intra_process(
5910                     ps_enc_ctxt->s_module_ctxt.pv_decomp_pre_intra_ctxt,
5911                     &ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_decomp_idx]->s_lap_out,
5912                     &ps_enc_ctxt->s_frm_ctb_prms,
5913                     ps_multi_thrd,
5914                     i4_thrd_id,
5915                     i4_cur_decomp_idx);
5916             }
5917         }
5918 
5919         /* ------------------------------------------------------------ */
5920         /*        Layer Decomp and Pre Intra Deinit                     */
5921         /* ------------------------------------------------------------ */
5922 
5923         /****** Lock the critical section for decomp deinit ******/
5924         {
5925             WORD32 i4_status;
5926             i4_status = osal_mutex_lock(ps_multi_thrd->pv_mutex_hdl_pre_enc_decomp_deinit);
5927 
5928             if(OSAL_SUCCESS != i4_status)
5929                 return 0;
5930         }
5931 
5932         ps_multi_thrd->ai4_num_thrds_processed_decomp[i4_cur_decomp_idx]++;
5933         i4_decomp_end_flag = ps_multi_thrd->ai4_end_flag_pre_enc[i4_cur_decomp_idx];
5934 
5935         /* check for last thread condition */
5936         if(ps_multi_thrd->ai4_num_thrds_processed_decomp[i4_cur_decomp_idx] ==
5937            ps_multi_thrd->i4_num_pre_enc_proc_thrds)
5938         {
5939             ps_multi_thrd->ai4_num_thrds_processed_decomp[i4_cur_decomp_idx] = 0;
5940 
5941             /* reset the init flag so that init happens by the first thread for the next frame
5942                of same ping_pong instance */
5943             ps_multi_thrd->ai4_pre_enc_init_done[i4_cur_decomp_idx] = 0;
5944 
5945             /* update the pre enc l1 done in dep manager */
5946             ihevce_dmgr_update_frm_frm_sync(pv_dep_mngr_prev_frame_pre_enc_l1);
5947         }
5948 
5949         /* index increment */
5950         i4_cur_decomp_idx = i4_cur_decomp_idx + 1;
5951 
5952         /* wrap around case */
5953         if(i4_cur_decomp_idx >= ps_multi_thrd->i4_max_delay_pre_me_btw_l0_ipe)
5954         {
5955             i4_cur_decomp_idx = 0;
5956         }
5957 
5958         /****** UnLock the critical section after decomp pre_intra deinit ******/
5959         {
5960             WORD32 i4_status;
5961             i4_status = osal_mutex_unlock(ps_multi_thrd->pv_mutex_hdl_pre_enc_decomp_deinit);
5962 
5963             if(OSAL_SUCCESS != i4_status)
5964                 return 0;
5965         }
5966 
5967         /* ------------------------------------------------------------ */
5968         /*                     HME Init                                 */
5969         /* ------------------------------------------------------------ */
5970 
5971         /* Wait till previous frame(instance)'s coarse_me is processed */
5972         {
5973             ihevce_dmgr_chk_frm_frm_sync(pv_dep_mngr_prev_frame_pre_enc_coarse_me, i4_thrd_id);
5974         }
5975 
5976         /****** Lock the critical section for hme init ******/
5977         {
5978             WORD32 i4_status;
5979 
5980             i4_status = osal_mutex_lock(ps_multi_thrd->pv_mutex_hdl_pre_enc_hme_init);
5981             if(OSAL_SUCCESS != i4_status)
5982                 return 0;
5983         }
5984 
5985         if(0 == ps_multi_thrd->ai4_pre_enc_hme_init_done[i4_cur_coarse_me_idx])
5986         {
5987             /* do the init processing if input frm data is valid */
5988             if(1 ==
5989                ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx]->i4_frm_proc_valid_flag)
5990             {
5991                 recon_pic_buf_t *ps_frm_recon = NULL;
5992 
5993                 /* DPB management for coarse me + HME init */
5994                 ihevce_pre_enc_coarse_me_init(
5995                     ps_enc_ctxt,
5996                     ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_coarse_me_idx],
5997                     ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx],
5998                     &ps_frm_recon,
5999                     ps_multi_thrd->ai4_decomp_lyr_buf_idx[i4_cur_coarse_me_idx],
6000                     ps_multi_thrd->ai4_cur_frame_qp_pre_enc[i4_cur_coarse_me_idx],
6001                     i4_cur_coarse_me_idx);
6002             }
6003 
6004             ps_multi_thrd->ai4_pre_enc_hme_init_done[i4_cur_coarse_me_idx] = 1;
6005         }
6006 
6007         /****** Unlock the critical section for hme init ******/
6008         {
6009             WORD32 i4_status;
6010 
6011             i4_status = osal_mutex_unlock(ps_multi_thrd->pv_mutex_hdl_pre_enc_hme_init);
6012             if(OSAL_SUCCESS != i4_status)
6013                 return 0;
6014         }
6015 
6016         /* ------------------------------------------------------------ */
6017         /*  Coarse Motion estimation and early intra-inter decision     */
6018         /* ------------------------------------------------------------ */
6019         if(1 == ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx]->i4_frm_proc_valid_flag)
6020         {
6021             ihevce_coarse_me_process(
6022                 ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
6023                 ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_coarse_me_idx],
6024                 &ps_enc_ctxt->s_multi_thrd,
6025                 i4_thrd_id,
6026                 i4_cur_coarse_me_idx);
6027         }
6028 
6029         /* update the end flag */
6030         i4_end_flag = ps_multi_thrd->ai4_end_flag_pre_enc[i4_cur_coarse_me_idx];
6031         i4_out_flush_flag =
6032             ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_coarse_me_idx]->s_lap_out.i4_out_flush_flag;
6033 
6034         /****** Lock the critical section for hme deinit ******/
6035         {
6036             WORD32 i4_status;
6037             i4_status = osal_mutex_lock(ps_multi_thrd->pv_mutex_hdl_pre_enc_hme_deinit);
6038 
6039             if(OSAL_SUCCESS != i4_status)
6040                 return 0;
6041         }
6042 
6043         /* last thread finishing pre_enc_process will update the flag indicating
6044         decomp and coarse ME is done. So that the next frame (next ping_pong instance)
6045         can start immediately after finishing current frame's IPE */
6046         if(1 == ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx]->i4_frm_proc_valid_flag)
6047         {
6048             ps_multi_thrd->ai4_num_thrds_processed_coarse_me[i4_cur_coarse_me_idx]++;
6049 
6050             /* ------------------------------------------------------------ */
6051             /*  Update qp used in based in L1 satd/act in case of scene cut */
6052             /* ------------------------------------------------------------ */
6053             {
6054                 ihevce_lap_enc_buf_t *ps_curr_inp =
6055                     ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_coarse_me_idx];
6056 
6057                 if(1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag)
6058                 {
6059                     WORD32 i4_prev_coarse_me_idx;
6060 
6061                     /* wrap around case */
6062                     if(i4_cur_coarse_me_idx == 0)
6063                     {
6064                         i4_prev_coarse_me_idx = ps_multi_thrd->i4_max_delay_pre_me_btw_l0_ipe - 1;
6065                     }
6066                     else
6067                     {
6068                         i4_prev_coarse_me_idx = i4_cur_coarse_me_idx - 1;
6069                     }
6070 
6071                     ihevce_update_qp_L1_sad_based(
6072                         ps_enc_ctxt,
6073                         ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_coarse_me_idx],
6074                         ps_multi_thrd->aps_curr_inp_pre_enc[i4_prev_coarse_me_idx],
6075                         ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx],
6076                         ((ps_multi_thrd->ai4_num_thrds_processed_coarse_me[i4_cur_coarse_me_idx] ==
6077                           ps_multi_thrd->i4_num_pre_enc_proc_thrds)));
6078                 }
6079             }
6080             /* check for last thread condition */
6081             if(ps_multi_thrd->ai4_num_thrds_processed_coarse_me[i4_cur_coarse_me_idx] ==
6082                ps_multi_thrd->i4_num_pre_enc_proc_thrds)
6083             {
6084                 ihevce_lap_enc_buf_t *ps_curr_inp =
6085                     ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_coarse_me_idx];
6086 
6087                 /*        Frame END processing                  */
6088                 ihevce_coarse_me_frame_end(ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt);
6089 
6090                 if(1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag)
6091                 {
6092                     WORD32 i4_enable_noise_detection = 0;
6093                     WORD32 i4_vqet = ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_vqet;
6094 
6095                     if(i4_vqet & (1 << BITPOS_IN_VQ_TOGGLE_FOR_CONTROL_TOGGLER))
6096                     {
6097                         if(i4_vqet & (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_NOISE_PRESERVATION))
6098                         {
6099                             i4_enable_noise_detection = 1;
6100                         }
6101                     }
6102 
6103                     if(1 != ((ps_curr_inp->s_lap_out.i4_pic_type == IV_B_FRAME) &&
6104                              (ps_enc_ctxt->s_lap_stat_prms.ai4_quality_preset[i4_resolution_id] ==
6105                               IHEVCE_QUALITY_P6)))
6106                     {
6107                         ihevce_decomp_pre_intra_curr_frame_pre_intra_deinit(
6108                             ps_enc_ctxt->s_module_ctxt.pv_decomp_pre_intra_ctxt,
6109                             ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx],
6110                             &ps_enc_ctxt->s_frm_ctb_prms);
6111                     }
6112                 }
6113 
6114                 ps_multi_thrd->ai4_decomp_coarse_me_complete_flag[i4_cur_coarse_me_idx] = 1;
6115 
6116                 ps_multi_thrd->ai4_num_thrds_processed_coarse_me[i4_cur_coarse_me_idx] = 0;
6117 
6118                 /* get the layer 1 ctxt to be passed on to encode group */
6119                 ihevce_coarse_me_get_lyr1_ctxt(
6120                     ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
6121                     ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx]->pv_me_lyr_ctxt,
6122                     ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx]->pv_me_lyr_bnk_ctxt);
6123 
6124                 /* reset the init flag so that init happens by the first thread for the next frame
6125                     of same ping_pong instance */
6126                 ps_multi_thrd->ai4_pre_enc_hme_init_done[i4_cur_coarse_me_idx] = 0;
6127 
6128                 /* update the pre enc l1 done in dep manager */
6129                 ihevce_dmgr_update_frm_frm_sync(pv_dep_mngr_prev_frame_pre_enc_coarse_me);
6130             }
6131 
6132             i4_num_buf_prod_for_l0_ipe++;
6133 
6134             /* index increment */
6135             i4_cur_coarse_me_idx = i4_cur_coarse_me_idx + 1;
6136 
6137             /* wrap around case */
6138             if(i4_cur_coarse_me_idx >= ps_multi_thrd->i4_max_delay_pre_me_btw_l0_ipe)
6139             {
6140                 i4_cur_coarse_me_idx = 0;
6141             }
6142         }
6143         else
6144         {
6145             /* for invalid frame set the processed flag to 1 for L0 IPE */
6146             ps_multi_thrd->ai4_decomp_coarse_me_complete_flag[i4_cur_coarse_me_idx] = 1;
6147 
6148             if(1 == i4_out_flush_flag)
6149             {
6150                 /* update the num thrds who have finished pre-enc processing */
6151                 ps_multi_thrd->ai4_num_thrds_processed_coarse_me[i4_cur_coarse_me_idx]++;
6152 
6153                 if(ps_multi_thrd->ai4_num_thrds_processed_coarse_me[i4_cur_coarse_me_idx] ==
6154                    ps_multi_thrd->i4_num_pre_enc_proc_thrds)
6155                 {
6156                     ps_multi_thrd->ai4_decomp_coarse_me_complete_flag[i4_cur_coarse_me_idx] = 1;
6157 
6158                     /* reset num thread finished counter */
6159                     ps_multi_thrd->ai4_num_thrds_processed_coarse_me[i4_cur_coarse_me_idx] = 0;
6160 
6161                     ps_multi_thrd->ai4_pre_enc_hme_init_done[i4_cur_coarse_me_idx] = 0;
6162 
6163                     /* update flag indicating coarse_me and decomp is done */
6164                     ihevce_dmgr_update_frm_frm_sync(pv_dep_mngr_prev_frame_pre_enc_coarse_me);
6165                 }
6166             }
6167 
6168             i4_num_buf_prod_for_l0_ipe++;
6169 
6170             /* index increment */
6171             i4_cur_coarse_me_idx = i4_cur_coarse_me_idx + 1;
6172 
6173             /* wrap around case */
6174             if(i4_cur_coarse_me_idx >= ps_multi_thrd->i4_max_delay_pre_me_btw_l0_ipe)
6175             {
6176                 i4_cur_coarse_me_idx = 0;
6177             }
6178         }
6179 
6180         /****** UnLock the critical section after hme deinit ******/
6181         {
6182             WORD32 i4_status;
6183             i4_status =
6184                 osal_mutex_unlock(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_deinit);
6185 
6186             if(OSAL_SUCCESS != i4_status)
6187                 return 0;
6188         }
6189 
6190         if(i4_thrd_id == 0)
6191         {
6192             PROFILE_STOP(&ps_hle_ctxt->profile_pre_enc_l1l2[i4_resolution_id], NULL);
6193         }
6194 
6195         /* ----------------------------------------------------------- */
6196         /*     IPE init and process                                    */
6197         /* ----------------------------------------------------------- */
6198         if(i4_thrd_id == 0)
6199         {
6200             PROFILE_START(&ps_hle_ctxt->profile_pre_enc_l0ipe[i4_resolution_id]);
6201         }
6202         if(i4_num_buf_prod_for_l0_ipe >= ps_multi_thrd->i4_delay_pre_me_btw_l0_ipe || i4_end_flag ||
6203            i4_out_flush_flag)
6204         {
6205             do
6206             {
6207                 /* Wait till previous frame(instance)'s IPE is processed */
6208                 {
6209                     ihevce_dmgr_chk_frm_frm_sync(pv_dep_mngr_prev_frame_pre_enc_l0, i4_thrd_id);
6210                 }
6211 
6212                 /* Wait till current frame(instance)'s L1 and below layers are processed */
6213                 {
6214                     volatile WORD32 *pi4_cur_l1_complete =
6215                         &ps_multi_thrd->ai4_decomp_coarse_me_complete_flag[i4_cur_ipe_idx];
6216 
6217                     while(1)
6218                     {
6219                         if(*pi4_cur_l1_complete)
6220                             break;
6221                     }
6222                 }
6223 
6224                 /* ----------------------------------------------------------- */
6225                 /*     L0 IPE qp init                                          */
6226                 /* ----------------------------------------------------------- */
6227 
6228                 /****** Lock the critical section for init ******/
6229                 {
6230                     WORD32 i4_status;
6231                     i4_status = osal_mutex_lock(ps_multi_thrd->pv_mutex_hdl_l0_ipe_init);
6232 
6233                     if(OSAL_SUCCESS != i4_status)
6234                         return 0;
6235                 }
6236 
6237                 /* first thread that enters will calculate qp and write that to shared variable
6238                    that will be accessed by other threads */
6239                 if(ps_multi_thrd->ai4_num_thrds_processed_L0_ipe_qp_init[i4_cur_ipe_idx] == 0)
6240                 {
6241                     volatile WORD32 i4_is_qp_valid = -1;
6242                     WORD32 i4_update_qp;
6243                     WORD32 i4_cur_q_scale;
6244 
6245                     i4_cur_q_scale =
6246                         ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->i4_curr_frm_qp;
6247                     i4_cur_q_scale = ps_enc_ctxt->s_rc_quant.pi4_qp_to_qscale[i4_cur_q_scale];
6248                     i4_cur_q_scale = (i4_cur_q_scale + (1 << (QSCALE_Q_FAC_3 - 1))) >>
6249                                      QSCALE_Q_FAC_3;
6250                     /* Get free buffer to store L0 IPE output to enc loop */
6251                     ps_multi_thrd->ps_L0_IPE_curr_out_pre_enc =
6252                         (pre_enc_L0_ipe_encloop_ctxt_t *)ihevce_q_get_free_buff(
6253                             (void *)ps_enc_ctxt,
6254                             IHEVCE_L0_IPE_ENC_Q,
6255                             &ps_multi_thrd->i4_L0_IPE_out_buf_id,
6256                             BUFF_QUE_BLOCKING_MODE);
6257                     if(ps_enc_ctxt->ps_stat_prms->s_pass_prms.i4_pass != 2 &&
6258                        ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_rate_control_mode != 3)
6259                     {
6260                         complexity_RC_reset_marking(
6261                             ps_enc_ctxt, i4_cur_ipe_idx, (i4_end_flag || i4_out_flush_flag));
6262                     }
6263                     if(1 == ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6264                                 ->s_input_buf.i4_inp_frm_data_valid_flag)
6265                     {
6266                         while(i4_is_qp_valid == -1)
6267                         {
6268                             /*this rate control call is outside mutex lock to avoid deadlock. If this acquires mutex lock enc will not be able to
6269                             populate qp*/
6270                             i4_is_qp_valid = ihevce_rc_check_is_pre_enc_qp_valid(
6271                                 (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
6272                                 (volatile WORD32 *)&ps_enc_ctxt->s_multi_thrd.i4_force_end_flag);
6273                             if(1 == ps_enc_ctxt->s_multi_thrd.i4_force_end_flag)
6274                             {
6275                                 /*** For force end condition break from this loop ***/
6276                                 i4_is_qp_valid = 1;
6277                                 break;
6278                             }
6279                         }
6280 
6281                         /*lock rate control context*/
6282                         osal_mutex_lock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
6283 
6284                         /* Qp query has to happen irrespective of using it or not since producer consumer logic will be disturbed */
6285                         i4_update_qp = ihevce_rc_pre_enc_qp_query(
6286                             (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
6287                             &ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]->s_rc_lap_out,
6288                             0);
6289 
6290                         if(ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_rate_control_mode != 3)
6291                         {
6292                             ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6293                                 ->s_rc_lap_out.i8_frm_satd_act_accum_L0_frm_L1 =
6294                                 ihevce_get_L0_satd_based_on_L1(
6295                                     ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6296                                         ->s_rc_lap_out.i8_frame_satd_by_act_L1_accum,
6297                                     ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6298                                         ->s_rc_lap_out.i4_num_pels_in_frame_considered,
6299                                     i4_cur_q_scale);
6300 
6301                             if(ps_enc_ctxt->ps_stat_prms->s_pass_prms.i4_pass != 2)
6302                             {
6303                                 if(ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6304                                            ->s_rc_lap_out.i4_rc_scene_type ==
6305                                        SCENE_TYPE_SCENE_CUT ||
6306                                    ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6307                                        ->s_rc_lap_out.i4_is_I_only_scd ||
6308                                    ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6309                                            ->s_rc_lap_out.i4_is_non_I_scd == 1)
6310                                 {
6311                                     float i_to_avg_rest_ratio;
6312                                     WORD32 i4_count = 0;
6313 
6314                                     while(1)
6315                                     {
6316                                         i_to_avg_rest_ratio = ihevce_get_i_to_avg_ratio(
6317                                             ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
6318                                             &ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6319                                                  ->s_rc_lap_out,
6320                                             1,
6321                                             0,
6322                                             0,
6323                                             ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6324                                                 ->s_rc_lap_out.ai4_offsets,
6325                                             0);
6326                                         /* HEVC_RC query rate control for qp */
6327                                         i4_update_qp = ihevce_get_L0_est_satd_based_scd_qp(
6328                                             ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
6329                                             &ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6330                                                  ->s_rc_lap_out,
6331                                             ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6332                                                 ->s_rc_lap_out.i8_frm_satd_act_accum_L0_frm_L1,
6333                                             i_to_avg_rest_ratio);
6334 
6335                                         ihevce_set_L0_scd_qp(
6336                                             ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
6337                                             i4_update_qp);
6338 
6339                                         if(ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6340                                                    ->s_lap_out.i4_pic_type != IV_IDR_FRAME &&
6341                                            ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6342                                                    ->s_lap_out.i4_pic_type != IV_I_FRAME)
6343                                         {
6344                                             i4_update_qp +=
6345                                                 ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6346                                                     ->s_lap_out.i4_temporal_lyr_id +
6347                                                 1;
6348 
6349                                             i4_update_qp =
6350                                                 CLIP3(i4_update_qp, MIN_HEVC_QP, MAX_HEVC_QP);
6351                                         }
6352 
6353                                         i4_count++;
6354                                         if((i4_update_qp ==
6355                                             ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6356                                                 ->s_rc_lap_out.i4_L0_qp) ||
6357                                            i4_count > 4)
6358                                             break;
6359 
6360                                         ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6361                                             ->s_rc_lap_out.i4_L0_qp = i4_update_qp;
6362                                     }
6363                                 }
6364                             }
6365                             else
6366                             {
6367                                 //i4_update_qp = ihevce_get_first_pass_qp(ps_enc_ctxt->s_multi_thrd.aps_curr_inp_pre_enc[i4_cur_ipe_idx]->s_lap_out.pv_frame_info);
6368                                 i4_update_qp = ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6369                                                    ->s_rc_lap_out.ps_frame_info->i4_rc_hevc_qp;
6370                             }
6371                         }
6372 
6373                         {
6374                             WORD32 i4_index = 0;
6375                             rc_lap_out_params_t *ps_rc_lap_temp =
6376                                 &ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]->s_rc_lap_out;
6377                             WORD32 i4_offset;
6378 
6379                             if(ps_rc_lap_temp->i4_rc_pic_type != IV_IDR_FRAME &&
6380                                ps_rc_lap_temp->i4_rc_pic_type != IV_I_FRAME)
6381                             {
6382                                 i4_index = ps_rc_lap_temp->i4_rc_temporal_lyr_id + 1;
6383                             }
6384                             i4_offset = ps_rc_lap_temp->ai4_offsets[i4_index];
6385                             ASSERT(i4_offset >= 0);
6386                             /* Map the current frame Qp to L0 Qp */
6387                             ps_rc_lap_temp->i4_L0_qp = i4_update_qp - i4_offset;
6388                         }
6389                         osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
6390                         ASSERT(ps_multi_thrd->i4_qp_update_l0_ipe == -1);
6391                         ps_multi_thrd->i4_qp_update_l0_ipe = i4_update_qp;
6392                         ps_multi_thrd->i4_rc_l0_qp = i4_update_qp;
6393                     }
6394                     ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6395                         ->s_lap_out.f_i_pic_lamda_modifier = CONST_LAMDA_MOD_VAL;
6396                 }
6397                 /* update qp only if it is not scene cut since it has already been
6398                    populated in L1 for scene cut frames */
6399                 if(1 == ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6400                             ->s_input_buf.i4_inp_frm_data_valid_flag &&
6401                    ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_rate_control_mode != 3)
6402                 {
6403                     /*get relevant lambda params*/
6404                     ihevce_get_frame_lambda_prms(
6405                         ps_enc_ctxt,
6406                         ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx],
6407                         ps_multi_thrd->i4_qp_update_l0_ipe,
6408                         ps_enc_ctxt->s_runtime_src_prms.i4_field_pic,
6409                         ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]->s_lap_out.i4_is_ref_pic,
6410                         ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6411                             ->s_lap_out.i4_temporal_lyr_id,
6412                         ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6413                             ->s_lap_out.f_i_pic_lamda_modifier,
6414                         0,
6415                         PRE_ENC_LAMBDA_TYPE);
6416 
6417                     ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->i4_curr_frm_qp =
6418                         ps_multi_thrd->i4_qp_update_l0_ipe;
6419                 }
6420                 /* Compute accumulated activity and strength */
6421                 if(1 == ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6422                             ->s_input_buf.i4_inp_frm_data_valid_flag &&
6423                    ps_multi_thrd->ai4_num_thrds_processed_L0_ipe_qp_init[i4_cur_ipe_idx] == 0)
6424                 {
6425                     ihevce_variance_calc_acc_activity(ps_enc_ctxt, i4_cur_ipe_idx);
6426                 }
6427 
6428                 /* Mark qp as read by last thread */
6429                 ps_multi_thrd->ai4_num_thrds_processed_L0_ipe_qp_init[i4_cur_ipe_idx]++;
6430                 if(ps_multi_thrd->ai4_num_thrds_processed_L0_ipe_qp_init[i4_cur_ipe_idx] ==
6431                    ps_multi_thrd->i4_num_pre_enc_proc_thrds)
6432                 {
6433                     ps_multi_thrd->ai4_num_thrds_processed_L0_ipe_qp_init[i4_cur_ipe_idx] = 0;
6434                     ps_multi_thrd->i4_qp_update_l0_ipe = -1;
6435                 }
6436 
6437                 /****** UnLock the critical section after deinit ******/
6438                 {
6439                     WORD32 i4_status;
6440                     i4_status = osal_mutex_unlock(ps_multi_thrd->pv_mutex_hdl_l0_ipe_init);
6441 
6442                     if(OSAL_SUCCESS != i4_status)
6443                         return 0;
6444                 }
6445 
6446                 if(1 == ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6447                             ->s_input_buf.i4_inp_frm_data_valid_flag)
6448                 {
6449                     WORD32 i4_slice_type =
6450                         (WORD32)ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]
6451                             ->s_slice_hdr.i1_slice_type;
6452                     WORD32 i4_quality_preset =
6453                         (WORD32)ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6454                             ->s_lap_out.i4_quality_preset;
6455                     WORD32 i4_temporal_layer_id =
6456                         (WORD32)ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6457                             ->s_lap_out.i4_temporal_lyr_id;
6458 #if DISABLE_L0_IPE_INTRA_IN_BPICS
6459                     if(1 != ((i4_quality_preset == IHEVCE_QUALITY_P6) &&
6460                              (i4_temporal_layer_id > TEMPORAL_LAYER_DISABLE)))
6461 #endif
6462                     {
6463                         UWORD8 i1_cu_qp_delta_enabled_flag =
6464                             ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_cu_level_rc;
6465 
6466                         ihevce_populate_ipe_frame_init(
6467                             ps_enc_ctxt->s_module_ctxt.pv_ipe_ctxt,
6468                             ps_enc_ctxt->ps_stat_prms,
6469                             ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->i4_curr_frm_qp,
6470                             i4_slice_type,
6471                             i4_thrd_id,
6472                             ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx],
6473                             i1_cu_qp_delta_enabled_flag,
6474                             &ps_enc_ctxt->s_rc_quant,
6475                             i4_quality_preset,
6476                             i4_temporal_layer_id,
6477                             &ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]->s_lap_out);
6478 
6479                         ihevce_ipe_process(
6480                             ps_enc_ctxt->s_module_ctxt.pv_ipe_ctxt,
6481                             &ps_enc_ctxt->s_frm_ctb_prms,
6482                             &ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->as_lambda_prms[0],
6483                             ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx],
6484                             ps_multi_thrd->ps_L0_IPE_curr_out_pre_enc,
6485                             ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->ps_ctb_analyse,
6486                             ps_multi_thrd->ps_L0_IPE_curr_out_pre_enc->ps_ipe_analyse_ctb,
6487                             &ps_enc_ctxt->s_multi_thrd,
6488                             i4_slice_type,
6489                             ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->ps_layer1_buf,
6490                             ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->ps_layer2_buf,
6491                             ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->ps_ed_ctb_l1,
6492                             i4_thrd_id,
6493                             i4_cur_ipe_idx);
6494                     }
6495                 }
6496 
6497                 /* ----------------------------------------------------------- */
6498                 /*     pre-enc de-init                                         */
6499                 /* ----------------------------------------------------------- */
6500 
6501                 /****** Lock the critical section for deinit ******/
6502                 {
6503                     WORD32 i4_status;
6504                     i4_status = osal_mutex_lock(ps_multi_thrd->pv_mutex_hdl_pre_enc_deinit);
6505 
6506                     if(OSAL_SUCCESS != i4_status)
6507                         return 0;
6508                 }
6509 
6510                 ps_multi_thrd->ai4_num_thrds_processed_pre_enc[i4_cur_ipe_idx]++;
6511                 if(ps_multi_thrd->ai4_num_thrds_processed_pre_enc[i4_cur_ipe_idx] ==
6512                    ps_multi_thrd->i4_num_pre_enc_proc_thrds)
6513                 {
6514                     ps_multi_thrd->ai4_pre_enc_deinit_done[i4_cur_ipe_idx] = 0;
6515                     ps_multi_thrd->ai4_num_thrds_processed_pre_enc[i4_cur_ipe_idx] = 0;
6516 
6517                     /* reset the init flag so that init happens by the first thread for the
6518                        next frame of same ping_pnog instnace */
6519                     ps_multi_thrd->ai4_pre_enc_init_done[i4_cur_ipe_idx] = 0;
6520                 }
6521 
6522                 /* de-init */
6523                 if(0 == ps_multi_thrd->ai4_pre_enc_deinit_done[i4_cur_ipe_idx])
6524                 {
6525                     ihevce_lap_enc_buf_t *ps_curr_inp =
6526                         ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx];
6527                     pre_enc_me_ctxt_t *ps_curr_out =
6528                         ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx];
6529 
6530                     /* set the flag saying de init is done so that other cores dont do it */
6531                     ps_multi_thrd->ai4_pre_enc_deinit_done[i4_cur_ipe_idx] = 1;
6532 
6533                     if(1 == ps_curr_out->i4_frm_proc_valid_flag)
6534                     {
6535                         LWORD64 frame_acc_satd_by_modqp;
6536                         float L1_full_processed_ratio;
6537 
6538                         if(ps_curr_inp->s_rc_lap_out.i8_satd_by_act_L1_accum_evaluated)
6539                         {
6540                             L1_full_processed_ratio =
6541                                 ((float)ps_curr_inp->s_rc_lap_out.i8_frame_satd_by_act_L1_accum /
6542                                  ps_curr_inp->s_rc_lap_out.i8_satd_by_act_L1_accum_evaluated);
6543                         }
6544                         else
6545                         {
6546                             L1_full_processed_ratio = 1.0;
6547                         }
6548                         /* Get frame-level satd cost and mode bit cost from IPE */
6549                         ps_curr_out->i8_frame_acc_satd_cost = ihevce_ipe_get_frame_intra_satd_cost(
6550                             ps_enc_ctxt->s_module_ctxt.pv_ipe_ctxt,
6551                             &frame_acc_satd_by_modqp,
6552                             &ps_curr_inp->s_rc_lap_out.i8_est_I_pic_header_bits,
6553                             &ps_curr_inp->s_lap_out.i8_frame_level_activity_fact,
6554                             &ps_curr_inp->s_lap_out.i8_frame_l0_acc_satd);
6555 
6556                         if((ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6) &&
6557                            (ps_curr_inp->s_lap_out.i4_temporal_lyr_id > TEMPORAL_LAYER_DISABLE))
6558                         {
6559                             ps_curr_inp->s_rc_lap_out.i8_est_I_pic_header_bits = -1;
6560                         }
6561 
6562                         {
6563                             WORD32 i4_cur_q_scale = (ps_enc_ctxt->s_rc_quant.pi4_qp_to_qscale
6564                                                          [ps_enc_ctxt->s_multi_thrd.i4_rc_l0_qp +
6565                                                           ps_enc_ctxt->s_rc_quant.i1_qp_offset] +
6566                                                      (1 << (QSCALE_Q_FAC_3 - 1))) >>
6567                                                     QSCALE_Q_FAC_3;
6568 
6569                             /* calculate satd/act_fac = satd/qm * (qp_used_at_L0_analysis) */
6570                             ps_curr_inp->s_rc_lap_out.i8_frame_satd_act_accum =
6571                                 frame_acc_satd_by_modqp * i4_cur_q_scale;
6572                         }
6573 
6574                         /* Because of early intra inter decision, L0 intra analysis might not happen for entire frame, correct the error
6575                            based on L1 data */
6576                         ps_curr_inp->s_rc_lap_out.i8_est_I_pic_header_bits = (LWORD64)(
6577                             ps_curr_inp->s_rc_lap_out.i8_est_I_pic_header_bits *
6578                             L1_full_processed_ratio);
6579 
6580                         if(L1_full_processed_ratio < 1.5)
6581                         {
6582                             ps_curr_inp->s_rc_lap_out.i8_frame_satd_act_accum = (LWORD64)(
6583                                 ps_curr_inp->s_rc_lap_out.i8_frame_satd_act_accum *
6584                                 L1_full_processed_ratio);
6585                         }
6586                         else
6587                         {
6588                             /* This is the case when too many candidates would not have gone through intra analysis, scaling based on L1 is found to be inappropriate,
6589                             Hence directly estimating L0 satd from L1 satd */
6590                             ps_curr_inp->s_rc_lap_out.i8_frame_satd_act_accum =
6591                                 ps_curr_inp->s_rc_lap_out.i8_frm_satd_act_accum_L0_frm_L1;
6592                         }
6593                     }
6594 
6595                     /* register the current input buffer to be cnosumed by encode group threads */
6596                     ps_curr_out->curr_inp_buf_id =
6597                         ps_multi_thrd->ai4_in_buf_id_pre_enc[i4_cur_ipe_idx];
6598                     ps_curr_out->ps_curr_inp = ps_curr_inp;
6599 
6600                     /* set the output buffer as produced */
6601                     ihevce_q_set_buff_prod(
6602                         (void *)ps_enc_ctxt,
6603                         IHEVCE_PRE_ENC_ME_Q,
6604                         ps_multi_thrd->ai4_out_buf_id_pre_enc[i4_cur_ipe_idx]);
6605 
6606                     /* set the output buffer of L0 IPE as produced */
6607                     ihevce_q_set_buff_prod(
6608                         (void *)ps_enc_ctxt,
6609                         IHEVCE_L0_IPE_ENC_Q,
6610                         ps_multi_thrd->i4_L0_IPE_out_buf_id);
6611 
6612                     /* update flag indicating ipe is done */
6613                     ihevce_dmgr_update_frm_frm_sync(pv_dep_mngr_prev_frame_pre_enc_l0);
6614                 }
6615 
6616                 {
6617                     /* index increment */
6618                     i4_cur_ipe_idx = i4_cur_ipe_idx + 1;
6619 
6620                     /* wrap around case */
6621                     if(i4_cur_ipe_idx >= ps_multi_thrd->i4_max_delay_pre_me_btw_l0_ipe)
6622                     {
6623                         i4_cur_ipe_idx = 0;
6624                     }
6625 
6626                     i4_num_buf_prod_for_l0_ipe--;
6627                 }
6628                 /*NOTE: update of above indices should mark end if ipe.do not access below this*/
6629 
6630                 /****** UnLock the critical section after deinit ******/
6631                 {
6632                     WORD32 i4_status;
6633                     i4_status = osal_mutex_unlock(ps_multi_thrd->pv_mutex_hdl_pre_enc_deinit);
6634 
6635                     if(OSAL_SUCCESS != i4_status)
6636                         return 0;
6637                 }
6638 
6639                 if(1 == ps_multi_thrd->i4_force_end_flag)
6640                 {
6641                     i4_end_flag = 1;
6642                     break;
6643                 }
6644             } while((i4_end_flag || i4_out_flush_flag) && i4_num_buf_prod_for_l0_ipe);
6645         }
6646         if(i4_thrd_id == 0)
6647         {
6648             PROFILE_STOP(&ps_hle_ctxt->profile_pre_enc_l0ipe[i4_resolution_id], NULL);
6649         }
6650     }
6651 
6652     return 0;
6653 }
6654 
calc_l1_level_hme_intra_sad_different_qp(enc_ctxt_t * ps_enc_ctxt,pre_enc_me_ctxt_t * ps_curr_out,ihevce_lap_enc_buf_t * ps_curr_inp,WORD32 i4_tot_ctb_l1_x,WORD32 i4_tot_ctb_l1_y)6655 void calc_l1_level_hme_intra_sad_different_qp(
6656     enc_ctxt_t *ps_enc_ctxt,
6657     pre_enc_me_ctxt_t *ps_curr_out,
6658     ihevce_lap_enc_buf_t *ps_curr_inp,
6659     WORD32 i4_tot_ctb_l1_x,
6660     WORD32 i4_tot_ctb_l1_y)
6661 {
6662     ihevce_ed_ctb_l1_t *ps_ed_ctb_l1;
6663     WORD32 i4_qp_counter, i4_qp_start = 0, i4_qp_end = 0, i, i4_j, i4_new_frame_qp;
6664     LWORD64 i8_l1_intra_sad_nc_accounted = 0, cur_intra_sad, raw_hme_sad = 0;
6665     LWORD64 cur_hme_sad = 0, cur_hme_sad_for_offset = 0, acc_hme_l1_sad = 0,
6666             acc_hme_l1_sad_for_offset = 0;
6667     i4_qp_start = 1;
6668     i4_qp_end = 51;
6669 
6670     for(i4_qp_counter = i4_qp_start; i4_qp_counter <= i4_qp_end; i4_qp_counter = i4_qp_counter + 3)
6671     {
6672         i8_l1_intra_sad_nc_accounted = 0;
6673         cur_intra_sad = 0;
6674         raw_hme_sad = 0;
6675         cur_hme_sad = 0;
6676         cur_hme_sad_for_offset = 0;
6677         acc_hme_l1_sad = 0;
6678         ps_ed_ctb_l1 = ps_curr_out->ps_ed_ctb_l1;
6679         i4_new_frame_qp = i4_qp_counter;
6680         acc_hme_l1_sad = 0;
6681 
6682         for(i = 0; i < (i4_tot_ctb_l1_x * i4_tot_ctb_l1_y); i += 1)
6683         {
6684             for(i4_j = 0; i4_j < 16; i4_j++)
6685             {
6686                 if(ps_ed_ctb_l1->i4_best_sad_8x8_l1_ipe[i4_j] != -1)
6687                 {
6688                     ASSERT(ps_ed_ctb_l1->i4_best_sad_8x8_l1_ipe[i4_j] >= 0);
6689                     if(ps_curr_inp->s_rc_lap_out.i4_rc_pic_type != IV_I_FRAME &&
6690                        ps_curr_inp->s_rc_lap_out.i4_rc_pic_type != IV_IDR_FRAME)
6691                     {
6692                         /*When l1 is disabled for B pics i4_best_sad_8x8_l1_ipe is set to max value always,
6693                         so will enter this path even for incomplete ctb, hence the assert holdsto good only for P pic  */
6694                         if(ps_curr_inp->s_rc_lap_out.i4_rc_quality_preset == IHEVCE_QUALITY_P6)
6695                         {
6696                             if(ps_curr_inp->s_rc_lap_out.i4_rc_pic_type == IV_P_FRAME)
6697                             {
6698                                 ASSERT(ps_ed_ctb_l1->i4_best_sad_8x8_l1_me[i4_j] >= 0);
6699                                 ASSERT(ps_ed_ctb_l1->i4_best_sad_8x8_l1_me_for_decide[i4_j] >= 0);
6700                             }
6701                         }
6702                         else
6703                         {
6704                             ASSERT(ps_ed_ctb_l1->i4_best_sad_8x8_l1_me[i4_j] >= 0);
6705                             ASSERT(ps_ed_ctb_l1->i4_best_sad_8x8_l1_me_for_decide[i4_j] >= 0);
6706                         }
6707 
6708 #if 1  //DISABLE_L1_L2_IPE_INTRA_IN_BPICS && RC_DEPENDENCY_FOR_BPIC
6709                         if((ps_ed_ctb_l1->i4_best_sad_8x8_l1_me[i4_j] != -1))
6710 #endif
6711                         {
6712                             cur_hme_sad = ps_ed_ctb_l1->i4_best_sad_8x8_l1_me[i4_j] -
6713                                           (QP2QUANT_MD[i4_new_frame_qp] << 3);
6714                         }
6715                         raw_hme_sad += ps_ed_ctb_l1->i4_best_sad_8x8_l1_me[i4_j];
6716 
6717                         if(cur_hme_sad > 0)
6718                             acc_hme_l1_sad += cur_hme_sad;
6719                     }
6720                     if(cur_hme_sad_for_offset > 0)
6721                     {
6722                         acc_hme_l1_sad_for_offset += cur_hme_sad_for_offset;
6723                     }
6724                     ASSERT(ps_ed_ctb_l1->i4_best_sad_8x8_l1_ipe[i4_j] >= 0);
6725                     /*intra sad is scaled by 1.17 to be account for 1/3 vs 1/6th rounding*/
6726                     cur_intra_sad = (LWORD64)(
6727                         (ps_ed_ctb_l1->i4_best_sad_8x8_l1_ipe[i4_j] * 1.17) -
6728                         (QP2QUANT_MD[i4_new_frame_qp] << 3));
6729 
6730                     if(cur_intra_sad > 0)
6731                         i8_l1_intra_sad_nc_accounted += cur_intra_sad;
6732                 }
6733             }
6734             ps_ed_ctb_l1 += 1;
6735         }
6736         if((ps_curr_inp->s_rc_lap_out.i4_rc_quality_preset == IHEVCE_QUALITY_P6) &&
6737            (ps_curr_inp->s_rc_lap_out.i4_rc_pic_type == IV_B_FRAME))
6738         {
6739             ps_curr_inp->s_rc_lap_out.ai8_pre_intra_sad[i4_qp_counter] = -1;
6740             ps_curr_inp->s_rc_lap_out.ai8_pre_intra_sad[i4_qp_counter + 1] = -1;
6741             ps_curr_inp->s_rc_lap_out.ai8_pre_intra_sad[i4_qp_counter + 2] = -1;
6742         }
6743         else
6744         {
6745             ps_curr_inp->s_rc_lap_out.ai8_pre_intra_sad[i4_qp_counter] =
6746                 i8_l1_intra_sad_nc_accounted;
6747             ps_curr_inp->s_rc_lap_out.ai8_pre_intra_sad[i4_qp_counter + 1] =
6748                 i8_l1_intra_sad_nc_accounted;
6749             ps_curr_inp->s_rc_lap_out.ai8_pre_intra_sad[i4_qp_counter + 2] =
6750                 i8_l1_intra_sad_nc_accounted;
6751         }
6752         ps_curr_inp->s_rc_lap_out.ai8_frame_acc_coarse_me_sad[i4_qp_counter] = acc_hme_l1_sad;
6753         ps_curr_inp->s_rc_lap_out.ai8_frame_acc_coarse_me_sad[i4_qp_counter + 1] = acc_hme_l1_sad;
6754         ps_curr_inp->s_rc_lap_out.ai8_frame_acc_coarse_me_sad[i4_qp_counter + 2] = acc_hme_l1_sad;
6755         ps_curr_inp->s_rc_lap_out.i8_raw_l1_coarse_me_sad = raw_hme_sad;
6756     }
6757 }
6758