~ppsspp/ppsspp/ffmpeg

« back to all changes in this revision

Viewing changes to libavcodec/hevc_mvs.c

  • Committer: Henrik Rydgård
  • Date: 2014-01-03 10:44:32 UTC
  • Revision ID: git-v1:87c6c126784b1718bfa448ecf2e6a9fef781eb4e
Update our ffmpeg snapshot to a clone of the official repository.

This is because Maxim's at3plus support has been officially merged!

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * HEVC video Decoder
 
2
 * HEVC video decoder
3
3
 *
4
4
 * Copyright (C) 2012 - 2013 Guillaume Martres
5
5
 * Copyright (C) 2013 Anand Meher Kotra
38
38
    { 3, 2, },
39
39
};
40
40
 
41
 
void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0, int nPbW, int nPbH)
 
41
void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0,
 
42
                                     int nPbW, int nPbH)
42
43
{
43
 
    HEVCLocalContext *lc = &s->HEVClc;
 
44
    HEVCLocalContext *lc = s->HEVClc;
44
45
    int x0b = x0 & ((1 << s->sps->log2_ctb_size) - 1);
45
46
    int y0b = y0 & ((1 << s->sps->log2_ctb_size) - 1);
46
47
 
65
66
{
66
67
#define MIN_TB_ADDR_ZS(x, y)                                            \
67
68
    s->pps->min_tb_addr_zs[(y) * s->sps->min_tb_width + (x)]
68
 
    int Curr =  MIN_TB_ADDR_ZS(xCurr >> s->sps->log2_min_transform_block_size,
69
 
                               yCurr >> s->sps->log2_min_transform_block_size);
 
69
    int Curr = MIN_TB_ADDR_ZS(xCurr >> s->sps->log2_min_tb_size,
 
70
                              yCurr >> s->sps->log2_min_tb_size);
70
71
    int N;
71
72
 
72
 
    if ((xN < 0) || (yN < 0) ||
73
 
        (xN >= s->sps->width) ||
74
 
        (yN >= s->sps->height))
 
73
    if (xN < 0 || yN < 0 ||
 
74
        xN >= s->sps->width ||
 
75
        yN >= s->sps->height)
75
76
        return 0;
76
77
 
77
 
    N = MIN_TB_ADDR_ZS(xN >> s->sps->log2_min_transform_block_size,
78
 
                       yN >> s->sps->log2_min_transform_block_size);
 
78
    N = MIN_TB_ADDR_ZS(xN >> s->sps->log2_min_tb_size,
 
79
                       yN >> s->sps->log2_min_tb_size);
79
80
 
80
81
    return N <= Curr;
81
82
}
82
83
 
83
 
 
84
84
static int same_prediction_block(HEVCLocalContext *lc, int log2_cb_size,
85
85
                                 int x0, int y0, int nPbW, int nPbH,
86
86
                                 int xA1, int yA1, int partIdx)
98
98
                                            int x0, int y0, int nPbW, int nPbH,
99
99
                                            int xA1, int yA1, int partIdx)
100
100
{
101
 
    HEVCLocalContext *lc = &s->HEVClc;
 
101
    HEVCLocalContext *lc = s->HEVClc;
102
102
 
103
103
    if (lc->cu.x < xA1 && lc->cu.y < yA1 &&
104
104
        (lc->cu.x + (1 << log2_cb_size)) > xA1 &&
169
169
    cur_poc_diff = poc    - refPicList[X].list[refIdxLx];
170
170
 
171
171
    if (!col_poc_diff)
172
 
        col_poc_diff = 1; // error resilience
 
172
        col_poc_diff = 1;  // error resilience
173
173
 
174
174
    if (cur_lt || col_poc_diff == cur_poc_diff) {
175
175
        mvLXCol->x = mvCol->x;
180
180
    return 1;
181
181
}
182
182
 
183
 
#define CHECK_MVSET(l) \
184
 
    check_mvset(mvLXCol, temp_col.mv + l, \
185
 
                colPic, s->poc, \
186
 
                refPicList, X, refIdxLx, \
187
 
                refPicList_col, L##l, temp_col.ref_idx[l])
 
183
#define CHECK_MVSET(l)                                          \
 
184
    check_mvset(mvLXCol, temp_col.mv + l,                       \
 
185
                colPic, s->poc,                                 \
 
186
                refPicList, X, refIdxLx,                        \
 
187
                refPicList_col, L ## l, temp_col.ref_idx[l])
188
188
 
189
189
// derive the motion vectors section 8.5.3.1.8
190
190
static int derive_temporal_colocated_mvs(HEVCContext *s, MvField temp_col,
191
 
                                         int refIdxLx, Mv* mvLXCol, int X,
192
 
                                         int colPic, RefPicList* refPicList_col)
 
191
                                         int refIdxLx, Mv *mvLXCol, int X,
 
192
                                         int colPic, RefPicList *refPicList_col)
193
193
{
194
194
    RefPicList *refPicList = s->ref->refPicList;
195
195
 
229
229
    return 0;
230
230
}
231
231
 
232
 
#define TAB_MVF(x, y) \
233
 
    tab_mvf[(y) * pic_width_in_min_pu + x]
234
 
 
235
 
#define TAB_MVF_PU(v) \
236
 
    TAB_MVF(x##v##_pu, y##v##_pu)
237
 
 
238
 
#define DERIVE_TEMPORAL_COLOCATED_MVS(v) \
239
 
    derive_temporal_colocated_mvs(s, temp_col, \
240
 
                                  refIdxLx, mvLXCol, X, colPic, \
241
 
                                  ff_hevc_get_ref_list(s, ref, \
242
 
                                                       x##v, y##v))
 
232
#define TAB_MVF(x, y)                                                   \
 
233
    tab_mvf[(y) * min_pu_width + x]
 
234
 
 
235
#define TAB_MVF_PU(v)                                                   \
 
236
    TAB_MVF(x ## v ## _pu, y ## v ## _pu)
 
237
 
 
238
#define DERIVE_TEMPORAL_COLOCATED_MVS                                   \
 
239
    derive_temporal_colocated_mvs(s, temp_col,                          \
 
240
                                  refIdxLx, mvLXCol, X, colPic,         \
 
241
                                  ff_hevc_get_ref_list(s, ref, x, y))
243
242
 
244
243
/*
245
244
 * 8.5.3.1.7  temporal luma motion vector prediction
246
245
 */
247
246
static int temporal_luma_motion_vector(HEVCContext *s, int x0, int y0,
248
247
                                       int nPbW, int nPbH, int refIdxLx,
249
 
                                       Mv* mvLXCol, int X)
 
248
                                       Mv *mvLXCol, int X)
250
249
{
251
250
    MvField *tab_mvf;
252
251
    MvField temp_col;
253
 
    int xPRb, yPRb;
254
 
    int xPRb_pu;
255
 
    int yPRb_pu;
256
 
    int xPCtr, yPCtr;
257
 
    int xPCtr_pu;
258
 
    int yPCtr_pu;
259
 
    int pic_width_in_min_pu = s->sps->width >> s->sps->log2_min_pu_size;
 
252
    int x, y, x_pu, y_pu;
 
253
    int min_pu_width = s->sps->min_pu_width;
260
254
    int availableFlagLXCol = 0;
261
255
    int colPic;
262
256
 
269
263
    colPic  = ref->poc;
270
264
 
271
265
    //bottom right collocated motion vector
272
 
    xPRb = x0 + nPbW;
273
 
    yPRb = y0 + nPbH;
 
266
    x = x0 + nPbW;
 
267
    y = y0 + nPbH;
274
268
 
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);
276
271
    if (tab_mvf &&
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);
286
 
    } else {
287
 
        mvLXCol->x = 0;
288
 
        mvLXCol->y = 0;
289
 
        availableFlagLXCol = 0;
 
272
        (y0 >> s->sps->log2_ctb_size) == (y >> s->sps->log2_ctb_size) &&
 
273
        y < s->sps->height &&
 
274
        x < s->sps->width) {
 
275
        x                  = ((x >> 4) << 4);
 
276
        y                  = ((y >> 4) << 4);
 
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;
290
281
    }
291
282
 
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);
 
287
        x                  = ((x >> 4) << 4);
 
288
        y                  = ((y >> 4) << 4);
 
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;
302
293
    }
303
294
    return availableFlagLXCol;
304
295
}
305
296
 
306
 
#define AVAILABLE(cand, v) \
 
297
#define AVAILABLE(cand, v)                                      \
307
298
    (cand && !TAB_MVF_PU(v).is_intra)
308
299
 
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)
313
304
 
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))
316
307
 
317
308
/*
318
309
 * 8.5.3.1.2  Derivation process for spatial merging candidates
319
310
 */
320
311
static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0,
321
 
                                            int nPbW, int nPbH, int log2_cb_size,
 
312
                                            int nPbW, int nPbH,
 
313
                                            int log2_cb_size,
322
314
                                            int singleMCLFlag, int part_idx,
323
315
                                            struct MvField mergecandlist[])
324
316
{
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;
328
 
 
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 };
339
 
 
340
 
    //first left spatial merge candidate
341
 
    int xA1 = x0 - 1;
342
 
    int yA1 = y0 + nPbH - 1;
343
 
    int is_available_a1;
344
 
    int pic_width_in_min_pu = s->sps->width >> s->sps->log2_min_pu_size;
345
 
 
346
 
    int check_MER = 1;
 
319
    MvField *tab_mvf       = s->ref->tab_mvf;
 
320
 
 
321
    const int min_pu_width = s->sps->min_pu_width;
 
322
 
 
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;
 
328
 
 
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;
 
333
 
 
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;
 
338
 
 
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;
 
343
 
 
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;
 
348
 
 
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;
 
353
 
 
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]);
 
356
    int check_MER   = 1;
347
357
    int check_MER_1 = 1;
348
358
 
349
 
    int xB1, yB1;
 
359
    int zero_idx = 0;
 
360
 
 
361
    int nb_merge_cand = 0;
 
362
    int nb_orig_merge_cand = 0;
 
363
 
 
364
    int is_available_a0;
 
365
    int is_available_a1;
 
366
    int is_available_b0;
350
367
    int is_available_b1;
351
 
    int xB1_pu;
352
 
    int yB1_pu;
353
 
 
 
368
    int is_available_b2;
354
369
    int check_B0;
355
 
    int xB0, yB0;
356
 
    int isAvailableB0;
357
 
    int xB0_pu;
358
 
    int yB0_pu;
359
 
 
360
370
    int check_A0;
361
 
    int xA0, yA0;
362
 
    int is_available_a0;
363
 
    int xA0_pu;
364
 
    int yA0_pu;
365
 
 
366
 
    int xB2, yB2;
367
 
    int isAvailableB2;
368
 
    int xB2_pu;
369
 
    int yB2_pu;
370
 
    int mergearray_index = 0;
371
 
 
372
 
    struct MvField zerovector;
373
 
    int numRefIdx = 0;
374
 
    int zeroIdx = 0;
375
 
 
376
 
    int numMergeCand = 0;
377
 
    int numOrigMergeCand = 0;
378
 
    int sumcandidates = 0;
379
 
    int combIdx = 0;
380
 
    int combStop = 0;
381
 
    int l0CandIdx = 0;
382
 
    int l1CandIdx = 0;
383
 
 
384
 
    int refIdxL0Col = 0;
385
 
    int refIdxL1Col = 0;
386
 
    int availableFlagLXCol = 0;
387
 
 
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;
393
 
 
394
 
 
395
 
    int xA1_pu = xA1 >> s->sps->log2_min_pu_size;
396
 
    int yA1_pu = yA1 >> s->sps->log2_min_pu_size;
397
 
 
398
 
    int availableFlagL0Col = 0;
399
 
    int availableFlagL1Col = 0;
400
 
 
 
371
 
 
372
    //first left spatial merge candidate
401
373
    is_available_a1 = AVAILABLE(cand_left, A1);
402
374
 
403
375
    if (!singleMCLFlag && part_idx == 1 &&
408
380
        is_available_a1 = 0;
409
381
    }
410
382
 
411
 
    if (is_available_a1) {
412
 
        available_a1_flag = 1;
413
 
        spatialCMVS[0] = TAB_MVF_PU(A1);
414
 
    } else {
415
 
        available_a1_flag = 0;
416
 
        spatialCMVS[0].ref_idx[0] = -1;
417
 
        spatialCMVS[0].ref_idx[1] = -1;
418
 
        spatialCMVS[0].mv[0].x = 0;
419
 
        spatialCMVS[0].mv[0].y = 0;
420
 
        spatialCMVS[0].mv[1].x = 0;
421
 
        spatialCMVS[0].mv[1].y = 0;
422
 
        spatialCMVS[0].pred_flag[0] = 0;
423
 
        spatialCMVS[0].pred_flag[1] = 0;
424
 
        spatialCMVS[0].is_intra = 0;
425
 
    }
 
383
    if (is_available_a1)
 
384
        mergecandlist[nb_merge_cand++] = TAB_MVF_PU(A1);
426
385
 
427
386
    // above spatial merge candidate
428
 
 
429
 
    xB1 = x0 + nPbW - 1;
430
 
    yB1 = y0 - 1;
431
 
    xB1_pu = xB1 >> s->sps->log2_min_pu_size;
432
 
    yB1_pu = yB1 >> s->sps->log2_min_pu_size;
433
 
 
434
387
    is_available_b1 = AVAILABLE(cand_up, B1);
435
388
 
436
389
    if (!singleMCLFlag && part_idx == 1 &&
444
397
    if (is_available_a1 && is_available_b1)
445
398
        check_MER = !COMPARE_MV_REFIDX(B1, A1);
446
399
 
447
 
    if (is_available_b1 && check_MER) {
448
 
        available_b1_flag = 1;
449
 
        spatialCMVS[1] = TAB_MVF_PU(B1);
450
 
    } else {
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;
461
 
    }
 
400
    if (is_available_b1 && check_MER)
 
401
        mergecandlist[nb_merge_cand++] = TAB_MVF_PU(B1);
462
402
 
463
403
    // above right spatial merge candidate
464
 
    xB0 = x0 + nPbW;
465
 
    yB0 = y0 - 1;
466
404
    check_MER = 1;
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);
470
406
 
471
 
    isAvailableB0 = check_B0 && AVAILABLE(cand_up_right, B0);
 
407
    is_available_b0 = check_B0 && AVAILABLE(cand_up_right, B0);
472
408
 
473
409
    if (isDiffMER(s, xB0, yB0, x0, y0))
474
 
        isAvailableB0 = 0;
 
410
        is_available_b0 = 0;
475
411
 
476
 
    if (is_available_b1 && isAvailableB0)
 
412
    if (is_available_b1 && is_available_b0)
477
413
        check_MER = !COMPARE_MV_REFIDX(B0, B1);
478
414
 
479
 
    if (isAvailableB0 && check_MER) {
480
 
        available_b0_flag = 1;
481
 
        spatialCMVS[2] = TAB_MVF_PU(B0);
482
 
    } else {
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;
493
 
    }
 
415
    if (is_available_b0 && check_MER)
 
416
        mergecandlist[nb_merge_cand++] = TAB_MVF_PU(B0);
494
417
 
495
418
    // left bottom spatial merge candidate
496
 
    xA0 = x0 - 1;
497
 
    yA0 = y0 + nPbH;
498
419
    check_MER = 1;
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);
502
421
 
503
422
    is_available_a0 = check_A0 && AVAILABLE(cand_bottom_left, A0);
504
423
 
508
427
    if (is_available_a1 && is_available_a0)
509
428
        check_MER = !COMPARE_MV_REFIDX(A0, A1);
510
429
 
511
 
    if (is_available_a0 && check_MER) {
512
 
        available_a0_flag = 1;
513
 
        spatialCMVS[3] = TAB_MVF_PU(A0);
514
 
    } else {
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;
525
 
    }
 
430
    if (is_available_a0 && check_MER)
 
431
        mergecandlist[nb_merge_cand++] = TAB_MVF_PU(A0);
526
432
 
527
433
    // above left spatial merge candidate
528
 
    xB2 = x0 - 1;
529
 
    yB2 = y0 - 1;
530
434
    check_MER = 1;
531
 
    xB2_pu = xB2 >> s->sps->log2_min_pu_size;
532
 
    yB2_pu = yB2 >> s->sps->log2_min_pu_size;
533
435
 
534
 
    isAvailableB2 = AVAILABLE(cand_up_left, B2);
 
436
    is_available_b2 = AVAILABLE(cand_up_left, B2);
535
437
 
536
438
    if (isDiffMER(s, xB2, yB2, x0, y0))
537
 
        isAvailableB2 = 0;
 
439
        is_available_b2 = 0;
538
440
 
539
 
    if (is_available_a1 && isAvailableB2)
 
441
    if (is_available_a1 && is_available_b2)
540
442
        check_MER = !COMPARE_MV_REFIDX(B2, A1);
541
443
 
542
 
    if (is_available_b1 && isAvailableB2)
 
444
    if (is_available_b1 && is_available_b2)
543
445
        check_MER_1 = !COMPARE_MV_REFIDX(B2, B1);
544
446
 
545
 
    sumcandidates = available_a1_flag + available_b1_flag + available_b0_flag
546
 
            + available_a0_flag;
547
 
 
548
 
    if (isAvailableB2 && check_MER && check_MER_1 && sumcandidates != 4) {
549
 
        available_b2_flag = 1;
550
 
        spatialCMVS[4] = TAB_MVF_PU(B2);
551
 
    } else {
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;
562
 
    }
 
447
    if (is_available_b2 && check_MER && check_MER_1 && nb_merge_cand != 4)
 
448
        mergecandlist[nb_merge_cand++] = TAB_MVF_PU(B2);
563
449
 
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;
569
 
    } else {
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);
576
 
        }
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;
585
 
            }
586
 
            if (TMVPCand.pred_flag[1]) {
587
 
                TMVPCand.mv[1] = mvL1Col;
588
 
                TMVPCand.ref_idx[1] = refIdxL1Col;
589
 
            }
590
 
        }
591
 
    }
592
 
 
593
 
    if (available_a1_flag) {
594
 
        mergecandlist[mergearray_index] = spatialCMVS[0];
595
 
        mergearray_index++;
596
 
    }
597
 
    if (available_b1_flag) {
598
 
        mergecandlist[mergearray_index] = spatialCMVS[1];
599
 
        mergearray_index++;
600
 
    }
601
 
    if (available_b0_flag) {
602
 
        mergecandlist[mergearray_index] = spatialCMVS[2];
603
 
        mergearray_index++;
604
 
    }
605
 
    if (available_a0_flag) {
606
 
        mergecandlist[mergearray_index] = spatialCMVS[3];
607
 
        mergearray_index++;
608
 
    }
609
 
    if (available_b2_flag) {
610
 
        mergecandlist[mergearray_index] = spatialCMVS[4];
611
 
        mergearray_index++;
612
 
    }
613
 
    if (availableFlagLXCol && mergearray_index < s->sh.max_num_merge_cand) {
614
 
        mergecandlist[mergearray_index] = TMVPCand;
615
 
        mergearray_index++;
616
 
    }
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,
 
455
                                                       0, &mv_l0_col, 0);
 
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;
 
459
 
 
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;
 
464
            if (available_l0) {
 
465
                mergecandlist[nb_merge_cand].mv[0]      = mv_l0_col;
 
466
                mergecandlist[nb_merge_cand].ref_idx[0] = 0;
 
467
            }
 
468
            if (available_l1) {
 
469
                mergecandlist[nb_merge_cand].mv[1]      = mv_l1_col;
 
470
                mergecandlist[nb_merge_cand].ref_idx[1] = 0;
 
471
            }
 
472
            nb_merge_cand++;
 
473
        }
 
474
    }
 
475
 
 
476
    nb_orig_merge_cand = nb_merge_cand;
619
477
 
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) {
624
 
 
625
 
            combIdx = 0;
626
 
            combStop = 0;
627
 
            while (combStop != 1) {
628
 
                MvField l0Cand;
629
 
                MvField l1Cand;
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;
650
 
                    numMergeCand++;
651
 
                }
652
 
                combIdx++;
653
 
                if (combIdx == numOrigMergeCand * (numOrigMergeCand - 1) ||
654
 
                    numMergeCand == s->sh.max_num_merge_cand)
655
 
                    combStop = 1;
 
479
    if (s->sh.slice_type == B_SLICE && nb_orig_merge_cand > 1 &&
 
480
        nb_orig_merge_cand < s->sh.max_num_merge_cand) {
 
481
        int comb_idx = 0;
 
482
 
 
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];
 
489
 
 
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;
 
504
                nb_merge_cand++;
656
505
            }
657
506
        }
658
507
    }
659
508
 
660
 
    /*
661
 
     * append Zero motion vector candidates
662
 
     */
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],
667
 
                          s->sh.nb_refs[1]);
668
 
    }
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;
680
 
        } else {
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;
690
 
        }
 
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;
691
520
 
692
 
        mergecandlist[numMergeCand] = zerovector;
693
 
        numMergeCand++;
694
 
        zeroIdx++;
 
521
        nb_merge_cand++;
 
522
        zero_idx++;
695
523
    }
696
524
}
697
525
 
707
535
    struct MvField mergecand_list[MRG_MAX_NUM_CANDS] = { { { { 0 } } } };
708
536
    int nPbW2 = nPbW;
709
537
    int nPbH2 = nPbH;
710
 
    HEVCLocalContext *lc = &s->HEVClc;
 
538
    HEVCLocalContext *lc = s->HEVClc;
711
539
 
712
540
    if (s->pps->log2_parallel_merge_level > 2 && nCS == 8) {
713
541
        singleMCLFlag = 1;
714
 
        x0 = lc->cu.x;
715
 
        y0 = lc->cu.y;
716
 
        nPbW = nCS;
717
 
        nPbH = nCS;
718
 
        part_idx = 0;
 
542
        x0            = lc->cu.x;
 
543
        y0            = lc->cu.y;
 
544
        nPbW          = nCS;
 
545
        nPbH          = nCS;
 
546
        part_idx      = 0;
719
547
    }
720
548
 
721
549
    ff_hevc_set_neighbour_available(s, x0, y0, nPbW, nPbH);
725
553
    if (mergecand_list[merge_idx].pred_flag[0] == 1 &&
726
554
        mergecand_list[merge_idx].pred_flag[1] == 1 &&
727
555
        (nPbW2 + nPbH2) == 12) {
728
 
        mergecand_list[merge_idx].ref_idx[1] = -1;
 
556
        mergecand_list[merge_idx].ref_idx[1]   = -1;
729
557
        mergecand_list[merge_idx].pred_flag[1] = 0;
730
558
    }
731
559
 
732
560
    *mv = mergecand_list[merge_idx];
733
561
}
734
562
 
735
 
static av_always_inline void dist_scale(HEVCContext *s, Mv * mv,
736
 
                                        int pic_width_in_min_pu, int x, int y,
 
563
static av_always_inline void dist_scale(HEVCContext *s, Mv *mv,
 
564
                                        int min_pu_width, int x, int y,
737
565
                                        int elist, int ref_idx_curr, int ref_idx)
738
566
{
739
567
    RefPicList *refPicList = s->ref->refPicList;
740
 
    MvField *tab_mvf = s->ref->tab_mvf;
741
 
    int ref_pic_elist = refPicList[elist].list[TAB_MVF(x, y).ref_idx[elist]];
742
 
    int ref_pic_curr  = refPicList[ref_idx_curr].list[ref_idx];
 
568
    MvField *tab_mvf       = s->ref->tab_mvf;
 
569
    int ref_pic_elist      = refPicList[elist].list[TAB_MVF(x, y).ref_idx[elist]];
 
570
    int ref_pic_curr       = refPicList[ref_idx_curr].list[ref_idx];
743
571
 
744
572
    if (ref_pic_elist != ref_pic_curr)
745
573
        mv_scale(mv, mv, s->poc - ref_pic_elist, s->poc - ref_pic_curr);
749
577
                         Mv *mv, int ref_idx_curr, int ref_idx)
750
578
{
751
579
    MvField *tab_mvf = s->ref->tab_mvf;
752
 
    int pic_width_in_min_pu = s->sps->width >> s->sps->log2_min_pu_size;
 
580
    int min_pu_width = s->sps->min_pu_width;
753
581
 
754
582
    RefPicList *refPicList = s->ref->refPicList;
755
583
 
761
589
    return 0;
762
590
}
763
591
 
764
 
 
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)
767
594
{
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;
770
597
 
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];
773
600
 
774
601
    int colIsLongTerm =
775
602
        refPicList[pred_flag_index].isLongTerm[(TAB_MVF(x, y).ref_idx[pred_flag_index])];
776
603
 
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);
781
610
        return 1;
782
611
    }
783
612
    return 0;
784
613
}
785
614
 
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)
788
618
 
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)
791
622
 
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)
796
627
{
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;
805
635
 
806
636
    int xA0, yA0;
807
637
    int xA0_pu, yA0_pu;
825
655
    Mv mvpcand_list[2] = { { 0 } };
826
656
    Mv mxA = { 0 };
827
657
    Mv mxB = { 0 };
828
 
    Mv mvLXCol = { 0 };
829
658
    int ref_idx_curr = 0;
830
659
    int ref_idx = 0;
831
660
    int pred_flag_index_l0;
857
686
    is_available_a0 = PRED_BLOCK_AVAILABLE(A0) && AVAILABLE(cand_bottom_left, A0);
858
687
 
859
688
    //left spatial merge candidate
860
 
    xA1 = x0 - 1;
861
 
    yA1 = y0 + nPbH - 1;
 
689
    xA1    = x0 - 1;
 
690
    yA1    = y0 + nPbH - 1;
862
691
    xA1_pu = xA1 >> s->sps->log2_min_pu_size;
863
692
    yA1_pu = yA1 >> s->sps->log2_min_pu_size;
864
693
 
865
694
    is_available_a1 = AVAILABLE(cand_left, A1);
866
 
    if (is_available_a0 || is_available_a1) {
 
695
    if (is_available_a0 || is_available_a1)
867
696
        isScaledFlag_L0 = 1;
868
 
    }
869
697
 
870
698
    if (is_available_a0) {
871
699
        availableFlagLXA0 = MP_MX(A0, pred_flag_index_l0, mxA);
893
721
 
894
722
    // B candidates
895
723
    // above right spatial merge candidate
896
 
    xB0 = x0 + nPbW;
897
 
    yB0 = y0 - 1;
 
724
    xB0    = x0 + nPbW;
 
725
    yB0    = y0 - 1;
898
726
    xB0_pu = xB0 >> s->sps->log2_min_pu_size;
899
727
    yB0_pu = yB0 >> s->sps->log2_min_pu_size;
900
728
 
908
736
 
909
737
    if (!availableFlagLXB0) {
910
738
        // above spatial merge candidate
911
 
        xB1 = x0 + nPbW - 1;
912
 
        yB1 = y0 - 1;
 
739
        xB1    = x0 + nPbW - 1;
 
740
        yB1    = y0 - 1;
913
741
        xB1_pu = xB1 >> s->sps->log2_min_pu_size;
914
742
        yB1_pu = yB1 >> s->sps->log2_min_pu_size;
915
743
 
964
792
        }
965
793
    }
966
794
 
967
 
    if (availableFlagLXA0 && availableFlagLXB0 &&
968
 
        (mxA.x != mxB.x || mxA.y != mxB.y)) {
969
 
        availableFlagLXCol = 0;
970
 
    } else {
971
 
        //temporal motion vector prediction candidate
972
 
        if (s->sh.slice_temporal_mvp_enabled_flag == 0) {
973
 
            availableFlagLXCol = 0;
974
 
        } else {
975
 
            availableFlagLXCol = temporal_luma_motion_vector(s, x0, y0, nPbW,
976
 
                    nPbH, ref_idx, &mvLXCol, LX);
977
 
        }
978
 
    }
979
 
 
980
 
    if (availableFlagLXA0) {
981
 
        mvpcand_list[numMVPCandLX] = mxA;
982
 
        numMVPCandLX++;
983
 
    }
984
 
    if (availableFlagLXB0) {
985
 
        mvpcand_list[numMVPCandLX] = mxB;
986
 
        numMVPCandLX++;
987
 
    }
988
 
 
989
 
    if (availableFlagLXA0 && availableFlagLXB0 &&
990
 
        mxA.x == mxB.x && mxA.y == mxB.y) {
991
 
        numMVPCandLX--;
992
 
    }
993
 
 
994
 
    if (availableFlagLXCol && numMVPCandLX < 2) {
995
 
        mvpcand_list[numMVPCandLX] = mvLXCol;
996
 
        numMVPCandLX++;
997
 
    }
998
 
 
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;
1002
 
        numMVPCandLX++;
1003
 
    }
 
795
    if (availableFlagLXA0)
 
796
        mvpcand_list[numMVPCandLX++] = mxA;
 
797
 
 
798
    if (availableFlagLXB0 && (!availableFlagLXA0 || mxA.x != mxB.x || mxA.y != mxB.y))
 
799
        mvpcand_list[numMVPCandLX++] = mxB;
 
800
 
 
801
    //temporal motion vector prediction candidate
 
802
    if (numMVPCandLX < 2 && s->sh.slice_temporal_mvp_enabled_flag) {
 
803
        Mv mv_col;
 
804
        int available_col = temporal_luma_motion_vector(s, x0, y0, nPbW,
 
805
                                                        nPbH, ref_idx,
 
806
                                                        &mv_col, LX);
 
807
        if (available_col)
 
808
            mvpcand_list[numMVPCandLX++] = mv_col;
 
809
    }
 
810
 
 
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 };
1004
814
 
1005
815
    mv->mv[LX].x = mvpcand_list[mvp_lx_flag].x;
1006
816
    mv->mv[LX].y = mvpcand_list[mvp_lx_flag].y;