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