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  * @file
     23  *  ihevcd_mv_pred_merge.c
     24  *
     25  * @brief
     26  *  Contains functions for motion vector merge candidates derivation
     27  *
     28  * @author
     29  *  Ittiam
     30  *
     31  * @par List of Functions:
     32  * - ihevce_compare_pu_mv_t()
     33  * - ihevce_mv_pred_merge()
     34  *
     35  * @remarks
     36  *  None
     37  *
     38  *******************************************************************************
     39  */
     40 /*****************************************************************************/
     41 /* File Includes                                                             */
     42 /*****************************************************************************/
     43 /* System include files */
     44 #include <stdio.h>
     45 #include <string.h>
     46 #include <stdlib.h>
     47 #include <assert.h>
     48 #include <stdarg.h>
     49 #include <math.h>
     50 
     51 /* User include files */
     52 #include "ihevc_typedefs.h"
     53 #include "itt_video_api.h"
     54 #include "ihevce_api.h"
     55 
     56 #include "rc_cntrl_param.h"
     57 #include "rc_frame_info_collector.h"
     58 #include "rc_look_ahead_params.h"
     59 
     60 #include "ihevc_defs.h"
     61 #include "ihevc_macros.h"
     62 #include "ihevc_debug.h"
     63 #include "ihevc_structs.h"
     64 #include "ihevc_platform_macros.h"
     65 #include "ihevc_deblk.h"
     66 #include "ihevc_itrans_recon.h"
     67 #include "ihevc_chroma_itrans_recon.h"
     68 #include "ihevc_chroma_intra_pred.h"
     69 #include "ihevc_intra_pred.h"
     70 #include "ihevc_inter_pred.h"
     71 #include "ihevc_mem_fns.h"
     72 #include "ihevc_padding.h"
     73 #include "ihevc_weighted_pred.h"
     74 #include "ihevc_sao.h"
     75 #include "ihevc_resi_trans.h"
     76 #include "ihevc_quant_iquant_ssd.h"
     77 #include "ihevc_cabac_tables.h"
     78 #include "ihevc_common_tables.h"
     79 
     80 #include "ihevce_defs.h"
     81 #include "ihevce_hle_interface.h"
     82 #include "ihevce_lap_enc_structs.h"
     83 #include "ihevce_multi_thrd_structs.h"
     84 #include "ihevce_me_common_defs.h"
     85 #include "ihevce_had_satd.h"
     86 #include "ihevce_error_codes.h"
     87 #include "ihevce_bitstream.h"
     88 #include "ihevce_cabac.h"
     89 #include "ihevce_rdoq_macros.h"
     90 #include "ihevce_function_selector.h"
     91 #include "ihevce_enc_structs.h"
     92 #include "ihevce_entropy_structs.h"
     93 #include "ihevce_cmn_utils_instr_set_router.h"
     94 #include "ihevce_enc_loop_structs.h"
     95 #include "hme_datatype.h"
     96 #include "hme_interface.h"
     97 #include "hme_common_defs.h"
     98 #include "hme_defs.h"
     99 #include "ihevce_mv_pred.h"
    100 #include "ihevce_mv_pred_merge.h"
    101 #include "ihevce_common_utils.h"
    102 
    103 /*****************************************************************************/
    104 /* Function Definitions                                                      */
    105 /*****************************************************************************/
    106 
    107 /**
    108  *******************************************************************************
    109  *
    110  * @brief Function scaling temporal motion vector
    111  *
    112  *
    113  * @par Description:
    114  *   Scales mv based on difference between current POC and current
    115  *   reference POC and neighbour reference poc
    116  *
    117  * @param[inout] mv
    118  *   motion vector to be scaled
    119  *
    120  * @param[in] cur_ref_poc
    121  *   Current PU refernce pic poc
    122  *
    123  * @param[in] nbr_ref_poc
    124  *   Neighbor PU reference pic poc
    125  *
    126  * @param[in] cur_poc
    127  *   Picture order count of current pic
    128  *
    129  * @returns
    130  *  None
    131  *
    132  * @remarks
    133  *
    134  *******************************************************************************
    135  */
    136 void ihevce_scale_collocated_mv(
    137     mv_t *ps_mv, WORD32 cur_ref_poc, WORD32 col_ref_poc, WORD32 col_poc, WORD32 cur_poc)
    138 {
    139     WORD32 td, tb, tx;
    140     WORD32 dist_scale_factor;
    141     WORD32 mvx, mvy;
    142 
    143     td = CLIP_S8(col_poc - col_ref_poc);
    144     tb = CLIP_S8(cur_poc - cur_ref_poc);
    145 
    146     tx = (16384 + (abs(td) >> 1)) / td;
    147 
    148     dist_scale_factor = (tb * tx + 32) >> 6;
    149     dist_scale_factor = CLIP3(dist_scale_factor, -4096, 4095);
    150 
    151     mvx = ps_mv->i2_mvx;
    152     mvy = ps_mv->i2_mvy;
    153 
    154     mvx = SIGN(dist_scale_factor * mvx) * ((abs(dist_scale_factor * mvx) + 127) >> 8);
    155     mvy = SIGN(dist_scale_factor * mvy) * ((abs(dist_scale_factor * mvy) + 127) >> 8);
    156 
    157     ps_mv->i2_mvx = CLIP_S16(mvx);
    158     ps_mv->i2_mvy = CLIP_S16(mvy);
    159 
    160 } /* End of ihevce_scale_collocated_mv */
    161 
    162 void ihevce_collocated_mvp(
    163     mv_pred_ctxt_t *ps_mv_ctxt,
    164     pu_t *ps_pu,
    165     mv_t *ps_mv_col,
    166     WORD32 *pu4_avail_col_flag,
    167     WORD32 use_pu_ref_idx,
    168     WORD32 x_col,
    169     WORD32 y_col)
    170 {
    171     sps_t *ps_sps = ps_mv_ctxt->ps_sps;
    172     slice_header_t *ps_slice_hdr = ps_mv_ctxt->ps_slice_hdr;
    173     recon_pic_buf_t *ps_col_ref_buf;
    174     WORD32 xp_col, yp_col;  //In pixel unit
    175     WORD32 col_ctb_x, col_ctb_y;  //In CTB unit
    176     mv_t as_mv_col[2];
    177     WORD32 log2_ctb_size;
    178     WORD32 ctb_size;
    179     WORD32 avail_col;
    180     WORD32 col_ctb_idx, pu_cnt;
    181     WORD32 au4_list_col[2];
    182     WORD32 num_minpu_in_ctb;
    183     UWORD8 *pu1_pic_pu_map_ctb;
    184     pu_col_mv_t *ps_col_mv;
    185     WORD32 part_pos_y;
    186 
    187     part_pos_y = ps_pu->b4_pos_y << 2;
    188 
    189     log2_ctb_size = ps_sps->i1_log2_ctb_size;
    190     ctb_size = (1 << log2_ctb_size);
    191 
    192     avail_col = 1;
    193 
    194     /* Initializing reference list */
    195     if((ps_slice_hdr->i1_slice_type == BSLICE) && (ps_slice_hdr->i1_collocated_from_l0_flag == 0))
    196     {
    197         /* L1 */
    198         ps_col_ref_buf = ps_mv_ctxt->ps_ref_list[1][ps_slice_hdr->i1_collocated_ref_idx];
    199     }
    200     else
    201     {
    202         /* L0 */
    203         ps_col_ref_buf = ps_mv_ctxt->ps_ref_list[0][ps_slice_hdr->i1_collocated_ref_idx];
    204     }
    205     num_minpu_in_ctb = (ctb_size / MIN_PU_SIZE) * (ctb_size / MIN_PU_SIZE);
    206 
    207     if(((part_pos_y >> log2_ctb_size) == (y_col >> log2_ctb_size)) &&
    208        (((x_col + (ps_mv_ctxt->i4_ctb_x << log2_ctb_size)) < ps_sps->i2_pic_width_in_luma_samples) ||
    209         ps_mv_ctxt->ai4_tile_xtra_ctb[2]) &&
    210        ((((y_col + (ps_mv_ctxt->i4_ctb_y << log2_ctb_size)) <
    211           ps_sps->i2_pic_height_in_luma_samples) ||
    212          ps_mv_ctxt->ai4_tile_xtra_ctb[3])))
    213     {
    214         xp_col = ((x_col >> 4) << 4);
    215         yp_col = ((y_col >> 4) << 4);
    216         col_ctb_x = ps_mv_ctxt->i4_ctb_x + (xp_col >> log2_ctb_size);
    217         col_ctb_y = ps_mv_ctxt->i4_ctb_y + (yp_col >> log2_ctb_size);
    218 
    219         /* pu1_frm_pu_map has (i2_pic_wd_in_ctb + 1) CTBs for stride */
    220         col_ctb_idx = col_ctb_x + (col_ctb_y) * (ps_sps->i2_pic_wd_in_ctb + 1);
    221 
    222         if(xp_col == ctb_size)
    223             xp_col = 0;
    224 
    225         pu1_pic_pu_map_ctb = ps_col_ref_buf->pu1_frm_pu_map + col_ctb_idx * num_minpu_in_ctb;
    226 
    227         pu_cnt = pu1_pic_pu_map_ctb[(yp_col >> 2) * (ctb_size / MIN_PU_SIZE) + (xp_col >> 2)];
    228 
    229         /* ps_frm_col_mv has (i2_pic_wd_in_ctb + 1) CTBs for stride */
    230         ps_col_mv = ps_col_ref_buf->ps_frm_col_mv +
    231                     (col_ctb_y * (ps_sps->i2_pic_wd_in_ctb + 1) + col_ctb_x) * num_minpu_in_ctb +
    232                     pu_cnt;
    233     }
    234     else
    235         avail_col = 0;
    236 
    237     if((avail_col == 0) || (ps_col_mv->b1_intra_flag == 1) ||
    238        (ps_slice_hdr->i1_slice_temporal_mvp_enable_flag == 0))
    239     {
    240         pu4_avail_col_flag[0] = 0;
    241         pu4_avail_col_flag[1] = 0;
    242         ps_mv_col[0].i2_mvx = 0;
    243         ps_mv_col[0].i2_mvy = 0;
    244         ps_mv_col[1].i2_mvx = 0;
    245         ps_mv_col[1].i2_mvy = 0;
    246     }
    247     else
    248     {
    249         WORD32 au4_ref_idx_col[2];
    250         WORD32 pred_flag_l0, pred_flag_l1;
    251         pred_flag_l0 = (ps_col_mv->b2_pred_mode != PRED_L1);
    252         pred_flag_l1 = (ps_col_mv->b2_pred_mode != PRED_L0);
    253 
    254         if(pred_flag_l0 == 0)
    255         {
    256             as_mv_col[0] = ps_col_mv->s_l1_mv;
    257             au4_ref_idx_col[0] = ps_col_mv->i1_l1_ref_idx;
    258             au4_list_col[0] = 1; /* L1 */
    259 
    260             as_mv_col[1] = ps_col_mv->s_l1_mv;
    261             au4_ref_idx_col[1] = ps_col_mv->i1_l1_ref_idx;
    262             au4_list_col[1] = 1; /* L1 */
    263         }
    264         else
    265         {
    266             if(pred_flag_l1 == 0)
    267             {
    268                 as_mv_col[0] = ps_col_mv->s_l0_mv;
    269                 au4_ref_idx_col[0] = ps_col_mv->i1_l0_ref_idx;
    270                 au4_list_col[0] = 0; /* L1 */
    271 
    272                 as_mv_col[1] = ps_col_mv->s_l0_mv;
    273                 au4_ref_idx_col[1] = ps_col_mv->i1_l0_ref_idx;
    274                 au4_list_col[1] = 0; /* L1 */
    275             }
    276             else
    277             {
    278                 if(1 == ps_slice_hdr->i1_low_delay_flag)
    279                 {
    280                     as_mv_col[0] = ps_col_mv->s_l0_mv;
    281                     au4_ref_idx_col[0] = ps_col_mv->i1_l0_ref_idx;
    282                     au4_list_col[0] = 0; /* L0 */
    283 
    284                     as_mv_col[1] = ps_col_mv->s_l1_mv;
    285                     au4_ref_idx_col[1] = ps_col_mv->i1_l1_ref_idx;
    286                     au4_list_col[1] = 1; /* L1 */
    287                 }
    288                 else
    289                 {
    290                     if(0 == ps_slice_hdr->i1_collocated_from_l0_flag)
    291                     {
    292                         as_mv_col[0] = ps_col_mv->s_l0_mv;
    293                         au4_ref_idx_col[0] = ps_col_mv->i1_l0_ref_idx;
    294 
    295                         as_mv_col[1] = ps_col_mv->s_l0_mv;
    296                         au4_ref_idx_col[1] = ps_col_mv->i1_l0_ref_idx;
    297                     }
    298                     else
    299                     {
    300                         as_mv_col[0] = ps_col_mv->s_l1_mv;
    301                         au4_ref_idx_col[0] = ps_col_mv->i1_l1_ref_idx;
    302 
    303                         as_mv_col[1] = ps_col_mv->s_l1_mv;
    304                         au4_ref_idx_col[1] = ps_col_mv->i1_l1_ref_idx;
    305                     }
    306 
    307                     au4_list_col[0] =
    308                         ps_slice_hdr->i1_collocated_from_l0_flag; /* L"collocated_from_l0_flag" */
    309                     au4_list_col[1] =
    310                         ps_slice_hdr->i1_collocated_from_l0_flag; /* L"collocated_from_l0_flag" */
    311                 }
    312             }
    313         }
    314         avail_col = 1;
    315         {
    316             WORD32 cur_poc, col_poc, col_ref_poc_l0, cur_ref_poc;
    317             WORD32 col_ref_poc_l0_lt, cur_ref_poc_lt;
    318             WORD32 ref_idx_l0, ref_idx_l1;
    319 
    320             if(use_pu_ref_idx)
    321             {
    322                 ref_idx_l0 = ps_pu->mv.i1_l0_ref_idx;
    323                 ref_idx_l1 = ps_pu->mv.i1_l1_ref_idx;
    324             }
    325             else
    326             {
    327                 ref_idx_l0 = 0;
    328                 ref_idx_l1 = 0;
    329             }
    330 
    331             col_poc = ps_col_ref_buf->i4_poc;
    332             cur_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
    333 
    334             if(-1 != ref_idx_l0)
    335             {
    336                 if(au4_list_col[0] == 0)
    337                 {
    338                     col_ref_poc_l0 = ps_col_ref_buf->ai4_col_l0_poc[au4_ref_idx_col[0]];
    339                     col_ref_poc_l0_lt = 0; /* Encoder has only short term references */
    340                 }
    341                 else
    342                 {
    343                     col_ref_poc_l0 = ps_col_ref_buf->ai4_col_l1_poc[au4_ref_idx_col[0]];
    344                     col_ref_poc_l0_lt = 0;
    345                 }
    346                 /* L0 collocated mv */
    347                 cur_ref_poc = ps_mv_ctxt->ps_ref_list[0][ref_idx_l0]->i4_poc;
    348                 cur_ref_poc_lt = 0;
    349 
    350                 {
    351                     pu4_avail_col_flag[0] = 1;
    352 
    353                     /*if(cur_ref_poc_lt || ((col_poc - col_ref_poc_l0) == (cur_poc - cur_ref_poc)))*/
    354                     if((col_poc - col_ref_poc_l0) == (cur_poc - cur_ref_poc))
    355                     {
    356                         ps_mv_col[0] = as_mv_col[0];
    357                     }
    358                     else
    359                     {
    360                         ps_mv_col[0] = as_mv_col[0];
    361                         if(col_ref_poc_l0 != col_poc)
    362                         {
    363                             ihevce_scale_collocated_mv(
    364                                 (mv_t *)(&ps_mv_col[0]),
    365                                 cur_ref_poc,
    366                                 col_ref_poc_l0,
    367                                 col_poc,
    368                                 cur_poc);
    369                         }
    370                     }
    371                 }
    372             }
    373             else
    374             {
    375                 pu4_avail_col_flag[0] = 0;
    376                 ps_mv_col[0].i2_mvx = 0;
    377                 ps_mv_col[0].i2_mvy = 0;
    378             }
    379             if((BSLICE == ps_slice_hdr->i1_slice_type) && (-1 != ref_idx_l1))
    380             {
    381                 WORD32 col_ref_poc_l1_lt, col_ref_poc_l1;
    382 
    383                 if(au4_list_col[1] == 0)
    384                 {
    385                     col_ref_poc_l1 = ps_col_ref_buf->ai4_col_l0_poc[au4_ref_idx_col[0]];
    386                     col_ref_poc_l1_lt = 0;
    387                 }
    388                 else
    389                 {
    390                     col_ref_poc_l1 = ps_col_ref_buf->ai4_col_l1_poc[au4_ref_idx_col[0]];
    391                     col_ref_poc_l1_lt = 0;
    392                 }
    393 
    394                 /* L1 collocated mv */
    395                 cur_ref_poc = ps_mv_ctxt->ps_ref_list[1][ref_idx_l1]->i4_poc;
    396                 cur_ref_poc_lt = 0;
    397 
    398                 {
    399                     pu4_avail_col_flag[1] = 1;
    400 
    401                     /*if(cur_ref_poc_lt || ((col_poc - col_ref_poc_l1) == (cur_poc - cur_ref_poc)))*/
    402                     if((col_poc - col_ref_poc_l1) == (cur_poc - cur_ref_poc))
    403                     {
    404                         ps_mv_col[1] = as_mv_col[1];
    405                     }
    406                     else
    407                     {
    408                         ps_mv_col[1] = as_mv_col[1];
    409                         if(col_ref_poc_l1 != col_poc)
    410                         {
    411                             ihevce_scale_collocated_mv(
    412                                 (mv_t *)&ps_mv_col[1],
    413                                 cur_ref_poc,
    414                                 col_ref_poc_l1,
    415                                 col_poc,
    416                                 cur_poc);
    417                         }
    418                     }
    419                 }
    420             } /* End of if BSLICE */
    421             else
    422             {
    423                 pu4_avail_col_flag[1] = 0;
    424             }
    425         }
    426 
    427     } /* End of collocated MV calculation */
    428 
    429 } /* End of ihevce_collocated_mvp */
    430 
    431 /**
    432  *******************************************************************************
    433  *
    434  * @brief Compare Motion vectors function
    435  *
    436  *
    437  * @par Description:
    438  *   Checks if MVs and Reference idx are excatly matching.
    439  *
    440  * @param[inout] ps_1
    441  *   motion vector 1 to be compared
    442  *
    443  * @param[in] ps_2
    444  *   motion vector 2 to be compared
    445  *
    446  * @returns
    447  *  0 : if not matching 1 : if matching
    448  *
    449  * @remarks
    450  *
    451  *******************************************************************************
    452  */
    453 
    454 /**
    455  *******************************************************************************
    456  *
    457  * @brief
    458  * This function performs Motion Vector Merge candidates derivation
    459  *
    460  * @par Description:
    461  *  MV merge list is computed using neighbor mvs and colocated mv
    462  *
    463  * @param[in] ps_ctxt
    464  * pointer to mv predictor context
    465  *
    466  * @param[in] ps_top_nbr_4x4
    467  * pointer to top 4x4 nbr structure
    468  *
    469  * @param[in] ps_left_nbr_4x4
    470  * pointer to left 4x4 nbr structure
    471  *
    472  * @param[in] ps_top_left_nbr_4x4
    473  * pointer to top left 4x4 nbr structure
    474  *
    475  * @param[in] left_nbr_4x4_strd
    476  * left nbr buffer stride in terms of 4x4 units
    477  *
    478  * @param[in] ps_avail_flags
    479  * Neighbor availability flags container
    480  *
    481  * @param[in] ps_col_mv
    482  * Colocated MV pointer
    483  *
    484  * @param[in] ps_pu
    485  * Current Partition PU strucrture pointer
    486  *
    487  * @param[in] part_mode
    488  * Partition mode @sa PART_SIZE_E
    489  *
    490  * @param[in] part_idx
    491  * Partition idx of current partition inside CU
    492  *
    493  * @param[in] single_mcl_flag
    494  * Single MCL flag based on 8x8 CU and Parallel merge value
    495  *
    496  * @param[out] ps_merge_cand_list
    497  * pointer to store MV merge candidates list
    498  *
    499  * @returns
    500  * Number of merge candidates
    501  * @remarks
    502  *
    503  *
    504  *******************************************************************************
    505  */
    506 WORD32 ihevce_mv_pred_merge(
    507     mv_pred_ctxt_t *ps_ctxt,
    508     nbr_4x4_t *ps_top_nbr_4x4,
    509     nbr_4x4_t *ps_left_nbr_4x4,
    510     nbr_4x4_t *ps_top_left_nbr_4x4,
    511     WORD32 left_nbr_4x4_strd,
    512     nbr_avail_flags_t *ps_avail_flags,
    513     pu_mv_t *ps_col_mv,
    514     pu_t *ps_pu,
    515     PART_SIZE_E part_mode,
    516     WORD32 part_idx,
    517     WORD32 single_mcl_flag,
    518     merge_cand_list_t *ps_merge_cand_list,
    519     UWORD8 *pu1_is_top_used)
    520 {
    521     /******************************************************/
    522     /*      Spatial Merge Candidates                      */
    523     /******************************************************/
    524     WORD32 part_pos_x;
    525     WORD32 part_pos_y;
    526     WORD32 part_wd;
    527     WORD32 part_ht;
    528     WORD32 slice_type;
    529     WORD32 num_ref_idx_l0_active;
    530     WORD32 num_ref_idx_l1_active;
    531     WORD32 num_merge_cand;
    532     WORD32 log2_parallel_merge_level_minus2;
    533     WORD32 n;
    534     WORD8 i1_spatial_avail_flag_n[MAX_NUM_MV_NBR]; /*[A0/A1/B0/B1/B2]*/
    535     WORD32 nbr_x[MAX_NUM_MV_NBR], nbr_y[MAX_NUM_MV_NBR];
    536     UWORD8 u1_nbr_avail[MAX_NUM_MV_NBR];
    537     WORD32 merge_shift;
    538     nbr_4x4_t *ps_nbr_mv[MAX_NUM_MV_NBR];
    539 
    540     /*******************************************/
    541     /* Neighbor location: Graphical indication */
    542     /*                                         */
    543     /*          B2 _____________B1 B0          */
    544     /*            |               |            */
    545     /*            |               |            */
    546     /*            |               |            */
    547     /*            |      PU     ht|            */
    548     /*            |               |            */
    549     /*            |               |            */
    550     /*          A1|______wd_______|            */
    551     /*          A0                             */
    552     /*                                         */
    553     /*******************************************/
    554 
    555     part_pos_x = ps_pu->b4_pos_x << 2;
    556     part_pos_y = ps_pu->b4_pos_y << 2;
    557     part_ht = (ps_pu->b4_ht + 1) << 2;
    558     part_wd = (ps_pu->b4_wd + 1) << 2;
    559 
    560     slice_type = ps_ctxt->ps_slice_hdr->i1_slice_type;
    561     num_ref_idx_l0_active = ps_ctxt->ps_slice_hdr->i1_num_ref_idx_l0_active;
    562     num_ref_idx_l1_active = ps_ctxt->ps_slice_hdr->i1_num_ref_idx_l1_active;
    563     log2_parallel_merge_level_minus2 = ps_ctxt->i4_log2_parallel_merge_level_minus2;
    564 
    565     /* Assigning co-ordinates to neighbors */
    566     nbr_x[NBR_A0] = part_pos_x - 1;
    567     nbr_y[NBR_A0] = part_pos_y + part_ht; /* A0 */
    568 
    569     nbr_x[NBR_A1] = part_pos_x - 1;
    570     nbr_y[NBR_A1] = part_pos_y + part_ht - 1; /* A1 */
    571 
    572     nbr_x[NBR_B0] = part_pos_x + part_wd;
    573     nbr_y[NBR_B0] = part_pos_y - 1; /* B0 */
    574 
    575     nbr_x[NBR_B1] = part_pos_x + part_wd - 1;
    576     nbr_y[NBR_B1] = part_pos_y - 1; /* B1 */
    577 
    578     nbr_x[NBR_B2] = part_pos_x - 1;
    579     nbr_y[NBR_B2] = part_pos_y - 1; /* B2 */
    580 
    581     /* Assigning mv's */
    582     ps_nbr_mv[NBR_A0] = ps_left_nbr_4x4 + ((nbr_y[NBR_A0] - part_pos_y) >> 2) * left_nbr_4x4_strd;
    583     ps_nbr_mv[NBR_A1] = ps_left_nbr_4x4 + ((nbr_y[NBR_A1] - part_pos_y) >> 2) * left_nbr_4x4_strd;
    584     ps_nbr_mv[NBR_B0] = ps_top_nbr_4x4 + ((nbr_x[NBR_B0] - part_pos_x) >> 2);
    585     ps_nbr_mv[NBR_B1] = ps_top_nbr_4x4 + ((nbr_x[NBR_B1] - part_pos_x) >> 2);
    586 
    587     if(part_pos_y == 0) /* AT vertical CTB boundary */
    588         ps_nbr_mv[NBR_B2] = ps_top_nbr_4x4 + ((nbr_x[NBR_B2] - part_pos_x) >> 2);
    589     else
    590         ps_nbr_mv[NBR_B2] = ps_top_left_nbr_4x4;
    591 
    592     /* Assigning nbr availability */
    593     u1_nbr_avail[NBR_A0] = ps_avail_flags->u1_bot_lt_avail &&
    594                            (!ps_nbr_mv[NBR_A0]->b1_intra_flag); /* A0 */
    595     u1_nbr_avail[NBR_A1] = ps_avail_flags->u1_left_avail &&
    596                            (!ps_nbr_mv[NBR_A1]->b1_intra_flag); /* A1 */
    597     u1_nbr_avail[NBR_B0] = ps_avail_flags->u1_top_rt_avail &&
    598                            (!ps_nbr_mv[NBR_B0]->b1_intra_flag); /* B0 */
    599     u1_nbr_avail[NBR_B1] = ps_avail_flags->u1_top_avail &&
    600                            (!ps_nbr_mv[NBR_B1]->b1_intra_flag); /* B1 */
    601     u1_nbr_avail[NBR_B2] = ps_avail_flags->u1_top_lt_avail &&
    602                            (!ps_nbr_mv[NBR_B2]->b1_intra_flag); /* B2 */
    603 
    604     merge_shift = log2_parallel_merge_level_minus2 + 2;
    605 
    606     /* Availability check */
    607     /* A1 */
    608     {
    609         WORD32 avail_flag;
    610         avail_flag = 1;
    611         n = NBR_A1;
    612 
    613         /* if at same merge level */
    614         if((part_pos_x >> merge_shift) == (nbr_x[n] >> merge_shift) &&
    615            ((part_pos_y >> merge_shift) == (nbr_y[n] >> merge_shift)))
    616         {
    617             u1_nbr_avail[n] = 0;
    618         }
    619 
    620         /* SPEC JCTVC-K1003_v9 version has a different way using not available       */
    621         /* candidates compared to software. for non square part and seconf part case */
    622         /* ideally nothing from the 1st partition should be used as per spec but     */
    623         /* HM 8.2 dev verison does not adhere to this. currenlty code fllows HM      */
    624 
    625         /* if single MCL is 0 , second part of 2 part in CU */
    626         if((single_mcl_flag == 0) && (part_idx == 1) &&
    627            ((part_mode == PART_Nx2N) || (part_mode == PART_nLx2N) || (part_mode == PART_nRx2N)))
    628         {
    629             u1_nbr_avail[n] = 0;
    630         }
    631 
    632         if(u1_nbr_avail[n] == 0)
    633         {
    634             avail_flag = 0;
    635         }
    636         i1_spatial_avail_flag_n[n] = avail_flag;
    637     }
    638     /* B1 */
    639     {
    640         WORD32 avail_flag;
    641         avail_flag = 1;
    642         n = NBR_B1;
    643 
    644         /* if at same merge level */
    645         if((part_pos_x >> merge_shift) == (nbr_x[n] >> merge_shift) &&
    646            ((part_pos_y >> merge_shift) == (nbr_y[n] >> merge_shift)))
    647         {
    648             u1_nbr_avail[n] = 0;
    649         }
    650 
    651         /* if single MCL is 0 , second part of 2 part in CU */
    652         if((single_mcl_flag == 0) && (part_idx == 1) &&
    653            ((part_mode == PART_2NxN) || (part_mode == PART_2NxnU) || (part_mode == PART_2NxnD)))
    654         {
    655             u1_nbr_avail[n] = 0;
    656         }
    657 
    658         if(u1_nbr_avail[n] == 0)
    659         {
    660             avail_flag = 0;
    661         }
    662 
    663         if((avail_flag == 1) && (u1_nbr_avail[NBR_A1] == 1))
    664         {
    665             /* TODO: Assumption: mvs and ref indicies in both l0 and l1*/
    666             /* should match for non availability                       */
    667             WORD32 i4_pred_1, i4_pred_2;
    668             i4_pred_1 =
    669                 (ps_nbr_mv[NBR_A1]->b1_pred_l0_flag | (ps_nbr_mv[NBR_A1]->b1_pred_l1_flag << 1)) -
    670                 1;
    671             i4_pred_2 = (ps_nbr_mv[n]->b1_pred_l0_flag | (ps_nbr_mv[n]->b1_pred_l1_flag << 1)) - 1;
    672             if(ihevce_compare_pu_mv_t(
    673                    &ps_nbr_mv[NBR_A1]->mv, &ps_nbr_mv[n]->mv, i4_pred_1, i4_pred_2))
    674             {
    675                 avail_flag = 0;
    676             }
    677         }
    678         i1_spatial_avail_flag_n[n] = avail_flag;
    679     }
    680 
    681     /* B0 */
    682     {
    683         WORD32 avail_flag;
    684         avail_flag = 1;
    685         n = NBR_B0;
    686 
    687         /* if at same merge level */
    688         if((part_pos_x >> merge_shift) == (nbr_x[n] >> merge_shift) &&
    689            ((part_pos_y >> merge_shift) == (nbr_y[n] >> merge_shift)))
    690         {
    691             u1_nbr_avail[n] = 0;
    692         }
    693 
    694         if(u1_nbr_avail[n] == 0)
    695         {
    696             avail_flag = 0;
    697         }
    698 
    699         if((avail_flag == 1) && (u1_nbr_avail[NBR_B1] == 1))
    700         {
    701             WORD32 i4_pred_1, i4_pred_2;
    702             i4_pred_1 =
    703                 (ps_nbr_mv[NBR_B1]->b1_pred_l0_flag | (ps_nbr_mv[NBR_B1]->b1_pred_l1_flag << 1)) -
    704                 1;
    705             i4_pred_2 = (ps_nbr_mv[n]->b1_pred_l0_flag | (ps_nbr_mv[n]->b1_pred_l1_flag << 1)) - 1;
    706             if(ihevce_compare_pu_mv_t(
    707                    &ps_nbr_mv[NBR_B1]->mv, &ps_nbr_mv[n]->mv, i4_pred_1, i4_pred_2))
    708             {
    709                 avail_flag = 0;
    710             }
    711         }
    712         i1_spatial_avail_flag_n[n] = avail_flag;
    713     }
    714 
    715     /* A0 */
    716     {
    717         WORD32 avail_flag;
    718         avail_flag = 1;
    719         n = NBR_A0;
    720 
    721         /* if at same merge level */
    722         if((part_pos_x >> merge_shift) == (nbr_x[n] >> merge_shift) &&
    723            ((part_pos_y >> merge_shift) == (nbr_y[n] >> merge_shift)))
    724         {
    725             u1_nbr_avail[n] = 0;
    726         }
    727 
    728         if(u1_nbr_avail[n] == 0)
    729         {
    730             avail_flag = 0;
    731         }
    732 
    733         if((avail_flag == 1) && (u1_nbr_avail[NBR_A1] == 1))
    734         {
    735             WORD32 i4_pred_1, i4_pred_2;
    736             i4_pred_1 =
    737                 (ps_nbr_mv[NBR_A1]->b1_pred_l0_flag | (ps_nbr_mv[NBR_A1]->b1_pred_l1_flag << 1)) -
    738                 1;
    739             i4_pred_2 = (ps_nbr_mv[n]->b1_pred_l0_flag | (ps_nbr_mv[n]->b1_pred_l1_flag << 1)) - 1;
    740             if(ihevce_compare_pu_mv_t(
    741                    &ps_nbr_mv[NBR_A1]->mv, &ps_nbr_mv[n]->mv, i4_pred_1, i4_pred_2))
    742             {
    743                 avail_flag = 0;
    744             }
    745         }
    746         i1_spatial_avail_flag_n[n] = avail_flag;
    747     }
    748     /* B2 */
    749     {
    750         WORD32 avail_flag;
    751         avail_flag = 1;
    752         n = NBR_B2;
    753 
    754         /* if at same merge level */
    755         if((part_pos_x >> merge_shift) == (nbr_x[n] >> merge_shift) &&
    756            ((part_pos_y >> merge_shift) == (nbr_y[n] >> merge_shift)))
    757         {
    758             u1_nbr_avail[n] = 0;
    759         }
    760 
    761         if(u1_nbr_avail[n] == 0)
    762         {
    763             avail_flag = 0;
    764         }
    765 
    766         if((i1_spatial_avail_flag_n[NBR_A0] + i1_spatial_avail_flag_n[NBR_A1] +
    767             i1_spatial_avail_flag_n[NBR_B0] + i1_spatial_avail_flag_n[NBR_B1]) == 4)
    768         {
    769             avail_flag = 0;
    770         }
    771 
    772         if(avail_flag == 1)
    773         {
    774             if(u1_nbr_avail[NBR_A1] == 1)
    775             {
    776                 WORD32 i4_pred_1, i4_pred_2;
    777                 i4_pred_1 = (ps_nbr_mv[NBR_A1]->b1_pred_l0_flag |
    778                              (ps_nbr_mv[NBR_A1]->b1_pred_l1_flag << 1)) -
    779                             1;
    780                 i4_pred_2 =
    781                     (ps_nbr_mv[n]->b1_pred_l0_flag | (ps_nbr_mv[n]->b1_pred_l1_flag << 1)) - 1;
    782                 if(ihevce_compare_pu_mv_t(
    783                        &ps_nbr_mv[NBR_A1]->mv, &ps_nbr_mv[n]->mv, i4_pred_1, i4_pred_2))
    784                 {
    785                     avail_flag = 0;
    786                 }
    787             }
    788             if(u1_nbr_avail[NBR_B1] == 1)
    789             {
    790                 WORD32 i4_pred_1, i4_pred_2;
    791                 i4_pred_1 = (ps_nbr_mv[NBR_B1]->b1_pred_l0_flag |
    792                              (ps_nbr_mv[NBR_B1]->b1_pred_l1_flag << 1)) -
    793                             1;
    794                 i4_pred_2 =
    795                     (ps_nbr_mv[n]->b1_pred_l0_flag | (ps_nbr_mv[n]->b1_pred_l1_flag << 1)) - 1;
    796                 if(ihevce_compare_pu_mv_t(
    797                        &ps_nbr_mv[NBR_B1]->mv, &ps_nbr_mv[n]->mv, i4_pred_1, i4_pred_2))
    798                 {
    799                     avail_flag = 0;
    800                 }
    801             }
    802         }
    803         i1_spatial_avail_flag_n[n] = avail_flag;
    804     }
    805 
    806     /******************************************************/
    807     /*          Merge Candidates List                     */
    808     /******************************************************/
    809     /* Preparing MV merge candidate list */
    810     {
    811         WORD32 merge_list_priority[MAX_NUM_MERGE_CAND] = { NBR_A1, NBR_B1, NBR_B0, NBR_A0, NBR_B2 };
    812 
    813         num_merge_cand = 0;
    814         for(n = 0; n < MAX_NUM_MERGE_CAND; n++)
    815         {
    816             WORD32 merge_idx;
    817             merge_idx = merge_list_priority[n];
    818             if(i1_spatial_avail_flag_n[merge_idx] == 1)
    819             {
    820                 ps_merge_cand_list[num_merge_cand].mv = ps_nbr_mv[merge_idx]->mv;
    821                 ps_merge_cand_list[num_merge_cand].u1_pred_flag_l0 =
    822                     (UWORD8)ps_nbr_mv[merge_idx]->b1_pred_l0_flag;
    823                 ps_merge_cand_list[num_merge_cand].u1_pred_flag_l1 =
    824                     (UWORD8)ps_nbr_mv[merge_idx]->b1_pred_l1_flag;
    825 
    826                 switch(merge_list_priority[n])
    827                 {
    828                 case NBR_A1:
    829                 case NBR_A0:
    830                 {
    831                     pu1_is_top_used[num_merge_cand] = 0;
    832 
    833                     break;
    834                 }
    835                 default:
    836                 {
    837                     pu1_is_top_used[num_merge_cand] = 1;
    838 
    839                     break;
    840                 }
    841                 }
    842 
    843                 num_merge_cand++;
    844             }
    845         }
    846 
    847         /******************************************************/
    848         /*           Temporal Merge Candidates                */
    849         /******************************************************/
    850         if(num_merge_cand < MAX_NUM_MERGE_CAND)
    851         {
    852             mv_t as_mv_col[2];
    853             WORD32 avail_col_flag[2] = { 0 }, x_col, y_col;
    854             WORD32 avail_col_l0, avail_col_l1;
    855 
    856             /* Checking Collocated MV availability at Bottom right of PU*/
    857             x_col = part_pos_x + part_wd;
    858             y_col = part_pos_y + part_ht;
    859             ihevce_collocated_mvp(ps_ctxt, ps_pu, as_mv_col, avail_col_flag, 0, x_col, y_col);
    860 
    861             avail_col_l0 = avail_col_flag[0];
    862             avail_col_l1 = avail_col_flag[1];
    863 
    864             if(avail_col_l0 || avail_col_l1)
    865             {
    866                 ps_merge_cand_list[num_merge_cand].mv.s_l0_mv = as_mv_col[0];
    867                 ps_merge_cand_list[num_merge_cand].mv.s_l1_mv = as_mv_col[1];
    868             }
    869 
    870             if(avail_col_l0 == 0 || avail_col_l1 == 0)
    871             {
    872                 /* Checking Collocated MV availability at Center of PU */
    873                 x_col = part_pos_x + (part_wd >> 1);
    874                 y_col = part_pos_y + (part_ht >> 1);
    875                 ihevce_collocated_mvp(ps_ctxt, ps_pu, as_mv_col, avail_col_flag, 0, x_col, y_col);
    876 
    877                 if(avail_col_l0 == 0)
    878                 {
    879                     ps_merge_cand_list[num_merge_cand].mv.s_l0_mv = as_mv_col[0];
    880                 }
    881                 if(avail_col_l1 == 0)
    882                 {
    883                     ps_merge_cand_list[num_merge_cand].mv.s_l1_mv = as_mv_col[1];
    884                 }
    885 
    886                 avail_col_l0 |= avail_col_flag[0];
    887                 avail_col_l1 |= avail_col_flag[1];
    888             }
    889 
    890             ps_merge_cand_list[num_merge_cand].mv.i1_l0_ref_idx = 0;
    891             ps_merge_cand_list[num_merge_cand].mv.i1_l1_ref_idx = 0;
    892             ps_merge_cand_list[num_merge_cand].u1_pred_flag_l0 = avail_col_l0 ? 1 : 0;
    893             ps_merge_cand_list[num_merge_cand].u1_pred_flag_l1 = avail_col_l1 ? 1 : 0;
    894 
    895             if(avail_col_l0 || avail_col_l1)
    896             {
    897                 pu1_is_top_used[num_merge_cand] = 0;
    898                 num_merge_cand++;
    899             }
    900         }
    901 
    902         /******************************************************/
    903         /*      Bi pred merge candidates                      */
    904         /******************************************************/
    905         if(slice_type == BSLICE)
    906         {
    907             if((num_merge_cand > 1) && (num_merge_cand < MAX_NUM_MERGE_CAND))
    908             {
    909                 WORD32 priority_list0[12] = { 0, 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3 };
    910                 WORD32 priority_list1[12] = { 1, 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2 };
    911                 WORD32 l0_cand, l1_cand;
    912                 WORD32 bi_pred_idx = 0;
    913                 WORD32 total_bi_pred_cand = num_merge_cand * (num_merge_cand - 1);
    914 
    915                 while(bi_pred_idx < total_bi_pred_cand)
    916                 {
    917                     l0_cand = priority_list0[bi_pred_idx];
    918                     l1_cand = priority_list1[bi_pred_idx];
    919 
    920                     if((ps_merge_cand_list[l0_cand].u1_pred_flag_l0 == 1) &&
    921                        (ps_merge_cand_list[l1_cand].u1_pred_flag_l1 == 1))
    922                     {
    923                         WORD8 i1_l0_ref_idx, i1_l1_ref_idx;
    924                         WORD32 l0_poc, l1_poc;
    925                         mv_t s_l0_mv, s_l1_mv;
    926 
    927                         i1_l0_ref_idx = ps_merge_cand_list[l0_cand].mv.i1_l0_ref_idx;
    928                         i1_l1_ref_idx = ps_merge_cand_list[l1_cand].mv.i1_l1_ref_idx;
    929                         l0_poc = ps_ctxt->ps_ref_list[0][i1_l0_ref_idx]->i4_poc;
    930                         l1_poc = ps_ctxt->ps_ref_list[1][i1_l1_ref_idx]->i4_poc;
    931                         s_l0_mv = ps_merge_cand_list[l0_cand].mv.s_l0_mv;
    932                         s_l1_mv = ps_merge_cand_list[l1_cand].mv.s_l1_mv;
    933 
    934                         if((l0_poc != l1_poc) || (s_l0_mv.i2_mvx != s_l1_mv.i2_mvx) ||
    935                            (s_l0_mv.i2_mvy != s_l1_mv.i2_mvy))
    936                         {
    937                             ps_merge_cand_list[num_merge_cand].mv.s_l0_mv = s_l0_mv;
    938                             ps_merge_cand_list[num_merge_cand].mv.s_l1_mv = s_l1_mv;
    939                             ps_merge_cand_list[num_merge_cand].mv.i1_l0_ref_idx = i1_l0_ref_idx;
    940                             ps_merge_cand_list[num_merge_cand].mv.i1_l1_ref_idx = i1_l1_ref_idx;
    941                             ps_merge_cand_list[num_merge_cand].u1_pred_flag_l0 = 1;
    942                             ps_merge_cand_list[num_merge_cand].u1_pred_flag_l1 = 1;
    943 
    944                             if(pu1_is_top_used[l0_cand] || pu1_is_top_used[l1_cand])
    945                             {
    946                                 pu1_is_top_used[num_merge_cand] = 1;
    947                             }
    948                             else
    949                             {
    950                                 pu1_is_top_used[num_merge_cand] = 0;
    951                             }
    952 
    953                             num_merge_cand++;
    954                         }
    955                     }
    956 
    957                     bi_pred_idx++;
    958 
    959                     if((bi_pred_idx == total_bi_pred_cand) ||
    960                        (num_merge_cand == MAX_NUM_MERGE_CAND))
    961                     {
    962                         break;
    963                     }
    964                 }
    965             }
    966         } /* End of Bipred merge candidates */
    967 
    968         /******************************************************/
    969         /*      Zero merge candidates                         */
    970         /******************************************************/
    971         if(num_merge_cand < MAX_NUM_MERGE_CAND)
    972         {
    973             WORD32 num_ref_idx;
    974             WORD32 zero_idx;
    975 
    976             zero_idx = 0;
    977 
    978             if(slice_type == PSLICE)
    979                 num_ref_idx = num_ref_idx_l0_active;
    980             else
    981                 /* Slice type B */
    982                 num_ref_idx = MIN(num_ref_idx_l0_active, num_ref_idx_l1_active);
    983 
    984             while(num_merge_cand < MAX_NUM_MERGE_CAND)
    985             {
    986                 if(slice_type == PSLICE)
    987                 {
    988                     ps_merge_cand_list[num_merge_cand].mv.i1_l0_ref_idx = zero_idx;
    989                     ps_merge_cand_list[num_merge_cand].mv.i1_l1_ref_idx = -1;
    990                     ps_merge_cand_list[num_merge_cand].u1_pred_flag_l0 = 1;
    991                     ps_merge_cand_list[num_merge_cand].u1_pred_flag_l1 = 0;
    992                 }
    993                 else /* Slice type B */
    994                 {
    995                     ps_merge_cand_list[num_merge_cand].mv.i1_l0_ref_idx = zero_idx;
    996                     ps_merge_cand_list[num_merge_cand].mv.i1_l1_ref_idx = zero_idx;
    997                     ps_merge_cand_list[num_merge_cand].u1_pred_flag_l0 = 1;
    998                     ps_merge_cand_list[num_merge_cand].u1_pred_flag_l1 = 1;
    999                 }
   1000 
   1001                 ps_merge_cand_list[num_merge_cand].mv.s_l0_mv.i2_mvx = 0;
   1002                 ps_merge_cand_list[num_merge_cand].mv.s_l0_mv.i2_mvy = 0;
   1003                 ps_merge_cand_list[num_merge_cand].mv.s_l1_mv.i2_mvx = 0;
   1004                 ps_merge_cand_list[num_merge_cand].mv.s_l1_mv.i2_mvy = 0;
   1005 
   1006                 pu1_is_top_used[num_merge_cand] = 0;
   1007 
   1008                 num_merge_cand++;
   1009                 zero_idx++;
   1010 
   1011                 /* if all the reference pics have been added as candidates      */
   1012                 /* the the loop shoudl break since it would add same cand again */
   1013                 if(zero_idx == num_ref_idx)
   1014                 {
   1015                     break;
   1016                 }
   1017             }
   1018         } /* End of zero merge candidates */
   1019 
   1020     } /* End of merge candidate list population */
   1021 
   1022     return (num_merge_cand);
   1023 }
   1024