FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/vvc/mvs.c
Date: 2025-09-01 20:07:09
Exec Total Coverage
Lines: 1200 1204 99.7%
Functions: 81 81 100.0%
Branches: 663 682 97.2%

Line Branch Exec Source
1 /*
2 * VVC motion vector decoder
3 *
4 * Copyright (C) 2023 Nuo Mi
5 * Copyright (C) 2022 Xu Mu
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include "ctu.h"
24 #include "data.h"
25 #include "refs.h"
26 #include "mvs.h"
27
28 #define IS_SAME_MV(a, b) (AV_RN64A(a) == AV_RN64A(b))
29
30 //check if the two luma locations belong to the same motion estimation region
31 673964 static av_always_inline int is_same_mer(const VVCFrameContext *fc, const int xN, const int yN, const int xP, const int yP)
32 {
33 673964 const uint8_t plevel = fc->ps.sps->log2_parallel_merge_level;
34
35
2/2
✓ Branch 0 taken 42122 times.
✓ Branch 1 taken 631842 times.
716086 return xN >> plevel == xP >> plevel &&
36
2/2
✓ Branch 0 taken 6192 times.
✓ Branch 1 taken 35930 times.
42122 yN >> plevel == yP >> plevel;
37 }
38
39 //return true if we have same mvs and ref_idxs
40 2181523 static av_always_inline int compare_mv_ref_idx(const MvField *n, const MvField *o)
41 {
42
4/4
✓ Branch 0 taken 1834419 times.
✓ Branch 1 taken 347104 times.
✓ Branch 2 taken 575073 times.
✓ Branch 3 taken 1259346 times.
2181523 if (!o || n->pred_flag != o->pred_flag)
43 922177 return 0;
44
2/2
✓ Branch 0 taken 1591840 times.
✓ Branch 1 taken 276092 times.
1867932 for (int i = 0; i < 2; i++) {
45 1591840 PredFlag mask = i + 1;
46
2/2
✓ Branch 0 taken 1431644 times.
✓ Branch 1 taken 160196 times.
1591840 if (n->pred_flag & mask) {
47 1431644 const int same_ref_idx = n->ref_idx[i] == o->ref_idx[i];
48 1431644 const int same_mv = IS_SAME_MV(n->mv + i, o->mv + i);
49
4/4
✓ Branch 0 taken 1295338 times.
✓ Branch 1 taken 136306 times.
✓ Branch 2 taken 846948 times.
✓ Branch 3 taken 448390 times.
1431644 if (!same_ref_idx || !same_mv)
50 983254 return 0;
51 }
52 }
53 276092 return 1;
54 }
55
56 // 8.5.2.15 Temporal motion buffer compression process for collocated motion vectors
57 2405588 static av_always_inline void mv_compression(Mv *motion)
58 {
59 2405588 int mv[2] = {motion->x, motion->y};
60
2/2
✓ Branch 0 taken 4811176 times.
✓ Branch 1 taken 2405588 times.
7216764 for (int i = 0; i < 2; i++) {
61 4811176 const int s = mv[i] >> 17;
62 4811176 const int f = av_log2((mv[i] ^ s) | 31) - 4;
63 4811176 const int mask = (-1 * (1 << f)) >> 1;
64 4811176 const int round = (1 << f) >> 2;
65 4811176 mv[i] = (mv[i] + round) & mask;
66 }
67 2405588 motion->x = mv[0];
68 2405588 motion->y = mv[1];
69 2405588 }
70
71 1986374 void ff_vvc_mv_scale(Mv *dst, const Mv *src, int td, int tb)
72 {
73 int tx, scale_factor;
74
75 1986374 td = av_clip_int8(td);
76 1986374 tb = av_clip_int8(tb);
77 1986374 tx = (0x4000 + (abs(td) >> 1)) / td;
78 1986374 scale_factor = av_clip_intp2((tb * tx + 32) >> 6, 12);
79 1986374 dst->x = av_clip_intp2((scale_factor * src->x + 127 +
80 1986374 (scale_factor * src->x < 0)) >> 8, 17);
81 1986374 dst->y = av_clip_intp2((scale_factor * src->y + 127 +
82 1986374 (scale_factor * src->y < 0)) >> 8, 17);
83 1986374 }
84
85 //part of 8.5.2.12 Derivation process for collocated motion vectors
86 2417657 static int check_mvset(Mv *mvLXCol, Mv *mvCol,
87 int colPic, int poc,
88 const RefPicList *refPicList, int X, int refIdxLx,
89 const RefPicList *refPicList_col, int listCol, int refidxCol)
90 {
91 2417657 int cur_lt = refPicList[X].refs[refIdxLx].is_lt;
92 2417657 int col_lt = refPicList_col[listCol].refs[refidxCol].is_lt;
93 int col_poc_diff, cur_poc_diff;
94
95
2/2
✓ Branch 0 taken 12069 times.
✓ Branch 1 taken 2405588 times.
2417657 if (cur_lt != col_lt) {
96 12069 mvLXCol->x = 0;
97 12069 mvLXCol->y = 0;
98 12069 return 0;
99 }
100
101 2405588 col_poc_diff = colPic - refPicList_col[listCol].refs[refidxCol].poc;
102 2405588 cur_poc_diff = poc - refPicList[X].refs[refIdxLx].poc;
103
104 2405588 mv_compression(mvCol);
105
4/4
✓ Branch 0 taken 2397370 times.
✓ Branch 1 taken 8218 times.
✓ Branch 2 taken 426838 times.
✓ Branch 3 taken 1970532 times.
2405588 if (cur_lt || col_poc_diff == cur_poc_diff) {
106 435056 mvLXCol->x = av_clip_intp2(mvCol->x, 17);
107 435056 mvLXCol->y = av_clip_intp2(mvCol->y, 17);
108 } else {
109 1970532 ff_vvc_mv_scale(mvLXCol, mvCol, col_poc_diff, cur_poc_diff);
110 }
111 2405588 return 1;
112 }
113
114 #define CHECK_MVSET(l) \
115 check_mvset(mvLXCol, temp_col.mv + l, \
116 colPic, fc->ps.ph.poc, \
117 refPicList, X, refIdxLx, \
118 refPicList_col, L ## l, temp_col.ref_idx[l])
119
120 //derive NoBackwardPredFlag
121 598319 int ff_vvc_no_backward_pred_flag(const VVCLocalContext *lc)
122 {
123 598319 int check_diffpicount = 0;
124 int i, j;
125 598319 const RefPicList *rpl = lc->sc->rpl;
126
127
2/2
✓ Branch 0 taken 1196638 times.
✓ Branch 1 taken 598319 times.
1794957 for (j = 0; j < 2; j++) {
128
2/2
✓ Branch 0 taken 1893247 times.
✓ Branch 1 taken 528377 times.
2421624 for (i = 0; i < lc->sc->sh.r->num_ref_idx_active[j]; i++) {
129
2/2
✓ Branch 0 taken 668261 times.
✓ Branch 1 taken 1224986 times.
1893247 if (rpl[j].refs[i].poc > lc->fc->ps.ph.poc) {
130 668261 check_diffpicount++;
131 668261 break;
132 }
133 }
134 }
135 598319 return !check_diffpicount;
136 }
137
138 //8.5.2.12 Derivation process for collocated motion vectors
139 2969656 static int derive_temporal_colocated_mvs(const VVCLocalContext *lc, MvField temp_col,
140 int refIdxLx, Mv *mvLXCol, int X,
141 int colPic, const RefPicList *refPicList_col, int sb_flag)
142 {
143 2969656 const VVCFrameContext *fc = lc->fc;
144 2969656 const SliceContext *sc = lc->sc;
145 2969656 RefPicList* refPicList = sc->rpl;
146
147
2/2
✓ Branch 0 taken 2890891 times.
✓ Branch 1 taken 78765 times.
2969656 if (temp_col.pred_flag == PF_INTRA ||
148
2/2
✓ Branch 0 taken 2886391 times.
✓ Branch 1 taken 4500 times.
2890891 temp_col.pred_flag == PF_IBC ||
149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2886391 times.
2886391 temp_col.pred_flag == PF_PLT)
150 83265 return 0;
151
152
2/2
✓ Branch 0 taken 2762815 times.
✓ Branch 1 taken 123576 times.
2886391 if (sb_flag){
153
2/2
✓ Branch 0 taken 1553780 times.
✓ Branch 1 taken 1209035 times.
2762815 if (X == 0) {
154
2/2
✓ Branch 0 taken 1366124 times.
✓ Branch 1 taken 187656 times.
1553780 if (temp_col.pred_flag & PF_L0)
155 1366124 return CHECK_MVSET(0);
156
3/4
✓ Branch 1 taken 2349 times.
✓ Branch 2 taken 185307 times.
✓ Branch 3 taken 2349 times.
✗ Branch 4 not taken.
187656 else if (ff_vvc_no_backward_pred_flag(lc) && (temp_col.pred_flag & PF_L1))
157 2349 return CHECK_MVSET(1);
158 } else {
159
2/2
✓ Branch 0 taken 861972 times.
✓ Branch 1 taken 347063 times.
1209035 if (temp_col.pred_flag & PF_L1)
160 861972 return CHECK_MVSET(1);
161
3/4
✓ Branch 1 taken 63636 times.
✓ Branch 2 taken 283427 times.
✓ Branch 3 taken 63636 times.
✗ Branch 4 not taken.
347063 else if (ff_vvc_no_backward_pred_flag(lc) && (temp_col.pred_flag & PF_L0))
162 63636 return CHECK_MVSET(0);
163 }
164 } else {
165
2/2
✓ Branch 0 taken 15706 times.
✓ Branch 1 taken 107870 times.
123576 if (!(temp_col.pred_flag & PF_L0))
166 15706 return CHECK_MVSET(1);
167
2/2
✓ Branch 0 taken 56415 times.
✓ Branch 1 taken 51455 times.
107870 else if (temp_col.pred_flag == PF_L0)
168 56415 return CHECK_MVSET(0);
169
1/2
✓ Branch 0 taken 51455 times.
✗ Branch 1 not taken.
51455 else if (temp_col.pred_flag == PF_BI) {
170
2/2
✓ Branch 1 taken 9703 times.
✓ Branch 2 taken 41752 times.
51455 if (ff_vvc_no_backward_pred_flag(lc)) {
171
2/2
✓ Branch 0 taken 5087 times.
✓ Branch 1 taken 4616 times.
9703 if (X == 0)
172 5087 return CHECK_MVSET(0);
173 else
174 4616 return CHECK_MVSET(1);
175 } else {
176
2/2
✓ Branch 0 taken 23178 times.
✓ Branch 1 taken 18574 times.
41752 if (!lc->sc->sh.r->sh_collocated_from_l0_flag)
177 23178 return CHECK_MVSET(0);
178 else
179 18574 return CHECK_MVSET(1);
180 }
181 }
182 }
183 468734 return 0;
184 }
185
186 #define TAB_MVF(x, y) \
187 tab_mvf[((y) >> MIN_PU_LOG2) * min_pu_width + ((x) >> MIN_PU_LOG2)]
188
189 #define TAB_MVF_PU(v) \
190 TAB_MVF(x ## v, y ## v)
191
192 #define TAB_CP_MV(lx, x, y) \
193 fc->tab.cp_mv[lx][((((y) >> min_cb_log2_size) * min_cb_width + ((x) >> min_cb_log2_size)) ) * MAX_CONTROL_POINTS]
194
195
196 #define DERIVE_TEMPORAL_COLOCATED_MVS(sb_flag) \
197 derive_temporal_colocated_mvs(lc, temp_col, \
198 refIdxLx, mvLXCol, X, colPic, \
199 ff_vvc_get_ref_list(fc, ref, x, y), sb_flag)
200
201 //8.5.2.11 Derivation process for temporal luma motion vector prediction
202 153072 static int temporal_luma_motion_vector(const VVCLocalContext *lc,
203 const int refIdxLx, Mv *mvLXCol, const int X, int check_center, int sb_flag)
204 {
205 153072 const VVCFrameContext *fc = lc->fc;
206 153072 const VVCSPS *sps = fc->ps.sps;
207 153072 const VVCPPS *pps = fc->ps.pps;
208 153072 const CodingUnit *cu = lc->cu;
209 153072 const int subpic_idx = lc->sc->sh.r->curr_subpic_idx;
210 153072 int x, y, x_end, y_end, colPic, availableFlagLXCol = 0;
211 153072 int min_pu_width = fc->ps.pps->min_pu_width;
212 153072 VVCFrame *ref = fc->ref->collocated_ref;
213 MvField *tab_mvf;
214 MvField temp_col;
215
216
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 153006 times.
153072 if (!ref) {
217 66 memset(mvLXCol, 0, sizeof(*mvLXCol));
218 66 return 0;
219 }
220
221
3/4
✓ Branch 0 taken 153006 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4749 times.
✓ Branch 3 taken 148257 times.
153006 if (!fc->ps.ph.r->ph_temporal_mvp_enabled_flag || (cu->cb_width * cu->cb_height <= 32))
222 4749 return 0;
223
224 148257 tab_mvf = ref->tab_dmvr_mvf;
225 148257 colPic = ref->poc;
226
227 //bottom right collocated motion vector
228 148257 x = cu->x0 + cu->cb_width;
229 148257 y = cu->y0 + cu->cb_height;
230
231 148257 x_end = pps->subpic_x[subpic_idx] + pps->subpic_width[subpic_idx];
232 148257 y_end = pps->subpic_y[subpic_idx] + pps->subpic_height[subpic_idx];
233
234
1/2
✓ Branch 0 taken 148257 times.
✗ Branch 1 not taken.
148257 if (tab_mvf &&
235
4/4
✓ Branch 0 taken 125422 times.
✓ Branch 1 taken 22835 times.
✓ Branch 2 taken 123069 times.
✓ Branch 3 taken 2353 times.
148257 (cu->y0 >> sps->ctb_log2_size_y) == (y >> sps->ctb_log2_size_y) &&
236
2/2
✓ Branch 0 taken 119041 times.
✓ Branch 1 taken 4028 times.
123069 x < x_end && y < y_end) {
237 119041 x &= ~7;
238 119041 y &= ~7;
239 119041 temp_col = TAB_MVF(x, y);
240 119041 availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS(sb_flag);
241 }
242
2/2
✓ Branch 0 taken 134433 times.
✓ Branch 1 taken 13824 times.
148257 if (check_center) {
243 // derive center collocated motion vector
244
3/4
✓ Branch 0 taken 134433 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 57611 times.
✓ Branch 3 taken 76822 times.
134433 if (tab_mvf && !availableFlagLXCol) {
245 57611 x = cu->x0 + (cu->cb_width >> 1);
246 57611 y = cu->y0 + (cu->cb_height >> 1);
247 57611 x &= ~7;
248 57611 y &= ~7;
249 57611 temp_col = TAB_MVF(x, y);
250 57611 availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS(sb_flag);
251 }
252 }
253 148257 return availableFlagLXCol;
254 }
255
256 6093322 void ff_vvc_set_mvf(const VVCLocalContext *lc, const int x0, const int y0, const int w, const int h, const MvField *mvf)
257 {
258 6093322 const VVCFrameContext *fc = lc->fc;
259 6093322 MvField *tab_mvf = fc->tab.mvf;
260 6093322 const int min_pu_width = fc->ps.pps->min_pu_width;
261 6093322 const int min_pu_size = 1 << MIN_PU_LOG2;
262
2/2
✓ Branch 0 taken 9702737 times.
✓ Branch 1 taken 6093322 times.
15796059 for (int dy = 0; dy < h; dy += min_pu_size) {
263
2/2
✓ Branch 0 taken 43669017 times.
✓ Branch 1 taken 9702737 times.
53371754 for (int dx = 0; dx < w; dx += min_pu_size) {
264 43669017 const int x = x0 + dx;
265 43669017 const int y = y0 + dy;
266 43669017 TAB_MVF(x, y) = *mvf;
267 }
268 }
269 6093322 }
270
271 696757 void ff_vvc_set_intra_mvf(const VVCLocalContext *lc, const bool dmvr, const PredFlag pf, const bool ciip_flag)
272 {
273 696757 const VVCFrameContext *fc = lc->fc;
274 696757 const CodingUnit *cu = lc->cu;
275
2/2
✓ Branch 0 taken 67240 times.
✓ Branch 1 taken 629517 times.
696757 MvField *tab_mvf = dmvr ? fc->ref->tab_dmvr_mvf : fc->tab.mvf;
276 696757 const int min_pu_width = fc->ps.pps->min_pu_width;
277 696757 const int min_pu_size = 1 << MIN_PU_LOG2;
278
2/2
✓ Branch 0 taken 1738299 times.
✓ Branch 1 taken 696757 times.
2435056 for (int dy = 0; dy < cu->cb_height; dy += min_pu_size) {
279
2/2
✓ Branch 0 taken 7126442 times.
✓ Branch 1 taken 1738299 times.
8864741 for (int dx = 0; dx < cu->cb_width; dx += min_pu_size) {
280 7126442 const int x = cu->x0 + dx;
281 7126442 const int y = cu->y0 + dy;
282 7126442 MvField *mv = &TAB_MVF(x, y);
283
284 7126442 mv->pred_flag = pf;
285 7126442 mv->ciip_flag = ciip_flag;
286 }
287 }
288 696757 }
289
290 //cbProfFlagLX from 8.5.5.9 Derivation process for motion vector arrays from affine control point motion vectors
291 46434 static int derive_cb_prof_flag_lx(const VVCLocalContext *lc, const PredictionUnit* pu, int lx, int is_fallback)
292 {
293 46434 const MotionInfo* mi = &pu->mi;
294 46434 const Mv* cp_mv = &mi->mv[lx][0];
295
4/4
✓ Branch 0 taken 46267 times.
✓ Branch 1 taken 167 times.
✓ Branch 2 taken 1104 times.
✓ Branch 3 taken 45163 times.
46434 if (lc->fc->ps.ph.r->ph_prof_disabled_flag || is_fallback)
296 1271 return 0;
297
2/2
✓ Branch 0 taken 19026 times.
✓ Branch 1 taken 26137 times.
45163 if (mi->motion_model_idc == MOTION_4_PARAMS_AFFINE) {
298
2/2
✓ Branch 0 taken 5534 times.
✓ Branch 1 taken 13492 times.
19026 if (IS_SAME_MV(cp_mv, cp_mv + 1))
299 5534 return 0;
300 }
301
2/2
✓ Branch 0 taken 26137 times.
✓ Branch 1 taken 13492 times.
39629 if (mi->motion_model_idc == MOTION_6_PARAMS_AFFINE) {
302
4/4
✓ Branch 0 taken 4643 times.
✓ Branch 1 taken 21494 times.
✓ Branch 2 taken 1152 times.
✓ Branch 3 taken 3491 times.
26137 if (IS_SAME_MV(cp_mv, cp_mv + 1) && IS_SAME_MV(cp_mv, cp_mv + 2))
303 1152 return 0;
304 }
305
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 38340 times.
38477 if (lc->sc->rpl[lx].refs[mi->ref_idx[lx]].is_scaled)
306 137 return 0;
307 38340 return 1;
308 }
309
310 typedef struct SubblockParams {
311 int d_hor_x;
312 int d_ver_x;
313 int d_hor_y;
314 int d_ver_y;
315 int mv_scale_hor;
316 int mv_scale_ver;
317 int is_fallback;
318
319 int cb_width;
320 int cb_height;
321 } SubblockParams;
322
323 46434 static int is_fallback_mode(const SubblockParams *sp, const PredFlag pred_flag)
324 {
325 46434 const int a = 4 * (2048 + sp->d_hor_x);
326 46434 const int b = 4 * sp->d_hor_y;
327 46434 const int c = 4 * (2048 + sp->d_ver_y);
328 46434 const int d = 4 * sp->d_ver_x;
329
2/2
✓ Branch 0 taken 20940 times.
✓ Branch 1 taken 25494 times.
46434 if (pred_flag == PF_BI) {
330
2/2
✓ Branch 0 taken 20829 times.
✓ Branch 1 taken 111 times.
20940 const int max_w4 = FFMAX(0, FFMAX(a, FFMAX(b, a + b)));
331
2/2
✓ Branch 0 taken 111 times.
✓ Branch 1 taken 20829 times.
20940 const int min_w4 = FFMIN(0, FFMIN(a, FFMIN(b, a + b)));
332
2/2
✓ Branch 0 taken 20840 times.
✓ Branch 1 taken 100 times.
20940 const int max_h4 = FFMAX(0, FFMAX(c, FFMAX(d, c + d)));
333
2/2
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 20840 times.
20940 const int min_h4 = FFMIN(0, FFMIN(c, FFMIN(d, c + d)));
334 20940 const int bx_wx4 = ((max_w4 - min_w4) >> 11) + 9;
335 20940 const int bx_hx4 = ((max_h4 - min_h4) >> 11) + 9;
336 20940 return bx_wx4 * bx_hx4 > 225;
337 } else {
338 25494 const int bx_wxh = (FFABS(a) >> 11) + 9;
339 25494 const int bx_hxh = (FFABS(d) >> 11) + 9;
340 25494 const int bx_wxv = (FFABS(b) >> 11) + 9;
341 25494 const int bx_hxv = (FFABS(c) >> 11) + 9;
342
4/4
✓ Branch 0 taken 24827 times.
✓ Branch 1 taken 667 times.
✓ Branch 2 taken 24733 times.
✓ Branch 3 taken 94 times.
25494 if (bx_wxh * bx_hxh <= 165 && bx_wxv * bx_hxv <= 165)
343 24733 return 0;
344 }
345 761 return 1;
346 }
347
348 46434 static void init_subblock_params(SubblockParams *sp, const MotionInfo* mi,
349 const int cb_width, const int cb_height, const int lx)
350 {
351 46434 const int log2_cbw = av_log2(cb_width);
352 46434 const int log2_cbh = av_log2(cb_height);
353 46434 const Mv* cp_mv = mi->mv[lx];
354 46434 const int num_cp_mv = mi->motion_model_idc + 1;
355 46434 sp->d_hor_x = (cp_mv[1].x - cp_mv[0].x) * (1 << (MAX_CU_DEPTH - log2_cbw));
356 46434 sp->d_ver_x = (cp_mv[1].y - cp_mv[0].y) * (1 << (MAX_CU_DEPTH - log2_cbw));
357
2/2
✓ Branch 0 taken 26530 times.
✓ Branch 1 taken 19904 times.
46434 if (num_cp_mv == 3) {
358 26530 sp->d_hor_y = (cp_mv[2].x - cp_mv[0].x) * (1 << (MAX_CU_DEPTH - log2_cbh));
359 26530 sp->d_ver_y = (cp_mv[2].y - cp_mv[0].y) * (1 << (MAX_CU_DEPTH - log2_cbh));
360 } else {
361 19904 sp->d_hor_y = -sp->d_ver_x;
362 19904 sp->d_ver_y = sp->d_hor_x;
363 }
364 46434 sp->mv_scale_hor = (cp_mv[0].x) * (1 << MAX_CU_DEPTH);
365 46434 sp->mv_scale_ver = (cp_mv[0].y) * (1 << MAX_CU_DEPTH);
366 46434 sp->cb_width = cb_width;
367 46434 sp->cb_height = cb_height;
368 46434 sp->is_fallback = is_fallback_mode(sp, mi->pred_flag);
369 46434 }
370
371 46434 static void derive_subblock_diff_mvs(const VVCLocalContext *lc, PredictionUnit* pu, const SubblockParams* sp, const int lx)
372 {
373 46434 pu->cb_prof_flag[lx] = derive_cb_prof_flag_lx(lc, pu, lx, sp->is_fallback);
374
2/2
✓ Branch 0 taken 38340 times.
✓ Branch 1 taken 8094 times.
46434 if (pu->cb_prof_flag[lx]) {
375 38340 const int dmv_limit = 1 << 5;
376 38340 const int pos_offset_x = 6 * (sp->d_hor_x + sp->d_hor_y);
377 38340 const int pos_offset_y = 6 * (sp->d_ver_x + sp->d_ver_y);
378
2/2
✓ Branch 0 taken 153360 times.
✓ Branch 1 taken 38340 times.
191700 for (int x = 0; x < AFFINE_MIN_BLOCK_SIZE; x++) {
379
2/2
✓ Branch 0 taken 613440 times.
✓ Branch 1 taken 153360 times.
766800 for (int y = 0; y < AFFINE_MIN_BLOCK_SIZE; y++) {
380 613440 LOCAL_ALIGNED_8(Mv, diff, [1]);
381 613440 diff->x = x * (sp->d_hor_x * (1 << 2)) + y * (sp->d_hor_y * (1 << 2)) - pos_offset_x;
382 613440 diff->y = x * (sp->d_ver_x * (1 << 2)) + y * (sp->d_ver_y * (1 << 2)) - pos_offset_y;
383 613440 ff_vvc_round_mv(diff, 0, 8);
384 613440 pu->diff_mv_x[lx][AFFINE_MIN_BLOCK_SIZE * y + x] = av_clip(diff->x, -dmv_limit + 1, dmv_limit - 1);
385 613440 pu->diff_mv_y[lx][AFFINE_MIN_BLOCK_SIZE * y + x] = av_clip(diff->y, -dmv_limit + 1, dmv_limit - 1);
386 }
387 }
388 }
389 46434 }
390
391 46434 static void store_cp_mv(const VVCLocalContext *lc, const MotionInfo *mi, const int lx)
392 {
393 46434 VVCFrameContext *fc = lc->fc;
394 46434 const CodingUnit *cu = lc->cu;
395 46434 const int log2_min_cb_size = fc->ps.sps->min_cb_log2_size_y;
396 46434 const int min_cb_size = fc->ps.sps->min_cb_size_y;
397 46434 const int min_cb_width = fc->ps.pps->min_cb_width;
398 46434 const int num_cp_mv = mi->motion_model_idc + 1;
399
400
2/2
✓ Branch 0 taken 364970 times.
✓ Branch 1 taken 46434 times.
411404 for (int dy = 0; dy < cu->cb_height; dy += min_cb_size) {
401
2/2
✓ Branch 0 taken 4579736 times.
✓ Branch 1 taken 364970 times.
4944706 for (int dx = 0; dx < cu->cb_width; dx += min_cb_size) {
402 4579736 const int x_cb = (cu->x0 + dx) >> log2_min_cb_size;
403 4579736 const int y_cb = (cu->y0 + dy) >> log2_min_cb_size;
404 4579736 const int offset = (y_cb * min_cb_width + x_cb) * MAX_CONTROL_POINTS;
405
406 4579736 memcpy(&fc->tab.cp_mv[lx][offset], mi->mv[lx], sizeof(Mv) * num_cp_mv);
407 }
408 }
409 46434 }
410
411 //8.5.5.9 Derivation process for motion vector arrays from affine control point motion vectors
412 35964 void ff_vvc_store_sb_mvs(const VVCLocalContext *lc, PredictionUnit *pu)
413 {
414 35964 const CodingUnit *cu = lc->cu;
415 35964 const MotionInfo *mi = &pu->mi;
416 35964 const int sbw = cu->cb_width / mi->num_sb_x;
417 35964 const int sbh = cu->cb_height / mi->num_sb_y;
418 SubblockParams params[2];
419 35964 MvField mvf = {0};
420
421 35964 mvf.pred_flag = mi->pred_flag;
422 35964 mvf.bcw_idx = mi->bcw_idx;
423 35964 mvf.hpel_if_idx = mi->hpel_if_idx;
424
2/2
✓ Branch 0 taken 71928 times.
✓ Branch 1 taken 35964 times.
107892 for (int i = 0; i < 2; i++) {
425 71928 const PredFlag mask = i + 1;
426
2/2
✓ Branch 0 taken 46434 times.
✓ Branch 1 taken 25494 times.
71928 if (mi->pred_flag & mask) {
427 46434 store_cp_mv(lc, mi, i);
428 46434 init_subblock_params(params + i, mi, cu->cb_width, cu->cb_height, i);
429 46434 derive_subblock_diff_mvs(lc, pu, params + i, i);
430 46434 mvf.ref_idx[i] = mi->ref_idx[i];
431 }
432 }
433
434
2/2
✓ Branch 0 taken 284102 times.
✓ Branch 1 taken 35964 times.
320066 for (int sby = 0; sby < mi->num_sb_y; sby++) {
435
2/2
✓ Branch 0 taken 3527044 times.
✓ Branch 1 taken 284102 times.
3811146 for (int sbx = 0; sbx < mi->num_sb_x; sbx++) {
436 3527044 const int x0 = cu->x0 + sbx * sbw;
437 3527044 const int y0 = cu->y0 + sby * sbh;
438
2/2
✓ Branch 0 taken 7054088 times.
✓ Branch 1 taken 3527044 times.
10581132 for (int i = 0; i < 2; i++) {
439 7054088 const PredFlag mask = i + 1;
440
2/2
✓ Branch 0 taken 4579736 times.
✓ Branch 1 taken 2474352 times.
7054088 if (mi->pred_flag & mask) {
441 4579736 const SubblockParams* sp = params + i;
442
2/2
✓ Branch 0 taken 141736 times.
✓ Branch 1 taken 4438000 times.
4579736 const int x_pos_cb = sp->is_fallback ? (cu->cb_width >> 1) : (2 + (sbx << MIN_CU_LOG2));
443
2/2
✓ Branch 0 taken 141736 times.
✓ Branch 1 taken 4438000 times.
4579736 const int y_pos_cb = sp->is_fallback ? (cu->cb_height >> 1) : (2 + (sby << MIN_CU_LOG2));
444 4579736 Mv *mv = mvf.mv + i;
445
446 4579736 mv->x = sp->mv_scale_hor + sp->d_hor_x * x_pos_cb + sp->d_hor_y * y_pos_cb;
447 4579736 mv->y = sp->mv_scale_ver + sp->d_ver_x * x_pos_cb + sp->d_ver_y * y_pos_cb;
448 4579736 ff_vvc_round_mv(mv, 0, MAX_CU_DEPTH);
449 4579736 ff_vvc_clip_mv(mv);
450 }
451 }
452 3527044 ff_vvc_set_mvf(lc, x0, y0, sbw, sbh, &mvf);
453 }
454 }
455 35964 }
456
457 27591 void ff_vvc_store_gpm_mvf(const VVCLocalContext *lc, const PredictionUnit *pu)
458 {
459 27591 const CodingUnit *cu = lc->cu;
460 27591 const int angle_idx = ff_vvc_gpm_angle_idx[pu->gpm_partition_idx];
461 27591 const int distance_idx = ff_vvc_gpm_distance_idx[pu->gpm_partition_idx];
462 27591 const int displacement_x = ff_vvc_gpm_distance_lut[angle_idx];
463 27591 const int displacement_y = ff_vvc_gpm_distance_lut[(angle_idx + 8) % 32];
464
4/4
✓ Branch 0 taken 14493 times.
✓ Branch 1 taken 13098 times.
✓ Branch 2 taken 11692 times.
✓ Branch 3 taken 2801 times.
27591 const int is_flip = angle_idx >= 13 &&angle_idx <= 27;
465
6/6
✓ Branch 0 taken 25441 times.
✓ Branch 1 taken 2150 times.
✓ Branch 2 taken 22418 times.
✓ Branch 3 taken 3023 times.
✓ Branch 4 taken 5658 times.
✓ Branch 5 taken 16760 times.
27591 const int shift_hor = (angle_idx % 16 == 8 || (angle_idx % 16 && cu->cb_height >= cu->cb_width)) ? 0 : 1;
466
2/2
✓ Branch 0 taken 16162 times.
✓ Branch 1 taken 11429 times.
27591 const int sign = angle_idx < 16 ? 1 : -1;
467 27591 const int block_size = 4;
468 27591 int offset_x = (-cu->cb_width) >> 1;
469 27591 int offset_y = (-cu->cb_height) >> 1;
470
471
2/2
✓ Branch 0 taken 18910 times.
✓ Branch 1 taken 8681 times.
27591 if (!shift_hor)
472 18910 offset_y += sign * ((distance_idx * cu->cb_height) >> 3);
473 else
474 8681 offset_x += sign * ((distance_idx * cu->cb_width) >> 3);
475
476
2/2
✓ Branch 0 taken 124750 times.
✓ Branch 1 taken 27591 times.
152341 for (int y = 0; y < cu->cb_height; y += block_size) {
477
2/2
✓ Branch 0 taken 615676 times.
✓ Branch 1 taken 124750 times.
740426 for (int x = 0; x < cu->cb_width; x += block_size) {
478 615676 const int motion_idx = (((x + offset_x) * (1 << 1)) + 5) * displacement_x +
479 615676 (((y + offset_y) * (1 << 1)) + 5) * displacement_y;
480
6/6
✓ Branch 0 taken 305044 times.
✓ Branch 1 taken 310632 times.
✓ Branch 2 taken 188260 times.
✓ Branch 3 taken 116784 times.
✓ Branch 4 taken 310632 times.
✓ Branch 5 taken 188260 times.
615676 const int s_type = FFABS(motion_idx) < 32 ? 2 : (motion_idx <= 0 ? (1 - is_flip) : is_flip);
481 615676 const int pred_flag = pu->gpm_mv[0].pred_flag | pu->gpm_mv[1].pred_flag;
482 615676 const int x0 = cu->x0 + x;
483 615676 const int y0 = cu->y0 + y;
484
485
2/2
✓ Branch 0 taken 243965 times.
✓ Branch 1 taken 371711 times.
615676 if (!s_type)
486 243965 ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, pu->gpm_mv + 0);
487
5/6
✓ Branch 0 taken 116784 times.
✓ Branch 1 taken 254927 times.
✓ Branch 2 taken 116784 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 61459 times.
✓ Branch 5 taken 55325 times.
371711 else if (s_type == 1 || (s_type == 2 && pred_flag != PF_BI))
488 316386 ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, pu->gpm_mv + 1);
489 else {
490 55325 MvField mvf = pu->gpm_mv[0];
491 55325 const MvField *mv1 = &pu->gpm_mv[1];
492 55325 const int lx = mv1->pred_flag - PF_L0;
493 55325 mvf.pred_flag = PF_BI;
494 55325 mvf.ref_idx[lx] = mv1->ref_idx[lx];
495 55325 mvf.mv[lx] = mv1->mv[lx];
496 55325 ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, &mvf);
497 }
498 }
499 }
500 27591 }
501
502 297332 void ff_vvc_store_mvf(const VVCLocalContext *lc, const MvField *mvf)
503 {
504 297332 const CodingUnit *cu = lc->cu;
505 297332 ff_vvc_set_mvf(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height, mvf);
506 297332 }
507
508 137668 void ff_vvc_store_mv(const VVCLocalContext *lc, const MotionInfo *mi)
509 {
510 137668 const CodingUnit *cu = lc->cu;
511 137668 MvField mvf = {0};
512
513 137668 mvf.hpel_if_idx = mi->hpel_if_idx;
514 137668 mvf.bcw_idx = mi->bcw_idx;
515 137668 mvf.pred_flag = mi->pred_flag;
516
517
2/2
✓ Branch 0 taken 275336 times.
✓ Branch 1 taken 137668 times.
413004 for (int i = 0; i < 2; i++) {
518 275336 const PredFlag mask = i + 1;
519
2/2
✓ Branch 0 taken 157079 times.
✓ Branch 1 taken 118257 times.
275336 if (mvf.pred_flag & mask) {
520 157079 mvf.mv[i] = mi->mv[i][0];
521 157079 mvf.ref_idx[i] = mi->ref_idx[i];
522 }
523 }
524 137668 ff_vvc_set_mvf(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height, &mvf);
525 137668 }
526
527 typedef enum NeighbourIdx {
528 A0,
529 A1,
530 A2,
531 B0,
532 B1,
533 B2,
534 B3,
535 NUM_NBS,
536 NB_IDX_NONE = NUM_NBS,
537 } NeighbourIdx;
538
539 typedef struct Neighbour {
540 int x;
541 int y;
542
543 int checked;
544 int available;
545 } Neighbour;
546
547 typedef struct NeighbourContext {
548 Neighbour neighbours[NUM_NBS];
549 const VVCLocalContext *lc;
550 } NeighbourContext;
551
552 1476472 static int is_available(const VVCFrameContext *fc, const int x0, const int y0)
553 {
554 1476472 const VVCSPS *sps = fc->ps.sps;
555 1476472 const int x = x0 >> sps->min_cb_log2_size_y;
556 1476472 const int y = y0 >> sps->min_cb_log2_size_y;
557 1476472 const int min_cb_width = fc->ps.pps->min_cb_width;
558
559 1476472 return SAMPLE_CTB(fc->tab.cb_width[0], x, y) != 0;
560 }
561
562 527621 static int is_a0_available(const VVCLocalContext *lc, const CodingUnit *cu)
563 {
564 527621 const VVCFrameContext *fc = lc->fc;
565 527621 const VVCSPS *sps = fc->ps.sps;
566 527621 const int x0b = av_zero_extend(cu->x0, sps->ctb_log2_size_y);
567 int cand_bottom_left;
568
569
4/4
✓ Branch 0 taken 114515 times.
✓ Branch 1 taken 413106 times.
✓ Branch 2 taken 15913 times.
✓ Branch 3 taken 98602 times.
527621 if (!x0b && !lc->ctb_left_flag) {
570 15913 cand_bottom_left = 0;
571 } else {
572 511708 const int max_y = FFMIN(fc->ps.pps->height, ((cu->y0 >> sps->ctb_log2_size_y) + 1) << sps->ctb_log2_size_y);
573
2/2
✓ Branch 0 taken 104485 times.
✓ Branch 1 taken 407223 times.
511708 if (cu->y0 + cu->cb_height >= max_y)
574 104485 cand_bottom_left = 0;
575 else
576 407223 cand_bottom_left = is_available(fc, cu->x0 - 1, cu->y0 + cu->cb_height);
577 }
578 527621 return cand_bottom_left;
579 }
580
581 527621 static void init_neighbour_context(NeighbourContext *ctx, const VVCLocalContext *lc)
582 {
583 527621 const CodingUnit *cu = lc->cu;
584 527621 const NeighbourAvailable *na = &lc->na;
585 527621 const int x0 = cu->x0;
586 527621 const int y0 = cu->y0;
587 527621 const int cb_width = cu->cb_width;
588 527621 const int cb_height = cu->cb_height;
589 527621 const int a0_available = is_a0_available(lc, cu);
590
591 527621 Neighbour neighbours[NUM_NBS] = {
592 527621 { x0 - 1, y0 + cb_height, !a0_available }, //A0
593 527621 { x0 - 1, y0 + cb_height - 1, !na->cand_left }, //A1
594 527621 { x0 - 1, y0, !na->cand_left }, //A2
595 527621 { x0 + cb_width, y0 - 1, !na->cand_up_right }, //B0
596 527621 { x0 + cb_width - 1, y0 - 1, !na->cand_up }, //B1
597 527621 { x0 - 1, y0 - 1, !na->cand_up_left }, //B2
598 527621 { x0, y0 - 1, !na->cand_up }, //B3
599 };
600
601 527621 memcpy(ctx->neighbours, neighbours, sizeof(neighbours));
602 527621 ctx->lc = lc;
603 527621 }
604
605 1019121 static av_always_inline PredMode pred_flag_to_mode(PredFlag pred)
606 {
607 static const PredMode lut[] = {
608 MODE_INTRA, // PF_INTRA
609 MODE_INTER, // PF_L0
610 MODE_INTER, // PF_L1
611 MODE_INTER, // PF_BI
612 0, // invalid
613 MODE_IBC, // PF_IBC
614 0, // invalid
615 0, // invalid
616 MODE_PLT, // PF_PLT
617 };
618
619 1019121 return lut[pred];
620 }
621
622 1369450 static int check_available(Neighbour *n, const VVCLocalContext *lc, const int check_mer)
623 {
624 1369450 const VVCFrameContext *fc = lc->fc;
625 1369450 const VVCSPS *sps = fc->ps.sps;
626 1369450 const CodingUnit *cu = lc->cu;
627 1369450 const MvField *tab_mvf = fc->tab.mvf;
628 1369450 const int min_pu_width = fc->ps.pps->min_pu_width;
629
630
2/2
✓ Branch 0 taken 1069449 times.
✓ Branch 1 taken 300001 times.
1369450 if (!n->checked) {
631 1069449 n->checked = 1;
632
4/4
✓ Branch 0 taken 87906 times.
✓ Branch 1 taken 981543 times.
✓ Branch 2 taken 87706 times.
✓ Branch 3 taken 200 times.
1069449 n->available = !sps->r->sps_entropy_coding_sync_enabled_flag || ((n->x >> sps->ctb_log2_size_y) <= (cu->x0 >> sps->ctb_log2_size_y));
633
6/6
✓ Branch 0 taken 1069249 times.
✓ Branch 1 taken 200 times.
✓ Branch 3 taken 1019121 times.
✓ Branch 4 taken 50128 times.
✓ Branch 6 taken 903541 times.
✓ Branch 7 taken 115580 times.
1069449 n->available = n->available && is_available(fc, n->x, n->y) && cu->pred_mode == pred_flag_to_mode(TAB_MVF(n->x, n->y).pred_flag);
634
2/2
✓ Branch 0 taken 748152 times.
✓ Branch 1 taken 321297 times.
1069449 if (check_mer)
635
4/4
✓ Branch 0 taken 673964 times.
✓ Branch 1 taken 74188 times.
✓ Branch 3 taken 667772 times.
✓ Branch 4 taken 6192 times.
748152 n->available = n->available && !is_same_mer(fc, n->x, n->y, cu->x0, cu->y0);
636 }
637 1369450 return n->available;
638 }
639
640 564533 static const MvField *mv_merge_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand)
641 {
642 564533 const VVCFrameContext *fc = lc->fc;
643 564533 const int min_pu_width = fc->ps.pps->min_pu_width;
644 564533 const MvField* tab_mvf = fc->tab.mvf;
645 564533 const MvField *mvf = &TAB_MVF(x_cand, y_cand);
646
647 564533 return mvf;
648 }
649
650 716161 static const MvField* mv_merge_from_nb(NeighbourContext *ctx, const NeighbourIdx nb)
651 {
652 716161 const VVCLocalContext *lc = ctx->lc;
653 716161 Neighbour *n = &ctx->neighbours[nb];
654
655
2/2
✓ Branch 1 taken 564533 times.
✓ Branch 2 taken 151628 times.
716161 if (check_available(n, lc, 1))
656 564533 return mv_merge_candidate(lc, n->x, n->y);
657 151628 return 0;
658 }
659 #define MV_MERGE_FROM_NB(nb) mv_merge_from_nb(&nctx, nb)
660
661 //8.5.2.3 Derivation process for spatial merging candidates
662 324923 static int mv_merge_spatial_candidates(const VVCLocalContext *lc, const int merge_idx,
663 const MvField **nb_list, MvField *cand_list, int *nb_merge_cand)
664 {
665 const MvField *cand;
666 324923 int num_cands = 0;
667 NeighbourContext nctx;
668
669 static NeighbourIdx nbs[][2] = {
670 {B1, NB_IDX_NONE },
671 {A1, B1 },
672 {B0, B1 },
673 {A0, A1 },
674 };
675
676 324923 init_neighbour_context(&nctx, lc);
677
2/2
✓ Branch 0 taken 648531 times.
✓ Branch 1 taken 68317 times.
716848 for (int i = 0; i < FF_ARRAY_ELEMS(nbs); i++) {
678 648531 NeighbourIdx nb = nbs[i][0];
679 648531 NeighbourIdx old = nbs[i][1];
680 648531 cand = nb_list[nb] = MV_MERGE_FROM_NB(nb);
681
4/4
✓ Branch 0 taken 511344 times.
✓ Branch 1 taken 137187 times.
✓ Branch 3 taken 462802 times.
✓ Branch 4 taken 48542 times.
648531 if (cand && !compare_mv_ref_idx(cand, nb_list[old])) {
682 462802 cand_list[num_cands] = *cand;
683
2/2
✓ Branch 0 taken 256606 times.
✓ Branch 1 taken 206196 times.
462802 if (merge_idx == num_cands)
684 256606 return 1;
685 206196 num_cands++;
686 }
687 }
688
2/2
✓ Branch 0 taken 67630 times.
✓ Branch 1 taken 687 times.
68317 if (num_cands != 4) {
689 67630 cand = MV_MERGE_FROM_NB(B2);
690
4/4
✓ Branch 0 taken 53189 times.
✓ Branch 1 taken 14441 times.
✓ Branch 3 taken 32216 times.
✓ Branch 4 taken 20973 times.
67630 if (cand && !compare_mv_ref_idx(cand, nb_list[A1])
691
2/2
✓ Branch 1 taken 22671 times.
✓ Branch 2 taken 9545 times.
32216 && !compare_mv_ref_idx(cand, nb_list[B1])) {
692 22671 cand_list[num_cands] = *cand;
693
2/2
✓ Branch 0 taken 10164 times.
✓ Branch 1 taken 12507 times.
22671 if (merge_idx == num_cands)
694 10164 return 1;
695 12507 num_cands++;
696 }
697 }
698 58153 *nb_merge_cand = num_cands;
699 58153 return 0;
700 }
701
702 58153 static int mv_merge_temporal_candidate(const VVCLocalContext *lc, MvField *cand)
703 {
704 58153 const VVCFrameContext *fc = lc->fc;
705 58153 const CodingUnit *cu = lc->cu;
706
707 58153 memset(cand, 0, sizeof(*cand));
708
4/4
✓ Branch 0 taken 58006 times.
✓ Branch 1 taken 147 times.
✓ Branch 2 taken 54207 times.
✓ Branch 3 taken 3799 times.
58153 if (fc->ps.ph.r->ph_temporal_mvp_enabled_flag && (cu->cb_width * cu->cb_height > 32)) {
709 54207 int available_l0 = temporal_luma_motion_vector(lc, 0, cand->mv + 0, 0, 1, 0);
710 108414 int available_l1 = IS_B(lc->sc->sh.r) ?
711
2/2
✓ Branch 0 taken 51418 times.
✓ Branch 1 taken 2789 times.
54207 temporal_luma_motion_vector(lc, 0, cand->mv + 1, 1, 1, 0) : 0;
712 54207 cand->pred_flag = available_l0 + (available_l1 << 1);
713 }
714 58153 return cand->pred_flag;
715 }
716
717 //8.5.2.6 Derivation process for history-based merging candidates
718 37069 static int mv_merge_history_candidates(const VVCLocalContext *lc, const int merge_idx,
719 const MvField **nb_list, MvField *cand_list, int *num_cands)
720 {
721 37069 const VVCSPS *sps = lc->fc->ps.sps;
722 37069 const EntryPoint* ep = lc->ep;
723
4/4
✓ Branch 0 taken 94908 times.
✓ Branch 1 taken 2779 times.
✓ Branch 2 taken 86096 times.
✓ Branch 3 taken 8812 times.
97687 for (int i = 1; i <= ep->num_hmvp && (*num_cands < sps->max_num_merge_cand - 1); i++) {
724 86096 const MvField *h = &ep->hmvp[ep->num_hmvp - i];
725
6/6
✓ Branch 0 taken 63271 times.
✓ Branch 1 taken 22825 times.
✓ Branch 3 taken 43601 times.
✓ Branch 4 taken 19670 times.
✓ Branch 6 taken 10824 times.
✓ Branch 7 taken 32777 times.
86096 const int same_motion = i <= 2 && (compare_mv_ref_idx(h, nb_list[A1]) || compare_mv_ref_idx(h, nb_list[B1]));
726
2/2
✓ Branch 0 taken 55602 times.
✓ Branch 1 taken 30494 times.
86096 if (!same_motion) {
727 55602 cand_list[*num_cands] = *h;
728
2/2
✓ Branch 0 taken 25478 times.
✓ Branch 1 taken 30124 times.
55602 if (merge_idx == *num_cands)
729 25478 return 1;
730 30124 (*num_cands)++;
731 }
732 }
733 11591 return 0;
734 }
735
736 //8.5.2.4 Derivation process for pairwise average merging candidate
737 11591 static int mv_merge_pairwise_candidate(MvField *cand_list, const int num_cands, const int is_b)
738 {
739
2/2
✓ Branch 0 taken 10783 times.
✓ Branch 1 taken 808 times.
11591 if (num_cands > 1) {
740
2/2
✓ Branch 0 taken 10259 times.
✓ Branch 1 taken 524 times.
10783 const int num_ref_rists = is_b ? 2 : 1;
741 10783 const MvField* p0 = cand_list + 0;
742 10783 const MvField* p1 = cand_list + 1;
743 10783 MvField* cand = cand_list + num_cands;
744
745 10783 cand->pred_flag = 0;
746
2/2
✓ Branch 0 taken 21042 times.
✓ Branch 1 taken 10783 times.
31825 for (int i = 0; i < num_ref_rists; i++) {
747 21042 PredFlag mask = i + 1;
748
2/2
✓ Branch 0 taken 17251 times.
✓ Branch 1 taken 3791 times.
21042 if (p0->pred_flag & mask) {
749 17251 cand->pred_flag |= mask;
750 17251 cand->ref_idx[i] = p0->ref_idx[i];
751
2/2
✓ Branch 0 taken 15285 times.
✓ Branch 1 taken 1966 times.
17251 if (p1->pred_flag & mask) {
752 15285 Mv *mv = cand->mv + i;
753 15285 mv->x = p0->mv[i].x + p1->mv[i].x;
754 15285 mv->y = p0->mv[i].y + p1->mv[i].y;
755 15285 ff_vvc_round_mv(mv, 0, 1);
756 } else {
757 1966 cand->mv[i] = p0->mv[i];
758 }
759
2/2
✓ Branch 0 taken 2253 times.
✓ Branch 1 taken 1538 times.
3791 } else if (p1->pred_flag & mask) {
760 2253 cand->pred_flag |= mask;
761 2253 cand->mv[i] = p1->mv[i];
762 2253 cand->ref_idx[i] = p1->ref_idx[i];
763 }
764 }
765
1/2
✓ Branch 0 taken 10783 times.
✗ Branch 1 not taken.
10783 if (cand->pred_flag) {
766
2/2
✓ Branch 0 taken 10014 times.
✓ Branch 1 taken 769 times.
10783 cand->hpel_if_idx = p0->hpel_if_idx == p1->hpel_if_idx ? p0->hpel_if_idx : 0;
767 10783 cand->bcw_idx = 0;
768 10783 cand->ciip_flag = 0;
769 10783 return 1;
770 }
771 }
772 808 return 0;
773 }
774
775 //8.5.2.5 Derivation process for zero motion vector merging candidates
776 1381 static void mv_merge_zero_motion_candidate(const VVCLocalContext *lc, const int merge_idx,
777 MvField *cand_list, int num_cands)
778 {
779 1381 const VVCSPS *sps = lc->fc->ps.sps;
780 1381 const H266RawSliceHeader *rsh = lc->sc->sh.r;
781 2762 const int num_ref_idx = IS_P(rsh) ?
782
2/2
✓ Branch 0 taken 210 times.
✓ Branch 1 taken 1171 times.
1381 rsh->num_ref_idx_active[L0] : FFMIN(rsh->num_ref_idx_active[L0], rsh->num_ref_idx_active[L1]);
783 1381 int zero_idx = 0;
784
785
1/2
✓ Branch 0 taken 2772 times.
✗ Branch 1 not taken.
2772 while (num_cands < sps->max_num_merge_cand) {
786 2772 MvField *cand = cand_list + num_cands;
787
788
2/2
✓ Branch 0 taken 2335 times.
✓ Branch 1 taken 437 times.
2772 cand->pred_flag = PF_L0 + (IS_B(rsh) << 1);
789 2772 AV_ZERO64(cand->mv + 0);
790 2772 AV_ZERO64(cand->mv + 1);
791
2/2
✓ Branch 0 taken 2539 times.
✓ Branch 1 taken 233 times.
2772 cand->ref_idx[0] = zero_idx < num_ref_idx ? zero_idx : 0;
792
2/2
✓ Branch 0 taken 2539 times.
✓ Branch 1 taken 233 times.
2772 cand->ref_idx[1] = zero_idx < num_ref_idx ? zero_idx : 0;
793 2772 cand->bcw_idx = 0;
794 2772 cand->hpel_if_idx = 0;
795
2/2
✓ Branch 0 taken 1381 times.
✓ Branch 1 taken 1391 times.
2772 if (merge_idx == num_cands)
796 1381 return;
797 1391 num_cands++;
798 1391 zero_idx++;
799 }
800 }
801
802 324923 static void mv_merge_mode(const VVCLocalContext *lc, const int merge_idx, MvField *cand_list)
803 {
804 324923 int num_cands = 0;
805 324923 const MvField *nb_list[NUM_NBS + 1] = { NULL };
806
807
2/2
✓ Branch 1 taken 266770 times.
✓ Branch 2 taken 58153 times.
324923 if (mv_merge_spatial_candidates(lc, merge_idx, nb_list, cand_list, &num_cands))
808 323542 return;
809
810
2/2
✓ Branch 1 taken 44181 times.
✓ Branch 2 taken 13972 times.
58153 if (mv_merge_temporal_candidate(lc, &cand_list[num_cands])) {
811
2/2
✓ Branch 0 taken 21084 times.
✓ Branch 1 taken 23097 times.
44181 if (merge_idx == num_cands)
812 21084 return;
813 23097 num_cands++;
814 }
815
816
2/2
✓ Branch 1 taken 25478 times.
✓ Branch 2 taken 11591 times.
37069 if (mv_merge_history_candidates(lc, merge_idx, nb_list, cand_list, &num_cands))
817 25478 return;
818
819
2/2
✓ Branch 1 taken 10783 times.
✓ Branch 2 taken 808 times.
11591 if (mv_merge_pairwise_candidate(cand_list, num_cands, IS_B(lc->sc->sh.r))) {
820
2/2
✓ Branch 0 taken 10210 times.
✓ Branch 1 taken 573 times.
10783 if (merge_idx == num_cands)
821 10210 return;
822 573 num_cands++;
823 }
824
825 1381 mv_merge_zero_motion_candidate(lc, merge_idx, cand_list, num_cands);
826 }
827
828 //8.5.2.2 Derivation process for luma motion vectors for merge mode
829 297332 void ff_vvc_luma_mv_merge_mode(VVCLocalContext *lc, const int merge_idx, const int ciip_flag, MvField *mv)
830 {
831 297332 const CodingUnit *cu = lc->cu;
832 MvField cand_list[MRG_MAX_NUM_CANDS];
833
834 297332 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
835 297332 mv_merge_mode(lc, merge_idx, cand_list);
836 297332 *mv = cand_list[merge_idx];
837 //ciip flag in not inhritable
838 297332 mv->ciip_flag = ciip_flag;
839 297332 }
840
841 //8.5.4.2 Derivation process for luma motion vectors for geometric partitioning merge mode
842 27591 void ff_vvc_luma_mv_merge_gpm(VVCLocalContext *lc, const int merge_gpm_idx[2], MvField *mv)
843 {
844 27591 const CodingUnit *cu = lc->cu;
845 MvField cand_list[MRG_MAX_NUM_CANDS];
846
847 27591 const int idx[] = { merge_gpm_idx[0], merge_gpm_idx[1] + (merge_gpm_idx[1] >= merge_gpm_idx[0]) };
848
849 27591 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
850 27591 mv_merge_mode(lc, FFMAX(idx[0], idx[1]), cand_list);
851 27591 memset(mv, 0, 2 * sizeof(*mv));
852
2/2
✓ Branch 0 taken 55182 times.
✓ Branch 1 taken 27591 times.
82773 for (int i = 0; i < 2; i++) {
853 55182 int lx = idx[i] & 1;
854 55182 int mask = lx + PF_L0;
855 55182 MvField *cand = cand_list + idx[i];
856
2/2
✓ Branch 0 taken 15183 times.
✓ Branch 1 taken 39999 times.
55182 if (!(cand->pred_flag & mask)) {
857 15183 lx = !lx;
858 15183 mask = lx + PF_L0;
859 }
860 55182 mv[i].pred_flag = mask;
861 55182 mv[i].ref_idx[lx] = cand->ref_idx[lx];
862 55182 mv[i].mv[lx] = cand->mv[lx];
863 }
864
865 27591 }
866
867 //8.5.5.5 Derivation process for luma affine control point motion vectors from a neighbouring block
868 30529 static void affine_cps_from_nb(const VVCLocalContext *lc,
869 const int x_nb, int y_nb, const int nbw, const int nbh, const int lx,
870 Mv *cps, int num_cps)
871 {
872 30529 const VVCFrameContext *fc = lc->fc;
873 30529 const CodingUnit *cu = lc->cu;
874 30529 const int x0 = cu->x0;
875 30529 const int y0 = cu->y0;
876 30529 const int cb_width = cu->cb_width;
877 30529 const int cb_height = cu->cb_height;
878 30529 const MvField* tab_mvf = fc->tab.mvf;
879 30529 const int min_cb_log2_size = fc->ps.sps->min_cb_log2_size_y;
880 30529 const int min_cb_width = fc->ps.pps->min_cb_width;
881
882 30529 const int log2_nbw = ff_log2(nbw);
883 30529 const int log2_nbh = ff_log2(nbh);
884
4/4
✓ Branch 0 taken 9069 times.
✓ Branch 1 taken 21460 times.
✓ Branch 2 taken 3464 times.
✓ Branch 3 taken 5605 times.
30529 const int is_ctb_boundary = !((y_nb + nbh) % fc->ps.sps->ctb_size_y) && (y_nb + nbh == y0);
885 const Mv *l, *r;
886 int mv_scale_hor, mv_scale_ver, d_hor_x, d_ver_x, d_hor_y, d_ver_y, motion_model_idc_nb;
887
2/2
✓ Branch 0 taken 3464 times.
✓ Branch 1 taken 27065 times.
30529 if (is_ctb_boundary) {
888 3464 const int min_pu_width = fc->ps.pps->min_pu_width;
889 3464 l = &TAB_MVF(x_nb, y_nb + nbh - 1).mv[lx];
890 3464 r = &TAB_MVF(x_nb + nbw - 1, y_nb + nbh - 1).mv[lx];
891 } else {
892 27065 const int x = x_nb >> min_cb_log2_size;
893 27065 const int y = y_nb >> min_cb_log2_size;
894 27065 motion_model_idc_nb = SAMPLE_CTB(fc->tab.mmi, x, y);
895
896 27065 l = &TAB_CP_MV(lx, x_nb, y_nb);
897 27065 r = &TAB_CP_MV(lx, x_nb + nbw - 1, y_nb) + 1;
898 }
899 30529 mv_scale_hor = l->x * (1 << 7);
900 30529 mv_scale_ver = l->y * (1 << 7);
901 30529 d_hor_x = (r->x - l->x) * (1 << (7 - log2_nbw));
902 30529 d_ver_x = (r->y - l->y) * (1 << (7 - log2_nbw));
903
4/4
✓ Branch 0 taken 27065 times.
✓ Branch 1 taken 3464 times.
✓ Branch 2 taken 15176 times.
✓ Branch 3 taken 11889 times.
30529 if (!is_ctb_boundary && motion_model_idc_nb == MOTION_6_PARAMS_AFFINE) {
904 15176 const Mv* lb = &TAB_CP_MV(lx, x_nb, y_nb + nbh - 1) + 2;
905 15176 d_hor_y = (lb->x - l->x) * (1 << (7 - log2_nbh));
906 15176 d_ver_y = (lb->y - l->y) * (1 << (7 - log2_nbh));
907 } else {
908 15353 d_hor_y = -d_ver_x;
909 15353 d_ver_y = d_hor_x;
910 }
911
912
2/2
✓ Branch 0 taken 3464 times.
✓ Branch 1 taken 27065 times.
30529 if (is_ctb_boundary) {
913 3464 y_nb = y0;
914 }
915 30529 cps[0].x = mv_scale_hor + d_hor_x * (x0 - x_nb) + d_hor_y * (y0 - y_nb);
916 30529 cps[0].y = mv_scale_ver + d_ver_x * (x0 - x_nb) + d_ver_y * (y0 - y_nb);
917 30529 cps[1].x = mv_scale_hor + d_hor_x * (x0 + cb_width - x_nb) + d_hor_y * (y0 - y_nb);
918 30529 cps[1].y = mv_scale_ver + d_ver_x * (x0 + cb_width - x_nb) + d_ver_y * (y0 - y_nb);
919
2/2
✓ Branch 0 taken 16740 times.
✓ Branch 1 taken 13789 times.
30529 if (num_cps == 3) {
920 16740 cps[2].x = mv_scale_hor + d_hor_x * (x0 - x_nb) + d_hor_y * (y0 + cb_height - y_nb);
921 16740 cps[2].y = mv_scale_ver + d_ver_x * (x0 - x_nb) + d_ver_y * (y0 + cb_height - y_nb);
922 }
923
2/2
✓ Branch 0 taken 77798 times.
✓ Branch 1 taken 30529 times.
108327 for (int i = 0; i < num_cps; i++) {
924 77798 ff_vvc_round_mv(cps + i, 0, 7);
925 77798 ff_vvc_clip_mv(cps + i);
926 }
927 30529 }
928
929 //derive affine neighbour's position, width and height,
930 96279 static int affine_neighbour_cb(const VVCFrameContext *fc, const int x_nb, const int y_nb, int *x_cb, int *y_cb, int *cbw, int *cbh)
931 {
932 96279 const int log2_min_cb_size = fc->ps.sps->min_cb_log2_size_y;
933 96279 const int min_cb_width = fc->ps.pps->min_cb_width;
934 96279 const int x = x_nb >> log2_min_cb_size;
935 96279 const int y = y_nb >> log2_min_cb_size;
936 96279 const int motion_model_idc = SAMPLE_CTB(fc->tab.mmi, x, y);
937
2/2
✓ Branch 0 taken 27227 times.
✓ Branch 1 taken 69052 times.
96279 if (motion_model_idc) {
938 27227 *x_cb = SAMPLE_CTB(fc->tab.cb_pos_x[0], x, y);
939 27227 *y_cb = SAMPLE_CTB(fc->tab.cb_pos_y[0], x, y);
940 27227 *cbw = SAMPLE_CTB(fc->tab.cb_width[0], x, y);
941 27227 *cbh = SAMPLE_CTB(fc->tab.cb_height[0], x, y);
942 }
943 96279 return motion_model_idc;
944 }
945
946 //part of 8.5.5.2 Derivation process for motion vectors and reference indices in subblock merge mode
947 65575 static int affine_merge_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand, MotionInfo* mi)
948 {
949 65575 const VVCFrameContext *fc = lc->fc;
950 int x, y, w, h, motion_model_idc;
951
952 65575 motion_model_idc = affine_neighbour_cb(fc, x_cand, y_cand, &x, &y, &w, &h);
953
2/2
✓ Branch 0 taken 19540 times.
✓ Branch 1 taken 46035 times.
65575 if (motion_model_idc) {
954 19540 const int min_pu_width = fc->ps.pps->min_pu_width;
955 19540 const MvField* tab_mvf = fc->tab.mvf;
956 19540 const MvField *mvf = &TAB_MVF(x, y);
957
958 19540 mi->bcw_idx = mvf->bcw_idx;
959 19540 mi->pred_flag = mvf->pred_flag;
960
2/2
✓ Branch 0 taken 39080 times.
✓ Branch 1 taken 19540 times.
58620 for (int i = 0; i < 2; i++) {
961 39080 PredFlag mask = i + 1;
962
2/2
✓ Branch 0 taken 24491 times.
✓ Branch 1 taken 14589 times.
39080 if (mi->pred_flag & mask) {
963 24491 affine_cps_from_nb(lc, x, y, w, h, i, &mi->mv[i][0], motion_model_idc + 1);
964 }
965 39080 mi->ref_idx[i] = mvf->ref_idx[i];
966 }
967 19540 mi->motion_model_idc = motion_model_idc;
968 }
969 65575 return motion_model_idc;
970 }
971
972 45834 static int affine_merge_from_nbs(NeighbourContext *ctx, const NeighbourIdx *nbs, const int num_nbs, MotionInfo* cand)
973 {
974 45834 const VVCLocalContext *lc = ctx->lc;
975
2/2
✓ Branch 0 taken 96548 times.
✓ Branch 1 taken 26294 times.
122842 for (int i = 0; i < num_nbs; i++) {
976 96548 Neighbour *n = &ctx->neighbours[nbs[i]];
977
4/4
✓ Branch 1 taken 65575 times.
✓ Branch 2 taken 30973 times.
✓ Branch 4 taken 19540 times.
✓ Branch 5 taken 46035 times.
96548 if (check_available(n, lc, 1) && affine_merge_candidate(lc, n->x, n->y, cand))
978 19540 return 1;
979 }
980 26294 return 0;
981 }
982 #define AFFINE_MERGE_FROM_NBS(nbs) affine_merge_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), mi)
983
984
985 101312 static const MvField* derive_corner_mvf(NeighbourContext *ctx, const NeighbourIdx *neighbour, const int num_neighbour)
986 {
987 101312 const VVCFrameContext *fc = ctx->lc->fc;
988 101312 const MvField *tab_mvf = fc->tab.mvf;
989 101312 const int min_pu_width = fc->ps.pps->min_pu_width;
990
2/2
✓ Branch 0 taken 107959 times.
✓ Branch 1 taken 7529 times.
115488 for (int i = 0; i < num_neighbour; i++) {
991 107959 Neighbour *n = &ctx->neighbours[neighbour[i]];
992
2/2
✓ Branch 1 taken 93783 times.
✓ Branch 2 taken 14176 times.
107959 if (check_available(n, ctx->lc, 1)) {
993 93783 return &TAB_MVF(n->x, n->y);
994 }
995 }
996 7529 return NULL;
997 }
998
999 #define DERIVE_CORNER_MV(nbs) derive_corner_mvf(nctx, nbs, FF_ARRAY_ELEMS(nbs))
1000
1001 // check if the mv's and refidx are the same between A and B
1002 53520 static av_always_inline int compare_pf_ref_idx(const MvField *A, const struct MvField *B, const struct MvField *C, const int lx)
1003 {
1004
1005 53520 const PredFlag mask = (lx + 1) & A->pred_flag;
1006
2/2
✓ Branch 0 taken 18975 times.
✓ Branch 1 taken 34545 times.
53520 if (!(B->pred_flag & mask))
1007 18975 return 0;
1008
2/2
✓ Branch 0 taken 1763 times.
✓ Branch 1 taken 32782 times.
34545 if (A->ref_idx[lx] != B->ref_idx[lx])
1009 1763 return 0;
1010
2/2
✓ Branch 0 taken 27134 times.
✓ Branch 1 taken 5648 times.
32782 if (C) {
1011
2/2
✓ Branch 0 taken 941 times.
✓ Branch 1 taken 26193 times.
27134 if (!(C->pred_flag & mask))
1012 941 return 0;
1013
2/2
✓ Branch 0 taken 1083 times.
✓ Branch 1 taken 25110 times.
26193 if (A->ref_idx[lx] != C->ref_idx[lx])
1014 1083 return 0;
1015 }
1016 30758 return 1;
1017 }
1018
1019 1569976 static av_always_inline void sb_clip_location(const VVCLocalContext *lc,
1020 const int x_ctb, const int y_ctb, const Mv* temp_mv, int *x, int *y)
1021 {
1022 1569976 const VVCFrameContext *fc = lc->fc;
1023 1569976 const VVCPPS *pps = fc->ps.pps;
1024 1569976 const int ctb_log2_size = fc->ps.sps->ctb_log2_size_y;
1025 1569976 const int subpic_idx = lc->sc->sh.r->curr_subpic_idx;
1026 1569976 const int x_end = pps->subpic_x[subpic_idx] + pps->subpic_width[subpic_idx];
1027 1569976 const int y_end = pps->subpic_y[subpic_idx] + pps->subpic_height[subpic_idx];
1028
1029 1569976 *x = av_clip(*x + temp_mv->x, x_ctb, FFMIN(x_end - 1, x_ctb + (1 << ctb_log2_size) + 3)) & ~7;
1030
2/2
✓ Branch 0 taken 1386025 times.
✓ Branch 1 taken 183951 times.
1569976 *y = av_clip(*y + temp_mv->y, y_ctb, FFMIN(y_end - 1, y_ctb + (1 << ctb_log2_size) - 1)) & ~7;
1031 1569976 }
1032
1033 1569976 static void sb_temproal_luma_motion(const VVCLocalContext *lc,
1034 const int x_ctb, const int y_ctb, const Mv *temp_mv,
1035 int x, int y, uint8_t *pred_flag, Mv *mv)
1036 {
1037 MvField temp_col;
1038 Mv* mvLXCol;
1039 1569976 const int refIdxLx = 0;
1040 1569976 const VVCFrameContext *fc = lc->fc;
1041 1569976 const VVCSH *sh = &lc->sc->sh;
1042 1569976 const int min_pu_width = fc->ps.pps->min_pu_width;
1043 1569976 VVCFrame *ref = fc->ref->collocated_ref;
1044 1569976 MvField *tab_mvf = ref->tab_dmvr_mvf;
1045 1569976 int colPic = ref->poc;
1046 1569976 int X = 0;
1047
1048 1569976 sb_clip_location(lc, x_ctb, y_ctb, temp_mv, &x, &y);
1049
1050 1569976 temp_col = TAB_MVF(x, y);
1051 1569976 mvLXCol = mv + 0;
1052 1569976 *pred_flag = DERIVE_TEMPORAL_COLOCATED_MVS(1);
1053
2/2
✓ Branch 0 taken 1223028 times.
✓ Branch 1 taken 346948 times.
1569976 if (IS_B(sh->r)) {
1054 1223028 X = 1;
1055 1223028 mvLXCol = mv + 1;
1056 1223028 *pred_flag |= (DERIVE_TEMPORAL_COLOCATED_MVS(1)) << 1;
1057 }
1058 1569976 }
1059
1060 //8.5.5.4 Derivation process for subblock-based temporal merging base motion data
1061 54374 static int sb_temporal_luma_motion_data(const VVCLocalContext *lc, const MvField *a1,
1062 const int x_ctb, const int y_ctb, MvField *ctr_mvf, Mv *temp_mv)
1063 {
1064 54374 const VVCFrameContext *fc = lc->fc;
1065 54374 const RefPicList *rpl = lc->sc->rpl;
1066 54374 const CodingUnit *cu = lc->cu;
1067 54374 const int x = cu->x0 + cu->cb_width / 2;
1068 54374 const int y = cu->y0 + cu->cb_height / 2;
1069 54374 const VVCFrame *ref = fc->ref->collocated_ref;
1070
1071 int colPic;
1072
1073 54374 memset(temp_mv, 0, sizeof(*temp_mv));
1074
1075
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54374 times.
54374 if (!ref) {
1076 memset(ctr_mvf, 0, sizeof(*ctr_mvf));
1077 return 0;
1078 }
1079
1080 54374 colPic = ref->poc;
1081
1082
2/2
✓ Branch 0 taken 50698 times.
✓ Branch 1 taken 3676 times.
54374 if (a1) {
1083
4/4
✓ Branch 0 taken 45811 times.
✓ Branch 1 taken 4887 times.
✓ Branch 2 taken 30778 times.
✓ Branch 3 taken 15033 times.
50698 if ((a1->pred_flag & PF_L0) && colPic == rpl[L0].refs[a1->ref_idx[L0]].poc)
1084 30778 *temp_mv = a1->mv[0];
1085
4/4
✓ Branch 0 taken 14068 times.
✓ Branch 1 taken 5852 times.
✓ Branch 2 taken 11218 times.
✓ Branch 3 taken 2850 times.
19920 else if ((a1->pred_flag & PF_L1) && colPic == rpl[L1].refs[a1->ref_idx[L1]].poc)
1086 11218 *temp_mv = a1->mv[1];
1087 50698 ff_vvc_round_mv(temp_mv, 0, 4);
1088 }
1089 54374 sb_temproal_luma_motion(lc, x_ctb, y_ctb, temp_mv, x, y, &ctr_mvf->pred_flag , ctr_mvf->mv);
1090
1091 54374 return ctr_mvf->pred_flag;
1092 }
1093
1094
1095 //8.5.5.3 Derivation process for subblock-based temporal merging candidates
1096 54562 static int sb_temporal_merge_candidate(const VVCLocalContext* lc, NeighbourContext *nctx, PredictionUnit *pu)
1097 {
1098 54562 const VVCFrameContext *fc = lc->fc;
1099 54562 const CodingUnit *cu = lc->cu;
1100 54562 const VVCSPS *sps = fc->ps.sps;
1101 54562 const VVCPH *ph = &fc->ps.ph;
1102 54562 MotionInfo *mi = &pu->mi;
1103 54562 const int ctb_log2_size = sps->ctb_log2_size_y;
1104 54562 const int x0 = cu->x0;
1105 54562 const int y0 = cu->y0;
1106 54562 const NeighbourIdx n = A1;
1107 const MvField *a1;
1108 MvField ctr_mvf;
1109 54562 LOCAL_ALIGNED_8(Mv, temp_mv, [1]);
1110 54562 const int x_ctb = (x0 >> ctb_log2_size) << ctb_log2_size;
1111 54562 const int y_ctb = (y0 >> ctb_log2_size) << ctb_log2_size;
1112
1113
1114
2/2
✓ Branch 0 taken 54475 times.
✓ Branch 1 taken 87 times.
54562 if (!ph->r->ph_temporal_mvp_enabled_flag ||
1115
2/2
✓ Branch 0 taken 54374 times.
✓ Branch 1 taken 101 times.
54475 !sps->r->sps_sbtmvp_enabled_flag ||
1116
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 54374 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
54374 (cu->cb_width < 8 && cu->cb_height < 8))
1117 188 return 0;
1118
1119 54374 mi->num_sb_x = cu->cb_width >> 3;
1120 54374 mi->num_sb_y = cu->cb_height >> 3;
1121
1122 54374 a1 = derive_corner_mvf(nctx, &n, 1);
1123
2/2
✓ Branch 1 taken 45965 times.
✓ Branch 2 taken 8409 times.
54374 if (sb_temporal_luma_motion_data(lc, a1, x_ctb, y_ctb, &ctr_mvf, temp_mv)) {
1124 45965 const int sbw = cu->cb_width / mi->num_sb_x;
1125 45965 const int sbh = cu->cb_height / mi->num_sb_y;
1126 45965 MvField mvf = {0};
1127
2/2
✓ Branch 0 taken 199371 times.
✓ Branch 1 taken 45965 times.
245336 for (int sby = 0; sby < mi->num_sb_y; sby++) {
1128
2/2
✓ Branch 0 taken 1515602 times.
✓ Branch 1 taken 199371 times.
1714973 for (int sbx = 0; sbx < mi->num_sb_x; sbx++) {
1129 1515602 int x = x0 + sbx * sbw;
1130 1515602 int y = y0 + sby * sbh;
1131 1515602 sb_temproal_luma_motion(lc, x_ctb, y_ctb, temp_mv, x + sbw / 2, y + sbh / 2, &mvf.pred_flag, mvf.mv);
1132
2/2
✓ Branch 0 taken 8588 times.
✓ Branch 1 taken 1507014 times.
1515602 if (!mvf.pred_flag) {
1133 8588 mvf.pred_flag = ctr_mvf.pred_flag;
1134 8588 memcpy(mvf.mv, ctr_mvf.mv, sizeof(mvf.mv));
1135 }
1136 1515602 ff_vvc_set_mvf(lc, x, y, sbw, sbh, &mvf);
1137 }
1138 }
1139 45965 return 1;
1140 }
1141 8409 return 0;
1142 }
1143
1144 14380 static int affine_merge_const1(const MvField *c0, const MvField *c1, const MvField *c2, MotionInfo *mi)
1145 {
1146
6/6
✓ Branch 0 taken 14307 times.
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 13627 times.
✓ Branch 3 taken 680 times.
✓ Branch 4 taken 13105 times.
✓ Branch 5 taken 522 times.
14380 if (c0 && c1 && c2) {
1147 13105 mi->pred_flag = 0;
1148
2/2
✓ Branch 0 taken 26210 times.
✓ Branch 1 taken 13105 times.
39315 for (int i = 0; i < 2; i++) {
1149 26210 PredFlag mask = i + 1;
1150
2/2
✓ Branch 1 taken 15429 times.
✓ Branch 2 taken 10781 times.
26210 if (compare_pf_ref_idx(c0, c1, c2, i)) {
1151 15429 mi->pred_flag |= mask;
1152 15429 mi->ref_idx[i] = c0->ref_idx[i];
1153 15429 mi->mv[i][0] = c0->mv[i];
1154 15429 mi->mv[i][1] = c1->mv[i];
1155 15429 mi->mv[i][2] = c2->mv[i];
1156 }
1157 }
1158
2/2
✓ Branch 0 taken 12106 times.
✓ Branch 1 taken 999 times.
13105 if (mi->pred_flag) {
1159
2/2
✓ Branch 0 taken 3323 times.
✓ Branch 1 taken 8783 times.
12106 if (mi->pred_flag == PF_BI)
1160 3323 mi->bcw_idx = c0->bcw_idx;
1161 12106 mi->motion_model_idc = MOTION_6_PARAMS_AFFINE;
1162 12106 return 1;
1163 }
1164 }
1165 2274 return 0;
1166 }
1167
1168 7650 static int affine_merge_const2(const MvField *c0, const MvField *c1, const MvField *c3, MotionInfo *mi)
1169 {
1170
6/6
✓ Branch 0 taken 7577 times.
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 6897 times.
✓ Branch 3 taken 680 times.
✓ Branch 4 taken 4656 times.
✓ Branch 5 taken 2241 times.
7650 if (c0 && c1 && c3) {
1171 4656 mi->pred_flag = 0;
1172
2/2
✓ Branch 0 taken 9312 times.
✓ Branch 1 taken 4656 times.
13968 for (int i = 0; i < 2; i++) {
1173 9312 PredFlag mask = i + 1;
1174
2/2
✓ Branch 1 taken 5464 times.
✓ Branch 2 taken 3848 times.
9312 if (compare_pf_ref_idx(c0, c1, c3, i)) {
1175 5464 mi->pred_flag |= mask;
1176 5464 mi->ref_idx[i] = c0->ref_idx[i];
1177 5464 mi->mv[i][0] = c0->mv[i];
1178 5464 mi->mv[i][1] = c1->mv[i];
1179 5464 mi->mv[i][2].x = c3->mv[i].x + c0->mv[i].x - c1->mv[i].x;
1180 5464 mi->mv[i][2].y = c3->mv[i].y + c0->mv[i].y - c1->mv[i].y;
1181 5464 ff_vvc_clip_mv(&mi->mv[i][2]);
1182 }
1183 }
1184
2/2
✓ Branch 0 taken 4056 times.
✓ Branch 1 taken 600 times.
4656 if (mi->pred_flag) {
1185
2/2
✓ Branch 0 taken 1408 times.
✓ Branch 1 taken 2648 times.
4056 mi->bcw_idx = mi->pred_flag == PF_BI ? c0->bcw_idx : 0;
1186 4056 mi->motion_model_idc = MOTION_6_PARAMS_AFFINE;
1187 4056 return 1;
1188 }
1189 }
1190 3594 return 0;
1191 }
1192
1193 5525 static int affine_merge_const3(const MvField *c0, const MvField *c2, const MvField *c3, MotionInfo *mi)
1194 {
1195
6/6
✓ Branch 0 taken 5452 times.
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 5118 times.
✓ Branch 3 taken 334 times.
✓ Branch 4 taken 2877 times.
✓ Branch 5 taken 2241 times.
5525 if (c0 && c2 && c3) {
1196 2877 mi->pred_flag = 0;
1197
2/2
✓ Branch 0 taken 5754 times.
✓ Branch 1 taken 2877 times.
8631 for (int i = 0; i < 2; i++) {
1198 5754 PredFlag mask = i + 1;
1199
2/2
✓ Branch 1 taken 3288 times.
✓ Branch 2 taken 2466 times.
5754 if (compare_pf_ref_idx(c0, c2, c3, i)) {
1200 3288 mi->pred_flag |= mask;
1201 3288 mi->ref_idx[i] = c0->ref_idx[i];
1202 3288 mi->mv[i][0] = c0->mv[i];
1203 3288 mi->mv[i][1].x = c3->mv[i].x + c0->mv[i].x - c2->mv[i].x;
1204 3288 mi->mv[i][1].y = c3->mv[i].y + c0->mv[i].y - c2->mv[i].y;
1205 3288 ff_vvc_clip_mv(&mi->mv[i][1]);
1206 3288 mi->mv[i][2] = c2->mv[i];
1207 }
1208 }
1209
2/2
✓ Branch 0 taken 2427 times.
✓ Branch 1 taken 450 times.
2877 if (mi->pred_flag) {
1210
2/2
✓ Branch 0 taken 861 times.
✓ Branch 1 taken 1566 times.
2427 mi->bcw_idx = mi->pred_flag == PF_BI ? c0->bcw_idx : 0;
1211 2427 mi->motion_model_idc = MOTION_6_PARAMS_AFFINE;
1212 2427 return 1;
1213 }
1214 }
1215 3098 return 0;
1216 }
1217
1218 3890 static int affine_merge_const4(const MvField *c1, const MvField *c2, const MvField *c3, MotionInfo *mi)
1219 {
1220
6/6
✓ Branch 0 taken 3442 times.
✓ Branch 1 taken 448 times.
✓ Branch 2 taken 3116 times.
✓ Branch 3 taken 326 times.
✓ Branch 4 taken 1105 times.
✓ Branch 5 taken 2011 times.
3890 if (c1 && c2 && c3) {
1221 1105 mi->pred_flag = 0;
1222
2/2
✓ Branch 0 taken 2210 times.
✓ Branch 1 taken 1105 times.
3315 for (int i = 0; i < 2; i++) {
1223 2210 PredFlag mask = i + 1;
1224
2/2
✓ Branch 1 taken 929 times.
✓ Branch 2 taken 1281 times.
2210 if (compare_pf_ref_idx(c1, c2, c3, i)) {
1225 929 mi->pred_flag |= mask;
1226 929 mi->ref_idx[i] = c1->ref_idx[i];
1227 929 mi->mv[i][0].x = c1->mv[i].x + c2->mv[i].x - c3->mv[i].x;
1228 929 mi->mv[i][0].y = c1->mv[i].y + c2->mv[i].y - c3->mv[i].y;
1229 929 ff_vvc_clip_mv(&mi->mv[i][0]);
1230 929 mi->mv[i][1] = c1->mv[i];
1231 929 mi->mv[i][2] = c2->mv[i];
1232 }
1233 }
1234
2/2
✓ Branch 0 taken 685 times.
✓ Branch 1 taken 420 times.
1105 if (mi->pred_flag) {
1235
2/2
✓ Branch 0 taken 244 times.
✓ Branch 1 taken 441 times.
685 mi->bcw_idx = mi->pred_flag == PF_BI ? c1->bcw_idx : 0;
1236 685 mi->motion_model_idc = MOTION_6_PARAMS_AFFINE;
1237 685 return 1;
1238 }
1239 }
1240 3205 return 0;
1241 }
1242
1243 4520 static int affine_merge_const5(const MvField *c0, const MvField *c1, MotionInfo *mi)
1244 {
1245
4/4
✓ Branch 0 taken 3754 times.
✓ Branch 1 taken 766 times.
✓ Branch 2 taken 3120 times.
✓ Branch 3 taken 634 times.
4520 if (c0 && c1) {
1246 3120 mi->pred_flag = 0;
1247
2/2
✓ Branch 0 taken 6240 times.
✓ Branch 1 taken 3120 times.
9360 for (int i = 0; i < 2; i++) {
1248 6240 PredFlag mask = i + 1;
1249
2/2
✓ Branch 1 taken 3449 times.
✓ Branch 2 taken 2791 times.
6240 if (compare_pf_ref_idx(c0, c1, NULL, i)) {
1250 3449 mi->pred_flag |= mask;
1251 3449 mi->ref_idx[i] = c0->ref_idx[i];
1252 3449 mi->mv[i][0] = c0->mv[i];
1253 3449 mi->mv[i][1] = c1->mv[i];
1254 }
1255 }
1256
2/2
✓ Branch 0 taken 2716 times.
✓ Branch 1 taken 404 times.
3120 if (mi->pred_flag) {
1257
2/2
✓ Branch 0 taken 733 times.
✓ Branch 1 taken 1983 times.
2716 if (mi->pred_flag == PF_BI)
1258 733 mi->bcw_idx = c0->bcw_idx;
1259 2716 mi->motion_model_idc = MOTION_4_PARAMS_AFFINE;
1260 2716 return 1;
1261 }
1262 }
1263 1804 return 0;
1264 }
1265
1266 2975 static int affine_merge_const6(const MvField* c0, const MvField* c2, const int cb_width, const int cb_height, MotionInfo *mi)
1267 {
1268
4/4
✓ Branch 0 taken 2209 times.
✓ Branch 1 taken 766 times.
✓ Branch 2 taken 1897 times.
✓ Branch 3 taken 312 times.
2975 if (c0 && c2) {
1269 1897 const int shift = 7 + av_log2(cb_width) - av_log2(cb_height);
1270 1897 mi->pred_flag = 0;
1271
2/2
✓ Branch 0 taken 3794 times.
✓ Branch 1 taken 1897 times.
5691 for (int i = 0; i < 2; i++) {
1272 3794 PredFlag mask = i + 1;
1273
2/2
✓ Branch 1 taken 2199 times.
✓ Branch 2 taken 1595 times.
3794 if (compare_pf_ref_idx(c0, c2, NULL, i)) {
1274 2199 mi->pred_flag |= mask;
1275 2199 mi->ref_idx[i] = c0->ref_idx[i];
1276 2199 mi->mv[i][0] = c0->mv[i];
1277 2199 mi->mv[i][1].x = (c0->mv[i].x * (1 << 7)) + ((c2->mv[i].y - c0->mv[i].y) * (1 << shift));
1278 2199 mi->mv[i][1].y = (c0->mv[i].y * (1 << 7)) - ((c2->mv[i].x - c0->mv[i].x) * (1 << shift));
1279 2199 ff_vvc_round_mv(&mi->mv[i][1], 0, 7);
1280 2199 ff_vvc_clip_mv(&mi->mv[i][1]);
1281 }
1282 }
1283
2/2
✓ Branch 0 taken 1709 times.
✓ Branch 1 taken 188 times.
1897 if (mi->pred_flag) {
1284
2/2
✓ Branch 0 taken 490 times.
✓ Branch 1 taken 1219 times.
1709 if (mi->pred_flag == PF_BI)
1285 490 mi->bcw_idx = c0->bcw_idx;
1286 1709 mi->motion_model_idc = MOTION_4_PARAMS_AFFINE;
1287 1709 return 1;
1288 }
1289 }
1290 1266 return 0;
1291 }
1292
1293 1733 static void affine_merge_zero_motion(const VVCLocalContext *lc, MotionInfo *mi)
1294 {
1295 1733 const CodingUnit *cu = lc->cu;
1296
1297 1733 memset(mi, 0, sizeof(*mi));
1298
2/2
✓ Branch 0 taken 1279 times.
✓ Branch 1 taken 454 times.
1733 mi->pred_flag = PF_L0 + (IS_B(lc->sc->sh.r) << 1);
1299 1733 mi->motion_model_idc = MOTION_4_PARAMS_AFFINE;
1300 1733 mi->num_sb_x = cu->cb_width >> MIN_PU_LOG2;
1301 1733 mi->num_sb_y = cu->cb_height >> MIN_PU_LOG2;
1302 1733 }
1303
1304 //8.5.5.6 Derivation process for constructed affine control point motion vector merging candidates
1305 15646 static int affine_merge_const_candidates(const VVCLocalContext *lc, MotionInfo *mi,
1306 NeighbourContext *nctx, const int merge_subblock_idx, int num_cands)
1307 {
1308 15646 const VVCFrameContext *fc = lc->fc;
1309 15646 const CodingUnit *cu = lc->cu;
1310 15646 const NeighbourIdx tl[] = { B2, B3, A2 };
1311 15646 const NeighbourIdx tr[] = { B1, B0};
1312 15646 const NeighbourIdx bl[] = { A1, A0};
1313 const MvField *c0, *c1, *c2;
1314
1315 15646 c0 = DERIVE_CORNER_MV(tl);
1316 15646 c1 = DERIVE_CORNER_MV(tr);
1317 15646 c2 = DERIVE_CORNER_MV(bl);
1318
1319
2/2
✓ Branch 0 taken 14380 times.
✓ Branch 1 taken 1266 times.
15646 if (fc->ps.sps->r->sps_6param_affine_enabled_flag) {
1320 14380 MvField corner3, *c3 = NULL;
1321 //Const1
1322
2/2
✓ Branch 1 taken 12106 times.
✓ Branch 2 taken 2274 times.
14380 if (affine_merge_const1(c0, c1, c2, mi)) {
1323
2/2
✓ Branch 0 taken 6730 times.
✓ Branch 1 taken 5376 times.
12106 if (merge_subblock_idx == num_cands)
1324 11126 return 1;
1325 5376 num_cands++;
1326 }
1327
1328 7650 memset(&corner3, 0, sizeof(corner3));
1329
2/2
✓ Branch 0 taken 7624 times.
✓ Branch 1 taken 26 times.
7650 if (fc->ps.ph.r->ph_temporal_mvp_enabled_flag){
1330 7624 const int available_l0 = temporal_luma_motion_vector(lc, 0, corner3.mv + 0, 0, 0, 0);
1331 15248 const int available_l1 = (lc->sc->sh.r->sh_slice_type == VVC_SLICE_TYPE_B) ?
1332
2/2
✓ Branch 0 taken 6200 times.
✓ Branch 1 taken 1424 times.
7624 temporal_luma_motion_vector(lc, 0, corner3.mv + 1, 1, 0, 0) : 0;
1333
1334 7624 corner3.pred_flag = available_l0 + (available_l1 << 1);
1335
2/2
✓ Branch 0 taken 5122 times.
✓ Branch 1 taken 2502 times.
7624 if (corner3.pred_flag)
1336 5122 c3 = &corner3;
1337 }
1338
1339 //Const2
1340
2/2
✓ Branch 1 taken 4056 times.
✓ Branch 2 taken 3594 times.
7650 if (affine_merge_const2(c0, c1, c3, mi)) {
1341
2/2
✓ Branch 0 taken 2125 times.
✓ Branch 1 taken 1931 times.
4056 if (merge_subblock_idx == num_cands)
1342 2125 return 1;
1343 1931 num_cands++;
1344 }
1345
1346 //Const3
1347
2/2
✓ Branch 1 taken 2427 times.
✓ Branch 2 taken 3098 times.
5525 if (affine_merge_const3(c0, c2, c3, mi)) {
1348
2/2
✓ Branch 0 taken 1635 times.
✓ Branch 1 taken 792 times.
2427 if (merge_subblock_idx == num_cands)
1349 1635 return 1;
1350 792 num_cands++;
1351 }
1352
1353 //Const4
1354
2/2
✓ Branch 1 taken 685 times.
✓ Branch 2 taken 3205 times.
3890 if (affine_merge_const4(c1, c2, c3, mi)) {
1355
2/2
✓ Branch 0 taken 636 times.
✓ Branch 1 taken 49 times.
685 if (merge_subblock_idx == num_cands)
1356 636 return 1;
1357 49 num_cands++;
1358 }
1359 }
1360
1361 //Const5
1362
2/2
✓ Branch 1 taken 2716 times.
✓ Branch 2 taken 1804 times.
4520 if (affine_merge_const5(c0, c1, mi)) {
1363
2/2
✓ Branch 0 taken 1545 times.
✓ Branch 1 taken 1171 times.
2716 if (merge_subblock_idx == num_cands)
1364 1545 return 1;
1365 1171 num_cands++;
1366 }
1367
1368
2/2
✓ Branch 1 taken 1709 times.
✓ Branch 2 taken 1266 times.
2975 if (affine_merge_const6(c0, c2, cu->cb_width, cu->cb_height, mi)) {
1369
2/2
✓ Branch 0 taken 1242 times.
✓ Branch 1 taken 467 times.
1709 if (merge_subblock_idx == num_cands)
1370 1242 return 1;
1371 }
1372 1733 return 0;
1373 }
1374
1375 //8.5.5.2 Derivation process for motion vectors and reference indices in subblock merge mode
1376 //return 1 if candidate is SbCol
1377 54562 static int sb_mv_merge_mode(const VVCLocalContext *lc, const int merge_subblock_idx, PredictionUnit *pu)
1378 {
1379 54562 const VVCSPS *sps = lc->fc->ps.sps;
1380 54562 const CodingUnit *cu = lc->cu;
1381 54562 MotionInfo *mi = &pu->mi;
1382 54562 int num_cands = 0;
1383 NeighbourContext nctx;
1384
1385 54562 init_neighbour_context(&nctx, lc);
1386
1387 //SbCol
1388
2/2
✓ Branch 1 taken 45965 times.
✓ Branch 2 taken 8597 times.
54562 if (sb_temporal_merge_candidate(lc, &nctx, pu)) {
1389
2/2
✓ Branch 0 taken 28768 times.
✓ Branch 1 taken 17197 times.
45965 if (merge_subblock_idx == num_cands)
1390 28768 return 1;
1391 17197 num_cands++;
1392 }
1393
1394 25794 pu->inter_affine_flag = 1;
1395 25794 mi->num_sb_x = cu->cb_width >> MIN_PU_LOG2;
1396 25794 mi->num_sb_y = cu->cb_height >> MIN_PU_LOG2;
1397
1398
1/2
✓ Branch 0 taken 25794 times.
✗ Branch 1 not taken.
25794 if (sps->r->sps_affine_enabled_flag) {
1399 25794 const NeighbourIdx ak[] = { A0, A1 };
1400 25794 const NeighbourIdx bk[] = { B0, B1, B2 };
1401 //A
1402
2/2
✓ Branch 1 taken 10242 times.
✓ Branch 2 taken 15552 times.
25794 if (AFFINE_MERGE_FROM_NBS(ak)) {
1403
2/2
✓ Branch 0 taken 5754 times.
✓ Branch 1 taken 4488 times.
10242 if (merge_subblock_idx == num_cands)
1404 24061 return 0;
1405 4488 num_cands++;
1406 }
1407
1408 //B
1409
2/2
✓ Branch 1 taken 9298 times.
✓ Branch 2 taken 10742 times.
20040 if (AFFINE_MERGE_FROM_NBS(bk)) {
1410
2/2
✓ Branch 0 taken 4394 times.
✓ Branch 1 taken 4904 times.
9298 if (merge_subblock_idx == num_cands)
1411 4394 return 0;
1412 4904 num_cands++;
1413 }
1414
1415 //Const1 to Const6
1416
2/2
✓ Branch 1 taken 13913 times.
✓ Branch 2 taken 1733 times.
15646 if (affine_merge_const_candidates(lc, mi, &nctx, merge_subblock_idx, num_cands))
1417 13913 return 0;
1418 }
1419 //Zero
1420 1733 affine_merge_zero_motion(lc, mi);
1421 1733 return 0;
1422 }
1423
1424 54562 void ff_vvc_sb_mv_merge_mode(VVCLocalContext *lc, const int merge_subblock_idx, PredictionUnit *pu)
1425 {
1426 54562 const CodingUnit *cu = lc->cu;
1427 54562 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
1428
2/2
✓ Branch 1 taken 25794 times.
✓ Branch 2 taken 28768 times.
54562 if (!sb_mv_merge_mode(lc, merge_subblock_idx, pu)) {
1429 25794 ff_vvc_store_sb_mvs(lc, pu);
1430 }
1431 54562 }
1432
1433 150731 static int mvp_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand,
1434 const int lx, const int8_t *ref_idx, Mv *mv)
1435 {
1436 150731 const VVCFrameContext *fc = lc->fc;
1437 150731 const RefPicList *rpl = lc->sc->rpl;
1438 150731 const int min_pu_width = fc->ps.pps->min_pu_width;
1439 150731 const MvField* tab_mvf = fc->tab.mvf;
1440 150731 const MvField *mvf = &TAB_MVF(x_cand, y_cand);
1441 150731 const PredFlag maskx = lx + 1;
1442 150731 const int poc = rpl[lx].refs[ref_idx[lx]].poc;
1443 150731 int available = 0;
1444
1445
4/4
✓ Branch 0 taken 115750 times.
✓ Branch 1 taken 34981 times.
✓ Branch 2 taken 76895 times.
✓ Branch 3 taken 38855 times.
150731 if ((mvf->pred_flag & maskx) && rpl[lx].refs[mvf->ref_idx[lx]].poc == poc) {
1446 76895 available = 1;
1447 76895 *mv = mvf->mv[lx];
1448 } else {
1449 73836 const int ly = !lx;
1450 73836 const PredFlag masky = ly + 1;
1451
4/4
✓ Branch 0 taken 50175 times.
✓ Branch 1 taken 23661 times.
✓ Branch 2 taken 10524 times.
✓ Branch 3 taken 39651 times.
73836 if ((mvf->pred_flag & masky) && rpl[ly].refs[mvf->ref_idx[ly]].poc == poc) {
1452 10524 available = 1;
1453 10524 *mv = mvf->mv[ly];
1454 }
1455 }
1456
1457 150731 return available;
1458 }
1459
1460 30704 static int affine_mvp_candidate(const VVCLocalContext *lc,
1461 const int x_cand, const int y_cand, const int lx, const int8_t *ref_idx,
1462 Mv *cps, const int num_cp)
1463 {
1464 30704 const VVCFrameContext *fc = lc->fc;
1465 30704 int x_nb, y_nb, nbw, nbh, motion_model_idc, available = 0;
1466
1467 30704 motion_model_idc = affine_neighbour_cb(fc, x_cand, y_cand, &x_nb, &y_nb, &nbw, &nbh);
1468
2/2
✓ Branch 0 taken 7687 times.
✓ Branch 1 taken 23017 times.
30704 if (motion_model_idc) {
1469 7687 const int min_pu_width = fc->ps.pps->min_pu_width;
1470 7687 const MvField* tab_mvf = fc->tab.mvf;
1471 7687 const MvField *mvf = &TAB_MVF(x_nb, y_nb);
1472 7687 RefPicList* rpl = lc->sc->rpl;
1473 7687 const PredFlag maskx = lx + 1;
1474 7687 const int poc = rpl[lx].refs[ref_idx[lx]].poc;
1475
1476
4/4
✓ Branch 0 taken 6481 times.
✓ Branch 1 taken 1206 times.
✓ Branch 2 taken 5259 times.
✓ Branch 3 taken 1222 times.
7687 if ((mvf->pred_flag & maskx) && rpl[lx].refs[mvf->ref_idx[lx]].poc == poc) {
1477 5259 available = 1;
1478 5259 affine_cps_from_nb(lc, x_nb, y_nb, nbw, nbh, lx, cps, num_cp);
1479 } else {
1480 2428 const int ly = !lx;
1481 2428 const PredFlag masky = ly + 1;
1482
4/4
✓ Branch 0 taken 1586 times.
✓ Branch 1 taken 842 times.
✓ Branch 2 taken 779 times.
✓ Branch 3 taken 807 times.
2428 if ((mvf->pred_flag & masky) && rpl[ly].refs[mvf->ref_idx[ly]].poc == poc) {
1483 779 available = 1;
1484 779 affine_cps_from_nb(lc, x_nb, y_nb, nbw, nbh, ly, cps, num_cp);
1485 }
1486 }
1487
1488 }
1489 30704 return available;
1490 }
1491
1492 170491 static int mvp_from_nbs(NeighbourContext *ctx,
1493 const NeighbourIdx *nbs, const int num_nbs, const int lx, const int8_t *ref_idx, const int amvr_shift,
1494 Mv *cps, const int num_cps)
1495 {
1496 170491 const VVCLocalContext *lc = ctx->lc;
1497 170491 int available = 0;
1498
1499
2/2
✓ Branch 0 taken 337866 times.
✓ Branch 1 taken 77034 times.
414900 for (int i = 0; i < num_nbs; i++) {
1500 337866 Neighbour *n = &ctx->neighbours[nbs[i]];
1501
2/2
✓ Branch 1 taken 181435 times.
✓ Branch 2 taken 156431 times.
337866 if (check_available(n, lc, 0)) {
1502
2/2
✓ Branch 0 taken 30704 times.
✓ Branch 1 taken 150731 times.
181435 if (num_cps > 1)
1503 30704 available = affine_mvp_candidate(lc, n->x, n->y, lx, ref_idx, cps, num_cps);
1504 else
1505 150731 available = mvp_candidate(lc, n->x, n->y, lx, ref_idx, cps);
1506
2/2
✓ Branch 0 taken 93457 times.
✓ Branch 1 taken 87978 times.
181435 if (available) {
1507
2/2
✓ Branch 0 taken 102475 times.
✓ Branch 1 taken 93457 times.
195932 for (int c = 0; c < num_cps; c++)
1508 102475 ff_vvc_round_mv(cps + c, amvr_shift, amvr_shift);
1509 93457 return 1;
1510 }
1511 }
1512 }
1513 77034 return 0;
1514 }
1515
1516 //get mvp from neighbours
1517 #define AFFINE_MVP_FROM_NBS(nbs) \
1518 mvp_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), lx, ref_idx, amvr_shift, cps, num_cp) \
1519
1520 #define MVP_FROM_NBS(nbs) \
1521 mvp_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), lx, ref_idx, amvr_shift, mv, 1) \
1522
1523 89839 static int mvp_spatial_candidates(const VVCLocalContext *lc,
1524 const int mvp_lx_flag, const int lx, const int8_t* ref_idx, const int amvr_shift,
1525 Mv* mv, int *nb_merge_cand)
1526 {
1527 89839 const NeighbourIdx ak[] = { A0, A1 };
1528 89839 const NeighbourIdx bk[] = { B0, B1, B2 };
1529 NeighbourContext nctx;
1530 89839 int available_a, num_cands = 0;
1531 89839 LOCAL_ALIGNED_8(Mv, mv_a, [1]);
1532
1533 89839 init_neighbour_context(&nctx, lc);
1534
1535 89839 available_a = MVP_FROM_NBS(ak);
1536
2/2
✓ Branch 0 taken 53099 times.
✓ Branch 1 taken 36740 times.
89839 if (available_a) {
1537
2/2
✓ Branch 0 taken 32192 times.
✓ Branch 1 taken 20907 times.
53099 if (mvp_lx_flag == num_cands)
1538 32192 return 1;
1539 20907 num_cands++;
1540 20907 *mv_a = *mv;
1541 }
1542
2/2
✓ Branch 1 taken 34320 times.
✓ Branch 2 taken 23327 times.
57647 if (MVP_FROM_NBS(bk)) {
1543
4/4
✓ Branch 0 taken 17878 times.
✓ Branch 1 taken 16442 times.
✓ Branch 2 taken 14978 times.
✓ Branch 3 taken 2900 times.
34320 if (!available_a || !IS_SAME_MV(mv_a, mv)) {
1544
2/2
✓ Branch 0 taken 25685 times.
✓ Branch 1 taken 5735 times.
31420 if (mvp_lx_flag == num_cands)
1545 25685 return 1;
1546 5735 num_cands++;
1547 }
1548 }
1549 31962 *nb_merge_cand = num_cands;
1550 31962 return 0;
1551 }
1552
1553 31962 static int mvp_temporal_candidates(const VVCLocalContext* lc,
1554 const int mvp_lx_flag, const int lx, const int8_t *ref_idx, const int amvr_shift,
1555 Mv* mv, int *num_cands)
1556 {
1557
2/2
✓ Branch 1 taken 18573 times.
✓ Branch 2 taken 13389 times.
31962 if (temporal_luma_motion_vector(lc, ref_idx[lx], mv, lx, 1, 0)) {
1558
2/2
✓ Branch 0 taken 15019 times.
✓ Branch 1 taken 3554 times.
18573 if (mvp_lx_flag == *num_cands) {
1559 15019 ff_vvc_round_mv(mv, amvr_shift, amvr_shift);
1560 15019 return 1;
1561 }
1562 3554 (*num_cands)++;
1563 }
1564 16943 return 0;
1565
1566 }
1567
1568 16943 static int mvp_history_candidates(const VVCLocalContext *lc,
1569 const int mvp_lx_flag, const int lx, const int8_t ref_idx, const int amvr_shift,
1570 Mv *mv, int num_cands)
1571 {
1572 16943 const EntryPoint* ep = lc->ep;
1573 16943 const RefPicList* rpl = lc->sc->rpl;
1574 16943 const int poc = rpl[lx].refs[ref_idx].poc;
1575
1576
2/2
✓ Branch 0 taken 1945 times.
✓ Branch 1 taken 14998 times.
16943 if (ep->num_hmvp == 0)
1577 1945 return 0;
1578
2/2
✓ Branch 0 taken 31451 times.
✓ Branch 1 taken 4725 times.
36176 for (int i = 1; i <= FFMIN(4, ep->num_hmvp); i++) {
1579 31451 const MvField* h = &ep->hmvp[i - 1];
1580
2/2
✓ Branch 0 taken 54057 times.
✓ Branch 1 taken 21178 times.
75235 for (int j = 0; j < 2; j++) {
1581
2/2
✓ Branch 0 taken 22606 times.
✓ Branch 1 taken 31451 times.
54057 const int ly = (j ? !lx : lx);
1582 54057 PredFlag mask = PF_L0 + ly;
1583
4/4
✓ Branch 0 taken 36934 times.
✓ Branch 1 taken 17123 times.
✓ Branch 2 taken 12531 times.
✓ Branch 3 taken 24403 times.
54057 if ((h->pred_flag & mask) && poc == rpl[ly].refs[h->ref_idx[ly]].poc) {
1584
2/2
✓ Branch 0 taken 10273 times.
✓ Branch 1 taken 2258 times.
12531 if (mvp_lx_flag == num_cands) {
1585 10273 *mv = h->mv[ly];
1586 10273 ff_vvc_round_mv(mv, amvr_shift, amvr_shift);
1587 10273 return 1;
1588 }
1589 2258 num_cands++;
1590 }
1591 }
1592 }
1593 4725 return 0;
1594 }
1595
1596 //8.5.2.8 Derivation process for luma motion vector prediction
1597 89839 static void mvp(const VVCLocalContext *lc, const int mvp_lx_flag, const int lx,
1598 const int8_t *ref_idx, const int amvr_shift, Mv *mv)
1599 {
1600 int num_cands;
1601
1602
2/2
✓ Branch 1 taken 57877 times.
✓ Branch 2 taken 31962 times.
89839 if (mvp_spatial_candidates(lc, mvp_lx_flag, lx, ref_idx, amvr_shift, mv, &num_cands))
1603 83169 return;
1604
1605
2/2
✓ Branch 1 taken 15019 times.
✓ Branch 2 taken 16943 times.
31962 if (mvp_temporal_candidates(lc, mvp_lx_flag, lx, ref_idx, amvr_shift, mv, &num_cands))
1606 15019 return;
1607
1608
2/2
✓ Branch 1 taken 10273 times.
✓ Branch 2 taken 6670 times.
16943 if (mvp_history_candidates(lc, mvp_lx_flag, lx, ref_idx[lx], amvr_shift, mv, num_cands))
1609 10273 return;
1610
1611 6670 memset(mv, 0, sizeof(*mv));
1612 }
1613
1614 70428 void ff_vvc_mvp(VVCLocalContext *lc, const int *mvp_lx_flag, const int amvr_shift, MotionInfo *mi)
1615 {
1616 70428 const CodingUnit *cu = lc->cu;
1617 70428 mi->num_sb_x = 1;
1618 70428 mi->num_sb_y = 1;
1619
1620 70428 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
1621
2/2
✓ Branch 0 taken 57970 times.
✓ Branch 1 taken 12458 times.
70428 if (mi->pred_flag != PF_L1)
1622 57970 mvp(lc, mvp_lx_flag[L0], L0, mi->ref_idx, amvr_shift, &mi->mv[L0][0]);
1623
2/2
✓ Branch 0 taken 31869 times.
✓ Branch 1 taken 38559 times.
70428 if (mi->pred_flag != PF_L0)
1624 31869 mvp(lc, mvp_lx_flag[L1], L1, mi->ref_idx, amvr_shift, &mi->mv[L1][0]);
1625 70428 }
1626
1627 67240 static int ibc_spatial_candidates(const VVCLocalContext *lc, const int merge_idx, Mv *const cand_list, int *nb_merge_cand)
1628 {
1629 67240 const CodingUnit *cu = lc->cu;
1630 67240 const VVCFrameContext *fc = lc->fc;
1631 67240 const int min_pu_width = fc->ps.pps->min_pu_width;
1632 67240 const MvField *tab_mvf = fc->tab.mvf;
1633 67240 const int is_gt4by4 = (cu->cb_width * cu->cb_height) > 16;
1634 67240 int num_cands = 0;
1635
1636 NeighbourContext nctx;
1637 67240 Neighbour *a1 = &nctx.neighbours[A1];
1638 67240 Neighbour *b1 = &nctx.neighbours[B1];
1639
1640
2/2
✓ Branch 0 taken 21469 times.
✓ Branch 1 taken 45771 times.
67240 if (!is_gt4by4) {
1641 21469 *nb_merge_cand = 0;
1642 21469 return 0;
1643 }
1644
1645 45771 init_neighbour_context(&nctx, lc);
1646
1647
2/2
✓ Branch 1 taken 28927 times.
✓ Branch 2 taken 16844 times.
45771 if (check_available(a1, lc, 0)) {
1648 28927 cand_list[num_cands++] = TAB_MVF(a1->x, a1->y).mv[L0];
1649
2/2
✓ Branch 0 taken 19533 times.
✓ Branch 1 taken 9394 times.
28927 if (num_cands > merge_idx)
1650 19533 return 1;
1651 }
1652
2/2
✓ Branch 1 taken 13791 times.
✓ Branch 2 taken 12447 times.
26238 if (check_available(b1, lc, 0)) {
1653 13791 const MvField *mvf = &TAB_MVF(b1->x, b1->y);
1654
4/4
✓ Branch 0 taken 6779 times.
✓ Branch 1 taken 7012 times.
✓ Branch 2 taken 6134 times.
✓ Branch 3 taken 645 times.
13791 if (!num_cands || !IS_SAME_MV(&cand_list[0], mvf->mv)) {
1655 13146 cand_list[num_cands++] = mvf->mv[L0];
1656
2/2
✓ Branch 0 taken 10406 times.
✓ Branch 1 taken 2740 times.
13146 if (num_cands > merge_idx)
1657 10406 return 1;
1658 }
1659 }
1660
1661 15832 *nb_merge_cand = num_cands;
1662 15832 return 0;
1663 }
1664
1665 37301 static int ibc_history_candidates(const VVCLocalContext *lc,
1666 const int merge_idx, Mv *cand_list, int *nb_merge_cand)
1667 {
1668 37301 const CodingUnit *cu = lc->cu;
1669 37301 const EntryPoint *ep = lc->ep;
1670 37301 const int is_gt4by4 = (cu->cb_width * cu->cb_height) > 16;
1671 37301 int num_cands = *nb_merge_cand;
1672
1673
2/2
✓ Branch 0 taken 57271 times.
✓ Branch 1 taken 1612 times.
58883 for (int i = 1; i <= ep->num_hmvp_ibc; i++) {
1674 57271 int same_motion = 0;
1675 57271 const MvField *mvf = &ep->hmvp_ibc[ep->num_hmvp_ibc - i];
1676
2/2
✓ Branch 0 taken 14282 times.
✓ Branch 1 taken 53419 times.
67701 for (int j = 0; j < *nb_merge_cand; j++) {
1677
5/6
✓ Branch 0 taken 14282 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6342 times.
✓ Branch 3 taken 7940 times.
✓ Branch 4 taken 3852 times.
✓ Branch 5 taken 2490 times.
14282 same_motion = is_gt4by4 && i == 1 && IS_SAME_MV(&mvf->mv[L0], &cand_list[j]);
1678
2/2
✓ Branch 0 taken 3852 times.
✓ Branch 1 taken 10430 times.
14282 if (same_motion)
1679 3852 break;
1680 }
1681
2/2
✓ Branch 0 taken 53419 times.
✓ Branch 1 taken 3852 times.
57271 if (!same_motion) {
1682 53419 cand_list[num_cands++] = mvf->mv[L0];
1683
2/2
✓ Branch 0 taken 35689 times.
✓ Branch 1 taken 17730 times.
53419 if (num_cands > merge_idx)
1684 35689 return 1;
1685 }
1686 }
1687
1688 1612 *nb_merge_cand = num_cands;
1689 1612 return 0;
1690 }
1691
1692 #define MV_BITS 18
1693 #define IBC_SHIFT(v) ((v) >= (1 << (MV_BITS - 1)) ? ((v) - (1 << MV_BITS)) : (v))
1694
1695 39050 static inline void ibc_add_mvp(Mv *mv, Mv *mvp, const int amvr_shift)
1696 {
1697 39050 ff_vvc_round_mv(mv, amvr_shift, 0);
1698 39050 ff_vvc_round_mv(mvp, amvr_shift, amvr_shift);
1699
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39050 times.
39050 mv->x = IBC_SHIFT(mv->x + mvp->x);
1700
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39050 times.
39050 mv->y = IBC_SHIFT(mv->y + mvp->y);
1701 39050 }
1702
1703 67240 static void ibc_merge_candidates(VVCLocalContext *lc, const int merge_idx, Mv *mv)
1704 {
1705 67240 const CodingUnit *cu = lc->cu;
1706 67240 LOCAL_ALIGNED_8(Mv, cand_list, [MRG_MAX_NUM_CANDS]);
1707 int nb_cands;
1708
1709 67240 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
1710
4/4
✓ Branch 1 taken 37301 times.
✓ Branch 2 taken 29939 times.
✓ Branch 3 taken 35689 times.
✓ Branch 4 taken 1612 times.
104541 if (ibc_spatial_candidates(lc, merge_idx, cand_list, &nb_cands) ||
1711 37301 ibc_history_candidates(lc, merge_idx, cand_list, &nb_cands)) {
1712 65628 *mv = cand_list[merge_idx];
1713 65628 return;
1714 }
1715
1716 //zero mv
1717 1612 memset(mv, 0, sizeof(*mv));
1718 }
1719
1720 67240 static int ibc_check_mv(VVCLocalContext *lc, Mv *mv)
1721 {
1722 67240 const VVCFrameContext *fc = lc->fc;
1723 67240 const VVCSPS *sps = lc->fc->ps.sps;
1724 67240 const CodingUnit *cu = lc->cu;
1725 67240 const Mv *bv = &cu->pu.mi.mv[L0][0];
1726
1727
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 67240 times.
67240 if (sps->ctb_size_y < ((cu->y0 + (bv->y >> 4)) & (sps->ctb_size_y - 1)) + cu->cb_height) {
1728 av_log(fc->log_ctx, AV_LOG_ERROR, "IBC region spans multiple CTBs.\n");
1729 return AVERROR_INVALIDDATA;
1730 }
1731
1732 67240 return 0;
1733 }
1734
1735 39050 int ff_vvc_mvp_ibc(VVCLocalContext *lc, const int mvp_l0_flag, const int amvr_shift, Mv *mv)
1736 {
1737 39050 LOCAL_ALIGNED_8(Mv, mvp, [1]);
1738
1739 39050 ibc_merge_candidates(lc, mvp_l0_flag, mvp);
1740 39050 ibc_add_mvp(mv, mvp, amvr_shift);
1741 39050 return ibc_check_mv(lc, mv);
1742 }
1743
1744 28190 int ff_vvc_luma_mv_merge_ibc(VVCLocalContext *lc, const int merge_idx, Mv *mv)
1745 {
1746 28190 ibc_merge_candidates(lc, merge_idx, mv);
1747 28190 return ibc_check_mv(lc, mv);
1748 }
1749
1750 24930 static int affine_mvp_constructed_cp(NeighbourContext *ctx,
1751 const NeighbourIdx *neighbour, const int num_neighbour,
1752 const int lx, const int8_t ref_idx, const int amvr_shift, Mv *cp)
1753 {
1754 24930 const VVCLocalContext *lc = ctx->lc;
1755 24930 const VVCFrameContext *fc = lc->fc;
1756 24930 const MvField *tab_mvf = fc->tab.mvf;
1757 24930 const int min_pu_width = fc->ps.pps->min_pu_width;
1758 24930 const RefPicList* rpl = lc->sc->rpl;
1759 24930 int available = 0;
1760
1761
2/2
✓ Branch 0 taken 38907 times.
✓ Branch 1 taken 8478 times.
47385 for (int i = 0; i < num_neighbour; i++) {
1762 38907 Neighbour *n = &ctx->neighbours[neighbour[i]];
1763
2/2
✓ Branch 1 taken 24498 times.
✓ Branch 2 taken 14409 times.
38907 if (check_available(n, ctx->lc, 0)) {
1764 24498 const PredFlag maskx = lx + 1;
1765 24498 const MvField* mvf = &TAB_MVF(n->x, n->y);
1766 24498 const int poc = rpl[lx].refs[ref_idx].poc;
1767
4/4
✓ Branch 0 taken 20002 times.
✓ Branch 1 taken 4496 times.
✓ Branch 2 taken 14579 times.
✓ Branch 3 taken 5423 times.
24498 if ((mvf->pred_flag & maskx) && rpl[lx].refs[mvf->ref_idx[lx]].poc == poc) {
1768 14579 available = 1;
1769 14579 *cp = mvf->mv[lx];
1770 } else {
1771 9919 const int ly = !lx;
1772 9919 const PredFlag masky = ly + 1;
1773
4/4
✓ Branch 0 taken 6735 times.
✓ Branch 1 taken 3184 times.
✓ Branch 2 taken 1873 times.
✓ Branch 3 taken 4862 times.
9919 if ((mvf->pred_flag & masky) && rpl[ly].refs[mvf->ref_idx[ly]].poc == poc) {
1774 1873 available = 1;
1775 1873 *cp = mvf->mv[ly];
1776 }
1777 }
1778
2/2
✓ Branch 0 taken 16452 times.
✓ Branch 1 taken 8046 times.
24498 if (available) {
1779 16452 ff_vvc_round_mv(cp, amvr_shift, amvr_shift);
1780 16452 return 1;
1781 }
1782 }
1783 }
1784 8478 return 0;
1785 }
1786
1787 #define AFFINE_MVP_CONSTRUCTED_CP(cands, cp) \
1788 affine_mvp_constructed_cp(nctx, cands, FF_ARRAY_ELEMS(cands), lx, ref_idx, \
1789 amvr_shift, cp)
1790
1791 //8.5.5.8 Derivation process for constructed affine control point motion vector prediction candidates
1792 8310 static int affine_mvp_const1(NeighbourContext* nctx,
1793 const int lx, const int8_t ref_idx, const int amvr_shift,
1794 Mv *cps, int *available)
1795 {
1796 8310 const NeighbourIdx tl[] = { B2, B3, A2 };
1797 8310 const NeighbourIdx tr[] = { B1, B0 };
1798 8310 const NeighbourIdx bl[] = { A1, A0 };
1799
1800 8310 available[0] = AFFINE_MVP_CONSTRUCTED_CP(tl, cps + 0);
1801 8310 available[1] = AFFINE_MVP_CONSTRUCTED_CP(tr, cps + 1);
1802 8310 available[2] = AFFINE_MVP_CONSTRUCTED_CP(bl, cps + 2);
1803
4/4
✓ Branch 0 taken 6372 times.
✓ Branch 1 taken 1938 times.
✓ Branch 2 taken 4831 times.
✓ Branch 3 taken 1541 times.
8310 return available[0] && available[1];
1804 }
1805
1806 //8.5.5.7 item 7
1807 3698 static void affine_mvp_const2(const int idx, Mv *cps, const int num_cp)
1808 {
1809 3698 const Mv mv = cps[idx];
1810
2/2
✓ Branch 0 taken 9160 times.
✓ Branch 1 taken 3698 times.
12858 for (int j = 0; j < num_cp; j++)
1811 9160 cps[j] = mv;
1812 3698 }
1813
1814 //8.5.5.7 Derivation process for luma affine control point motion vector predictors
1815 12526 static void affine_mvp(const VVCLocalContext *lc,
1816 const int mvp_lx_flag, const int lx, const int8_t *ref_idx, const int amvr_shift,
1817 MotionModelIdc motion_model_idc, Mv *cps)
1818 {
1819 12526 const NeighbourIdx ak[] = { A0, A1 };
1820 12526 const NeighbourIdx bk[] = { B0, B1, B2 };
1821 12526 const int num_cp = motion_model_idc + 1;
1822 NeighbourContext nctx;
1823 int available[MAX_CONTROL_POINTS];
1824 12526 int num_cands = 0;
1825
1826 12526 init_neighbour_context(&nctx, lc);
1827 //Ak
1828
2/2
✓ Branch 1 taken 3048 times.
✓ Branch 2 taken 9478 times.
12526 if (AFFINE_MVP_FROM_NBS(ak)) {
1829
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 1001 times.
3048 if (mvp_lx_flag == num_cands)
1830 11769 return;
1831 1001 num_cands++;
1832 }
1833 //Bk
1834
2/2
✓ Branch 1 taken 2990 times.
✓ Branch 2 taken 7489 times.
10479 if (AFFINE_MVP_FROM_NBS(bk)) {
1835
2/2
✓ Branch 0 taken 2169 times.
✓ Branch 1 taken 821 times.
2990 if (mvp_lx_flag == num_cands)
1836 2169 return;
1837 821 num_cands++;
1838 }
1839
1840 //Const1
1841
2/2
✓ Branch 1 taken 4831 times.
✓ Branch 2 taken 3479 times.
8310 if (affine_mvp_const1(&nctx, lx, ref_idx[lx], amvr_shift, cps, available)) {
1842
4/4
✓ Branch 0 taken 1293 times.
✓ Branch 1 taken 3538 times.
✓ Branch 2 taken 739 times.
✓ Branch 3 taken 554 times.
4831 if (available[2] || motion_model_idc == MOTION_4_PARAMS_AFFINE) {
1843
2/2
✓ Branch 0 taken 2951 times.
✓ Branch 1 taken 1326 times.
4277 if (mvp_lx_flag == num_cands)
1844 2951 return;
1845 1326 num_cands++;
1846 }
1847 }
1848
1849 //Const2
1850
2/2
✓ Branch 0 taken 10743 times.
✓ Branch 1 taken 1661 times.
12404 for (int i = 2; i >= 0; i--) {
1851
2/2
✓ Branch 0 taken 4276 times.
✓ Branch 1 taken 6467 times.
10743 if (available[i]) {
1852
2/2
✓ Branch 0 taken 3698 times.
✓ Branch 1 taken 578 times.
4276 if (mvp_lx_flag == num_cands) {
1853 3698 affine_mvp_const2(i, cps, num_cp);
1854 3698 return;
1855 }
1856 578 num_cands++;
1857 }
1858 }
1859
2/2
✓ Branch 1 taken 1127 times.
✓ Branch 2 taken 534 times.
1661 if (temporal_luma_motion_vector(lc, ref_idx[lx], cps, lx, 1, 0)) {
1860
2/2
✓ Branch 0 taken 904 times.
✓ Branch 1 taken 223 times.
1127 if (mvp_lx_flag == num_cands) {
1861 904 ff_vvc_round_mv(cps, amvr_shift, amvr_shift);
1862
2/2
✓ Branch 0 taken 1197 times.
✓ Branch 1 taken 904 times.
2101 for (int i = 1; i < num_cp; i++)
1863 1197 cps[i] = cps[0];
1864 904 return;
1865 }
1866 223 num_cands++;
1867 }
1868
1869 //Zero Mv
1870 757 memset(cps, 0, num_cp * sizeof(Mv));
1871 }
1872
1873 10170 void ff_vvc_affine_mvp(VVCLocalContext *lc, const int *mvp_lx_flag, const int amvr_shift, MotionInfo *mi)
1874 {
1875 10170 const CodingUnit *cu = lc->cu;
1876
1877 10170 mi->num_sb_x = cu->cb_width >> MIN_PU_LOG2;
1878 10170 mi->num_sb_y = cu->cb_height >> MIN_PU_LOG2;
1879
1880 10170 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
1881
2/2
✓ Branch 0 taken 8973 times.
✓ Branch 1 taken 1197 times.
10170 if (mi->pred_flag != PF_L1)
1882 8973 affine_mvp(lc, mvp_lx_flag[L0], L0, mi->ref_idx, amvr_shift, mi->motion_model_idc, &mi->mv[L0][0]);
1883
2/2
✓ Branch 0 taken 3553 times.
✓ Branch 1 taken 6617 times.
10170 if (mi->pred_flag != PF_L0)
1884 3553 affine_mvp(lc, mvp_lx_flag[L1], L1, mi->ref_idx, amvr_shift, mi->motion_model_idc, &mi->mv[L1][0]);
1885 10170 }
1886
1887 //8.5.2.14 Rounding process for motion vectors
1888 8197349 void ff_vvc_round_mv(Mv *mv, const int lshift, const int rshift)
1889 {
1890
2/2
✓ Branch 0 taken 8156623 times.
✓ Branch 1 taken 40726 times.
8197349 if (rshift) {
1891 8156623 const int offset = 1 << (rshift - 1);
1892 8156623 mv->x = ((mv->x + offset - (mv->x >= 0)) >> rshift) * (1 << lshift);
1893 8156623 mv->y = ((mv->y + offset - (mv->y >= 0)) >> rshift) * (1 << lshift);
1894 } else {
1895 40726 mv->x = mv->x * (1 << lshift);
1896 40726 mv->y = mv->y * (1 << lshift);
1897 }
1898 8197349 }
1899
1900 5586456 void ff_vvc_clip_mv(Mv *mv)
1901 {
1902 5586456 mv->x = av_clip(mv->x, -(1 << 17), (1 << 17) - 1);
1903 5586456 mv->y = av_clip(mv->y, -(1 << 17), (1 << 17) - 1);
1904 5586456 }
1905
1906 //8.5.2.1 Derivation process for motion vector components and reference indices
1907 367760 static av_always_inline int is_greater_mer(const VVCFrameContext *fc, const int x0, const int y0, const int x0_br, const int y0_br)
1908 {
1909 367760 const uint8_t plevel = fc->ps.sps->log2_parallel_merge_level;
1910
1911
2/2
✓ Branch 0 taken 357636 times.
✓ Branch 1 taken 10124 times.
725396 return x0_br >> plevel > x0 >> plevel &&
1912
2/2
✓ Branch 0 taken 352864 times.
✓ Branch 1 taken 4772 times.
357636 y0_br >> plevel > y0 >> plevel;
1913 }
1914
1915 398635 static void update_hmvp(MvField *hmvp, int *num_hmvp, const MvField *mvf,
1916 int (*compare)(const MvField *n, const MvField *o))
1917 {
1918 int i;
1919
2/2
✓ Branch 0 taken 1667639 times.
✓ Branch 1 taken 206411 times.
1874050 for (i = 0; i < *num_hmvp; i++) {
1920
2/2
✓ Branch 1 taken 192224 times.
✓ Branch 2 taken 1475415 times.
1667639 if (compare(mvf, hmvp + i)) {
1921 192224 (*num_hmvp)--;
1922 192224 break;
1923 }
1924 }
1925
2/2
✓ Branch 0 taken 182149 times.
✓ Branch 1 taken 216486 times.
398635 if (i == MAX_NUM_HMVP_CANDS) {
1926 182149 (*num_hmvp)--;
1927 182149 i = 0;
1928 }
1929
1930 398635 memmove(hmvp + i, hmvp + i + 1, (*num_hmvp - i) * sizeof(MvField));
1931 398635 hmvp[(*num_hmvp)++] = *mvf;
1932 398635 }
1933
1934 189737 static int compare_l0_mv(const MvField *n, const MvField *o)
1935 {
1936 189737 return IS_SAME_MV(&n->mv[L0], &o->mv[L0]);
1937 }
1938
1939 //8.6.2.4 Derivation process for IBC history-based block vector candidates
1940 //8.5.2.16 Updating process for the history-based motion vector predictor candidate list
1941 435000 void ff_vvc_update_hmvp(VVCLocalContext *lc, const MotionInfo *mi)
1942 {
1943 435000 const VVCFrameContext *fc = lc->fc;
1944 435000 const CodingUnit *cu = lc->cu;
1945 435000 const int min_pu_width = fc->ps.pps->min_pu_width;
1946 435000 const MvField *tab_mvf = fc->tab.mvf;
1947 435000 EntryPoint *ep = lc->ep;
1948
1949
2/2
✓ Branch 0 taken 67240 times.
✓ Branch 1 taken 367760 times.
435000 if (cu->pred_mode == MODE_IBC) {
1950
2/2
✓ Branch 0 taken 21469 times.
✓ Branch 1 taken 45771 times.
67240 if (cu->cb_width * cu->cb_height <= 16)
1951 21469 return;
1952 45771 update_hmvp(ep->hmvp_ibc, &ep->num_hmvp_ibc, &TAB_MVF(cu->x0, cu->y0), compare_l0_mv);
1953 } else {
1954
2/2
✓ Branch 1 taken 14896 times.
✓ Branch 2 taken 352864 times.
367760 if (!is_greater_mer(fc, cu->x0, cu->y0, cu->x0 + cu->cb_width, cu->y0 + cu->cb_height))
1955 14896 return;
1956 352864 update_hmvp(ep->hmvp, &ep->num_hmvp, &TAB_MVF(cu->x0, cu->y0), compare_mv_ref_idx);
1957 }
1958 }
1959
1960 13587731 MvField* ff_vvc_get_mvf(const VVCFrameContext *fc, const int x0, const int y0)
1961 {
1962 13587731 const int min_pu_width = fc->ps.pps->min_pu_width;
1963 13587731 MvField* tab_mvf = fc->tab.mvf;
1964
1965 13587731 return &TAB_MVF(x0, y0);
1966 }
1967