Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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