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