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