Home | History | Annotate | Download | only in decoder
      1 /******************************************************************************
      2 *
      3 * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
      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 /**
     19  *******************************************************************************
     20  * @file
     21  *  ihevcd_mv_merge.c
     22  *
     23  * @brief
     24  *  Contains functions for motion vector merge candidates derivation
     25  *
     26  * @author
     27  *  Ittiam
     28  *
     29  * @par List of Functions:
     30  * - ihevcd_compare_pu_mv_t()
     31  * - ihevcd_mv_pred_merge()
     32  *
     33  * @remarks
     34  *  None
     35  *
     36  *******************************************************************************
     37  */
     38 /*****************************************************************************/
     39 /* File Includes                                                             */
     40 /*****************************************************************************/
     41 #include <stdio.h>
     42 #include <stddef.h>
     43 #include <stdlib.h>
     44 #include <string.h>
     45 
     46 #include "ihevc_typedefs.h"
     47 #include "iv.h"
     48 #include "ivd.h"
     49 #include "ihevcd_cxa.h"
     50 #include "ithread.h"
     51 
     52 #include "ihevc_defs.h"
     53 #include "ihevc_debug.h"
     54 #include "ihevc_structs.h"
     55 #include "ihevc_macros.h"
     56 #include "ihevc_platform_macros.h"
     57 #include "ihevc_cabac_tables.h"
     58 #include "ihevc_disp_mgr.h"
     59 #include "ihevc_buf_mgr.h"
     60 #include "ihevc_dpb_mgr.h"
     61 
     62 #include "ihevcd_defs.h"
     63 #include "ihevcd_function_selector.h"
     64 #include "ihevcd_structs.h"
     65 #include "ihevcd_error.h"
     66 #include "ihevcd_nal.h"
     67 #include "ihevcd_bitstream.h"
     68 #include "ihevcd_fmt_conv.h"
     69 #include "ihevcd_job_queue.h"
     70 #include "ihevcd_debug.h"
     71 #include "ihevcd_mv_merge.h"
     72 /**
     73  *******************************************************************************
     74  *
     75  * @brief Compare Motion vectors function
     76  *
     77  *
     78  * @par Description:
     79  *   Checks if MVs and Reference idx are excatly matching.
     80  *
     81  * @param[inout] ps_1
     82  *   motion vector 1 to be compared
     83  *
     84  * @param[in] ps_2
     85  *   motion vector 2 to be compared
     86  *
     87  * @returns
     88  *  0 : if not matching 1 : if matching
     89  *
     90  * @remarks
     91  *
     92  *******************************************************************************
     93  */
     94 WORD32 ihevcd_compare_pu_t(pu_t *ps_pu_1, pu_t *ps_pu_2)
     95 {
     96     WORD32 l0_match = 0, l1_match = 0;
     97     pu_mv_t *ps_mv_1, *ps_mv_2;
     98     WORD32 pred_mode_1, pred_mode_2;
     99 
    100     ps_mv_1 = &ps_pu_1->mv;
    101     ps_mv_2 = &ps_pu_2->mv;
    102 
    103     pred_mode_1 = ps_pu_1->b2_pred_mode;
    104     pred_mode_2 = ps_pu_2->b2_pred_mode;
    105 
    106     if(pred_mode_1 == pred_mode_2)
    107     {
    108         if(pred_mode_1 != PRED_L1)
    109         {
    110             if(ps_mv_1->i1_l0_ref_idx == ps_mv_2->i1_l0_ref_idx)
    111             {
    112                 if(0 == memcmp(&ps_mv_1->s_l0_mv, &ps_mv_2->s_l0_mv, sizeof(mv_t)))
    113                 {
    114                     l0_match = 1;
    115                 }
    116             }
    117         }
    118         if(pred_mode_1 != PRED_L0)
    119         {
    120             if(ps_mv_1->i1_l1_ref_idx == ps_mv_2->i1_l1_ref_idx)
    121             {
    122                 if(0 == memcmp(&ps_mv_1->s_l1_mv, &ps_mv_2->s_l1_mv, sizeof(mv_t)))
    123                 {
    124                     l1_match = 1;
    125                 }
    126             }
    127         }
    128         if(pred_mode_1 == PRED_BI)
    129             return (l1_match && l0_match);
    130         else if(pred_mode_1 == PRED_L0)
    131             return l0_match;
    132         else
    133             return l1_match;
    134     }
    135 
    136     return 0;
    137 }
    138 
    139 void ihevcd_collocated_mvp(mv_ctxt_t *ps_mv_ctxt,
    140                            pu_t *ps_pu,
    141                            mv_t *ps_mv_col,
    142                            WORD32 *pu4_avail_col_flag,
    143                            WORD32 use_pu_ref_idx,
    144                            WORD32 x_col,
    145                            WORD32 y_col)
    146 {
    147     sps_t *ps_sps = ps_mv_ctxt->ps_sps;
    148     slice_header_t *ps_slice_hdr = ps_mv_ctxt->ps_slice_hdr;
    149     ref_list_t *ps_ref_list[2];
    150     mv_buf_t *ps_mv_buf_col;
    151     WORD32 xp_col, yp_col;
    152     WORD32 col_ctb_x, col_ctb_y;
    153     mv_t as_mv_col[2];
    154     WORD32 log2_ctb_size;
    155     WORD32 ctb_size;
    156     WORD32 avail_col;
    157     WORD32 col_ctb_idx, pu_cnt;
    158     WORD32 au4_list_col[2];
    159     WORD32 num_minpu_in_ctb;
    160     UWORD8 *pu1_pic_pu_map_ctb;
    161     pu_t *ps_col_pu;
    162     WORD32 part_pos_y;
    163 
    164 
    165     part_pos_y = ps_pu->b4_pos_y << 2;
    166 
    167     log2_ctb_size = ps_sps->i1_log2_ctb_size;
    168     ctb_size = (1 << log2_ctb_size);
    169 
    170     avail_col = 1;
    171 
    172     /* Initializing reference list */
    173     ps_ref_list[0] = ps_slice_hdr->as_ref_pic_list0;
    174     ps_ref_list[1] = ps_slice_hdr->as_ref_pic_list1;
    175     if(PSLICE == ps_slice_hdr->i1_slice_type)
    176         ps_ref_list[1] = ps_slice_hdr->as_ref_pic_list0;
    177 
    178     if((ps_slice_hdr->i1_slice_type == BSLICE) && (ps_slice_hdr->i1_collocated_from_l0_flag == 0))
    179     {
    180         /* L1 */
    181         ps_mv_buf_col = (mv_buf_t *)ps_ref_list[1][ps_slice_hdr->i1_collocated_ref_idx].pv_mv_buf;
    182 
    183     }
    184     else
    185     {
    186         /* L0 */
    187         ps_mv_buf_col = (mv_buf_t *)ps_ref_list[0][ps_slice_hdr->i1_collocated_ref_idx].pv_mv_buf;
    188 
    189     }
    190     num_minpu_in_ctb = (ctb_size / MIN_PU_SIZE) * (ctb_size / MIN_PU_SIZE);
    191 
    192     if(((part_pos_y >> log2_ctb_size) == (y_col >> log2_ctb_size))
    193                     && ((x_col + (ps_mv_ctxt->i4_ctb_x << log2_ctb_size)) < ps_sps->i2_pic_width_in_luma_samples)
    194                     && (((y_col + (ps_mv_ctxt->i4_ctb_y << log2_ctb_size))
    195                                     < ps_sps->i2_pic_height_in_luma_samples)))
    196     {
    197         xp_col = ((x_col >> 4) << 4);
    198         yp_col = ((y_col >> 4) << 4);
    199         col_ctb_x = ps_mv_ctxt->i4_ctb_x + (xp_col >> log2_ctb_size);
    200         col_ctb_y = ps_mv_ctxt->i4_ctb_y + (yp_col >> log2_ctb_size);
    201         col_ctb_idx = col_ctb_x + (col_ctb_y)*(ps_sps->i2_pic_wd_in_ctb);
    202         pu_cnt = ps_mv_buf_col->pu4_pic_pu_idx[col_ctb_idx];
    203         pu1_pic_pu_map_ctb = ps_mv_buf_col->pu1_pic_pu_map
    204                         + col_ctb_idx * num_minpu_in_ctb;
    205         if(xp_col == ctb_size)
    206             xp_col = 0;
    207         pu_cnt += pu1_pic_pu_map_ctb[(yp_col >> 2)
    208                         * (ctb_size / MIN_PU_SIZE) + (xp_col >> 2)];
    209         ps_col_pu = &ps_mv_buf_col->ps_pic_pu[pu_cnt];
    210     }
    211     else
    212         avail_col = 0;
    213 
    214     if((avail_col == 0) || (ps_col_pu->b1_intra_flag == 1)
    215                     || (ps_slice_hdr->i1_slice_temporal_mvp_enable_flag == 0))
    216     {
    217         pu4_avail_col_flag[0] = 0;
    218         pu4_avail_col_flag[1] = 0;
    219         ps_mv_col[0].i2_mvx = 0;
    220         ps_mv_col[0].i2_mvy = 0;
    221         ps_mv_col[1].i2_mvx = 0;
    222         ps_mv_col[1].i2_mvy = 0;
    223     }
    224     else
    225     {
    226         WORD32 au4_ref_idx_col[2];
    227         WORD32 pred_flag_l0, pred_flag_l1;
    228         pred_flag_l0 = (ps_col_pu->b2_pred_mode != PRED_L1);
    229         pred_flag_l1 = (ps_col_pu->b2_pred_mode != PRED_L0);
    230 
    231         if(pred_flag_l0 == 0)
    232         {
    233             as_mv_col[0] = ps_col_pu->mv.s_l1_mv;
    234             au4_ref_idx_col[0] = ps_col_pu->mv.i1_l1_ref_idx;
    235             au4_list_col[0] = 1; /* L1 */
    236 
    237             as_mv_col[1] = ps_col_pu->mv.s_l1_mv;
    238             au4_ref_idx_col[1] = ps_col_pu->mv.i1_l1_ref_idx;
    239             au4_list_col[1] = 1; /* L1 */
    240         }
    241         else
    242         {
    243             if(pred_flag_l1 == 0)
    244             {
    245                 as_mv_col[0] = ps_col_pu->mv.s_l0_mv;
    246                 au4_ref_idx_col[0] = ps_col_pu->mv.i1_l0_ref_idx;
    247                 au4_list_col[0] = 0; /* L1 */
    248 
    249                 as_mv_col[1] = ps_col_pu->mv.s_l0_mv;
    250                 au4_ref_idx_col[1] = ps_col_pu->mv.i1_l0_ref_idx;
    251                 au4_list_col[1] = 0; /* L1 */
    252             }
    253             else
    254             {
    255                 if(1 == ps_slice_hdr->i1_low_delay_flag)
    256                 {
    257                     as_mv_col[0] = ps_col_pu->mv.s_l0_mv;
    258                     au4_ref_idx_col[0] = ps_col_pu->mv.i1_l0_ref_idx;
    259                     au4_list_col[0] = 0; /* L0 */
    260 
    261                     as_mv_col[1] = ps_col_pu->mv.s_l1_mv;
    262                     au4_ref_idx_col[1] = ps_col_pu->mv.i1_l1_ref_idx;
    263                     au4_list_col[1] = 1; /* L1 */
    264                 }
    265                 else
    266                 {
    267                     if(0 == ps_slice_hdr->i1_collocated_from_l0_flag)
    268                     {
    269                         as_mv_col[0] = ps_col_pu->mv.s_l0_mv;
    270                         au4_ref_idx_col[0] = ps_col_pu->mv.i1_l0_ref_idx;
    271 
    272                         as_mv_col[1] = ps_col_pu->mv.s_l0_mv;
    273                         au4_ref_idx_col[1] = ps_col_pu->mv.i1_l0_ref_idx;
    274                     }
    275                     else
    276                     {
    277                         as_mv_col[0] = ps_col_pu->mv.s_l1_mv;
    278                         au4_ref_idx_col[0] = ps_col_pu->mv.i1_l1_ref_idx;
    279 
    280                         as_mv_col[1] = ps_col_pu->mv.s_l1_mv;
    281                         au4_ref_idx_col[1] = ps_col_pu->mv.i1_l1_ref_idx;
    282                     }
    283 
    284                     au4_list_col[0] = ps_slice_hdr->i1_collocated_from_l0_flag; /* L"collocated_from_l0_flag" */
    285                     au4_list_col[1] = ps_slice_hdr->i1_collocated_from_l0_flag; /* L"collocated_from_l0_flag" */
    286                 }
    287             }
    288         }
    289         avail_col = 1;
    290         {
    291             WORD32 cur_poc, col_poc, col_ref_poc_l0, cur_ref_poc;
    292             WORD32 col_ref_poc_l0_lt, cur_ref_poc_lt;
    293             WORD32 ref_idx_l0, ref_idx_l1;
    294             WORD32 slice_idx;
    295             pic_buf_t *ps_pic_buf;
    296 
    297             if(use_pu_ref_idx)
    298             {
    299                 ref_idx_l0 = ps_pu->mv.i1_l0_ref_idx;
    300                 ref_idx_l1 = ps_pu->mv.i1_l1_ref_idx;
    301             }
    302             else
    303             {
    304                 ref_idx_l0 = 0;
    305                 ref_idx_l1 = 0;
    306             }
    307 
    308             col_poc = ps_mv_buf_col->i4_abs_poc;
    309             cur_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
    310 
    311             slice_idx = *(ps_mv_buf_col->pu1_pic_slice_map + col_ctb_x + col_ctb_y * ps_sps->i2_pic_wd_in_ctb);
    312             slice_idx &= (MAX_SLICE_HDR_CNT - 1);
    313             if(au4_list_col[0] == 0)
    314             {
    315                 col_ref_poc_l0 =
    316                                 ps_mv_buf_col->ai4_l0_collocated_poc[slice_idx][au4_ref_idx_col[0]];
    317                 col_ref_poc_l0_lt =
    318                                 (ps_mv_buf_col->ai1_l0_collocated_poc_lt[slice_idx][au4_ref_idx_col[0]] == LONG_TERM_REF);
    319             }
    320             else
    321             {
    322                 col_ref_poc_l0 =
    323                                 ps_mv_buf_col->ai4_l1_collocated_poc[slice_idx][au4_ref_idx_col[0]];
    324                 col_ref_poc_l0_lt =
    325                                 (ps_mv_buf_col->ai1_l1_collocated_poc_lt[slice_idx][au4_ref_idx_col[0]] == LONG_TERM_REF);
    326             }
    327             /* L0 collocated mv */
    328             ps_pic_buf = (pic_buf_t *)((ps_ref_list[0][ref_idx_l0].pv_pic_buf));
    329             cur_ref_poc = ps_pic_buf->i4_abs_poc;
    330             cur_ref_poc_lt = (ps_pic_buf->u1_used_as_ref == LONG_TERM_REF);
    331 
    332             if(cur_ref_poc_lt == col_ref_poc_l0_lt)
    333             {
    334                 pu4_avail_col_flag[0] = 1;
    335 
    336                 if(cur_ref_poc_lt || ((col_poc - col_ref_poc_l0) == (cur_poc - cur_ref_poc)))
    337                 {
    338                     ps_mv_col[0] = as_mv_col[0];
    339                 }
    340                 else
    341                 {
    342                     ps_mv_col[0] = as_mv_col[0];
    343                     if(col_ref_poc_l0 != col_poc)
    344                         ihevcd_scale_collocated_mv((mv_t *)(&ps_mv_col[0]), cur_ref_poc,
    345                                                    col_ref_poc_l0, col_poc, cur_poc);
    346                 }
    347             }
    348             else
    349             {
    350                 pu4_avail_col_flag[0] = 0;
    351                 ps_mv_col[0].i2_mvx = 0;
    352                 ps_mv_col[0].i2_mvy = 0;
    353             }
    354             if((BSLICE == ps_slice_hdr->i1_slice_type))
    355             {
    356                 WORD32 col_ref_poc_l1_lt, col_ref_poc_l1;
    357 
    358                 if(au4_list_col[1] == 0)
    359                 {
    360                     col_ref_poc_l1 =
    361                                     ps_mv_buf_col->ai4_l0_collocated_poc[slice_idx][au4_ref_idx_col[1]];
    362                     col_ref_poc_l1_lt =
    363                                     (ps_mv_buf_col->ai1_l0_collocated_poc_lt[slice_idx][au4_ref_idx_col[1]] == LONG_TERM_REF);
    364                 }
    365                 else
    366                 {
    367                     col_ref_poc_l1 =
    368                                     ps_mv_buf_col->ai4_l1_collocated_poc[slice_idx][au4_ref_idx_col[1]];
    369                     col_ref_poc_l1_lt =
    370                                     (ps_mv_buf_col->ai1_l1_collocated_poc_lt[slice_idx][au4_ref_idx_col[1]] == LONG_TERM_REF);
    371                 }
    372 
    373                 /* L1 collocated mv */
    374                 ps_pic_buf = (pic_buf_t *)((ps_ref_list[1][ref_idx_l1].pv_pic_buf));
    375                 cur_ref_poc = ps_pic_buf->i4_abs_poc;
    376                 cur_ref_poc_lt = (ps_pic_buf->u1_used_as_ref == LONG_TERM_REF);
    377 
    378                 if(cur_ref_poc_lt == col_ref_poc_l1_lt)
    379                 {
    380                     pu4_avail_col_flag[1] = 1;
    381 
    382                     if(cur_ref_poc_lt || ((col_poc - col_ref_poc_l1) == (cur_poc - cur_ref_poc)))
    383                     {
    384                         ps_mv_col[1] = as_mv_col[1];
    385                     }
    386                     else
    387                     {
    388                         ps_mv_col[1] = as_mv_col[1];
    389                         if(col_ref_poc_l1 != col_poc)
    390                             ihevcd_scale_collocated_mv((mv_t *)&ps_mv_col[1], cur_ref_poc,
    391                                                        col_ref_poc_l1, col_poc, cur_poc);
    392                     }
    393                 }
    394                 else
    395                 {
    396                     pu4_avail_col_flag[1] = 0;
    397                     ps_mv_col[1].i2_mvx = 0;
    398                     ps_mv_col[1].i2_mvy = 0;
    399                 }
    400             }
    401             else
    402             {
    403                 pu4_avail_col_flag[1] = 0;
    404             }
    405         }
    406     }
    407 }
    408 
    409 
    410 /**
    411  *******************************************************************************
    412  *
    413  * @brief
    414  * This function performs Motion Vector Merge candidates derivation
    415  *
    416  * @par Description:
    417  *  MV merge list is computed using neighbor mvs and colocated mv
    418  *
    419  * @param[in] ps_ctxt
    420  * pointer to mv predictor context
    421  *
    422  * @param[in] ps_top_nbr_4x4
    423  * pointer to top 4x4 nbr structure
    424  *
    425  * @param[in] ps_left_nbr_4x4
    426  * pointer to left 4x4 nbr structure
    427  *
    428  * @param[in] ps_top_left_nbr_4x4
    429  * pointer to top left 4x4 nbr structure
    430  *
    431  * @param[in] left_nbr_4x4_strd
    432  * left nbr buffer stride in terms of 4x4 units
    433  *
    434  * @param[in] ps_avail_flags
    435  * Neighbor availability flags container
    436  *
    437  * @param[in] ps_col_mv
    438  * Colocated MV pointer
    439  *
    440  * @param[in] ps_pu
    441  * Current Partition PU strucrture pointer
    442  *
    443  * @param[in] part_mode
    444  * Partition mode @sa PART_SIZE_E
    445  *
    446  * @param[in] part_idx
    447  * Partition idx of current partition inside CU
    448  *
    449  * @param[in] single_mcl_flag
    450  * Single MCL flag based on 8x8 CU and Parallel merge value
    451  *
    452  * @param[out] ps_merge_cand_list
    453  * pointer to store MV merge candidates list
    454  *
    455  * @returns
    456  * None
    457  * @remarks
    458  *
    459  *
    460  *******************************************************************************
    461  */
    462 void ihevcd_mv_merge(mv_ctxt_t *ps_mv_ctxt,
    463                      UWORD32 *pu4_top_pu_idx,
    464                      UWORD32 *pu4_left_pu_idx,
    465                      WORD32 left_nbr_4x4_strd,
    466                      pu_t *ps_pu,
    467                      WORD32 part_mode,
    468                      WORD32 part_idx,
    469                      WORD32 part_wd,
    470                      WORD32 part_ht,
    471                      WORD32 part_pos_x,
    472                      WORD32 part_pos_y,
    473                      WORD32 single_mcl_flag,
    474                      WORD32 lb_avail,
    475                      WORD32 l_avail,
    476                      WORD32 tr_avail,
    477                      WORD32 t_avail,
    478                      WORD32 tl_avail)
    479 {
    480     /******************************************************/
    481     /*      Spatial Merge Candidates                      */
    482     /******************************************************/
    483     slice_header_t *ps_slice_hdr;
    484     pu_t as_pu_merge_list[MAX_NUM_MERGE_CAND];
    485     pps_t *ps_pps;
    486     ref_list_t *ps_ref_list[2];
    487     WORD32 sum_avail_a0_a1_b0_b1 = 0; /*Sum of availability of A0, A1, B0, B1*/
    488     WORD32 nbr_x, nbr_y;
    489     WORD32 nbr_avail[MAX_NUM_MV_NBR];
    490     WORD32 merge_shift;
    491     WORD32 nbr_pu_idx;
    492     pu_t *ps_nbr_pu[MAX_NUM_MV_NBR];
    493     WORD32 max_num_merge_cand;
    494     WORD32 candidate_cnt;
    495     WORD32 pos_x_merge_shift, pos_y_merge_shift;
    496 
    497     ps_slice_hdr = ps_mv_ctxt->ps_slice_hdr;
    498     ps_pps = ps_mv_ctxt->ps_pps;
    499     /* Initializing reference list */
    500     ps_ref_list[0] = ps_slice_hdr->as_ref_pic_list0;
    501     ps_ref_list[1] = ps_slice_hdr->as_ref_pic_list1;
    502     if(PSLICE == ps_slice_hdr->i1_slice_type)
    503         ps_ref_list[1] = ps_slice_hdr->as_ref_pic_list0;
    504 
    505     candidate_cnt = 0;
    506     /*******************************************/
    507     /* Neighbor location: Graphical indication */
    508     /*                                         */
    509     /*          B2 _____________B1 B0          */
    510     /*            |               |            */
    511     /*            |               |            */
    512     /*            |               |            */
    513     /*            |      PU     ht|            */
    514     /*            |               |            */
    515     /*            |               |            */
    516     /*          A1|______wd_______|            */
    517     /*          A0                             */
    518     /*                                         */
    519     /*******************************************/
    520 
    521     merge_shift = ps_pps->i1_log2_parallel_merge_level;
    522 
    523     /* Availability check */
    524     /* A1 */
    525     nbr_x = part_pos_x - 1;
    526     nbr_y = part_pos_y + part_ht - 1; /* A1 */
    527 
    528     nbr_pu_idx = *(pu4_left_pu_idx + ((nbr_y - part_pos_y) >> 2) * left_nbr_4x4_strd);
    529     ps_nbr_pu[NBR_A1] = ps_mv_ctxt->ps_pic_pu + nbr_pu_idx;
    530 
    531     nbr_avail[NBR_A1] = l_avail
    532                     && (!ps_nbr_pu[NBR_A1]->b1_intra_flag); /* A1 */
    533 
    534     pos_x_merge_shift = (part_pos_x >> merge_shift);
    535     pos_y_merge_shift = (part_pos_y >> merge_shift);
    536     max_num_merge_cand = ps_pu->b3_merge_idx + 1;
    537 
    538     {
    539         if(nbr_avail[NBR_A1])
    540         {
    541             /* if at same merge level */
    542             if(pos_x_merge_shift == (nbr_x >> merge_shift) &&
    543                (pos_y_merge_shift == (nbr_y >> merge_shift)))
    544             {
    545                 nbr_avail[NBR_A1] = 0;
    546             }
    547 
    548             /* SPEC JCTVC-K1003_v9 version has a different way using not available       */
    549             /* candidates compared to software. for non square part and seconf part case */
    550             /* ideally nothing from the 1st partition should be used as per spec but     */
    551             /* HM 8.2 dev verison does not adhere to this. currenlty code fllows HM      */
    552 
    553             /* if single MCL is 0 , second part of 2 part in CU */
    554             else if((single_mcl_flag == 0) && (part_idx == 1) &&
    555                             ((part_mode == PART_Nx2N) || (part_mode == PART_nLx2N) ||
    556                                             (part_mode == PART_nRx2N)))
    557             {
    558                 nbr_avail[NBR_A1] = 0;
    559             }
    560             sum_avail_a0_a1_b0_b1 += nbr_avail[NBR_A1];
    561             if(nbr_avail[NBR_A1])
    562             {
    563                 as_pu_merge_list[candidate_cnt] = *ps_nbr_pu[NBR_A1];
    564                 candidate_cnt++;
    565                 if(candidate_cnt == max_num_merge_cand)
    566                 {
    567                     ps_pu[0].mv = as_pu_merge_list[candidate_cnt - 1].mv;
    568                     ps_pu[0].b2_pred_mode = as_pu_merge_list[candidate_cnt - 1].b2_pred_mode;
    569                     return;
    570                 }
    571             }
    572         }
    573     }
    574 
    575     /* B1 */
    576     nbr_x = part_pos_x + part_wd - 1;
    577     nbr_y = part_pos_y - 1;
    578 
    579     nbr_pu_idx = *(pu4_top_pu_idx + ((nbr_x - part_pos_x) >> 2));
    580     ps_nbr_pu[NBR_B1] = ps_mv_ctxt->ps_pic_pu + nbr_pu_idx;
    581 
    582     nbr_avail[NBR_B1] = t_avail
    583                     && (!ps_nbr_pu[NBR_B1]->b1_intra_flag); /* B1 */
    584 
    585     {
    586         WORD32 avail_flag;
    587         avail_flag = nbr_avail[NBR_B1];
    588 
    589         if(nbr_avail[NBR_B1])
    590         {
    591             /* if at same merge level */
    592             if(pos_x_merge_shift == (nbr_x >> merge_shift) &&
    593                (pos_y_merge_shift == (nbr_y >> merge_shift)))
    594             {
    595                 nbr_avail[NBR_B1] = 0;
    596                 avail_flag = 0;
    597             }
    598 
    599             /* if single MCL is 0 , second part of 2 part in CU */
    600             else if((single_mcl_flag == 0) && (part_idx == 1) &&
    601                             ((part_mode == PART_2NxN) || (part_mode == PART_2NxnU) ||
    602                                             (part_mode == PART_2NxnD)))
    603             {
    604                 nbr_avail[NBR_B1] = 0;
    605                 avail_flag = 0;
    606             }
    607 
    608             else if(nbr_avail[NBR_A1])
    609             {
    610                 avail_flag = !ihevcd_compare_pu_t(ps_nbr_pu[NBR_A1], ps_nbr_pu[NBR_B1]);
    611             }
    612 
    613             sum_avail_a0_a1_b0_b1 += avail_flag;
    614             if(avail_flag)
    615             {
    616                 as_pu_merge_list[candidate_cnt] = *ps_nbr_pu[NBR_B1];
    617                 candidate_cnt++;
    618                 if(candidate_cnt == max_num_merge_cand)
    619                 {
    620                     ps_pu[0].mv = as_pu_merge_list[candidate_cnt - 1].mv;
    621                     ps_pu[0].b2_pred_mode = as_pu_merge_list[candidate_cnt - 1].b2_pred_mode;
    622                     return;
    623                 }
    624             }
    625         }
    626     }
    627     /* B0 */
    628     nbr_x = part_pos_x + part_wd;
    629     nbr_y = part_pos_y - 1;
    630 
    631     nbr_pu_idx = *(pu4_top_pu_idx + ((nbr_x - part_pos_x) >> 2));
    632     ps_nbr_pu[NBR_B0] = ps_mv_ctxt->ps_pic_pu + nbr_pu_idx;
    633 
    634     nbr_avail[NBR_B0] = tr_avail
    635                     && (!ps_nbr_pu[NBR_B0]->b1_intra_flag); /* B0 */
    636 
    637     {
    638         WORD32 avail_flag;
    639         avail_flag = nbr_avail[NBR_B0];
    640 
    641         /* if at same merge level */
    642         if(nbr_avail[NBR_B0])
    643         {
    644             if(pos_x_merge_shift == (nbr_x >> merge_shift) &&
    645                (pos_y_merge_shift == (nbr_y >> merge_shift)))
    646             {
    647                 nbr_avail[NBR_B0] = 0;
    648                 avail_flag = 0;
    649             }
    650             else if(nbr_avail[NBR_B1])
    651             {
    652                 avail_flag = !ihevcd_compare_pu_t(ps_nbr_pu[NBR_B1], ps_nbr_pu[NBR_B0]);
    653             }
    654 
    655             sum_avail_a0_a1_b0_b1 += avail_flag;
    656             if(avail_flag)
    657             {
    658                 as_pu_merge_list[candidate_cnt] = *ps_nbr_pu[NBR_B0];
    659                 candidate_cnt++;
    660                 if(candidate_cnt == max_num_merge_cand)
    661                 {
    662                     ps_pu[0].mv = as_pu_merge_list[candidate_cnt - 1].mv;
    663                     ps_pu[0].b2_pred_mode = as_pu_merge_list[candidate_cnt - 1].b2_pred_mode;
    664                     return;
    665                 }
    666             }
    667         }
    668     }
    669     /* A0 */
    670     nbr_x = part_pos_x - 1;
    671     nbr_y = part_pos_y + part_ht; /* A0 */
    672 
    673     nbr_pu_idx = *(pu4_left_pu_idx + ((nbr_y - part_pos_y) >> 2) * left_nbr_4x4_strd);
    674     ps_nbr_pu[NBR_A0] = ps_mv_ctxt->ps_pic_pu + nbr_pu_idx;
    675 
    676     nbr_avail[NBR_A0] = lb_avail
    677                     && (!ps_nbr_pu[NBR_A0]->b1_intra_flag); /* A0 */
    678     {
    679         WORD32 avail_flag;
    680         avail_flag = nbr_avail[NBR_A0];
    681 
    682         if(nbr_avail[NBR_A0])
    683         {
    684             /* if at same merge level */
    685             if(pos_x_merge_shift == (nbr_x >> merge_shift) &&
    686                             (pos_y_merge_shift == (nbr_y >> merge_shift)))
    687             {
    688                 nbr_avail[NBR_A0] = 0;
    689                 avail_flag = 0;
    690             }
    691             else if(nbr_avail[NBR_A1])
    692             {
    693                 avail_flag = !ihevcd_compare_pu_t(ps_nbr_pu[NBR_A1], ps_nbr_pu[NBR_A0]);
    694             }
    695 
    696             sum_avail_a0_a1_b0_b1 += avail_flag;
    697             if(avail_flag)
    698             {
    699                 as_pu_merge_list[candidate_cnt] = *ps_nbr_pu[NBR_A0];
    700                 candidate_cnt++;
    701                 if(candidate_cnt == max_num_merge_cand)
    702                 {
    703                     ps_pu[0].mv = as_pu_merge_list[candidate_cnt - 1].mv;
    704                     ps_pu[0].b2_pred_mode = as_pu_merge_list[candidate_cnt - 1].b2_pred_mode;
    705                     return;
    706                 }
    707             }
    708         }
    709     }
    710     /* B2 */
    711 
    712     nbr_x = part_pos_x - 1;
    713     nbr_y = part_pos_y - 1; /* B2 */
    714 
    715     nbr_pu_idx = *(pu4_top_pu_idx + ((nbr_x - part_pos_x) >> 2));
    716     ps_nbr_pu[NBR_B2] = ps_mv_ctxt->ps_pic_pu + nbr_pu_idx;
    717 
    718     nbr_avail[NBR_B2] = tl_avail
    719                     && (!ps_nbr_pu[NBR_B2]->b1_intra_flag); /* B2 */
    720 
    721     {
    722         WORD32 avail_flag;
    723         avail_flag = nbr_avail[NBR_B2];
    724 
    725         if(nbr_avail[NBR_B2])
    726         {
    727             /* if at same merge level */
    728             if(pos_x_merge_shift == (nbr_x >> merge_shift) &&
    729                             (pos_y_merge_shift == (nbr_y >> merge_shift)))
    730             {
    731                 nbr_avail[NBR_B2] = 0;
    732                 avail_flag = 0;
    733             }
    734             else if(4 == sum_avail_a0_a1_b0_b1)
    735             {
    736                 avail_flag = 0;
    737             }
    738 
    739             else
    740             {
    741                 if(nbr_avail[NBR_A1])
    742                 {
    743                     avail_flag = !ihevcd_compare_pu_t(ps_nbr_pu[NBR_A1], ps_nbr_pu[NBR_B2]);
    744                 }
    745 
    746                 if(avail_flag && nbr_avail[NBR_B1])
    747                 {
    748                     avail_flag = !ihevcd_compare_pu_t(ps_nbr_pu[NBR_B1], ps_nbr_pu[NBR_B2]);
    749                 }
    750             }
    751 
    752             if(avail_flag)
    753             {
    754                 as_pu_merge_list[candidate_cnt] = *ps_nbr_pu[NBR_B2];
    755                 candidate_cnt++;
    756                 if(candidate_cnt == max_num_merge_cand)
    757                 {
    758                     ps_pu[0].mv = as_pu_merge_list[candidate_cnt - 1].mv;
    759                     ps_pu[0].b2_pred_mode = as_pu_merge_list[candidate_cnt - 1].b2_pred_mode;
    760                     return;
    761                 }
    762             }
    763         }
    764     }
    765 
    766     /***********************************************************/
    767     /*          Collocated MV prediction                       */
    768     /***********************************************************/
    769     {
    770         mv_t as_mv_col[2];
    771         WORD32 avail_col_flag[2] = { 0 }, x_col, y_col;
    772         WORD32 avail_col_l0, avail_col_l1;
    773 //        ihevcd_collocated_mvp(ps_mv_ctxt,ps_pu,part_pos_x,part_pos_y,part_wd,part_ht,as_mv_col,avail_col_flag,0);
    774 
    775         /* Checking Collocated MV availability at Bottom right of PU*/
    776         x_col = part_pos_x + part_wd;
    777         y_col = part_pos_y + part_ht;
    778         ihevcd_collocated_mvp(ps_mv_ctxt, ps_pu, as_mv_col, avail_col_flag, 0, x_col, y_col);
    779 
    780         avail_col_l0 = avail_col_flag[0];
    781         avail_col_l1 = avail_col_flag[1];
    782 
    783         if(avail_col_l0 || avail_col_l1)
    784         {
    785             as_pu_merge_list[candidate_cnt].mv.s_l0_mv = as_mv_col[0];
    786             as_pu_merge_list[candidate_cnt].mv.s_l1_mv = as_mv_col[1];
    787         }
    788 
    789         if(avail_col_l0 == 0 || avail_col_l1 == 0)
    790         {
    791             /* Checking Collocated MV availability at Center of PU */
    792             x_col = part_pos_x + (part_wd >> 1);
    793             y_col = part_pos_y + (part_ht >> 1);
    794             ihevcd_collocated_mvp(ps_mv_ctxt, ps_pu, as_mv_col, avail_col_flag, 0, x_col, y_col);
    795 
    796             if(avail_col_l0 == 0)
    797             {
    798                 as_pu_merge_list[candidate_cnt].mv.s_l0_mv = as_mv_col[0];
    799             }
    800             if(avail_col_l1 == 0)
    801             {
    802                 as_pu_merge_list[candidate_cnt].mv.s_l1_mv = as_mv_col[1];
    803             }
    804 
    805             avail_col_l0 |= avail_col_flag[0];
    806             avail_col_l1 |= avail_col_flag[1];
    807         }
    808 
    809         as_pu_merge_list[candidate_cnt].mv.i1_l0_ref_idx = 0;
    810         as_pu_merge_list[candidate_cnt].mv.i1_l1_ref_idx = 0;
    811         as_pu_merge_list[candidate_cnt].b2_pred_mode = avail_col_l0 ? (avail_col_l1 ? PRED_BI : PRED_L0) : PRED_L1;
    812 
    813         candidate_cnt += (avail_col_l0 || avail_col_l1);
    814 
    815         if(candidate_cnt == max_num_merge_cand)
    816         {
    817             ps_pu[0].mv = as_pu_merge_list[candidate_cnt - 1].mv;
    818             ps_pu[0].b2_pred_mode = as_pu_merge_list[candidate_cnt - 1].b2_pred_mode;
    819             return;
    820         }
    821 
    822     }
    823     {
    824         WORD32 slice_type;
    825 
    826         slice_type = ps_slice_hdr->i1_slice_type;
    827         /* Colocated mv has to be added to list, if available */
    828 
    829         /******************************************************/
    830         /*      Bi pred merge candidates                      */
    831         /******************************************************/
    832         if(slice_type == BSLICE)
    833         {
    834             if((candidate_cnt > 1) && (candidate_cnt < MAX_NUM_MERGE_CAND))
    835             {
    836                 WORD32 priority_list0[12] =
    837                     { 0, 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3 };
    838                 WORD32 priority_list1[12] =
    839                     { 1, 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2 };
    840                 WORD32 l0_cand, l1_cand;
    841                 WORD32 bi_pred_idx = 0;
    842                 WORD32 total_bi_pred_cand =
    843                                 candidate_cnt * (candidate_cnt - 1);
    844 
    845                 while(bi_pred_idx < total_bi_pred_cand)
    846                 {
    847                     l0_cand = priority_list0[bi_pred_idx];
    848                     l1_cand = priority_list1[bi_pred_idx];
    849 
    850                     if((as_pu_merge_list[l0_cand].b2_pred_mode != PRED_L1)
    851                                     && (as_pu_merge_list[l1_cand].b2_pred_mode
    852                                                     != PRED_L0))
    853                     {
    854                         WORD8 i1_l0_ref_idx, i1_l1_ref_idx;
    855                         mv_t s_l0_mv, s_l1_mv;
    856                         pic_buf_t *ps_pic_buf_l0, *ps_pic_buf_l1;
    857 
    858                         i1_l0_ref_idx = as_pu_merge_list[l0_cand].mv.i1_l0_ref_idx;
    859                         i1_l1_ref_idx = as_pu_merge_list[l1_cand].mv.i1_l1_ref_idx;
    860                         ps_pic_buf_l0 = (pic_buf_t *)((ps_ref_list[0][i1_l0_ref_idx].pv_pic_buf));
    861                         ps_pic_buf_l1 = (pic_buf_t *)((ps_ref_list[1][i1_l1_ref_idx].pv_pic_buf));
    862                         s_l0_mv = as_pu_merge_list[l0_cand].mv.s_l0_mv;
    863                         s_l1_mv = as_pu_merge_list[l1_cand].mv.s_l1_mv;
    864 
    865                         if((ps_pic_buf_l0->i4_abs_poc != ps_pic_buf_l1->i4_abs_poc)
    866                                         || (s_l0_mv.i2_mvx != s_l1_mv.i2_mvx)
    867                                         || (s_l0_mv.i2_mvy != s_l1_mv.i2_mvy))
    868                         {
    869                             candidate_cnt++;
    870                             if(candidate_cnt == max_num_merge_cand)
    871                             {
    872                                 ps_pu[0].mv.s_l0_mv = s_l0_mv;
    873                                 ps_pu[0].mv.s_l1_mv = s_l1_mv;
    874                                 ps_pu[0].mv.i1_l0_ref_idx = i1_l0_ref_idx;
    875                                 ps_pu[0].mv.i1_l1_ref_idx = i1_l1_ref_idx;
    876                                 ps_pu[0].b2_pred_mode = PRED_BI;
    877                                 return;
    878                             }
    879                         }
    880                     }
    881 
    882                     bi_pred_idx++;
    883 
    884                     if((bi_pred_idx == total_bi_pred_cand)
    885                                     || (candidate_cnt == MAX_NUM_MERGE_CAND))
    886                     {
    887                         break;
    888                     }
    889                 }
    890             }
    891         }
    892 
    893         /******************************************************/
    894         /*      Zero merge candidates                         */
    895         /******************************************************/
    896 //        if(candidate_cnt < max_num_merge_cand)
    897         {
    898             WORD32 num_ref_idx;
    899             WORD32 zero_idx;
    900 
    901             zero_idx = max_num_merge_cand - candidate_cnt - 1;
    902 
    903             if(slice_type == PSLICE)
    904                 num_ref_idx = ps_slice_hdr->i1_num_ref_idx_l0_active;
    905             else
    906                 /* Slice type B */
    907                 num_ref_idx = MIN(ps_slice_hdr->i1_num_ref_idx_l0_active, ps_slice_hdr->i1_num_ref_idx_l1_active);
    908 
    909             if(zero_idx >= num_ref_idx)
    910                 zero_idx = 0;
    911 
    912             ps_pu[0].mv.i1_l0_ref_idx = zero_idx;
    913             if(slice_type == PSLICE)
    914             {
    915                 ps_pu[0].mv.i1_l1_ref_idx = 0;
    916                 ps_pu[0].b2_pred_mode = PRED_L0;
    917             }
    918             else /* Slice type B */
    919             {
    920                 ps_pu[0].mv.i1_l1_ref_idx = zero_idx;
    921                 ps_pu[0].b2_pred_mode = PRED_BI;
    922             }
    923 
    924             ps_pu[0].mv.s_l0_mv.i2_mvx = 0;
    925             ps_pu[0].mv.s_l0_mv.i2_mvy = 0;
    926             ps_pu[0].mv.s_l1_mv.i2_mvx = 0;
    927             ps_pu[0].mv.s_l1_mv.i2_mvy = 0;
    928 
    929             candidate_cnt++;
    930         }
    931     }
    932 
    933     return;
    934 }
    935 
    936 
    937