Coverage Report

Created: 2026-10-28 08:13

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 "libavcodec/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
275M
{
46
275M
    int x0b = av_zero_extend(x0, log2_ctb_size);
47
275M
    int y0b = av_zero_extend(y0, log2_ctb_size);
48
49
275M
    lc->na.cand_up       = (lc->ctb_up_flag   || y0b);
50
275M
    lc->na.cand_left     = (lc->ctb_left_flag || x0b);
51
275M
    lc->na.cand_up_left  = (x0b || y0b) ? lc->na.cand_left && lc->na.cand_up : lc->ctb_up_left_flag;
52
275M
    lc->na.cand_up_right_sap =
53
275M
            (x0b + nPbW == 1 << log2_ctb_size) ?
54
233M
                    lc->ctb_up_right_flag && !y0b : lc->na.cand_up;
55
275M
    lc->na.cand_up_right =
56
275M
            lc->na.cand_up_right_sap
57
238M
                     && (x0 + nPbW) < lc->end_of_tiles_x;
58
275M
    lc->na.cand_bottom_left = ((y0 + nPbH) >= lc->end_of_tiles_y) ? 0 : lc->na.cand_left;
59
275M
}
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
3.49M
{
68
3.49M
#define MIN_TB_ADDR_ZS(x, y)                                            \
69
5.42M
    pps->min_tb_addr_zs[(y) * (sps->tb_mask+2) + (x)]
70
71
3.49M
    int xCurr_ctb = xCurr >> sps->log2_ctb_size;
72
3.49M
    int yCurr_ctb = yCurr >> sps->log2_ctb_size;
73
3.49M
    int xN_ctb    = xN    >> sps->log2_ctb_size;
74
3.49M
    int yN_ctb    = yN    >> sps->log2_ctb_size;
75
3.49M
    if( yN_ctb < yCurr_ctb || xN_ctb < xCurr_ctb )
76
780k
        return 1;
77
2.71M
    else {
78
2.71M
        int Curr = MIN_TB_ADDR_ZS((xCurr >> sps->log2_min_tb_size) & sps->tb_mask,
79
2.71M
                (yCurr >> sps->log2_min_tb_size) & sps->tb_mask);
80
2.71M
        int N    = MIN_TB_ADDR_ZS((xN >> sps->log2_min_tb_size) & sps->tb_mask,
81
2.71M
                (yN >> sps->log2_min_tb_size) & sps->tb_mask);
82
2.71M
        return N <= Curr;
83
2.71M
    }
84
3.49M
}
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
11.0M
{
89
11.0M
    uint8_t plevel = pps->log2_parallel_merge_level;
90
91
11.0M
    return xN >> plevel == xP >> plevel &&
92
5.39M
           yN >> plevel == yP >> plevel;
93
11.0M
}
94
95
2.86M
#define MATCH_MV(x) (AV_RN32A(&A.x) == AV_RN32A(&B.x))
96
4.43M
#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.78M
{
101
1.78M
    int a_pf = A.pred_flag;
102
1.78M
    int b_pf = B.pred_flag;
103
1.78M
    if (a_pf == b_pf) {
104
1.47M
        if (a_pf == PF_BI) {
105
843k
            return MATCH(ref_idx[0]) && MATCH_MV(mv[0]) &&
106
653k
                   MATCH(ref_idx[1]) && MATCH_MV(mv[1]);
107
843k
        } else if (a_pf == PF_L0) {
108
596k
            return MATCH(ref_idx[0]) && MATCH_MV(mv[0]);
109
596k
        } else if (a_pf == PF_L1) {
110
29.9k
            return MATCH(ref_idx[1]) && MATCH_MV(mv[1]);
111
29.9k
        }
112
1.47M
    }
113
316k
    return 0;
114
1.78M
}
115
116
static av_always_inline void mv_scale(Mv *dst, const Mv *src, int td, int tb)
117
214k
{
118
214k
    int tx, scale_factor;
119
120
214k
    td = av_clip_int8(td);
121
214k
    tb = av_clip_int8(tb);
122
214k
    tx = (0x4000 + abs(td / 2)) / td;
123
214k
    scale_factor = av_clip_intp2((tb * tx + 32) >> 6, 12);
124
214k
    dst->x = av_clip_int16((scale_factor * src->x + 127 +
125
214k
                           (scale_factor * src->x < 0)) >> 8);
126
214k
    dst->y = av_clip_int16((scale_factor * src->y + 127 +
127
214k
                           (scale_factor * src->y < 0)) >> 8);
128
214k
}
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
1.61M
{
135
1.61M
    int cur_lt = refPicList[X].isLongTerm[refIdxLx];
136
1.61M
    int col_lt = refPicList_col[listCol].isLongTerm[refidxCol];
137
1.61M
    int col_poc_diff, cur_poc_diff;
138
139
1.61M
    if (cur_lt != col_lt) {
140
11.0k
        mvLXCol->x = 0;
141
11.0k
        mvLXCol->y = 0;
142
11.0k
        return 0;
143
11.0k
    }
144
145
1.60M
    col_poc_diff = colPic - refPicList_col[listCol].list[refidxCol];
146
1.60M
    cur_poc_diff = poc    - refPicList[X].list[refIdxLx];
147
148
1.60M
    if (cur_lt || col_poc_diff == cur_poc_diff || !col_poc_diff) {
149
1.45M
        mvLXCol->x = mvCol->x;
150
1.45M
        mvLXCol->y = mvCol->y;
151
1.45M
    } else {
152
146k
        mv_scale(mvLXCol, mvCol, col_poc_diff, cur_poc_diff);
153
146k
    }
154
1.60M
    return 1;
155
1.61M
}
156
157
#define CHECK_MVSET(l)                                          \
158
1.61M
    check_mvset(mvLXCol, temp_col.mv + l,                       \
159
1.61M
                colPic, s->poc,                                 \
160
1.61M
                refPicList, X, refIdxLx,                        \
161
1.61M
                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
3.07M
{
168
3.07M
    const RefPicList *refPicList = s->cur_frame->refPicList;
169
170
3.07M
    if (temp_col.pred_flag == PF_INTRA)
171
1.46M
        return 0;
172
173
1.61M
    if (!(temp_col.pred_flag & PF_L0))
174
42.5k
        return CHECK_MVSET(1);
175
1.56M
    else if (temp_col.pred_flag == PF_L0)
176
633k
        return CHECK_MVSET(0);
177
936k
    else if (temp_col.pred_flag == PF_BI) {
178
936k
        int check_diffpicount = 0;
179
936k
        int i, j;
180
2.80M
        for (j = 0; j < 2; j++) {
181
3.91M
            for (i = 0; i < refPicList[j].nb_refs; i++) {
182
2.13M
                if (refPicList[j].list[i] > s->poc) {
183
95.7k
                    check_diffpicount++;
184
95.7k
                    break;
185
95.7k
                }
186
2.13M
            }
187
1.87M
        }
188
936k
        if (!check_diffpicount) {
189
882k
            if (X==0)
190
443k
                return CHECK_MVSET(0);
191
438k
            else
192
438k
                return CHECK_MVSET(1);
193
882k
        } else {
194
54.0k
            if (s->sh.collocated_list == L1)
195
46.9k
                return CHECK_MVSET(0);
196
7.18k
            else
197
7.18k
                return CHECK_MVSET(1);
198
54.0k
        }
199
936k
    }
200
201
0
    return 0;
202
1.61M
}
203
204
#define TAB_MVF(x, y)                                                   \
205
39.1M
    tab_mvf[(y) * min_pu_width + x]
206
207
#define TAB_MVF_PU(v)                                                   \
208
25.9M
    TAB_MVF(((x ## v) >> sps->log2_min_pu_size),                        \
209
25.9M
            ((y ## v) >> sps->log2_min_pu_size))
210
211
#define DERIVE_TEMPORAL_COLOCATED_MVS                                   \
212
3.07M
    derive_temporal_colocated_mvs(s, temp_col,                          \
213
3.07M
                                  refIdxLx, mvLXCol, X, colPic,         \
214
3.07M
                                  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
2.14M
{
224
2.14M
    const MvField *tab_mvf;
225
2.14M
    MvField temp_col;
226
2.14M
    int x, y, x_pu, y_pu;
227
2.14M
    int min_pu_width = sps->min_pu_width;
228
2.14M
    int availableFlagLXCol = 0;
229
2.14M
    int colPic;
230
231
2.14M
    const HEVCFrame *ref = s->collocated_ref;
232
233
2.14M
    if (!ref) {
234
0
        memset(mvLXCol, 0, sizeof(*mvLXCol));
235
0
        return 0;
236
0
    }
237
238
2.14M
    tab_mvf = ref->tab_mvf;
239
2.14M
    colPic  = ref->poc;
240
241
    //bottom right collocated motion vector
242
2.14M
    x = x0 + nPbW;
243
2.14M
    y = y0 + nPbH;
244
245
2.14M
    if (tab_mvf &&
246
2.14M
        (y0 >> sps->log2_ctb_size) == (y >> sps->log2_ctb_size) &&
247
1.81M
        y < sps->height &&
248
1.65M
        x < sps->width) {
249
1.61M
        x                 &= ~15;
250
1.61M
        y                 &= ~15;
251
1.61M
        if (s->avctx->active_thread_type == FF_THREAD_FRAME)
252
0
            ff_progress_frame_await(&ref->tf, y);
253
1.61M
        x_pu               = x >> sps->log2_min_pu_size;
254
1.61M
        y_pu               = y >> sps->log2_min_pu_size;
255
1.61M
        temp_col           = TAB_MVF(x_pu, y_pu);
256
1.61M
        availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS;
257
1.61M
    }
258
259
    // derive center collocated motion vector
260
2.14M
    if (tab_mvf && !availableFlagLXCol) {
261
1.46M
        x                  = x0 + (nPbW >> 1);
262
1.46M
        y                  = y0 + (nPbH >> 1);
263
1.46M
        x                 &= ~15;
264
1.46M
        y                 &= ~15;
265
1.46M
        if (s->avctx->active_thread_type == FF_THREAD_FRAME)
266
0
            ff_progress_frame_await(&ref->tf, y);
267
1.46M
        x_pu               = x >> sps->log2_min_pu_size;
268
1.46M
        y_pu               = y >> sps->log2_min_pu_size;
269
1.46M
        temp_col           = TAB_MVF(x_pu, y_pu);
270
1.46M
        availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS;
271
1.46M
    }
272
2.14M
    return availableFlagLXCol;
273
2.14M
}
274
275
#define AVAILABLE(cand, v)                                      \
276
27.6M
    (cand && !(TAB_MVF_PU(v).pred_flag == PF_INTRA))
277
278
#define PRED_BLOCK_AVAILABLE(v)                                 \
279
10.4M
    z_scan_block_avail(pps, sps, x0, y0, x ## v, y ## v)
280
281
#define COMPARE_MV_REFIDX(a, b)                                 \
282
1.78M
    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
5.84M
{
296
5.84M
    const RefPicList *refPicList = s->cur_frame->refPicList;
297
5.84M
    const MvField *tab_mvf       = s->cur_frame->tab_mvf;
298
299
5.84M
    const int min_pu_width = sps->min_pu_width;
300
301
5.84M
    const int cand_bottom_left = lc->na.cand_bottom_left;
302
5.84M
    const int cand_left        = lc->na.cand_left;
303
5.84M
    const int cand_up_left     = lc->na.cand_up_left;
304
5.84M
    const int cand_up          = lc->na.cand_up;
305
5.84M
    const int cand_up_right    = lc->na.cand_up_right_sap;
306
307
5.84M
    const int xA1    = x0 - 1;
308
5.84M
    const int yA1    = y0 + nPbH - 1;
309
310
5.84M
    const int xB1    = x0 + nPbW - 1;
311
5.84M
    const int yB1    = y0 - 1;
312
313
5.84M
    const int xB0    = x0 + nPbW;
314
5.84M
    const int yB0    = y0 - 1;
315
316
5.84M
    const int xA0    = x0 - 1;
317
5.84M
    const int yA0    = y0 + nPbH;
318
319
5.84M
    const int xB2    = x0 - 1;
320
5.84M
    const int yB2    = y0 - 1;
321
322
5.84M
    const int nb_refs = (s->sh.slice_type == HEVC_SLICE_P) ?
323
5.12M
                        s->sh.nb_refs[0] : FFMIN(s->sh.nb_refs[0], s->sh.nb_refs[1]);
324
325
5.84M
    int zero_idx = 0;
326
327
5.84M
    int nb_merge_cand = 0;
328
5.84M
    int nb_orig_merge_cand = 0;
329
330
5.84M
    int is_available_a0;
331
5.84M
    int is_available_a1;
332
5.84M
    int is_available_b0;
333
5.84M
    int is_available_b1;
334
5.84M
    int is_available_b2;
335
336
337
5.84M
    if (!singleMCLFlag && part_idx == 1 &&
338
332k
        (lc->cu.part_mode == PART_Nx2N ||
339
167k
         lc->cu.part_mode == PART_nLx2N ||
340
143k
         lc->cu.part_mode == PART_nRx2N) ||
341
5.64M
        is_diff_mer(pps, xA1, yA1, x0, y0)) {
342
1.75M
        is_available_a1 = 0;
343
4.09M
    } else {
344
4.09M
        is_available_a1 = AVAILABLE(cand_left, A1);
345
4.09M
        if (is_available_a1) {
346
3.82M
            mergecandlist[nb_merge_cand] = TAB_MVF_PU(A1);
347
3.82M
            if (merge_idx == 0)
348
3.09M
                return;
349
728k
            nb_merge_cand++;
350
728k
        }
351
4.09M
    }
352
353
2.75M
    if (!singleMCLFlag && part_idx == 1 &&
354
253k
        (lc->cu.part_mode == PART_2NxN ||
355
211k
         lc->cu.part_mode == PART_2NxnU ||
356
206k
         lc->cu.part_mode == PART_2NxnD) ||
357
2.70M
        is_diff_mer(pps, xB1, yB1, x0, y0)) {
358
1.19M
        is_available_b1 = 0;
359
1.55M
    } else {
360
1.55M
        is_available_b1 = AVAILABLE(cand_up, B1);
361
1.55M
        if (is_available_b1 &&
362
1.38M
            !(is_available_a1 && COMPARE_MV_REFIDX(B1, A1))) {
363
1.11M
            mergecandlist[nb_merge_cand] = TAB_MVF_PU(B1);
364
1.11M
            if (merge_idx == nb_merge_cand)
365
789k
                return;
366
326k
            nb_merge_cand++;
367
326k
        }
368
1.55M
    }
369
370
    // above right spatial merge candidate
371
1.96M
    is_available_b0 = AVAILABLE(cand_up_right, B0) &&
372
1.15M
                      xB0 < sps->width &&
373
1.12M
                      PRED_BLOCK_AVAILABLE(B0) &&
374
914k
                      !is_diff_mer(pps, xB0, yB0, x0, y0);
375
376
1.96M
    if (is_available_b0 &&
377
508k
        !(is_available_b1 && COMPARE_MV_REFIDX(B0, B1))) {
378
279k
        mergecandlist[nb_merge_cand] = TAB_MVF_PU(B0);
379
279k
        if (merge_idx == nb_merge_cand)
380
211k
            return;
381
68.0k
        nb_merge_cand++;
382
68.0k
    }
383
384
    // left bottom spatial merge candidate
385
1.75M
    is_available_a0 = AVAILABLE(cand_bottom_left, A0) &&
386
608k
                      yA0 < sps->height &&
387
608k
                      PRED_BLOCK_AVAILABLE(A0) &&
388
289k
                      !is_diff_mer(pps, xA0, yA0, x0, y0);
389
390
1.75M
    if (is_available_a0 &&
391
194k
        !(is_available_a1 && COMPARE_MV_REFIDX(A0, A1))) {
392
78.0k
        mergecandlist[nb_merge_cand] = TAB_MVF_PU(A0);
393
78.0k
        if (merge_idx == nb_merge_cand)
394
49.8k
            return;
395
28.2k
        nb_merge_cand++;
396
28.2k
    }
397
398
    // above left spatial merge candidate
399
1.70M
    is_available_b2 = AVAILABLE(cand_up_left, B2) &&
400
1.49M
                      !is_diff_mer(pps, xB2, yB2, x0, y0);
401
402
1.70M
    if (is_available_b2 &&
403
558k
        !(is_available_a1 && COMPARE_MV_REFIDX(B2, A1)) &&
404
333k
        !(is_available_b1 && COMPARE_MV_REFIDX(B2, B1)) &&
405
215k
        nb_merge_cand != 4) {
406
214k
        mergecandlist[nb_merge_cand] = TAB_MVF_PU(B2);
407
214k
        if (merge_idx == nb_merge_cand)
408
144k
            return;
409
69.8k
        nb_merge_cand++;
410
69.8k
    }
411
412
    // temporal motion vector candidate
413
1.55M
    if (s->sh.slice_temporal_mvp_enabled_flag &&
414
1.01M
        nb_merge_cand < s->sh.max_num_merge_cand) {
415
1.01M
        Mv mv_l0_col = { 0 }, mv_l1_col = { 0 };
416
1.01M
        int available_l0 = temporal_luma_motion_vector(s, sps, x0, y0, nPbW, nPbH,
417
1.01M
                                                       0, &mv_l0_col, 0);
418
1.01M
        int available_l1 = (s->sh.slice_type == HEVC_SLICE_B) ?
419
956k
                           temporal_luma_motion_vector(s, sps, x0, y0, nPbW, nPbH,
420
956k
                                                       0, &mv_l1_col, 1) : 0;
421
422
1.01M
        if (available_l0 || available_l1) {
423
776k
            mergecandlist[nb_merge_cand].pred_flag = available_l0 + (available_l1 << 1);
424
776k
            AV_ZERO16(mergecandlist[nb_merge_cand].ref_idx);
425
776k
            mergecandlist[nb_merge_cand].mv[0]      = mv_l0_col;
426
776k
            mergecandlist[nb_merge_cand].mv[1]      = mv_l1_col;
427
428
776k
            if (merge_idx == nb_merge_cand)
429
511k
                return;
430
265k
            nb_merge_cand++;
431
265k
        }
432
1.01M
    }
433
434
1.04M
    nb_orig_merge_cand = nb_merge_cand;
435
436
    // combined bi-predictive merge candidates  (applies for B slices)
437
1.04M
    if (s->sh.slice_type == HEVC_SLICE_B && nb_orig_merge_cand > 1 &&
438
165k
        nb_orig_merge_cand < s->sh.max_num_merge_cand) {
439
165k
        int comb_idx = 0;
440
441
472k
        for (comb_idx = 0; nb_merge_cand < s->sh.max_num_merge_cand &&
442
472k
                           comb_idx < nb_orig_merge_cand * (nb_orig_merge_cand - 1); comb_idx++) {
443
377k
            int l0_cand_idx = l0_l1_cand_idx[comb_idx][0];
444
377k
            int l1_cand_idx = l0_l1_cand_idx[comb_idx][1];
445
377k
            MvField l0_cand = mergecandlist[l0_cand_idx];
446
377k
            MvField l1_cand = mergecandlist[l1_cand_idx];
447
448
377k
            if ((l0_cand.pred_flag & PF_L0) && (l1_cand.pred_flag & PF_L1) &&
449
274k
                (refPicList[0].list[l0_cand.ref_idx[0]] !=
450
274k
                 refPicList[1].list[l1_cand.ref_idx[1]] ||
451
255k
                 AV_RN32A(&l0_cand.mv[0]) != AV_RN32A(&l1_cand.mv[1]))) {
452
109k
                mergecandlist[nb_merge_cand].ref_idx[0]   = l0_cand.ref_idx[0];
453
109k
                mergecandlist[nb_merge_cand].ref_idx[1]   = l1_cand.ref_idx[1];
454
109k
                mergecandlist[nb_merge_cand].pred_flag    = PF_BI;
455
109k
                AV_COPY32(&mergecandlist[nb_merge_cand].mv[0], &l0_cand.mv[0]);
456
109k
                AV_COPY32(&mergecandlist[nb_merge_cand].mv[1], &l1_cand.mv[1]);
457
109k
                if (merge_idx == nb_merge_cand)
458
70.0k
                    return;
459
39.0k
                nb_merge_cand++;
460
39.0k
            }
461
377k
        }
462
165k
    }
463
464
    // append Zero motion vector candidates
465
1.34M
    while (nb_merge_cand < s->sh.max_num_merge_cand) {
466
1.34M
        mergecandlist[nb_merge_cand].pred_flag    = PF_L0 + ((s->sh.slice_type == HEVC_SLICE_B) << 1);
467
1.34M
        AV_ZERO32(mergecandlist[nb_merge_cand].mv + 0);
468
1.34M
        AV_ZERO32(mergecandlist[nb_merge_cand].mv + 1);
469
1.34M
        mergecandlist[nb_merge_cand].ref_idx[0]   = zero_idx < nb_refs ? zero_idx : 0;
470
1.34M
        mergecandlist[nb_merge_cand].ref_idx[1]   = zero_idx < nb_refs ? zero_idx : 0;
471
472
1.34M
        if (merge_idx == nb_merge_cand)
473
975k
            return;
474
364k
        nb_merge_cand++;
475
364k
        zero_idx++;
476
364k
    }
477
975k
}
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
5.84M
{
487
5.84M
    const HEVCSPS *const  sps = pps->sps;
488
5.84M
    const HEVCContext *const s = lc->parent;
489
5.84M
    int singleMCLFlag = 0;
490
5.84M
    int nCS = 1 << log2_cb_size;
491
5.84M
    MvField mergecand_list[MRG_MAX_NUM_CANDS] = { 0 };
492
5.84M
    int nPbW2 = nPbW;
493
5.84M
    int nPbH2 = nPbH;
494
495
5.84M
    if (pps->log2_parallel_merge_level > 2 && nCS == 8) {
496
2.80M
        singleMCLFlag = 1;
497
2.80M
        x0            = lc->cu.x;
498
2.80M
        y0            = lc->cu.y;
499
2.80M
        nPbW          = nCS;
500
2.80M
        nPbH          = nCS;
501
2.80M
        part_idx      = 0;
502
2.80M
    }
503
504
5.84M
    ff_hevc_set_neighbour_available(lc, x0, y0, nPbW, nPbH, sps->log2_ctb_size);
505
5.84M
    derive_spatial_merge_candidates(lc, s, pps, sps, x0, y0, nPbW, nPbH, log2_cb_size,
506
5.84M
                                    singleMCLFlag, part_idx,
507
5.84M
                                    merge_idx, mergecand_list);
508
509
5.84M
    if (mergecand_list[merge_idx].pred_flag == PF_BI &&
510
3.68M
        (nPbW2 + nPbH2) == 12) {
511
510k
        mergecand_list[merge_idx].pred_flag = PF_L0;
512
510k
    }
513
514
5.84M
    *mv = mergecand_list[merge_idx];
515
5.84M
}
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
111k
{
521
111k
    const RefPicList *refPicList = s->cur_frame->refPicList;
522
111k
    const MvField *tab_mvf       = s->cur_frame->tab_mvf;
523
111k
    int ref_pic_elist      = refPicList[elist].list[TAB_MVF(x, y).ref_idx[elist]];
524
111k
    int ref_pic_curr       = refPicList[ref_idx_curr].list[ref_idx];
525
526
111k
    if (ref_pic_elist != ref_pic_curr) {
527
67.9k
        int poc_diff = s->poc - ref_pic_elist;
528
67.9k
        if (!poc_diff)
529
960
            poc_diff = 1;
530
67.9k
        mv_scale(mv, mv, poc_diff, s->poc - ref_pic_curr);
531
67.9k
    }
532
111k
}
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
3.54M
{
538
3.54M
    const MvField *tab_mvf = s->cur_frame->tab_mvf;
539
3.54M
    int min_pu_width = sps->min_pu_width;
540
541
3.54M
    const RefPicList *refPicList = s->cur_frame->refPicList;
542
543
3.54M
    if (((TAB_MVF(x, y).pred_flag) & (1 << pred_flag_index)) &&
544
3.17M
        refPicList[pred_flag_index].list[TAB_MVF(x, y).ref_idx[pred_flag_index]] == refPicList[ref_idx_curr].list[ref_idx]) {
545
2.84M
        *mv = TAB_MVF(x, y).mv[pred_flag_index];
546
2.84M
        return 1;
547
2.84M
    }
548
708k
    return 0;
549
3.54M
}
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
200k
{
555
200k
    const MvField *tab_mvf = s->cur_frame->tab_mvf;
556
200k
    int min_pu_width = sps->min_pu_width;
557
558
200k
    const RefPicList *refPicList = s->cur_frame->refPicList;
559
560
200k
    if ((TAB_MVF(x, y).pred_flag) & (1 << pred_flag_index)) {
561
172k
        int currIsLongTerm     = refPicList[ref_idx_curr].isLongTerm[ref_idx];
562
563
172k
        int colIsLongTerm =
564
172k
            refPicList[pred_flag_index].isLongTerm[(TAB_MVF(x, y).ref_idx[pred_flag_index])];
565
566
172k
        if (colIsLongTerm == currIsLongTerm) {
567
153k
            *mv = TAB_MVF(x, y).mv[pred_flag_index];
568
153k
            if (!currIsLongTerm)
569
111k
                dist_scale(s, mv, min_pu_width, x, y,
570
111k
                           pred_flag_index, ref_idx_curr, ref_idx);
571
153k
            return 1;
572
153k
        }
573
172k
    }
574
47.7k
    return 0;
575
200k
}
576
577
#define MP_MX(v, pred, mx)                                      \
578
3.54M
    mv_mp_mode_mx(s, sps,                                       \
579
3.54M
                  (x ## v) >> sps->log2_min_pu_size,            \
580
3.54M
                  (y ## v) >> sps->log2_min_pu_size,            \
581
3.54M
                  pred, &mx, ref_idx_curr, ref_idx)
582
583
#define MP_MX_LT(v, pred, mx)                                   \
584
200k
    mv_mp_mode_mx_lt(s, sps,                                    \
585
200k
                     (x ## v) >> sps->log2_min_pu_size,         \
586
200k
                     (y ## v) >> sps->log2_min_pu_size,         \
587
200k
                     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.59M
{
595
1.59M
    const HEVCSPS *const  sps = pps->sps;
596
1.59M
    const HEVCContext *const s = lc->parent;
597
1.59M
    const MvField *const tab_mvf = s->cur_frame->tab_mvf;
598
1.59M
    int isScaledFlag_L0 = 0;
599
1.59M
    int availableFlagLXA0 = 1;
600
1.59M
    int availableFlagLXB0 = 1;
601
1.59M
    int numMVPCandLX = 0;
602
1.59M
    int min_pu_width = sps->min_pu_width;
603
604
1.59M
    int xA0, yA0;
605
1.59M
    int is_available_a0;
606
1.59M
    int xA1, yA1;
607
1.59M
    int is_available_a1;
608
1.59M
    int xB0, yB0;
609
1.59M
    int is_available_b0;
610
1.59M
    int xB1, yB1;
611
1.59M
    int is_available_b1;
612
1.59M
    int xB2, yB2;
613
1.59M
    int is_available_b2;
614
615
1.59M
    Mv mvpcand_list[2] = { { 0 } };
616
1.59M
    Mv mxA;
617
1.59M
    Mv mxB;
618
1.59M
    int ref_idx_curr;
619
1.59M
    int ref_idx = 0;
620
1.59M
    int pred_flag_index_l0;
621
1.59M
    int pred_flag_index_l1;
622
623
1.59M
    const int cand_bottom_left = lc->na.cand_bottom_left;
624
1.59M
    const int cand_left        = lc->na.cand_left;
625
1.59M
    const int cand_up_left     = lc->na.cand_up_left;
626
1.59M
    const int cand_up          = lc->na.cand_up;
627
1.59M
    const int cand_up_right    = lc->na.cand_up_right_sap;
628
1.59M
    ref_idx_curr       = LX;
629
1.59M
    ref_idx            = mv->ref_idx[LX];
630
1.59M
    pred_flag_index_l0 = LX;
631
1.59M
    pred_flag_index_l1 = !LX;
632
633
    // left bottom spatial candidate
634
1.59M
    xA0 = x0 - 1;
635
1.59M
    yA0 = y0 + nPbH;
636
637
1.59M
    is_available_a0 = AVAILABLE(cand_bottom_left, A0) &&
638
740k
                      yA0 < sps->height &&
639
740k
                      PRED_BLOCK_AVAILABLE(A0);
640
641
    //left spatial merge candidate
642
1.59M
    xA1    = x0 - 1;
643
1.59M
    yA1    = y0 + nPbH - 1;
644
645
1.59M
    is_available_a1 = AVAILABLE(cand_left, A1);
646
1.59M
    if (is_available_a0 || is_available_a1)
647
1.48M
        isScaledFlag_L0 = 1;
648
649
1.59M
    if (is_available_a0) {
650
478k
        if (MP_MX(A0, pred_flag_index_l0, mxA)) {
651
417k
            goto b_candidates;
652
417k
        }
653
60.3k
        if (MP_MX(A0, pred_flag_index_l1, mxA)) {
654
33.6k
            goto b_candidates;
655
33.6k
        }
656
60.3k
    }
657
658
1.14M
    if (is_available_a1) {
659
1.03M
        if (MP_MX(A1, pred_flag_index_l0, mxA)) {
660
887k
            goto b_candidates;
661
887k
        }
662
148k
        if (MP_MX(A1, pred_flag_index_l1, mxA)) {
663
78.2k
            goto b_candidates;
664
78.2k
        }
665
148k
    }
666
667
181k
    if (is_available_a0) {
668
20.4k
        if (MP_MX_LT(A0, pred_flag_index_l0, mxA)) {
669
14.5k
            goto b_candidates;
670
14.5k
        }
671
5.89k
        if (MP_MX_LT(A0, pred_flag_index_l1, mxA)) {
672
2.93k
            goto b_candidates;
673
2.93k
        }
674
5.89k
    }
675
676
164k
    if (is_available_a1) {
677
53.2k
        if (MP_MX_LT(A1, pred_flag_index_l0, mxA)) {
678
34.1k
            goto b_candidates;
679
34.1k
        }
680
19.1k
        if (MP_MX_LT(A1, pred_flag_index_l1, mxA)) {
681
10.5k
            goto b_candidates;
682
10.5k
        }
683
19.1k
    }
684
119k
    availableFlagLXA0 = 0;
685
686
1.59M
b_candidates:
687
    // B candidates
688
    // above right spatial merge candidate
689
1.59M
    xB0    = x0 + nPbW;
690
1.59M
    yB0    = y0 - 1;
691
692
1.59M
    is_available_b0 =  AVAILABLE(cand_up_right, B0) &&
693
1.04M
                       xB0 < sps->width &&
694
1.02M
                       PRED_BLOCK_AVAILABLE(B0);
695
696
    // above spatial merge candidate
697
1.59M
    xB1    = x0 + nPbW - 1;
698
1.59M
    yB1    = y0 - 1;
699
1.59M
    is_available_b1 = AVAILABLE(cand_up, B1);
700
701
    // above left spatial merge candidate
702
1.59M
    xB2 = x0 - 1;
703
1.59M
    yB2 = y0 - 1;
704
1.59M
    is_available_b2 = AVAILABLE(cand_up_left, B2);
705
706
    // above right spatial merge candidate
707
1.59M
    if (is_available_b0) {
708
918k
        if (MP_MX(B0, pred_flag_index_l0, mxB)) {
709
805k
            goto scalef;
710
805k
        }
711
113k
        if (MP_MX(B0, pred_flag_index_l1, mxB)) {
712
69.5k
            goto scalef;
713
69.5k
        }
714
113k
    }
715
716
    // above spatial merge candidate
717
724k
    if (is_available_b1) {
718
571k
        if (MP_MX(B1, pred_flag_index_l0, mxB)) {
719
469k
            goto scalef;
720
469k
        }
721
102k
        if (MP_MX(B1, pred_flag_index_l1, mxB)) {
722
42.7k
            goto scalef;
723
42.7k
        }
724
102k
    }
725
726
    // above left spatial merge candidate
727
212k
    if (is_available_b2) {
728
75.8k
        if (MP_MX(B2, pred_flag_index_l0, mxB)) {
729
32.0k
            goto scalef;
730
32.0k
        }
731
43.8k
        if (MP_MX(B2, pred_flag_index_l1, mxB)) {
732
4.66k
            goto scalef;
733
4.66k
        }
734
43.8k
    }
735
175k
    availableFlagLXB0 = 0;
736
737
1.59M
scalef:
738
1.59M
    if (!isScaledFlag_L0) {
739
111k
        if (availableFlagLXB0) {
740
86.7k
            availableFlagLXA0 = 1;
741
86.7k
            mxA = mxB;
742
86.7k
        }
743
111k
        availableFlagLXB0 = 0;
744
745
        // XB0 and L1
746
111k
        if (is_available_b0) {
747
57.5k
            availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l0, mxB);
748
57.5k
            if (!availableFlagLXB0)
749
5.62k
                availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l1, mxB);
750
57.5k
        }
751
752
111k
        if (is_available_b1 && !availableFlagLXB0) {
753
29.9k
            availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l0, mxB);
754
29.9k
            if (!availableFlagLXB0)
755
3.73k
                availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l1, mxB);
756
29.9k
        }
757
758
111k
        if (is_available_b2 && !availableFlagLXB0) {
759
4.62k
            availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l0, mxB);
760
4.62k
            if (!availableFlagLXB0)
761
547
                availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l1, mxB);
762
4.62k
        }
763
111k
    }
764
765
1.59M
    if (availableFlagLXA0)
766
1.56M
        mvpcand_list[numMVPCandLX++] = mxA;
767
768
1.59M
    if (availableFlagLXB0 && (!availableFlagLXA0 || mxA.x != mxB.x || mxA.y != mxB.y))
769
846k
        mvpcand_list[numMVPCandLX++] = mxB;
770
771
    //temporal motion vector prediction candidate
772
1.59M
    if (numMVPCandLX < 2 && s->sh.slice_temporal_mvp_enabled_flag &&
773
467k
        mvp_lx_flag == numMVPCandLX) {
774
177k
        Mv mv_col;
775
177k
        int available_col = temporal_luma_motion_vector(s, sps, x0, y0, nPbW,
776
177k
                                                        nPbH, ref_idx,
777
177k
                                                        &mv_col, LX);
778
177k
        if (available_col)
779
96.5k
            mvpcand_list[numMVPCandLX++] = mv_col;
780
177k
    }
781
782
1.59M
    mv->mv[LX] = mvpcand_list[mvp_lx_flag];
783
1.59M
}