1/* 2 * HEVC video decoder 3 * 4 * Copyright (C) 2012 - 2013 Guillaume Martres 5 * Copyright (C) 2013 Anand Meher Kotra 6 * 7 * This file is part of FFmpeg. 8 * 9 * FFmpeg is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2.1 of the License, or (at your option) any later version. 13 * 14 * FFmpeg is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with FFmpeg; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 */ 23 24#include "hevc.h" 25#include "hevcdec.h" 26#include "threadframe.h" 27 28static const uint8_t l0_l1_cand_idx[12][2] = { 29 { 0, 1, }, 30 { 1, 0, }, 31 { 0, 2, }, 32 { 2, 0, }, 33 { 1, 2, }, 34 { 2, 1, }, 35 { 0, 3, }, 36 { 3, 0, }, 37 { 1, 3, }, 38 { 3, 1, }, 39 { 2, 3, }, 40 { 3, 2, }, 41}; 42 43void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0, 44 int nPbW, int nPbH) 45{ 46 HEVCLocalContext *lc = s->HEVClc; 47 int x0b = av_mod_uintp2(x0, s->ps.sps->log2_ctb_size); 48 int y0b = av_mod_uintp2(y0, s->ps.sps->log2_ctb_size); 49 50 lc->na.cand_up = (lc->ctb_up_flag || y0b); 51 lc->na.cand_left = (lc->ctb_left_flag || x0b); 52 lc->na.cand_up_left = (x0b || y0b) ? lc->na.cand_left && lc->na.cand_up : lc->ctb_up_left_flag; 53 lc->na.cand_up_right_sap = 54 (x0b + nPbW == 1 << s->ps.sps->log2_ctb_size) ? 55 lc->ctb_up_right_flag && !y0b : lc->na.cand_up; 56 lc->na.cand_up_right = 57 lc->na.cand_up_right_sap 58 && (x0 + nPbW) < lc->end_of_tiles_x; 59 lc->na.cand_bottom_left = ((y0 + nPbH) >= lc->end_of_tiles_y) ? 0 : lc->na.cand_left; 60} 61 62/* 63 * 6.4.1 Derivation process for z-scan order block availability 64 */ 65static av_always_inline int z_scan_block_avail(HEVCContext *s, int xCurr, int yCurr, 66 int xN, int yN) 67{ 68#define MIN_TB_ADDR_ZS(x, y) \ 69 s->ps.pps->min_tb_addr_zs[(y) * (s->ps.sps->tb_mask+2) + (x)] 70 71 int xCurr_ctb = xCurr >> s->ps.sps->log2_ctb_size; 72 int yCurr_ctb = yCurr >> s->ps.sps->log2_ctb_size; 73 int xN_ctb = xN >> s->ps.sps->log2_ctb_size; 74 int yN_ctb = yN >> s->ps.sps->log2_ctb_size; 75 if( yN_ctb < yCurr_ctb || xN_ctb < xCurr_ctb ) 76 return 1; 77 else { 78 int Curr = MIN_TB_ADDR_ZS((xCurr >> s->ps.sps->log2_min_tb_size) & s->ps.sps->tb_mask, 79 (yCurr >> s->ps.sps->log2_min_tb_size) & s->ps.sps->tb_mask); 80 int N = MIN_TB_ADDR_ZS((xN >> s->ps.sps->log2_min_tb_size) & s->ps.sps->tb_mask, 81 (yN >> s->ps.sps->log2_min_tb_size) & s->ps.sps->tb_mask); 82 return N <= Curr; 83 } 84} 85 86//check if the two luma locations belong to the same motion estimation region 87static av_always_inline int is_diff_mer(HEVCContext *s, int xN, int yN, int xP, int yP) 88{ 89 uint8_t plevel = s->ps.pps->log2_parallel_merge_level; 90 91 return xN >> plevel == xP >> plevel && 92 yN >> plevel == yP >> plevel; 93} 94 95#define MATCH_MV(x) (AV_RN32A(&A.x) == AV_RN32A(&B.x)) 96#define MATCH(x) (A.x == B.x) 97 98// check if the mv's and refidx are the same between A and B 99static av_always_inline int compare_mv_ref_idx(struct MvField A, struct MvField B) 100{ 101 int a_pf = A.pred_flag; 102 int b_pf = B.pred_flag; 103 if (a_pf == b_pf) { 104 if (a_pf == PF_BI) { 105 return MATCH(ref_idx[0]) && MATCH_MV(mv[0]) && 106 MATCH(ref_idx[1]) && MATCH_MV(mv[1]); 107 } else if (a_pf == PF_L0) { 108 return MATCH(ref_idx[0]) && MATCH_MV(mv[0]); 109 } else if (a_pf == PF_L1) { 110 return MATCH(ref_idx[1]) && MATCH_MV(mv[1]); 111 } 112 } 113 return 0; 114} 115 116static av_always_inline void mv_scale(Mv *dst, const Mv *src, int td, int tb) 117{ 118 int tx, scale_factor; 119 120 td = av_clip_int8(td); 121 tb = av_clip_int8(tb); 122 tx = (0x4000 + abs(td / 2)) / td; 123 scale_factor = av_clip_intp2((tb * tx + 32) >> 6, 12); 124 dst->x = av_clip_int16((scale_factor * src->x + 127 + 125 (scale_factor * src->x < 0)) >> 8); 126 dst->y = av_clip_int16((scale_factor * src->y + 127 + 127 (scale_factor * src->y < 0)) >> 8); 128} 129 130static int check_mvset(Mv *mvLXCol, const Mv *mvCol, 131 int colPic, int poc, 132 const RefPicList *refPicList, int X, int refIdxLx, 133 const RefPicList *refPicList_col, int listCol, int refidxCol) 134{ 135 int cur_lt = refPicList[X].isLongTerm[refIdxLx]; 136 int col_lt = refPicList_col[listCol].isLongTerm[refidxCol]; 137 int col_poc_diff, cur_poc_diff; 138 139 if (cur_lt != col_lt) { 140 mvLXCol->x = 0; 141 mvLXCol->y = 0; 142 return 0; 143 } 144 145 col_poc_diff = colPic - refPicList_col[listCol].list[refidxCol]; 146 cur_poc_diff = poc - refPicList[X].list[refIdxLx]; 147 148 if (cur_lt || col_poc_diff == cur_poc_diff || !col_poc_diff) { 149 mvLXCol->x = mvCol->x; 150 mvLXCol->y = mvCol->y; 151 } else { 152 mv_scale(mvLXCol, mvCol, col_poc_diff, cur_poc_diff); 153 } 154 return 1; 155} 156 157#define CHECK_MVSET(l) \ 158 check_mvset(mvLXCol, temp_col.mv + l, \ 159 colPic, s->poc, \ 160 refPicList, X, refIdxLx, \ 161 refPicList_col, L ## l, temp_col.ref_idx[l]) 162 163// derive the motion vectors section 8.5.3.1.8 164static int derive_temporal_colocated_mvs(HEVCContext *s, MvField temp_col, 165 int refIdxLx, Mv *mvLXCol, int X, 166 int colPic, const RefPicList *refPicList_col) 167{ 168 RefPicList *refPicList = s->ref->refPicList; 169 170 if (temp_col.pred_flag == PF_INTRA) 171 return 0; 172 173 if (!(temp_col.pred_flag & PF_L0)) 174 return CHECK_MVSET(1); 175 else if (temp_col.pred_flag == PF_L0) 176 return CHECK_MVSET(0); 177 else if (temp_col.pred_flag == PF_BI) { 178 int check_diffpicount = 0; 179 int i, j; 180 for (j = 0; j < 2; j++) { 181 for (i = 0; i < refPicList[j].nb_refs; i++) { 182 if (refPicList[j].list[i] > s->poc) { 183 check_diffpicount++; 184 break; 185 } 186 } 187 } 188 if (!check_diffpicount) { 189 if (X==0) 190 return CHECK_MVSET(0); 191 else 192 return CHECK_MVSET(1); 193 } else { 194 if (s->sh.collocated_list == L1) 195 return CHECK_MVSET(0); 196 else 197 return CHECK_MVSET(1); 198 } 199 } 200 201 return 0; 202} 203 204#define TAB_MVF(x, y) \ 205 tab_mvf[(y) * min_pu_width + x] 206 207#define TAB_MVF_PU(v) \ 208 TAB_MVF(((x ## v) >> s->ps.sps->log2_min_pu_size), \ 209 ((y ## v) >> s->ps.sps->log2_min_pu_size)) 210 211#define DERIVE_TEMPORAL_COLOCATED_MVS \ 212 derive_temporal_colocated_mvs(s, temp_col, \ 213 refIdxLx, mvLXCol, X, colPic, \ 214 ff_hevc_get_ref_list(s, ref, x, y)) 215 216/* 217 * 8.5.3.1.7 temporal luma motion vector prediction 218 */ 219static int temporal_luma_motion_vector(HEVCContext *s, int x0, int y0, 220 int nPbW, int nPbH, int refIdxLx, 221 Mv *mvLXCol, int X) 222{ 223 MvField *tab_mvf; 224 MvField temp_col; 225 int x, y, x_pu, y_pu; 226 int min_pu_width = s->ps.sps->min_pu_width; 227 int availableFlagLXCol = 0; 228 int colPic; 229 230 HEVCFrame *ref = s->ref->collocated_ref; 231 232 if (!ref) { 233 memset(mvLXCol, 0, sizeof(*mvLXCol)); 234 return 0; 235 } 236 237 tab_mvf = ref->tab_mvf; 238 colPic = ref->poc; 239 240 //bottom right collocated motion vector 241 x = x0 + nPbW; 242 y = y0 + nPbH; 243 244 if (tab_mvf && 245 (y0 >> s->ps.sps->log2_ctb_size) == (y >> s->ps.sps->log2_ctb_size) && 246 y < s->ps.sps->height && 247 x < s->ps.sps->width) { 248 x &= ~15; 249 y &= ~15; 250 if (s->threads_type == FF_THREAD_FRAME) 251 ff_thread_await_progress(&ref->tf, y, 0); 252 x_pu = x >> s->ps.sps->log2_min_pu_size; 253 y_pu = y >> s->ps.sps->log2_min_pu_size; 254 temp_col = TAB_MVF(x_pu, y_pu); 255 availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS; 256 } 257 258 // derive center collocated motion vector 259 if (tab_mvf && !availableFlagLXCol) { 260 x = x0 + (nPbW >> 1); 261 y = y0 + (nPbH >> 1); 262 x &= ~15; 263 y &= ~15; 264 if (s->threads_type == FF_THREAD_FRAME) 265 ff_thread_await_progress(&ref->tf, y, 0); 266 x_pu = x >> s->ps.sps->log2_min_pu_size; 267 y_pu = y >> s->ps.sps->log2_min_pu_size; 268 temp_col = TAB_MVF(x_pu, y_pu); 269 availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS; 270 } 271 return availableFlagLXCol; 272} 273 274#define AVAILABLE(cand, v) \ 275 (cand && !(TAB_MVF_PU(v).pred_flag == PF_INTRA)) 276 277#define PRED_BLOCK_AVAILABLE(v) \ 278 z_scan_block_avail(s, x0, y0, x ## v, y ## v) 279 280#define COMPARE_MV_REFIDX(a, b) \ 281 compare_mv_ref_idx(TAB_MVF_PU(a), TAB_MVF_PU(b)) 282 283/* 284 * 8.5.3.1.2 Derivation process for spatial merging candidates 285 */ 286static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0, 287 int nPbW, int nPbH, 288 int log2_cb_size, 289 int singleMCLFlag, int part_idx, 290 int merge_idx, 291 struct MvField mergecandlist[]) 292{ 293 HEVCLocalContext *lc = s->HEVClc; 294 RefPicList *refPicList = s->ref->refPicList; 295 MvField *tab_mvf = s->ref->tab_mvf; 296 297 const int min_pu_width = s->ps.sps->min_pu_width; 298 299 const int cand_bottom_left = lc->na.cand_bottom_left; 300 const int cand_left = lc->na.cand_left; 301 const int cand_up_left = lc->na.cand_up_left; 302 const int cand_up = lc->na.cand_up; 303 const int cand_up_right = lc->na.cand_up_right_sap; 304 305 const int xA1 = x0 - 1; 306 const int yA1 = y0 + nPbH - 1; 307 308 const int xB1 = x0 + nPbW - 1; 309 const int yB1 = y0 - 1; 310 311 const int xB0 = x0 + nPbW; 312 const int yB0 = y0 - 1; 313 314 const int xA0 = x0 - 1; 315 const int yA0 = y0 + nPbH; 316 317 const int xB2 = x0 - 1; 318 const int yB2 = y0 - 1; 319 320 const int nb_refs = (s->sh.slice_type == HEVC_SLICE_P) ? 321 s->sh.nb_refs[0] : FFMIN(s->sh.nb_refs[0], s->sh.nb_refs[1]); 322 323 int zero_idx = 0; 324 325 int nb_merge_cand = 0; 326 int nb_orig_merge_cand = 0; 327 328 int is_available_a0; 329 int is_available_a1; 330 int is_available_b0; 331 int is_available_b1; 332 int is_available_b2; 333 334 335 if (!singleMCLFlag && part_idx == 1 && 336 (lc->cu.part_mode == PART_Nx2N || 337 lc->cu.part_mode == PART_nLx2N || 338 lc->cu.part_mode == PART_nRx2N) || 339 is_diff_mer(s, xA1, yA1, x0, y0)) { 340 is_available_a1 = 0; 341 } else { 342 is_available_a1 = AVAILABLE(cand_left, A1); 343 if (is_available_a1) { 344 mergecandlist[nb_merge_cand] = TAB_MVF_PU(A1); 345 if (merge_idx == 0) 346 return; 347 nb_merge_cand++; 348 } 349 } 350 351 if (!singleMCLFlag && part_idx == 1 && 352 (lc->cu.part_mode == PART_2NxN || 353 lc->cu.part_mode == PART_2NxnU || 354 lc->cu.part_mode == PART_2NxnD) || 355 is_diff_mer(s, xB1, yB1, x0, y0)) { 356 is_available_b1 = 0; 357 } else { 358 is_available_b1 = AVAILABLE(cand_up, B1); 359 if (is_available_b1 && 360 !(is_available_a1 && COMPARE_MV_REFIDX(B1, A1))) { 361 mergecandlist[nb_merge_cand] = TAB_MVF_PU(B1); 362 if (merge_idx == nb_merge_cand) 363 return; 364 nb_merge_cand++; 365 } 366 } 367 368 // above right spatial merge candidate 369 is_available_b0 = AVAILABLE(cand_up_right, B0) && 370 xB0 < s->ps.sps->width && 371 PRED_BLOCK_AVAILABLE(B0) && 372 !is_diff_mer(s, xB0, yB0, x0, y0); 373 374 if (is_available_b0 && 375 !(is_available_b1 && COMPARE_MV_REFIDX(B0, B1))) { 376 mergecandlist[nb_merge_cand] = TAB_MVF_PU(B0); 377 if (merge_idx == nb_merge_cand) 378 return; 379 nb_merge_cand++; 380 } 381 382 // left bottom spatial merge candidate 383 is_available_a0 = AVAILABLE(cand_bottom_left, A0) && 384 yA0 < s->ps.sps->height && 385 PRED_BLOCK_AVAILABLE(A0) && 386 !is_diff_mer(s, xA0, yA0, x0, y0); 387 388 if (is_available_a0 && 389 !(is_available_a1 && COMPARE_MV_REFIDX(A0, A1))) { 390 mergecandlist[nb_merge_cand] = TAB_MVF_PU(A0); 391 if (merge_idx == nb_merge_cand) 392 return; 393 nb_merge_cand++; 394 } 395 396 // above left spatial merge candidate 397 is_available_b2 = AVAILABLE(cand_up_left, B2) && 398 !is_diff_mer(s, xB2, yB2, x0, y0); 399 400 if (is_available_b2 && 401 !(is_available_a1 && COMPARE_MV_REFIDX(B2, A1)) && 402 !(is_available_b1 && COMPARE_MV_REFIDX(B2, B1)) && 403 nb_merge_cand != 4) { 404 mergecandlist[nb_merge_cand] = TAB_MVF_PU(B2); 405 if (merge_idx == nb_merge_cand) 406 return; 407 nb_merge_cand++; 408 } 409 410 // temporal motion vector candidate 411 if (s->sh.slice_temporal_mvp_enabled_flag && 412 nb_merge_cand < s->sh.max_num_merge_cand) { 413 Mv mv_l0_col = { 0 }, mv_l1_col = { 0 }; 414 int available_l0 = temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH, 415 0, &mv_l0_col, 0); 416 int available_l1 = (s->sh.slice_type == HEVC_SLICE_B) ? 417 temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH, 418 0, &mv_l1_col, 1) : 0; 419 420 if (available_l0 || available_l1) { 421 mergecandlist[nb_merge_cand].pred_flag = available_l0 + (available_l1 << 1); 422 AV_ZERO16(mergecandlist[nb_merge_cand].ref_idx); 423 mergecandlist[nb_merge_cand].mv[0] = mv_l0_col; 424 mergecandlist[nb_merge_cand].mv[1] = mv_l1_col; 425 426 if (merge_idx == nb_merge_cand) 427 return; 428 nb_merge_cand++; 429 } 430 } 431 432 nb_orig_merge_cand = nb_merge_cand; 433 434 // combined bi-predictive merge candidates (applies for B slices) 435 if (s->sh.slice_type == HEVC_SLICE_B && nb_orig_merge_cand > 1 && 436 nb_orig_merge_cand < s->sh.max_num_merge_cand) { 437 int comb_idx = 0; 438 439 for (comb_idx = 0; nb_merge_cand < s->sh.max_num_merge_cand && 440 comb_idx < nb_orig_merge_cand * (nb_orig_merge_cand - 1); comb_idx++) { 441 int l0_cand_idx = l0_l1_cand_idx[comb_idx][0]; 442 int l1_cand_idx = l0_l1_cand_idx[comb_idx][1]; 443 MvField l0_cand = mergecandlist[l0_cand_idx]; 444 MvField l1_cand = mergecandlist[l1_cand_idx]; 445 446 if ((l0_cand.pred_flag & PF_L0) && (l1_cand.pred_flag & PF_L1) && 447 (refPicList[0].list[l0_cand.ref_idx[0]] != 448 refPicList[1].list[l1_cand.ref_idx[1]] || 449 AV_RN32A(&l0_cand.mv[0]) != AV_RN32A(&l1_cand.mv[1]))) { 450 mergecandlist[nb_merge_cand].ref_idx[0] = l0_cand.ref_idx[0]; 451 mergecandlist[nb_merge_cand].ref_idx[1] = l1_cand.ref_idx[1]; 452 mergecandlist[nb_merge_cand].pred_flag = PF_BI; 453 AV_COPY32(&mergecandlist[nb_merge_cand].mv[0], &l0_cand.mv[0]); 454 AV_COPY32(&mergecandlist[nb_merge_cand].mv[1], &l1_cand.mv[1]); 455 if (merge_idx == nb_merge_cand) 456 return; 457 nb_merge_cand++; 458 } 459 } 460 } 461 462 // append Zero motion vector candidates 463 while (nb_merge_cand < s->sh.max_num_merge_cand) { 464 mergecandlist[nb_merge_cand].pred_flag = PF_L0 + ((s->sh.slice_type == HEVC_SLICE_B) << 1); 465 AV_ZERO32(mergecandlist[nb_merge_cand].mv + 0); 466 AV_ZERO32(mergecandlist[nb_merge_cand].mv + 1); 467 mergecandlist[nb_merge_cand].ref_idx[0] = zero_idx < nb_refs ? zero_idx : 0; 468 mergecandlist[nb_merge_cand].ref_idx[1] = zero_idx < nb_refs ? zero_idx : 0; 469 470 if (merge_idx == nb_merge_cand) 471 return; 472 nb_merge_cand++; 473 zero_idx++; 474 } 475} 476 477/* 478 * 8.5.3.1.1 Derivation process of luma Mvs for merge mode 479 */ 480void ff_hevc_luma_mv_merge_mode(HEVCContext *s, int x0, int y0, int nPbW, 481 int nPbH, int log2_cb_size, int part_idx, 482 int merge_idx, MvField *mv) 483{ 484 int singleMCLFlag = 0; 485 int nCS = 1 << log2_cb_size; 486 MvField mergecand_list[MRG_MAX_NUM_CANDS]; 487 int nPbW2 = nPbW; 488 int nPbH2 = nPbH; 489 HEVCLocalContext *lc = s->HEVClc; 490 491 if (s->ps.pps->log2_parallel_merge_level > 2 && nCS == 8) { 492 singleMCLFlag = 1; 493 x0 = lc->cu.x; 494 y0 = lc->cu.y; 495 nPbW = nCS; 496 nPbH = nCS; 497 part_idx = 0; 498 } 499 500 ff_hevc_set_neighbour_available(s, x0, y0, nPbW, nPbH); 501 derive_spatial_merge_candidates(s, x0, y0, nPbW, nPbH, log2_cb_size, 502 singleMCLFlag, part_idx, 503 merge_idx, mergecand_list); 504 505 if (mergecand_list[merge_idx].pred_flag == PF_BI && 506 (nPbW2 + nPbH2) == 12) { 507 mergecand_list[merge_idx].pred_flag = PF_L0; 508 } 509 510 *mv = mergecand_list[merge_idx]; 511} 512 513static av_always_inline void dist_scale(HEVCContext *s, Mv *mv, 514 int min_pu_width, int x, int y, 515 int elist, int ref_idx_curr, int ref_idx) 516{ 517 RefPicList *refPicList = s->ref->refPicList; 518 MvField *tab_mvf = s->ref->tab_mvf; 519 int ref_pic_elist = refPicList[elist].list[TAB_MVF(x, y).ref_idx[elist]]; 520 int ref_pic_curr = refPicList[ref_idx_curr].list[ref_idx]; 521 522 if (ref_pic_elist != ref_pic_curr) { 523 int poc_diff = s->poc - ref_pic_elist; 524 if (!poc_diff) 525 poc_diff = 1; 526 mv_scale(mv, mv, poc_diff, s->poc - ref_pic_curr); 527 } 528} 529 530static int mv_mp_mode_mx(HEVCContext *s, int x, int y, int pred_flag_index, 531 Mv *mv, int ref_idx_curr, int ref_idx) 532{ 533 MvField *tab_mvf = s->ref->tab_mvf; 534 int min_pu_width = s->ps.sps->min_pu_width; 535 536 RefPicList *refPicList = s->ref->refPicList; 537 538 if (((TAB_MVF(x, y).pred_flag) & (1 << pred_flag_index)) && 539 refPicList[pred_flag_index].list[TAB_MVF(x, y).ref_idx[pred_flag_index]] == refPicList[ref_idx_curr].list[ref_idx]) { 540 *mv = TAB_MVF(x, y).mv[pred_flag_index]; 541 return 1; 542 } 543 return 0; 544} 545 546static int mv_mp_mode_mx_lt(HEVCContext *s, int x, int y, int pred_flag_index, 547 Mv *mv, int ref_idx_curr, int ref_idx) 548{ 549 MvField *tab_mvf = s->ref->tab_mvf; 550 int min_pu_width = s->ps.sps->min_pu_width; 551 552 RefPicList *refPicList = s->ref->refPicList; 553 554 if ((TAB_MVF(x, y).pred_flag) & (1 << pred_flag_index)) { 555 int currIsLongTerm = refPicList[ref_idx_curr].isLongTerm[ref_idx]; 556 557 int colIsLongTerm = 558 refPicList[pred_flag_index].isLongTerm[(TAB_MVF(x, y).ref_idx[pred_flag_index])]; 559 560 if (colIsLongTerm == currIsLongTerm) { 561 *mv = TAB_MVF(x, y).mv[pred_flag_index]; 562 if (!currIsLongTerm) 563 dist_scale(s, mv, min_pu_width, x, y, 564 pred_flag_index, ref_idx_curr, ref_idx); 565 return 1; 566 } 567 } 568 return 0; 569} 570 571#define MP_MX(v, pred, mx) \ 572 mv_mp_mode_mx(s, \ 573 (x ## v) >> s->ps.sps->log2_min_pu_size, \ 574 (y ## v) >> s->ps.sps->log2_min_pu_size, \ 575 pred, &mx, ref_idx_curr, ref_idx) 576 577#define MP_MX_LT(v, pred, mx) \ 578 mv_mp_mode_mx_lt(s, \ 579 (x ## v) >> s->ps.sps->log2_min_pu_size, \ 580 (y ## v) >> s->ps.sps->log2_min_pu_size, \ 581 pred, &mx, ref_idx_curr, ref_idx) 582 583void ff_hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0, int nPbW, 584 int nPbH, int log2_cb_size, int part_idx, 585 int merge_idx, MvField *mv, 586 int mvp_lx_flag, int LX) 587{ 588 HEVCLocalContext *lc = s->HEVClc; 589 MvField *tab_mvf = s->ref->tab_mvf; 590 int isScaledFlag_L0 = 0; 591 int availableFlagLXA0 = 1; 592 int availableFlagLXB0 = 1; 593 int numMVPCandLX = 0; 594 int min_pu_width = s->ps.sps->min_pu_width; 595 596 int xA0, yA0; 597 int is_available_a0; 598 int xA1, yA1; 599 int is_available_a1; 600 int xB0, yB0; 601 int is_available_b0; 602 int xB1, yB1; 603 int is_available_b1; 604 int xB2, yB2; 605 int is_available_b2; 606 607 Mv mvpcand_list[2] = { { 0 } }; 608 Mv mxA; 609 Mv mxB; 610 int ref_idx_curr; 611 int ref_idx = 0; 612 int pred_flag_index_l0; 613 int pred_flag_index_l1; 614 615 const int cand_bottom_left = lc->na.cand_bottom_left; 616 const int cand_left = lc->na.cand_left; 617 const int cand_up_left = lc->na.cand_up_left; 618 const int cand_up = lc->na.cand_up; 619 const int cand_up_right = lc->na.cand_up_right_sap; 620 ref_idx_curr = LX; 621 ref_idx = mv->ref_idx[LX]; 622 pred_flag_index_l0 = LX; 623 pred_flag_index_l1 = !LX; 624 625 // left bottom spatial candidate 626 xA0 = x0 - 1; 627 yA0 = y0 + nPbH; 628 629 is_available_a0 = AVAILABLE(cand_bottom_left, A0) && 630 yA0 < s->ps.sps->height && 631 PRED_BLOCK_AVAILABLE(A0); 632 633 //left spatial merge candidate 634 xA1 = x0 - 1; 635 yA1 = y0 + nPbH - 1; 636 637 is_available_a1 = AVAILABLE(cand_left, A1); 638 if (is_available_a0 || is_available_a1) 639 isScaledFlag_L0 = 1; 640 641 if (is_available_a0) { 642 if (MP_MX(A0, pred_flag_index_l0, mxA)) { 643 goto b_candidates; 644 } 645 if (MP_MX(A0, pred_flag_index_l1, mxA)) { 646 goto b_candidates; 647 } 648 } 649 650 if (is_available_a1) { 651 if (MP_MX(A1, pred_flag_index_l0, mxA)) { 652 goto b_candidates; 653 } 654 if (MP_MX(A1, pred_flag_index_l1, mxA)) { 655 goto b_candidates; 656 } 657 } 658 659 if (is_available_a0) { 660 if (MP_MX_LT(A0, pred_flag_index_l0, mxA)) { 661 goto b_candidates; 662 } 663 if (MP_MX_LT(A0, pred_flag_index_l1, mxA)) { 664 goto b_candidates; 665 } 666 } 667 668 if (is_available_a1) { 669 if (MP_MX_LT(A1, pred_flag_index_l0, mxA)) { 670 goto b_candidates; 671 } 672 if (MP_MX_LT(A1, pred_flag_index_l1, mxA)) { 673 goto b_candidates; 674 } 675 } 676 availableFlagLXA0 = 0; 677 678b_candidates: 679 // B candidates 680 // above right spatial merge candidate 681 xB0 = x0 + nPbW; 682 yB0 = y0 - 1; 683 684 is_available_b0 = AVAILABLE(cand_up_right, B0) && 685 xB0 < s->ps.sps->width && 686 PRED_BLOCK_AVAILABLE(B0); 687 688 // above spatial merge candidate 689 xB1 = x0 + nPbW - 1; 690 yB1 = y0 - 1; 691 is_available_b1 = AVAILABLE(cand_up, B1); 692 693 // above left spatial merge candidate 694 xB2 = x0 - 1; 695 yB2 = y0 - 1; 696 is_available_b2 = AVAILABLE(cand_up_left, B2); 697 698 // above right spatial merge candidate 699 if (is_available_b0) { 700 if (MP_MX(B0, pred_flag_index_l0, mxB)) { 701 goto scalef; 702 } 703 if (MP_MX(B0, pred_flag_index_l1, mxB)) { 704 goto scalef; 705 } 706 } 707 708 // above spatial merge candidate 709 if (is_available_b1) { 710 if (MP_MX(B1, pred_flag_index_l0, mxB)) { 711 goto scalef; 712 } 713 if (MP_MX(B1, pred_flag_index_l1, mxB)) { 714 goto scalef; 715 } 716 } 717 718 // above left spatial merge candidate 719 if (is_available_b2) { 720 if (MP_MX(B2, pred_flag_index_l0, mxB)) { 721 goto scalef; 722 } 723 if (MP_MX(B2, pred_flag_index_l1, mxB)) { 724 goto scalef; 725 } 726 } 727 availableFlagLXB0 = 0; 728 729scalef: 730 if (!isScaledFlag_L0) { 731 if (availableFlagLXB0) { 732 availableFlagLXA0 = 1; 733 mxA = mxB; 734 } 735 availableFlagLXB0 = 0; 736 737 // XB0 and L1 738 if (is_available_b0) { 739 availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l0, mxB); 740 if (!availableFlagLXB0) 741 availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l1, mxB); 742 } 743 744 if (is_available_b1 && !availableFlagLXB0) { 745 availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l0, mxB); 746 if (!availableFlagLXB0) 747 availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l1, mxB); 748 } 749 750 if (is_available_b2 && !availableFlagLXB0) { 751 availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l0, mxB); 752 if (!availableFlagLXB0) 753 availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l1, mxB); 754 } 755 } 756 757 if (availableFlagLXA0) 758 mvpcand_list[numMVPCandLX++] = mxA; 759 760 if (availableFlagLXB0 && (!availableFlagLXA0 || mxA.x != mxB.x || mxA.y != mxB.y)) 761 mvpcand_list[numMVPCandLX++] = mxB; 762 763 //temporal motion vector prediction candidate 764 if (numMVPCandLX < 2 && s->sh.slice_temporal_mvp_enabled_flag && 765 mvp_lx_flag == numMVPCandLX) { 766 Mv mv_col; 767 int available_col = temporal_luma_motion_vector(s, x0, y0, nPbW, 768 nPbH, ref_idx, 769 &mv_col, LX); 770 if (available_col) 771 mvpcand_list[numMVPCandLX++] = mv_col; 772 } 773 774 mv->mv[LX] = mvpcand_list[mvp_lx_flag]; 775} 776