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_ipe_pass.c
     24 *
     25 * \brief
     26 *    This file contains interface functions of Intra Prediction Estimation
     27 *    module
     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 
     52 /* User include files */
     53 #include "ihevc_typedefs.h"
     54 #include "itt_video_api.h"
     55 #include "ihevce_api.h"
     56 
     57 #include "rc_cntrl_param.h"
     58 #include "rc_frame_info_collector.h"
     59 #include "rc_look_ahead_params.h"
     60 
     61 #include "ihevc_debug.h"
     62 #include "ihevc_defs.h"
     63 #include "ihevc_structs.h"
     64 #include "ihevc_platform_macros.h"
     65 #include "ihevc_deblk.h"
     66 #include "ihevc_itrans_recon.h"
     67 #include "ihevc_chroma_itrans_recon.h"
     68 #include "ihevc_chroma_intra_pred.h"
     69 #include "ihevc_intra_pred.h"
     70 #include "ihevc_inter_pred.h"
     71 #include "ihevc_mem_fns.h"
     72 #include "ihevc_padding.h"
     73 #include "ihevc_weighted_pred.h"
     74 #include "ihevc_sao.h"
     75 #include "ihevc_resi_trans.h"
     76 #include "ihevc_quant_iquant_ssd.h"
     77 #include "ihevc_cabac_tables.h"
     78 #include "ihevc_quant_tables.h"
     79 
     80 #include "ihevce_defs.h"
     81 #include "ihevce_hle_interface.h"
     82 #include "ihevce_lap_enc_structs.h"
     83 #include "ihevce_multi_thrd_structs.h"
     84 #include "ihevce_multi_thrd_funcs.h"
     85 #include "ihevce_me_common_defs.h"
     86 #include "ihevce_had_satd.h"
     87 #include "ihevce_error_codes.h"
     88 #include "ihevce_bitstream.h"
     89 #include "ihevce_cabac.h"
     90 #include "ihevce_rdoq_macros.h"
     91 #include "ihevce_function_selector.h"
     92 #include "ihevce_enc_structs.h"
     93 #include "ihevce_entropy_structs.h"
     94 #include "ihevce_cmn_utils_instr_set_router.h"
     95 #include "ihevce_enc_loop_structs.h"
     96 #include "ihevce_inter_pred.h"
     97 #include "ihevc_weighted_pred.h"
     98 #include "ihevce_ipe_instr_set_router.h"
     99 #include "ihevce_ipe_structs.h"
    100 #include "ihevce_ipe_pass.h"
    101 #include "ihevce_decomp_pre_intra_structs.h"
    102 #include "ihevce_decomp_pre_intra_pass.h"
    103 #include "ihevce_recur_bracketing.h"
    104 #include "ihevce_nbr_avail.h"
    105 #include "ihevce_global_tables.h"
    106 #include "ihevc_resi_trans.h"
    107 
    108 #include "cast_types.h"
    109 #include "osal.h"
    110 #include "osal_defaults.h"
    111 
    112 /*****************************************************************************/
    113 /* Global Tables                                                             */
    114 /*****************************************************************************/
    115 
    116 /**
    117 ******************************************************************************
    118 * @brief  Look up table for choosing the appropriate function for
    119 *         Intra prediction
    120 *
    121 * @remarks Same look up table enums are used for luma & chroma but each
    122 *          have seperate functions implemented
    123 ******************************************************************************
    124 */
    125 WORD32 g_i4_ipe_funcs[MAX_NUM_IP_MODES] = {
    126     IPE_FUNC_MODE_0, /* Mode 0 */
    127     IPE_FUNC_MODE_1, /* Mode 1 */
    128     IPE_FUNC_MODE_2, /* Mode 2 */
    129     IPE_FUNC_MODE_3TO9, /* Mode 3 */
    130     IPE_FUNC_MODE_3TO9, /* Mode 4 */
    131     IPE_FUNC_MODE_3TO9, /* Mode 5 */
    132     IPE_FUNC_MODE_3TO9, /* Mode 6 */
    133     IPE_FUNC_MODE_3TO9, /* Mode 7 */
    134     IPE_FUNC_MODE_3TO9, /* Mode 8 */
    135     IPE_FUNC_MODE_3TO9, /* Mode 9 */
    136     IPE_FUNC_MODE_10, /* Mode 10 */
    137     IPE_FUNC_MODE_11TO17, /* Mode 11 */
    138     IPE_FUNC_MODE_11TO17, /* Mode 12 */
    139     IPE_FUNC_MODE_11TO17, /* Mode 13 */
    140     IPE_FUNC_MODE_11TO17, /* Mode 14 */
    141     IPE_FUNC_MODE_11TO17, /* Mode 15 */
    142     IPE_FUNC_MODE_11TO17, /* Mode 16 */
    143     IPE_FUNC_MODE_11TO17, /* Mode 17 */
    144     IPE_FUNC_MODE_18_34, /* Mode 18 */
    145     IPE_FUNC_MODE_19TO25, /* Mode 19 */
    146     IPE_FUNC_MODE_19TO25, /* Mode 20 */
    147     IPE_FUNC_MODE_19TO25, /* Mode 21 */
    148     IPE_FUNC_MODE_19TO25, /* Mode 22 */
    149     IPE_FUNC_MODE_19TO25, /* Mode 23 */
    150     IPE_FUNC_MODE_19TO25, /* Mode 24 */
    151     IPE_FUNC_MODE_19TO25, /* Mode 25 */
    152     IPE_FUNC_MODE_26, /* Mode 26 */
    153     IPE_FUNC_MODE_27TO33, /* Mode 27 */
    154     IPE_FUNC_MODE_27TO33, /* Mode 26 */
    155     IPE_FUNC_MODE_27TO33, /* Mode 29 */
    156     IPE_FUNC_MODE_27TO33, /* Mode 30 */
    157     IPE_FUNC_MODE_27TO33, /* Mode 31 */
    158     IPE_FUNC_MODE_27TO33, /* Mode 32 */
    159     IPE_FUNC_MODE_27TO33, /* Mode 33 */
    160     IPE_FUNC_MODE_18_34, /* Mode 34 */
    161 };
    162 
    163 /**
    164 ******************************************************************************
    165 * @brief  Look up table for deciding whether to use original samples or
    166 *         filtered reference samples for Intra prediction
    167 *
    168 * @remarks This table has the flags for transform size of 8, 16 and 32
    169 *          Input is log2nT - 3 and intra prediction mode
    170 ******************************************************************************
    171 */
    172 UWORD8 gau1_ipe_filter_flag[3][MAX_NUM_IP_MODES] = {
    173     { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    174       1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    175     { 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1,
    176       1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
    177     { 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
    178       1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 }
    179 };
    180 
    181 /*****************************************************************************/
    182 /* Function Definitions                                                      */
    183 /*****************************************************************************/
    184 
    185 /*!
    186 ******************************************************************************
    187 * \if Function name : ihevce_ipe_recompute_lambda_from_min_8x8_act_in_ctb \endif
    188 *
    189 * \brief
    190 *    This function recomputes lambda using min 8x8 act in CTB
    191 *
    192 * \author
    193 *    Ittiam
    194 *
    195 * \return
    196 *    Nothing
    197 *
    198 ******************************************************************************
    199 */
    200 void ihevce_ipe_recompute_lambda_from_min_8x8_act_in_ctb(
    201     ihevce_ipe_ctxt_t *ps_ctxt, ihevce_ed_ctb_l1_t *ps_ed_ctb_l1)
    202 {
    203     WORD32 i4_cu_qp = 0;
    204     WORD32 i4_mod_factor_num;
    205 #if MODULATE_LAMDA_WHEN_SPATIAL_MOD_ON
    206     WORD32 i4_activity;
    207 #endif
    208     WORD32 i4_qscale;
    209     WORD32 i4_curr_satd;
    210     long double ld_avg_satd;
    211 
    212 #if MODULATE_LAMDA_WHEN_SPATIAL_MOD_ON
    213     WORD32 i4_mod_factor_denom = QP_MOD_FACTOR_DEN;
    214 #endif
    215 
    216     if(ISLICE == ps_ctxt->i4_slice_type)
    217     {
    218         i4_mod_factor_num = INTRA_QP_MOD_FACTOR_NUM;
    219     }
    220     else
    221     {
    222         i4_mod_factor_num = INTER_QP_MOD_FACTOR_NUM;
    223     }
    224 
    225 #if LAMDA_BASED_ON_QUANT
    226     i4_curr_satd = ps_ed_ctb_l1->i4_32x32_satd[0][2];
    227     i8_avg_satd = ps_ctxt->i8_curr_frame_32x32_avg_act[2];
    228 #else
    229     i4_curr_satd = ps_ed_ctb_l1->i4_32x32_satd[0][3];
    230 
    231     ld_avg_satd = 2.0 + ps_ctxt->ld_curr_frame_16x16_log_avg[0];
    232 
    233 #endif
    234     if(ps_ctxt->i4_l0ipe_qp_mod)
    235     {
    236 #if MODULATE_LAMDA_WHEN_SPATIAL_MOD_ON
    237         i4_cu_qp = ihevce_cu_level_qp_mod(
    238             ps_ctxt->i4_qscale,
    239             i4_curr_satd,
    240             ld_avg_satd,
    241             ps_ctxt->f_strength,
    242             &i4_activity,
    243             &i4_qscale,
    244             ps_ctxt->ps_rc_quant_ctxt);
    245 #endif
    246     }
    247     ihevce_get_ipe_ol_cu_lambda_prms(ps_ctxt, i4_cu_qp);
    248 }
    249 /*!
    250 ******************************************************************************
    251 * \if Function name : ihevce_ipe_pass_satd \endif
    252 *
    253 * \brief
    254 *    This function calcuates the SATD for a given size and returns the value
    255 *
    256 * \date
    257 *    18/09/2012
    258 *
    259 * \author
    260 *    Ittiam
    261 *
    262 * \return
    263 *
    264 * List of Functions
    265 *
    266 ******************************************************************************
    267 */
    268 UWORD32 ihevce_ipe_pass_satd(WORD16 *pi2_coeff, WORD32 coeff_stride, WORD32 trans_size)
    269 {
    270     WORD32 i, j, satd;
    271 
    272     satd = 0;
    273 
    274     /* run a loop and find the satd by doing ABS */
    275     for(i = 0; i < trans_size; i++)
    276     {
    277         for(j = 0; j < trans_size; j++)
    278         {
    279             satd += abs(*pi2_coeff++);
    280         }
    281         /* row level update */
    282         pi2_coeff += coeff_stride - trans_size;
    283     }
    284 
    285     {
    286         WORD32 transform_shift;
    287         WORD32 log2_trans_size;
    288 
    289         GETRANGE(log2_trans_size, trans_size);
    290         log2_trans_size -= 1;
    291         transform_shift = MAX_TR_DYNAMIC_RANGE - BIT_DEPTH - log2_trans_size;
    292         satd >>= transform_shift;
    293     }
    294 
    295     return (satd);
    296 }
    297 
    298 /*!
    299 ******************************************************************************
    300 * \if Function name : ihevce_ipe_get_num_mem_recs \endif
    301 *
    302 * \brief
    303 *    Number of memory records are returned for IPE module
    304 *
    305 *
    306 * \return
    307 *    None
    308 *
    309 * \author
    310 *  Ittiam
    311 *
    312 *****************************************************************************
    313 */
    314 WORD32 ihevce_ipe_get_num_mem_recs(void)
    315 {
    316     return (NUM_IPE_MEM_RECS);
    317 }
    318 
    319 /*!
    320 ******************************************************************************
    321 * \if Function name : ihevce_ipe_get_mem_recs \endif
    322 *
    323 * \brief
    324 *    Memory requirements are returned for IPE.
    325 *
    326 * \param[in,out]  ps_mem_tab : pointer to memory descriptors table
    327 * \param[in] ps_init_prms : Create time static parameters
    328 * \param[in] i4_num_proc_thrds : Number of processing threads for this module
    329 * \param[in] i4_mem_space : memspace in whihc memory request should be done
    330 *
    331 * \return
    332 *    None
    333 *
    334 * \author
    335 *  Ittiam
    336 *
    337 *****************************************************************************
    338 */
    339 WORD32
    340     ihevce_ipe_get_mem_recs(iv_mem_rec_t *ps_mem_tab, WORD32 i4_num_proc_thrds, WORD32 i4_mem_space)
    341 {
    342     /* memories should be requested assuming worst case requirememnts */
    343 
    344     /* Module context structure */
    345     ps_mem_tab[IPE_CTXT].i4_mem_size = sizeof(ihevce_ipe_master_ctxt_t);
    346 
    347     ps_mem_tab[IPE_CTXT].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
    348 
    349     ps_mem_tab[IPE_CTXT].i4_mem_alignment = 8;
    350 
    351     /* Threads ctxt structure */
    352     ps_mem_tab[IPE_THRDS_CTXT].i4_mem_size = i4_num_proc_thrds * sizeof(ihevce_ipe_ctxt_t);
    353 
    354     ps_mem_tab[IPE_THRDS_CTXT].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
    355 
    356     ps_mem_tab[IPE_THRDS_CTXT].i4_mem_alignment = 32;
    357 
    358     return (NUM_IPE_MEM_RECS);
    359 }
    360 
    361 /*!
    362 ******************************************************************************
    363 * \if Function name : ihevce_ipe_init \endif
    364 *
    365 * \brief
    366 *    Intialization for IPE context state structure .
    367 *
    368 * \param[in] ps_mem_tab : pointer to memory descriptors table
    369 * \param[in] ps_init_prms : Create time static parameters
    370 *
    371 * \return
    372 *    None
    373 *
    374 * \author
    375 *  Ittiam
    376 *
    377 *****************************************************************************
    378 */
    379 void *ihevce_ipe_init(
    380     iv_mem_rec_t *ps_mem_tab,
    381     ihevce_static_cfg_params_t *ps_init_prms,
    382     WORD32 i4_num_proc_thrds,
    383     WORD32 i4_ref_id,
    384     func_selector_t *ps_func_selector,
    385     rc_quant_t *ps_rc_quant_ctxt,
    386     WORD32 i4_resolution_id,
    387     UWORD8 u1_is_popcnt_available)
    388 {
    389     WORD32 i4_thrds;
    390     UWORD32 u4_width, u4_ctb_in_a_row;
    391     //  WORD32 i4_ctr;
    392     ihevce_ipe_master_ctxt_t *ps_master_ctxt;
    393     ihevce_ipe_ctxt_t *ps_ctxt;
    394 
    395     /* IPE master state structure */
    396     ps_master_ctxt = (ihevce_ipe_master_ctxt_t *)ps_mem_tab[IPE_CTXT].pv_base;
    397 
    398     ps_master_ctxt->i4_num_proc_thrds = i4_num_proc_thrds;
    399 
    400     ps_ctxt = (ihevce_ipe_ctxt_t *)ps_mem_tab[IPE_THRDS_CTXT].pv_base;
    401 
    402     ps_ctxt->ps_rc_quant_ctxt = ps_rc_quant_ctxt;
    403 
    404     /*width of the input YUV to be encoded. */
    405     u4_width = ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_width;
    406     /*making the width a multiple of CTB size*/
    407     u4_width += SET_CTB_ALIGN(
    408         ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_width, MAX_CTB_SIZE);
    409 
    410     u4_ctb_in_a_row = (u4_width / MAX_CTB_SIZE);
    411 
    412     /* perform all one initialisation here */
    413     for(i4_thrds = 0; i4_thrds < ps_master_ctxt->i4_num_proc_thrds; i4_thrds++)
    414     {
    415         ps_master_ctxt->aps_ipe_thrd_ctxt[i4_thrds] = ps_ctxt;
    416 
    417         /* initialise the CU and TU sizes */
    418         ps_ctxt->u1_ctb_size = (1 << ps_init_prms->s_config_prms.i4_max_log2_cu_size);
    419         ps_ctxt->u1_min_cu_size = (1 << ps_init_prms->s_config_prms.i4_min_log2_cu_size);
    420         ps_ctxt->u1_min_tu_size = (1 << ps_init_prms->s_config_prms.i4_min_log2_tu_size);
    421 
    422         /** Register the function selector pointer*/
    423         ps_ctxt->ps_func_selector = ps_func_selector;
    424 
    425         /* Initiailize the encoder quality preset           */
    426         /* IPE algorithm is controlled based on this preset */
    427         ps_ctxt->i4_quality_preset =
    428             ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_quality_preset;
    429 
    430         if(ps_ctxt->i4_quality_preset == IHEVCE_QUALITY_P7)
    431         {
    432             ps_ctxt->i4_quality_preset = IHEVCE_QUALITY_P6;
    433         }
    434 
    435         /* initialise all the pointer to start of arrays */
    436         ps_ctxt->ps_ipe_cu_tree = &ps_ctxt->as_ipe_cu_tree[0];
    437 
    438         /* initialize QP */
    439         ps_ctxt->i1_QP =
    440             ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].ai4_frame_qp[i4_ref_id];
    441         ps_ctxt->u1_num_b_frames =
    442             (1 << ps_init_prms->s_coding_tools_prms.i4_max_temporal_layers) - 1;
    443 
    444         ps_ctxt->b_sad_type = IPE_SAD_TYPE;
    445         ps_ctxt->u1_ipe_step_size = IPE_STEP_SIZE;
    446 
    447         ps_ctxt->apf_ipe_lum_ip[IPE_FUNC_MODE_0] =
    448             ps_ctxt->ps_func_selector->ihevc_intra_pred_luma_planar_fptr;
    449         ps_ctxt->apf_ipe_lum_ip[IPE_FUNC_MODE_1] =
    450             ps_ctxt->ps_func_selector->ihevc_intra_pred_luma_dc_fptr;
    451         ps_ctxt->apf_ipe_lum_ip[IPE_FUNC_MODE_2] =
    452             ps_ctxt->ps_func_selector->ihevc_intra_pred_luma_mode2_fptr;
    453         ps_ctxt->apf_ipe_lum_ip[IPE_FUNC_MODE_3TO9] =
    454             ps_ctxt->ps_func_selector->ihevc_intra_pred_luma_mode_3_to_9_fptr;
    455         ps_ctxt->apf_ipe_lum_ip[IPE_FUNC_MODE_10] =
    456             ps_ctxt->ps_func_selector->ihevc_intra_pred_luma_horz_fptr;
    457         ps_ctxt->apf_ipe_lum_ip[IPE_FUNC_MODE_11TO17] =
    458             ps_ctxt->ps_func_selector->ihevc_intra_pred_luma_mode_11_to_17_fptr;
    459         ps_ctxt->apf_ipe_lum_ip[IPE_FUNC_MODE_18_34] =
    460             ps_ctxt->ps_func_selector->ihevc_intra_pred_luma_mode_18_34_fptr;
    461         ps_ctxt->apf_ipe_lum_ip[IPE_FUNC_MODE_19TO25] =
    462             ps_ctxt->ps_func_selector->ihevc_intra_pred_luma_mode_19_to_25_fptr;
    463         ps_ctxt->apf_ipe_lum_ip[IPE_FUNC_MODE_26] =
    464             ps_ctxt->ps_func_selector->ihevc_intra_pred_luma_ver_fptr;
    465         ps_ctxt->apf_ipe_lum_ip[IPE_FUNC_MODE_27TO33] =
    466             ps_ctxt->ps_func_selector->ihevc_intra_pred_luma_mode_27_to_33_fptr;
    467 
    468         /* nbr parameters initialization */
    469         /* perform all one initialisation here */
    470 
    471         ps_ctxt->i4_nbr_map_strd = MAX_PU_IN_CTB_ROW + 1 + 8;
    472 
    473         ps_ctxt->pu1_ctb_nbr_map = ps_ctxt->au1_nbr_ctb_map[0];
    474 
    475         /* move the pointer to 1,2 location */
    476         ps_ctxt->pu1_ctb_nbr_map += ps_ctxt->i4_nbr_map_strd;
    477         ps_ctxt->pu1_ctb_nbr_map++;
    478         ps_ctxt->i4_l0ipe_qp_mod = ps_init_prms->s_config_prms.i4_cu_level_rc & 1;
    479         ps_ctxt->i4_pass = ps_init_prms->s_pass_prms.i4_pass;
    480         if(ps_init_prms->s_coding_tools_prms.i4_use_default_sc_mtx == 0)
    481         {
    482             /* initialise the scale & rescale matricies */
    483             ps_ctxt->api2_scal_mat[0] = (WORD16 *)&gi2_flat_scale_mat_4x4[0];
    484             ps_ctxt->api2_scal_mat[1] = (WORD16 *)&gi2_flat_scale_mat_4x4[0];
    485             ps_ctxt->api2_scal_mat[2] = (WORD16 *)&gi2_flat_scale_mat_8x8[0];
    486             ps_ctxt->api2_scal_mat[3] = (WORD16 *)&gi2_flat_scale_mat_16x16[0];
    487             ps_ctxt->api2_scal_mat[4] = (WORD16 *)&gi2_flat_scale_mat_32x32[0];
    488             /*init for inter matrix*/
    489             ps_ctxt->api2_scal_mat[5] = (WORD16 *)&gi2_flat_scale_mat_4x4[0];
    490             ps_ctxt->api2_scal_mat[6] = (WORD16 *)&gi2_flat_scale_mat_4x4[0];
    491             ps_ctxt->api2_scal_mat[7] = (WORD16 *)&gi2_flat_scale_mat_8x8[0];
    492             ps_ctxt->api2_scal_mat[8] = (WORD16 *)&gi2_flat_scale_mat_16x16[0];
    493             ps_ctxt->api2_scal_mat[9] = (WORD16 *)&gi2_flat_scale_mat_32x32[0];
    494 
    495             /*init for rescale matrix*/
    496             ps_ctxt->api2_rescal_mat[0] = (WORD16 *)&gi2_flat_rescale_mat_4x4[0];
    497             ps_ctxt->api2_rescal_mat[1] = (WORD16 *)&gi2_flat_rescale_mat_4x4[0];
    498             ps_ctxt->api2_rescal_mat[2] = (WORD16 *)&gi2_flat_rescale_mat_8x8[0];
    499             ps_ctxt->api2_rescal_mat[3] = (WORD16 *)&gi2_flat_rescale_mat_16x16[0];
    500             ps_ctxt->api2_rescal_mat[4] = (WORD16 *)&gi2_flat_rescale_mat_32x32[0];
    501             /*init for rescale inter matrix*/
    502             ps_ctxt->api2_rescal_mat[5] = (WORD16 *)&gi2_flat_rescale_mat_4x4[0];
    503             ps_ctxt->api2_rescal_mat[6] = (WORD16 *)&gi2_flat_rescale_mat_4x4[0];
    504             ps_ctxt->api2_rescal_mat[7] = (WORD16 *)&gi2_flat_rescale_mat_8x8[0];
    505             ps_ctxt->api2_rescal_mat[8] = (WORD16 *)&gi2_flat_rescale_mat_16x16[0];
    506             ps_ctxt->api2_rescal_mat[9] = (WORD16 *)&gi2_flat_rescale_mat_32x32[0];
    507         }
    508         else if(ps_init_prms->s_coding_tools_prms.i4_use_default_sc_mtx == 1)
    509         {
    510             /* initialise the scale & rescale matricies */
    511             ps_ctxt->api2_scal_mat[0] = (WORD16 *)&gi2_flat_scale_mat_4x4[0];
    512             ps_ctxt->api2_scal_mat[1] = (WORD16 *)&gi2_flat_scale_mat_4x4[0];
    513             ps_ctxt->api2_scal_mat[2] = (WORD16 *)&gi2_intra_default_scale_mat_8x8[0];
    514             ps_ctxt->api2_scal_mat[3] = (WORD16 *)&gi2_intra_default_scale_mat_16x16[0];
    515             ps_ctxt->api2_scal_mat[4] = (WORD16 *)&gi2_intra_default_scale_mat_32x32[0];
    516             /*init for inter matrix*/
    517             ps_ctxt->api2_scal_mat[5] = (WORD16 *)&gi2_flat_scale_mat_4x4[0];
    518             ps_ctxt->api2_scal_mat[6] = (WORD16 *)&gi2_flat_scale_mat_4x4[0];
    519             ps_ctxt->api2_scal_mat[7] = (WORD16 *)&gi2_inter_default_scale_mat_8x8[0];
    520             ps_ctxt->api2_scal_mat[8] = (WORD16 *)&gi2_inter_default_scale_mat_16x16[0];
    521             ps_ctxt->api2_scal_mat[9] = (WORD16 *)&gi2_inter_default_scale_mat_32x32[0];
    522 
    523             /*init for rescale matrix*/
    524             ps_ctxt->api2_rescal_mat[0] = (WORD16 *)&gi2_flat_rescale_mat_4x4[0];
    525             ps_ctxt->api2_rescal_mat[1] = (WORD16 *)&gi2_flat_rescale_mat_4x4[0];
    526             ps_ctxt->api2_rescal_mat[2] = (WORD16 *)&gi2_intra_default_rescale_mat_8x8[0];
    527             ps_ctxt->api2_rescal_mat[3] = (WORD16 *)&gi2_intra_default_rescale_mat_16x16[0];
    528             ps_ctxt->api2_rescal_mat[4] = (WORD16 *)&gi2_intra_default_rescale_mat_32x32[0];
    529             /*init for rescale inter matrix*/
    530             ps_ctxt->api2_rescal_mat[5] = (WORD16 *)&gi2_flat_rescale_mat_4x4[0];
    531             ps_ctxt->api2_rescal_mat[6] = (WORD16 *)&gi2_flat_rescale_mat_4x4[0];
    532             ps_ctxt->api2_rescal_mat[7] = (WORD16 *)&gi2_inter_default_rescale_mat_8x8[0];
    533             ps_ctxt->api2_rescal_mat[8] = (WORD16 *)&gi2_inter_default_rescale_mat_16x16[0];
    534             ps_ctxt->api2_rescal_mat[9] = (WORD16 *)&gi2_inter_default_rescale_mat_32x32[0];
    535         }
    536         else
    537         {
    538             ASSERT(0);
    539         }
    540 
    541         ps_ctxt->u1_bit_depth = ps_init_prms->s_tgt_lyr_prms.i4_internal_bit_depth;
    542 
    543         /**
    544         * Initialize the intra prediction modes map for the CTB to INTRA_DC
    545         **/
    546         {
    547             WORD32 row, col;
    548             for(row = 0; row < (MAX_TU_ROW_IN_CTB + 1); row++)
    549                 for(col = 0; col < (MAX_TU_COL_IN_CTB + 1); col++)
    550                     ps_ctxt->au1_ctb_mode_map[row][col] = INTRA_DC;
    551         }
    552 
    553         ihevce_cmn_utils_instr_set_router(
    554             &ps_ctxt->s_cmn_opt_func, u1_is_popcnt_available, ps_init_prms->e_arch_type);
    555 
    556         ihevce_ipe_instr_set_router(
    557             &ps_ctxt->s_ipe_optimised_function_list, ps_init_prms->e_arch_type);
    558 
    559         /* increment the thread ctxt pointer */
    560         ps_ctxt++;
    561     }
    562 
    563     /* return the handle to caller */
    564     return ((void *)ps_master_ctxt);
    565 }
    566 /*!
    567 ******************************************************************************
    568 * \if Function name : ihevce_ipe_get_frame_intra_satd_cost \endif
    569 *
    570 * \brief
    571 *    Function to export frame-level accumalated SATD .
    572 *
    573 * \param[in] pv_ctxt : pointer to IPE module
    574 *
    575 * \return
    576 *    None
    577 *
    578 * \author
    579 *  Ittiam
    580 *
    581 *****************************************************************************
    582 */
    583 LWORD64 ihevce_ipe_get_frame_intra_satd_cost(
    584     void *pv_ctxt,
    585     LWORD64 *pi8_frame_satd_by_qpmod,
    586     LWORD64 *pi8_frame_acc_mode_bits_cost,
    587     LWORD64 *pi8_frame_acc_activity_factor,
    588     LWORD64 *pi8_frame_l0_acc_satd)
    589 {
    590     WORD32 i4_thrds;
    591 
    592     ihevce_ipe_master_ctxt_t *ps_master_ctxt;
    593     ihevce_ipe_ctxt_t *ps_ctxt;
    594     LWORD64 i8_frame_acc_satd_cost = 0;
    595     LWORD64 i8_frame_acc_satd = 0;
    596     LWORD64 i8_frame_satd_by_qpmod = 0;
    597     LWORD64 i8_frame_acc_mode_bits_cost = 0;
    598     LWORD64 i8_frame_acc_activity_factor = 0;
    599     /* IPE master state structure */
    600     ps_master_ctxt = (ihevce_ipe_master_ctxt_t *)pv_ctxt;
    601 
    602     /* perform all one initialisation here */
    603     for(i4_thrds = 0; i4_thrds < ps_master_ctxt->i4_num_proc_thrds; i4_thrds++)
    604     {
    605         ps_ctxt = ps_master_ctxt->aps_ipe_thrd_ctxt[i4_thrds];
    606 
    607         i8_frame_acc_satd_cost += ps_ctxt->i8_frame_acc_satd_cost;
    608         i8_frame_satd_by_qpmod += (ps_ctxt->i8_frame_acc_satd_by_modqp_q10 >> SATD_BY_ACT_Q_FAC);
    609         i8_frame_acc_mode_bits_cost += ps_ctxt->i8_frame_acc_mode_bits_cost;
    610 
    611         i8_frame_acc_activity_factor += ps_ctxt->i8_frame_acc_act_factor;
    612 
    613         i8_frame_acc_satd += ps_ctxt->i8_frame_acc_satd;
    614     }
    615     *pi8_frame_satd_by_qpmod = i8_frame_satd_by_qpmod;
    616 
    617     *pi8_frame_acc_mode_bits_cost = i8_frame_acc_mode_bits_cost;
    618 
    619     *pi8_frame_acc_activity_factor = i8_frame_acc_activity_factor;
    620 
    621     *pi8_frame_l0_acc_satd = i8_frame_acc_satd;
    622 
    623     return (i8_frame_acc_satd_cost);
    624 }
    625 
    626 /**
    627 *******************************************************************************
    628 * \if Function name : ihevce_intra_pred_ref_filtering \endif
    629 *
    630 * \brief
    631 *    Intra prediction interpolation filter for ref_filtering for Encoder
    632 *
    633 * \par Description:
    634 *    Reference DC filtering for neighboring samples dependent  on TU size and
    635 *    mode  Refer to section 8.4.4.2.3 in the standard
    636 *
    637 * \param[in] pu1_src pointer to the source
    638 * \param[out] pu1_dst pointer to the destination
    639 * \param[in] nt integer Transform Block size
    640 *
    641 * \returns
    642 *  none
    643 *
    644 * \author
    645 *  Ittiam
    646 *
    647 *******************************************************************************
    648 */
    649 
    650 #if IHEVCE_INTRA_REF_FILTERING == C
    651 void ihevce_intra_pred_ref_filtering(UWORD8 *pu1_src, WORD32 nt, UWORD8 *pu1_dst)
    652 {
    653     WORD32 i; /* Generic indexing variable */
    654     WORD32 four_nt = 4 * nt;
    655 
    656     /* Extremities Untouched*/
    657     pu1_dst[0] = pu1_src[0];
    658     pu1_dst[4 * nt] = pu1_src[4 * nt];
    659     /* Perform bilinear filtering of Reference Samples */
    660     for(i = 0; i < (four_nt - 1); i++)
    661     {
    662         pu1_dst[i + 1] = (pu1_src[i] + 2 * pu1_src[i + 1] + pu1_src[i + 2] + 2) >> 2;
    663     }
    664 }
    665 #endif
    666 
    667 /*!
    668 ******************************************************************************
    669 * \if Function name : ihevce_ipe_process_ctb \endif
    670 *
    671 * \brief
    672 *    CTB level IPE function
    673 *
    674 * \param[in] pv_ctxt : pointer to IPE module
    675 * \param[in] ps_frm_ctb_prms : CTB characteristics parameters
    676 * \param[in] ps_curr_src  : pointer to input yuv buffer (row buffer)
    677 * \param[out] ps_ctb_out : pointer to CTB analyse output structure (row buffer)
    678 * \param[out] ps_row_cu : pointer to CU analyse output structure (row buffer)
    679 *
    680 * \return
    681 *    None
    682 *
    683 * Note : This function will receive CTB pointers which may point to
    684 * blocks of CTB size or smaller (at the right and bottom edges of the picture)
    685 * This function recursively creates smaller square partitions and passes them
    686 * on for intra processing estimation
    687 *
    688 * \author
    689 *  Ittiam
    690 *
    691 *****************************************************************************
    692 */
    693 void ihevce_ipe_process_ctb(
    694     ihevce_ipe_ctxt_t *ps_ctxt,
    695     frm_ctb_ctxt_t *ps_frm_ctb_prms,
    696     iv_enc_yuv_buf_t *ps_curr_src,
    697     ihevce_ipe_cu_tree_t *ps_curr_ctb_node,
    698     ipe_l0_ctb_analyse_for_me_t *ps_l0_ipe_out_ctb,
    699     ctb_analyse_t *ps_ctb_out,
    700     //cu_analyse_t      *ps_row_cu,
    701     ihevce_ed_blk_t *ps_ed_l1_ctb,
    702     ihevce_ed_blk_t *ps_ed_l2_ctb,
    703     ihevce_ed_ctb_l1_t *ps_ed_ctb_l1)
    704 {
    705     /* reset the map buffer to 0*/
    706     memset(
    707         &ps_ctxt->au1_nbr_ctb_map[0][0],
    708         0,
    709         (MAX_PU_IN_CTB_ROW + 1 + 8) * (MAX_PU_IN_CTB_ROW + 1 + 8));
    710 
    711     /* set the CTB neighbour availability flags */
    712     ihevce_set_ctb_nbr(
    713         &ps_ctxt->s_ctb_nbr_avail_flags,
    714         ps_ctxt->pu1_ctb_nbr_map,
    715         ps_ctxt->i4_nbr_map_strd,
    716         ps_ctxt->u2_ctb_num_in_row,
    717         ps_ctxt->u2_ctb_row_num,
    718         ps_frm_ctb_prms);
    719 
    720     /* IPE cu and mode decision */
    721     ihevce_bracketing_analysis(
    722         ps_ctxt,
    723         ps_curr_ctb_node,
    724         ps_curr_src,
    725         ps_ctb_out,
    726         //ps_row_cu,
    727         ps_ed_l1_ctb,
    728         ps_ed_l2_ctb,
    729         ps_ed_ctb_l1,
    730         ps_l0_ipe_out_ctb);
    731 
    732     return;
    733 }
    734 
    735 /*!
    736 ******************************************************************************
    737 * \if Function name : ihevce_ipe_process_row \endif
    738 *
    739 * \brief
    740 *    Row level IPE function
    741 *
    742 * \param[in] pv_ctxt : pointer to IPE module
    743 * \param[in] ps_frm_ctb_prms : CTB characteristics parameters
    744 * \param[in] ps_curr_src  : pointer to input yuv buffer (row buffer)
    745 * \param[out] ps_ctb_out : pointer to CTB analyse output structure (row buffer)
    746 * \param[out] ps_cu_out : pointer to CU analyse output structure (row buffer)
    747 *\param[out]  pi4_num_ctbs_cur_row  : pointer to store the number of ctbs processed in current row
    748 *\param[in]  pi4_num_ctbs_top_row  : pointer to check the number of ctbs processed in top row
    749 *
    750 * \return
    751 *    None
    752 *
    753 * Note : Currently the frame level calculations done assumes that
    754 *        framewidth of the input are excat multiple of ctbsize
    755 *
    756 * \author
    757 *  Ittiam
    758 *
    759 *****************************************************************************
    760 */
    761 void ihevce_ipe_process_row(
    762     ihevce_ipe_ctxt_t *ps_ctxt,
    763     frm_ctb_ctxt_t *ps_frm_ctb_prms,
    764     iv_enc_yuv_buf_t *ps_curr_src,
    765     ipe_l0_ctb_analyse_for_me_t *ps_ipe_ctb_out_row,
    766     ctb_analyse_t *ps_ctb_out,
    767     //cu_analyse_t   *ps_row_cu,
    768     ihevce_ed_blk_t *ps_ed_l1_row,
    769     ihevce_ed_blk_t *ps_ed_l2_row,
    770     ihevce_ed_ctb_l1_t *ps_ed_ctb_l1_row,
    771     WORD32 blk_inc_ctb_l1,
    772     WORD32 blk_inc_ctb_l2)
    773 {
    774     /* local variables */
    775     UWORD16 ctb_ctr;
    776     iv_enc_yuv_buf_t s_curr_src_bufs;
    777     ipe_l0_ctb_analyse_for_me_t *ps_l0_ipe_out_ctb;
    778     UWORD16 u2_pic_wdt;
    779     UWORD16 u2_pic_hgt;
    780     ihevce_ed_blk_t *ps_ed_l1_ctb;
    781     ihevce_ed_blk_t *ps_ed_l2_ctb;
    782     ihevce_ed_ctb_l1_t *ps_ed_ctb_l1;
    783 
    784     UWORD8 u1_ctb_size;
    785 
    786     u2_pic_wdt = ps_frm_ctb_prms->i4_cu_aligned_pic_wd;
    787     u2_pic_hgt = ps_frm_ctb_prms->i4_cu_aligned_pic_ht;
    788 
    789     u1_ctb_size = ps_ctxt->u1_ctb_size;
    790 
    791     /* ----------------------------------------------------- */
    792     /* store the stride and dimensions of source             */
    793     /* buffer pointers will be over written at every CTB row */
    794     /* ----------------------------------------------------- */
    795     memcpy(&s_curr_src_bufs, ps_curr_src, sizeof(iv_enc_yuv_buf_t));
    796     ps_l0_ipe_out_ctb = ps_ipe_ctb_out_row;
    797 
    798     /* --------- Loop over all the CTBs in a row --------------- */
    799     for(ctb_ctr = 0; ctb_ctr < ps_frm_ctb_prms->i4_num_ctbs_horz; ctb_ctr++)
    800     {
    801         //UWORD8            num_cus_in_ctb;
    802 
    803         UWORD8 *pu1_tmp;
    804 
    805         /* Create pointer to ctb node */
    806         ihevce_ipe_cu_tree_t *ps_ctb_node;
    807 
    808         WORD32 nbr_flags;
    809 
    810         WORD32 row;
    811         /* luma src */
    812         pu1_tmp = (UWORD8 *)ps_curr_src->pv_y_buf;
    813         pu1_tmp += (ctb_ctr * ps_frm_ctb_prms->i4_ctb_size);
    814 
    815         s_curr_src_bufs.pv_y_buf = pu1_tmp;
    816 
    817         /* Cb & CR pixel interleaved src */
    818         pu1_tmp = (UWORD8 *)ps_curr_src->pv_u_buf;
    819         pu1_tmp += (ctb_ctr * (ps_frm_ctb_prms->i4_ctb_size >> 1));
    820 
    821         s_curr_src_bufs.pv_u_buf = pu1_tmp;
    822 
    823         /* Store the number of current ctb within row in the context */
    824         ps_ctxt->u2_ctb_num_in_row = ctb_ctr;
    825 
    826         /* Initialize number of coding units in ctb to 0 */
    827         ps_ctb_out->u1_num_cus_in_ctb = 0;
    828         /* Initialize split flag to 0 - No partition  */
    829         ps_ctb_out->u4_cu_split_flags = 0;
    830         /* store the cu pointer for current ctb out */
    831         //ps_ctb_out->ps_coding_units_in_ctb = ps_row_cu;
    832 
    833         /* Initialize the CTB parameters at the root node level */
    834         ps_ctb_node = ps_ctxt->ps_ipe_cu_tree;
    835         ps_ctb_node->ps_parent = NULL;
    836         ps_ctb_node->u1_depth = 0;
    837         ps_ctb_node->u1_cu_size = u1_ctb_size;
    838         ps_ctb_node->u2_x0 = 0;
    839         ps_ctb_node->u2_y0 = 0;
    840 
    841         ps_ctb_node->u2_orig_x = ctb_ctr * ps_ctb_node->u1_cu_size;
    842         ps_ctb_node->u2_orig_y = ps_ctxt->u2_ctb_row_num * ps_ctb_node->u1_cu_size;
    843 
    844         ps_ctb_node->u1_width = u1_ctb_size;
    845         ps_ctb_node->u1_height = u1_ctb_size;
    846 #if !(PIC_ALIGN_CTB_SIZE)
    847         if(ps_ctxt->u2_ctb_num_in_row == (ps_frm_ctb_prms->i4_num_ctbs_horz - 1))
    848         {
    849             ps_ctb_node->u1_width = u2_pic_wdt - (ps_ctxt->u2_ctb_num_in_row) * (u1_ctb_size);
    850         }
    851         if(ps_ctxt->u2_ctb_row_num == (ps_frm_ctb_prms->i4_num_ctbs_vert - 1))
    852         {
    853             ps_ctb_node->u1_height = u2_pic_hgt - (ps_ctxt->u2_ctb_row_num) * (u1_ctb_size);
    854         }
    855 #endif
    856 
    857         switch(ps_ctb_node->u1_cu_size)
    858         {
    859         case 64:
    860             ps_ctb_node->u1_log2_nt = 6;
    861             ps_ctb_node->u1_part_flag_pos = 0;
    862             break;
    863         case 32:
    864             ps_ctb_node->u1_log2_nt = 5;
    865             ps_ctb_node->u1_part_flag_pos = 4;
    866             break;
    867         case 16:
    868             ps_ctb_node->u1_log2_nt = 4;
    869             ps_ctb_node->u1_part_flag_pos = 8;
    870             break;
    871         }
    872 
    873         /* Set neighbor flags for the CTB */
    874         nbr_flags = 0;
    875 
    876         if(ps_ctxt->u2_ctb_num_in_row != 0)
    877         {
    878             nbr_flags |= LEFT_FLAG; /* Set Left Flag if not in first column */
    879             ps_ctb_node->u1_num_left_avail = ((u2_pic_hgt - ps_ctb_node->u2_orig_y) >= u1_ctb_size)
    880                                                  ? u1_ctb_size
    881                                                  : u2_pic_hgt - ps_ctb_node->u2_orig_y;
    882         }
    883         else
    884         {
    885             ps_ctb_node->u1_num_left_avail = 0;
    886         }
    887 
    888         if((ps_ctxt->u2_ctb_num_in_row != 0) && (ps_ctxt->u2_ctb_row_num != 0))
    889             nbr_flags |= TOP_LEFT_FLAG; /* Set Top-Left Flag if not in first row or first column */
    890 
    891         if(ps_ctxt->u2_ctb_row_num != 0)
    892         {
    893             nbr_flags |= TOP_FLAG; /* Set Top Flag if not in first row */
    894             ps_ctb_node->u1_num_top_avail = ((u2_pic_wdt - ps_ctb_node->u2_orig_x) >= u1_ctb_size)
    895                                                 ? u1_ctb_size
    896                                                 : u2_pic_wdt - ps_ctb_node->u2_orig_x;
    897         }
    898         else
    899         {
    900             ps_ctb_node->u1_num_top_avail = 0;
    901         }
    902 
    903         if(ps_ctxt->u2_ctb_row_num != 0)
    904         {
    905             if(ps_ctxt->u2_ctb_num_in_row == (ps_frm_ctb_prms->i4_num_ctbs_horz - 1))
    906                 ps_ctb_node->u1_num_top_right_avail = 0;
    907             else
    908             {
    909                 ps_ctb_node->u1_num_top_right_avail =
    910                     ((u2_pic_wdt - ps_ctb_node->u2_orig_x - u1_ctb_size) >= u1_ctb_size)
    911                         ? u1_ctb_size
    912                         : u2_pic_wdt - ps_ctb_node->u2_orig_x - u1_ctb_size;
    913                 nbr_flags |=
    914                     TOP_RIGHT_FLAG; /* Set Top-Right Flag if not in first row or last column*/
    915             }
    916         }
    917         else
    918         {
    919             ps_ctb_node->u1_num_top_right_avail = 0;
    920         }
    921 
    922         ps_ctb_node->u1_num_bottom_left_avail = 0;
    923 
    924         ps_ctb_node->i4_nbr_flag = nbr_flags;
    925 
    926         /**
    927         * Update CTB Mode Map
    928         * In case this is first CTB in a row, set left most column to INTRA_DC (NA)
    929         * else copy last column to first column
    930         **/
    931         if(ctb_ctr == 0)
    932         {
    933             for(row = 0; row < (MAX_TU_ROW_IN_CTB + 1); row++)
    934             {
    935                 ps_ctxt->au1_ctb_mode_map[row][0] = INTRA_DC;
    936             }
    937         }
    938         else
    939         {
    940             for(row = 0; row < (MAX_TU_ROW_IN_CTB + 1); row++)
    941             {
    942                 ps_ctxt->au1_ctb_mode_map[row][0] =
    943                     ps_ctxt->au1_ctb_mode_map[row][MAX_TU_COL_IN_CTB];
    944             }
    945         }
    946 
    947         /* --------- IPE call at CTB level ------------------ */
    948 
    949         /* IPE CTB function is expected to Decide on the CUs sizes  */
    950         /* and populate the best intra prediction modes and TX flags*/
    951         /* Interface of this CTb level function is kept open */
    952 
    953         ps_ed_l1_ctb = ps_ed_l1_row + ctb_ctr * blk_inc_ctb_l1;
    954         ps_ed_l2_ctb = ps_ed_l2_row + ctb_ctr * blk_inc_ctb_l2;
    955         ps_ed_ctb_l1 = ps_ed_ctb_l1_row + ctb_ctr;
    956 
    957         if(ps_ctxt->u1_use_lambda_derived_from_min_8x8_act_in_ctb)
    958         {
    959             /*HACK : MAMATHA, This function assumes that data is accumalated
    960             for all probable CU-TU combinations for INcomplete CTB, which is currently not the case,
    961             hence not recomputing lamda for the incomplete CTB */
    962             if((ps_ctb_node->u1_width == u1_ctb_size) && (ps_ctb_node->u1_height == u1_ctb_size))
    963             {
    964                 ihevce_ipe_recompute_lambda_from_min_8x8_act_in_ctb(ps_ctxt, ps_ed_ctb_l1);
    965             }
    966         }
    967 
    968         ihevce_ipe_process_ctb(
    969             ps_ctxt,
    970             ps_frm_ctb_prms,
    971             &s_curr_src_bufs,
    972             ps_ctb_node,
    973             ps_l0_ipe_out_ctb,
    974             ps_ctb_out,
    975             //ps_row_cu,
    976             ps_ed_l1_ctb,
    977             ps_ed_l2_ctb,
    978             ps_ed_ctb_l1);
    979 
    980         /* -------------- ctb level updates ----------------- */
    981 
    982         ps_l0_ipe_out_ctb++;
    983         //num_cus_in_ctb = ps_ctb_out->u1_num_cus_in_ctb;
    984 
    985         //ps_row_cu += num_cus_in_ctb;
    986 
    987         ps_ctb_out++;
    988     }
    989     return;
    990 }
    991 
    992 /*!
    993 ******************************************************************************
    994 * \if Function name : ihevce_ipe_process \endif
    995 *
    996 * \brief
    997 *    Frame level IPE function
    998 *
    999 * \param[in] pv_ctxt : pointer to IPE module
   1000 * \param[in] ps_frm_ctb_prms : CTB characteristics parameters
   1001 * \param[in] ps_inp  : pointer to input yuv buffer (frame buffer)
   1002 * \param[out] ps_ctb_out : pointer to CTB analyse output structure (frame buffer)
   1003 * \param[out] ps_cu_out : pointer to CU analyse output structure (frame buffer)
   1004 *
   1005 * \return
   1006 *    None
   1007 *
   1008 * Note : Currently the frame level calculations done assumes that
   1009 *        framewidth of the input are excat multiple of ctbsize
   1010 *
   1011 * \author
   1012 *  Ittiam
   1013 *
   1014 *****************************************************************************
   1015 */
   1016 void ihevce_ipe_process(
   1017     void *pv_ctxt,
   1018     frm_ctb_ctxt_t *ps_frm_ctb_prms,
   1019     frm_lambda_ctxt_t *ps_frm_lamda,
   1020     ihevce_lap_enc_buf_t *ps_curr_inp,
   1021     pre_enc_L0_ipe_encloop_ctxt_t *ps_L0_IPE_curr_out_pre_enc,
   1022     ctb_analyse_t *ps_ctb_out,
   1023     //cu_analyse_t               *ps_cu_out,
   1024     ipe_l0_ctb_analyse_for_me_t *ps_ipe_ctb_out,
   1025     void *pv_multi_thrd_ctxt,
   1026     WORD32 slice_type,
   1027     ihevce_ed_blk_t *ps_ed_pic_l1,
   1028     ihevce_ed_blk_t *ps_ed_pic_l2,
   1029     ihevce_ed_ctb_l1_t *ps_ed_ctb_l1_pic,
   1030     WORD32 thrd_id,
   1031     WORD32 i4_ping_pong)
   1032 {
   1033     /* local variables */
   1034     ihevce_ipe_master_ctxt_t *ps_master_ctxt;
   1035     iv_enc_yuv_buf_t *ps_inp = &ps_curr_inp->s_lap_out.s_input_buf;
   1036     ihevce_ipe_ctxt_t *ps_ctxt;
   1037     iv_enc_yuv_buf_t s_curr_src_bufs;
   1038     WORD32 end_of_frame;
   1039 
   1040     ihevce_ed_blk_t *ps_ed_l1_row;
   1041     ihevce_ed_blk_t *ps_ed_l2_row;
   1042     ihevce_ed_ctb_l1_t *ps_ed_ctb_l1_row;
   1043     WORD32 blk_inc_ctb_l1 = 0;
   1044     WORD32 blk_inc_ctb_l2 = 0;
   1045 
   1046     /* Layer 1 pre intra analysis related initilization.
   1047     * Compute no of 8x8 blks in the ctb which which is
   1048     * same as no of 4x4 blks in the ctb in layer 1 */
   1049     blk_inc_ctb_l1 = ps_frm_ctb_prms->i4_ctb_size >> 3;
   1050     blk_inc_ctb_l1 = blk_inc_ctb_l1 * blk_inc_ctb_l1;
   1051 
   1052     /* Layer 2 pre intra analysis related initilization.
   1053     * Compute no of 16x16 blks in the ctb which which is
   1054     * same as no of 8x8 blks in the ctb in layer 2 */
   1055     blk_inc_ctb_l2 = ps_frm_ctb_prms->i4_ctb_size >> 4;
   1056     blk_inc_ctb_l2 = blk_inc_ctb_l2 * blk_inc_ctb_l2;
   1057 
   1058     /* ----------------------------------------------------- */
   1059     /* store the stride and dimensions of source             */
   1060     /* buffer pointers will be over written at every CTB row */
   1061     /* ----------------------------------------------------- */
   1062     memcpy(&s_curr_src_bufs, ps_inp, sizeof(iv_enc_yuv_buf_t));
   1063 
   1064     ps_master_ctxt = (ihevce_ipe_master_ctxt_t *)pv_ctxt;
   1065     ps_ctxt = ps_master_ctxt->aps_ipe_thrd_ctxt[thrd_id];
   1066     end_of_frame = 0;
   1067 
   1068     if(ISLICE == slice_type)
   1069     {
   1070         ps_ctxt->b_sad_type = IPE_SAD_TYPE;
   1071         ps_ctxt->i4_ol_satd_lambda = ps_frm_lamda->i4_ol_satd_lambda_qf;
   1072         ps_ctxt->i4_ol_sad_lambda = ps_frm_lamda->i4_ol_sad_lambda_qf;
   1073     }
   1074     else
   1075     {
   1076         ps_ctxt->b_sad_type = IPE_SAD_TYPE; /* SAD */
   1077         ps_ctxt->i4_ol_satd_lambda = ps_frm_lamda->i4_ol_satd_lambda_qf;
   1078         ps_ctxt->i4_ol_sad_lambda = ps_frm_lamda->i4_ol_sad_lambda_qf;
   1079     }
   1080 
   1081     ihevce_populate_ipe_ol_cu_lambda_prms(
   1082         (void *)ps_ctxt,
   1083         ps_frm_lamda,
   1084         slice_type,
   1085         ps_curr_inp->s_lap_out.i4_temporal_lyr_id,
   1086         IPE_LAMBDA_TYPE);
   1087 
   1088     /* register the slice type in the ctxt */
   1089     ps_ctxt->i4_slice_type = slice_type;
   1090 
   1091     /** Frame-levelSATD cost accumalator init to 0 */
   1092     ps_ctxt->i8_frame_acc_satd_cost = 0;
   1093 
   1094     /** Frame-levelSATD accumalator init to 0 */
   1095     ps_ctxt->i8_frame_acc_satd = 0;
   1096 
   1097     /** Frame-level Activity factor accumalator init to 1 */
   1098     ps_ctxt->i8_frame_acc_act_factor = 1;
   1099 
   1100     /** Frame-levelMode Bits cost accumalator init to 0 */
   1101     ps_ctxt->i8_frame_acc_mode_bits_cost = 0;
   1102 
   1103     /** Frame -level SATD/qp acc init to 0*/
   1104     ps_ctxt->i8_frame_acc_satd_by_modqp_q10 = 0;
   1105 
   1106     /* ------------ Loop over all the CTB rows --------------- */
   1107     while(0 == end_of_frame)
   1108     {
   1109         UWORD8 *pu1_tmp;
   1110         WORD32 vert_ctr;
   1111         //cu_analyse_t *ps_row_cu;
   1112         ctb_analyse_t *ps_ctb_out_row;
   1113         job_queue_t *ps_job;
   1114         ipe_l0_ctb_analyse_for_me_t *ps_ipe_ctb_out_row;
   1115 
   1116         /* Get the current row from the job queue */
   1117         ps_job = (job_queue_t *)ihevce_pre_enc_grp_get_next_job(
   1118             pv_multi_thrd_ctxt, IPE_JOB_LYR0, 1, i4_ping_pong);
   1119 
   1120         /* If all rows are done, set the end of process flag to 1, */
   1121         /* and the current row to -1 */
   1122         if(NULL == ps_job)
   1123         {
   1124             vert_ctr = -1;
   1125             end_of_frame = 1;
   1126         }
   1127         else
   1128         {
   1129             ASSERT(IPE_JOB_LYR0 == ps_job->i4_pre_enc_task_type);
   1130 
   1131             /* Obtain the current row's details from the job */
   1132             vert_ctr = ps_job->s_job_info.s_ipe_job_info.i4_ctb_row_no;
   1133             //DBG_PRINTF("IPE PASS : Thread id %d, Vert Ctr %d\n",thrd_id,vert_ctr);
   1134 
   1135             /* Update the ipe context with current row number */
   1136             ps_ctxt->u2_ctb_row_num = vert_ctr;
   1137 
   1138             /* derive the current ctb row pointers */
   1139 
   1140             /* luma src */
   1141             pu1_tmp = (UWORD8 *)ps_curr_inp->s_lap_out.s_input_buf.pv_y_buf;
   1142             pu1_tmp += (vert_ctr * ps_frm_ctb_prms->i4_ctb_size * ps_inp->i4_y_strd);
   1143 
   1144             s_curr_src_bufs.pv_y_buf = pu1_tmp;
   1145 
   1146             /* Cb & CR pixel interleaved src */
   1147             pu1_tmp = (UWORD8 *)ps_curr_inp->s_lap_out.s_input_buf.pv_u_buf;
   1148             pu1_tmp += (vert_ctr * (ps_frm_ctb_prms->i4_ctb_size >> 1) * ps_inp->i4_uv_strd);
   1149 
   1150             s_curr_src_bufs.pv_u_buf = pu1_tmp;
   1151 
   1152             /* row intra analyse cost buffer */
   1153             ps_ipe_ctb_out_row = ps_ipe_ctb_out + vert_ctr * ps_frm_ctb_prms->i4_num_ctbs_horz;
   1154 
   1155             /* row ctb out structure */
   1156             ps_ctb_out_row = ps_ctb_out + vert_ctr * ps_frm_ctb_prms->i4_num_ctbs_horz;
   1157 
   1158             /* call the row level processing function */
   1159             ps_ed_l1_row =
   1160                 ps_ed_pic_l1 + ps_frm_ctb_prms->i4_num_ctbs_horz * blk_inc_ctb_l1 * vert_ctr;
   1161             ps_ed_l2_row =
   1162                 ps_ed_pic_l2 + ps_frm_ctb_prms->i4_num_ctbs_horz * blk_inc_ctb_l2 * vert_ctr;
   1163             ps_ed_ctb_l1_row = ps_ed_ctb_l1_pic + ps_frm_ctb_prms->i4_num_ctbs_horz * vert_ctr;
   1164             ihevce_ipe_process_row(
   1165                 ps_ctxt,
   1166                 ps_frm_ctb_prms,
   1167                 &s_curr_src_bufs,
   1168                 ps_ipe_ctb_out_row,
   1169                 ps_ctb_out_row,
   1170                 //ps_row_cu,
   1171                 ps_ed_l1_row,
   1172                 ps_ed_l2_row,
   1173                 ps_ed_ctb_l1_row,
   1174                 blk_inc_ctb_l1,
   1175                 blk_inc_ctb_l2);
   1176 
   1177             memset(
   1178                 ps_ed_l1_row,
   1179                 0,
   1180                 ps_frm_ctb_prms->i4_num_ctbs_horz * blk_inc_ctb_l1 * sizeof(ihevce_ed_blk_t));
   1181             memset(
   1182                 ps_ed_l2_row,
   1183                 0,
   1184                 ps_frm_ctb_prms->i4_num_ctbs_horz * blk_inc_ctb_l2 * sizeof(ihevce_ed_blk_t));
   1185 
   1186             /* set the output dependency */
   1187             ihevce_pre_enc_grp_job_set_out_dep(pv_multi_thrd_ctxt, ps_job, i4_ping_pong);
   1188         }
   1189     }
   1190 
   1191     /* EIID: Print stat regarding how many 16x16 blocks are skipped in the frame, valid for single thread only */
   1192     //DBG_PRINTF("num_16x16_analyze_skipped: %d\n",ps_ctxt->u4_num_16x16_skips_at_L0_IPE);
   1193 
   1194     return;
   1195 }
   1196 
   1197 /*!
   1198 ******************************************************************************
   1199 * \if Function name : ihevce_get_frame_lambda_prms \endif
   1200 *
   1201 * \brief
   1202 *    Function whihc calculates the Lambda params for current picture
   1203 *
   1204 * \param[in] ps_enc_ctxt : encoder ctxt pointer
   1205 * \param[in] ps_cur_pic_ctxt : current pic ctxt
   1206 * \param[in] i4_cur_frame_qp : current pic QP
   1207 * \param[in] first_field : is first field flag
   1208 * \param[in] i4_temporal_lyr_id : Current picture layer id
   1209 *
   1210 * \return
   1211 *    None
   1212 *
   1213 * \author
   1214 *  Ittiam
   1215 *
   1216 *****************************************************************************
   1217 */
   1218 void ihevce_get_ipe_ol_cu_lambda_prms(void *pv_ctxt, WORD32 i4_cur_cu_qp)
   1219 {
   1220     ihevce_ipe_ctxt_t *ps_ctxt = (ihevce_ipe_ctxt_t *)pv_ctxt;
   1221     //WORD32 chroma_qp = gau1_ihevc_chroma_qp_scale[i4_cur_cu_qp];
   1222 
   1223     /* Store the params for IPE pass */
   1224     ps_ctxt->i4_ol_satd_lambda = ps_ctxt->i4_ol_satd_lambda_qf_array[i4_cur_cu_qp];
   1225     ps_ctxt->i4_ol_sad_lambda = ps_ctxt->i4_ol_sad_lambda_qf_array[i4_cur_cu_qp];
   1226 }
   1227 
   1228 /*!
   1229 ******************************************************************************
   1230 * \if Function name : ihevce_get_frame_lambda_prms \endif
   1231 *
   1232 * \brief
   1233 *    Function whihc calculates the Lambda params for current picture
   1234 *
   1235 * \param[in] ps_enc_ctxt : encoder ctxt pointer
   1236 * \param[in] ps_cur_pic_ctxt : current pic ctxt
   1237 * \param[in] i4_cur_frame_qp : current pic QP
   1238 * \param[in] first_field : is first field flag
   1239 * \param[in] i4_temporal_lyr_id : Current picture layer id
   1240 *
   1241 * \return
   1242 *    None
   1243 *
   1244 * \author
   1245 *  Ittiam
   1246 *
   1247 *****************************************************************************
   1248 */
   1249 void ihevce_populate_ipe_ol_cu_lambda_prms(
   1250     void *pv_ctxt,
   1251     frm_lambda_ctxt_t *ps_frm_lamda,
   1252     WORD32 i4_slice_type,
   1253     WORD32 i4_temporal_lyr_id,
   1254     WORD32 i4_lambda_type)
   1255 {
   1256     WORD32 i4_curr_cu_qp;
   1257     double lambda_modifier;
   1258     double lambda_uv_modifier;
   1259     double lambda;
   1260     double lambda_uv;
   1261 
   1262     ihevce_ipe_ctxt_t *ps_ctxt = (ihevce_ipe_ctxt_t *)pv_ctxt;
   1263 
   1264     WORD32 i4_qp_bd_offset = 6 * (ps_ctxt->u1_bit_depth - 8);
   1265 
   1266     for(i4_curr_cu_qp =
   1267             ps_ctxt->ps_rc_quant_ctxt->i2_min_qp + ps_ctxt->ps_rc_quant_ctxt->i1_qp_offset;
   1268         i4_curr_cu_qp <= ps_ctxt->ps_rc_quant_ctxt->i2_max_qp;
   1269         i4_curr_cu_qp++)
   1270     {
   1271         WORD32 chroma_qp = i4_curr_cu_qp;
   1272 
   1273         if((BSLICE == i4_slice_type) && (i4_temporal_lyr_id))
   1274         {
   1275             lambda_modifier = ps_frm_lamda->lambda_modifier *
   1276                               CLIP3((((double)(i4_curr_cu_qp - 12)) / 6.0), 2.00, 4.00);
   1277             lambda_uv_modifier = ps_frm_lamda->lambda_uv_modifier *
   1278                                  CLIP3((((double)(chroma_qp - 12)) / 6.0), 2.00, 4.00);
   1279         }
   1280         else
   1281         {
   1282             lambda_modifier = ps_frm_lamda->lambda_modifier;
   1283             lambda_uv_modifier = ps_frm_lamda->lambda_uv_modifier;
   1284         }
   1285         if(ps_ctxt->i4_use_const_lamda_modifier)
   1286         {
   1287             if(ISLICE == i4_slice_type)
   1288             {
   1289                 lambda_modifier = ps_ctxt->f_i_pic_lamda_modifier;
   1290                 lambda_uv_modifier = ps_ctxt->f_i_pic_lamda_modifier;
   1291             }
   1292             else
   1293             {
   1294                 lambda_modifier = CONST_LAMDA_MOD_VAL;
   1295                 lambda_uv_modifier = CONST_LAMDA_MOD_VAL;
   1296             }
   1297         }
   1298 
   1299         switch(i4_lambda_type)
   1300         {
   1301         case 0:
   1302         {
   1303             i4_qp_bd_offset = 0;
   1304 
   1305             lambda = pow(2.0, (((double)(i4_curr_cu_qp + i4_qp_bd_offset - 12)) / 3.0));
   1306 
   1307             lambda_uv = pow(2.0, (((double)(chroma_qp + i4_qp_bd_offset - 12)) / 3.0));
   1308 
   1309             lambda *= lambda_modifier;
   1310             lambda_uv *= lambda_uv_modifier;
   1311             if(ps_ctxt->i4_use_const_lamda_modifier)
   1312             {
   1313                 ps_ctxt->i4_ol_sad_lambda_qf_array[i4_curr_cu_qp] =
   1314                     (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
   1315 
   1316                 ps_ctxt->i4_ol_satd_lambda_qf_array[i4_curr_cu_qp] =
   1317                     (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
   1318             }
   1319             else
   1320             {
   1321                 ps_ctxt->i4_ol_sad_lambda_qf_array[i4_curr_cu_qp] =
   1322                     (WORD32)((sqrt(lambda) / 2) * (1 << LAMBDA_Q_SHIFT));
   1323 
   1324                 ps_ctxt->i4_ol_satd_lambda_qf_array[i4_curr_cu_qp] =
   1325                     (WORD32)((sqrt(lambda * 1.9) / 2) * (1 << LAMBDA_Q_SHIFT));
   1326             }
   1327 
   1328             ps_ctxt->i4_ol_sad_type2_lambda_qf_array[i4_curr_cu_qp] =
   1329                 ps_ctxt->i4_ol_sad_lambda_qf_array[i4_curr_cu_qp];
   1330 
   1331             ps_ctxt->i4_ol_satd_type2_lambda_qf_array[i4_curr_cu_qp] =
   1332                 ps_ctxt->i4_ol_satd_lambda_qf_array[i4_curr_cu_qp];
   1333 
   1334             break;
   1335         }
   1336         case 1:
   1337         {
   1338             ASSERT(0); /* should not enter the path for IPE*/
   1339             lambda = pow(2.0, (((double)(i4_curr_cu_qp + i4_qp_bd_offset - 12)) / 3.0));
   1340 
   1341             lambda_uv = pow(2.0, (((double)(chroma_qp + i4_qp_bd_offset - 12)) / 3.0));
   1342 
   1343             lambda *= lambda_modifier;
   1344             lambda_uv *= lambda_uv_modifier;
   1345             if(ps_ctxt->i4_use_const_lamda_modifier)
   1346             {
   1347                 ps_ctxt->i4_ol_sad_lambda_qf_array[i4_curr_cu_qp] =
   1348                     (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
   1349 
   1350                 ps_ctxt->i4_ol_satd_lambda_qf_array[i4_curr_cu_qp] =
   1351                     (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
   1352             }
   1353             else
   1354             {
   1355                 ps_ctxt->i4_ol_sad_lambda_qf_array[i4_curr_cu_qp] =
   1356                     (WORD32)((sqrt(lambda) / 2) * (1 << LAMBDA_Q_SHIFT));
   1357 
   1358                 ps_ctxt->i4_ol_satd_lambda_qf_array[i4_curr_cu_qp] =
   1359                     (WORD32)((sqrt(lambda * 1.9) / 2) * (1 << LAMBDA_Q_SHIFT));
   1360             }
   1361 
   1362             ps_ctxt->i4_ol_sad_type2_lambda_qf_array[i4_curr_cu_qp] =
   1363                 ps_ctxt->i4_ol_sad_lambda_qf_array[i4_curr_cu_qp];
   1364 
   1365             ps_ctxt->i4_ol_satd_type2_lambda_qf_array[i4_curr_cu_qp] =
   1366                 ps_ctxt->i4_ol_satd_lambda_qf_array[i4_curr_cu_qp];
   1367 
   1368             break;
   1369         }
   1370         case 2:
   1371         {
   1372             ASSERT(0); /* should not enter the path for IPE*/
   1373             lambda = pow(2.0, (((double)(i4_curr_cu_qp + i4_qp_bd_offset - 12)) / 3.0));
   1374 
   1375             lambda_uv = pow(2.0, (((double)(chroma_qp + i4_qp_bd_offset - 12)) / 3.0));
   1376 
   1377             lambda *= lambda_modifier;
   1378             lambda_uv *= lambda_uv_modifier;
   1379             if(ps_ctxt->i4_use_const_lamda_modifier)
   1380             {
   1381                 ps_ctxt->i4_ol_sad_lambda_qf_array[i4_curr_cu_qp] =
   1382                     (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
   1383 
   1384                 ps_ctxt->i4_ol_satd_lambda_qf_array[i4_curr_cu_qp] =
   1385                     (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
   1386             }
   1387             else
   1388             {
   1389                 ps_ctxt->i4_ol_sad_lambda_qf_array[i4_curr_cu_qp] =
   1390                     (WORD32)((sqrt(lambda) / 2) * (1 << LAMBDA_Q_SHIFT));
   1391 
   1392                 ps_ctxt->i4_ol_satd_lambda_qf_array[i4_curr_cu_qp] =
   1393                     (WORD32)((sqrt(lambda * 1.9) / 2) * (1 << LAMBDA_Q_SHIFT));
   1394             }
   1395             i4_qp_bd_offset = 0;
   1396 
   1397             lambda = pow(2.0, (((double)(i4_curr_cu_qp + i4_qp_bd_offset - 12)) / 3.0));
   1398 
   1399             lambda_uv = pow(2.0, (((double)(chroma_qp + i4_qp_bd_offset - 12)) / 3.0));
   1400 
   1401             lambda *= lambda_modifier;
   1402             lambda_uv *= lambda_uv_modifier;
   1403             if(ps_ctxt->i4_use_const_lamda_modifier)
   1404             {
   1405                 ps_ctxt->i4_ol_sad_type2_lambda_qf_array[i4_curr_cu_qp] =
   1406                     (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
   1407 
   1408                 ps_ctxt->i4_ol_satd_type2_lambda_qf_array[i4_curr_cu_qp] =
   1409                     (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
   1410             }
   1411             else
   1412             {
   1413                 ps_ctxt->i4_ol_sad_type2_lambda_qf_array[i4_curr_cu_qp] =
   1414                     (WORD32)((sqrt(lambda) / 2) * (1 << LAMBDA_Q_SHIFT));
   1415 
   1416                 ps_ctxt->i4_ol_satd_type2_lambda_qf_array[i4_curr_cu_qp] =
   1417                     (WORD32)((sqrt(lambda * 1.9) / 2) * (1 << LAMBDA_Q_SHIFT));
   1418             }
   1419             break;
   1420         }
   1421         default:
   1422         {
   1423             /* Intended to be a barren wasteland! */
   1424             ASSERT(0);
   1425         }
   1426         }
   1427     }
   1428 }
   1429 
   1430 #define ME_COST_THRSHOLD 7
   1431 /*!
   1432 ******************************************************************************
   1433 * \if Function name : ihevce_get_frame_lambda_prms \endif
   1434 *
   1435 * \brief
   1436 *    Function whihc calculates the Lambda params for current picture
   1437 *
   1438 * \param[in] ps_enc_ctxt : encoder ctxt pointer
   1439 * \param[in] ps_cur_pic_ctxt : current pic ctxt
   1440 * \param[in] i4_cur_frame_qp : current pic QP
   1441 * \param[in] first_field : is first field flag
   1442 * \param[in] i4_temporal_lyr_id : Current picture layer id
   1443 *
   1444 * \return
   1445 *    None
   1446 *
   1447 * \author
   1448 *  Ittiam
   1449 *
   1450 *****************************************************************************
   1451 */
   1452 #define MAX_64BIT_VAL 0x7fffffffffffffff
   1453 void ihevce_populate_ipe_frame_init(
   1454     void *pv_ctxt,
   1455     ihevce_static_cfg_params_t *ps_stat_prms,
   1456     WORD32 i4_curr_frm_qp,
   1457     WORD32 i4_slice_type,
   1458     WORD32 i4_thrd_id,
   1459     pre_enc_me_ctxt_t *ps_curr_out,
   1460     WORD8 i1_cu_qp_delta_enabled_flag,
   1461     rc_quant_t *ps_rc_quant_ctxt,
   1462     WORD32 i4_quality_preset,
   1463     WORD32 i4_temporal_lyr_id,
   1464     ihevce_lap_output_params_t *ps_lap_out)
   1465 {
   1466     ihevce_ipe_master_ctxt_t *ps_master_ctxt = (ihevce_ipe_master_ctxt_t *)pv_ctxt;
   1467     WORD32 i4_i;
   1468     WORD32 ai4_mod_factor_num[2];
   1469 
   1470     ihevce_ipe_ctxt_t *ps_ctxt = ps_master_ctxt->aps_ipe_thrd_ctxt[i4_thrd_id];
   1471     ps_ctxt->i4_hevc_qp = i4_curr_frm_qp;
   1472     ps_ctxt->i4_quality_preset = i4_quality_preset;
   1473     ps_ctxt->i4_temporal_lyr_id = i4_temporal_lyr_id;
   1474     ps_ctxt->ps_rc_quant_ctxt = ps_rc_quant_ctxt;
   1475     ps_ctxt->i4_qscale =
   1476         ps_ctxt->ps_rc_quant_ctxt
   1477             ->pi4_qp_to_qscale[i4_curr_frm_qp + ps_ctxt->ps_rc_quant_ctxt->i1_qp_offset];
   1478 
   1479     ps_ctxt->i4_frm_qp = i4_curr_frm_qp + ps_ctxt->ps_rc_quant_ctxt->i1_qp_offset;
   1480     ps_ctxt->i4_slice_type = i4_slice_type;  //EIID
   1481     ps_ctxt->i4_temporal_layer = ps_lap_out->i4_temporal_lyr_id;
   1482     ps_ctxt->i4_is_ref_pic = ps_lap_out->i4_is_ref_pic;
   1483     ps_ctxt->u4_num_16x16_skips_at_L0_IPE = 0;
   1484     ps_ctxt->i4_use_const_lamda_modifier = USE_CONSTANT_LAMBDA_MODIFIER;
   1485     ps_ctxt->i4_use_const_lamda_modifier =
   1486         ps_ctxt->i4_use_const_lamda_modifier ||
   1487         ((ps_stat_prms->s_coding_tools_prms.i4_vqet &
   1488           (1 << BITPOS_IN_VQ_TOGGLE_FOR_CONTROL_TOGGLER)) &&
   1489          ((ps_stat_prms->s_coding_tools_prms.i4_vqet &
   1490            (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_NOISE_PRESERVATION)) ||
   1491           (ps_stat_prms->s_coding_tools_prms.i4_vqet &
   1492            (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_PSYRDOPT_1)) ||
   1493           (ps_stat_prms->s_coding_tools_prms.i4_vqet &
   1494            (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_PSYRDOPT_2)) ||
   1495           (ps_stat_prms->s_coding_tools_prms.i4_vqet &
   1496            (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_PSYRDOPT_3))));
   1497     {
   1498         ps_ctxt->f_i_pic_lamda_modifier = ps_lap_out->f_i_pic_lamda_modifier;
   1499     }
   1500 #if POW_OPT
   1501     for(i4_i = 0; i4_i < 2; i4_i++)
   1502     {
   1503         ps_ctxt->ld_curr_frame_8x8_log_avg[i4_i] = ps_curr_out->ld_curr_frame_8x8_log_avg[i4_i];
   1504         ps_ctxt->ld_curr_frame_16x16_log_avg[i4_i] = ps_curr_out->ld_curr_frame_16x16_log_avg[i4_i];
   1505         ps_ctxt->ld_curr_frame_32x32_log_avg[i4_i] = ps_curr_out->ld_curr_frame_32x32_log_avg[i4_i];
   1506     }
   1507 
   1508     ps_ctxt->ld_curr_frame_16x16_log_avg[2] = ps_curr_out->ld_curr_frame_16x16_log_avg[2];
   1509     ps_ctxt->ld_curr_frame_32x32_log_avg[2] = ps_curr_out->ld_curr_frame_32x32_log_avg[2];
   1510     ps_ctxt->i8_curr_frame_avg_mean_act = ps_curr_out->i8_curr_frame_avg_mean_act;
   1511 #else
   1512     for(i4_i = 0; i4_i < 2; i4_i++)
   1513     {
   1514         ps_ctxt->i8_curr_frame_8x8_avg_act[i4_i] = ps_curr_out->i8_curr_frame_8x8_avg_act[i4_i];
   1515         ps_ctxt->i8_curr_frame_16x16_avg_act[i4_i] = ps_curr_out->i8_curr_frame_16x16_avg_act[i4_i];
   1516         ps_ctxt->i8_curr_frame_32x32_avg_act[i4_i] = ps_curr_out->i8_curr_frame_32x32_avg_act[i4_i];
   1517     }
   1518 
   1519     ps_ctxt->i8_curr_frame_16x16_avg_act[2] = ps_curr_out->i8_curr_frame_16x16_avg_act[2];
   1520     ps_ctxt->i8_curr_frame_32x32_avg_act[2] = ps_curr_out->i8_curr_frame_32x32_avg_act[2];
   1521 #endif
   1522 
   1523     ps_ctxt->pi2_trans_out =
   1524         (WORD16 *)&ps_ctxt->au1_pred_samples[0];  //overlaying trans coeff memory with pred_samples
   1525     ps_ctxt->pi2_trans_tmp = (WORD16 *)&ps_ctxt->au1_pred_samples[2048];
   1526 
   1527     /*Mod factor NUM */
   1528     ps_ctxt->ai4_mod_factor_derived_by_variance[0] =
   1529         ps_curr_out->ai4_mod_factor_derived_by_variance[0];
   1530     ps_ctxt->ai4_mod_factor_derived_by_variance[1] =
   1531         ps_curr_out->ai4_mod_factor_derived_by_variance[1];
   1532 
   1533     ps_ctxt->f_strength = ps_curr_out->f_strength;
   1534 
   1535     if(ps_stat_prms->s_coding_tools_prms.i4_vqet & (1 << BITPOS_IN_VQ_TOGGLE_FOR_CONTROL_TOGGLER))
   1536     {
   1537         if(ps_stat_prms->s_coding_tools_prms.i4_vqet &
   1538            (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_NOISE_PRESERVATION))
   1539         {
   1540             ps_ctxt->i4_enable_noise_detection = 1;
   1541         }
   1542         else
   1543         {
   1544             ps_ctxt->i4_enable_noise_detection = 0;
   1545         }
   1546     }
   1547     else
   1548     {
   1549         ps_ctxt->i4_enable_noise_detection = 0;
   1550     }
   1551 
   1552     {
   1553         if(ISLICE == ps_ctxt->i4_slice_type)
   1554         {
   1555             ai4_mod_factor_num[0] = INTRA_QP_MOD_FACTOR_NUM;  //16;
   1556             ai4_mod_factor_num[1] = INTRA_QP_MOD_FACTOR_NUM;  //16;
   1557         }
   1558         else
   1559         {
   1560             ai4_mod_factor_num[0] = INTER_QP_MOD_FACTOR_NUM;  //4;
   1561             ai4_mod_factor_num[1] = INTER_QP_MOD_FACTOR_NUM;  //4;
   1562         }
   1563 
   1564 #if ENABLE_QP_MOD_BASED_ON_SPATIAL_VARIANCE
   1565         for(i4_i = 0; i4_i < 2; i4_i++)
   1566         {
   1567             WORD32 mod_factor_num_val =
   1568                 ps_ctxt->ai4_mod_factor_derived_by_variance[i4_i] * QP_MOD_FACTOR_DEN;
   1569 
   1570             ai4_mod_factor_num[i4_i] = CLIP3(mod_factor_num_val, 1, ai4_mod_factor_num[i4_i]);
   1571             ps_ctxt->ai4_mod_factor_derived_by_variance[i4_i] = ai4_mod_factor_num[i4_i];
   1572         }
   1573 #else
   1574         for(i4_i = 0; i4_i < 2; i4_i++)
   1575         {
   1576             ps_ctxt->ai4_mod_factor_derived_by_variance[i4_i] = ai4_mod_factor_num[i4_i];
   1577         }
   1578 #endif
   1579     }
   1580 
   1581     ps_ctxt->u1_use_lambda_derived_from_min_8x8_act_in_ctb = MODULATE_LAMDA_WHEN_SPATIAL_MOD_ON &&
   1582                                                              i1_cu_qp_delta_enabled_flag;
   1583 
   1584     ps_ctxt->u1_use_satd = 1;
   1585     ps_ctxt->u1_level_1_refine_on = 1;
   1586     ps_ctxt->u1_disable_child_cu_decide = 0;
   1587 
   1588 #if !OLD_XTREME_SPEED
   1589     if(((ps_ctxt->i4_quality_preset == IHEVCE_QUALITY_P5) ||
   1590         (ps_ctxt->i4_quality_preset == IHEVCE_QUALITY_P6)) &&
   1591        (ps_ctxt->i4_slice_type != ISLICE))
   1592     {
   1593         ps_ctxt->u1_use_satd = 0;
   1594         ps_ctxt->u1_level_1_refine_on = 1;
   1595         ps_ctxt->u1_disable_child_cu_decide = 0;
   1596     }
   1597 
   1598 #endif
   1599 
   1600     if((ps_ctxt->i4_quality_preset == IHEVCE_QUALITY_P4) && (ps_ctxt->i4_slice_type != ISLICE))
   1601         ps_ctxt->u1_use_satd = 0;
   1602     if(ps_ctxt->i4_quality_preset > IHEVCE_QUALITY_P3)
   1603         ps_ctxt->u1_use_satd = 0;
   1604 }
   1605