FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/vvc/mvs.c
Date: 2024-05-03 15:42:48
Exec Total Coverage
Lines: 1176 1188 99.0%
Functions: 79 79 100.0%
Branches: 621 666 93.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 667942 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 667942 const uint8_t plevel = fc->ps.sps->log2_parallel_merge_level;
34
35
2/2
✓ Branch 0 taken 35423 times.
✓ Branch 1 taken 632519 times.
703365 return xN >> plevel == xP >> plevel &&
36
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35423 times.
35423 yN >> plevel == yP >> plevel;
37 }
38
39 //return true if we have same mvs and ref_idxs
40 1961032 static av_always_inline int compare_mv_ref_idx(const MvField *n, const MvField *o)
41 {
42
4/4
✓ Branch 0 taken 1656355 times.
✓ Branch 1 taken 304677 times.
✓ Branch 2 taken 509730 times.
✓ Branch 3 taken 1146625 times.
1961032 if (!o || n->pred_flag != o->pred_flag)
43 814407 return 0;
44
2/2
✓ Branch 0 taken 1439766 times.
✓ Branch 1 taken 244772 times.
1684538 for (int i = 0; i < 2; i++) {
45 1439766 PredFlag mask = i + 1;
46
2/2
✓ Branch 0 taken 1304802 times.
✓ Branch 1 taken 134964 times.
1439766 if (n->pred_flag & mask) {
47 1304802 const int same_ref_idx = n->ref_idx[i] == o->ref_idx[i];
48 1304802 const int same_mv = IS_SAME_MV(n->mv + i, o->mv + i);
49
4/4
✓ Branch 0 taken 1189490 times.
✓ Branch 1 taken 115312 times.
✓ Branch 2 taken 786541 times.
✓ Branch 3 taken 402949 times.
1304802 if (!same_ref_idx || !same_mv)
50 901853 return 0;
51 }
52 }
53 244772 return 1;
54 }
55
56 // 8.5.2.15 Temporal motion buffer compression process for collocated motion vectors
57 1905325 static av_always_inline void mv_compression(Mv *motion)
58 {
59 1905325 int mv[2] = {motion->x, motion->y};
60
2/2
✓ Branch 0 taken 3810650 times.
✓ Branch 1 taken 1905325 times.
5715975 for (int i = 0; i < 2; i++) {
61 3810650 const int s = mv[i] >> 17;
62 3810650 const int f = av_log2((mv[i] ^ s) | 31) - 4;
63 3810650 const int mask = (-1 * (1 << f)) >> 1;
64 3810650 const int round = (1 << f) >> 2;
65 3810650 mv[i] = (mv[i] + round) & mask;
66 }
67 1905325 motion->x = mv[0];
68 1905325 motion->y = mv[1];
69 1905325 }
70
71 1520264 void ff_vvc_mv_scale(Mv *dst, const Mv *src, int td, int tb)
72 {
73 int tx, scale_factor;
74
75 1520264 td = av_clip_int8(td);
76 1520264 tb = av_clip_int8(tb);
77 1520264 tx = (0x4000 + (abs(td) >> 1)) / td;
78 1520264 scale_factor = av_clip_intp2((tb * tx + 32) >> 6, 12);
79 1520264 dst->x = av_clip_intp2((scale_factor * src->x + 127 +
80 1520264 (scale_factor * src->x < 0)) >> 8, 17);
81 1520264 dst->y = av_clip_intp2((scale_factor * src->y + 127 +
82 1520264 (scale_factor * src->y < 0)) >> 8, 17);
83 1520264 }
84
85 //part of 8.5.2.12 Derivation process for collocated motion vectors
86 1905325 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 1905325 int cur_lt = refPicList[X].isLongTerm[refIdxLx];
92 1905325 int col_lt = refPicList_col[listCol].isLongTerm[refidxCol];
93 int col_poc_diff, cur_poc_diff;
94
95
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1905325 times.
1905325 if (cur_lt != col_lt) {
96 mvLXCol->x = 0;
97 mvLXCol->y = 0;
98 return 0;
99 }
100
101 1905325 col_poc_diff = colPic - refPicList_col[listCol].list[refidxCol];
102 1905325 cur_poc_diff = poc - refPicList[X].list[refIdxLx];
103
104 1905325 mv_compression(mvCol);
105
3/4
✓ Branch 0 taken 1905325 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 400066 times.
✓ Branch 3 taken 1505259 times.
1905325 if (cur_lt || col_poc_diff == cur_poc_diff) {
106 400066 mvLXCol->x = av_clip_intp2(mvCol->x, 17);
107 400066 mvLXCol->y = av_clip_intp2(mvCol->y, 17);
108 } else {
109 1505259 ff_vvc_mv_scale(mvLXCol, mvCol, col_poc_diff, cur_poc_diff);
110 }
111 1905325 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 445319 int ff_vvc_no_backward_pred_flag(const VVCLocalContext *lc)
122 {
123 445319 int check_diffpicount = 0;
124 int i, j;
125 445319 const RefPicList *rpl = lc->sc->rpl;
126
127
2/2
✓ Branch 0 taken 890638 times.
✓ Branch 1 taken 445319 times.
1335957 for (j = 0; j < 2; j++) {
128
2/2
✓ Branch 0 taken 1372334 times.
✓ Branch 1 taken 400376 times.
1772710 for (i = 0; i < lc->sc->sh.r->num_ref_idx_active[j]; i++) {
129
2/2
✓ Branch 0 taken 490262 times.
✓ Branch 1 taken 882072 times.
1372334 if (rpl[j].list[i] > lc->fc->ps.ph.poc) {
130 490262 check_diffpicount++;
131 490262 break;
132 }
133 }
134 }
135 445319 return !check_diffpicount;
136 }
137
138 //8.5.2.12 Derivation process for collocated motion vectors
139 2301772 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 2301772 const VVCFrameContext *fc = lc->fc;
144 2301772 const SliceContext *sc = lc->sc;
145 2301772 RefPicList* refPicList = sc->rpl;
146
147
2/2
✓ Branch 0 taken 68004 times.
✓ Branch 1 taken 2233768 times.
2301772 if (temp_col.pred_flag == PF_INTRA)
148 68004 return 0;
149
150
2/2
✓ Branch 0 taken 2132436 times.
✓ Branch 1 taken 101332 times.
2233768 if (sb_flag){
151
2/2
✓ Branch 0 taken 1237535 times.
✓ Branch 1 taken 894901 times.
2132436 if (X == 0) {
152
2/2
✓ Branch 0 taken 1120922 times.
✓ Branch 1 taken 116613 times.
1237535 if (temp_col.pred_flag & PF_L0)
153 1120922 return CHECK_MVSET(0);
154
3/4
✓ Branch 1 taken 1825 times.
✓ Branch 2 taken 114788 times.
✓ Branch 3 taken 1825 times.
✗ Branch 4 not taken.
116613 else if (ff_vvc_no_backward_pred_flag(lc) && (temp_col.pred_flag & PF_L1))
155 1825 return CHECK_MVSET(1);
156 } else {
157
2/2
✓ Branch 0 taken 622275 times.
✓ Branch 1 taken 272626 times.
894901 if (temp_col.pred_flag & PF_L1)
158 622275 return CHECK_MVSET(1);
159
3/4
✓ Branch 1 taken 58971 times.
✓ Branch 2 taken 213655 times.
✓ Branch 3 taken 58971 times.
✗ Branch 4 not taken.
272626 else if (ff_vvc_no_backward_pred_flag(lc) && (temp_col.pred_flag & PF_L0))
160 58971 return CHECK_MVSET(0);
161 }
162 } else {
163
2/2
✓ Branch 0 taken 11708 times.
✓ Branch 1 taken 89624 times.
101332 if (!(temp_col.pred_flag & PF_L0))
164 11708 return CHECK_MVSET(1);
165
2/2
✓ Branch 0 taken 44568 times.
✓ Branch 1 taken 45056 times.
89624 else if (temp_col.pred_flag == PF_L0)
166 44568 return CHECK_MVSET(0);
167
1/2
✓ Branch 0 taken 45056 times.
✗ Branch 1 not taken.
45056 else if (temp_col.pred_flag == PF_BI) {
168
2/2
✓ Branch 1 taken 8659 times.
✓ Branch 2 taken 36397 times.
45056 if (ff_vvc_no_backward_pred_flag(lc)) {
169
2/2
✓ Branch 0 taken 4457 times.
✓ Branch 1 taken 4202 times.
8659 if (X == 0)
170 4457 return CHECK_MVSET(0);
171 else
172 4202 return CHECK_MVSET(1);
173 } else {
174
2/2
✓ Branch 0 taken 21698 times.
✓ Branch 1 taken 14699 times.
36397 if (!lc->sc->sh.r->sh_collocated_from_l0_flag)
175 21698 return CHECK_MVSET(0);
176 else
177 14699 return CHECK_MVSET(1);
178 }
179 }
180 }
181 328443 return 0;
182 }
183
184 #define TAB_MVF(x, y) \
185 tab_mvf[((y) >> MIN_PU_LOG2) * min_pu_width + ((x) >> MIN_PU_LOG2)]
186
187 #define TAB_MVF_PU(v) \
188 TAB_MVF(x ## v, y ## v)
189
190 #define TAB_CP_MV(lx, x, y) \
191 fc->tab.cp_mv[lx][((((y) >> min_cb_log2_size) * min_cb_width + ((x) >> min_cb_log2_size)) ) * MAX_CONTROL_POINTS]
192
193
194 #define DERIVE_TEMPORAL_COLOCATED_MVS(sb_flag) \
195 derive_temporal_colocated_mvs(lc, temp_col, \
196 refIdxLx, mvLXCol, X, colPic, \
197 ff_vvc_get_ref_list(fc, ref, x, y), sb_flag)
198
199 //8.5.2.11 Derivation process for temporal luma motion vector prediction
200 126861 static int temporal_luma_motion_vector(const VVCLocalContext *lc,
201 const int refIdxLx, Mv *mvLXCol, const int X, int check_center, int sb_flag)
202 {
203 126861 const VVCFrameContext *fc = lc->fc;
204 126861 const VVCSPS *sps = fc->ps.sps;
205 126861 const VVCPPS *pps = fc->ps.pps;
206 126861 const CodingUnit *cu = lc->cu;
207 126861 const int subpic_idx = lc->sc->sh.r->curr_subpic_idx;
208 126861 int x, y, x_end, y_end, colPic, availableFlagLXCol = 0;
209 126861 int min_pu_width = fc->ps.pps->min_pu_width;
210 126861 VVCFrame *ref = fc->ref->collocated_ref;
211 MvField *tab_mvf;
212 MvField temp_col;
213
214
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 126861 times.
126861 if (!ref) {
215 memset(mvLXCol, 0, sizeof(*mvLXCol));
216 return 0;
217 }
218
219
3/4
✓ Branch 0 taken 126861 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1672 times.
✓ Branch 3 taken 125189 times.
126861 if (!fc->ps.ph.r->ph_temporal_mvp_enabled_flag || (cu->cb_width * cu->cb_height <= 32))
220 1672 return 0;
221
222 125189 tab_mvf = ref->tab_dmvr_mvf;
223 125189 colPic = ref->poc;
224
225 //bottom right collocated motion vector
226 125189 x = cu->x0 + cu->cb_width;
227 125189 y = cu->y0 + cu->cb_height;
228
229 125189 x_end = pps->subpic_x[subpic_idx] + pps->subpic_width[subpic_idx];
230 125189 y_end = pps->subpic_y[subpic_idx] + pps->subpic_height[subpic_idx];
231
232
1/2
✓ Branch 0 taken 125189 times.
✗ Branch 1 not taken.
125189 if (tab_mvf &&
233
4/4
✓ Branch 0 taken 105316 times.
✓ Branch 1 taken 19873 times.
✓ Branch 2 taken 103427 times.
✓ Branch 3 taken 1889 times.
125189 (cu->y0 >> sps->ctb_log2_size_y) == (y >> sps->ctb_log2_size_y) &&
234
2/2
✓ Branch 0 taken 99807 times.
✓ Branch 1 taken 3620 times.
103427 x < x_end && y < y_end) {
235 99807 x &= ~7;
236 99807 y &= ~7;
237 99807 temp_col = TAB_MVF(x, y);
238 99807 availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS(sb_flag);
239 }
240
2/2
✓ Branch 0 taken 112095 times.
✓ Branch 1 taken 13094 times.
125189 if (check_center) {
241 // derive center collocated motion vector
242
3/4
✓ Branch 0 taken 112095 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44337 times.
✓ Branch 3 taken 67758 times.
112095 if (tab_mvf && !availableFlagLXCol) {
243 44337 x = cu->x0 + (cu->cb_width >> 1);
244 44337 y = cu->y0 + (cu->cb_height >> 1);
245 44337 x &= ~7;
246 44337 y &= ~7;
247 44337 temp_col = TAB_MVF(x, y);
248 44337 availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS(sb_flag);
249 }
250 }
251 125189 return availableFlagLXCol;
252 }
253
254 5133955 void ff_vvc_set_mvf(const VVCLocalContext *lc, const int x0, const int y0, const int w, const int h, const MvField *mvf)
255 {
256 5133955 const VVCFrameContext *fc = lc->fc;
257 5133955 MvField *tab_mvf = fc->tab.mvf;
258 5133955 const int min_pu_width = fc->ps.pps->min_pu_width;
259 5133955 const int min_pu_size = 1 << MIN_PU_LOG2;
260
2/2
✓ Branch 0 taken 8081814 times.
✓ Branch 1 taken 5133955 times.
13215769 for (int dy = 0; dy < h; dy += min_pu_size) {
261
2/2
✓ Branch 0 taken 36433572 times.
✓ Branch 1 taken 8081814 times.
44515386 for (int dx = 0; dx < w; dx += min_pu_size) {
262 36433572 const int x = x0 + dx;
263 36433572 const int y = y0 + dy;
264 36433572 TAB_MVF(x, y) = *mvf;
265 }
266 }
267 5133955 }
268
269 404836 void ff_vvc_set_intra_mvf(const VVCLocalContext *lc, const int dmvr)
270 {
271 404836 const VVCFrameContext *fc = lc->fc;
272 404836 const CodingUnit *cu = lc->cu;
273
2/2
✓ Branch 0 taken 1582 times.
✓ Branch 1 taken 403254 times.
404836 MvField *tab_mvf = dmvr ? fc->ref->tab_dmvr_mvf : fc->tab.mvf;
274 404836 const int min_pu_width = fc->ps.pps->min_pu_width;
275 404836 const int min_pu_size = 1 << MIN_PU_LOG2;
276
2/2
✓ Branch 0 taken 1094867 times.
✓ Branch 1 taken 404836 times.
1499703 for (int dy = 0; dy < cu->cb_height; dy += min_pu_size) {
277
2/2
✓ Branch 0 taken 4946600 times.
✓ Branch 1 taken 1094867 times.
6041467 for (int dx = 0; dx < cu->cb_width; dx += min_pu_size) {
278 4946600 const int x = cu->x0 + dx;
279 4946600 const int y = cu->y0 + dy;
280 4946600 TAB_MVF(x, y).pred_flag = PF_INTRA;
281 }
282 }
283 404836 }
284
285 //cbProfFlagLX from 8.5.5.9 Derivation process for motion vector arrays from affine control point motion vectors
286 40580 static int derive_cb_prof_flag_lx(const VVCLocalContext *lc, const PredictionUnit* pu, int lx, int is_fallback)
287 {
288 40580 const MotionInfo* mi = &pu->mi;
289 40580 const Mv* cp_mv = &mi->mv[lx][0];
290
3/4
✓ Branch 0 taken 40580 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231 times.
✓ Branch 3 taken 40349 times.
40580 if (lc->fc->ps.ph.r->ph_prof_disabled_flag || is_fallback)
291 231 return 0;
292
2/2
✓ Branch 0 taken 15341 times.
✓ Branch 1 taken 25008 times.
40349 if (mi->motion_model_idc == MOTION_4_PARAMS_AFFINE) {
293
2/2
✓ Branch 0 taken 2401 times.
✓ Branch 1 taken 12940 times.
15341 if (IS_SAME_MV(cp_mv, cp_mv + 1))
294 2401 return 0;
295 }
296
2/2
✓ Branch 0 taken 25008 times.
✓ Branch 1 taken 12940 times.
37948 if (mi->motion_model_idc == MOTION_6_PARAMS_AFFINE) {
297
4/4
✓ Branch 0 taken 4204 times.
✓ Branch 1 taken 20804 times.
✓ Branch 2 taken 888 times.
✓ Branch 3 taken 3316 times.
25008 if (IS_SAME_MV(cp_mv, cp_mv + 1) && IS_SAME_MV(cp_mv, cp_mv + 2))
298 888 return 0;
299 }
300 //fixme: RprConstraintsActiveFlag
301 37060 return 1;
302 }
303
304 typedef struct SubblockParams {
305 int d_hor_x;
306 int d_ver_x;
307 int d_hor_y;
308 int d_ver_y;
309 int mv_scale_hor;
310 int mv_scale_ver;
311 int is_fallback;
312
313 int cb_width;
314 int cb_height;
315 } SubblockParams;
316
317 40580 static int is_fallback_mode(const SubblockParams *sp, const PredFlag pred_flag)
318 {
319 40580 const int a = 4 * (2048 + sp->d_hor_x);
320 40580 const int b = 4 * sp->d_hor_y;
321 40580 const int c = 4 * (2048 + sp->d_ver_y);
322 40580 const int d = 4 * sp->d_ver_x;
323
2/2
✓ Branch 0 taken 17004 times.
✓ Branch 1 taken 23576 times.
40580 if (pred_flag == PF_BI) {
324
2/2
✓ Branch 0 taken 16991 times.
✓ Branch 1 taken 13 times.
17004 const int max_w4 = FFMAX(0, FFMAX(a, FFMAX(b, a + b)));
325
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 16991 times.
17004 const int min_w4 = FFMIN(0, FFMIN(a, FFMIN(b, a + b)));
326
2/2
✓ Branch 0 taken 16998 times.
✓ Branch 1 taken 6 times.
17004 const int max_h4 = FFMAX(0, FFMAX(c, FFMAX(d, c + d)));
327
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 16998 times.
17004 const int min_h4 = FFMIN(0, FFMIN(c, FFMIN(d, c + d)));
328 17004 const int bx_wx4 = ((max_w4 - min_w4) >> 11) + 9;
329 17004 const int bx_hx4 = ((max_h4 - min_h4) >> 11) + 9;
330 17004 return bx_wx4 * bx_hx4 > 225;
331 } else {
332 23576 const int bx_wxh = (FFABS(a) >> 11) + 9;
333 23576 const int bx_hxh = (FFABS(d) >> 11) + 9;
334 23576 const int bx_wxv = (FFABS(b) >> 11) + 9;
335 23576 const int bx_hxv = (FFABS(c) >> 11) + 9;
336
4/4
✓ Branch 0 taken 23496 times.
✓ Branch 1 taken 80 times.
✓ Branch 2 taken 23406 times.
✓ Branch 3 taken 90 times.
23576 if (bx_wxh * bx_hxh <= 165 && bx_wxv * bx_hxv <= 165)
337 23406 return 0;
338 }
339 170 return 1;
340 }
341
342 40580 static void init_subblock_params(SubblockParams *sp, const MotionInfo* mi,
343 const int cb_width, const int cb_height, const int lx)
344 {
345 40580 const int log2_cbw = av_log2(cb_width);
346 40580 const int log2_cbh = av_log2(cb_height);
347 40580 const Mv* cp_mv = mi->mv[lx];
348 40580 const int num_cp_mv = mi->motion_model_idc + 1;
349 40580 sp->d_hor_x = (cp_mv[1].x - cp_mv[0].x) * (1 << (MAX_CU_DEPTH - log2_cbw));
350 40580 sp->d_ver_x = (cp_mv[1].y - cp_mv[0].y) * (1 << (MAX_CU_DEPTH - log2_cbw));
351
2/2
✓ Branch 0 taken 25227 times.
✓ Branch 1 taken 15353 times.
40580 if (num_cp_mv == 3) {
352 25227 sp->d_hor_y = (cp_mv[2].x - cp_mv[0].x) * (1 << (MAX_CU_DEPTH - log2_cbh));
353 25227 sp->d_ver_y = (cp_mv[2].y - cp_mv[0].y) * (1 << (MAX_CU_DEPTH - log2_cbh));
354 } else {
355 15353 sp->d_hor_y = -sp->d_ver_x;
356 15353 sp->d_ver_y = sp->d_hor_x;
357 }
358 40580 sp->mv_scale_hor = (cp_mv[0].x) * (1 << MAX_CU_DEPTH);
359 40580 sp->mv_scale_ver = (cp_mv[0].y) * (1 << MAX_CU_DEPTH);
360 40580 sp->cb_width = cb_width;
361 40580 sp->cb_height = cb_height;
362 40580 sp->is_fallback = is_fallback_mode(sp, mi->pred_flag);
363 40580 }
364
365 40580 static void derive_subblock_diff_mvs(const VVCLocalContext *lc, PredictionUnit* pu, const SubblockParams* sp, const int lx)
366 {
367 40580 pu->cb_prof_flag[lx] = derive_cb_prof_flag_lx(lc, pu, lx, sp->is_fallback);
368
2/2
✓ Branch 0 taken 37060 times.
✓ Branch 1 taken 3520 times.
40580 if (pu->cb_prof_flag[lx]) {
369 37060 const int dmv_limit = 1 << 5;
370 37060 const int pos_offset_x = 6 * (sp->d_hor_x + sp->d_hor_y);
371 37060 const int pos_offset_y = 6 * (sp->d_ver_x + sp->d_ver_y);
372
2/2
✓ Branch 0 taken 148240 times.
✓ Branch 1 taken 37060 times.
185300 for (int x = 0; x < AFFINE_MIN_BLOCK_SIZE; x++) {
373
2/2
✓ Branch 0 taken 592960 times.
✓ Branch 1 taken 148240 times.
741200 for (int y = 0; y < AFFINE_MIN_BLOCK_SIZE; y++) {
374 592960 LOCAL_ALIGNED_8(Mv, diff, [1]);
375 592960 diff->x = x * (sp->d_hor_x * (1 << 2)) + y * (sp->d_hor_y * (1 << 2)) - pos_offset_x;
376 592960 diff->y = x * (sp->d_ver_x * (1 << 2)) + y * (sp->d_ver_y * (1 << 2)) - pos_offset_y;
377 592960 ff_vvc_round_mv(diff, 0, 8);
378 592960 pu->diff_mv_x[lx][AFFINE_MIN_BLOCK_SIZE * y + x] = av_clip(diff->x, -dmv_limit + 1, dmv_limit - 1);
379 592960 pu->diff_mv_y[lx][AFFINE_MIN_BLOCK_SIZE * y + x] = av_clip(diff->y, -dmv_limit + 1, dmv_limit - 1);
380 }
381 }
382 }
383 40580 }
384
385 40580 static void store_cp_mv(const VVCLocalContext *lc, const MotionInfo *mi, const int lx)
386 {
387 40580 VVCFrameContext *fc = lc->fc;
388 40580 const CodingUnit *cu = lc->cu;
389 40580 const int log2_min_cb_size = fc->ps.sps->min_cb_log2_size_y;
390 40580 const int min_cb_size = fc->ps.sps->min_cb_size_y;
391 40580 const int min_cb_width = fc->ps.pps->min_cb_width;
392 40580 const int num_cp_mv = mi->motion_model_idc + 1;
393
394
2/2
✓ Branch 0 taken 320264 times.
✓ Branch 1 taken 40580 times.
360844 for (int dy = 0; dy < cu->cb_height; dy += min_cb_size) {
395
2/2
✓ Branch 0 taken 3987640 times.
✓ Branch 1 taken 320264 times.
4307904 for (int dx = 0; dx < cu->cb_width; dx += min_cb_size) {
396 3987640 const int x_cb = (cu->x0 + dx) >> log2_min_cb_size;
397 3987640 const int y_cb = (cu->y0 + dy) >> log2_min_cb_size;
398 3987640 const int offset = (y_cb * min_cb_width + x_cb) * MAX_CONTROL_POINTS;
399
400 3987640 memcpy(&fc->tab.cp_mv[lx][offset], mi->mv[lx], sizeof(Mv) * num_cp_mv);
401 3987640 SAMPLE_CTB(fc->tab.mmi, x_cb, y_cb) = mi->motion_model_idc;
402 }
403 }
404 40580 }
405
406 //8.5.5.9 Derivation process for motion vector arrays from affine control point motion vectors
407 32078 void ff_vvc_store_sb_mvs(const VVCLocalContext *lc, PredictionUnit *pu)
408 {
409 32078 const CodingUnit *cu = lc->cu;
410 32078 const MotionInfo *mi = &pu->mi;
411 32078 const int sbw = cu->cb_width / mi->num_sb_x;
412 32078 const int sbh = cu->cb_height / mi->num_sb_y;
413 SubblockParams params[2];
414 MvField mvf;
415
416 32078 mvf.pred_flag = mi->pred_flag;
417 32078 mvf.bcw_idx = mi->bcw_idx;
418 32078 mvf.hpel_if_idx = mi->hpel_if_idx;
419 32078 mvf.ciip_flag = 0;
420
2/2
✓ Branch 0 taken 64156 times.
✓ Branch 1 taken 32078 times.
96234 for (int i = 0; i < 2; i++) {
421 64156 const PredFlag mask = i + 1;
422
2/2
✓ Branch 0 taken 40580 times.
✓ Branch 1 taken 23576 times.
64156 if (mi->pred_flag & mask) {
423 40580 store_cp_mv(lc, mi, i);
424 40580 init_subblock_params(params + i, mi, cu->cb_width, cu->cb_height, i);
425 40580 derive_subblock_diff_mvs(lc, pu, params + i, i);
426 40580 mvf.ref_idx[i] = mi->ref_idx[i];
427 }
428 }
429
430
2/2
✓ Branch 0 taken 253562 times.
✓ Branch 1 taken 32078 times.
285640 for (int sby = 0; sby < mi->num_sb_y; sby++) {
431
2/2
✓ Branch 0 taken 3124200 times.
✓ Branch 1 taken 253562 times.
3377762 for (int sbx = 0; sbx < mi->num_sb_x; sbx++) {
432 3124200 const int x0 = cu->x0 + sbx * sbw;
433 3124200 const int y0 = cu->y0 + sby * sbh;
434
2/2
✓ Branch 0 taken 6248400 times.
✓ Branch 1 taken 3124200 times.
9372600 for (int i = 0; i < 2; i++) {
435 6248400 const PredFlag mask = i + 1;
436
2/2
✓ Branch 0 taken 3987640 times.
✓ Branch 1 taken 2260760 times.
6248400 if (mi->pred_flag & mask) {
437 3987640 const SubblockParams* sp = params + i;
438
2/2
✓ Branch 0 taken 7572 times.
✓ Branch 1 taken 3980068 times.
3987640 const int x_pos_cb = sp->is_fallback ? (cu->cb_width >> 1) : (2 + (sbx << MIN_CU_LOG2));
439
2/2
✓ Branch 0 taken 7572 times.
✓ Branch 1 taken 3980068 times.
3987640 const int y_pos_cb = sp->is_fallback ? (cu->cb_height >> 1) : (2 + (sby << MIN_CU_LOG2));
440 3987640 Mv *mv = mvf.mv + i;
441
442 3987640 mv->x = sp->mv_scale_hor + sp->d_hor_x * x_pos_cb + sp->d_hor_y * y_pos_cb;
443 3987640 mv->y = sp->mv_scale_ver + sp->d_ver_x * x_pos_cb + sp->d_ver_y * y_pos_cb;
444 3987640 ff_vvc_round_mv(mv, 0, MAX_CU_DEPTH);
445 3987640 ff_vvc_clip_mv(mv);
446 }
447 }
448 3124200 ff_vvc_set_mvf(lc, x0, y0, sbw, sbh, &mvf);
449 }
450 }
451 32078 }
452
453 24398 void ff_vvc_store_gpm_mvf(const VVCLocalContext *lc, const PredictionUnit *pu)
454 {
455 24398 const CodingUnit *cu = lc->cu;
456 24398 const int angle_idx = ff_vvc_gpm_angle_idx[pu->gpm_partition_idx];
457 24398 const int distance_idx = ff_vvc_gpm_distance_idx[pu->gpm_partition_idx];
458 24398 const int displacement_x = ff_vvc_gpm_distance_lut[angle_idx];
459 24398 const int displacement_y = ff_vvc_gpm_distance_lut[(angle_idx + 8) % 32];
460
4/4
✓ Branch 0 taken 12809 times.
✓ Branch 1 taken 11589 times.
✓ Branch 2 taken 10291 times.
✓ Branch 3 taken 2518 times.
24398 const int is_flip = angle_idx >= 13 &&angle_idx <= 27;
461
6/6
✓ Branch 0 taken 22876 times.
✓ Branch 1 taken 1522 times.
✓ Branch 2 taken 20206 times.
✓ Branch 3 taken 2670 times.
✓ Branch 4 taken 4845 times.
✓ Branch 5 taken 15361 times.
24398 const int shift_hor = (angle_idx % 16 == 8 || (angle_idx % 16 && cu->cb_height >= cu->cb_width)) ? 0 : 1;
462
2/2
✓ Branch 0 taken 14357 times.
✓ Branch 1 taken 10041 times.
24398 const int sign = angle_idx < 16 ? 1 : -1;
463 24398 const int block_size = 4;
464 24398 int offset_x = (-cu->cb_width) >> 1;
465 24398 int offset_y = (-cu->cb_height) >> 1;
466
467
2/2
✓ Branch 0 taken 16883 times.
✓ Branch 1 taken 7515 times.
24398 if (!shift_hor)
468 16883 offset_y += sign * ((distance_idx * cu->cb_height) >> 3);
469 else
470 7515 offset_x += sign * ((distance_idx * cu->cb_width) >> 3);
471
472
2/2
✓ Branch 0 taken 108608 times.
✓ Branch 1 taken 24398 times.
133006 for (int y = 0; y < cu->cb_height; y += block_size) {
473
2/2
✓ Branch 0 taken 493236 times.
✓ Branch 1 taken 108608 times.
601844 for (int x = 0; x < cu->cb_width; x += block_size) {
474 493236 const int motion_idx = (((x + offset_x) * (1 << 1)) + 5) * displacement_x +
475 493236 (((y + offset_y) * (1 << 1)) + 5) * displacement_y;
476
6/6
✓ Branch 0 taken 248562 times.
✓ Branch 1 taken 244674 times.
✓ Branch 2 taken 149161 times.
✓ Branch 3 taken 99401 times.
✓ Branch 4 taken 244674 times.
✓ Branch 5 taken 149161 times.
493236 const int s_type = FFABS(motion_idx) < 32 ? 2 : (motion_idx <= 0 ? (1 - is_flip) : is_flip);
477 493236 const int pred_flag = pu->gpm_mv[0].pred_flag | pu->gpm_mv[1].pred_flag;
478 493236 const int x0 = cu->x0 + x;
479 493236 const int y0 = cu->y0 + y;
480
481
2/2
✓ Branch 0 taken 191541 times.
✓ Branch 1 taken 301695 times.
493236 if (!s_type)
482 191541 ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, pu->gpm_mv + 0);
483
5/6
✓ Branch 0 taken 99401 times.
✓ Branch 1 taken 202294 times.
✓ Branch 2 taken 99401 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 52726 times.
✓ Branch 5 taken 46675 times.
301695 else if (s_type == 1 || (s_type == 2 && pred_flag != PF_BI))
484 255020 ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, pu->gpm_mv + 1);
485 else {
486 46675 MvField mvf = pu->gpm_mv[0];
487 46675 const MvField *mv1 = &pu->gpm_mv[1];
488 46675 const int lx = mv1->pred_flag - PF_L0;
489 46675 mvf.pred_flag = PF_BI;
490 46675 mvf.ref_idx[lx] = mv1->ref_idx[lx];
491 46675 mvf.mv[lx] = mv1->mv[lx];
492 46675 ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, &mvf);
493 }
494 }
495 }
496 24398 }
497
498 263955 void ff_vvc_store_mvf(const VVCLocalContext *lc, const MvField *mvf)
499 {
500 263955 const CodingUnit *cu = lc->cu;
501 263955 ff_vvc_set_mvf(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height, mvf);
502 263955 }
503
504 49902 void ff_vvc_store_mv(const VVCLocalContext *lc, const MotionInfo *mi)
505 {
506 49902 const CodingUnit *cu = lc->cu;
507 MvField mvf;
508
509 49902 mvf.hpel_if_idx = mi->hpel_if_idx;
510 49902 mvf.bcw_idx = mi->bcw_idx;
511 49902 mvf.pred_flag = mi->pred_flag;
512 49902 mvf.ciip_flag = 0;
513
514
2/2
✓ Branch 0 taken 99804 times.
✓ Branch 1 taken 49902 times.
149706 for (int i = 0; i < 2; i++) {
515 99804 const PredFlag mask = i + 1;
516
2/2
✓ Branch 0 taken 64883 times.
✓ Branch 1 taken 34921 times.
99804 if (mvf.pred_flag & mask) {
517 64883 mvf.mv[i] = mi->mv[i][0];
518 64883 mvf.ref_idx[i] = mi->ref_idx[i];
519 }
520 }
521 49902 ff_vvc_set_mvf(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height, &mvf);
522 49902 }
523
524 typedef enum NeighbourIdx {
525 A0,
526 A1,
527 A2,
528 B0,
529 B1,
530 B2,
531 B3,
532 NUM_NBS,
533 NB_IDX_NONE = NUM_NBS,
534 } NeighbourIdx;
535
536 typedef struct Neighbour {
537 int x;
538 int y;
539
540 int checked;
541 int available;
542 } Neighbour;
543
544 typedef struct NeighbourContext {
545 Neighbour neighbours[NUM_NBS];
546 const VVCLocalContext *lc;
547 } NeighbourContext;
548
549 412466 static int is_a0_available(const VVCLocalContext *lc, const CodingUnit *cu)
550 {
551 412466 const VVCFrameContext *fc = lc->fc;
552 412466 const VVCSPS *sps = fc->ps.sps;
553 412466 const int x0b = av_mod_uintp2(cu->x0, sps->ctb_log2_size_y);
554 int cand_bottom_left;
555
556
4/4
✓ Branch 0 taken 92481 times.
✓ Branch 1 taken 319985 times.
✓ Branch 2 taken 12100 times.
✓ Branch 3 taken 80381 times.
412466 if (!x0b && !lc->ctb_left_flag) {
557 12100 cand_bottom_left = 0;
558 } else {
559 400366 const int log2_min_cb_size = sps->min_cb_log2_size_y;
560 400366 const int min_cb_width = fc->ps.pps->min_cb_width;
561 400366 const int x = (cu->x0 - 1) >> log2_min_cb_size;
562 400366 const int y = (cu->y0 + cu->cb_height) >> log2_min_cb_size;
563 400366 const int max_y = FFMIN(fc->ps.pps->height, ((cu->y0 >> sps->ctb_log2_size_y) + 1) << sps->ctb_log2_size_y);
564
2/2
✓ Branch 0 taken 86732 times.
✓ Branch 1 taken 313634 times.
400366 if (cu->y0 + cu->cb_height >= max_y)
565 86732 cand_bottom_left = 0;
566 else
567 313634 cand_bottom_left = SAMPLE_CTB(fc->tab.cb_width[0], x, y) != 0;
568 }
569 412466 return cand_bottom_left;
570 }
571
572 412466 static void init_neighbour_context(NeighbourContext *ctx, const VVCLocalContext *lc)
573 {
574 412466 const CodingUnit *cu = lc->cu;
575 412466 const NeighbourAvailable *na = &lc->na;
576 412466 const int x0 = cu->x0;
577 412466 const int y0 = cu->y0;
578 412466 const int cb_width = cu->cb_width;
579 412466 const int cb_height = cu->cb_height;
580 412466 const int a0_available = is_a0_available(lc, cu);
581
582 412466 Neighbour neighbours[NUM_NBS] = {
583 412466 { x0 - 1, y0 + cb_height, !a0_available }, //A0
584 412466 { x0 - 1, y0 + cb_height - 1, !na->cand_left }, //A1
585 412466 { x0 - 1, y0, !na->cand_left }, //A2
586 412466 { x0 + cb_width, y0 - 1, !na->cand_up_right }, //B0
587 412466 { x0 + cb_width - 1, y0 - 1, !na->cand_up }, //B1
588 412466 { x0 - 1, y0 - 1, !na->cand_up_left }, //B2
589 412466 { x0, y0 - 1, !na->cand_up }, //B3
590 };
591
592 412466 memcpy(ctx->neighbours, neighbours, sizeof(neighbours));
593 412466 ctx->lc = lc;
594 412466 }
595
596 837582 static av_always_inline PredMode pred_flag_to_mode(PredFlag pred)
597 {
598
2/2
✓ Branch 0 taken 836266 times.
✓ Branch 1 taken 1316 times.
837582 return pred == PF_IBC ? MODE_IBC : (pred == PF_INTRA ? MODE_INTRA : MODE_INTER);
599 }
600
601 1083212 static int check_available(Neighbour *n, const VVCLocalContext *lc, const int check_mer)
602 {
603 1083212 const VVCFrameContext *fc = lc->fc;
604 1083212 const VVCSPS *sps = fc->ps.sps;
605 1083212 const CodingUnit *cu = lc->cu;
606 1083212 const MvField *tab_mvf = fc->tab.mvf;
607 1083212 const int min_pu_width = fc->ps.pps->min_pu_width;
608
609
2/2
✓ Branch 0 taken 837582 times.
✓ Branch 1 taken 245630 times.
1083212 if (!n->checked) {
610 837582 n->checked = 1;
611
4/4
✓ Branch 0 taken 87906 times.
✓ Branch 1 taken 749676 times.
✓ Branch 2 taken 87706 times.
✓ Branch 3 taken 200 times.
837582 n->available = !sps->r->sps_entropy_coding_sync_enabled_flag || ((n->x >> sps->ctb_log2_size_y) <= (cu->x0 >> sps->ctb_log2_size_y));
612 837582 n->available &= cu->pred_mode == pred_flag_to_mode(TAB_MVF(n->x, n->y).pred_flag);
613
2/2
✓ Branch 0 taken 667942 times.
✓ Branch 1 taken 169640 times.
837582 if (check_mer)
614 667942 n->available &= !is_same_mer(fc, n->x, n->y, cu->x0, cu->y0);
615 }
616 1083212 return n->available;
617 }
618
619 512016 static const MvField *mv_merge_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand)
620 {
621 512016 const VVCFrameContext *fc = lc->fc;
622 512016 const int min_pu_width = fc->ps.pps->min_pu_width;
623 512016 const MvField* tab_mvf = fc->tab.mvf;
624 512016 const MvField *mvf = &TAB_MVF(x_cand, y_cand);
625
626 512016 return mvf;
627 }
628
629 638927 static const MvField* mv_merge_from_nb(NeighbourContext *ctx, const NeighbourIdx nb)
630 {
631 638927 const VVCLocalContext *lc = ctx->lc;
632 638927 Neighbour *n = &ctx->neighbours[nb];
633
634
2/2
✓ Branch 1 taken 512016 times.
✓ Branch 2 taken 126911 times.
638927 if (check_available(n, lc, 1))
635 512016 return mv_merge_candidate(lc, n->x, n->y);
636 126911 return 0;
637 }
638 #define MV_MERGE_FROM_NB(nb) mv_merge_from_nb(&nctx, nb)
639
640 //8.5.2.3 Derivation process for spatial merging candidates
641 288353 static int mv_merge_spatial_candidates(const VVCLocalContext *lc, const int merge_idx,
642 const MvField **nb_list, MvField *cand_list, int *nb_merge_cand)
643 {
644 const MvField *cand;
645 288353 int num_cands = 0;
646 NeighbourContext nctx;
647
648 static NeighbourIdx nbs[][2] = {
649 {B1, NB_IDX_NONE },
650 {A1, B1 },
651 {B0, B1 },
652 {A0, A1 },
653 };
654
655 288353 init_neighbour_context(&nctx, lc);
656
2/2
✓ Branch 0 taken 578473 times.
✓ Branch 1 taken 61092 times.
639565 for (int i = 0; i < FF_ARRAY_ELEMS(nbs); i++) {
657 578473 NeighbourIdx nb = nbs[i][0];
658 578473 NeighbourIdx old = nbs[i][1];
659 578473 cand = nb_list[nb] = MV_MERGE_FROM_NB(nb);
660
4/4
✓ Branch 0 taken 462697 times.
✓ Branch 1 taken 115776 times.
✓ Branch 3 taken 417471 times.
✓ Branch 4 taken 45226 times.
578473 if (cand && !compare_mv_ref_idx(cand, nb_list[old])) {
661 417471 cand_list[num_cands] = *cand;
662
2/2
✓ Branch 0 taken 227261 times.
✓ Branch 1 taken 190210 times.
417471 if (merge_idx == num_cands)
663 227261 return 1;
664 190210 num_cands++;
665 }
666 }
667
2/2
✓ Branch 0 taken 60454 times.
✓ Branch 1 taken 638 times.
61092 if (num_cands != 4) {
668 60454 cand = MV_MERGE_FROM_NB(B2);
669
4/4
✓ Branch 0 taken 49319 times.
✓ Branch 1 taken 11135 times.
✓ Branch 3 taken 29748 times.
✓ Branch 4 taken 19571 times.
60454 if (cand && !compare_mv_ref_idx(cand, nb_list[A1])
670
2/2
✓ Branch 1 taken 21086 times.
✓ Branch 2 taken 8662 times.
29748 && !compare_mv_ref_idx(cand, nb_list[B1])) {
671 21086 cand_list[num_cands] = *cand;
672
2/2
✓ Branch 0 taken 9492 times.
✓ Branch 1 taken 11594 times.
21086 if (merge_idx == num_cands)
673 9492 return 1;
674 11594 num_cands++;
675 }
676 }
677 51600 *nb_merge_cand = num_cands;
678 51600 return 0;
679 }
680
681 51600 static int mv_merge_temporal_candidate(const VVCLocalContext *lc, MvField *cand)
682 {
683 51600 const VVCFrameContext *fc = lc->fc;
684 51600 const CodingUnit *cu = lc->cu;
685
686 51600 memset(cand, 0, sizeof(*cand));
687
3/4
✓ Branch 0 taken 51600 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 48780 times.
✓ Branch 3 taken 2820 times.
51600 if (fc->ps.ph.r->ph_temporal_mvp_enabled_flag && (cu->cb_width * cu->cb_height > 32)) {
688 48780 int available_l0 = temporal_luma_motion_vector(lc, 0, cand->mv + 0, 0, 1, 0);
689 97560 int available_l1 = IS_B(lc->sc->sh.r) ?
690
2/2
✓ Branch 0 taken 46382 times.
✓ Branch 1 taken 2398 times.
48780 temporal_luma_motion_vector(lc, 0, cand->mv + 1, 1, 1, 0) : 0;
691 48780 cand->pred_flag = available_l0 + (available_l1 << 1);
692 }
693 51600 return cand->pred_flag;
694 }
695
696 //8.5.2.6 Derivation process for history-based merging candidates
697 31899 static int mv_merge_history_candidates(const VVCLocalContext *lc, const int merge_idx,
698 const MvField **nb_list, MvField *cand_list, int *num_cands)
699 {
700 31899 const VVCSPS *sps = lc->fc->ps.sps;
701 31899 const EntryPoint* ep = lc->ep;
702
4/4
✓ Branch 0 taken 83612 times.
✓ Branch 1 taken 1591 times.
✓ Branch 2 taken 75373 times.
✓ Branch 3 taken 8239 times.
85203 for (int i = 1; i <= ep->num_hmvp && (*num_cands < sps->max_num_merge_cand - 1); i++) {
703 75373 const MvField *h = &ep->hmvp[ep->num_hmvp - i];
704
6/6
✓ Branch 0 taken 55370 times.
✓ Branch 1 taken 20003 times.
✓ Branch 3 taken 37209 times.
✓ Branch 4 taken 18161 times.
✓ Branch 6 taken 9882 times.
✓ Branch 7 taken 27327 times.
75373 const int same_motion = i <= 2 && (compare_mv_ref_idx(h, nb_list[A1]) || compare_mv_ref_idx(h, nb_list[B1]));
705
2/2
✓ Branch 0 taken 47330 times.
✓ Branch 1 taken 28043 times.
75373 if (!same_motion) {
706 47330 cand_list[*num_cands] = *h;
707
2/2
✓ Branch 0 taken 22069 times.
✓ Branch 1 taken 25261 times.
47330 if (merge_idx == *num_cands)
708 22069 return 1;
709 25261 (*num_cands)++;
710 }
711 }
712 9830 return 0;
713 }
714
715 //8.5.2.4 Derivation process for pairwise average merging candidate
716 9830 static int mv_merge_pairwise_candidate(MvField *cand_list, const int num_cands, const int is_b)
717 {
718
2/2
✓ Branch 0 taken 9584 times.
✓ Branch 1 taken 246 times.
9830 if (num_cands > 1) {
719
2/2
✓ Branch 0 taken 9140 times.
✓ Branch 1 taken 444 times.
9584 const int num_ref_rists = is_b ? 2 : 1;
720 9584 const MvField* p0 = cand_list + 0;
721 9584 const MvField* p1 = cand_list + 1;
722 9584 MvField* cand = cand_list + num_cands;
723
724 9584 cand->pred_flag = 0;
725
2/2
✓ Branch 0 taken 18724 times.
✓ Branch 1 taken 9584 times.
28308 for (int i = 0; i < num_ref_rists; i++) {
726 18724 PredFlag mask = i + 1;
727
2/2
✓ Branch 0 taken 15519 times.
✓ Branch 1 taken 3205 times.
18724 if (p0->pred_flag & mask) {
728 15519 cand->pred_flag |= mask;
729 15519 cand->ref_idx[i] = p0->ref_idx[i];
730
2/2
✓ Branch 0 taken 13885 times.
✓ Branch 1 taken 1634 times.
15519 if (p1->pred_flag & mask) {
731 13885 Mv *mv = cand->mv + i;
732 13885 mv->x = p0->mv[i].x + p1->mv[i].x;
733 13885 mv->y = p0->mv[i].y + p1->mv[i].y;
734 13885 ff_vvc_round_mv(mv, 0, 1);
735 } else {
736 1634 cand->mv[i] = p0->mv[i];
737 }
738
2/2
✓ Branch 0 taken 1893 times.
✓ Branch 1 taken 1312 times.
3205 } else if (p1->pred_flag & mask) {
739 1893 cand->pred_flag |= mask;
740 1893 cand->mv[i] = p1->mv[i];
741 1893 cand->ref_idx[i] = p1->ref_idx[i];
742 }
743 }
744
1/2
✓ Branch 0 taken 9584 times.
✗ Branch 1 not taken.
9584 if (cand->pred_flag) {
745
2/2
✓ Branch 0 taken 8995 times.
✓ Branch 1 taken 589 times.
9584 cand->hpel_if_idx = p0->hpel_if_idx == p1->hpel_if_idx ? p0->hpel_if_idx : 0;
746 9584 cand->bcw_idx = 0;
747 9584 cand->ciip_flag = 0;
748 9584 return 1;
749 }
750 }
751 246 return 0;
752 }
753
754 //8.5.2.5 Derivation process for zero motion vector merging candidates
755 494 static void mv_merge_zero_motion_candidate(const VVCLocalContext *lc, const int merge_idx,
756 MvField *cand_list, int num_cands)
757 {
758 494 const VVCSPS *sps = lc->fc->ps.sps;
759 494 const H266RawSliceHeader *rsh = lc->sc->sh.r;
760 988 const int num_ref_idx = IS_P(rsh) ?
761
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 460 times.
494 rsh->num_ref_idx_active[L0] : FFMIN(rsh->num_ref_idx_active[L0], rsh->num_ref_idx_active[L1]);
762 494 int zero_idx = 0;
763
764
1/2
✓ Branch 0 taken 652 times.
✗ Branch 1 not taken.
652 while (num_cands < sps->max_num_merge_cand) {
765 652 MvField *cand = cand_list + num_cands;
766
767
2/2
✓ Branch 0 taken 590 times.
✓ Branch 1 taken 62 times.
652 cand->pred_flag = PF_L0 + (IS_B(rsh) << 1);
768 652 AV_ZERO64(cand->mv + 0);
769 652 AV_ZERO64(cand->mv + 1);
770
2/2
✓ Branch 0 taken 627 times.
✓ Branch 1 taken 25 times.
652 cand->ref_idx[0] = zero_idx < num_ref_idx ? zero_idx : 0;
771
2/2
✓ Branch 0 taken 627 times.
✓ Branch 1 taken 25 times.
652 cand->ref_idx[1] = zero_idx < num_ref_idx ? zero_idx : 0;
772 652 cand->bcw_idx = 0;
773 652 cand->hpel_if_idx = 0;
774
2/2
✓ Branch 0 taken 494 times.
✓ Branch 1 taken 158 times.
652 if (merge_idx == num_cands)
775 494 return;
776 158 num_cands++;
777 158 zero_idx++;
778 }
779 }
780
781 288353 static void mv_merge_mode(const VVCLocalContext *lc, const int merge_idx, MvField *cand_list)
782 {
783 288353 int num_cands = 0;
784 288353 const MvField *nb_list[NUM_NBS + 1] = { NULL };
785
786
2/2
✓ Branch 1 taken 236753 times.
✓ Branch 2 taken 51600 times.
288353 if (mv_merge_spatial_candidates(lc, merge_idx, nb_list, cand_list, &num_cands))
787 287859 return;
788
789
2/2
✓ Branch 1 taken 40546 times.
✓ Branch 2 taken 11054 times.
51600 if (mv_merge_temporal_candidate(lc, &cand_list[num_cands])) {
790
2/2
✓ Branch 0 taken 19701 times.
✓ Branch 1 taken 20845 times.
40546 if (merge_idx == num_cands)
791 19701 return;
792 20845 num_cands++;
793 }
794
795
2/2
✓ Branch 1 taken 22069 times.
✓ Branch 2 taken 9830 times.
31899 if (mv_merge_history_candidates(lc, merge_idx, nb_list, cand_list, &num_cands))
796 22069 return;
797
798
2/2
✓ Branch 1 taken 9584 times.
✓ Branch 2 taken 246 times.
9830 if (mv_merge_pairwise_candidate(cand_list, num_cands, IS_B(lc->sc->sh.r))) {
799
2/2
✓ Branch 0 taken 9336 times.
✓ Branch 1 taken 248 times.
9584 if (merge_idx == num_cands)
800 9336 return;
801 248 num_cands++;
802 }
803
804 494 mv_merge_zero_motion_candidate(lc, merge_idx, cand_list, num_cands);
805 }
806
807 //8.5.2.2 Derivation process for luma motion vectors for merge mode
808 263955 void ff_vvc_luma_mv_merge_mode(VVCLocalContext *lc, const int merge_idx, const int ciip_flag, MvField *mv)
809 {
810 263955 const CodingUnit *cu = lc->cu;
811 MvField cand_list[MRG_MAX_NUM_CANDS];
812
813 263955 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
814 263955 mv_merge_mode(lc, merge_idx, cand_list);
815 263955 *mv = cand_list[merge_idx];
816 //ciip flag in not inhritable
817 263955 mv->ciip_flag = ciip_flag;
818 263955 }
819
820 //8.5.4.2 Derivation process for luma motion vectors for geometric partitioning merge mode
821 24398 void ff_vvc_luma_mv_merge_gpm(VVCLocalContext *lc, const int merge_gpm_idx[2], MvField *mv)
822 {
823 24398 const CodingUnit *cu = lc->cu;
824 MvField cand_list[MRG_MAX_NUM_CANDS];
825
826 24398 const int idx[] = { merge_gpm_idx[0], merge_gpm_idx[1] + (merge_gpm_idx[1] >= merge_gpm_idx[0]) };
827
828 24398 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
829 24398 mv_merge_mode(lc, FFMAX(idx[0], idx[1]), cand_list);
830 24398 memset(mv, 0, 2 * sizeof(*mv));
831
2/2
✓ Branch 0 taken 48796 times.
✓ Branch 1 taken 24398 times.
73194 for (int i = 0; i < 2; i++) {
832 48796 int lx = idx[i] & 1;
833 48796 int mask = lx + PF_L0;
834 48796 MvField *cand = cand_list + idx[i];
835
2/2
✓ Branch 0 taken 13299 times.
✓ Branch 1 taken 35497 times.
48796 if (!(cand->pred_flag & mask)) {
836 13299 lx = !lx;
837 13299 mask = lx + PF_L0;
838 }
839 48796 mv[i].pred_flag = mask;
840 48796 mv[i].ref_idx[lx] = cand->ref_idx[lx];
841 48796 mv[i].mv[lx] = cand->mv[lx];
842 }
843
844 24398 }
845
846 //8.5.5.5 Derivation process for luma affine control point motion vectors from a neighbouring block
847 28220 static void affine_cps_from_nb(const VVCLocalContext *lc,
848 const int x_nb, int y_nb, const int nbw, const int nbh, const int lx,
849 Mv *cps, int num_cps)
850 {
851 28220 const VVCFrameContext *fc = lc->fc;
852 28220 const CodingUnit *cu = lc->cu;
853 28220 const int x0 = cu->x0;
854 28220 const int y0 = cu->y0;
855 28220 const int cb_width = cu->cb_width;
856 28220 const int cb_height = cu->cb_height;
857 28220 const MvField* tab_mvf = fc->tab.mvf;
858 28220 const int min_cb_log2_size = fc->ps.sps->min_cb_log2_size_y;
859 28220 const int min_cb_width = fc->ps.pps->min_cb_width;
860
861 28220 const int log2_nbw = ff_log2(nbw);
862 28220 const int log2_nbh = ff_log2(nbh);
863
4/4
✓ Branch 0 taken 8403 times.
✓ Branch 1 taken 19817 times.
✓ Branch 2 taken 3258 times.
✓ Branch 3 taken 5145 times.
28220 const int is_ctb_boundary = !((y_nb + nbh) % fc->ps.sps->ctb_size_y) && (y_nb + nbh == y0);
864 const Mv *l, *r;
865 int mv_scale_hor, mv_scale_ver, d_hor_x, d_ver_x, d_hor_y, d_ver_y, motion_model_idc_nb;
866
2/2
✓ Branch 0 taken 3258 times.
✓ Branch 1 taken 24962 times.
28220 if (is_ctb_boundary) {
867 3258 const int min_pu_width = fc->ps.pps->min_pu_width;
868 3258 l = &TAB_MVF(x_nb, y_nb + nbh - 1).mv[lx];
869 3258 r = &TAB_MVF(x_nb + nbw - 1, y_nb + nbh - 1).mv[lx];
870 } else {
871 24962 const int x = x_nb >> min_cb_log2_size;
872 24962 const int y = y_nb >> min_cb_log2_size;
873 24962 motion_model_idc_nb = SAMPLE_CTB(fc->tab.mmi, x, y);
874
875 24962 l = &TAB_CP_MV(lx, x_nb, y_nb);
876 24962 r = &TAB_CP_MV(lx, x_nb + nbw - 1, y_nb) + 1;
877 }
878 28220 mv_scale_hor = l->x * (1 << 7);
879 28220 mv_scale_ver = l->y * (1 << 7);
880 28220 d_hor_x = (r->x - l->x) * (1 << (7 - log2_nbw));
881 28220 d_ver_x = (r->y - l->y) * (1 << (7 - log2_nbw));
882
4/4
✓ Branch 0 taken 24962 times.
✓ Branch 1 taken 3258 times.
✓ Branch 2 taken 14461 times.
✓ Branch 3 taken 10501 times.
28220 if (!is_ctb_boundary && motion_model_idc_nb == MOTION_6_PARAMS_AFFINE) {
883 14461 const Mv* lb = &TAB_CP_MV(lx, x_nb, y_nb + nbh - 1) + 2;
884 14461 d_hor_y = (lb->x - l->x) * (1 << (7 - log2_nbh));
885 14461 d_ver_y = (lb->y - l->y) * (1 << (7 - log2_nbh));
886 } else {
887 13759 d_hor_y = -d_ver_x;
888 13759 d_ver_y = d_hor_x;
889 }
890
891
2/2
✓ Branch 0 taken 3258 times.
✓ Branch 1 taken 24962 times.
28220 if (is_ctb_boundary) {
892 3258 y_nb = y0;
893 }
894 28220 cps[0].x = mv_scale_hor + d_hor_x * (x0 - x_nb) + d_hor_y * (y0 - y_nb);
895 28220 cps[0].y = mv_scale_ver + d_ver_x * (x0 - x_nb) + d_ver_y * (y0 - y_nb);
896 28220 cps[1].x = mv_scale_hor + d_hor_x * (x0 + cb_width - x_nb) + d_hor_y * (y0 - y_nb);
897 28220 cps[1].y = mv_scale_ver + d_ver_x * (x0 + cb_width - x_nb) + d_ver_y * (y0 - y_nb);
898
2/2
✓ Branch 0 taken 15982 times.
✓ Branch 1 taken 12238 times.
28220 if (num_cps == 3) {
899 15982 cps[2].x = mv_scale_hor + d_hor_x * (x0 - x_nb) + d_hor_y * (y0 + cb_height - y_nb);
900 15982 cps[2].y = mv_scale_ver + d_ver_x * (x0 - x_nb) + d_ver_y * (y0 + cb_height - y_nb);
901 }
902
2/2
✓ Branch 0 taken 72422 times.
✓ Branch 1 taken 28220 times.
100642 for (int i = 0; i < num_cps; i++) {
903 72422 ff_vvc_round_mv(cps + i, 0, 7);
904 72422 ff_vvc_clip_mv(cps + i);
905 }
906 28220 }
907
908 //derive affine neighbour's postion, width and height,
909 88322 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)
910 {
911 88322 const int log2_min_cb_size = fc->ps.sps->min_cb_log2_size_y;
912 88322 const int min_cb_width = fc->ps.pps->min_cb_width;
913 88322 const int x = x_nb >> log2_min_cb_size;
914 88322 const int y = y_nb >> log2_min_cb_size;
915 88322 const int motion_model_idc = SAMPLE_CTB(fc->tab.mmi, x, y);
916
2/2
✓ Branch 0 taken 25277 times.
✓ Branch 1 taken 63045 times.
88322 if (motion_model_idc) {
917 25277 *x_cb = SAMPLE_CTB(fc->tab.cb_pos_x[0], x, y);
918 25277 *y_cb = SAMPLE_CTB(fc->tab.cb_pos_y[0], x, y);
919 25277 *cbw = SAMPLE_CTB(fc->tab.cb_width[0], x, y);
920 25277 *cbh = SAMPLE_CTB(fc->tab.cb_height[0], x, y);
921 }
922 88322 return motion_model_idc;
923 }
924
925 //part of 8.5.5.2 Derivation process for motion vectors and reference indices in subblock merge mode
926 60692 static int affine_merge_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand, MotionInfo* mi)
927 {
928 60692 const VVCFrameContext *fc = lc->fc;
929 int x, y, w, h, motion_model_idc;
930
931 60692 motion_model_idc = affine_neighbour_cb(fc, x_cand, y_cand, &x, &y, &w, &h);
932
2/2
✓ Branch 0 taken 18296 times.
✓ Branch 1 taken 42396 times.
60692 if (motion_model_idc) {
933 18296 const int min_pu_width = fc->ps.pps->min_pu_width;
934 18296 const MvField* tab_mvf = fc->tab.mvf;
935 18296 const MvField *mvf = &TAB_MVF(x, y);
936
937 18296 mi->bcw_idx = mvf->bcw_idx;
938 18296 mi->pred_flag = mvf->pred_flag;
939
2/2
✓ Branch 0 taken 36592 times.
✓ Branch 1 taken 18296 times.
54888 for (int i = 0; i < 2; i++) {
940 36592 PredFlag mask = i + 1;
941
2/2
✓ Branch 0 taken 22584 times.
✓ Branch 1 taken 14008 times.
36592 if (mi->pred_flag & mask) {
942 22584 affine_cps_from_nb(lc, x, y, w, h, i, &mi->mv[i][0], motion_model_idc + 1);
943 }
944 36592 mi->ref_idx[i] = mvf->ref_idx[i];
945 }
946 18296 mi->motion_model_idc = motion_model_idc;
947 }
948 60692 return motion_model_idc;
949 }
950
951 40912 static int affine_merge_from_nbs(NeighbourContext *ctx, const NeighbourIdx *nbs, const int num_nbs, MotionInfo* cand)
952 {
953 40912 const VVCLocalContext *lc = ctx->lc;
954
2/2
✓ Branch 0 taken 85321 times.
✓ Branch 1 taken 22616 times.
107937 for (int i = 0; i < num_nbs; i++) {
955 85321 Neighbour *n = &ctx->neighbours[nbs[i]];
956
4/4
✓ Branch 1 taken 60692 times.
✓ Branch 2 taken 24629 times.
✓ Branch 4 taken 18296 times.
✓ Branch 5 taken 42396 times.
85321 if (check_available(n, lc, 1) && affine_merge_candidate(lc, n->x, n->y, cand))
957 18296 return 1;
958 }
959 22616 return 0;
960 }
961 #define AFFINE_MERGE_FROM_NBS(nbs) affine_merge_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), mi)
962
963
964 89308 static const MvField* derive_corner_mvf(NeighbourContext *ctx, const NeighbourIdx *neighbour, const int num_neighbour)
965 {
966 89308 const VVCFrameContext *fc = ctx->lc->fc;
967 89308 const MvField *tab_mvf = fc->tab.mvf;
968 89308 const int min_pu_width = fc->ps.pps->min_pu_width;
969
2/2
✓ Branch 0 taken 92265 times.
✓ Branch 1 taken 3741 times.
96006 for (int i = 0; i < num_neighbour; i++) {
970 92265 Neighbour *n = &ctx->neighbours[neighbour[i]];
971
2/2
✓ Branch 1 taken 85567 times.
✓ Branch 2 taken 6698 times.
92265 if (check_available(n, ctx->lc, 1)) {
972 85567 return &TAB_MVF(n->x, n->y);
973 }
974 }
975 3741 return NULL;
976 }
977
978 #define DERIVE_CORNER_MV(nbs) derive_corner_mvf(nctx, nbs, FF_ARRAY_ELEMS(nbs))
979
980 // check if the mv's and refidx are the same between A and B
981 49684 static av_always_inline int compare_pf_ref_idx(const MvField *A, const struct MvField *B, const struct MvField *C, const int lx)
982 {
983
984 49684 const PredFlag mask = (lx + 1) & A->pred_flag;
985
2/2
✓ Branch 0 taken 17628 times.
✓ Branch 1 taken 32056 times.
49684 if (!(B->pred_flag & mask))
986 17628 return 0;
987
2/2
✓ Branch 0 taken 1432 times.
✓ Branch 1 taken 30624 times.
32056 if (A->ref_idx[lx] != B->ref_idx[lx])
988 1432 return 0;
989
2/2
✓ Branch 0 taken 25879 times.
✓ Branch 1 taken 4745 times.
30624 if (C) {
990
2/2
✓ Branch 0 taken 885 times.
✓ Branch 1 taken 24994 times.
25879 if (!(C->pred_flag & mask))
991 885 return 0;
992
2/2
✓ Branch 0 taken 1003 times.
✓ Branch 1 taken 23991 times.
24994 if (A->ref_idx[lx] != C->ref_idx[lx])
993 1003 return 0;
994 }
995 28736 return 1;
996 }
997
998 1251056 static av_always_inline void sb_clip_location(const VVCLocalContext *lc,
999 const int x_ctb, const int y_ctb, const Mv* temp_mv, int *x, int *y)
1000 {
1001 1251056 const VVCFrameContext *fc = lc->fc;
1002 1251056 const VVCPPS *pps = fc->ps.pps;
1003 1251056 const int ctb_log2_size = fc->ps.sps->ctb_log2_size_y;
1004 1251056 const int subpic_idx = lc->sc->sh.r->curr_subpic_idx;
1005 1251056 const int x_end = pps->subpic_x[subpic_idx] + pps->subpic_width[subpic_idx];
1006 1251056 const int y_end = pps->subpic_y[subpic_idx] + pps->subpic_height[subpic_idx];
1007
1008 1251056 *x = av_clip(*x + temp_mv->x, x_ctb, FFMIN(x_end - 1, x_ctb + (1 << ctb_log2_size) + 3)) & ~7;
1009
2/2
✓ Branch 0 taken 1104968 times.
✓ Branch 1 taken 146088 times.
1251056 *y = av_clip(*y + temp_mv->y, y_ctb, FFMIN(y_end - 1, y_ctb + (1 << ctb_log2_size) - 1)) & ~7;
1010 1251056 }
1011
1012 1251056 static void sb_temproal_luma_motion(const VVCLocalContext *lc,
1013 const int x_ctb, const int y_ctb, const Mv *temp_mv,
1014 int x, int y, uint8_t *pred_flag, Mv *mv)
1015 {
1016 MvField temp_col;
1017 Mv* mvLXCol;
1018 1251056 const int refIdxLx = 0;
1019 1251056 const VVCFrameContext *fc = lc->fc;
1020 1251056 const VVCSH *sh = &lc->sc->sh;
1021 1251056 const int min_pu_width = fc->ps.pps->min_pu_width;
1022 1251056 VVCFrame *ref = fc->ref->collocated_ref;
1023 1251056 MvField *tab_mvf = ref->tab_dmvr_mvf;
1024 1251056 int colPic = ref->poc;
1025 1251056 int X = 0;
1026
1027 1251056 sb_clip_location(lc, x_ctb, y_ctb, temp_mv, &x, &y);
1028
1029 1251056 temp_col = TAB_MVF(x, y);
1030 1251056 mvLXCol = mv + 0;
1031 1251056 *pred_flag = DERIVE_TEMPORAL_COLOCATED_MVS(1);
1032
2/2
✓ Branch 0 taken 906572 times.
✓ Branch 1 taken 344484 times.
1251056 if (IS_B(sh->r)) {
1033 906572 X = 1;
1034 906572 mvLXCol = mv + 1;
1035 906572 *pred_flag |= (DERIVE_TEMPORAL_COLOCATED_MVS(1)) << 1;
1036 }
1037 1251056 }
1038
1039 //8.5.5.4 Derivation process for subblock-based temporal merging base motion data
1040 48394 static int sb_temporal_luma_motion_data(const VVCLocalContext *lc, const MvField *a1,
1041 const int x_ctb, const int y_ctb, MvField *ctr_mvf, Mv *temp_mv)
1042 {
1043 48394 const VVCFrameContext *fc = lc->fc;
1044 48394 const RefPicList *rpl = lc->sc->rpl;
1045 48394 const CodingUnit *cu = lc->cu;
1046 48394 const int x = cu->x0 + cu->cb_width / 2;
1047 48394 const int y = cu->y0 + cu->cb_height / 2;
1048 48394 const VVCFrame *ref = fc->ref->collocated_ref;
1049
1050 int colPic;
1051
1052 48394 memset(temp_mv, 0, sizeof(*temp_mv));
1053
1054
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48394 times.
48394 if (!ref) {
1055 memset(ctr_mvf, 0, sizeof(*ctr_mvf));
1056 return 0;
1057 }
1058
1059 48394 colPic = ref->poc;
1060
1061
2/2
✓ Branch 0 taken 45945 times.
✓ Branch 1 taken 2449 times.
48394 if (a1) {
1062
4/4
✓ Branch 0 taken 42102 times.
✓ Branch 1 taken 3843 times.
✓ Branch 2 taken 28801 times.
✓ Branch 3 taken 13301 times.
45945 if ((a1->pred_flag & PF_L0) && colPic == rpl[0].list[a1->ref_idx[0]])
1063 28801 *temp_mv = a1->mv[0];
1064
4/4
✓ Branch 0 taken 11895 times.
✓ Branch 1 taken 5249 times.
✓ Branch 2 taken 9736 times.
✓ Branch 3 taken 2159 times.
17144 else if ((a1->pred_flag & PF_L1) && colPic == rpl[1].list[a1->ref_idx[1]])
1065 9736 *temp_mv = a1->mv[1];
1066 45945 ff_vvc_round_mv(temp_mv, 0, 4);
1067 }
1068 48394 sb_temproal_luma_motion(lc, x_ctb, y_ctb, temp_mv, x, y, &ctr_mvf->pred_flag , ctr_mvf->mv);
1069
1070 48394 return ctr_mvf->pred_flag;
1071 }
1072
1073
1074 //8.5.5.3 Derivation process for subblock-based temporal merging candidates
1075 48394 static int sb_temporal_merge_candidate(const VVCLocalContext* lc, NeighbourContext *nctx, PredictionUnit *pu)
1076 {
1077 48394 const VVCFrameContext *fc = lc->fc;
1078 48394 const CodingUnit *cu = lc->cu;
1079 48394 const VVCSPS *sps = fc->ps.sps;
1080 48394 const VVCPH *ph = &fc->ps.ph;
1081 48394 MotionInfo *mi = &pu->mi;
1082 48394 const int ctb_log2_size = sps->ctb_log2_size_y;
1083 48394 const int x0 = cu->x0;
1084 48394 const int y0 = cu->y0;
1085 48394 const NeighbourIdx n = A1;
1086 const MvField *a1;
1087 MvField ctr_mvf;
1088 48394 LOCAL_ALIGNED_8(Mv, temp_mv, [1]);
1089 48394 const int x_ctb = (x0 >> ctb_log2_size) << ctb_log2_size;
1090 48394 const int y_ctb = (y0 >> ctb_log2_size) << ctb_log2_size;
1091
1092
1093
1/2
✓ Branch 0 taken 48394 times.
✗ Branch 1 not taken.
48394 if (!ph->r->ph_temporal_mvp_enabled_flag ||
1094
1/2
✓ Branch 0 taken 48394 times.
✗ Branch 1 not taken.
48394 !sps->r->sps_sbtmvp_enabled_flag ||
1095
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 48394 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
48394 (cu->cb_width < 8 && cu->cb_height < 8))
1096 return 0;
1097
1098 48394 mi->num_sb_x = cu->cb_width >> 3;
1099 48394 mi->num_sb_y = cu->cb_height >> 3;
1100
1101 48394 a1 = derive_corner_mvf(nctx, &n, 1);
1102
2/2
✓ Branch 1 taken 41366 times.
✓ Branch 2 taken 7028 times.
48394 if (sb_temporal_luma_motion_data(lc, a1, x_ctb, y_ctb, &ctr_mvf, temp_mv)) {
1103 41366 const int sbw = cu->cb_width / mi->num_sb_x;
1104 41366 const int sbh = cu->cb_height / mi->num_sb_y;
1105 41366 MvField mvf = {0};
1106
2/2
✓ Branch 0 taken 171088 times.
✓ Branch 1 taken 41366 times.
212454 for (int sby = 0; sby < mi->num_sb_y; sby++) {
1107
2/2
✓ Branch 0 taken 1202662 times.
✓ Branch 1 taken 171088 times.
1373750 for (int sbx = 0; sbx < mi->num_sb_x; sbx++) {
1108 1202662 int x = x0 + sbx * sbw;
1109 1202662 int y = y0 + sby * sbh;
1110 1202662 sb_temproal_luma_motion(lc, x_ctb, y_ctb, temp_mv, x + sbw / 2, y + sbh / 2, &mvf.pred_flag, mvf.mv);
1111
2/2
✓ Branch 0 taken 6493 times.
✓ Branch 1 taken 1196169 times.
1202662 if (!mvf.pred_flag) {
1112 6493 mvf.pred_flag = ctr_mvf.pred_flag;
1113 6493 memcpy(mvf.mv, ctr_mvf.mv, sizeof(mvf.mv));
1114 }
1115 1202662 ff_vvc_set_mvf(lc, x, y, sbw, sbh, &mvf);
1116 }
1117 }
1118 41366 return 1;
1119 }
1120 7028 return 0;
1121 }
1122
1123 13638 static int affine_merge_const1(const MvField *c0, const MvField *c1, const MvField *c2, MotionInfo *mi)
1124 {
1125
6/6
✓ Branch 0 taken 13575 times.
✓ Branch 1 taken 63 times.
✓ Branch 2 taken 12962 times.
✓ Branch 3 taken 613 times.
✓ Branch 4 taken 12469 times.
✓ Branch 5 taken 493 times.
13638 if (c0 && c1 && c2) {
1126 12469 mi->pred_flag = 0;
1127
2/2
✓ Branch 0 taken 24938 times.
✓ Branch 1 taken 12469 times.
37407 for (int i = 0; i < 2; i++) {
1128 24938 PredFlag mask = i + 1;
1129
2/2
✓ Branch 1 taken 14670 times.
✓ Branch 2 taken 10268 times.
24938 if (compare_pf_ref_idx(c0, c1, c2, i)) {
1130 14670 mi->pred_flag |= mask;
1131 14670 mi->ref_idx[i] = c0->ref_idx[i];
1132 14670 mi->mv[i][0] = c0->mv[i];
1133 14670 mi->mv[i][1] = c1->mv[i];
1134 14670 mi->mv[i][2] = c2->mv[i];
1135 }
1136 }
1137
2/2
✓ Branch 0 taken 11540 times.
✓ Branch 1 taken 929 times.
12469 if (mi->pred_flag) {
1138
2/2
✓ Branch 0 taken 3130 times.
✓ Branch 1 taken 8410 times.
11540 if (mi->pred_flag == PF_BI)
1139 3130 mi->bcw_idx = c0->bcw_idx;
1140 11540 mi->motion_model_idc = MOTION_6_PARAMS_AFFINE;
1141 11540 return 1;
1142 }
1143 }
1144 2098 return 0;
1145 }
1146
1147 7259 static int affine_merge_const2(const MvField *c0, const MvField *c1, const MvField *c3, MotionInfo *mi)
1148 {
1149
6/6
✓ Branch 0 taken 7196 times.
✓ Branch 1 taken 63 times.
✓ Branch 2 taken 6583 times.
✓ Branch 3 taken 613 times.
✓ Branch 4 taken 4477 times.
✓ Branch 5 taken 2106 times.
7259 if (c0 && c1 && c3) {
1150 4477 mi->pred_flag = 0;
1151
2/2
✓ Branch 0 taken 8954 times.
✓ Branch 1 taken 4477 times.
13431 for (int i = 0; i < 2; i++) {
1152 8954 PredFlag mask = i + 1;
1153
2/2
✓ Branch 1 taken 5265 times.
✓ Branch 2 taken 3689 times.
8954 if (compare_pf_ref_idx(c0, c1, c3, i)) {
1154 5265 mi->pred_flag |= mask;
1155 5265 mi->ref_idx[i] = c0->ref_idx[i];
1156 5265 mi->mv[i][0] = c0->mv[i];
1157 5265 mi->mv[i][1] = c1->mv[i];
1158 5265 mi->mv[i][2].x = c3->mv[i].x + c0->mv[i].x - c1->mv[i].x;
1159 5265 mi->mv[i][2].y = c3->mv[i].y + c0->mv[i].y - c1->mv[i].y;
1160 5265 ff_vvc_clip_mv(&mi->mv[i][2]);
1161 }
1162 }
1163
2/2
✓ Branch 0 taken 3914 times.
✓ Branch 1 taken 563 times.
4477 if (mi->pred_flag) {
1164
2/2
✓ Branch 0 taken 1351 times.
✓ Branch 1 taken 2563 times.
3914 mi->bcw_idx = mi->pred_flag == PF_BI ? c0->bcw_idx : 0;
1165 3914 mi->motion_model_idc = MOTION_6_PARAMS_AFFINE;
1166 3914 return 1;
1167 }
1168 }
1169 3345 return 0;
1170 }
1171
1172 5212 static int affine_merge_const3(const MvField *c0, const MvField *c2, const MvField *c3, MotionInfo *mi)
1173 {
1174
6/6
✓ Branch 0 taken 5149 times.
✓ Branch 1 taken 63 times.
✓ Branch 2 taken 4838 times.
✓ Branch 3 taken 311 times.
✓ Branch 4 taken 2747 times.
✓ Branch 5 taken 2091 times.
5212 if (c0 && c2 && c3) {
1175 2747 mi->pred_flag = 0;
1176
2/2
✓ Branch 0 taken 5494 times.
✓ Branch 1 taken 2747 times.
8241 for (int i = 0; i < 2; i++) {
1177 5494 PredFlag mask = i + 1;
1178
2/2
✓ Branch 1 taken 3154 times.
✓ Branch 2 taken 2340 times.
5494 if (compare_pf_ref_idx(c0, c2, c3, i)) {
1179 3154 mi->pred_flag |= mask;
1180 3154 mi->ref_idx[i] = c0->ref_idx[i];
1181 3154 mi->mv[i][0] = c0->mv[i];
1182 3154 mi->mv[i][1].x = c3->mv[i].x + c0->mv[i].x - c2->mv[i].x;
1183 3154 mi->mv[i][1].y = c3->mv[i].y + c0->mv[i].y - c2->mv[i].y;
1184 3154 ff_vvc_clip_mv(&mi->mv[i][1]);
1185 3154 mi->mv[i][2] = c2->mv[i];
1186 }
1187 }
1188
2/2
✓ Branch 0 taken 2329 times.
✓ Branch 1 taken 418 times.
2747 if (mi->pred_flag) {
1189
2/2
✓ Branch 0 taken 825 times.
✓ Branch 1 taken 1504 times.
2329 mi->bcw_idx = mi->pred_flag == PF_BI ? c0->bcw_idx : 0;
1190 2329 mi->motion_model_idc = MOTION_6_PARAMS_AFFINE;
1191 2329 return 1;
1192 }
1193 }
1194 2883 return 0;
1195 }
1196
1197 3633 static int affine_merge_const4(const MvField *c1, const MvField *c2, const MvField *c3, MotionInfo *mi)
1198 {
1199
6/6
✓ Branch 0 taken 3248 times.
✓ Branch 1 taken 385 times.
✓ Branch 2 taken 2943 times.
✓ Branch 3 taken 305 times.
✓ Branch 4 taken 1052 times.
✓ Branch 5 taken 1891 times.
3633 if (c1 && c2 && c3) {
1200 1052 mi->pred_flag = 0;
1201
2/2
✓ Branch 0 taken 2104 times.
✓ Branch 1 taken 1052 times.
3156 for (int i = 0; i < 2; i++) {
1202 2104 PredFlag mask = i + 1;
1203
2/2
✓ Branch 1 taken 902 times.
✓ Branch 2 taken 1202 times.
2104 if (compare_pf_ref_idx(c1, c2, c3, i)) {
1204 902 mi->pred_flag |= mask;
1205 902 mi->ref_idx[i] = c1->ref_idx[i];
1206 902 mi->mv[i][0].x = c1->mv[i].x + c2->mv[i].x - c3->mv[i].x;
1207 902 mi->mv[i][0].y = c1->mv[i].y + c2->mv[i].y - c3->mv[i].y;
1208 902 ff_vvc_clip_mv(&mi->mv[i][0]);
1209 902 mi->mv[i][1] = c1->mv[i];
1210 902 mi->mv[i][2] = c2->mv[i];
1211 }
1212 }
1213
2/2
✓ Branch 0 taken 662 times.
✓ Branch 1 taken 390 times.
1052 if (mi->pred_flag) {
1214
2/2
✓ Branch 0 taken 240 times.
✓ Branch 1 taken 422 times.
662 mi->bcw_idx = mi->pred_flag == PF_BI ? c1->bcw_idx : 0;
1215 662 mi->motion_model_idc = MOTION_6_PARAMS_AFFINE;
1216 662 return 1;
1217 }
1218 }
1219 2971 return 0;
1220 }
1221
1222 3016 static int affine_merge_const5(const MvField *c0, const MvField *c1, MotionInfo *mi)
1223 {
1224
4/4
✓ Branch 0 taken 2953 times.
✓ Branch 1 taken 63 times.
✓ Branch 2 taken 2624 times.
✓ Branch 3 taken 329 times.
3016 if (c0 && c1) {
1225 2624 mi->pred_flag = 0;
1226
2/2
✓ Branch 0 taken 5248 times.
✓ Branch 1 taken 2624 times.
7872 for (int i = 0; i < 2; i++) {
1227 5248 PredFlag mask = i + 1;
1228
2/2
✓ Branch 1 taken 2983 times.
✓ Branch 2 taken 2265 times.
5248 if (compare_pf_ref_idx(c0, c1, NULL, i)) {
1229 2983 mi->pred_flag |= mask;
1230 2983 mi->ref_idx[i] = c0->ref_idx[i];
1231 2983 mi->mv[i][0] = c0->mv[i];
1232 2983 mi->mv[i][1] = c1->mv[i];
1233 }
1234 }
1235
2/2
✓ Branch 0 taken 2356 times.
✓ Branch 1 taken 268 times.
2624 if (mi->pred_flag) {
1236
2/2
✓ Branch 0 taken 627 times.
✓ Branch 1 taken 1729 times.
2356 if (mi->pred_flag == PF_BI)
1237 627 mi->bcw_idx = c0->bcw_idx;
1238 2356 mi->motion_model_idc = MOTION_4_PARAMS_AFFINE;
1239 2356 return 1;
1240 }
1241 }
1242 660 return 0;
1243 }
1244
1245 1613 static int affine_merge_const6(const MvField* c0, const MvField* c2, const int cb_width, const int cb_height, MotionInfo *mi)
1246 {
1247
4/4
✓ Branch 0 taken 1550 times.
✓ Branch 1 taken 63 times.
✓ Branch 2 taken 1473 times.
✓ Branch 3 taken 77 times.
1613 if (c0 && c2) {
1248 1473 const int shift = 7 + av_log2(cb_width) - av_log2(cb_height);
1249 1473 mi->pred_flag = 0;
1250
2/2
✓ Branch 0 taken 2946 times.
✓ Branch 1 taken 1473 times.
4419 for (int i = 0; i < 2; i++) {
1251 2946 PredFlag mask = i + 1;
1252
2/2
✓ Branch 1 taken 1762 times.
✓ Branch 2 taken 1184 times.
2946 if (compare_pf_ref_idx(c0, c2, NULL, i)) {
1253 1762 mi->pred_flag |= mask;
1254 1762 mi->ref_idx[i] = c0->ref_idx[i];
1255 1762 mi->mv[i][0] = c0->mv[i];
1256 1762 mi->mv[i][1].x = (c0->mv[i].x * (1 << 7)) + ((c2->mv[i].y - c0->mv[i].y) * (1 << shift));
1257 1762 mi->mv[i][1].y = (c0->mv[i].y * (1 << 7)) - ((c2->mv[i].x - c0->mv[i].x) * (1 << shift));
1258 1762 ff_vvc_round_mv(&mi->mv[i][1], 0, 7);
1259 1762 ff_vvc_clip_mv(&mi->mv[i][1]);
1260 }
1261 }
1262
2/2
✓ Branch 0 taken 1381 times.
✓ Branch 1 taken 92 times.
1473 if (mi->pred_flag) {
1263
2/2
✓ Branch 0 taken 381 times.
✓ Branch 1 taken 1000 times.
1381 if (mi->pred_flag == PF_BI)
1264 381 mi->bcw_idx = c0->bcw_idx;
1265 1381 mi->motion_model_idc = MOTION_4_PARAMS_AFFINE;
1266 1381 return 1;
1267 }
1268 }
1269 232 return 0;
1270 }
1271
1272 523 static void affine_merge_zero_motion(const VVCLocalContext *lc, MotionInfo *mi)
1273 {
1274 523 const CodingUnit *cu = lc->cu;
1275
1276 523 memset(mi, 0, sizeof(*mi));
1277
2/2
✓ Branch 0 taken 401 times.
✓ Branch 1 taken 122 times.
523 mi->pred_flag = PF_L0 + (IS_B(lc->sc->sh.r) << 1);
1278 523 mi->motion_model_idc = MOTION_4_PARAMS_AFFINE;
1279 523 mi->num_sb_x = cu->cb_width >> MIN_PU_LOG2;
1280 523 mi->num_sb_y = cu->cb_height >> MIN_PU_LOG2;
1281 523 }
1282
1283 //8.5.5.6 Derivation process for constructed affine control point motion vector merging candidates
1284 13638 static int affine_merge_const_candidates(const VVCLocalContext *lc, MotionInfo *mi,
1285 NeighbourContext *nctx, const int merge_subblock_idx, int num_cands)
1286 {
1287 13638 const VVCFrameContext *fc = lc->fc;
1288 13638 const CodingUnit *cu = lc->cu;
1289 13638 const NeighbourIdx tl[] = { B2, B3, A2 };
1290 13638 const NeighbourIdx tr[] = { B1, B0};
1291 13638 const NeighbourIdx bl[] = { A1, A0};
1292 const MvField *c0, *c1, *c2;
1293
1294 13638 c0 = DERIVE_CORNER_MV(tl);
1295 13638 c1 = DERIVE_CORNER_MV(tr);
1296 13638 c2 = DERIVE_CORNER_MV(bl);
1297
1298
1/2
✓ Branch 0 taken 13638 times.
✗ Branch 1 not taken.
13638 if (fc->ps.sps->r->sps_6param_affine_enabled_flag) {
1299 13638 MvField corner3, *c3 = NULL;
1300 //Const1
1301
2/2
✓ Branch 1 taken 11540 times.
✓ Branch 2 taken 2098 times.
13638 if (affine_merge_const1(c0, c1, c2, mi)) {
1302
2/2
✓ Branch 0 taken 6379 times.
✓ Branch 1 taken 5161 times.
11540 if (merge_subblock_idx == num_cands)
1303 10622 return 1;
1304 5161 num_cands++;
1305 }
1306
1307 7259 memset(&corner3, 0, sizeof(corner3));
1308
1/2
✓ Branch 0 taken 7259 times.
✗ Branch 1 not taken.
7259 if (fc->ps.ph.r->ph_temporal_mvp_enabled_flag){
1309 7259 const int available_l0 = temporal_luma_motion_vector(lc, 0, corner3.mv + 0, 0, 0, 0);
1310 14518 const int available_l1 = (lc->sc->sh.r->sh_slice_type == VVC_SLICE_TYPE_B) ?
1311
2/2
✓ Branch 0 taken 5835 times.
✓ Branch 1 taken 1424 times.
7259 temporal_luma_motion_vector(lc, 0, corner3.mv + 1, 1, 0, 0) : 0;
1312
1313 7259 corner3.pred_flag = available_l0 + (available_l1 << 1);
1314
2/2
✓ Branch 0 taken 4906 times.
✓ Branch 1 taken 2353 times.
7259 if (corner3.pred_flag)
1315 4906 c3 = &corner3;
1316 }
1317
1318 //Const2
1319
2/2
✓ Branch 1 taken 3914 times.
✓ Branch 2 taken 3345 times.
7259 if (affine_merge_const2(c0, c1, c3, mi)) {
1320
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 1867 times.
3914 if (merge_subblock_idx == num_cands)
1321 2047 return 1;
1322 1867 num_cands++;
1323 }
1324
1325 //Const3
1326
2/2
✓ Branch 1 taken 2329 times.
✓ Branch 2 taken 2883 times.
5212 if (affine_merge_const3(c0, c2, c3, mi)) {
1327
2/2
✓ Branch 0 taken 1579 times.
✓ Branch 1 taken 750 times.
2329 if (merge_subblock_idx == num_cands)
1328 1579 return 1;
1329 750 num_cands++;
1330 }
1331
1332 //Const4
1333
2/2
✓ Branch 1 taken 662 times.
✓ Branch 2 taken 2971 times.
3633 if (affine_merge_const4(c1, c2, c3, mi)) {
1334
2/2
✓ Branch 0 taken 617 times.
✓ Branch 1 taken 45 times.
662 if (merge_subblock_idx == num_cands)
1335 617 return 1;
1336 45 num_cands++;
1337 }
1338 }
1339
1340 //Const5
1341
2/2
✓ Branch 1 taken 2356 times.
✓ Branch 2 taken 660 times.
3016 if (affine_merge_const5(c0, c1, mi)) {
1342
2/2
✓ Branch 0 taken 1403 times.
✓ Branch 1 taken 953 times.
2356 if (merge_subblock_idx == num_cands)
1343 1403 return 1;
1344 953 num_cands++;
1345 }
1346
1347
2/2
✓ Branch 1 taken 1381 times.
✓ Branch 2 taken 232 times.
1613 if (affine_merge_const6(c0, c2, cu->cb_width, cu->cb_height, mi)) {
1348
2/2
✓ Branch 0 taken 1090 times.
✓ Branch 1 taken 291 times.
1381 if (merge_subblock_idx == num_cands)
1349 1090 return 1;
1350 }
1351 523 return 0;
1352 }
1353
1354 //8.5.5.2 Derivation process for motion vectors and reference indices in subblock merge mode
1355 //return 1 if candidate is SbCol
1356 48394 static int sb_mv_merge_mode(const VVCLocalContext *lc, const int merge_subblock_idx, PredictionUnit *pu)
1357 {
1358 48394 const VVCSPS *sps = lc->fc->ps.sps;
1359 48394 const CodingUnit *cu = lc->cu;
1360 48394 MotionInfo *mi = &pu->mi;
1361 48394 int num_cands = 0;
1362 NeighbourContext nctx;
1363
1364 48394 init_neighbour_context(&nctx, lc);
1365
1366 //SbCol
1367
2/2
✓ Branch 1 taken 41366 times.
✓ Branch 2 taken 7028 times.
48394 if (sb_temporal_merge_candidate(lc, &nctx, pu)) {
1368
2/2
✓ Branch 0 taken 25317 times.
✓ Branch 1 taken 16049 times.
41366 if (merge_subblock_idx == num_cands)
1369 25317 return 1;
1370 16049 num_cands++;
1371 }
1372
1373 23077 pu->inter_affine_flag = 1;
1374 23077 mi->num_sb_x = cu->cb_width >> MIN_PU_LOG2;
1375 23077 mi->num_sb_y = cu->cb_height >> MIN_PU_LOG2;
1376
1377
1/2
✓ Branch 0 taken 23077 times.
✗ Branch 1 not taken.
23077 if (sps->r->sps_affine_enabled_flag) {
1378 23077 const NeighbourIdx ak[] = { A0, A1 };
1379 23077 const NeighbourIdx bk[] = { B0, B1, B2 };
1380 //A
1381
2/2
✓ Branch 1 taken 9506 times.
✓ Branch 2 taken 13571 times.
23077 if (AFFINE_MERGE_FROM_NBS(ak)) {
1382
2/2
✓ Branch 0 taken 5242 times.
✓ Branch 1 taken 4264 times.
9506 if (merge_subblock_idx == num_cands)
1383 22554 return 0;
1384 4264 num_cands++;
1385 }
1386
1387 //B
1388
2/2
✓ Branch 1 taken 8790 times.
✓ Branch 2 taken 9045 times.
17835 if (AFFINE_MERGE_FROM_NBS(bk)) {
1389
2/2
✓ Branch 0 taken 4197 times.
✓ Branch 1 taken 4593 times.
8790 if (merge_subblock_idx == num_cands)
1390 4197 return 0;
1391 4593 num_cands++;
1392 }
1393
1394 //Const1 to Const6
1395
2/2
✓ Branch 1 taken 13115 times.
✓ Branch 2 taken 523 times.
13638 if (affine_merge_const_candidates(lc, mi, &nctx, merge_subblock_idx, num_cands))
1396 13115 return 0;
1397 }
1398 //Zero
1399 523 affine_merge_zero_motion(lc, mi);
1400 523 return 0;
1401 }
1402
1403 48394 void ff_vvc_sb_mv_merge_mode(VVCLocalContext *lc, const int merge_subblock_idx, PredictionUnit *pu)
1404 {
1405 48394 const CodingUnit *cu = lc->cu;
1406 48394 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
1407
2/2
✓ Branch 1 taken 23077 times.
✓ Branch 2 taken 25317 times.
48394 if (!sb_mv_merge_mode(lc, merge_subblock_idx, pu)) {
1408 23077 ff_vvc_store_sb_mvs(lc, pu);
1409 }
1410 48394 }
1411
1412 104485 static int mvp_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand,
1413 const int lx, const int8_t *ref_idx, Mv *mv)
1414 {
1415 104485 const VVCFrameContext *fc = lc->fc;
1416 104485 const RefPicList *rpl = lc->sc->rpl;
1417 104485 const int min_pu_width = fc->ps.pps->min_pu_width;
1418 104485 const MvField* tab_mvf = fc->tab.mvf;
1419 104485 const MvField *mvf = &TAB_MVF(x_cand, y_cand);
1420 104485 const PredFlag maskx = lx + 1;
1421 104485 const int poc = rpl[lx].list[ref_idx[lx]];
1422 104485 int available = 0;
1423
1424
4/4
✓ Branch 0 taken 81140 times.
✓ Branch 1 taken 23345 times.
✓ Branch 2 taken 60313 times.
✓ Branch 3 taken 20827 times.
104485 if ((mvf->pred_flag & maskx) && rpl[lx].list[mvf->ref_idx[lx]] == poc) {
1425 60313 available = 1;
1426 60313 *mv = mvf->mv[lx];
1427 } else {
1428 44172 const int ly = !lx;
1429 44172 const PredFlag masky = ly + 1;
1430
4/4
✓ Branch 0 taken 32683 times.
✓ Branch 1 taken 11489 times.
✓ Branch 2 taken 6962 times.
✓ Branch 3 taken 25721 times.
44172 if ((mvf->pred_flag & masky) && rpl[ly].list[mvf->ref_idx[ly]] == poc) {
1431 6962 available = 1;
1432 6962 *mv = mvf->mv[ly];
1433 }
1434 }
1435
1436 104485 return available;
1437 }
1438
1439 27630 static int affine_mvp_candidate(const VVCLocalContext *lc,
1440 const int x_cand, const int y_cand, const int lx, const int8_t *ref_idx,
1441 Mv *cps, const int num_cp)
1442 {
1443 27630 const VVCFrameContext *fc = lc->fc;
1444 27630 int x_nb, y_nb, nbw, nbh, motion_model_idc, available = 0;
1445
1446 27630 motion_model_idc = affine_neighbour_cb(fc, x_cand, y_cand, &x_nb, &y_nb, &nbw, &nbh);
1447
2/2
✓ Branch 0 taken 6981 times.
✓ Branch 1 taken 20649 times.
27630 if (motion_model_idc) {
1448 6981 const int min_pu_width = fc->ps.pps->min_pu_width;
1449 6981 const MvField* tab_mvf = fc->tab.mvf;
1450 6981 const MvField *mvf = &TAB_MVF(x_nb, y_nb);
1451 6981 RefPicList* rpl = lc->sc->rpl;
1452 6981 const PredFlag maskx = lx + 1;
1453 6981 const int poc = rpl[lx].list[ref_idx[lx]];
1454
1455
4/4
✓ Branch 0 taken 5909 times.
✓ Branch 1 taken 1072 times.
✓ Branch 2 taken 4958 times.
✓ Branch 3 taken 951 times.
6981 if ((mvf->pred_flag & maskx) && rpl[lx].list[mvf->ref_idx[lx]] == poc) {
1456 4958 available = 1;
1457 4958 affine_cps_from_nb(lc, x_nb, y_nb, nbw, nbh, lx, cps, num_cp);
1458 } else {
1459 2023 const int ly = !lx;
1460 2023 const PredFlag masky = ly + 1;
1461
4/4
✓ Branch 0 taken 1304 times.
✓ Branch 1 taken 719 times.
✓ Branch 2 taken 678 times.
✓ Branch 3 taken 626 times.
2023 if ((mvf->pred_flag & masky) && rpl[ly].list[mvf->ref_idx[ly]] == poc) {
1462 678 available = 1;
1463 678 affine_cps_from_nb(lc, x_nb, y_nb, nbw, nbh, ly, cps, num_cp);
1464 }
1465 }
1466
1467 }
1468 27630 return available;
1469 }
1470
1471 120880 static int mvp_from_nbs(NeighbourContext *ctx,
1472 const NeighbourIdx *nbs, const int num_nbs, const int lx, const int8_t *ref_idx, const int amvr_shift,
1473 Mv *cps, const int num_cps)
1474 {
1475 120880 const VVCLocalContext *lc = ctx->lc;
1476 120880 int available = 0;
1477
1478
2/2
✓ Branch 0 taken 233126 times.
✓ Branch 1 taken 47969 times.
281095 for (int i = 0; i < num_nbs; i++) {
1479 233126 Neighbour *n = &ctx->neighbours[nbs[i]];
1480
2/2
✓ Branch 1 taken 132115 times.
✓ Branch 2 taken 101011 times.
233126 if (check_available(n, lc, 0)) {
1481
2/2
✓ Branch 0 taken 27630 times.
✓ Branch 1 taken 104485 times.
132115 if (num_cps > 1)
1482 27630 available = affine_mvp_candidate(lc, n->x, n->y, lx, ref_idx, cps, num_cps);
1483 else
1484 104485 available = mvp_candidate(lc, n->x, n->y, lx, ref_idx, cps);
1485
2/2
✓ Branch 0 taken 72911 times.
✓ Branch 1 taken 59204 times.
132115 if (available) {
1486
2/2
✓ Branch 0 taken 81433 times.
✓ Branch 1 taken 72911 times.
154344 for (int c = 0; c < num_cps; c++)
1487 81433 ff_vvc_round_mv(cps + c, amvr_shift, amvr_shift);
1488 72911 return 1;
1489 }
1490 }
1491 }
1492 47969 return 0;
1493 }
1494
1495 //get mvp from neighbours
1496 #define AFFINE_MVP_FROM_NBS(nbs) \
1497 mvp_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), lx, ref_idx, amvr_shift, cps, num_cp) \
1498
1499 #define MVP_FROM_NBS(nbs) \
1500 mvp_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), lx, ref_idx, amvr_shift, mv, 1) \
1501
1502 63301 static int mvp_spatial_candidates(const VVCLocalContext *lc,
1503 const int mvp_lx_flag, const int lx, const int8_t* ref_idx, const int amvr_shift,
1504 Mv* mv, int *nb_merge_cand)
1505 {
1506 63301 const NeighbourIdx ak[] = { A0, A1 };
1507 63301 const NeighbourIdx bk[] = { B0, B1, B2 };
1508 NeighbourContext nctx;
1509 63301 int available_a, num_cands = 0;
1510 63301 LOCAL_ALIGNED_8(Mv, mv_a, [1]);
1511
1512 63301 init_neighbour_context(&nctx, lc);
1513
1514 63301 available_a = MVP_FROM_NBS(ak);
1515
2/2
✓ Branch 0 taken 41955 times.
✓ Branch 1 taken 21346 times.
63301 if (available_a) {
1516
2/2
✓ Branch 0 taken 25872 times.
✓ Branch 1 taken 16083 times.
41955 if (mvp_lx_flag == num_cands)
1517 25872 return 1;
1518 16083 num_cands++;
1519 16083 *mv_a = *mv;
1520 }
1521
2/2
✓ Branch 1 taken 25320 times.
✓ Branch 2 taken 12109 times.
37429 if (MVP_FROM_NBS(bk)) {
1522
4/4
✓ Branch 0 taken 14269 times.
✓ Branch 1 taken 11051 times.
✓ Branch 2 taken 12124 times.
✓ Branch 3 taken 2145 times.
25320 if (!available_a || !IS_SAME_MV(mv_a, mv)) {
1523
2/2
✓ Branch 0 taken 19888 times.
✓ Branch 1 taken 3287 times.
23175 if (mvp_lx_flag == num_cands)
1524 19888 return 1;
1525 3287 num_cands++;
1526 }
1527 }
1528 17541 *nb_merge_cand = num_cands;
1529 17541 return 0;
1530 }
1531
1532 17541 static int mvp_temporal_candidates(const VVCLocalContext* lc,
1533 const int mvp_lx_flag, const int lx, const int8_t *ref_idx, const int amvr_shift,
1534 Mv* mv, int *num_cands)
1535 {
1536
2/2
✓ Branch 1 taken 12808 times.
✓ Branch 2 taken 4733 times.
17541 if (temporal_luma_motion_vector(lc, ref_idx[lx], mv, lx, 1, 0)) {
1537
2/2
✓ Branch 0 taken 11039 times.
✓ Branch 1 taken 1769 times.
12808 if (mvp_lx_flag == *num_cands) {
1538 11039 ff_vvc_round_mv(mv, amvr_shift, amvr_shift);
1539 11039 return 1;
1540 }
1541 1769 (*num_cands)++;
1542 }
1543 6502 return 0;
1544
1545 }
1546
1547 6502 static int mvp_history_candidates(const VVCLocalContext *lc,
1548 const int mvp_lx_flag, const int lx, const int8_t ref_idx, const int amvr_shift,
1549 Mv *mv, int num_cands)
1550 {
1551 6502 const EntryPoint* ep = lc->ep;
1552 6502 const RefPicList* rpl = lc->sc->rpl;
1553 6502 const int poc = rpl[lx].list[ref_idx];
1554
1555
2/2
✓ Branch 0 taken 271 times.
✓ Branch 1 taken 6231 times.
6502 if (ep->num_hmvp == 0)
1556 271 return 0;
1557
2/2
✓ Branch 0 taken 12874 times.
✓ Branch 1 taken 1471 times.
14345 for (int i = 1; i <= FFMIN(4, ep->num_hmvp); i++) {
1558 12874 const MvField* h = &ep->hmvp[i - 1];
1559
2/2
✓ Branch 0 taken 21403 times.
✓ Branch 1 taken 8114 times.
29517 for (int j = 0; j < 2; j++) {
1560
2/2
✓ Branch 0 taken 8529 times.
✓ Branch 1 taken 12874 times.
21403 const int ly = (j ? !lx : lx);
1561 21403 PredFlag mask = PF_L0 + ly;
1562
4/4
✓ Branch 0 taken 14984 times.
✓ Branch 1 taken 6419 times.
✓ Branch 2 taken 5478 times.
✓ Branch 3 taken 9506 times.
21403 if ((h->pred_flag & mask) && poc == rpl[ly].list[h->ref_idx[ly]]) {
1563
2/2
✓ Branch 0 taken 4760 times.
✓ Branch 1 taken 718 times.
5478 if (mvp_lx_flag == num_cands) {
1564 4760 *mv = h->mv[ly];
1565 4760 ff_vvc_round_mv(mv, amvr_shift, amvr_shift);
1566 4760 return 1;
1567 }
1568 718 num_cands++;
1569 }
1570 }
1571 }
1572 1471 return 0;
1573 }
1574
1575 //8.5.2.8 Derivation process for luma motion vector prediction
1576 63301 static void mvp(const VVCLocalContext *lc, const int mvp_lx_flag, const int lx,
1577 const int8_t *ref_idx, const int amvr_shift, Mv *mv)
1578 {
1579 int num_cands;
1580
1581
2/2
✓ Branch 1 taken 45760 times.
✓ Branch 2 taken 17541 times.
63301 if (mvp_spatial_candidates(lc, mvp_lx_flag, lx, ref_idx, amvr_shift, mv, &num_cands))
1582 61559 return;
1583
1584
2/2
✓ Branch 1 taken 11039 times.
✓ Branch 2 taken 6502 times.
17541 if (mvp_temporal_candidates(lc, mvp_lx_flag, lx, ref_idx, amvr_shift, mv, &num_cands))
1585 11039 return;
1586
1587
2/2
✓ Branch 1 taken 4760 times.
✓ Branch 2 taken 1742 times.
6502 if (mvp_history_candidates(lc, mvp_lx_flag, lx, ref_idx[lx], amvr_shift, mv, num_cands))
1588 4760 return;
1589
1590 1742 memset(mv, 0, sizeof(*mv));
1591 }
1592
1593 48320 void ff_vvc_mvp(VVCLocalContext *lc, const int *mvp_lx_flag, const int amvr_shift, MotionInfo *mi)
1594 {
1595 48320 const CodingUnit *cu = lc->cu;
1596 48320 mi->num_sb_x = 1;
1597 48320 mi->num_sb_y = 1;
1598
1599 48320 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
1600
2/2
✓ Branch 0 taken 41310 times.
✓ Branch 1 taken 7010 times.
48320 if (mi->pred_flag != PF_L1)
1601 41310 mvp(lc, mvp_lx_flag[L0], L0, mi->ref_idx, amvr_shift, &mi->mv[L0][0]);
1602
2/2
✓ Branch 0 taken 21991 times.
✓ Branch 1 taken 26329 times.
48320 if (mi->pred_flag != PF_L0)
1603 21991 mvp(lc, mvp_lx_flag[L1], L1, mi->ref_idx, amvr_shift, &mi->mv[L1][0]);
1604 48320 }
1605
1606 1582 static int ibc_spatial_candidates(const VVCLocalContext *lc, const int merge_idx, Mv *const cand_list, int *nb_merge_cand)
1607 {
1608 1582 const CodingUnit *cu = lc->cu;
1609 1582 const VVCFrameContext *fc = lc->fc;
1610 1582 const int min_pu_width = fc->ps.pps->min_pu_width;
1611 1582 const MvField *tab_mvf = fc->tab.mvf;
1612 1582 const int is_gt4by4 = (cu->cb_width * cu->cb_height) > 16;
1613 1582 int num_cands = 0;
1614
1615 NeighbourContext nctx;
1616 1582 Neighbour *a1 = &nctx.neighbours[A1];
1617 1582 Neighbour *b1 = &nctx.neighbours[B1];
1618
1619
2/2
✓ Branch 0 taken 202 times.
✓ Branch 1 taken 1380 times.
1582 if (!is_gt4by4) {
1620 202 *nb_merge_cand = 0;
1621 202 return 0;
1622 }
1623
1624 1380 init_neighbour_context(&nctx, lc);
1625
1626
2/2
✓ Branch 1 taken 1070 times.
✓ Branch 2 taken 310 times.
1380 if (check_available(a1, lc, 1)) {
1627 1070 cand_list[num_cands++] = TAB_MVF(a1->x, a1->y).mv[L0];
1628
1/2
✓ Branch 0 taken 1070 times.
✗ Branch 1 not taken.
1070 if (num_cands > merge_idx)
1629 1070 return 1;
1630 }
1631
2/2
✓ Branch 1 taken 179 times.
✓ Branch 2 taken 131 times.
310 if (check_available(b1, lc, 1)) {
1632 179 const MvField *mvf = &TAB_MVF(b1->x, b1->y);
1633
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 179 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
179 if (!num_cands || !IS_SAME_MV(&cand_list[0], mvf->mv)) {
1634 179 cand_list[num_cands++] = mvf->mv[L0];
1635
1/2
✓ Branch 0 taken 179 times.
✗ Branch 1 not taken.
179 if (num_cands > merge_idx)
1636 179 return 1;
1637 }
1638 }
1639
1640 131 *nb_merge_cand = num_cands;
1641 131 return 0;
1642 }
1643
1644 333 static int ibc_history_candidates(const VVCLocalContext *lc,
1645 const int merge_idx, Mv *cand_list, int *nb_merge_cand)
1646 {
1647 333 const CodingUnit *cu = lc->cu;
1648 333 const EntryPoint *ep = lc->ep;
1649 333 const int is_gt4by4 = (cu->cb_width * cu->cb_height) > 16;
1650 333 int num_cands = *nb_merge_cand;
1651
1652
2/2
✓ Branch 0 taken 319 times.
✓ Branch 1 taken 14 times.
333 for (int i = 1; i <= ep->num_hmvp_ibc; i++) {
1653 319 int same_motion = 0;
1654 319 const MvField *mvf = &ep->hmvp_ibc[ep->num_hmvp_ibc - i];
1655
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 319 times.
319 for (int j = 0; j < *nb_merge_cand; j++) {
1656 same_motion = is_gt4by4 && i == 1 && IS_SAME_MV(&mvf->mv[L0], &cand_list[j]);
1657 if (same_motion)
1658 break;
1659 }
1660
1/2
✓ Branch 0 taken 319 times.
✗ Branch 1 not taken.
319 if (!same_motion) {
1661 319 cand_list[num_cands++] = mvf->mv[L0];
1662
1/2
✓ Branch 0 taken 319 times.
✗ Branch 1 not taken.
319 if (num_cands > merge_idx)
1663 319 return 1;
1664 }
1665 }
1666
1667 14 *nb_merge_cand = num_cands;
1668 14 return 0;
1669 }
1670
1671 #define MV_BITS 18
1672 #define IBC_SHIFT(v) ((v) >= (1 << (MV_BITS - 1)) ? ((v) - (1 << MV_BITS)) : (v))
1673
1674 1342 static inline void ibc_add_mvp(Mv *mv, Mv *mvp, const int amvr_shift)
1675 {
1676 1342 ff_vvc_round_mv(mv, amvr_shift, 0);
1677 1342 ff_vvc_round_mv(mvp, amvr_shift, amvr_shift);
1678
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1342 times.
1342 mv->x = IBC_SHIFT(mv->x + mvp->x);
1679
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1342 times.
1342 mv->y = IBC_SHIFT(mv->y + mvp->y);
1680 1342 }
1681
1682 1582 static void ibc_merge_candidates(VVCLocalContext *lc, const int merge_idx, Mv *mv)
1683 {
1684 1582 const CodingUnit *cu = lc->cu;
1685 1582 LOCAL_ALIGNED_8(Mv, cand_list, [MRG_MAX_NUM_CANDS]);
1686 int nb_cands;
1687
1688 1582 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
1689
4/4
✓ Branch 1 taken 333 times.
✓ Branch 2 taken 1249 times.
✓ Branch 3 taken 319 times.
✓ Branch 4 taken 14 times.
1915 if (ibc_spatial_candidates(lc, merge_idx, cand_list, &nb_cands) ||
1690 333 ibc_history_candidates(lc, merge_idx, cand_list, &nb_cands)) {
1691 1568 *mv = cand_list[merge_idx];
1692 1568 return;
1693 }
1694
1695 //zero mv
1696 14 memset(mv, 0, sizeof(*mv));
1697 }
1698
1699 1342 void ff_vvc_mvp_ibc(VVCLocalContext *lc, const int mvp_l0_flag, const int amvr_shift, Mv *mv)
1700 {
1701 1342 LOCAL_ALIGNED_8(Mv, mvp, [1]);
1702
1703 1342 ibc_merge_candidates(lc, mvp_l0_flag, mvp);
1704 1342 ibc_add_mvp(mv, mvp, amvr_shift);
1705 1342 }
1706
1707 240 void ff_vvc_luma_mv_merge_ibc(VVCLocalContext *lc, const int merge_idx, Mv *mv)
1708 {
1709 240 ibc_merge_candidates(lc, merge_idx, mv);
1710 240 }
1711
1712 21246 static int affine_mvp_constructed_cp(NeighbourContext *ctx,
1713 const NeighbourIdx *neighbour, const int num_neighbour,
1714 const int lx, const int8_t ref_idx, const int amvr_shift, Mv *cp)
1715 {
1716 21246 const VVCLocalContext *lc = ctx->lc;
1717 21246 const VVCFrameContext *fc = lc->fc;
1718 21246 const MvField *tab_mvf = fc->tab.mvf;
1719 21246 const int min_pu_width = fc->ps.pps->min_pu_width;
1720 21246 const RefPicList* rpl = lc->sc->rpl;
1721 21246 int available = 0;
1722
1723
2/2
✓ Branch 0 taken 31883 times.
✓ Branch 1 taken 6245 times.
38128 for (int i = 0; i < num_neighbour; i++) {
1724 31883 Neighbour *n = &ctx->neighbours[neighbour[i]];
1725
2/2
✓ Branch 1 taken 21342 times.
✓ Branch 2 taken 10541 times.
31883 if (check_available(n, ctx->lc, 0)) {
1726 21342 const PredFlag maskx = lx + 1;
1727 21342 const MvField* mvf = &TAB_MVF(n->x, n->y);
1728 21342 const int poc = rpl[lx].list[ref_idx];
1729
4/4
✓ Branch 0 taken 17559 times.
✓ Branch 1 taken 3783 times.
✓ Branch 2 taken 13413 times.
✓ Branch 3 taken 4146 times.
21342 if ((mvf->pred_flag & maskx) && rpl[lx].list[mvf->ref_idx[lx]] == poc) {
1730 13413 available = 1;
1731 13413 *cp = mvf->mv[lx];
1732 } else {
1733 7929 const int ly = !lx;
1734 7929 const PredFlag masky = ly + 1;
1735
4/4
✓ Branch 0 taken 5446 times.
✓ Branch 1 taken 2483 times.
✓ Branch 2 taken 1588 times.
✓ Branch 3 taken 3858 times.
7929 if ((mvf->pred_flag & masky) && rpl[ly].list[mvf->ref_idx[ly]] == poc) {
1736 1588 available = 1;
1737 1588 *cp = mvf->mv[ly];
1738 }
1739 }
1740
2/2
✓ Branch 0 taken 15001 times.
✓ Branch 1 taken 6341 times.
21342 if (available) {
1741 15001 ff_vvc_round_mv(cp, amvr_shift, amvr_shift);
1742 15001 return 1;
1743 }
1744 }
1745 }
1746 6245 return 0;
1747 }
1748
1749 #define AFFINE_MVP_CONSTRUCTED_CP(cands, cp) \
1750 affine_mvp_constructed_cp(nctx, cands, FF_ARRAY_ELEMS(cands), lx, ref_idx, \
1751 amvr_shift, cp)
1752
1753 //8.5.5.8 Derivation process for constructed affine control point motion vector prediction candidates
1754 7082 static int affine_mvp_const1(NeighbourContext* nctx,
1755 const int lx, const int8_t ref_idx, const int amvr_shift,
1756 Mv *cps, int *available)
1757 {
1758 7082 const NeighbourIdx tl[] = { B2, B3, A2 };
1759 7082 const NeighbourIdx tr[] = { B1, B0 };
1760 7082 const NeighbourIdx bl[] = { A1, A0 };
1761
1762 7082 available[0] = AFFINE_MVP_CONSTRUCTED_CP(tl, cps + 0);
1763 7082 available[1] = AFFINE_MVP_CONSTRUCTED_CP(tr, cps + 1);
1764 7082 available[2] = AFFINE_MVP_CONSTRUCTED_CP(bl, cps + 2);
1765
4/4
✓ Branch 0 taken 5774 times.
✓ Branch 1 taken 1308 times.
✓ Branch 2 taken 4467 times.
✓ Branch 3 taken 1307 times.
7082 return available[0] && available[1];
1766 }
1767
1768 //8.5.5.7 item 7
1769 3290 static void affine_mvp_const2(const int idx, Mv *cps, const int num_cp)
1770 {
1771 3290 const Mv mv = cps[idx];
1772
2/2
✓ Branch 0 taken 8294 times.
✓ Branch 1 taken 3290 times.
11584 for (int j = 0; j < num_cp; j++)
1773 8294 cps[j] = mv;
1774 3290 }
1775
1776 //8.5.5.7 Derivation process for luma affine control point motion vector predictors
1777 11038 static void affine_mvp(const VVCLocalContext *lc,
1778 const int mvp_lx_flag, const int lx, const int8_t *ref_idx, const int amvr_shift,
1779 MotionModelIdc motion_model_idc, Mv *cps)
1780 {
1781 11038 const NeighbourIdx ak[] = { A0, A1 };
1782 11038 const NeighbourIdx bk[] = { B0, B1, B2 };
1783 11038 const int num_cp = motion_model_idc + 1;
1784 NeighbourContext nctx;
1785 int available[MAX_CONTROL_POINTS];
1786 11038 int num_cands = 0;
1787
1788 11038 init_neighbour_context(&nctx, lc);
1789 //Ak
1790
2/2
✓ Branch 1 taken 2861 times.
✓ Branch 2 taken 8177 times.
11038 if (AFFINE_MVP_FROM_NBS(ak)) {
1791
2/2
✓ Branch 0 taken 1926 times.
✓ Branch 1 taken 935 times.
2861 if (mvp_lx_flag == num_cands)
1792 10713 return;
1793 935 num_cands++;
1794 }
1795 //Bk
1796
2/2
✓ Branch 1 taken 2775 times.
✓ Branch 2 taken 6337 times.
9112 if (AFFINE_MVP_FROM_NBS(bk)) {
1797
2/2
✓ Branch 0 taken 2030 times.
✓ Branch 1 taken 745 times.
2775 if (mvp_lx_flag == num_cands)
1798 2030 return;
1799 745 num_cands++;
1800 }
1801
1802 //Const1
1803
2/2
✓ Branch 1 taken 4467 times.
✓ Branch 2 taken 2615 times.
7082 if (affine_mvp_const1(&nctx, lx, ref_idx[lx], amvr_shift, cps, available)) {
1804
4/4
✓ Branch 0 taken 1145 times.
✓ Branch 1 taken 3322 times.
✓ Branch 2 taken 600 times.
✓ Branch 3 taken 545 times.
4467 if (available[2] || motion_model_idc == MOTION_4_PARAMS_AFFINE) {
1805
2/2
✓ Branch 0 taken 2728 times.
✓ Branch 1 taken 1194 times.
3922 if (mvp_lx_flag == num_cands)
1806 2728 return;
1807 1194 num_cands++;
1808 }
1809 }
1810
1811 //Const2
1812
2/2
✓ Branch 0 taken 8264 times.
✓ Branch 1 taken 1064 times.
9328 for (int i = 2; i >= 0; i--) {
1813
2/2
✓ Branch 0 taken 3736 times.
✓ Branch 1 taken 4528 times.
8264 if (available[i]) {
1814
2/2
✓ Branch 0 taken 3290 times.
✓ Branch 1 taken 446 times.
3736 if (mvp_lx_flag == num_cands) {
1815 3290 affine_mvp_const2(i, cps, num_cp);
1816 3290 return;
1817 }
1818 446 num_cands++;
1819 }
1820 }
1821
2/2
✓ Branch 1 taken 846 times.
✓ Branch 2 taken 218 times.
1064 if (temporal_luma_motion_vector(lc, ref_idx[lx], cps, lx, 1, 0)) {
1822
2/2
✓ Branch 0 taken 739 times.
✓ Branch 1 taken 107 times.
846 if (mvp_lx_flag == num_cands) {
1823 739 ff_vvc_round_mv(cps, amvr_shift, amvr_shift);
1824
2/2
✓ Branch 0 taken 1020 times.
✓ Branch 1 taken 739 times.
1759 for (int i = 1; i < num_cp; i++)
1825 1020 cps[i] = cps[0];
1826 739 return;
1827 }
1828 107 num_cands++;
1829 }
1830
1831 //Zero Mv
1832 325 memset(cps, 0, num_cp * sizeof(Mv));
1833 }
1834
1835 9001 void ff_vvc_affine_mvp(VVCLocalContext *lc, const int *mvp_lx_flag, const int amvr_shift, MotionInfo *mi)
1836 {
1837 9001 const CodingUnit *cu = lc->cu;
1838
1839 9001 mi->num_sb_x = cu->cb_width >> MIN_PU_LOG2;
1840 9001 mi->num_sb_y = cu->cb_height >> MIN_PU_LOG2;
1841
1842 9001 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
1843
2/2
✓ Branch 0 taken 8031 times.
✓ Branch 1 taken 970 times.
9001 if (mi->pred_flag != PF_L1)
1844 8031 affine_mvp(lc, mvp_lx_flag[L0], L0, mi->ref_idx, amvr_shift, mi->motion_model_idc, &mi->mv[L0][0]);
1845
2/2
✓ Branch 0 taken 3007 times.
✓ Branch 1 taken 5994 times.
9001 if (mi->pred_flag != PF_L0)
1846 3007 affine_mvp(lc, mvp_lx_flag[L1], L1, mi->ref_idx, amvr_shift, mi->motion_model_idc, &mi->mv[L1][0]);
1847 9001 }
1848
1849 //8.5.2.14 Rounding process for motion vectors
1850 7081946 void ff_vvc_round_mv(Mv *mv, const int lshift, const int rshift)
1851 {
1852
2/2
✓ Branch 0 taken 7079388 times.
✓ Branch 1 taken 2558 times.
7081946 if (rshift) {
1853 7079388 const int offset = 1 << (rshift - 1);
1854 7079388 mv->x = ((mv->x + offset - (mv->x >= 0)) >> rshift) * (1 << lshift);
1855 7079388 mv->y = ((mv->y + offset - (mv->y >= 0)) >> rshift) * (1 << lshift);
1856 } else {
1857 2558 mv->x = mv->x * (1 << lshift);
1858 2558 mv->y = mv->y * (1 << lshift);
1859 }
1860 7081946 }
1861
1862 4970999 void ff_vvc_clip_mv(Mv *mv)
1863 {
1864 4970999 mv->x = av_clip(mv->x, -(1 << 17), (1 << 17) - 1);
1865 4970999 mv->y = av_clip(mv->y, -(1 << 17), (1 << 17) - 1);
1866 4970999 }
1867
1868 //8.5.2.1 Derivation process for motion vector components and reference indices
1869 312275 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)
1870 {
1871 312275 const uint8_t plevel = fc->ps.sps->log2_parallel_merge_level;
1872
1873
1/2
✓ Branch 0 taken 312275 times.
✗ Branch 1 not taken.
624550 return x0_br >> plevel > x0 >> plevel &&
1874
1/2
✓ Branch 0 taken 312275 times.
✗ Branch 1 not taken.
312275 y0_br >> plevel > y0 >> plevel;
1875 }
1876
1877 313655 static void update_hmvp(MvField *hmvp, int *num_hmvp, const MvField *mvf,
1878 int (*compare)(const MvField *n, const MvField *o))
1879 {
1880 int i;
1881
2/2
✓ Branch 0 taken 1332944 times.
✓ Branch 1 taken 169989 times.
1502933 for (i = 0; i < *num_hmvp; i++) {
1882
2/2
✓ Branch 1 taken 143666 times.
✓ Branch 2 taken 1189278 times.
1332944 if (compare(mvf, hmvp + i)) {
1883 143666 (*num_hmvp)--;
1884 143666 break;
1885 }
1886 }
1887
2/2
✓ Branch 0 taken 152121 times.
✓ Branch 1 taken 161534 times.
313655 if (i == MAX_NUM_HMVP_CANDS) {
1888 152121 (*num_hmvp)--;
1889 152121 i = 0;
1890 }
1891
1892 313655 memmove(hmvp + i, hmvp + i + 1, (*num_hmvp - i) * sizeof(MvField));
1893 313655 hmvp[(*num_hmvp)++] = *mvf;
1894 313655 }
1895
1896 6255 static int compare_l0_mv(const MvField *n, const MvField *o)
1897 {
1898 6255 return IS_SAME_MV(&n->mv[L0], &o->mv[L0]);
1899 }
1900
1901 //8.6.2.4 Derivation process for IBC history-based block vector candidates
1902 //8.5.2.16 Updating process for the history-based motion vector predictor candidate list
1903 313857 void ff_vvc_update_hmvp(VVCLocalContext *lc, const MotionInfo *mi)
1904 {
1905 313857 const VVCFrameContext *fc = lc->fc;
1906 313857 const CodingUnit *cu = lc->cu;
1907 313857 const int min_pu_width = fc->ps.pps->min_pu_width;
1908 313857 const MvField *tab_mvf = fc->tab.mvf;
1909 313857 EntryPoint *ep = lc->ep;
1910
1911
2/2
✓ Branch 0 taken 1582 times.
✓ Branch 1 taken 312275 times.
313857 if (cu->pred_mode == MODE_IBC) {
1912
2/2
✓ Branch 0 taken 202 times.
✓ Branch 1 taken 1380 times.
1582 if (cu->cb_width * cu->cb_height <= 16)
1913 202 return;
1914 1380 update_hmvp(ep->hmvp_ibc, &ep->num_hmvp_ibc, &TAB_MVF(cu->x0, cu->y0), compare_l0_mv);
1915 } else {
1916
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 312275 times.
312275 if (!is_greater_mer(fc, cu->x0, cu->y0, cu->x0 + cu->cb_width, cu->y0 + cu->cb_height))
1917 return;
1918 312275 update_hmvp(ep->hmvp, &ep->num_hmvp, &TAB_MVF(cu->x0, cu->y0), compare_mv_ref_idx);
1919 }
1920 }
1921
1922 11627792 MvField* ff_vvc_get_mvf(const VVCFrameContext *fc, const int x0, const int y0)
1923 {
1924 11627792 const int min_pu_width = fc->ps.pps->min_pu_width;
1925 11627792 MvField* tab_mvf = fc->tab.mvf;
1926
1927 11627792 return &TAB_MVF(x0, y0);
1928 }
1929