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_enc_loop_inter_mode_sifter.c
     24 *
     25 * \brief
     26 *    This file contains functions for selecting best inter candidates for RDOPT evaluation
     27 *
     28 * \date
     29 *    10/09/2014
     30 *
     31 ******************************************************************************
     32 */
     33 
     34 /*****************************************************************************/
     35 /* File Includes                                                             */
     36 /*****************************************************************************/
     37 /* System include files */
     38 #include <stdio.h>
     39 #include <string.h>
     40 #include <stdlib.h>
     41 #include <assert.h>
     42 #include <stdarg.h>
     43 #include <math.h>
     44 #include <limits.h>
     45 
     46 /* User include files */
     47 #include "ihevc_typedefs.h"
     48 #include "itt_video_api.h"
     49 #include "ihevce_api.h"
     50 
     51 #include "rc_cntrl_param.h"
     52 #include "rc_frame_info_collector.h"
     53 #include "rc_look_ahead_params.h"
     54 
     55 #include "ihevc_defs.h"
     56 #include "ihevc_macros.h"
     57 #include "ihevc_debug.h"
     58 #include "ihevc_structs.h"
     59 #include "ihevc_platform_macros.h"
     60 #include "ihevc_deblk.h"
     61 #include "ihevc_itrans_recon.h"
     62 #include "ihevc_chroma_itrans_recon.h"
     63 #include "ihevc_chroma_intra_pred.h"
     64 #include "ihevc_intra_pred.h"
     65 #include "ihevc_inter_pred.h"
     66 #include "ihevc_mem_fns.h"
     67 #include "ihevc_padding.h"
     68 #include "ihevc_weighted_pred.h"
     69 #include "ihevc_sao.h"
     70 #include "ihevc_resi_trans.h"
     71 #include "ihevc_quant_iquant_ssd.h"
     72 #include "ihevc_cabac_tables.h"
     73 
     74 #include "ihevce_defs.h"
     75 #include "ihevce_hle_interface.h"
     76 #include "ihevce_lap_enc_structs.h"
     77 #include "ihevce_multi_thrd_structs.h"
     78 #include "ihevce_multi_thrd_funcs.h"
     79 #include "ihevce_me_common_defs.h"
     80 #include "ihevce_had_satd.h"
     81 #include "ihevce_error_codes.h"
     82 #include "ihevce_bitstream.h"
     83 #include "ihevce_cabac.h"
     84 #include "ihevce_rdoq_macros.h"
     85 #include "ihevce_function_selector.h"
     86 #include "ihevce_enc_structs.h"
     87 #include "ihevce_entropy_structs.h"
     88 #include "ihevce_cmn_utils_instr_set_router.h"
     89 #include "ihevce_ipe_instr_set_router.h"
     90 #include "ihevce_decomp_pre_intra_structs.h"
     91 #include "ihevce_decomp_pre_intra_pass.h"
     92 #include "ihevce_enc_loop_structs.h"
     93 #include "ihevce_global_tables.h"
     94 #include "ihevce_nbr_avail.h"
     95 #include "ihevce_enc_loop_utils.h"
     96 #include "ihevce_bs_compute_ctb.h"
     97 #include "ihevce_cabac_rdo.h"
     98 #include "ihevce_dep_mngr_interface.h"
     99 #include "ihevce_enc_loop_pass.h"
    100 #include "ihevce_rc_enc_structs.h"
    101 #include "ihevce_common_utils.h"
    102 #include "ihevce_stasino_helpers.h"
    103 
    104 #include "hme_datatype.h"
    105 #include "hme_common_defs.h"
    106 #include "hme_common_utils.h"
    107 #include "hme_interface.h"
    108 #include "hme_defs.h"
    109 #include "ihevce_me_instr_set_router.h"
    110 #include "hme_err_compute.h"
    111 #include "hme_globals.h"
    112 #include "ihevce_mv_pred.h"
    113 #include "ihevce_mv_pred_merge.h"
    114 #include "ihevce_inter_pred.h"
    115 #include "ihevce_enc_loop_inter_mode_sifter.h"
    116 
    117 /*****************************************************************************/
    118 /* Function Definitions                                                      */
    119 /*****************************************************************************/
    120 static WORD32 ihevce_get_num_part_types_in_me_cand_list(
    121     cu_inter_cand_t *ps_me_cand_list,
    122     UWORD8 *pu1_part_type_ref_cand,
    123     UWORD8 *pu1_idx_ref_cand,
    124     UWORD8 *pu1_diff_skip_cand_flag,
    125     WORD8 *pi1_skip_cand_from_merge_idx,
    126     WORD8 *pi1_final_skip_cand_merge_idx,
    127     UWORD8 u1_max_num_part_types_to_select,
    128     UWORD8 u1_num_me_cands)
    129 {
    130     UWORD8 i, j;
    131     UWORD8 u1_num_unique_parts = 0;
    132 
    133     for(i = 0; i < u1_num_me_cands; i++)
    134     {
    135         UWORD8 u1_cur_part_type = ps_me_cand_list[i].b3_part_size;
    136         UWORD8 u1_is_unique = 1;
    137 
    138         if(u1_num_unique_parts >= u1_max_num_part_types_to_select)
    139         {
    140             return u1_num_unique_parts;
    141         }
    142 
    143         /* loop to check if the current cand is already present in the list */
    144         for(j = 0; j < u1_num_unique_parts; j++)
    145         {
    146             if(u1_cur_part_type == pu1_part_type_ref_cand[j])
    147             {
    148                 u1_is_unique = 0;
    149                 break;
    150             }
    151         }
    152 
    153         if(u1_is_unique)
    154         {
    155             if(SIZE_2Nx2N == u1_cur_part_type)
    156             {
    157                 *pu1_diff_skip_cand_flag = 0;
    158                 *pi1_skip_cand_from_merge_idx = u1_num_unique_parts;
    159                 *pi1_final_skip_cand_merge_idx = u1_num_unique_parts;
    160             }
    161 
    162             pu1_part_type_ref_cand[u1_num_unique_parts] = u1_cur_part_type;
    163             pu1_idx_ref_cand[u1_num_unique_parts] = i;
    164             u1_num_unique_parts++;
    165         }
    166     }
    167 
    168     return u1_num_unique_parts;
    169 }
    170 
    171 static WORD32 ihevce_compute_inter_pred_and_cost(
    172     inter_pred_ctxt_t *ps_mc_ctxt,
    173     PF_LUMA_INTER_PRED_PU pf_luma_inter_pred_pu,
    174     PF_SAD_FXN_T pf_sad_func,
    175     pu_t *ps_pu,
    176     void *pv_src,
    177     void *pv_pred,
    178     WORD32 i4_src_stride,
    179     WORD32 i4_pred_stride,
    180     UWORD8 u1_compute_error,
    181     ihevce_cmn_opt_func_t *ps_cmn_utils_optimised_function_list)
    182 {
    183     IV_API_CALL_STATUS_T u1_is_valid_mv;
    184     WORD32 i4_error;
    185 
    186     u1_is_valid_mv = pf_luma_inter_pred_pu(ps_mc_ctxt, ps_pu, pv_pred, i4_pred_stride, 0);
    187 
    188     if(u1_compute_error)
    189     {
    190         if(IV_SUCCESS == u1_is_valid_mv)
    191         {
    192             err_prms_t s_err_prms;
    193 
    194             s_err_prms.i4_blk_ht = (ps_pu->b4_ht + 1) << 2;
    195             s_err_prms.i4_blk_wd = (ps_pu->b4_wd + 1) << 2;
    196             s_err_prms.pu1_inp = (UWORD8 *)pv_src;
    197             s_err_prms.pu2_inp = (UWORD16 *)pv_src;
    198             s_err_prms.pu1_ref = (UWORD8 *)pv_pred;
    199             s_err_prms.pu2_ref = (UWORD16 *)pv_pred;
    200             s_err_prms.i4_inp_stride = i4_src_stride;
    201             s_err_prms.i4_ref_stride = i4_pred_stride;
    202             s_err_prms.pi4_sad_grid = &i4_error;
    203 
    204             s_err_prms.ps_cmn_utils_optimised_function_list = ps_cmn_utils_optimised_function_list;
    205 
    206             pf_sad_func(&s_err_prms);
    207         }
    208         else
    209         {
    210             /* max 32 bit satd */
    211             i4_error = INT_MAX;
    212         }
    213 
    214         return i4_error;
    215     }
    216 
    217     return INT_MAX;
    218 }
    219 
    220 static WORD32 ihevce_determine_best_merge_pu(
    221     merge_prms_t *ps_prms,
    222     pu_t *ps_pu_merge,
    223     pu_t *ps_pu_me,
    224     void *pv_src,
    225     WORD32 i4_me_cand_cost,
    226     WORD32 i4_pred_buf_offset,
    227     UWORD8 u1_num_cands,
    228     UWORD8 u1_part_id,
    229     UWORD8 u1_force_pred_evaluation)
    230 {
    231     pu_t *ps_pu;
    232 
    233     INTER_CANDIDATE_ID_T e_cand_id;
    234 
    235     UWORD8 i;
    236     UWORD8 u1_best_pred_mode;
    237     WORD32 i4_mean;
    238     UWORD32 u4_cur_variance, u4_best_variance;
    239 
    240     merge_cand_list_t *ps_list = ps_prms->ps_list;
    241     inter_pred_ctxt_t *ps_mc_ctxt = ps_prms->ps_mc_ctxt;
    242     PF_LUMA_INTER_PRED_PU pf_luma_inter_pred_pu = ps_prms->pf_luma_inter_pred_pu;
    243     PF_SAD_FXN_T pf_sad_fxn = ps_prms->pf_sad_fxn;
    244 
    245     ihevce_cmn_opt_func_t *ps_cmn_utils_optimised_function_list =
    246         ps_prms->ps_cmn_utils_optimised_function_list;
    247 
    248     WORD32(*pai4_noise_term)[MAX_NUM_INTER_PARTS] = ps_prms->pai4_noise_term;
    249     UWORD32(*pau4_pred_variance)[MAX_NUM_INTER_PARTS] = ps_prms->pau4_pred_variance;
    250     WORD32 i4_alpha_stim_multiplier = ps_prms->i4_alpha_stim_multiplier;
    251     UWORD32 *pu4_src_variance = ps_prms->pu4_src_variance;
    252     UWORD8 u1_is_cu_noisy = ps_prms->u1_is_cu_noisy;
    253     UWORD8 u1_is_hbd = ps_prms->u1_is_hbd;
    254     UWORD8 *pu1_valid_merge_indices = ps_prms->au1_valid_merge_indices;
    255     void **ppv_pred_buf_list = ps_prms->ppv_pred_buf_list;
    256     UWORD8 *pu1_merge_pred_buf_array = ps_prms->pu1_merge_pred_buf_array;
    257     UWORD8(*pau1_best_pred_buf_id)[MAX_NUM_INTER_PARTS] = ps_prms->pau1_best_pred_buf_id;
    258     UWORD8 u1_merge_idx_cabac_model = ps_prms->u1_merge_idx_cabac_model;
    259     WORD32 i4_lambda = ps_prms->i4_lambda;
    260     WORD32 i4_src_stride = ps_prms->i4_src_stride;
    261     WORD32 i4_pred_stride = ps_prms->i4_pred_stride;
    262     UWORD8 u1_max_cands = ps_prms->u1_max_cands;
    263     UWORD8 u1_best_buf_id = pu1_merge_pred_buf_array[0];
    264     UWORD8 u1_cur_buf_id = pu1_merge_pred_buf_array[1];
    265     UWORD8 u1_best_cand_id = UCHAR_MAX;
    266     WORD32 i4_best_cost = INT_MAX;
    267     WORD32 i4_cur_noise_term = 0;
    268     WORD32 i4_best_noise_term = 0;
    269 
    270     ps_pu = ps_pu_merge;
    271     e_cand_id = MERGE_DERIVED;
    272 
    273     ASSERT(ps_pu->b1_merge_flag);
    274 
    275     for(i = 0; i < u1_num_cands; i++)
    276     {
    277         WORD32 i4_cur_cost;
    278 
    279         void *pv_pred = (UWORD8 *)ppv_pred_buf_list[u1_cur_buf_id] + i4_pred_buf_offset;
    280         UWORD8 u1_is_pred_available = 0;
    281 
    282         if(!ps_prms->u1_use_merge_cand_from_top_row && ps_prms->pu1_is_top_used[i])
    283         {
    284             continue;
    285         }
    286 
    287         ps_pu->mv = ps_list[i].mv;
    288         ps_pu->b3_merge_idx = pu1_valid_merge_indices[i];
    289 
    290         /* set the prediction mode */
    291         if(ps_list[i].u1_pred_flag_l0 && ps_list[i].u1_pred_flag_l1)
    292         {
    293             ps_pu->b2_pred_mode = PRED_BI;
    294         }
    295         else if(ps_list[i].u1_pred_flag_l0)
    296         {
    297             ps_pu->b2_pred_mode = PRED_L0;
    298         }
    299         else
    300         {
    301             ps_pu->b2_pred_mode = PRED_L1;
    302         }
    303 
    304         /* 8x8 SMPs should not have bipred mode as per std */
    305         {
    306             WORD32 i4_part_wd, i4_part_ht;
    307 
    308             i4_part_wd = (ps_pu->b4_wd + 1) << 2;
    309             i4_part_ht = (ps_pu->b4_ht + 1) << 2;
    310 
    311             if((PRED_BI == ps_pu->b2_pred_mode) && ((i4_part_wd + i4_part_ht) < 16))
    312             {
    313                 continue;
    314             }
    315         }
    316 
    317         if((!u1_force_pred_evaluation) &&
    318            (ihevce_compare_pu_mv_t(
    319                &ps_pu->mv, &ps_pu_me->mv, ps_pu->b2_pred_mode, ps_pu_me->b2_pred_mode)))
    320         {
    321             i4_cur_cost = i4_me_cand_cost;
    322             u1_is_pred_available = 1;
    323 
    324             if((i4_cur_cost < INT_MAX) && u1_is_cu_noisy && i4_alpha_stim_multiplier)
    325             {
    326                 i4_cur_noise_term = pai4_noise_term[ME_OR_SKIP_DERIVED][u1_part_id];
    327                 u4_cur_variance = pau4_pred_variance[ME_OR_SKIP_DERIVED][u1_part_id];
    328             }
    329         }
    330         else
    331         {
    332             i4_cur_cost = ihevce_compute_inter_pred_and_cost(
    333                 ps_mc_ctxt,
    334                 pf_luma_inter_pred_pu,
    335                 pf_sad_fxn,
    336                 ps_pu,
    337                 pv_src,
    338                 pv_pred,
    339                 i4_src_stride,
    340                 i4_pred_stride,
    341                 1,
    342                 ps_cmn_utils_optimised_function_list);
    343 
    344             if((i4_cur_cost < INT_MAX) && u1_is_cu_noisy && i4_alpha_stim_multiplier)
    345             {
    346                 ihevce_calc_variance(
    347                     pv_pred,
    348                     i4_pred_stride,
    349                     &i4_mean,
    350                     &u4_cur_variance,
    351                     (ps_pu->b4_ht + 1) << 2,
    352                     (ps_pu->b4_wd + 1) << 2,
    353                     u1_is_hbd,
    354                     0);
    355 
    356                 i4_cur_noise_term = ihevce_compute_noise_term(
    357                     i4_alpha_stim_multiplier, pu4_src_variance[u1_part_id], u4_cur_variance);
    358 
    359                 MULTIPLY_STIM_WITH_DISTORTION(
    360                     i4_cur_cost, i4_cur_noise_term, STIM_Q_FORMAT, ALPHA_Q_FORMAT);
    361             }
    362         }
    363 
    364         if(i4_cur_cost < INT_MAX)
    365         {
    366             WORD32 i4_merge_idx_cost = 0;
    367             COMPUTE_MERGE_IDX_COST(
    368                 u1_merge_idx_cabac_model, i, u1_max_cands, i4_lambda, i4_merge_idx_cost);
    369             i4_cur_cost += i4_merge_idx_cost;
    370         }
    371 
    372         if(i4_cur_cost < i4_best_cost)
    373         {
    374             i4_best_cost = i4_cur_cost;
    375 
    376             if(u1_is_cu_noisy && i4_alpha_stim_multiplier)
    377             {
    378                 i4_best_noise_term = i4_cur_noise_term;
    379                 u4_best_variance = u4_cur_variance;
    380             }
    381 
    382             u1_best_cand_id = i;
    383             u1_best_pred_mode = ps_pu->b2_pred_mode;
    384 
    385             if(u1_is_pred_available)
    386             {
    387                 pau1_best_pred_buf_id[e_cand_id][u1_part_id] =
    388                     pau1_best_pred_buf_id[ME_OR_SKIP_DERIVED][u1_part_id];
    389             }
    390             else
    391             {
    392                 SWAP(u1_best_buf_id, u1_cur_buf_id);
    393                 pau1_best_pred_buf_id[e_cand_id][u1_part_id] = u1_best_buf_id;
    394             }
    395         }
    396     }
    397 
    398     if(u1_best_cand_id != UCHAR_MAX)
    399     {
    400         ps_pu->mv = ps_list[u1_best_cand_id].mv;
    401         ps_pu->b2_pred_mode = u1_best_pred_mode;
    402         ps_pu->b3_merge_idx = pu1_valid_merge_indices[u1_best_cand_id];
    403 
    404         if(u1_is_cu_noisy && i4_alpha_stim_multiplier)
    405         {
    406             pai4_noise_term[MERGE_DERIVED][u1_part_id] = i4_best_noise_term;
    407             pau4_pred_variance[MERGE_DERIVED][u1_part_id] = u4_best_variance;
    408         }
    409     }
    410 
    411     return i4_best_cost;
    412 }
    413 
    414 static WORD8 ihevce_merge_cand_pred_buffer_preparation(
    415     void **ppv_pred_buf_list,
    416     cu_inter_cand_t *ps_cand,
    417     UWORD8 (*pau1_final_pred_buf_id)[MAX_NUM_INTER_PARTS],
    418     WORD32 i4_pred_stride,
    419     UWORD8 u1_cu_size,
    420     UWORD8 u1_part_type,
    421     UWORD8 u1_num_bytes_per_pel,
    422     FT_COPY_2D *pf_copy_2d)
    423 {
    424     WORD32 i4_part_wd;
    425     WORD32 i4_part_ht;
    426     WORD32 i4_part_wd_pu2;
    427     WORD32 i4_part_ht_pu2;
    428     WORD32 i4_buf_offset;
    429     UWORD8 *pu1_pred_src;
    430     UWORD8 *pu1_pred_dst;
    431     WORD8 i1_retval = pau1_final_pred_buf_id[MERGE_DERIVED][0];
    432 
    433     WORD32 i4_stride = i4_pred_stride * u1_num_bytes_per_pel;
    434 
    435     if((0 == u1_part_type) ||
    436        (pau1_final_pred_buf_id[MERGE_DERIVED][0] == pau1_final_pred_buf_id[MERGE_DERIVED][1]))
    437     {
    438         ps_cand->pu1_pred_data =
    439             (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][0]];
    440         ps_cand->pu2_pred_data =
    441             (UWORD16 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][0]];
    442         ps_cand->i4_pred_data_stride = i4_pred_stride;
    443 
    444         i1_retval = pau1_final_pred_buf_id[MERGE_DERIVED][0];
    445     }
    446     else if(pau1_final_pred_buf_id[MERGE_DERIVED][0] == pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0])
    447     {
    448         i4_part_wd = (ps_cand->as_inter_pu[0].b4_wd + 1) << 2;
    449         i4_part_ht = (ps_cand->as_inter_pu[0].b4_ht + 1) << 2;
    450 
    451         i4_buf_offset = 0;
    452 
    453         pu1_pred_src = (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0]] +
    454                        i4_buf_offset;
    455         pu1_pred_dst =
    456             (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][1]] + i4_buf_offset;
    457 
    458         pf_copy_2d(
    459             pu1_pred_dst,
    460             i4_stride,
    461             pu1_pred_src,
    462             i4_stride,
    463             i4_part_wd * u1_num_bytes_per_pel,
    464             i4_part_ht);
    465 
    466         ps_cand->pu1_pred_data =
    467             (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][1]];
    468         ps_cand->pu2_pred_data =
    469             (UWORD16 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][1]];
    470         ps_cand->i4_pred_data_stride = i4_pred_stride;
    471 
    472         i1_retval = pau1_final_pred_buf_id[MERGE_DERIVED][1];
    473     }
    474     else if(pau1_final_pred_buf_id[MERGE_DERIVED][1] == pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][1])
    475     {
    476         i4_part_wd = (ps_cand->as_inter_pu[0].b4_wd + 1) << 2;
    477         i4_part_ht = (ps_cand->as_inter_pu[0].b4_ht + 1) << 2;
    478 
    479         i4_buf_offset = (i4_part_ht < u1_cu_size) * i4_part_ht * i4_pred_stride +
    480                         (i4_part_wd < u1_cu_size) * i4_part_wd;
    481 
    482         i4_buf_offset *= u1_num_bytes_per_pel;
    483 
    484         i4_part_wd = (ps_cand->as_inter_pu[1].b4_wd + 1) << 2;
    485         i4_part_ht = (ps_cand->as_inter_pu[1].b4_ht + 1) << 2;
    486 
    487         pu1_pred_src = (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][1]] +
    488                        i4_buf_offset;
    489         pu1_pred_dst =
    490             (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][0]] + i4_buf_offset;
    491 
    492         pf_copy_2d(
    493             pu1_pred_dst,
    494             i4_stride,
    495             pu1_pred_src,
    496             i4_stride,
    497             i4_part_wd * u1_num_bytes_per_pel,
    498             i4_part_ht);
    499 
    500         ps_cand->pu1_pred_data =
    501             (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][0]];
    502         ps_cand->pu2_pred_data =
    503             (UWORD16 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][0]];
    504         ps_cand->i4_pred_data_stride = i4_pred_stride;
    505 
    506         i1_retval = pau1_final_pred_buf_id[MERGE_DERIVED][0];
    507     }
    508     else
    509     {
    510         i4_part_wd = (ps_cand->as_inter_pu[0].b4_wd + 1) << 2;
    511         i4_part_ht = (ps_cand->as_inter_pu[0].b4_ht + 1) << 2;
    512 
    513         i4_part_wd_pu2 = (ps_cand->as_inter_pu[1].b4_wd + 1) << 2;
    514         i4_part_ht_pu2 = (ps_cand->as_inter_pu[1].b4_ht + 1) << 2;
    515 
    516         switch((PART_TYPE_T)u1_part_type)
    517         {
    518         case PRT_2NxN:
    519         case PRT_Nx2N:
    520         case PRT_2NxnU:
    521         case PRT_nLx2N:
    522         {
    523             pu1_pred_src = (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][0]];
    524             pu1_pred_dst = (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][1]];
    525 
    526             ps_cand->pu1_pred_data =
    527                 (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][1]];
    528             ps_cand->pu2_pred_data =
    529                 (UWORD16 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][1]];
    530 
    531             i1_retval = pau1_final_pred_buf_id[MERGE_DERIVED][1];
    532 
    533             break;
    534         }
    535         case PRT_nRx2N:
    536         case PRT_2NxnD:
    537         {
    538             i4_buf_offset = (i4_part_ht < u1_cu_size) * i4_part_ht * i4_pred_stride +
    539                             (i4_part_wd < u1_cu_size) * i4_part_wd;
    540 
    541             i4_buf_offset *= u1_num_bytes_per_pel;
    542 
    543             pu1_pred_src = (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][1]] +
    544                            i4_buf_offset;
    545             pu1_pred_dst = (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][0]] +
    546                            i4_buf_offset;
    547 
    548             i4_part_wd = i4_part_wd_pu2;
    549             i4_part_ht = i4_part_ht_pu2;
    550 
    551             ps_cand->pu1_pred_data =
    552                 (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][0]];
    553             ps_cand->pu2_pred_data =
    554                 (UWORD16 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][0]];
    555 
    556             i1_retval = pau1_final_pred_buf_id[MERGE_DERIVED][0];
    557 
    558             break;
    559         }
    560         }
    561 
    562         pf_copy_2d(
    563             pu1_pred_dst,
    564             i4_stride,
    565             pu1_pred_src,
    566             i4_stride,
    567             i4_part_wd * u1_num_bytes_per_pel,
    568             i4_part_ht);
    569 
    570         ps_cand->i4_pred_data_stride = i4_pred_stride;
    571     }
    572 
    573     return i1_retval;
    574 }
    575 
    576 static WORD8 ihevce_mixed_mode_cand_type1_pred_buffer_preparation(
    577     void **ppv_pred_buf_list,
    578     cu_inter_cand_t *ps_cand,
    579     UWORD8 (*pau1_final_pred_buf_id)[MAX_NUM_INTER_PARTS],
    580     UWORD8 *pu1_merge_pred_buf_idx_array,
    581     WORD32 i4_pred_stride,
    582     UWORD8 u1_me_pred_buf_id,
    583     UWORD8 u1_merge_pred_buf_id,
    584     UWORD8 u1_type0_cand_is_valid,
    585     UWORD8 u1_cu_size,
    586     UWORD8 u1_part_type,
    587     UWORD8 u1_num_bytes_per_pel,
    588     FT_COPY_2D *pf_copy_2d)
    589 {
    590     WORD32 i4_part_wd;
    591     WORD32 i4_part_ht;
    592     WORD32 i4_part_wd_pu2;
    593     WORD32 i4_part_ht_pu2;
    594     UWORD8 *pu1_pred_src;
    595     UWORD8 *pu1_pred_dst = NULL;
    596     WORD8 i1_retval = pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0];
    597 
    598     WORD32 i4_stride = i4_pred_stride * u1_num_bytes_per_pel;
    599 
    600     ASSERT(0 != u1_part_type);
    601 
    602     i4_part_wd = (ps_cand->as_inter_pu[0].b4_wd + 1) << 2;
    603     i4_part_ht = (ps_cand->as_inter_pu[0].b4_ht + 1) << 2;
    604 
    605     i4_part_wd_pu2 = (ps_cand->as_inter_pu[1].b4_wd + 1) << 2;
    606     i4_part_ht_pu2 = (ps_cand->as_inter_pu[1].b4_ht + 1) << 2;
    607 
    608     if(pau1_final_pred_buf_id[MIXED_MODE_TYPE1][1] == pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][1])
    609     {
    610         ps_cand->pu1_pred_data =
    611             (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0]];
    612         ps_cand->pu2_pred_data =
    613             (UWORD16 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0]];
    614         ps_cand->i4_pred_data_stride = i4_pred_stride;
    615 
    616         i1_retval = pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0];
    617 
    618         return i1_retval;
    619     }
    620     else
    621     {
    622         UWORD8 u1_bitfield = ((u1_merge_pred_buf_id == UCHAR_MAX) << 3) |
    623                              ((u1_me_pred_buf_id == UCHAR_MAX) << 2) |
    624                              ((!u1_type0_cand_is_valid) << 1) |
    625                              (pau1_final_pred_buf_id[MIXED_MODE_TYPE1][1] ==
    626                               pau1_final_pred_buf_id[MERGE_DERIVED][1]);
    627 
    628         WORD32 i4_buf_offset = (i4_part_ht < u1_cu_size) * i4_part_ht * i4_pred_stride +
    629                                (i4_part_wd < u1_cu_size) * i4_part_wd;
    630 
    631         i4_buf_offset *= u1_num_bytes_per_pel;
    632 
    633         switch(u1_bitfield)
    634         {
    635         case 15:
    636         case 14:
    637         case 6:
    638         {
    639             switch((PART_TYPE_T)u1_part_type)
    640             {
    641             case PRT_2NxN:
    642             case PRT_Nx2N:
    643             case PRT_2NxnU:
    644             case PRT_nLx2N:
    645             {
    646                 pu1_pred_src =
    647                     (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0]];
    648                 pu1_pred_dst =
    649                     (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MIXED_MODE_TYPE1][1]];
    650 
    651                 i1_retval = pau1_final_pred_buf_id[MIXED_MODE_TYPE1][1];
    652 
    653                 break;
    654             }
    655             case PRT_nRx2N:
    656             case PRT_2NxnD:
    657             {
    658                 pu1_pred_src =
    659                     (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MIXED_MODE_TYPE1][1]] +
    660                     i4_buf_offset;
    661                 pu1_pred_dst =
    662                     (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0]] +
    663                     i4_buf_offset;
    664 
    665                 i4_part_wd = i4_part_wd_pu2;
    666                 i4_part_ht = i4_part_ht_pu2;
    667 
    668                 i1_retval = pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0];
    669 
    670                 break;
    671             }
    672             }
    673 
    674             ps_cand->pu1_pred_data = (UWORD8 *)ppv_pred_buf_list[i1_retval];
    675             ps_cand->pu2_pred_data = (UWORD16 *)ppv_pred_buf_list[i1_retval];
    676             ps_cand->i4_pred_data_stride = i4_pred_stride;
    677 
    678             pf_copy_2d(
    679                 pu1_pred_dst,
    680                 i4_stride,
    681                 pu1_pred_src,
    682                 i4_stride,
    683                 i4_part_wd * u1_num_bytes_per_pel,
    684                 i4_part_ht);
    685 
    686             break;
    687         }
    688         case 13:
    689         case 9:
    690         case 5:
    691         {
    692             UWORD8 i;
    693 
    694             for(i = 0; i < 3; i++)
    695             {
    696                 if((pu1_merge_pred_buf_idx_array[i] != pau1_final_pred_buf_id[MERGE_DERIVED][1]) &&
    697                    (pu1_merge_pred_buf_idx_array[i] != pau1_final_pred_buf_id[MERGE_DERIVED][0]))
    698                 {
    699                     pu1_pred_dst = (UWORD8 *)ppv_pred_buf_list[pu1_merge_pred_buf_idx_array[i]] +
    700                                    i4_buf_offset;
    701 
    702                     i1_retval = pu1_merge_pred_buf_idx_array[i];
    703 
    704                     break;
    705                 }
    706             }
    707 
    708             pu1_pred_src = (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][1]] +
    709                            i4_buf_offset;
    710 
    711             pf_copy_2d(
    712                 pu1_pred_dst,
    713                 i4_stride,
    714                 pu1_pred_src,
    715                 i4_stride,
    716                 i4_part_wd_pu2 * u1_num_bytes_per_pel,
    717                 i4_part_ht_pu2);
    718             /* Copy PU1 */
    719             pu1_pred_src =
    720                 (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0]];
    721             pu1_pred_dst = (UWORD8 *)ppv_pred_buf_list[i1_retval];
    722 
    723             pf_copy_2d(
    724                 pu1_pred_dst,
    725                 i4_stride,
    726                 pu1_pred_src,
    727                 i4_stride,
    728                 i4_part_wd * u1_num_bytes_per_pel,
    729                 i4_part_ht);
    730 
    731             ps_cand->pu1_pred_data = (UWORD8 *)ppv_pred_buf_list[i1_retval];
    732             ps_cand->pu2_pred_data = (UWORD16 *)ppv_pred_buf_list[i1_retval];
    733             ps_cand->i4_pred_data_stride = i4_pred_stride;
    734 
    735             break;
    736         }
    737         case 12:
    738         case 10:
    739         case 8:
    740         case 4:
    741         case 2:
    742         case 0:
    743         {
    744             pu1_pred_src =
    745                 (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0]];
    746             pu1_pred_dst = (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MIXED_MODE_TYPE1][1]];
    747 
    748             i1_retval = pau1_final_pred_buf_id[MIXED_MODE_TYPE1][1];
    749 
    750             ps_cand->pu1_pred_data = (UWORD8 *)ppv_pred_buf_list[i1_retval];
    751             ps_cand->pu2_pred_data = (UWORD16 *)ppv_pred_buf_list[i1_retval];
    752             ps_cand->i4_pred_data_stride = i4_pred_stride;
    753 
    754             pf_copy_2d(
    755                 pu1_pred_dst,
    756                 i4_stride,
    757                 pu1_pred_src,
    758                 i4_stride,
    759                 i4_part_wd * u1_num_bytes_per_pel,
    760                 i4_part_ht);
    761 
    762             break;
    763         }
    764         case 11:
    765         {
    766             pu1_pred_src =
    767                 (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0]];
    768             pu1_pred_dst = (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][1]];
    769 
    770             i1_retval = pau1_final_pred_buf_id[MERGE_DERIVED][1];
    771 
    772             ps_cand->pu1_pred_data = (UWORD8 *)ppv_pred_buf_list[i1_retval];
    773             ps_cand->pu2_pred_data = (UWORD16 *)ppv_pred_buf_list[i1_retval];
    774             ps_cand->i4_pred_data_stride = i4_pred_stride;
    775 
    776             pf_copy_2d(
    777                 pu1_pred_dst,
    778                 i4_stride,
    779                 pu1_pred_src,
    780                 i4_stride,
    781                 i4_part_wd * u1_num_bytes_per_pel,
    782                 i4_part_ht);
    783 
    784             break;
    785         }
    786         case 7:
    787         {
    788             pu1_pred_src = (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][1]] +
    789                            i4_buf_offset;
    790             pu1_pred_dst =
    791                 (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][1]] +
    792                 i4_buf_offset;
    793 
    794             i1_retval = pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][1];
    795 
    796             ps_cand->pu1_pred_data = (UWORD8 *)ppv_pred_buf_list[i1_retval];
    797             ps_cand->pu2_pred_data = (UWORD16 *)ppv_pred_buf_list[i1_retval];
    798             ps_cand->i4_pred_data_stride = i4_pred_stride;
    799 
    800             pf_copy_2d(
    801                 pu1_pred_dst,
    802                 i4_stride,
    803                 pu1_pred_src,
    804                 i4_stride,
    805                 i4_part_wd_pu2 * u1_num_bytes_per_pel,
    806                 i4_part_ht_pu2);
    807 
    808             break;
    809         }
    810         case 3:
    811         case 1:
    812         {
    813             if((u1_merge_pred_buf_id == pau1_final_pred_buf_id[MERGE_DERIVED][0]) &&
    814                (u1_merge_pred_buf_id != pau1_final_pred_buf_id[MERGE_DERIVED][1]))
    815             {
    816                 pu1_pred_src =
    817                     (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0]];
    818                 pu1_pred_dst =
    819                     (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][1]];
    820 
    821                 i1_retval = pau1_final_pred_buf_id[MERGE_DERIVED][1];
    822 
    823                 ps_cand->pu1_pred_data = (UWORD8 *)ppv_pred_buf_list[i1_retval];
    824                 ps_cand->pu2_pred_data = (UWORD16 *)ppv_pred_buf_list[i1_retval];
    825                 ps_cand->i4_pred_data_stride = i4_pred_stride;
    826 
    827                 pf_copy_2d(
    828                     pu1_pred_dst,
    829                     i4_stride,
    830                     pu1_pred_src,
    831                     i4_stride,
    832                     i4_part_wd * u1_num_bytes_per_pel,
    833                     i4_part_ht);
    834             }
    835             else
    836             {
    837                 UWORD8 i;
    838 
    839                 for(i = 0; i < 3; i++)
    840                 {
    841                     if((pu1_merge_pred_buf_idx_array[i] !=
    842                         pau1_final_pred_buf_id[MERGE_DERIVED][1]) &&
    843                        (pu1_merge_pred_buf_idx_array[i] !=
    844                         pau1_final_pred_buf_id[MERGE_DERIVED][0]))
    845                     {
    846                         pu1_pred_dst =
    847                             (UWORD8 *)ppv_pred_buf_list[pu1_merge_pred_buf_idx_array[i]] +
    848                             i4_buf_offset;
    849 
    850                         i1_retval = pu1_merge_pred_buf_idx_array[i];
    851 
    852                         break;
    853                     }
    854                 }
    855 
    856                 pu1_pred_src =
    857                     (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][1]] +
    858                     i4_buf_offset;
    859 
    860                 pf_copy_2d(
    861                     pu1_pred_dst,
    862                     i4_stride,
    863                     pu1_pred_src,
    864                     i4_stride,
    865                     i4_part_wd_pu2 * u1_num_bytes_per_pel,
    866                     i4_part_ht_pu2);
    867 
    868                 /* Copy PU1 */
    869                 pu1_pred_src =
    870                     (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0]];
    871                 pu1_pred_dst = (UWORD8 *)ppv_pred_buf_list[i1_retval];
    872 
    873                 pf_copy_2d(
    874                     pu1_pred_dst,
    875                     i4_stride,
    876                     pu1_pred_src,
    877                     i4_stride,
    878                     i4_part_wd * u1_num_bytes_per_pel,
    879                     i4_part_ht);
    880 
    881                 ps_cand->pu1_pred_data = (UWORD8 *)ppv_pred_buf_list[i1_retval];
    882                 ps_cand->pu2_pred_data = (UWORD16 *)ppv_pred_buf_list[i1_retval];
    883                 ps_cand->i4_pred_data_stride = i4_pred_stride;
    884 
    885                 break;
    886             }
    887         }
    888         }
    889     }
    890 
    891     return i1_retval;
    892 }
    893 
    894 static WORD8 ihevce_mixed_mode_cand_type0_pred_buffer_preparation(
    895     void **ppv_pred_buf_list,
    896     cu_inter_cand_t *ps_cand,
    897     UWORD8 (*pau1_final_pred_buf_id)[MAX_NUM_INTER_PARTS],
    898     UWORD8 *pu1_merge_pred_buf_idx_array,
    899     UWORD8 u1_me_pred_buf_id,
    900     UWORD8 u1_merge_pred_buf_id,
    901     UWORD8 u1_mixed_tyep1_pred_buf_id,
    902     WORD32 i4_pred_stride,
    903     UWORD8 u1_cu_size,
    904     UWORD8 u1_part_type,
    905     UWORD8 u1_num_bytes_per_pel,
    906     FT_COPY_2D *pf_copy_2d)
    907 {
    908     WORD32 i4_part_wd;
    909     WORD32 i4_part_ht;
    910     WORD32 i4_part_wd_pu2;
    911     WORD32 i4_part_ht_pu2;
    912     WORD32 i4_buf_offset;
    913     UWORD8 *pu1_pred_src;
    914     UWORD8 *pu1_pred_dst = NULL;
    915     WORD8 i1_retval = pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0];
    916 
    917     WORD32 i4_stride = i4_pred_stride * u1_num_bytes_per_pel;
    918 
    919     ASSERT(0 != u1_part_type);
    920 
    921     i4_part_wd = (ps_cand->as_inter_pu[0].b4_wd + 1) << 2;
    922     i4_part_ht = (ps_cand->as_inter_pu[0].b4_ht + 1) << 2;
    923     i4_part_wd_pu2 = (ps_cand->as_inter_pu[1].b4_wd + 1) << 2;
    924     i4_part_ht_pu2 = (ps_cand->as_inter_pu[1].b4_ht + 1) << 2;
    925 
    926     i4_buf_offset = (i4_part_ht < u1_cu_size) * i4_part_ht * i4_pred_stride +
    927                     (i4_part_wd < u1_cu_size) * i4_part_wd;
    928 
    929     i4_buf_offset *= u1_num_bytes_per_pel;
    930 
    931     if(pau1_final_pred_buf_id[MIXED_MODE_TYPE0][0] == pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0])
    932     {
    933         ps_cand->pu1_pred_data =
    934             (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0]];
    935         ps_cand->pu2_pred_data =
    936             (UWORD16 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0]];
    937         ps_cand->i4_pred_data_stride = i4_pred_stride;
    938 
    939         i1_retval = pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0];
    940     }
    941     else
    942     {
    943         UWORD8 u1_bitfield =
    944             ((u1_merge_pred_buf_id == UCHAR_MAX) << 2) | ((u1_me_pred_buf_id == UCHAR_MAX) << 1) |
    945             (u1_mixed_tyep1_pred_buf_id != pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0]);
    946 
    947         switch(u1_bitfield)
    948         {
    949         case 7:
    950         {
    951             switch((PART_TYPE_T)u1_part_type)
    952             {
    953             case PRT_2NxN:
    954             case PRT_Nx2N:
    955             case PRT_2NxnU:
    956             case PRT_nLx2N:
    957             {
    958                 pu1_pred_src =
    959                     (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MIXED_MODE_TYPE0][0]];
    960                 pu1_pred_dst =
    961                     (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][1]];
    962 
    963                 i1_retval = pau1_final_pred_buf_id[MIXED_MODE_TYPE0][1];
    964 
    965                 break;
    966             }
    967             case PRT_nRx2N:
    968             case PRT_2NxnD:
    969             {
    970                 pu1_pred_src =
    971                     (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][1]] +
    972                     i4_buf_offset;
    973                 pu1_pred_dst =
    974                     (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MIXED_MODE_TYPE0][0]] +
    975                     i4_buf_offset;
    976 
    977                 i4_part_wd = i4_part_wd_pu2;
    978                 i4_part_ht = i4_part_ht_pu2;
    979 
    980                 i1_retval = pau1_final_pred_buf_id[MIXED_MODE_TYPE0][0];
    981 
    982                 break;
    983             }
    984             }
    985 
    986             ps_cand->pu1_pred_data = (UWORD8 *)ppv_pred_buf_list[i1_retval];
    987             ps_cand->pu2_pred_data = (UWORD16 *)ppv_pred_buf_list[i1_retval];
    988             ps_cand->i4_pred_data_stride = i4_pred_stride;
    989 
    990             pf_copy_2d(
    991                 pu1_pred_dst,
    992                 i4_stride,
    993                 pu1_pred_src,
    994                 i4_stride,
    995                 i4_part_wd * u1_num_bytes_per_pel,
    996                 i4_part_ht);
    997 
    998             break;
    999         }
   1000         case 6:
   1001         case 5:
   1002         case 4:
   1003         {
   1004             pu1_pred_src =
   1005                 (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][1]] +
   1006                 i4_buf_offset;
   1007             pu1_pred_dst =
   1008                 (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MIXED_MODE_TYPE0][0]] +
   1009                 i4_buf_offset;
   1010 
   1011             i1_retval = pau1_final_pred_buf_id[MIXED_MODE_TYPE0][0];
   1012 
   1013             ps_cand->pu1_pred_data = (UWORD8 *)ppv_pred_buf_list[i1_retval];
   1014             ps_cand->pu2_pred_data = (UWORD16 *)ppv_pred_buf_list[i1_retval];
   1015             ps_cand->i4_pred_data_stride = i4_pred_stride;
   1016 
   1017             pf_copy_2d(
   1018                 pu1_pred_dst,
   1019                 i4_stride,
   1020                 pu1_pred_src,
   1021                 i4_stride,
   1022                 i4_part_wd_pu2 * u1_num_bytes_per_pel,
   1023                 i4_part_ht_pu2);
   1024             break;
   1025         }
   1026         case 3:
   1027         {
   1028             pu1_pred_src = (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MIXED_MODE_TYPE0][0]];
   1029             pu1_pred_dst =
   1030                 (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][1]];
   1031 
   1032             i1_retval = pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][1];
   1033 
   1034             ps_cand->pu1_pred_data = (UWORD8 *)ppv_pred_buf_list[i1_retval];
   1035             ps_cand->pu2_pred_data = (UWORD16 *)ppv_pred_buf_list[i1_retval];
   1036             ps_cand->i4_pred_data_stride = i4_pred_stride;
   1037 
   1038             pf_copy_2d(
   1039                 pu1_pred_dst,
   1040                 i4_stride,
   1041                 pu1_pred_src,
   1042                 i4_stride,
   1043                 i4_part_wd * u1_num_bytes_per_pel,
   1044                 i4_part_ht);
   1045 
   1046             break;
   1047         }
   1048         case 2:
   1049         case 1:
   1050         case 0:
   1051         {
   1052             if((u1_merge_pred_buf_id == pau1_final_pred_buf_id[MERGE_DERIVED][1]) &&
   1053                (u1_merge_pred_buf_id != pau1_final_pred_buf_id[MERGE_DERIVED][0]))
   1054             {
   1055                 pu1_pred_src =
   1056                     (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][1]] +
   1057                     i4_buf_offset;
   1058                 pu1_pred_dst =
   1059                     (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][0]] +
   1060                     i4_buf_offset;
   1061 
   1062                 i1_retval = pau1_final_pred_buf_id[MERGE_DERIVED][0];
   1063 
   1064                 ps_cand->pu1_pred_data = (UWORD8 *)ppv_pred_buf_list[i1_retval];
   1065                 ps_cand->pu2_pred_data = (UWORD16 *)ppv_pred_buf_list[i1_retval];
   1066                 ps_cand->i4_pred_data_stride = i4_pred_stride;
   1067 
   1068                 pf_copy_2d(
   1069                     pu1_pred_dst,
   1070                     i4_stride,
   1071                     pu1_pred_src,
   1072                     i4_stride,
   1073                     i4_part_wd_pu2 * u1_num_bytes_per_pel,
   1074                     i4_part_ht_pu2);
   1075             }
   1076             else
   1077             {
   1078                 UWORD8 i;
   1079 
   1080                 for(i = 0; i < 3; i++)
   1081                 {
   1082                     if((pu1_merge_pred_buf_idx_array[i] != u1_merge_pred_buf_id) &&
   1083                        (pu1_merge_pred_buf_idx_array[i] != u1_mixed_tyep1_pred_buf_id))
   1084                     {
   1085                         pu1_pred_dst =
   1086                             (UWORD8 *)ppv_pred_buf_list[pu1_merge_pred_buf_idx_array[i]] +
   1087                             i4_buf_offset;
   1088 
   1089                         i1_retval = pu1_merge_pred_buf_idx_array[i];
   1090 
   1091                         break;
   1092                     }
   1093                 }
   1094 
   1095                 pu1_pred_src =
   1096                     (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][1]] +
   1097                     i4_buf_offset;
   1098 
   1099                 pf_copy_2d(
   1100                     pu1_pred_dst,
   1101                     i4_stride,
   1102                     pu1_pred_src,
   1103                     i4_stride,
   1104                     i4_part_wd_pu2 * u1_num_bytes_per_pel,
   1105                     i4_part_ht_pu2);
   1106 
   1107                 /* Copy PU1 */
   1108                 pu1_pred_src =
   1109                     (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[MERGE_DERIVED][0]];
   1110                 pu1_pred_dst = (UWORD8 *)ppv_pred_buf_list[i1_retval];
   1111 
   1112                 pf_copy_2d(
   1113                     pu1_pred_dst,
   1114                     i4_stride,
   1115                     pu1_pred_src,
   1116                     i4_stride,
   1117                     i4_part_wd * u1_num_bytes_per_pel,
   1118                     i4_part_ht);
   1119 
   1120                 ps_cand->pu1_pred_data = (UWORD8 *)ppv_pred_buf_list[i1_retval];
   1121                 ps_cand->pu2_pred_data = (UWORD16 *)ppv_pred_buf_list[i1_retval];
   1122                 ps_cand->i4_pred_data_stride = i4_pred_stride;
   1123 
   1124                 break;
   1125             }
   1126         }
   1127         }
   1128     }
   1129 
   1130     return i1_retval;
   1131 }
   1132 
   1133 static UWORD8 ihevce_find_idx_of_worst_cost(UWORD32 *pu4_cost_array, UWORD8 u1_array_size)
   1134 {
   1135     WORD32 i;
   1136 
   1137     UWORD8 u1_worst_cost_idx = 0;
   1138 
   1139     for(i = 1; i < u1_array_size; i++)
   1140     {
   1141         if(pu4_cost_array[i] > pu4_cost_array[u1_worst_cost_idx])
   1142         {
   1143             u1_worst_cost_idx = i;
   1144         }
   1145     }
   1146 
   1147     return u1_worst_cost_idx;
   1148 }
   1149 
   1150 static void ihevce_free_unused_buf_indices(
   1151     UWORD32 *pu4_pred_buf_usage_indicator,
   1152     UWORD8 *pu1_merge_pred_buf_idx_array,
   1153     UWORD8 *pu1_buf_id_in_use,
   1154     UWORD8 *pu1_buf_id_to_free,
   1155     UWORD8 u1_me_buf_id,
   1156     UWORD8 u1_num_available_cands,
   1157     UWORD8 u1_num_bufs_to_free,
   1158     UWORD8 u1_eval_merge,
   1159     UWORD8 u1_eval_skip,
   1160     UWORD8 u1_part_type)
   1161 {
   1162     UWORD8 i;
   1163 
   1164     if(u1_eval_skip)
   1165     {
   1166         if(pu1_buf_id_in_use[ME_OR_SKIP_DERIVED] == pu1_merge_pred_buf_idx_array[0])
   1167         {
   1168             ihevce_set_pred_buf_as_free(
   1169                 pu4_pred_buf_usage_indicator, pu1_merge_pred_buf_idx_array[1]);
   1170         }
   1171         else if(pu1_buf_id_in_use[ME_OR_SKIP_DERIVED] == pu1_merge_pred_buf_idx_array[1])
   1172         {
   1173             ihevce_set_pred_buf_as_free(
   1174                 pu4_pred_buf_usage_indicator, pu1_merge_pred_buf_idx_array[0]);
   1175         }
   1176         else
   1177         {
   1178             ihevce_set_pred_buf_as_free(
   1179                 pu4_pred_buf_usage_indicator, pu1_merge_pred_buf_idx_array[0]);
   1180 
   1181             ihevce_set_pred_buf_as_free(
   1182                 pu4_pred_buf_usage_indicator, pu1_merge_pred_buf_idx_array[1]);
   1183         }
   1184 
   1185         for(i = 0; i < u1_num_bufs_to_free; i++)
   1186         {
   1187             if(pu1_buf_id_to_free[i] != u1_me_buf_id)
   1188             {
   1189                 ihevce_set_pred_buf_as_free(pu4_pred_buf_usage_indicator, pu1_buf_id_to_free[i]);
   1190             }
   1191         }
   1192     }
   1193     else if((!u1_eval_merge) && (!u1_eval_skip) && (pu1_buf_id_in_use[ME_OR_SKIP_DERIVED] == UCHAR_MAX))
   1194     {
   1195         ihevce_set_pred_buf_as_free(pu4_pred_buf_usage_indicator, u1_me_buf_id);
   1196 
   1197         for(i = 0; i < u1_num_bufs_to_free; i++)
   1198         {
   1199             if(pu1_buf_id_to_free[i] != u1_me_buf_id)
   1200             {
   1201                 ihevce_set_pred_buf_as_free(pu4_pred_buf_usage_indicator, pu1_buf_id_to_free[i]);
   1202             }
   1203         }
   1204     }
   1205     else if((!u1_eval_merge) && (!u1_eval_skip) && (pu1_buf_id_in_use[ME_OR_SKIP_DERIVED] != UCHAR_MAX))
   1206     {
   1207         for(i = 0; i < u1_num_bufs_to_free; i++)
   1208         {
   1209             if(pu1_buf_id_to_free[i] != u1_me_buf_id)
   1210             {
   1211                 ihevce_set_pred_buf_as_free(pu4_pred_buf_usage_indicator, pu1_buf_id_to_free[i]);
   1212             }
   1213         }
   1214     }
   1215     else if((u1_eval_merge) && (0 == u1_part_type))
   1216     {
   1217         /* ME pred buf */
   1218         COMPUTE_NUM_POSITIVE_REFERENCES_AND_FREE_IF_ZERO(
   1219             u1_me_buf_id,
   1220             pu1_buf_id_in_use,
   1221             pu1_buf_id_to_free,
   1222             4,
   1223             u1_num_bufs_to_free,
   1224             pu4_pred_buf_usage_indicator);
   1225 
   1226         /* Merge pred buf 0 */
   1227         COMPUTE_NUM_POSITIVE_REFERENCES_AND_FREE_IF_ZERO(
   1228             pu1_merge_pred_buf_idx_array[0],
   1229             pu1_buf_id_in_use,
   1230             pu1_buf_id_to_free,
   1231             4,
   1232             u1_num_bufs_to_free,
   1233             pu4_pred_buf_usage_indicator);
   1234 
   1235         /* Merge pred buf 1 */
   1236         COMPUTE_NUM_POSITIVE_REFERENCES_AND_FREE_IF_ZERO(
   1237             pu1_merge_pred_buf_idx_array[1],
   1238             pu1_buf_id_in_use,
   1239             pu1_buf_id_to_free,
   1240             4,
   1241             u1_num_bufs_to_free,
   1242             pu4_pred_buf_usage_indicator);
   1243 
   1244         for(i = 0; i < u1_num_bufs_to_free; i++)
   1245         {
   1246             if((pu1_buf_id_to_free[i] != u1_me_buf_id) &&
   1247                (pu1_merge_pred_buf_idx_array[0] != pu1_buf_id_to_free[i]) &&
   1248                (pu1_merge_pred_buf_idx_array[1] != pu1_buf_id_to_free[i]))
   1249             {
   1250                 ihevce_set_pred_buf_as_free(pu4_pred_buf_usage_indicator, pu1_buf_id_to_free[i]);
   1251             }
   1252         }
   1253     }
   1254     else if((u1_eval_merge) || (u1_eval_skip))
   1255     {
   1256         /* ME pred buf */
   1257         COMPUTE_NUM_POSITIVE_REFERENCES_AND_FREE_IF_ZERO(
   1258             u1_me_buf_id,
   1259             pu1_buf_id_in_use,
   1260             pu1_buf_id_to_free,
   1261             4,
   1262             u1_num_bufs_to_free,
   1263             pu4_pred_buf_usage_indicator);
   1264 
   1265         /* Merge pred buf 0 */
   1266         COMPUTE_NUM_POSITIVE_REFERENCES_AND_FREE_IF_ZERO(
   1267             pu1_merge_pred_buf_idx_array[0],
   1268             pu1_buf_id_in_use,
   1269             pu1_buf_id_to_free,
   1270             4,
   1271             u1_num_bufs_to_free,
   1272             pu4_pred_buf_usage_indicator);
   1273 
   1274         /* Merge pred buf 1 */
   1275         COMPUTE_NUM_POSITIVE_REFERENCES_AND_FREE_IF_ZERO(
   1276             pu1_merge_pred_buf_idx_array[1],
   1277             pu1_buf_id_in_use,
   1278             pu1_buf_id_to_free,
   1279             4,
   1280             u1_num_bufs_to_free,
   1281             pu4_pred_buf_usage_indicator);
   1282 
   1283         /* Merge pred buf 2 */
   1284         COMPUTE_NUM_POSITIVE_REFERENCES_AND_FREE_IF_ZERO(
   1285             pu1_merge_pred_buf_idx_array[2],
   1286             pu1_buf_id_in_use,
   1287             pu1_buf_id_to_free,
   1288             4,
   1289             u1_num_bufs_to_free,
   1290             pu4_pred_buf_usage_indicator);
   1291 
   1292         for(i = 0; i < u1_num_bufs_to_free; i++)
   1293         {
   1294             if((pu1_buf_id_to_free[i] != u1_me_buf_id) &&
   1295                (pu1_merge_pred_buf_idx_array[0] != pu1_buf_id_to_free[i]) &&
   1296                (pu1_merge_pred_buf_idx_array[1] != pu1_buf_id_to_free[i]))
   1297             {
   1298                 ihevce_set_pred_buf_as_free(pu4_pred_buf_usage_indicator, pu1_buf_id_to_free[i]);
   1299             }
   1300         }
   1301     }
   1302 }
   1303 
   1304 static UWORD8 ihevce_check_if_buf_can_be_freed(
   1305     UWORD8 *pu1_pred_id_of_winners,
   1306     UWORD8 u1_idx_of_worst_cost_in_pred_buf_array,
   1307     UWORD8 u1_num_cands_previously_added)
   1308 {
   1309     UWORD8 i;
   1310 
   1311     UWORD8 u1_num_trysts = 0;
   1312 
   1313     for(i = 0; i < u1_num_cands_previously_added; i++)
   1314     {
   1315         if(u1_idx_of_worst_cost_in_pred_buf_array == pu1_pred_id_of_winners[i])
   1316         {
   1317             u1_num_trysts++;
   1318 
   1319             if(u1_num_trysts > 1)
   1320             {
   1321                 return 0;
   1322             }
   1323         }
   1324     }
   1325 
   1326     ASSERT(u1_num_trysts > 0);
   1327 
   1328     return 1;
   1329 }
   1330 
   1331 static void ihevce_get_worst_costs_and_indices(
   1332     UWORD32 *pu4_cost_src,
   1333     UWORD32 *pu4_cost_dst,
   1334     UWORD8 *pu1_worst_dst_cand_idx,
   1335     UWORD8 u1_src_array_length,
   1336     UWORD8 u1_num_cands_to_pick,
   1337     UWORD8 u1_worst_cost_idx_in_dst_array)
   1338 {
   1339     WORD32 i;
   1340 
   1341     pu4_cost_dst[0] = pu4_cost_src[u1_worst_cost_idx_in_dst_array];
   1342     pu4_cost_src[u1_worst_cost_idx_in_dst_array] = 0;
   1343     pu1_worst_dst_cand_idx[0] = u1_worst_cost_idx_in_dst_array;
   1344 
   1345     for(i = 1; i < u1_num_cands_to_pick; i++)
   1346     {
   1347         pu1_worst_dst_cand_idx[i] =
   1348             ihevce_find_idx_of_worst_cost(pu4_cost_src, u1_src_array_length);
   1349 
   1350         pu4_cost_dst[i] = pu4_cost_src[pu1_worst_dst_cand_idx[i]];
   1351         pu4_cost_src[pu1_worst_dst_cand_idx[i]] = 0;
   1352     }
   1353 
   1354     for(i = 0; i < u1_num_cands_to_pick; i++)
   1355     {
   1356         pu4_cost_src[pu1_worst_dst_cand_idx[i]] = pu4_cost_dst[i];
   1357     }
   1358 }
   1359 
   1360 static UWORD8 ihevce_select_cands_to_replace_previous_worst(
   1361     UWORD32 *pu4_cost_src,
   1362     UWORD32 *pu4_cost_dst,
   1363     INTER_CANDIDATE_ID_T *pe_cand_id,
   1364     UWORD8 *pu1_cand_idx_in_dst_array,
   1365     UWORD8 *pu1_buf_id_to_free,
   1366     UWORD8 *pu1_pred_id_of_winners,
   1367     UWORD8 *pu1_num_bufs_to_free,
   1368     WORD32 i4_max_num_inter_rdopt_cands,
   1369     UWORD8 u1_num_cands_previously_added,
   1370     UWORD8 u1_num_available_cands,
   1371     UWORD8 u1_worst_cost_idx_in_dst_array)
   1372 {
   1373     WORD32 i, j, k;
   1374     UWORD32 au4_worst_dst_costs[4];
   1375     UWORD8 au1_worst_dst_cand_idx[4];
   1376 
   1377     INTER_CANDIDATE_ID_T ae_default_cand_id[4] = {
   1378         ME_OR_SKIP_DERIVED, MERGE_DERIVED, MIXED_MODE_TYPE1, MIXED_MODE_TYPE0
   1379     };
   1380 
   1381     UWORD8 u1_num_cands_to_add_wo_comparisons =
   1382         i4_max_num_inter_rdopt_cands - u1_num_cands_previously_added;
   1383     UWORD8 u1_num_cands_to_add_after_comparisons =
   1384         u1_num_available_cands - u1_num_cands_to_add_wo_comparisons;
   1385     UWORD8 u1_num_cands_to_add = 0;
   1386     UWORD8 au1_valid_src_cands[4] = { 0, 0, 0, 0 };
   1387 
   1388     ASSERT(u1_num_cands_to_add_after_comparisons >= 0);
   1389 
   1390     /* Sorting src costs */
   1391     SORT_PRIMARY_INTTYPE_ARRAY_AND_REORDER_GENERIC_COMPANION_ARRAY(
   1392         pu4_cost_src, pe_cand_id, u1_num_available_cands, INTER_CANDIDATE_ID_T);
   1393 
   1394     for(i = 0; i < u1_num_cands_to_add_wo_comparisons; i++)
   1395     {
   1396         pu1_cand_idx_in_dst_array[u1_num_cands_to_add++] = u1_num_cands_previously_added + i;
   1397         au1_valid_src_cands[pe_cand_id[i]] = 1;
   1398     }
   1399 
   1400     if(u1_num_cands_previously_added)
   1401     {
   1402         WORD8 i1_last_index = 0;
   1403 
   1404         ihevce_get_worst_costs_and_indices(
   1405             pu4_cost_dst,
   1406             au4_worst_dst_costs,
   1407             au1_worst_dst_cand_idx,
   1408             u1_num_cands_previously_added,
   1409             u1_num_cands_to_add_after_comparisons,
   1410             u1_worst_cost_idx_in_dst_array);
   1411 
   1412         for(i = u1_num_available_cands - 1; i >= u1_num_cands_to_add_wo_comparisons; i--)
   1413         {
   1414             for(j = u1_num_cands_to_add_after_comparisons - 1; j >= i1_last_index; j--)
   1415             {
   1416                 if((pu4_cost_src[i] < au4_worst_dst_costs[j]))
   1417                 {
   1418                     if((i - u1_num_cands_to_add_wo_comparisons) <= j)
   1419                     {
   1420                         for(k = 0; k <= (i - u1_num_cands_to_add_wo_comparisons); k++)
   1421                         {
   1422                             pu1_cand_idx_in_dst_array[u1_num_cands_to_add++] =
   1423                                 au1_worst_dst_cand_idx[k];
   1424                             au1_valid_src_cands[pe_cand_id[u1_num_cands_to_add_wo_comparisons + k]] =
   1425                                 1;
   1426 
   1427                             if(1 == ihevce_check_if_buf_can_be_freed(
   1428                                         pu1_pred_id_of_winners,
   1429                                         pu1_pred_id_of_winners[au1_worst_dst_cand_idx[k]],
   1430                                         u1_num_cands_previously_added))
   1431                             {
   1432                                 pu1_buf_id_to_free[(*pu1_num_bufs_to_free)++] =
   1433                                     pu1_pred_id_of_winners[au1_worst_dst_cand_idx[k]];
   1434                             }
   1435                             else
   1436                             {
   1437                                 pu1_pred_id_of_winners[au1_worst_dst_cand_idx[k]] = UCHAR_MAX;
   1438                             }
   1439                         }
   1440 
   1441                         i1_last_index = -1;
   1442                     }
   1443                     else
   1444                     {
   1445                         i1_last_index = j;
   1446                     }
   1447 
   1448                     break;
   1449                 }
   1450             }
   1451 
   1452             if(-1 == i1_last_index)
   1453             {
   1454                 break;
   1455             }
   1456         }
   1457     }
   1458 
   1459     for(i = 0, j = 0; i < u1_num_available_cands; i++)
   1460     {
   1461         if(au1_valid_src_cands[ae_default_cand_id[i]])
   1462         {
   1463             pe_cand_id[j++] = ae_default_cand_id[i];
   1464         }
   1465     }
   1466 
   1467     return u1_num_cands_to_add;
   1468 }
   1469 
   1470 static UWORD8 ihevce_merge_cands_with_existing_best(
   1471     inter_cu_mode_info_t *ps_mode_info,
   1472     cu_inter_cand_t **pps_cand_src,
   1473     pu_mv_t (*pas_mvp_winner)[NUM_INTER_PU_PARTS],
   1474     UWORD32 (*pau4_cost)[MAX_NUM_INTER_PARTS],
   1475     void **ppv_pred_buf_list,
   1476     UWORD8 (*pau1_final_pred_buf_id)[MAX_NUM_INTER_PARTS],
   1477     UWORD32 *pu4_pred_buf_usage_indicator,
   1478     UWORD8 *pu1_num_merge_cands,
   1479     UWORD8 *pu1_num_skip_cands,
   1480     UWORD8 *pu1_num_mixed_mode_type0_cands,
   1481     UWORD8 *pu1_num_mixed_mode_type1_cands,
   1482     UWORD8 *pu1_merge_pred_buf_idx_array,
   1483 
   1484     FT_COPY_2D *pf_copy_2d,
   1485 
   1486     WORD32 i4_pred_stride,
   1487     WORD32 i4_max_num_inter_rdopt_cands,
   1488     UWORD8 u1_cu_size,
   1489     UWORD8 u1_part_type,
   1490     UWORD8 u1_eval_merge,
   1491     UWORD8 u1_eval_skip,
   1492     UWORD8 u1_num_bytes_per_pel)
   1493 {
   1494     UWORD32 au4_cost_src[4];
   1495     WORD32 i;
   1496     WORD32 u1_num_available_cands;
   1497     UWORD8 au1_buf_id_in_use[4];
   1498     UWORD8 au1_buf_id_to_free[4];
   1499     UWORD8 au1_cand_idx_in_dst_array[4];
   1500 
   1501     INTER_CANDIDATE_ID_T ae_cand_id[4] = {
   1502         ME_OR_SKIP_DERIVED, MERGE_DERIVED, MIXED_MODE_TYPE1, MIXED_MODE_TYPE0
   1503     };
   1504 
   1505     cu_inter_cand_t **pps_cand_dst = ps_mode_info->aps_cu_data;
   1506 
   1507     UWORD8 u1_num_cands_previously_added = ps_mode_info->u1_num_inter_cands;
   1508     UWORD8 u1_worst_cost_idx = ps_mode_info->u1_idx_of_worst_cost_in_cost_array;
   1509     UWORD8 u1_idx_of_worst_cost_in_pred_buf_array =
   1510         ps_mode_info->u1_idx_of_worst_cost_in_pred_buf_array;
   1511     UWORD32 *pu4_cost_dst = ps_mode_info->au4_cost;
   1512     UWORD8 *pu1_pred_id_of_winners = ps_mode_info->au1_pred_buf_idx;
   1513     UWORD8 u1_num_bufs_to_free = 0;
   1514     UWORD8 u1_skip_or_merge_cand_is_valid = 0;
   1515     UWORD8 u1_num_invalid_cands = 0;
   1516 
   1517     memset(au1_buf_id_in_use, UCHAR_MAX, sizeof(au1_buf_id_in_use));
   1518 
   1519     u1_num_available_cands = (u1_eval_merge) ? 2 + ((u1_part_type != 0) + 1) : 1;
   1520 
   1521     for(i = 0; i < u1_num_available_cands; i++)
   1522     {
   1523         WORD32 i4_idx = i - u1_num_invalid_cands;
   1524 
   1525         if(u1_part_type == 0)
   1526         {
   1527             au4_cost_src[i4_idx] = pau4_cost[ae_cand_id[i4_idx]][0];
   1528         }
   1529         else
   1530         {
   1531             au4_cost_src[i4_idx] =
   1532                 pau4_cost[ae_cand_id[i4_idx]][0] + pau4_cost[ae_cand_id[i4_idx]][1];
   1533         }
   1534 
   1535         if(au4_cost_src[i4_idx] >= INT_MAX)
   1536         {
   1537             memmove(
   1538                 &ae_cand_id[i4_idx],
   1539                 &ae_cand_id[i4_idx + 1],
   1540                 sizeof(INTER_CANDIDATE_ID_T) * (u1_num_available_cands - i - 1));
   1541 
   1542             u1_num_invalid_cands++;
   1543         }
   1544     }
   1545 
   1546     u1_num_available_cands -= u1_num_invalid_cands;
   1547 
   1548     if((u1_num_cands_previously_added + u1_num_available_cands) > i4_max_num_inter_rdopt_cands)
   1549     {
   1550         u1_num_available_cands = ihevce_select_cands_to_replace_previous_worst(
   1551             au4_cost_src,
   1552             pu4_cost_dst,
   1553             ae_cand_id,
   1554             au1_cand_idx_in_dst_array,
   1555             au1_buf_id_to_free,
   1556             pu1_pred_id_of_winners,
   1557             &u1_num_bufs_to_free,
   1558             i4_max_num_inter_rdopt_cands,
   1559             u1_num_cands_previously_added,
   1560             u1_num_available_cands,
   1561             u1_worst_cost_idx);
   1562     }
   1563     else
   1564     {
   1565         for(i = 0; i < u1_num_available_cands; i++)
   1566         {
   1567             au1_cand_idx_in_dst_array[i] = u1_num_cands_previously_added + i;
   1568         }
   1569     }
   1570 
   1571     for(i = 0; i < u1_num_available_cands; i++)
   1572     {
   1573         UWORD8 u1_dst_array_idx = au1_cand_idx_in_dst_array[i];
   1574 
   1575         if(u1_part_type == 0)
   1576         {
   1577             au4_cost_src[i] = pau4_cost[ae_cand_id[i]][0];
   1578         }
   1579         else
   1580         {
   1581             au4_cost_src[i] = pau4_cost[ae_cand_id[i]][0] + pau4_cost[ae_cand_id[i]][1];
   1582         }
   1583 
   1584         pps_cand_dst[u1_dst_array_idx] = pps_cand_src[ae_cand_id[i]];
   1585 
   1586         /* Adding a skip candidate identical to the merge winner */
   1587         if((u1_eval_merge) && (0 == u1_part_type) && (MIXED_MODE_TYPE1 == ae_cand_id[i]))
   1588         {
   1589             (*pu1_num_skip_cands)++;
   1590 
   1591             pu4_cost_dst[u1_dst_array_idx] = au4_cost_src[i];
   1592 
   1593             if(u1_num_cands_previously_added >= i4_max_num_inter_rdopt_cands)
   1594             {
   1595                 u1_worst_cost_idx =
   1596                     ihevce_find_idx_of_worst_cost(pu4_cost_dst, u1_num_cands_previously_added);
   1597 
   1598                 u1_idx_of_worst_cost_in_pred_buf_array = pu1_pred_id_of_winners[u1_worst_cost_idx];
   1599             }
   1600             else
   1601             {
   1602                 u1_num_cands_previously_added++;
   1603             }
   1604 
   1605             if(u1_skip_or_merge_cand_is_valid)
   1606             {
   1607                 pps_cand_dst[u1_dst_array_idx]->pu1_pred_data =
   1608                     (UWORD8 *)ppv_pred_buf_list[au1_buf_id_in_use[MERGE_DERIVED]];
   1609                 pps_cand_dst[u1_dst_array_idx]->pu2_pred_data =
   1610                     (UWORD16 *)ppv_pred_buf_list[au1_buf_id_in_use[MERGE_DERIVED]];
   1611                 pps_cand_dst[u1_dst_array_idx]->i4_pred_data_stride = i4_pred_stride;
   1612 
   1613                 au1_buf_id_in_use[MIXED_MODE_TYPE1] = au1_buf_id_in_use[MERGE_DERIVED];
   1614                 pu1_pred_id_of_winners[u1_dst_array_idx] = au1_buf_id_in_use[MERGE_DERIVED];
   1615             }
   1616             else
   1617             {
   1618                 u1_skip_or_merge_cand_is_valid = 1;
   1619 
   1620                 au1_buf_id_in_use[MIXED_MODE_TYPE1] = ihevce_merge_cand_pred_buffer_preparation(
   1621                     ppv_pred_buf_list,
   1622                     pps_cand_dst[u1_dst_array_idx],
   1623                     pau1_final_pred_buf_id,
   1624                     i4_pred_stride,
   1625                     u1_cu_size,
   1626                     u1_part_type,
   1627                     u1_num_bytes_per_pel,
   1628                     pf_copy_2d);
   1629 
   1630                 pu1_pred_id_of_winners[u1_dst_array_idx] = au1_buf_id_in_use[MIXED_MODE_TYPE1];
   1631             }
   1632 
   1633             continue;
   1634         }
   1635 
   1636         if(u1_num_cands_previously_added < i4_max_num_inter_rdopt_cands)
   1637         {
   1638             if(u1_num_cands_previously_added)
   1639             {
   1640                 if(au4_cost_src[i] > pu4_cost_dst[u1_worst_cost_idx])
   1641                 {
   1642                     u1_worst_cost_idx = u1_num_cands_previously_added;
   1643                 }
   1644             }
   1645 
   1646             pu4_cost_dst[u1_dst_array_idx] = au4_cost_src[i];
   1647 
   1648             u1_num_cands_previously_added++;
   1649         }
   1650         else
   1651         {
   1652             pu4_cost_dst[u1_dst_array_idx] = au4_cost_src[i];
   1653 
   1654             u1_worst_cost_idx = ihevce_find_idx_of_worst_cost(
   1655                 ps_mode_info->au4_cost, u1_num_cands_previously_added);
   1656 
   1657             u1_idx_of_worst_cost_in_pred_buf_array = pu1_pred_id_of_winners[u1_worst_cost_idx];
   1658         }
   1659 
   1660         switch(ae_cand_id[i])
   1661         {
   1662         case ME_OR_SKIP_DERIVED:
   1663         {
   1664             (*pu1_num_skip_cands) += u1_eval_skip;
   1665 
   1666             pps_cand_dst[u1_dst_array_idx]->pu1_pred_data =
   1667                 (UWORD8 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0]];
   1668             pps_cand_dst[u1_dst_array_idx]->pu2_pred_data =
   1669                 (UWORD16 *)ppv_pred_buf_list[pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0]];
   1670             pps_cand_dst[u1_dst_array_idx]->i4_pred_data_stride = i4_pred_stride;
   1671 
   1672             if(u1_worst_cost_idx == u1_dst_array_idx)
   1673             {
   1674                 u1_idx_of_worst_cost_in_pred_buf_array =
   1675                     pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0];
   1676             }
   1677 
   1678             u1_skip_or_merge_cand_is_valid = u1_eval_skip;
   1679 
   1680             au1_buf_id_in_use[ME_OR_SKIP_DERIVED] = pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0];
   1681             pu1_pred_id_of_winners[u1_dst_array_idx] =
   1682                 pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0];
   1683 
   1684             break;
   1685         }
   1686         case MERGE_DERIVED:
   1687         {
   1688             (*pu1_num_merge_cands)++;
   1689 
   1690             au1_buf_id_in_use[MERGE_DERIVED] = ihevce_merge_cand_pred_buffer_preparation(
   1691                 ppv_pred_buf_list,
   1692                 pps_cand_dst[u1_dst_array_idx],
   1693                 pau1_final_pred_buf_id,
   1694                 i4_pred_stride,
   1695                 u1_cu_size,
   1696                 u1_part_type,
   1697                 u1_num_bytes_per_pel,
   1698                 pf_copy_2d
   1699 
   1700             );
   1701 
   1702             pu1_pred_id_of_winners[u1_dst_array_idx] = au1_buf_id_in_use[MERGE_DERIVED];
   1703 
   1704             if(u1_worst_cost_idx == u1_dst_array_idx)
   1705             {
   1706                 u1_idx_of_worst_cost_in_pred_buf_array = au1_buf_id_in_use[MERGE_DERIVED];
   1707             }
   1708 
   1709             u1_skip_or_merge_cand_is_valid = 1;
   1710 
   1711             break;
   1712         }
   1713         case MIXED_MODE_TYPE1:
   1714         {
   1715             (*pu1_num_mixed_mode_type1_cands)++;
   1716 
   1717             au1_buf_id_in_use[MIXED_MODE_TYPE1] =
   1718                 ihevce_mixed_mode_cand_type1_pred_buffer_preparation(
   1719                     ppv_pred_buf_list,
   1720                     pps_cand_dst[u1_dst_array_idx],
   1721                     pau1_final_pred_buf_id,
   1722                     pu1_merge_pred_buf_idx_array,
   1723                     i4_pred_stride,
   1724                     au1_buf_id_in_use[ME_OR_SKIP_DERIVED],
   1725                     au1_buf_id_in_use[MERGE_DERIVED],
   1726                     (u1_num_available_cands - i) > 1,
   1727                     u1_cu_size,
   1728                     u1_part_type,
   1729                     u1_num_bytes_per_pel,
   1730                     pf_copy_2d
   1731 
   1732                 );
   1733 
   1734             pu1_pred_id_of_winners[u1_dst_array_idx] = au1_buf_id_in_use[MIXED_MODE_TYPE1];
   1735 
   1736             if(u1_worst_cost_idx == u1_dst_array_idx)
   1737             {
   1738                 u1_idx_of_worst_cost_in_pred_buf_array = au1_buf_id_in_use[MIXED_MODE_TYPE1];
   1739             }
   1740 
   1741             break;
   1742         }
   1743         case MIXED_MODE_TYPE0:
   1744         {
   1745             (*pu1_num_mixed_mode_type0_cands)++;
   1746 
   1747             au1_buf_id_in_use[MIXED_MODE_TYPE0] =
   1748                 ihevce_mixed_mode_cand_type0_pred_buffer_preparation(
   1749                     ppv_pred_buf_list,
   1750                     pps_cand_dst[u1_dst_array_idx],
   1751                     pau1_final_pred_buf_id,
   1752                     pu1_merge_pred_buf_idx_array,
   1753                     au1_buf_id_in_use[ME_OR_SKIP_DERIVED],
   1754                     au1_buf_id_in_use[MERGE_DERIVED],
   1755                     au1_buf_id_in_use[MIXED_MODE_TYPE1],
   1756                     i4_pred_stride,
   1757                     u1_cu_size,
   1758                     u1_part_type,
   1759                     u1_num_bytes_per_pel,
   1760                     pf_copy_2d);
   1761 
   1762             pu1_pred_id_of_winners[u1_dst_array_idx] = au1_buf_id_in_use[MIXED_MODE_TYPE0];
   1763 
   1764             if(u1_worst_cost_idx == u1_dst_array_idx)
   1765             {
   1766                 u1_idx_of_worst_cost_in_pred_buf_array = au1_buf_id_in_use[MIXED_MODE_TYPE0];
   1767             }
   1768 
   1769             break;
   1770         }
   1771         }
   1772     }
   1773 
   1774     ihevce_free_unused_buf_indices(
   1775         pu4_pred_buf_usage_indicator,
   1776         pu1_merge_pred_buf_idx_array,
   1777         au1_buf_id_in_use,
   1778         au1_buf_id_to_free,
   1779         pau1_final_pred_buf_id[ME_OR_SKIP_DERIVED][0],
   1780         u1_num_available_cands,
   1781         u1_num_bufs_to_free,
   1782         u1_eval_merge,
   1783         u1_eval_skip,
   1784         u1_part_type);
   1785 
   1786     ps_mode_info->u1_idx_of_worst_cost_in_cost_array = u1_worst_cost_idx;
   1787     ps_mode_info->u1_num_inter_cands = u1_num_cands_previously_added;
   1788     ps_mode_info->u1_idx_of_worst_cost_in_pred_buf_array = u1_idx_of_worst_cost_in_pred_buf_array;
   1789 
   1790     return u1_skip_or_merge_cand_is_valid;
   1791 }
   1792 
   1793 static UWORD8 ihevce_prepare_cand_containers(
   1794     ihevce_inter_cand_sifter_prms_t *ps_ctxt,
   1795     cu_inter_cand_t **pps_cands,
   1796     UWORD8 *pu1_merge_pred_buf_idx_array,
   1797     UWORD8 *pu1_me_pred_buf_idx,
   1798     UWORD8 u1_part_type,
   1799     UWORD8 u1_me_cand_list_idx,
   1800     UWORD8 u1_eval_merge,
   1801     UWORD8 u1_eval_skip)
   1802 {
   1803     UWORD8 u1_num_bufs_currently_allocated;
   1804 
   1805     WORD32 i4_pred_stride = ps_ctxt->ps_pred_buf_data->i4_pred_stride;
   1806     UWORD8 u1_cu_size = ps_ctxt->u1_cu_size;
   1807     UWORD8 u1_cu_pos_x = ps_ctxt->u1_cu_pos_x;
   1808     UWORD8 u1_cu_pos_y = ps_ctxt->u1_cu_pos_y;
   1809     void **ppv_pred_buf_list = ps_ctxt->ps_pred_buf_data->apv_inter_pred_data;
   1810 
   1811     if(!u1_eval_merge)
   1812     {
   1813         if(u1_eval_skip)
   1814         {
   1815             u1_num_bufs_currently_allocated = ihevce_get_free_pred_buf_indices(
   1816                 pu1_merge_pred_buf_idx_array, &ps_ctxt->ps_pred_buf_data->u4_is_buf_in_use, 2);
   1817 
   1818             if(u1_num_bufs_currently_allocated < 2)
   1819             {
   1820                 return 0;
   1821             }
   1822 
   1823             pps_cands[ME_OR_SKIP_DERIVED] =
   1824                 &ps_ctxt->ps_cu_inter_merge_skip->as_cu_inter_merge_skip_cand
   1825                      [MAX_NUM_CU_MERGE_SKIP_CAND - 1 -
   1826                       ps_ctxt->ps_cu_inter_merge_skip->u1_num_skip_cands];
   1827 
   1828             pps_cands[ME_OR_SKIP_DERIVED]->b1_skip_flag = 1;
   1829             pps_cands[ME_OR_SKIP_DERIVED]->b1_eval_mark = 1;
   1830             pps_cands[ME_OR_SKIP_DERIVED]->b1_eval_tx_cusize = 1;
   1831             pps_cands[ME_OR_SKIP_DERIVED]->b1_eval_tx_cusize_by2 = 1;
   1832             pps_cands[ME_OR_SKIP_DERIVED]->b1_intra_has_won = 0;
   1833             pps_cands[ME_OR_SKIP_DERIVED]->b3_part_size = 0;
   1834             pps_cands[ME_OR_SKIP_DERIVED]->i4_pred_data_stride = i4_pred_stride;
   1835             pps_cands[ME_OR_SKIP_DERIVED]->as_inter_pu->b1_intra_flag = 0;
   1836             pps_cands[ME_OR_SKIP_DERIVED]->as_inter_pu->b1_merge_flag = 1;
   1837             pps_cands[ME_OR_SKIP_DERIVED]->as_inter_pu->b4_pos_x = u1_cu_pos_x >> 2;
   1838             pps_cands[ME_OR_SKIP_DERIVED]->as_inter_pu->b4_pos_y = u1_cu_pos_y >> 2;
   1839             pps_cands[ME_OR_SKIP_DERIVED]->as_inter_pu->b4_wd = (u1_cu_size >> 2) - 1;
   1840             pps_cands[ME_OR_SKIP_DERIVED]->as_inter_pu->b4_ht = (u1_cu_size >> 2) - 1;
   1841 
   1842             pps_cands[MERGE_DERIVED] = pps_cands[ME_OR_SKIP_DERIVED];
   1843         }
   1844         else
   1845         {
   1846             u1_num_bufs_currently_allocated = ihevce_get_free_pred_buf_indices(
   1847                 pu1_me_pred_buf_idx, &ps_ctxt->ps_pred_buf_data->u4_is_buf_in_use, 1);
   1848 
   1849             if(u1_num_bufs_currently_allocated < 1)
   1850             {
   1851                 return 0;
   1852             }
   1853 
   1854             pps_cands[ME_OR_SKIP_DERIVED] = &ps_ctxt->ps_me_cands[u1_me_cand_list_idx];
   1855             pps_cands[ME_OR_SKIP_DERIVED]->i4_pred_data_stride = i4_pred_stride;
   1856             pps_cands[ME_OR_SKIP_DERIVED]->pu1_pred_data =
   1857                 (UWORD8 *)ppv_pred_buf_list[*pu1_me_pred_buf_idx];
   1858             pps_cands[ME_OR_SKIP_DERIVED]->pu2_pred_data =
   1859                 (UWORD16 *)ppv_pred_buf_list[*pu1_me_pred_buf_idx];
   1860         }
   1861     }
   1862     else
   1863     {
   1864         u1_num_bufs_currently_allocated = ihevce_get_free_pred_buf_indices(
   1865             pu1_me_pred_buf_idx, &ps_ctxt->ps_pred_buf_data->u4_is_buf_in_use, 1);
   1866 
   1867         if(u1_num_bufs_currently_allocated < 1)
   1868         {
   1869             return 0;
   1870         }
   1871 
   1872         pps_cands[ME_OR_SKIP_DERIVED] = &ps_ctxt->ps_me_cands[u1_me_cand_list_idx];
   1873 
   1874         if(u1_part_type > 0)
   1875         {
   1876             u1_num_bufs_currently_allocated = ihevce_get_free_pred_buf_indices(
   1877                 pu1_merge_pred_buf_idx_array, &ps_ctxt->ps_pred_buf_data->u4_is_buf_in_use, 3);
   1878 
   1879             if(u1_num_bufs_currently_allocated < 3)
   1880             {
   1881                 return 0;
   1882             }
   1883 
   1884             pps_cands[MERGE_DERIVED] = &ps_ctxt->ps_cu_inter_merge_skip->as_cu_inter_merge_skip_cand
   1885                                             [ps_ctxt->ps_cu_inter_merge_skip->u1_num_merge_cands];
   1886 
   1887             pps_cands[MIXED_MODE_TYPE0] =
   1888                 &ps_ctxt->ps_mixed_modes_datastore
   1889                      ->as_cu_data[ps_ctxt->ps_mixed_modes_datastore->u1_num_mixed_mode_type0_cands];
   1890 
   1891             pps_cands[MIXED_MODE_TYPE1] =
   1892                 &ps_ctxt->ps_mixed_modes_datastore->as_cu_data
   1893                      [MAX_NUM_MIXED_MODE_INTER_RDO_CANDS - 1 -
   1894                       ps_ctxt->ps_mixed_modes_datastore->u1_num_mixed_mode_type1_cands];
   1895 
   1896             *pps_cands[MERGE_DERIVED] = *pps_cands[ME_OR_SKIP_DERIVED];
   1897             *pps_cands[MIXED_MODE_TYPE0] = *pps_cands[ME_OR_SKIP_DERIVED];
   1898             *pps_cands[MIXED_MODE_TYPE1] = *pps_cands[ME_OR_SKIP_DERIVED];
   1899         }
   1900         else
   1901         {
   1902             u1_num_bufs_currently_allocated = ihevce_get_free_pred_buf_indices(
   1903                 pu1_merge_pred_buf_idx_array, &ps_ctxt->ps_pred_buf_data->u4_is_buf_in_use, 2);
   1904 
   1905             if(u1_num_bufs_currently_allocated < 2)
   1906             {
   1907                 return 0;
   1908             }
   1909 
   1910             pps_cands[MERGE_DERIVED] = &ps_ctxt->ps_cu_inter_merge_skip->as_cu_inter_merge_skip_cand
   1911                                             [ps_ctxt->ps_cu_inter_merge_skip->u1_num_merge_cands];
   1912 
   1913             *pps_cands[MERGE_DERIVED] = *pps_cands[ME_OR_SKIP_DERIVED];
   1914         }
   1915 
   1916         pps_cands[MERGE_DERIVED]->as_inter_pu[0].b1_merge_flag = 1;
   1917         pps_cands[MERGE_DERIVED]->as_inter_pu[1].b1_merge_flag = 1;
   1918     }
   1919 
   1920     return u1_num_bufs_currently_allocated;
   1921 }
   1922 
   1923 static __inline void ihevce_merge_prms_init(
   1924     merge_prms_t *ps_prms,
   1925     merge_cand_list_t *ps_list,
   1926     inter_pred_ctxt_t *ps_mc_ctxt,
   1927     mv_pred_ctxt_t *ps_mv_pred_ctxt,
   1928     PF_LUMA_INTER_PRED_PU pf_luma_inter_pred_pu,
   1929     PF_SAD_FXN_T pf_sad_fxn,
   1930     void **ppv_pred_buf_list,
   1931     ihevce_cmn_opt_func_t *ps_cmn_utils_optimised_function_list,
   1932     UWORD8 *pu1_merge_pred_buf_array,
   1933     UWORD8 (*pau1_best_pred_buf_id)[MAX_NUM_INTER_PARTS],
   1934     UWORD8 *pu1_is_top_used,
   1935     WORD32 (*pai4_noise_term)[MAX_NUM_INTER_PARTS],
   1936     UWORD32 (*pau4_pred_variance)[MAX_NUM_INTER_PARTS],
   1937     UWORD32 *pu4_src_variance,
   1938     WORD32 i4_alpha_stim_multiplier,
   1939     WORD32 i4_src_stride,
   1940     WORD32 i4_pred_stride,
   1941     WORD32 i4_lambda,
   1942     UWORD8 u1_is_cu_noisy,
   1943     UWORD8 u1_is_hbd,
   1944     UWORD8 u1_max_cands,
   1945     UWORD8 u1_merge_idx_cabac_model,
   1946     UWORD8 u1_use_merge_cand_from_top_row)
   1947 {
   1948     ps_prms->ps_list = ps_list;
   1949     ps_prms->ps_mc_ctxt = ps_mc_ctxt;
   1950     ps_prms->ps_mv_pred_ctxt = ps_mv_pred_ctxt;
   1951     ps_prms->pf_luma_inter_pred_pu = pf_luma_inter_pred_pu;
   1952     ps_prms->pf_sad_fxn = pf_sad_fxn;
   1953     ps_prms->ppv_pred_buf_list = ppv_pred_buf_list;
   1954     ps_prms->ps_cmn_utils_optimised_function_list = ps_cmn_utils_optimised_function_list;
   1955 
   1956     ps_prms->pu1_merge_pred_buf_array = pu1_merge_pred_buf_array;
   1957     ps_prms->pau1_best_pred_buf_id = pau1_best_pred_buf_id;
   1958     ps_prms->pu1_is_top_used = pu1_is_top_used;
   1959     ps_prms->pai4_noise_term = pai4_noise_term;
   1960     ps_prms->pau4_pred_variance = pau4_pred_variance;
   1961     ps_prms->pu4_src_variance = pu4_src_variance;
   1962     ps_prms->i4_alpha_stim_multiplier = i4_alpha_stim_multiplier;
   1963     ps_prms->i4_src_stride = i4_src_stride;
   1964     ps_prms->i4_pred_stride = i4_pred_stride;
   1965     ps_prms->i4_lambda = i4_lambda;
   1966     ps_prms->u1_is_cu_noisy = u1_is_cu_noisy;
   1967     ps_prms->u1_is_hbd = u1_is_hbd;
   1968     ps_prms->u1_max_cands = u1_max_cands;
   1969     ps_prms->u1_merge_idx_cabac_model = u1_merge_idx_cabac_model;
   1970     ps_prms->u1_use_merge_cand_from_top_row = u1_use_merge_cand_from_top_row;
   1971 }
   1972 
   1973 static UWORD8 ihevce_merge_candidate_seive(
   1974     nbr_avail_flags_t *ps_nbr,
   1975     merge_cand_list_t *ps_merge_cand,
   1976     UWORD8 *pu1_is_top_used,
   1977     UWORD8 u1_num_merge_cands,
   1978     UWORD8 u1_use_merge_cand_from_top_row)
   1979 {
   1980     if(!u1_use_merge_cand_from_top_row)
   1981     {
   1982         if(ps_nbr->u1_bot_lt_avail || ps_nbr->u1_left_avail)
   1983         {
   1984             return !pu1_is_top_used[0];
   1985         }
   1986         else
   1987         {
   1988             return 0;
   1989         }
   1990     }
   1991     else
   1992     {
   1993         return u1_num_merge_cands;
   1994     }
   1995 }
   1996 
   1997 static UWORD8 ihevce_compute_pred_and_populate_modes(
   1998     ihevce_inter_cand_sifter_prms_t *ps_ctxt,
   1999     PF_SAD_FXN_T pf_sad_func,
   2000     UWORD32 *pu4_src_variance,
   2001     UWORD8 u1_part_type,
   2002     UWORD8 u1_me_cand_list_idx,
   2003     UWORD8 u1_eval_merge,
   2004     UWORD8 u1_eval_skip)
   2005 {
   2006     cu_inter_cand_t *aps_cands[4];
   2007     pu_mv_t as_mvp_winner[4][NUM_INTER_PU_PARTS];
   2008     merge_prms_t s_merge_prms;
   2009     merge_cand_list_t as_merge_cand[MAX_NUM_MERGE_CAND];
   2010 
   2011     UWORD8 i, j;
   2012     UWORD32 au4_cost[4][NUM_INTER_PU_PARTS];
   2013     UWORD8 au1_final_pred_buf_id[4][NUM_INTER_PU_PARTS];
   2014     UWORD8 au1_merge_pred_buf_idx_array[3];
   2015     UWORD8 au1_is_top_used[MAX_NUM_MERGE_CAND];
   2016     UWORD8 u1_me_pred_buf_idx;
   2017     UWORD8 u1_num_bufs_currently_allocated;
   2018     WORD32 i4_mean;
   2019     UWORD32 au4_pred_variance[4][NUM_INTER_PU_PARTS];
   2020     WORD32 ai4_noise_term[4][NUM_INTER_PU_PARTS];
   2021 
   2022     UWORD8 u1_cu_pos_x = ps_ctxt->u1_cu_pos_x;
   2023     UWORD8 u1_cu_pos_y = ps_ctxt->u1_cu_pos_y;
   2024 
   2025     inter_cu_mode_info_t *ps_cu_mode_info = ps_ctxt->ps_inter_cu_mode_info;
   2026     inter_pred_ctxt_t *ps_mc_ctxt = ps_ctxt->ps_mc_ctxt;
   2027     nbr_4x4_t *ps_cu_nbr_buf = ps_ctxt->aps_cu_nbr_buf[0];
   2028     nbr_4x4_t *ps_pu_left_nbr = ps_ctxt->ps_left_nbr_4x4;
   2029     nbr_4x4_t *ps_pu_top_nbr = ps_ctxt->ps_top_nbr_4x4;
   2030     nbr_4x4_t *ps_pu_topleft_nbr = ps_ctxt->ps_topleft_nbr_4x4;
   2031 
   2032     ihevce_inter_pred_buf_data_t *ps_pred_buf_info = ps_ctxt->ps_pred_buf_data;
   2033     mv_pred_ctxt_t *ps_mv_pred_ctxt = ps_ctxt->ps_mv_pred_ctxt;
   2034 
   2035     PF_LUMA_INTER_PRED_PU pf_luma_inter_pred_pu = ps_ctxt->pf_luma_inter_pred_pu;
   2036 
   2037     void *pv_src = ps_ctxt->pv_src;
   2038     WORD32 i4_src_stride = ps_ctxt->i4_src_strd;
   2039     WORD32 i4_pred_stride = ps_ctxt->ps_pred_buf_data->i4_pred_stride;
   2040     UWORD8 u1_num_parts = (u1_part_type != PRT_2Nx2N) + 1;
   2041     UWORD8 u1_num_bytes_per_pel = ps_ctxt->u1_is_hbd + 1;
   2042     void **ppv_pred_buf_list = ps_ctxt->ps_pred_buf_data->apv_inter_pred_data;
   2043     UWORD8 u1_cu_size = ps_ctxt->u1_cu_size;
   2044     WORD32 i4_nbr_4x4_left_stride = ps_ctxt->i4_nbr_4x4_left_strd;
   2045     UWORD8 *pu1_ctb_nbr_map = ps_ctxt->pu1_ctb_nbr_map;
   2046     WORD32 i4_nbr_map_stride = ps_ctxt->i4_ctb_nbr_map_stride;
   2047     UWORD8 u1_max_merge_candidates = ps_ctxt->u1_max_merge_candidates;
   2048     WORD32 i4_max_num_inter_rdopt_cands = ps_ctxt->i4_max_num_inter_rdopt_cands;
   2049     WORD32 i4_pred_buf_offset = 0;
   2050     WORD32 i4_src_buf_offset = 0;
   2051     UWORD8 u1_single_mcl_flag =
   2052         ((8 == u1_cu_size) && (ps_mv_pred_ctxt->i4_log2_parallel_merge_level_minus2 > 0));
   2053     UWORD8 u1_skip_or_merge_cand_is_valid = 0;
   2054     WORD32 i4_lambda_qf = ps_ctxt->i4_lambda_qf;
   2055     UWORD8 u1_is_cu_noisy = ps_ctxt->u1_is_cu_noisy;
   2056 
   2057     ASSERT(0 == (u1_eval_skip && u1_eval_merge));
   2058     ASSERT(u1_me_cand_list_idx < ps_ctxt->u1_num_me_cands);
   2059 
   2060     /*
   2061     Algorithm -
   2062     1. Determine pred and satd for ME cand.
   2063     2. Determine merge winner for PU1.
   2064     3. Determine pred and satd for mixed_type0 cand.
   2065     4. Determine merge winner for PU2 and hence derive pred and satd for merge cand.
   2066     5. Determine merge winner for PU2 assuming ME cand as PU1 winner and hence derive
   2067     pred and satd for mixed_type1 cand.
   2068     6. Sort the 4 preceding costs and hence, the cand list.
   2069     7. Merge the sorted lists with the final cand list.
   2070 
   2071     PS : 2 - 7 will be relevant only if u1_eval_merge = 1 and u1_eval_skip = 0
   2072     PPS : 1 will not be relevant if u1_eval_skip = 1
   2073     */
   2074 
   2075     /*
   2076     Explanatory notes -
   2077     1. Motion Vector Merge candidates and nbr's in all merge mode (RealD)
   2078     2. Motion Vector Merge candidates and nbr's in mixed mode (AltD)
   2079     */
   2080 
   2081     u1_num_bufs_currently_allocated = ihevce_prepare_cand_containers(
   2082         ps_ctxt,
   2083         aps_cands,
   2084         au1_merge_pred_buf_idx_array,
   2085         &u1_me_pred_buf_idx,
   2086         u1_part_type,
   2087         u1_me_cand_list_idx,
   2088         u1_eval_merge,
   2089         u1_eval_skip);
   2090 
   2091     if(0 == u1_num_bufs_currently_allocated)
   2092     {
   2093         return 0;
   2094     }
   2095 
   2096     if((u1_eval_merge) || (u1_eval_skip))
   2097     {
   2098         ihevce_merge_prms_init(
   2099             &s_merge_prms,
   2100             as_merge_cand,
   2101             ps_mc_ctxt,
   2102             ps_mv_pred_ctxt,
   2103             pf_luma_inter_pred_pu,
   2104             pf_sad_func,
   2105             ppv_pred_buf_list,
   2106             ps_ctxt->ps_cmn_utils_optimised_function_list,
   2107             au1_merge_pred_buf_idx_array,
   2108             au1_final_pred_buf_id,
   2109             au1_is_top_used,
   2110             ai4_noise_term,
   2111             au4_pred_variance,
   2112             pu4_src_variance,
   2113             ps_ctxt->i4_alpha_stim_multiplier,
   2114             i4_src_stride,
   2115             i4_pred_stride,
   2116             i4_lambda_qf,
   2117             u1_is_cu_noisy,
   2118             ps_ctxt->u1_is_hbd,
   2119             u1_max_merge_candidates,
   2120             ps_ctxt->u1_merge_idx_cabac_model,
   2121             ps_ctxt->u1_use_merge_cand_from_top_row);
   2122     }
   2123 
   2124     for(i = 0; i < u1_num_parts; i++)
   2125     {
   2126         nbr_avail_flags_t s_nbr;
   2127 
   2128         UWORD8 u1_part_wd;
   2129         UWORD8 u1_part_ht;
   2130         UWORD8 u1_pu_pos_x_4x4;
   2131         UWORD8 u1_pu_pos_y_4x4;
   2132 
   2133         pu_t *ps_pu = &aps_cands[MERGE_DERIVED]->as_inter_pu[i];
   2134 
   2135         PART_SIZE_E e_part_size = (PART_SIZE_E)aps_cands[ME_OR_SKIP_DERIVED]->b3_part_size;
   2136 
   2137         void *pv_pu_src = (UWORD8 *)pv_src + i4_src_buf_offset;
   2138         UWORD8 u1_num_merge_cands = 0;
   2139 
   2140         u1_part_wd = (aps_cands[0]->as_inter_pu[i].b4_wd + 1) << 2;
   2141         u1_part_ht = (aps_cands[0]->as_inter_pu[i].b4_ht + 1) << 2;
   2142         u1_pu_pos_x_4x4 = aps_cands[0]->as_inter_pu[i].b4_pos_x;
   2143         u1_pu_pos_y_4x4 = aps_cands[0]->as_inter_pu[i].b4_pos_y;
   2144 
   2145         /* Inter cand pred and satd */
   2146         if(!u1_eval_skip)
   2147         {
   2148             void *pv_pu_pred = (UWORD8 *)ppv_pred_buf_list[u1_me_pred_buf_idx] + i4_pred_buf_offset;
   2149 
   2150             if(ps_ctxt->u1_reuse_me_sad)
   2151             {
   2152                 ihevce_compute_inter_pred_and_cost(
   2153                     ps_mc_ctxt,
   2154                     pf_luma_inter_pred_pu,
   2155                     pf_sad_func,
   2156                     &aps_cands[ME_OR_SKIP_DERIVED]->as_inter_pu[i],
   2157                     pv_pu_src,
   2158                     pv_pu_pred,
   2159                     i4_src_stride,
   2160                     i4_pred_stride,
   2161                     0,
   2162                     ps_ctxt->ps_cmn_utils_optimised_function_list);
   2163 
   2164                 au4_cost[ME_OR_SKIP_DERIVED][i] =
   2165                     ps_ctxt->pai4_me_err_metric[u1_me_cand_list_idx][i];
   2166             }
   2167             else
   2168             {
   2169                 au4_cost[ME_OR_SKIP_DERIVED][i] = ihevce_compute_inter_pred_and_cost(
   2170                     ps_mc_ctxt,
   2171                     pf_luma_inter_pred_pu,
   2172                     pf_sad_func,
   2173                     &aps_cands[ME_OR_SKIP_DERIVED]->as_inter_pu[i],
   2174                     pv_pu_src,
   2175                     pv_pu_pred,
   2176                     i4_src_stride,
   2177                     i4_pred_stride,
   2178                     1,
   2179                     ps_ctxt->ps_cmn_utils_optimised_function_list);
   2180             }
   2181 
   2182             au1_final_pred_buf_id[ME_OR_SKIP_DERIVED][i] = u1_me_pred_buf_idx;
   2183 
   2184             if(u1_is_cu_noisy && ps_ctxt->i4_alpha_stim_multiplier)
   2185             {
   2186                 ihevce_calc_variance(
   2187                     pv_pu_pred,
   2188                     i4_pred_stride,
   2189                     &i4_mean,
   2190                     &au4_pred_variance[ME_OR_SKIP_DERIVED][i],
   2191                     u1_part_ht,
   2192                     u1_part_wd,
   2193                     ps_ctxt->u1_is_hbd,
   2194                     0);
   2195 
   2196                 ai4_noise_term[ME_OR_SKIP_DERIVED][i] = ihevce_compute_noise_term(
   2197                     ps_ctxt->i4_alpha_stim_multiplier,
   2198                     pu4_src_variance[i],
   2199                     au4_pred_variance[ME_OR_SKIP_DERIVED][i]);
   2200 
   2201                 MULTIPLY_STIM_WITH_DISTORTION(
   2202                     au4_cost[ME_OR_SKIP_DERIVED][i],
   2203                     ai4_noise_term[ME_OR_SKIP_DERIVED][i],
   2204                     STIM_Q_FORMAT,
   2205                     ALPHA_Q_FORMAT);
   2206             }
   2207         }
   2208 
   2209         if(u1_eval_skip || u1_eval_merge)
   2210         {
   2211             pu_t s_pu, *ps_pu_merge;
   2212 
   2213             UWORD8 u1_is_any_top_available = 1;
   2214             UWORD8 u1_are_valid_merge_cands_available = 1;
   2215 
   2216             /* get the neighbour availability flags */
   2217             if((u1_num_parts > 1) && u1_single_mcl_flag)
   2218             { /* 8x8 SMPs take the 2Nx2N neighbours */
   2219                 ihevce_get_only_nbr_flag(
   2220                     &s_nbr,
   2221                     pu1_ctb_nbr_map,
   2222                     i4_nbr_map_stride,
   2223                     aps_cands[0]->as_inter_pu[0].b4_pos_x,
   2224                     aps_cands[0]->as_inter_pu[0].b4_pos_y,
   2225                     u1_cu_size >> 2,
   2226                     u1_cu_size >> 2);
   2227 
   2228                 /* Make the PU width and height as 8 */
   2229                 memcpy(&s_pu, ps_pu, sizeof(pu_t));
   2230                 s_pu.b4_pos_x = u1_cu_pos_x >> 2;
   2231                 s_pu.b4_pos_y = u1_cu_pos_y >> 2;
   2232                 s_pu.b4_wd = (u1_cu_size >> 2) - 1;
   2233                 s_pu.b4_ht = (u1_cu_size >> 2) - 1;
   2234 
   2235                 /* Give the local PU structure to MV merge */
   2236                 ps_pu_merge = &s_pu;
   2237             }
   2238             else
   2239             {
   2240                 ihevce_get_only_nbr_flag(
   2241                     &s_nbr,
   2242                     pu1_ctb_nbr_map,
   2243                     i4_nbr_map_stride,
   2244                     u1_pu_pos_x_4x4,
   2245                     u1_pu_pos_y_4x4,
   2246                     u1_part_wd >> 2,
   2247                     u1_part_ht >> 2);
   2248 
   2249                 u1_is_any_top_available = s_nbr.u1_top_avail || s_nbr.u1_top_rt_avail ||
   2250                                           s_nbr.u1_top_lt_avail;
   2251 
   2252                 if(!ps_ctxt->u1_use_merge_cand_from_top_row)
   2253                 {
   2254                     if(u1_is_any_top_available)
   2255                     {
   2256                         if(s_nbr.u1_left_avail || s_nbr.u1_bot_lt_avail)
   2257                         {
   2258                             s_nbr.u1_top_avail = 0;
   2259                             s_nbr.u1_top_rt_avail = 0;
   2260                             s_nbr.u1_top_lt_avail = 0;
   2261                         }
   2262                         else
   2263                         {
   2264                             u1_are_valid_merge_cands_available = 0;
   2265                         }
   2266                     }
   2267                 }
   2268 
   2269                 /* Actual PU passed to MV merge */
   2270                 ps_pu_merge = ps_pu;
   2271             }
   2272             if(u1_are_valid_merge_cands_available)
   2273             {
   2274                 u1_num_merge_cands = ihevce_mv_pred_merge(
   2275                     ps_mv_pred_ctxt,
   2276                     ps_pu_top_nbr,
   2277                     ps_pu_left_nbr,
   2278                     ps_pu_topleft_nbr,
   2279                     i4_nbr_4x4_left_stride,
   2280                     &s_nbr,
   2281                     NULL,
   2282                     ps_pu_merge,
   2283                     e_part_size,
   2284                     i,
   2285                     u1_single_mcl_flag,
   2286                     as_merge_cand,
   2287                     au1_is_top_used);
   2288 
   2289                 if(u1_num_merge_cands > u1_max_merge_candidates)
   2290                 {
   2291                     u1_num_merge_cands = u1_max_merge_candidates;
   2292                 }
   2293 
   2294                 u1_num_merge_cands = ihevce_merge_candidate_seive(
   2295                     &s_nbr,
   2296                     as_merge_cand,
   2297                     au1_is_top_used,
   2298                     u1_num_merge_cands,
   2299                     ps_ctxt->u1_use_merge_cand_from_top_row || !u1_is_any_top_available);
   2300 
   2301                 for(j = 0; j < u1_num_merge_cands; j++)
   2302                 {
   2303                     s_merge_prms.au1_valid_merge_indices[j] = j;
   2304                 }
   2305 
   2306                 au4_cost[MERGE_DERIVED][i] = ihevce_determine_best_merge_pu(
   2307                     &s_merge_prms,
   2308                     &aps_cands[MERGE_DERIVED]->as_inter_pu[i],
   2309                     &aps_cands[ME_OR_SKIP_DERIVED]->as_inter_pu[i],
   2310                     pv_pu_src,
   2311                     au4_cost[ME_OR_SKIP_DERIVED][i],
   2312                     i4_pred_buf_offset,
   2313                     u1_num_merge_cands,
   2314                     i,
   2315                     u1_eval_skip);
   2316             }
   2317             else
   2318             {
   2319                 au4_cost[MERGE_DERIVED][i] = INT_MAX;
   2320             }
   2321 
   2322             au4_cost[(i) ? MIXED_MODE_TYPE1 : MIXED_MODE_TYPE0][i] = au4_cost[MERGE_DERIVED][i];
   2323 
   2324             if(u1_eval_skip)
   2325             {
   2326                 /* This statement ensures that the skip candidate is always added */
   2327                 au4_cost[ME_OR_SKIP_DERIVED][i] =
   2328                     (au4_cost[MERGE_DERIVED][0] < INT_MAX) ? SKIP_MODE_COST : INT_MAX;
   2329                 au1_final_pred_buf_id[ME_OR_SKIP_DERIVED][i] =
   2330                     au1_final_pred_buf_id[MERGE_DERIVED][i];
   2331             }
   2332             else
   2333             {
   2334                 au4_cost[ME_OR_SKIP_DERIVED][i] += ps_ctxt->pai4_mv_cost[u1_me_cand_list_idx][i];
   2335                 au4_cost[(i) ? MIXED_MODE_TYPE0 : MIXED_MODE_TYPE1][i] =
   2336                     au4_cost[ME_OR_SKIP_DERIVED][i];
   2337             }
   2338 
   2339             au1_final_pred_buf_id[(i) ? MIXED_MODE_TYPE1 : MIXED_MODE_TYPE0][i] =
   2340                 au1_final_pred_buf_id[MERGE_DERIVED][i];
   2341             au1_final_pred_buf_id[(i) ? MIXED_MODE_TYPE0 : MIXED_MODE_TYPE1][i] =
   2342                 au1_final_pred_buf_id[ME_OR_SKIP_DERIVED][i];
   2343         }
   2344         else
   2345         {
   2346             au4_cost[ME_OR_SKIP_DERIVED][i] += ps_ctxt->pai4_mv_cost[u1_me_cand_list_idx][i];
   2347         }
   2348 
   2349         if(!i && (u1_num_parts > 1) && u1_eval_merge)
   2350         {
   2351             ihevce_set_inter_nbr_map(
   2352                 pu1_ctb_nbr_map,
   2353                 i4_nbr_map_stride,
   2354                 u1_pu_pos_x_4x4,
   2355                 u1_pu_pos_y_4x4,
   2356                 (u1_part_wd >> 2),
   2357                 (u1_part_ht >> 2),
   2358                 1);
   2359             ihevce_populate_nbr_4x4_with_pu_data(
   2360                 ps_cu_nbr_buf, &aps_cands[ME_OR_SKIP_DERIVED]->as_inter_pu[i], u1_cu_size >> 2);
   2361 
   2362             if(u1_part_wd < u1_cu_size)
   2363             {
   2364                 i4_pred_buf_offset = i4_src_buf_offset = u1_part_wd;
   2365 
   2366                 if(!u1_single_mcl_flag) /* 8x8 SMPs take the 2Nx2N neighbours */
   2367                 {
   2368                     ps_cu_nbr_buf += (u1_part_wd >> 2);
   2369                     ps_pu_left_nbr = ps_cu_nbr_buf - 1;
   2370                     ps_pu_top_nbr += (u1_part_wd >> 2);
   2371                     ps_pu_topleft_nbr = ps_pu_top_nbr - 1;
   2372 
   2373                     i4_nbr_4x4_left_stride = (u1_cu_size >> 2);
   2374                 }
   2375             }
   2376             else if(u1_part_ht < u1_cu_size)
   2377             {
   2378                 i4_pred_buf_offset = u1_part_ht * i4_pred_stride;
   2379                 i4_src_buf_offset = u1_part_ht * i4_src_stride;
   2380 
   2381                 if(!u1_single_mcl_flag) /* 8x8 SMPs take the 2Nx2N neighbours */
   2382                 {
   2383                     ps_cu_nbr_buf += (u1_part_ht >> 2) * (u1_cu_size >> 2);
   2384                     ps_pu_left_nbr += (u1_part_ht >> 2) * i4_nbr_4x4_left_stride;
   2385                     ps_pu_top_nbr = ps_cu_nbr_buf - (u1_cu_size >> 2);
   2386                     ps_pu_topleft_nbr = ps_pu_left_nbr - i4_nbr_4x4_left_stride;
   2387                 }
   2388             }
   2389 
   2390             i4_pred_buf_offset *= u1_num_bytes_per_pel;
   2391             i4_src_buf_offset *= u1_num_bytes_per_pel;
   2392 
   2393             aps_cands[MIXED_MODE_TYPE0]->as_inter_pu[0] = aps_cands[MERGE_DERIVED]->as_inter_pu[0];
   2394         }
   2395         else if(!i && (u1_num_parts > 1) && (!u1_eval_merge))
   2396         {
   2397             if(u1_part_wd < u1_cu_size)
   2398             {
   2399                 i4_pred_buf_offset = i4_src_buf_offset = u1_part_wd;
   2400             }
   2401             else if(u1_part_ht < u1_cu_size)
   2402             {
   2403                 i4_pred_buf_offset = u1_part_ht * i4_pred_stride;
   2404                 i4_src_buf_offset = u1_part_ht * i4_src_stride;
   2405             }
   2406 
   2407             i4_pred_buf_offset *= u1_num_bytes_per_pel;
   2408             i4_src_buf_offset *= u1_num_bytes_per_pel;
   2409         }
   2410         else if(i && (u1_num_parts > 1) && u1_eval_merge)
   2411         {
   2412             aps_cands[MIXED_MODE_TYPE1]->as_inter_pu[1] = aps_cands[MERGE_DERIVED]->as_inter_pu[1];
   2413         }
   2414     }
   2415 
   2416     /* Adding a skip candidate */
   2417     if((u1_eval_merge) && (0 == u1_part_type))
   2418     {
   2419         cu_inter_cand_t *ps_cand = &ps_ctxt->ps_cu_inter_merge_skip->as_cu_inter_merge_skip_cand
   2420                                         [MAX_NUM_CU_MERGE_SKIP_CAND - 1 -
   2421                                          ps_ctxt->ps_cu_inter_merge_skip->u1_num_skip_cands];
   2422 
   2423         (*ps_cand) = (*aps_cands[MERGE_DERIVED]);
   2424 
   2425         ps_cand->b1_skip_flag = 1;
   2426 
   2427         aps_cands[MIXED_MODE_TYPE1] = ps_cand;
   2428         au4_cost[MIXED_MODE_TYPE1][0] = (au4_cost[MERGE_DERIVED][0] < INT_MAX) ? SKIP_MODE_COST
   2429                                                                                : INT_MAX;
   2430     }
   2431 
   2432     /* Sort and populate */
   2433     u1_skip_or_merge_cand_is_valid = ihevce_merge_cands_with_existing_best(
   2434         ps_cu_mode_info,
   2435         aps_cands,
   2436         as_mvp_winner,
   2437         au4_cost,
   2438         ppv_pred_buf_list,
   2439         au1_final_pred_buf_id,
   2440         &ps_pred_buf_info->u4_is_buf_in_use,
   2441         &ps_ctxt->ps_cu_inter_merge_skip->u1_num_merge_cands,
   2442         &ps_ctxt->ps_cu_inter_merge_skip->u1_num_skip_cands,
   2443         &ps_ctxt->ps_mixed_modes_datastore->u1_num_mixed_mode_type0_cands,
   2444         &ps_ctxt->ps_mixed_modes_datastore->u1_num_mixed_mode_type1_cands,
   2445         au1_merge_pred_buf_idx_array,
   2446         ps_ctxt->ps_cmn_utils_optimised_function_list->pf_copy_2d,
   2447 
   2448         i4_pred_stride,
   2449         i4_max_num_inter_rdopt_cands,
   2450         u1_cu_size,
   2451         u1_part_type,
   2452         u1_eval_merge,
   2453         u1_eval_skip,
   2454         u1_num_bytes_per_pel);
   2455 
   2456     return u1_skip_or_merge_cand_is_valid;
   2457 }
   2458 
   2459 static __inline void ihevce_redundant_candidate_pruner(inter_cu_mode_info_t *ps_inter_cu_mode_info)
   2460 {
   2461     WORD8 i, j;
   2462     WORD8 i1_num_merge_vs_mvds;
   2463 
   2464     UWORD8 au1_redundant_cand_indices[MAX_NUM_INTER_RDO_CANDS] = { 0 };
   2465 
   2466     for(i = 0; i < (ps_inter_cu_mode_info->u1_num_inter_cands - 1); i++)
   2467     {
   2468         if(au1_redundant_cand_indices[i] || ps_inter_cu_mode_info->aps_cu_data[i]->b1_skip_flag)
   2469         {
   2470             continue;
   2471         }
   2472 
   2473         for(j = i + 1; j < ps_inter_cu_mode_info->u1_num_inter_cands; j++)
   2474         {
   2475             if(au1_redundant_cand_indices[j] || ps_inter_cu_mode_info->aps_cu_data[j]->b1_skip_flag)
   2476             {
   2477                 continue;
   2478             }
   2479 
   2480             i1_num_merge_vs_mvds = 0;
   2481 
   2482             if(ps_inter_cu_mode_info->aps_cu_data[j]->b3_part_size ==
   2483                ps_inter_cu_mode_info->aps_cu_data[i]->b3_part_size)
   2484             {
   2485                 if(ihevce_compare_pu_mv_t(
   2486                        &ps_inter_cu_mode_info->aps_cu_data[i]->as_inter_pu->mv,
   2487                        &ps_inter_cu_mode_info->aps_cu_data[j]->as_inter_pu->mv,
   2488                        ps_inter_cu_mode_info->aps_cu_data[i]->as_inter_pu->b2_pred_mode,
   2489                        ps_inter_cu_mode_info->aps_cu_data[j]->as_inter_pu->b2_pred_mode))
   2490                 {
   2491                     i1_num_merge_vs_mvds +=
   2492                         ps_inter_cu_mode_info->aps_cu_data[i]->as_inter_pu->b1_merge_flag -
   2493                         ps_inter_cu_mode_info->aps_cu_data[j]->as_inter_pu->b1_merge_flag;
   2494 
   2495                     if(ps_inter_cu_mode_info->aps_cu_data[i]->b3_part_size)
   2496                     {
   2497                         if(ihevce_compare_pu_mv_t(
   2498                                &ps_inter_cu_mode_info->aps_cu_data[i]->as_inter_pu[1].mv,
   2499                                &ps_inter_cu_mode_info->aps_cu_data[j]->as_inter_pu[1].mv,
   2500                                ps_inter_cu_mode_info->aps_cu_data[i]->as_inter_pu[1].b2_pred_mode,
   2501                                ps_inter_cu_mode_info->aps_cu_data[j]->as_inter_pu[1].b2_pred_mode))
   2502                         {
   2503                             i1_num_merge_vs_mvds +=
   2504                                 ps_inter_cu_mode_info->aps_cu_data[i]->as_inter_pu[1].b1_merge_flag -
   2505                                 ps_inter_cu_mode_info->aps_cu_data[j]->as_inter_pu[1].b1_merge_flag;
   2506                         }
   2507                     }
   2508                 }
   2509             }
   2510 
   2511             if(i1_num_merge_vs_mvds != 0)
   2512             {
   2513                 au1_redundant_cand_indices[(i1_num_merge_vs_mvds > 0) ? j : i] = 1;
   2514             }
   2515         }
   2516     }
   2517 
   2518     for(i = 0; i < ps_inter_cu_mode_info->u1_num_inter_cands; i++)
   2519     {
   2520         if(au1_redundant_cand_indices[i])
   2521         {
   2522             memmove(
   2523                 &ps_inter_cu_mode_info->aps_cu_data[i],
   2524                 &ps_inter_cu_mode_info->aps_cu_data[i + 1],
   2525                 (ps_inter_cu_mode_info->u1_num_inter_cands - i - 1) *
   2526                     sizeof(ps_inter_cu_mode_info->aps_cu_data[i]));
   2527 
   2528             memmove(
   2529                 &ps_inter_cu_mode_info->au4_cost[i],
   2530                 &ps_inter_cu_mode_info->au4_cost[i + 1],
   2531                 (ps_inter_cu_mode_info->u1_num_inter_cands - i - 1) *
   2532                     sizeof(ps_inter_cu_mode_info->au4_cost[i]));
   2533 
   2534             memmove(
   2535                 &ps_inter_cu_mode_info->au1_pred_buf_idx[i],
   2536                 &ps_inter_cu_mode_info->au1_pred_buf_idx[i + 1],
   2537                 (ps_inter_cu_mode_info->u1_num_inter_cands - i - 1) *
   2538                     sizeof(ps_inter_cu_mode_info->au1_pred_buf_idx[i]));
   2539 
   2540             memmove(
   2541                 &au1_redundant_cand_indices[i],
   2542                 &au1_redundant_cand_indices[i + 1],
   2543                 (ps_inter_cu_mode_info->u1_num_inter_cands - i - 1) *
   2544                     sizeof(au1_redundant_cand_indices[i]));
   2545 
   2546             ps_inter_cu_mode_info->u1_num_inter_cands--;
   2547             i--;
   2548         }
   2549     }
   2550 }
   2551 
   2552 /*!
   2553 ******************************************************************************
   2554 * \if Function name : ihevce_inter_cand_sifter \endif
   2555 *
   2556 * \brief
   2557 *    Selects the best inter candidate modes amongst ME, merge,
   2558 *    skip and mixed modes. Also computes corresponding preds
   2559 *
   2560 * \author
   2561 *  Ittiam
   2562 *
   2563 *****************************************************************************
   2564 */
   2565 void ihevce_inter_cand_sifter(ihevce_inter_cand_sifter_prms_t *ps_ctxt)
   2566 {
   2567     PF_SAD_FXN_T pf_sad_func;
   2568 
   2569     UWORD8 au1_final_cand_idx[MAX_INTER_CU_CANDIDATES];
   2570     UWORD8 au1_part_types_evaluated[MAX_INTER_CU_CANDIDATES];
   2571     UWORD8 u1_num_unique_parts;
   2572     UWORD8 i, j;
   2573     UWORD32 au4_src_variance[NUM_INTER_PU_PARTS];
   2574     WORD32 i4_mean;
   2575 
   2576     cu_inter_cand_t *ps_me_cands = ps_ctxt->ps_me_cands;
   2577     inter_cu_mode_info_t *ps_cu_mode_info = ps_ctxt->ps_inter_cu_mode_info;
   2578 
   2579     UWORD8 u1_diff_skip_cand_flag = 1;
   2580     WORD8 i1_skip_cand_from_merge_idx = -1;
   2581     WORD8 i1_final_skip_cand_merge_idx = -1;
   2582     UWORD8 u1_max_num_part_types_to_select = MAX_INTER_CU_CANDIDATES;
   2583     UWORD8 u1_num_me_cands = ps_ctxt->u1_num_me_cands;
   2584     UWORD8 u1_num_parts_evaluated_for_merge = 0;
   2585     UWORD8 u1_is_cu_noisy = ps_ctxt->u1_is_cu_noisy;
   2586 
   2587     if((ps_ctxt->u1_quality_preset >= IHEVCE_QUALITY_P3) && (ps_ctxt->i1_slice_type == BSLICE))
   2588     {
   2589         u1_max_num_part_types_to_select = 1;
   2590     }
   2591 
   2592     {
   2593         pf_sad_func = (ps_ctxt->u1_use_satd_for_merge_eval) ? compute_satd_8bit
   2594                                                             : ps_ctxt->pf_evalsad_pt_npu_mxn_8bit;
   2595     }
   2596 
   2597     u1_num_unique_parts = ihevce_get_num_part_types_in_me_cand_list(
   2598         ps_me_cands,
   2599         au1_part_types_evaluated,
   2600         au1_final_cand_idx,
   2601         &u1_diff_skip_cand_flag,
   2602         &i1_skip_cand_from_merge_idx,
   2603         &i1_final_skip_cand_merge_idx,
   2604         u1_max_num_part_types_to_select,
   2605         u1_num_me_cands);
   2606 
   2607     if((u1_num_me_cands + u1_diff_skip_cand_flag) && u1_is_cu_noisy &&
   2608        ps_ctxt->i4_alpha_stim_multiplier)
   2609     {
   2610         ihevce_calc_variance(
   2611             ps_ctxt->pv_src,
   2612             ps_ctxt->i4_src_strd,
   2613             &i4_mean,
   2614             &ps_cu_mode_info->u4_src_variance,
   2615             ps_ctxt->u1_cu_size,
   2616             ps_ctxt->u1_cu_size,
   2617             ps_ctxt->u1_is_hbd,
   2618             0);
   2619     }
   2620 
   2621     if(DISABLE_SKIP_AND_MERGE_WHEN_NOISY && u1_is_cu_noisy)
   2622     {
   2623         u1_diff_skip_cand_flag = 0;
   2624     }
   2625     else if(!DISABLE_SKIP_AND_MERGE_WHEN_NOISY && u1_is_cu_noisy)
   2626     {
   2627         if(ps_ctxt->u1_cu_size > MAX_CU_SIZE_WHERE_MERGE_AND_SKIPS_ENABLED_AND_WHEN_NOISY)
   2628         {
   2629             u1_diff_skip_cand_flag = 0;
   2630         }
   2631     }
   2632 
   2633     for(i = 0; i < u1_num_me_cands + u1_diff_skip_cand_flag; i++)
   2634     {
   2635         UWORD8 u1_part_type;
   2636         UWORD8 u1_eval_skip;
   2637         UWORD8 u1_eval_merge;
   2638         UWORD8 u1_valid_cand;
   2639 
   2640         if(i == u1_num_me_cands)
   2641         {
   2642             u1_eval_skip = 1;
   2643             u1_eval_merge = 0;
   2644             u1_part_type = 0;
   2645         }
   2646         else
   2647         {
   2648             u1_eval_skip = 0;
   2649             u1_part_type = ps_me_cands[i].b3_part_size;
   2650 
   2651             if(u1_num_parts_evaluated_for_merge >= u1_num_unique_parts)
   2652             {
   2653                 u1_eval_merge = 0;
   2654                 u1_num_parts_evaluated_for_merge = u1_num_unique_parts;
   2655             }
   2656             else
   2657             {
   2658                 u1_eval_merge = (i == au1_final_cand_idx[u1_num_parts_evaluated_for_merge]);
   2659             }
   2660 
   2661             for(j = 0; (j < u1_num_parts_evaluated_for_merge) && (u1_eval_merge); j++)
   2662             {
   2663                 if(u1_part_type == au1_part_types_evaluated[j])
   2664                 {
   2665                     u1_eval_merge = 0;
   2666                     break;
   2667                 }
   2668             }
   2669         }
   2670 
   2671         if(u1_is_cu_noisy && u1_part_type && ps_ctxt->i4_alpha_stim_multiplier)
   2672         {
   2673             void *pv_src = ps_ctxt->pv_src;
   2674             UWORD8 u1_pu_wd = (ps_me_cands[i].as_inter_pu[0].b4_wd + 1) << 2;
   2675             UWORD8 u1_pu_ht = (ps_me_cands[i].as_inter_pu[0].b4_ht + 1) << 2;
   2676 
   2677             ihevce_calc_variance(
   2678                 pv_src,
   2679                 ps_ctxt->i4_src_strd,
   2680                 &i4_mean,
   2681                 &au4_src_variance[0],
   2682                 u1_pu_ht,
   2683                 u1_pu_wd,
   2684                 ps_ctxt->u1_is_hbd,
   2685                 0);
   2686 
   2687             pv_src = (void *) (((UWORD8 *) pv_src) +
   2688                 ((ps_ctxt->u1_cu_size == u1_pu_wd) ? ps_ctxt->i4_src_strd * u1_pu_ht : u1_pu_wd)
   2689                 * (ps_ctxt->u1_is_hbd + 1));
   2690             u1_pu_wd = (ps_me_cands[i].as_inter_pu[1].b4_wd + 1) << 2;
   2691             u1_pu_ht = (ps_me_cands[i].as_inter_pu[1].b4_ht + 1) << 2;
   2692 
   2693             ihevce_calc_variance(
   2694                 pv_src,
   2695                 ps_ctxt->i4_src_strd,
   2696                 &i4_mean,
   2697                 &au4_src_variance[1],
   2698                 u1_pu_ht,
   2699                 u1_pu_wd,
   2700                 ps_ctxt->u1_is_hbd,
   2701                 0);
   2702         }
   2703         else if(u1_is_cu_noisy && !u1_part_type && ps_ctxt->i4_alpha_stim_multiplier)
   2704         {
   2705             au4_src_variance[0] = ps_cu_mode_info->u4_src_variance;
   2706         }
   2707 
   2708         if(DISABLE_SKIP_AND_MERGE_WHEN_NOISY && u1_is_cu_noisy)
   2709         {
   2710             u1_eval_merge = 0;
   2711         }
   2712         else if(!DISABLE_SKIP_AND_MERGE_WHEN_NOISY && u1_is_cu_noisy)
   2713         {
   2714             if(ps_ctxt->u1_cu_size > MAX_CU_SIZE_WHERE_MERGE_AND_SKIPS_ENABLED_AND_WHEN_NOISY)
   2715             {
   2716                 u1_eval_merge = 0;
   2717             }
   2718         }
   2719 
   2720         u1_valid_cand = ihevce_compute_pred_and_populate_modes(
   2721             ps_ctxt,
   2722             pf_sad_func,
   2723             au4_src_variance,
   2724             u1_part_type,
   2725             MIN(i, (u1_num_me_cands - 1)),
   2726             u1_eval_merge,
   2727             u1_eval_skip);
   2728 
   2729         u1_num_parts_evaluated_for_merge += u1_eval_merge;
   2730 
   2731         /* set the neighbour map to 0 */
   2732         if(u1_part_type)
   2733         {
   2734             ihevce_set_nbr_map(
   2735                 ps_ctxt->pu1_ctb_nbr_map,
   2736                 ps_ctxt->i4_ctb_nbr_map_stride,
   2737                 (ps_ctxt->u1_cu_pos_x >> 2),
   2738                 (ps_ctxt->u1_cu_pos_y >> 2),
   2739                 (ps_ctxt->u1_cu_size >> 2),
   2740                 0);
   2741         }
   2742     }
   2743 
   2744     ihevce_redundant_candidate_pruner(ps_ctxt->ps_inter_cu_mode_info);
   2745 }
   2746