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