269
263
colPic = ref->poc;
271
265
//bottom right collocated motion vector
275
ff_thread_await_progress(&ref->tf, INT_MAX, 0);
269
if (s->threads_type == FF_THREAD_FRAME )
270
ff_thread_await_progress(&ref->tf, y, 0);
277
y0 >> s->sps->log2_ctb_size == yPRb >> s->sps->log2_ctb_size &&
278
yPRb < s->sps->height &&
279
xPRb < s->sps->width) {
280
xPRb = ((xPRb >> 4) << 4);
281
yPRb = ((yPRb >> 4) << 4);
282
xPRb_pu = xPRb >> s->sps->log2_min_pu_size;
283
yPRb_pu = yPRb >> s->sps->log2_min_pu_size;
284
temp_col = TAB_MVF_PU(PRb);
285
availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS(PRb);
289
availableFlagLXCol = 0;
272
(y0 >> s->sps->log2_ctb_size) == (y >> s->sps->log2_ctb_size) &&
273
y < s->sps->height &&
277
x_pu = x >> s->sps->log2_min_pu_size;
278
y_pu = y >> s->sps->log2_min_pu_size;
279
temp_col = TAB_MVF(x_pu, y_pu);
280
availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS;
292
283
// derive center collocated motion vector
293
if (tab_mvf && availableFlagLXCol == 0) {
294
xPCtr = x0 + (nPbW >> 1);
295
yPCtr = y0 + (nPbH >> 1);
296
xPCtr = ((xPCtr >> 4) << 4);
297
yPCtr = ((yPCtr >> 4) << 4);
298
xPCtr_pu = xPCtr >> s->sps->log2_min_pu_size;
299
yPCtr_pu = yPCtr >> s->sps->log2_min_pu_size;
300
temp_col = TAB_MVF_PU(PCtr);
301
availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS(PCtr);
284
if (tab_mvf && !availableFlagLXCol) {
285
x = x0 + (nPbW >> 1);
286
y = y0 + (nPbH >> 1);
289
x_pu = x >> s->sps->log2_min_pu_size;
290
y_pu = y >> s->sps->log2_min_pu_size;
291
temp_col = TAB_MVF(x_pu, y_pu);
292
availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS;
303
294
return availableFlagLXCol;
306
#define AVAILABLE(cand, v) \
297
#define AVAILABLE(cand, v) \
307
298
(cand && !TAB_MVF_PU(v).is_intra)
309
#define PRED_BLOCK_AVAILABLE(v) \
310
check_prediction_block_available(s, log2_cb_size, \
311
x0, y0, nPbW, nPbH, \
312
x##v, y##v, part_idx)
300
#define PRED_BLOCK_AVAILABLE(v) \
301
check_prediction_block_available(s, log2_cb_size, \
302
x0, y0, nPbW, nPbH, \
303
x ## v, y ## v, part_idx)
314
#define COMPARE_MV_REFIDX(a, b) \
305
#define COMPARE_MV_REFIDX(a, b) \
315
306
compareMVrefidx(TAB_MVF_PU(a), TAB_MVF_PU(b))
318
309
* 8.5.3.1.2 Derivation process for spatial merging candidates
320
311
static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0,
321
int nPbW, int nPbH, int log2_cb_size,
322
314
int singleMCLFlag, int part_idx,
323
315
struct MvField mergecandlist[])
325
HEVCLocalContext *lc = &s->HEVClc;
317
HEVCLocalContext *lc = s->HEVClc;
326
318
RefPicList *refPicList = s->ref->refPicList;
327
MvField *tab_mvf = s->ref->tab_mvf;
329
int available_a1_flag = 0;
330
int available_b1_flag = 0;
331
int available_b0_flag = 0;
332
int available_a0_flag = 0;
333
int available_b2_flag = 0;
334
struct MvField spatialCMVS[MRG_MAX_NUM_CANDS];
335
struct MvField combCand = { { { 0 } } };
336
struct MvField TMVPCand = { { { 0 } } };
337
struct Mv mvL0Col = { 0 };
338
struct Mv mvL1Col = { 0 };
340
//first left spatial merge candidate
342
int yA1 = y0 + nPbH - 1;
344
int pic_width_in_min_pu = s->sps->width >> s->sps->log2_min_pu_size;
319
MvField *tab_mvf = s->ref->tab_mvf;
321
const int min_pu_width = s->sps->min_pu_width;
323
const int cand_bottom_left = lc->na.cand_bottom_left;
324
const int cand_left = lc->na.cand_left;
325
const int cand_up_left = lc->na.cand_up_left;
326
const int cand_up = lc->na.cand_up;
327
const int cand_up_right = lc->na.cand_up_right_sap;
329
const int xA1 = x0 - 1;
330
const int yA1 = y0 + nPbH - 1;
331
const int xA1_pu = xA1 >> s->sps->log2_min_pu_size;
332
const int yA1_pu = yA1 >> s->sps->log2_min_pu_size;
334
const int xB1 = x0 + nPbW - 1;
335
const int yB1 = y0 - 1;
336
const int xB1_pu = xB1 >> s->sps->log2_min_pu_size;
337
const int yB1_pu = yB1 >> s->sps->log2_min_pu_size;
339
const int xB0 = x0 + nPbW;
340
const int yB0 = y0 - 1;
341
const int xB0_pu = xB0 >> s->sps->log2_min_pu_size;
342
const int yB0_pu = yB0 >> s->sps->log2_min_pu_size;
344
const int xA0 = x0 - 1;
345
const int yA0 = y0 + nPbH;
346
const int xA0_pu = xA0 >> s->sps->log2_min_pu_size;
347
const int yA0_pu = yA0 >> s->sps->log2_min_pu_size;
349
const int xB2 = x0 - 1;
350
const int yB2 = y0 - 1;
351
const int xB2_pu = xB2 >> s->sps->log2_min_pu_size;
352
const int yB2_pu = yB2 >> s->sps->log2_min_pu_size;
354
const int nb_refs = (s->sh.slice_type == P_SLICE) ?
355
s->sh.nb_refs[0] : FFMIN(s->sh.nb_refs[0], s->sh.nb_refs[1]);
347
357
int check_MER_1 = 1;
361
int nb_merge_cand = 0;
362
int nb_orig_merge_cand = 0;
350
367
int is_available_b1;
370
int mergearray_index = 0;
372
struct MvField zerovector;
376
int numMergeCand = 0;
377
int numOrigMergeCand = 0;
378
int sumcandidates = 0;
386
int availableFlagLXCol = 0;
388
int cand_bottom_left = lc->na.cand_bottom_left;
389
int cand_left = lc->na.cand_left;
390
int cand_up_left = lc->na.cand_up_left;
391
int cand_up = lc->na.cand_up;
392
int cand_up_right = lc->na.cand_up_right_sap;
395
int xA1_pu = xA1 >> s->sps->log2_min_pu_size;
396
int yA1_pu = yA1 >> s->sps->log2_min_pu_size;
398
int availableFlagL0Col = 0;
399
int availableFlagL1Col = 0;
372
//first left spatial merge candidate
401
373
is_available_a1 = AVAILABLE(cand_left, A1);
403
375
if (!singleMCLFlag && part_idx == 1 &&
444
397
if (is_available_a1 && is_available_b1)
445
398
check_MER = !COMPARE_MV_REFIDX(B1, A1);
447
if (is_available_b1 && check_MER) {
448
available_b1_flag = 1;
449
spatialCMVS[1] = TAB_MVF_PU(B1);
451
available_b1_flag = 0;
452
spatialCMVS[1].ref_idx[0] = -1;
453
spatialCMVS[1].ref_idx[1] = -1;
454
spatialCMVS[1].mv[0].x = 0;
455
spatialCMVS[1].mv[0].y = 0;
456
spatialCMVS[1].mv[1].x = 0;
457
spatialCMVS[1].mv[1].y = 0;
458
spatialCMVS[1].pred_flag[0] = 0;
459
spatialCMVS[1].pred_flag[1] = 0;
460
spatialCMVS[1].is_intra = 0;
400
if (is_available_b1 && check_MER)
401
mergecandlist[nb_merge_cand++] = TAB_MVF_PU(B1);
463
403
// above right spatial merge candidate
467
xB0_pu = xB0 >> s->sps->log2_min_pu_size;
468
yB0_pu = yB0 >> s->sps->log2_min_pu_size;
469
check_B0 = PRED_BLOCK_AVAILABLE(B0);
405
check_B0 = PRED_BLOCK_AVAILABLE(B0);
471
isAvailableB0 = check_B0 && AVAILABLE(cand_up_right, B0);
407
is_available_b0 = check_B0 && AVAILABLE(cand_up_right, B0);
473
409
if (isDiffMER(s, xB0, yB0, x0, y0))
476
if (is_available_b1 && isAvailableB0)
412
if (is_available_b1 && is_available_b0)
477
413
check_MER = !COMPARE_MV_REFIDX(B0, B1);
479
if (isAvailableB0 && check_MER) {
480
available_b0_flag = 1;
481
spatialCMVS[2] = TAB_MVF_PU(B0);
483
available_b0_flag = 0;
484
spatialCMVS[2].ref_idx[0] = -1;
485
spatialCMVS[2].ref_idx[1] = -1;
486
spatialCMVS[2].mv[0].x = 0;
487
spatialCMVS[2].mv[0].y = 0;
488
spatialCMVS[2].mv[1].x = 0;
489
spatialCMVS[2].mv[1].y = 0;
490
spatialCMVS[2].pred_flag[0] = 0;
491
spatialCMVS[2].pred_flag[1] = 0;
492
spatialCMVS[2].is_intra = 0;
415
if (is_available_b0 && check_MER)
416
mergecandlist[nb_merge_cand++] = TAB_MVF_PU(B0);
495
418
// left bottom spatial merge candidate
499
xA0_pu = xA0 >> s->sps->log2_min_pu_size;
500
yA0_pu = yA0 >> s->sps->log2_min_pu_size;
501
check_A0 = PRED_BLOCK_AVAILABLE(A0);
420
check_A0 = PRED_BLOCK_AVAILABLE(A0);
503
422
is_available_a0 = check_A0 && AVAILABLE(cand_bottom_left, A0);
508
427
if (is_available_a1 && is_available_a0)
509
428
check_MER = !COMPARE_MV_REFIDX(A0, A1);
511
if (is_available_a0 && check_MER) {
512
available_a0_flag = 1;
513
spatialCMVS[3] = TAB_MVF_PU(A0);
515
available_a0_flag = 0;
516
spatialCMVS[3].ref_idx[0] = -1;
517
spatialCMVS[3].ref_idx[1] = -1;
518
spatialCMVS[3].mv[0].x = 0;
519
spatialCMVS[3].mv[0].y = 0;
520
spatialCMVS[3].mv[1].x = 0;
521
spatialCMVS[3].mv[1].y = 0;
522
spatialCMVS[3].pred_flag[0] = 0;
523
spatialCMVS[3].pred_flag[1] = 0;
524
spatialCMVS[3].is_intra = 0;
430
if (is_available_a0 && check_MER)
431
mergecandlist[nb_merge_cand++] = TAB_MVF_PU(A0);
527
433
// above left spatial merge candidate
531
xB2_pu = xB2 >> s->sps->log2_min_pu_size;
532
yB2_pu = yB2 >> s->sps->log2_min_pu_size;
534
isAvailableB2 = AVAILABLE(cand_up_left, B2);
436
is_available_b2 = AVAILABLE(cand_up_left, B2);
536
438
if (isDiffMER(s, xB2, yB2, x0, y0))
539
if (is_available_a1 && isAvailableB2)
441
if (is_available_a1 && is_available_b2)
540
442
check_MER = !COMPARE_MV_REFIDX(B2, A1);
542
if (is_available_b1 && isAvailableB2)
444
if (is_available_b1 && is_available_b2)
543
445
check_MER_1 = !COMPARE_MV_REFIDX(B2, B1);
545
sumcandidates = available_a1_flag + available_b1_flag + available_b0_flag
548
if (isAvailableB2 && check_MER && check_MER_1 && sumcandidates != 4) {
549
available_b2_flag = 1;
550
spatialCMVS[4] = TAB_MVF_PU(B2);
552
available_b2_flag = 0;
553
spatialCMVS[4].ref_idx[0] = -1;
554
spatialCMVS[4].ref_idx[1] = -1;
555
spatialCMVS[4].mv[0].x = 0;
556
spatialCMVS[4].mv[0].y = 0;
557
spatialCMVS[4].mv[1].x = 0;
558
spatialCMVS[4].mv[1].y = 0;
559
spatialCMVS[4].pred_flag[0] = 0;
560
spatialCMVS[4].pred_flag[1] = 0;
561
spatialCMVS[4].is_intra = 0;
447
if (is_available_b2 && check_MER && check_MER_1 && nb_merge_cand != 4)
448
mergecandlist[nb_merge_cand++] = TAB_MVF_PU(B2);
564
450
// temporal motion vector candidate
565
// one optimization is that do temporal checking only if the number of
566
// available candidates < MRG_MAX_NUM_CANDS
567
if (s->sh.slice_temporal_mvp_enabled_flag == 0) {
568
availableFlagLXCol = 0;
570
availableFlagL0Col = temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH,
571
refIdxL0Col, &mvL0Col, 0);
572
// one optimization is that l1 check can be done only when the current slice type is B_SLICE
573
if (s->sh.slice_type == B_SLICE) {
574
availableFlagL1Col = temporal_luma_motion_vector(s, x0, y0, nPbW,
575
nPbH, refIdxL1Col, &mvL1Col, 1);
577
availableFlagLXCol = availableFlagL0Col || availableFlagL1Col;
578
if (availableFlagLXCol) {
579
TMVPCand.is_intra = 0;
580
TMVPCand.pred_flag[0] = availableFlagL0Col;
581
TMVPCand.pred_flag[1] = availableFlagL1Col;
582
if (TMVPCand.pred_flag[0]) {
583
TMVPCand.mv[0] = mvL0Col;
584
TMVPCand.ref_idx[0] = refIdxL0Col;
586
if (TMVPCand.pred_flag[1]) {
587
TMVPCand.mv[1] = mvL1Col;
588
TMVPCand.ref_idx[1] = refIdxL1Col;
593
if (available_a1_flag) {
594
mergecandlist[mergearray_index] = spatialCMVS[0];
597
if (available_b1_flag) {
598
mergecandlist[mergearray_index] = spatialCMVS[1];
601
if (available_b0_flag) {
602
mergecandlist[mergearray_index] = spatialCMVS[2];
605
if (available_a0_flag) {
606
mergecandlist[mergearray_index] = spatialCMVS[3];
609
if (available_b2_flag) {
610
mergecandlist[mergearray_index] = spatialCMVS[4];
613
if (availableFlagLXCol && mergearray_index < s->sh.max_num_merge_cand) {
614
mergecandlist[mergearray_index] = TMVPCand;
617
numMergeCand = mergearray_index;
618
numOrigMergeCand = mergearray_index;
451
if (s->sh.slice_temporal_mvp_enabled_flag &&
452
nb_merge_cand < s->sh.max_num_merge_cand) {
453
Mv mv_l0_col, mv_l1_col;
454
int available_l0 = temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH,
456
int available_l1 = (s->sh.slice_type == B_SLICE) ?
457
temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH,
458
0, &mv_l1_col, 1) : 0;
460
if (available_l0 || available_l1) {
461
mergecandlist[nb_merge_cand].is_intra = 0;
462
mergecandlist[nb_merge_cand].pred_flag[0] = available_l0;
463
mergecandlist[nb_merge_cand].pred_flag[1] = available_l1;
465
mergecandlist[nb_merge_cand].mv[0] = mv_l0_col;
466
mergecandlist[nb_merge_cand].ref_idx[0] = 0;
469
mergecandlist[nb_merge_cand].mv[1] = mv_l1_col;
470
mergecandlist[nb_merge_cand].ref_idx[1] = 0;
476
nb_orig_merge_cand = nb_merge_cand;
620
478
// combined bi-predictive merge candidates (applies for B slices)
621
if (s->sh.slice_type == B_SLICE) {
622
if (numOrigMergeCand > 1 &&
623
numOrigMergeCand < s->sh.max_num_merge_cand) {
627
while (combStop != 1) {
630
l0CandIdx = l0_l1_cand_idx[combIdx][0];
631
l1CandIdx = l0_l1_cand_idx[combIdx][1];
632
l0Cand = mergecandlist[l0CandIdx];
633
l1Cand = mergecandlist[l1CandIdx];
634
if (l0Cand.pred_flag[0] == 1 &&
635
l1Cand.pred_flag[1] == 1 &&
636
(refPicList[0].list[l0Cand.ref_idx[0]] !=
637
refPicList[1].list[l1Cand.ref_idx[1]] ||
638
l0Cand.mv[0].x != l1Cand.mv[1].x ||
639
l0Cand.mv[0].y != l1Cand.mv[1].y)) {
640
combCand.ref_idx[0] = l0Cand.ref_idx[0];
641
combCand.ref_idx[1] = l1Cand.ref_idx[1];
642
combCand.pred_flag[0] = 1;
643
combCand.pred_flag[1] = 1;
644
combCand.mv[0].x = l0Cand.mv[0].x;
645
combCand.mv[0].y = l0Cand.mv[0].y;
646
combCand.mv[1].x = l1Cand.mv[1].x;
647
combCand.mv[1].y = l1Cand.mv[1].y;
648
combCand.is_intra = 0;
649
mergecandlist[numMergeCand] = combCand;
653
if (combIdx == numOrigMergeCand * (numOrigMergeCand - 1) ||
654
numMergeCand == s->sh.max_num_merge_cand)
479
if (s->sh.slice_type == B_SLICE && nb_orig_merge_cand > 1 &&
480
nb_orig_merge_cand < s->sh.max_num_merge_cand) {
483
for (comb_idx = 0; nb_merge_cand < s->sh.max_num_merge_cand &&
484
comb_idx < nb_orig_merge_cand * (nb_orig_merge_cand - 1); comb_idx++) {
485
int l0_cand_idx = l0_l1_cand_idx[comb_idx][0];
486
int l1_cand_idx = l0_l1_cand_idx[comb_idx][1];
487
MvField l0_cand = mergecandlist[l0_cand_idx];
488
MvField l1_cand = mergecandlist[l1_cand_idx];
490
if (l0_cand.pred_flag[0] && l1_cand.pred_flag[1] &&
491
(refPicList[0].list[l0_cand.ref_idx[0]] !=
492
refPicList[1].list[l1_cand.ref_idx[1]] ||
493
l0_cand.mv[0].x != l1_cand.mv[1].x ||
494
l0_cand.mv[0].y != l1_cand.mv[1].y)) {
495
mergecandlist[nb_merge_cand].ref_idx[0] = l0_cand.ref_idx[0];
496
mergecandlist[nb_merge_cand].ref_idx[1] = l1_cand.ref_idx[1];
497
mergecandlist[nb_merge_cand].pred_flag[0] = 1;
498
mergecandlist[nb_merge_cand].pred_flag[1] = 1;
499
mergecandlist[nb_merge_cand].mv[0].x = l0_cand.mv[0].x;
500
mergecandlist[nb_merge_cand].mv[0].y = l0_cand.mv[0].y;
501
mergecandlist[nb_merge_cand].mv[1].x = l1_cand.mv[1].x;
502
mergecandlist[nb_merge_cand].mv[1].y = l1_cand.mv[1].y;
503
mergecandlist[nb_merge_cand].is_intra = 0;
661
* append Zero motion vector candidates
663
if (s->sh.slice_type == P_SLICE) {
664
numRefIdx = s->sh.nb_refs[0];
665
} else if (s->sh.slice_type == B_SLICE) {
666
numRefIdx = FFMIN(s->sh.nb_refs[0],
669
while (numMergeCand < s->sh.max_num_merge_cand) {
670
if (s->sh.slice_type == P_SLICE) {
671
zerovector.ref_idx[0] = (zeroIdx < numRefIdx) ? zeroIdx : 0;
672
zerovector.ref_idx[1] = -1;
673
zerovector.pred_flag[0] = 1;
674
zerovector.pred_flag[1] = 0;
675
zerovector.mv[0].x = 0;
676
zerovector.mv[0].y = 0;
677
zerovector.mv[1].x = 0;
678
zerovector.mv[1].y = 0;
679
zerovector.is_intra = 0;
681
zerovector.ref_idx[0] = (zeroIdx < numRefIdx) ? zeroIdx : 0;
682
zerovector.ref_idx[1] = (zeroIdx < numRefIdx) ? zeroIdx : 0;
683
zerovector.pred_flag[0] = 1;
684
zerovector.pred_flag[1] = 1;
685
zerovector.mv[0].x = 0;
686
zerovector.mv[0].y = 0;
687
zerovector.mv[1].x = 0;
688
zerovector.mv[1].y = 0;
689
zerovector.is_intra = 0;
509
// append Zero motion vector candidates
510
while (nb_merge_cand < s->sh.max_num_merge_cand) {
511
mergecandlist[nb_merge_cand].pred_flag[0] = 1;
512
mergecandlist[nb_merge_cand].pred_flag[1] = s->sh.slice_type == B_SLICE;
513
mergecandlist[nb_merge_cand].mv[0].x = 0;
514
mergecandlist[nb_merge_cand].mv[0].y = 0;
515
mergecandlist[nb_merge_cand].mv[1].x = 0;
516
mergecandlist[nb_merge_cand].mv[1].y = 0;
517
mergecandlist[nb_merge_cand].is_intra = 0;
518
mergecandlist[nb_merge_cand].ref_idx[0] = zero_idx < nb_refs ? zero_idx : 0;
519
mergecandlist[nb_merge_cand].ref_idx[1] = zero_idx < nb_refs ? zero_idx : 0;
692
mergecandlist[numMergeCand] = zerovector;
765
592
static int mv_mp_mode_mx_lt(HEVCContext *s, int x, int y, int pred_flag_index,
766
593
Mv *mv, int ref_idx_curr, int ref_idx)
768
595
MvField *tab_mvf = s->ref->tab_mvf;
769
int pic_width_in_min_pu = s->sps->width >> s->sps->log2_min_pu_size;
596
int min_pu_width = s->sps->min_pu_width;
771
598
RefPicList *refPicList = s->ref->refPicList;
772
int currIsLongTerm = refPicList[ref_idx_curr].isLongTerm[ref_idx];
599
int currIsLongTerm = refPicList[ref_idx_curr].isLongTerm[ref_idx];
774
601
int colIsLongTerm =
775
602
refPicList[pred_flag_index].isLongTerm[(TAB_MVF(x, y).ref_idx[pred_flag_index])];
777
if (TAB_MVF(x, y).pred_flag[pred_flag_index] && colIsLongTerm == currIsLongTerm) {
604
if (TAB_MVF(x, y).pred_flag[pred_flag_index] &&
605
colIsLongTerm == currIsLongTerm) {
778
606
*mv = TAB_MVF(x, y).mv[pred_flag_index];
779
607
if (!currIsLongTerm)
780
dist_scale(s, mv, pic_width_in_min_pu, x, y, pred_flag_index, ref_idx_curr, ref_idx);
608
dist_scale(s, mv, min_pu_width, x, y,
609
pred_flag_index, ref_idx_curr, ref_idx);
786
#define MP_MX(v, pred, mx) \
787
mv_mp_mode_mx(s, x##v##_pu, y##v##_pu, pred, &mx, ref_idx_curr, ref_idx)
615
#define MP_MX(v, pred, mx) \
616
mv_mp_mode_mx(s, x ## v ## _pu, y ## v ## _pu, pred, \
617
&mx, ref_idx_curr, ref_idx)
789
#define MP_MX_LT(v, pred, mx) \
790
mv_mp_mode_mx_lt(s, x##v##_pu, y##v##_pu, pred, &mx, ref_idx_curr, ref_idx)
619
#define MP_MX_LT(v, pred, mx) \
620
mv_mp_mode_mx_lt(s, x ## v ## _pu, y ## v ## _pu, pred, \
621
&mx, ref_idx_curr, ref_idx)
792
623
void ff_hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0, int nPbW,
793
624
int nPbH, int log2_cb_size, int part_idx,
794
625
int merge_idx, MvField *mv,
795
626
int mvp_lx_flag, int LX)
797
HEVCLocalContext *lc = &s->HEVClc;
628
HEVCLocalContext *lc = s->HEVClc;
798
629
MvField *tab_mvf = s->ref->tab_mvf;
799
630
int isScaledFlag_L0 = 0;
800
631
int availableFlagLXA0 = 0;
801
632
int availableFlagLXB0 = 0;
802
int availableFlagLXCol = 0;
803
633
int numMVPCandLX = 0;
804
int pic_width_in_min_pu = s->sps->width >> s->sps->log2_min_pu_size;
634
int min_pu_width = s->sps->min_pu_width;
807
637
int xA0_pu, yA0_pu;
967
if (availableFlagLXA0 && availableFlagLXB0 &&
968
(mxA.x != mxB.x || mxA.y != mxB.y)) {
969
availableFlagLXCol = 0;
971
//temporal motion vector prediction candidate
972
if (s->sh.slice_temporal_mvp_enabled_flag == 0) {
973
availableFlagLXCol = 0;
975
availableFlagLXCol = temporal_luma_motion_vector(s, x0, y0, nPbW,
976
nPbH, ref_idx, &mvLXCol, LX);
980
if (availableFlagLXA0) {
981
mvpcand_list[numMVPCandLX] = mxA;
984
if (availableFlagLXB0) {
985
mvpcand_list[numMVPCandLX] = mxB;
989
if (availableFlagLXA0 && availableFlagLXB0 &&
990
mxA.x == mxB.x && mxA.y == mxB.y) {
994
if (availableFlagLXCol && numMVPCandLX < 2) {
995
mvpcand_list[numMVPCandLX] = mvLXCol;
999
while (numMVPCandLX < 2) { // insert zero motion vectors when the number of available candidates are less than 2
1000
mvpcand_list[numMVPCandLX].x = 0;
1001
mvpcand_list[numMVPCandLX].y = 0;
795
if (availableFlagLXA0)
796
mvpcand_list[numMVPCandLX++] = mxA;
798
if (availableFlagLXB0 && (!availableFlagLXA0 || mxA.x != mxB.x || mxA.y != mxB.y))
799
mvpcand_list[numMVPCandLX++] = mxB;
801
//temporal motion vector prediction candidate
802
if (numMVPCandLX < 2 && s->sh.slice_temporal_mvp_enabled_flag) {
804
int available_col = temporal_luma_motion_vector(s, x0, y0, nPbW,
808
mvpcand_list[numMVPCandLX++] = mv_col;
811
// insert zero motion vectors when the number of available candidates are less than 2
812
while (numMVPCandLX < 2)
813
mvpcand_list[numMVPCandLX++] = (Mv){ 0, 0 };
1005
815
mv->mv[LX].x = mvpcand_list[mvp_lx_flag].x;
1006
816
mv->mv[LX].y = mvpcand_list[mvp_lx_flag].y;