Coverage Report

Created: 2026-05-23 07:06

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