Home | History | Annotate | Download | only in encoder
      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 */
    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 */
    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 */
    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 */
    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 */
   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 */
   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 */
   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 */
   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 
   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 */
   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 */
   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 */
   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 */
   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 */
   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 */
   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 */
   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 
   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