FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/vvc/mvs.c
Date: 2024-11-20 23:03:26
Exec Total Coverage
Lines: 1189 1200 99.1%
Functions: 81 81 100.0%
Branches: 639 680 94.0%

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 620510 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 620510 const uint8_t plevel = fc->ps.sps->log2_parallel_merge_level;
34
35
2/2
✓ Branch 0 taken 32794 times.
✓ Branch 1 taken 587716 times.
653304 return xN >> plevel == xP >> plevel &&
36
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32794 times.
32794 yN >> plevel == yP >> plevel;
37 }
38
39 //return true if we have same mvs and ref_idxs
40 2011514 static av_always_inline int compare_mv_ref_idx(const MvField *n, const MvField *o)
41 {
42
4/4
✓ Branch 0 taken 1699206 times.
✓ Branch 1 taken 312308 times.
✓ Branch 2 taken 524124 times.
✓ Branch 3 taken 1175082 times.
2011514 if (!o || n->pred_flag != o->pred_flag)
43 836432 return 0;
44
2/2
✓ Branch 0 taken 1475450 times.
✓ Branch 1 taken 251429 times.
1726879 for (int i = 0; i < 2; i++) {
45 1475450 PredFlag mask = i + 1;
46
2/2
✓ Branch 0 taken 1337590 times.
✓ Branch 1 taken 137860 times.
1475450 if (n->pred_flag & mask) {
47 1337590 const int same_ref_idx = n->ref_idx[i] == o->ref_idx[i];
48 1337590 const int same_mv = IS_SAME_MV(n->mv + i, o->mv + i);
49
4/4
✓ Branch 0 taken 1219678 times.
✓ Branch 1 taken 117912 times.
✓ Branch 2 taken 805741 times.
✓ Branch 3 taken 413937 times.
1337590 if (!same_ref_idx || !same_mv)
50 923653 return 0;
51 }
52 }
53 251429 return 1;
54 }
55
56 // 8.5.2.15 Temporal motion buffer compression process for collocated motion vectors
57 1913700 static av_always_inline void mv_compression(Mv *motion)
58 {
59 1913700 int mv[2] = {motion->x, motion->y};
60
2/2
✓ Branch 0 taken 3827400 times.
✓ Branch 1 taken 1913700 times.
5741100 for (int i = 0; i < 2; i++) {
61 3827400 const int s = mv[i] >> 17;
62 3827400 const int f = av_log2((mv[i] ^ s) | 31) - 4;
63 3827400 const int mask = (-1 * (1 << f)) >> 1;
64 3827400 const int round = (1 << f) >> 2;
65 3827400 mv[i] = (mv[i] + round) & mask;
66 }
67 1913700 motion->x = mv[0];
68 1913700 motion->y = mv[1];
69 1913700 }
70
71 1522009 void ff_vvc_mv_scale(Mv *dst, const Mv *src, int td, int tb)
72 {
73 int tx, scale_factor;
74
75 1522009 td = av_clip_int8(td);
76 1522009 tb = av_clip_int8(tb);
77 1522009 tx = (0x4000 + (abs(td) >> 1)) / td;
78 1522009 scale_factor = av_clip_intp2((tb * tx + 32) >> 6, 12);
79 1522009 dst->x = av_clip_intp2((scale_factor * src->x + 127 +
80 1522009 (scale_factor * src->x < 0)) >> 8, 17);
81 1522009 dst->y = av_clip_intp2((scale_factor * src->y + 127 +
82 1522009 (scale_factor * src->y < 0)) >> 8, 17);
83 1522009 }
84
85 //part of 8.5.2.12 Derivation process for collocated motion vectors
86 1913700 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 1913700 int cur_lt = refPicList[X].refs[refIdxLx].is_lt;
92 1913700 int col_lt = refPicList_col[listCol].refs[refidxCol].is_lt;
93 int col_poc_diff, cur_poc_diff;
94
95
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1913700 times.
1913700 if (cur_lt != col_lt) {
96 mvLXCol->x = 0;
97 mvLXCol->y = 0;
98 return 0;
99 }
100
101 1913700 col_poc_diff = colPic - refPicList_col[listCol].refs[refidxCol].poc;
102 1913700 cur_poc_diff = poc - refPicList[X].refs[refIdxLx].poc;
103
104 1913700 mv_compression(mvCol);
105
3/4
✓ Branch 0 taken 1913700 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 406696 times.
✓ Branch 3 taken 1507004 times.
1913700 if (cur_lt || col_poc_diff == cur_poc_diff) {
106 406696 mvLXCol->x = av_clip_intp2(mvCol->x, 17);
107 406696 mvLXCol->y = av_clip_intp2(mvCol->y, 17);
108 } else {
109 1507004 ff_vvc_mv_scale(mvLXCol, mvCol, col_poc_diff, cur_poc_diff);
110 }
111 1913700 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 449291 int ff_vvc_no_backward_pred_flag(const VVCLocalContext *lc)
122 {
123 449291 int check_diffpicount = 0;
124 int i, j;
125 449291 const RefPicList *rpl = lc->sc->rpl;
126
127
2/2
✓ Branch 0 taken 898582 times.
✓ Branch 1 taken 449291 times.
1347873 for (j = 0; j < 2; j++) {
128
2/2
✓ Branch 0 taken 1394677 times.
✓ Branch 1 taken 407321 times.
1801998 for (i = 0; i < lc->sc->sh.r->num_ref_idx_active[j]; i++) {
129
2/2
✓ Branch 0 taken 491261 times.
✓ Branch 1 taken 903416 times.
1394677 if (rpl[j].refs[i].poc > lc->fc->ps.ph.poc) {
130 491261 check_diffpicount++;
131 491261 break;
132 }
133 }
134 }
135 449291 return !check_diffpicount;
136 }
137
138 //8.5.2.12 Derivation process for collocated motion vectors
139 2311633 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 2311633 const VVCFrameContext *fc = lc->fc;
144 2311633 const SliceContext *sc = lc->sc;
145 2311633 RefPicList* refPicList = sc->rpl;
146
147
2/2
✓ Branch 0 taken 69490 times.
✓ Branch 1 taken 2242143 times.
2311633 if (temp_col.pred_flag == PF_INTRA)
148 69490 return 0;
149
150
2/2
✓ Branch 0 taken 2139046 times.
✓ Branch 1 taken 103097 times.
2242143 if (sb_flag){
151
2/2
✓ Branch 0 taken 1240840 times.
✓ Branch 1 taken 898206 times.
2139046 if (X == 0) {
152
2/2
✓ Branch 0 taken 1124178 times.
✓ Branch 1 taken 116662 times.
1240840 if (temp_col.pred_flag & PF_L0)
153 1124178 return CHECK_MVSET(0);
154
3/4
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 114788 times.
✓ Branch 3 taken 1874 times.
✗ Branch 4 not taken.
116662 else if (ff_vvc_no_backward_pred_flag(lc) && (temp_col.pred_flag & PF_L1))
155 1874 return CHECK_MVSET(1);
156 } else {
157
2/2
✓ Branch 0 taken 622529 times.
✓ Branch 1 taken 275677 times.
898206 if (temp_col.pred_flag & PF_L1)
158 622529 return CHECK_MVSET(1);
159
3/4
✓ Branch 1 taken 62022 times.
✓ Branch 2 taken 213655 times.
✓ Branch 3 taken 62022 times.
✗ Branch 4 not taken.
275677 else if (ff_vvc_no_backward_pred_flag(lc) && (temp_col.pred_flag & PF_L0))
160 62022 return CHECK_MVSET(0);
161 }
162 } else {
163
2/2
✓ Branch 0 taken 11801 times.
✓ Branch 1 taken 91296 times.
103097 if (!(temp_col.pred_flag & PF_L0))
164 11801 return CHECK_MVSET(1);
165
2/2
✓ Branch 0 taken 45422 times.
✓ Branch 1 taken 45874 times.
91296 else if (temp_col.pred_flag == PF_L0)
166 45422 return CHECK_MVSET(0);
167
1/2
✓ Branch 0 taken 45874 times.
✗ Branch 1 not taken.
45874 else if (temp_col.pred_flag == PF_BI) {
168
2/2
✓ Branch 1 taken 8805 times.
✓ Branch 2 taken 37069 times.
45874 if (ff_vvc_no_backward_pred_flag(lc)) {
169
2/2
✓ Branch 0 taken 4540 times.
✓ Branch 1 taken 4265 times.
8805 if (X == 0)
170 4540 return CHECK_MVSET(0);
171 else
172 4265 return CHECK_MVSET(1);
173 } else {
174
2/2
✓ Branch 0 taken 22117 times.
✓ Branch 1 taken 14952 times.
37069 if (!lc->sc->sh.r->sh_collocated_from_l0_flag)
175 22117 return CHECK_MVSET(0);
176 else
177 14952 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 129253 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 129253 const VVCFrameContext *fc = lc->fc;
204 129253 const VVCSPS *sps = fc->ps.sps;
205 129253 const VVCPPS *pps = fc->ps.pps;
206 129253 const CodingUnit *cu = lc->cu;
207 129253 const int subpic_idx = lc->sc->sh.r->curr_subpic_idx;
208 129253 int x, y, x_end, y_end, colPic, availableFlagLXCol = 0;
209 129253 int min_pu_width = fc->ps.pps->min_pu_width;
210 129253 VVCFrame *ref = fc->ref->collocated_ref;
211 MvField *tab_mvf;
212 MvField temp_col;
213
214
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 129187 times.
129253 if (!ref) {
215 66 memset(mvLXCol, 0, sizeof(*mvLXCol));
216 66 return 0;
217 }
218
219
3/4
✓ Branch 0 taken 129187 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1672 times.
✓ Branch 3 taken 127515 times.
129187 if (!fc->ps.ph.r->ph_temporal_mvp_enabled_flag || (cu->cb_width * cu->cb_height <= 32))
220 1672 return 0;
221
222 127515 tab_mvf = ref->tab_dmvr_mvf;
223 127515 colPic = ref->poc;
224
225 //bottom right collocated motion vector
226 127515 x = cu->x0 + cu->cb_width;
227 127515 y = cu->y0 + cu->cb_height;
228
229 127515 x_end = pps->subpic_x[subpic_idx] + pps->subpic_width[subpic_idx];
230 127515 y_end = pps->subpic_y[subpic_idx] + pps->subpic_height[subpic_idx];
231
232
1/2
✓ Branch 0 taken 127515 times.
✗ Branch 1 not taken.
127515 if (tab_mvf &&
233
4/4
✓ Branch 0 taken 107121 times.
✓ Branch 1 taken 20394 times.
✓ Branch 2 taken 105229 times.
✓ Branch 3 taken 1892 times.
127515 (cu->y0 >> sps->ctb_log2_size_y) == (y >> sps->ctb_log2_size_y) &&
234
2/2
✓ Branch 0 taken 101593 times.
✓ Branch 1 taken 3636 times.
105229 x < x_end && y < y_end) {
235 101593 x &= ~7;
236 101593 y &= ~7;
237 101593 temp_col = TAB_MVF(x, y);
238 101593 availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS(sb_flag);
239 }
240
2/2
✓ Branch 0 taken 114237 times.
✓ Branch 1 taken 13278 times.
127515 if (check_center) {
241 // derive center collocated motion vector
242
3/4
✓ Branch 0 taken 114237 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45400 times.
✓ Branch 3 taken 68837 times.
114237 if (tab_mvf && !availableFlagLXCol) {
243 45400 x = cu->x0 + (cu->cb_width >> 1);
244 45400 y = cu->y0 + (cu->cb_height >> 1);
245 45400 x &= ~7;
246 45400 y &= ~7;
247 45400 temp_col = TAB_MVF(x, y);
248 45400 availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS(sb_flag);
249 }
250 }
251 127515 return availableFlagLXCol;
252 }
253
254 5209614 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 5209614 const VVCFrameContext *fc = lc->fc;
257 5209614 MvField *tab_mvf = fc->tab.mvf;
258 5209614 const int min_pu_width = fc->ps.pps->min_pu_width;
259 5209614 const int min_pu_size = 1 << MIN_PU_LOG2;
260
2/2
✓ Branch 0 taken 8201275 times.
✓ Branch 1 taken 5209614 times.
13410889 for (int dy = 0; dy < h; dy += min_pu_size) {
261
2/2
✓ Branch 0 taken 36905324 times.
✓ Branch 1 taken 8201275 times.
45106599 for (int dx = 0; dx < w; dx += min_pu_size) {
262 36905324 const int x = x0 + dx;
263 36905324 const int y = y0 + dy;
264 36905324 TAB_MVF(x, y) = *mvf;
265 }
266 }
267 5209614 }
268
269 544620 void ff_vvc_set_intra_mvf(const VVCLocalContext *lc, const int dmvr)
270 {
271 544620 const VVCFrameContext *fc = lc->fc;
272 544620 const CodingUnit *cu = lc->cu;
273
2/2
✓ Branch 0 taken 1582 times.
✓ Branch 1 taken 543038 times.
544620 MvField *tab_mvf = dmvr ? fc->ref->tab_dmvr_mvf : fc->tab.mvf;
274 544620 const int min_pu_width = fc->ps.pps->min_pu_width;
275 544620 const int min_pu_size = 1 << MIN_PU_LOG2;
276
2/2
✓ Branch 0 taken 1429282 times.
✓ Branch 1 taken 544620 times.
1973902 for (int dy = 0; dy < cu->cb_height; dy += min_pu_size) {
277
2/2
✓ Branch 0 taken 6249720 times.
✓ Branch 1 taken 1429282 times.
7679002 for (int dx = 0; dx < cu->cb_width; dx += min_pu_size) {
278 6249720 const int x = cu->x0 + dx;
279 6249720 const int y = cu->y0 + dy;
280 6249720 TAB_MVF(x, y).pred_flag = PF_INTRA;
281 }
282 }
283 544620 }
284
285 //cbProfFlagLX from 8.5.5.9 Derivation process for motion vector arrays from affine control point motion vectors
286 41182 static int derive_cb_prof_flag_lx(const VVCLocalContext *lc, const PredictionUnit* pu, int lx, int is_fallback)
287 {
288 41182 const MotionInfo* mi = &pu->mi;
289 41182 const Mv* cp_mv = &mi->mv[lx][0];
290
4/4
✓ Branch 0 taken 41015 times.
✓ Branch 1 taken 167 times.
✓ Branch 2 taken 237 times.
✓ Branch 3 taken 40778 times.
41182 if (lc->fc->ps.ph.r->ph_prof_disabled_flag || is_fallback)
291 404 return 0;
292
2/2
✓ Branch 0 taken 15544 times.
✓ Branch 1 taken 25234 times.
40778 if (mi->motion_model_idc == MOTION_4_PARAMS_AFFINE) {
293
2/2
✓ Branch 0 taken 2447 times.
✓ Branch 1 taken 13097 times.
15544 if (IS_SAME_MV(cp_mv, cp_mv + 1))
294 2447 return 0;
295 }
296
2/2
✓ Branch 0 taken 25234 times.
✓ Branch 1 taken 13097 times.
38331 if (mi->motion_model_idc == MOTION_6_PARAMS_AFFINE) {
297
4/4
✓ Branch 0 taken 4239 times.
✓ Branch 1 taken 20995 times.
✓ Branch 2 taken 891 times.
✓ Branch 3 taken 3348 times.
25234 if (IS_SAME_MV(cp_mv, cp_mv + 1) && IS_SAME_MV(cp_mv, cp_mv + 2))
298 891 return 0;
299 }
300
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 37303 times.
37440 if (lc->sc->rpl[lx].refs[mi->ref_idx[lx]].is_scaled)
301 137 return 0;
302 37303 return 1;
303 }
304
305 typedef struct SubblockParams {
306 int d_hor_x;
307 int d_ver_x;
308 int d_hor_y;
309 int d_ver_y;
310 int mv_scale_hor;
311 int mv_scale_ver;
312 int is_fallback;
313
314 int cb_width;
315 int cb_height;
316 } SubblockParams;
317
318 41182 static int is_fallback_mode(const SubblockParams *sp, const PredFlag pred_flag)
319 {
320 41182 const int a = 4 * (2048 + sp->d_hor_x);
321 41182 const int b = 4 * sp->d_hor_y;
322 41182 const int c = 4 * (2048 + sp->d_ver_y);
323 41182 const int d = 4 * sp->d_ver_x;
324
2/2
✓ Branch 0 taken 17210 times.
✓ Branch 1 taken 23972 times.
41182 if (pred_flag == PF_BI) {
325
2/2
✓ Branch 0 taken 17195 times.
✓ Branch 1 taken 15 times.
17210 const int max_w4 = FFMAX(0, FFMAX(a, FFMAX(b, a + b)));
326
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 17195 times.
17210 const int min_w4 = FFMIN(0, FFMIN(a, FFMIN(b, a + b)));
327
2/2
✓ Branch 0 taken 17204 times.
✓ Branch 1 taken 6 times.
17210 const int max_h4 = FFMAX(0, FFMAX(c, FFMAX(d, c + d)));
328
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 17204 times.
17210 const int min_h4 = FFMIN(0, FFMIN(c, FFMIN(d, c + d)));
329 17210 const int bx_wx4 = ((max_w4 - min_w4) >> 11) + 9;
330 17210 const int bx_hx4 = ((max_h4 - min_h4) >> 11) + 9;
331 17210 return bx_wx4 * bx_hx4 > 225;
332 } else {
333 23972 const int bx_wxh = (FFABS(a) >> 11) + 9;
334 23972 const int bx_hxh = (FFABS(d) >> 11) + 9;
335 23972 const int bx_wxv = (FFABS(b) >> 11) + 9;
336 23972 const int bx_hxv = (FFABS(c) >> 11) + 9;
337
4/4
✓ Branch 0 taken 23887 times.
✓ Branch 1 taken 85 times.
✓ Branch 2 taken 23797 times.
✓ Branch 3 taken 90 times.
23972 if (bx_wxh * bx_hxh <= 165 && bx_wxv * bx_hxv <= 165)
338 23797 return 0;
339 }
340 175 return 1;
341 }
342
343 41182 static void init_subblock_params(SubblockParams *sp, const MotionInfo* mi,
344 const int cb_width, const int cb_height, const int lx)
345 {
346 41182 const int log2_cbw = av_log2(cb_width);
347 41182 const int log2_cbh = av_log2(cb_height);
348 41182 const Mv* cp_mv = mi->mv[lx];
349 41182 const int num_cp_mv = mi->motion_model_idc + 1;
350 41182 sp->d_hor_x = (cp_mv[1].x - cp_mv[0].x) * (1 << (MAX_CU_DEPTH - log2_cbw));
351 41182 sp->d_ver_x = (cp_mv[1].y - cp_mv[0].y) * (1 << (MAX_CU_DEPTH - log2_cbw));
352
2/2
✓ Branch 0 taken 25614 times.
✓ Branch 1 taken 15568 times.
41182 if (num_cp_mv == 3) {
353 25614 sp->d_hor_y = (cp_mv[2].x - cp_mv[0].x) * (1 << (MAX_CU_DEPTH - log2_cbh));
354 25614 sp->d_ver_y = (cp_mv[2].y - cp_mv[0].y) * (1 << (MAX_CU_DEPTH - log2_cbh));
355 } else {
356 15568 sp->d_hor_y = -sp->d_ver_x;
357 15568 sp->d_ver_y = sp->d_hor_x;
358 }
359 41182 sp->mv_scale_hor = (cp_mv[0].x) * (1 << MAX_CU_DEPTH);
360 41182 sp->mv_scale_ver = (cp_mv[0].y) * (1 << MAX_CU_DEPTH);
361 41182 sp->cb_width = cb_width;
362 41182 sp->cb_height = cb_height;
363 41182 sp->is_fallback = is_fallback_mode(sp, mi->pred_flag);
364 41182 }
365
366 41182 static void derive_subblock_diff_mvs(const VVCLocalContext *lc, PredictionUnit* pu, const SubblockParams* sp, const int lx)
367 {
368 41182 pu->cb_prof_flag[lx] = derive_cb_prof_flag_lx(lc, pu, lx, sp->is_fallback);
369
2/2
✓ Branch 0 taken 37303 times.
✓ Branch 1 taken 3879 times.
41182 if (pu->cb_prof_flag[lx]) {
370 37303 const int dmv_limit = 1 << 5;
371 37303 const int pos_offset_x = 6 * (sp->d_hor_x + sp->d_hor_y);
372 37303 const int pos_offset_y = 6 * (sp->d_ver_x + sp->d_ver_y);
373
2/2
✓ Branch 0 taken 149212 times.
✓ Branch 1 taken 37303 times.
186515 for (int x = 0; x < AFFINE_MIN_BLOCK_SIZE; x++) {
374
2/2
✓ Branch 0 taken 596848 times.
✓ Branch 1 taken 149212 times.
746060 for (int y = 0; y < AFFINE_MIN_BLOCK_SIZE; y++) {
375 596848 LOCAL_ALIGNED_8(Mv, diff, [1]);
376 596848 diff->x = x * (sp->d_hor_x * (1 << 2)) + y * (sp->d_hor_y * (1 << 2)) - pos_offset_x;
377 596848 diff->y = x * (sp->d_ver_x * (1 << 2)) + y * (sp->d_ver_y * (1 << 2)) - pos_offset_y;
378 596848 ff_vvc_round_mv(diff, 0, 8);
379 596848 pu->diff_mv_x[lx][AFFINE_MIN_BLOCK_SIZE * y + x] = av_clip(diff->x, -dmv_limit + 1, dmv_limit - 1);
380 596848 pu->diff_mv_y[lx][AFFINE_MIN_BLOCK_SIZE * y + x] = av_clip(diff->y, -dmv_limit + 1, dmv_limit - 1);
381 }
382 }
383 }
384 41182 }
385
386 41182 static void store_cp_mv(const VVCLocalContext *lc, const MotionInfo *mi, const int lx)
387 {
388 41182 VVCFrameContext *fc = lc->fc;
389 41182 const CodingUnit *cu = lc->cu;
390 41182 const int log2_min_cb_size = fc->ps.sps->min_cb_log2_size_y;
391 41182 const int min_cb_size = fc->ps.sps->min_cb_size_y;
392 41182 const int min_cb_width = fc->ps.pps->min_cb_width;
393 41182 const int num_cp_mv = mi->motion_model_idc + 1;
394
395
2/2
✓ Branch 0 taken 325474 times.
✓ Branch 1 taken 41182 times.
366656 for (int dy = 0; dy < cu->cb_height; dy += min_cb_size) {
396
2/2
✓ Branch 0 taken 4037476 times.
✓ Branch 1 taken 325474 times.
4362950 for (int dx = 0; dx < cu->cb_width; dx += min_cb_size) {
397 4037476 const int x_cb = (cu->x0 + dx) >> log2_min_cb_size;
398 4037476 const int y_cb = (cu->y0 + dy) >> log2_min_cb_size;
399 4037476 const int offset = (y_cb * min_cb_width + x_cb) * MAX_CONTROL_POINTS;
400
401 4037476 memcpy(&fc->tab.cp_mv[lx][offset], mi->mv[lx], sizeof(Mv) * num_cp_mv);
402 }
403 }
404 41182 }
405
406 //8.5.5.9 Derivation process for motion vector arrays from affine control point motion vectors
407 32577 void ff_vvc_store_sb_mvs(const VVCLocalContext *lc, PredictionUnit *pu)
408 {
409 32577 const CodingUnit *cu = lc->cu;
410 32577 const MotionInfo *mi = &pu->mi;
411 32577 const int sbw = cu->cb_width / mi->num_sb_x;
412 32577 const int sbh = cu->cb_height / mi->num_sb_y;
413 SubblockParams params[2];
414 32577 MvField mvf = {0};
415
416 32577 mvf.pred_flag = mi->pred_flag;
417 32577 mvf.bcw_idx = mi->bcw_idx;
418 32577 mvf.hpel_if_idx = mi->hpel_if_idx;
419
2/2
✓ Branch 0 taken 65154 times.
✓ Branch 1 taken 32577 times.
97731 for (int i = 0; i < 2; i++) {
420 65154 const PredFlag mask = i + 1;
421
2/2
✓ Branch 0 taken 41182 times.
✓ Branch 1 taken 23972 times.
65154 if (mi->pred_flag & mask) {
422 41182 store_cp_mv(lc, mi, i);
423 41182 init_subblock_params(params + i, mi, cu->cb_width, cu->cb_height, i);
424 41182 derive_subblock_diff_mvs(lc, pu, params + i, i);
425 41182 mvf.ref_idx[i] = mi->ref_idx[i];
426 }
427 }
428
429
2/2
✓ Branch 0 taken 258140 times.
✓ Branch 1 taken 32577 times.
290717 for (int sby = 0; sby < mi->num_sb_y; sby++) {
430
2/2
✓ Branch 0 taken 3169240 times.
✓ Branch 1 taken 258140 times.
3427380 for (int sbx = 0; sbx < mi->num_sb_x; sbx++) {
431 3169240 const int x0 = cu->x0 + sbx * sbw;
432 3169240 const int y0 = cu->y0 + sby * sbh;
433
2/2
✓ Branch 0 taken 6338480 times.
✓ Branch 1 taken 3169240 times.
9507720 for (int i = 0; i < 2; i++) {
434 6338480 const PredFlag mask = i + 1;
435
2/2
✓ Branch 0 taken 4037476 times.
✓ Branch 1 taken 2301004 times.
6338480 if (mi->pred_flag & mask) {
436 4037476 const SubblockParams* sp = params + i;
437
2/2
✓ Branch 0 taken 7700 times.
✓ Branch 1 taken 4029776 times.
4037476 const int x_pos_cb = sp->is_fallback ? (cu->cb_width >> 1) : (2 + (sbx << MIN_CU_LOG2));
438
2/2
✓ Branch 0 taken 7700 times.
✓ Branch 1 taken 4029776 times.
4037476 const int y_pos_cb = sp->is_fallback ? (cu->cb_height >> 1) : (2 + (sby << MIN_CU_LOG2));
439 4037476 Mv *mv = mvf.mv + i;
440
441 4037476 mv->x = sp->mv_scale_hor + sp->d_hor_x * x_pos_cb + sp->d_hor_y * y_pos_cb;
442 4037476 mv->y = sp->mv_scale_ver + sp->d_ver_x * x_pos_cb + sp->d_ver_y * y_pos_cb;
443 4037476 ff_vvc_round_mv(mv, 0, MAX_CU_DEPTH);
444 4037476 ff_vvc_clip_mv(mv);
445 }
446 }
447 3169240 ff_vvc_set_mvf(lc, x0, y0, sbw, sbh, &mvf);
448 }
449 }
450 32577 }
451
452 24737 void ff_vvc_store_gpm_mvf(const VVCLocalContext *lc, const PredictionUnit *pu)
453 {
454 24737 const CodingUnit *cu = lc->cu;
455 24737 const int angle_idx = ff_vvc_gpm_angle_idx[pu->gpm_partition_idx];
456 24737 const int distance_idx = ff_vvc_gpm_distance_idx[pu->gpm_partition_idx];
457 24737 const int displacement_x = ff_vvc_gpm_distance_lut[angle_idx];
458 24737 const int displacement_y = ff_vvc_gpm_distance_lut[(angle_idx + 8) % 32];
459
4/4
✓ Branch 0 taken 12982 times.
✓ Branch 1 taken 11755 times.
✓ Branch 2 taken 10424 times.
✓ Branch 3 taken 2558 times.
24737 const int is_flip = angle_idx >= 13 &&angle_idx <= 27;
460
6/6
✓ Branch 0 taken 23196 times.
✓ Branch 1 taken 1541 times.
✓ Branch 2 taken 20487 times.
✓ Branch 3 taken 2709 times.
✓ Branch 4 taken 4918 times.
✓ Branch 5 taken 15569 times.
24737 const int shift_hor = (angle_idx % 16 == 8 || (angle_idx % 16 && cu->cb_height >= cu->cb_width)) ? 0 : 1;
461
2/2
✓ Branch 0 taken 14571 times.
✓ Branch 1 taken 10166 times.
24737 const int sign = angle_idx < 16 ? 1 : -1;
462 24737 const int block_size = 4;
463 24737 int offset_x = (-cu->cb_width) >> 1;
464 24737 int offset_y = (-cu->cb_height) >> 1;
465
466
2/2
✓ Branch 0 taken 17110 times.
✓ Branch 1 taken 7627 times.
24737 if (!shift_hor)
467 17110 offset_y += sign * ((distance_idx * cu->cb_height) >> 3);
468 else
469 7627 offset_x += sign * ((distance_idx * cu->cb_width) >> 3);
470
471
2/2
✓ Branch 0 taken 111242 times.
✓ Branch 1 taken 24737 times.
135979 for (int y = 0; y < cu->cb_height; y += block_size) {
472
2/2
✓ Branch 0 taken 511556 times.
✓ Branch 1 taken 111242 times.
622798 for (int x = 0; x < cu->cb_width; x += block_size) {
473 511556 const int motion_idx = (((x + offset_x) * (1 << 1)) + 5) * displacement_x +
474 511556 (((y + offset_y) * (1 << 1)) + 5) * displacement_y;
475
6/6
✓ Branch 0 taken 256690 times.
✓ Branch 1 taken 254866 times.
✓ Branch 2 taken 154995 times.
✓ Branch 3 taken 101695 times.
✓ Branch 4 taken 254866 times.
✓ Branch 5 taken 154995 times.
511556 const int s_type = FFABS(motion_idx) < 32 ? 2 : (motion_idx <= 0 ? (1 - is_flip) : is_flip);
476 511556 const int pred_flag = pu->gpm_mv[0].pred_flag | pu->gpm_mv[1].pred_flag;
477 511556 const int x0 = cu->x0 + x;
478 511556 const int y0 = cu->y0 + y;
479
480
2/2
✓ Branch 0 taken 199134 times.
✓ Branch 1 taken 312422 times.
511556 if (!s_type)
481 199134 ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, pu->gpm_mv + 0);
482
5/6
✓ Branch 0 taken 101695 times.
✓ Branch 1 taken 210727 times.
✓ Branch 2 taken 101695 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 54610 times.
✓ Branch 5 taken 47085 times.
312422 else if (s_type == 1 || (s_type == 2 && pred_flag != PF_BI))
483 265337 ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, pu->gpm_mv + 1);
484 else {
485 47085 MvField mvf = pu->gpm_mv[0];
486 47085 const MvField *mv1 = &pu->gpm_mv[1];
487 47085 const int lx = mv1->pred_flag - PF_L0;
488 47085 mvf.pred_flag = PF_BI;
489 47085 mvf.ref_idx[lx] = mv1->ref_idx[lx];
490 47085 mvf.mv[lx] = mv1->mv[lx];
491 47085 ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, &mvf);
492 }
493 }
494 }
495 24737 }
496
497 270839 void ff_vvc_store_mvf(const VVCLocalContext *lc, const MvField *mvf)
498 {
499 270839 const CodingUnit *cu = lc->cu;
500 270839 ff_vvc_set_mvf(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height, mvf);
501 270839 }
502
503 52051 void ff_vvc_store_mv(const VVCLocalContext *lc, const MotionInfo *mi)
504 {
505 52051 const CodingUnit *cu = lc->cu;
506 52051 MvField mvf = {0};
507
508 52051 mvf.hpel_if_idx = mi->hpel_if_idx;
509 52051 mvf.bcw_idx = mi->bcw_idx;
510 52051 mvf.pred_flag = mi->pred_flag;
511
512
2/2
✓ Branch 0 taken 104102 times.
✓ Branch 1 taken 52051 times.
156153 for (int i = 0; i < 2; i++) {
513 104102 const PredFlag mask = i + 1;
514
2/2
✓ Branch 0 taken 67915 times.
✓ Branch 1 taken 36187 times.
104102 if (mvf.pred_flag & mask) {
515 67915 mvf.mv[i] = mi->mv[i][0];
516 67915 mvf.ref_idx[i] = mi->ref_idx[i];
517 }
518 }
519 52051 ff_vvc_set_mvf(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height, &mvf);
520 52051 }
521
522 typedef enum NeighbourIdx {
523 A0,
524 A1,
525 A2,
526 B0,
527 B1,
528 B2,
529 B3,
530 NUM_NBS,
531 NB_IDX_NONE = NUM_NBS,
532 } NeighbourIdx;
533
534 typedef struct Neighbour {
535 int x;
536 int y;
537
538 int checked;
539 int available;
540 } Neighbour;
541
542 typedef struct NeighbourContext {
543 Neighbour neighbours[NUM_NBS];
544 const VVCLocalContext *lc;
545 } NeighbourContext;
546
547 1179207 static int is_available(const VVCFrameContext *fc, const int x0, const int y0)
548 {
549 1179207 const VVCSPS *sps = fc->ps.sps;
550 1179207 const int x = x0 >> sps->min_cb_log2_size_y;
551 1179207 const int y = y0 >> sps->min_cb_log2_size_y;
552 1179207 const int min_cb_width = fc->ps.pps->min_cb_width;
553
554 1179207 return SAMPLE_CTB(fc->tab.cb_width[0], x, y) != 0;
555 }
556
557 423267 static int is_a0_available(const VVCLocalContext *lc, const CodingUnit *cu)
558 {
559 423267 const VVCFrameContext *fc = lc->fc;
560 423267 const VVCSPS *sps = fc->ps.sps;
561 423267 const int x0b = av_zero_extend(cu->x0, sps->ctb_log2_size_y);
562 int cand_bottom_left;
563
564
4/4
✓ Branch 0 taken 95403 times.
✓ Branch 1 taken 327864 times.
✓ Branch 2 taken 12334 times.
✓ Branch 3 taken 83069 times.
423267 if (!x0b && !lc->ctb_left_flag) {
565 12334 cand_bottom_left = 0;
566 } else {
567 410933 const int max_y = FFMIN(fc->ps.pps->height, ((cu->y0 >> sps->ctb_log2_size_y) + 1) << sps->ctb_log2_size_y);
568
2/2
✓ Branch 0 taken 89529 times.
✓ Branch 1 taken 321404 times.
410933 if (cu->y0 + cu->cb_height >= max_y)
569 89529 cand_bottom_left = 0;
570 else
571 321404 cand_bottom_left = is_available(fc, cu->x0 - 1, cu->y0 + cu->cb_height);
572 }
573 423267 return cand_bottom_left;
574 }
575
576 423267 static void init_neighbour_context(NeighbourContext *ctx, const VVCLocalContext *lc)
577 {
578 423267 const CodingUnit *cu = lc->cu;
579 423267 const NeighbourAvailable *na = &lc->na;
580 423267 const int x0 = cu->x0;
581 423267 const int y0 = cu->y0;
582 423267 const int cb_width = cu->cb_width;
583 423267 const int cb_height = cu->cb_height;
584 423267 const int a0_available = is_a0_available(lc, cu);
585
586 423267 Neighbour neighbours[NUM_NBS] = {
587 423267 { x0 - 1, y0 + cb_height, !a0_available }, //A0
588 423267 { x0 - 1, y0 + cb_height - 1, !na->cand_left }, //A1
589 423267 { x0 - 1, y0, !na->cand_left }, //A2
590 423267 { x0 + cb_width, y0 - 1, !na->cand_up_right }, //B0
591 423267 { x0 + cb_width - 1, y0 - 1, !na->cand_up }, //B1
592 423267 { x0 - 1, y0 - 1, !na->cand_up_left }, //B2
593 423267 { x0, y0 - 1, !na->cand_up }, //B3
594 };
595
596 423267 memcpy(ctx->neighbours, neighbours, sizeof(neighbours));
597 423267 ctx->lc = lc;
598 423267 }
599
600 818195 static av_always_inline PredMode pred_flag_to_mode(PredFlag pred)
601 {
602
2/2
✓ Branch 0 taken 816879 times.
✓ Branch 1 taken 1316 times.
818195 return pred == PF_IBC ? MODE_IBC : (pred == PF_INTRA ? MODE_INTRA : MODE_INTER);
603 }
604
605 1109197 static int check_available(Neighbour *n, const VVCLocalContext *lc, const int check_mer)
606 {
607 1109197 const VVCFrameContext *fc = lc->fc;
608 1109197 const VVCSPS *sps = fc->ps.sps;
609 1109197 const CodingUnit *cu = lc->cu;
610 1109197 const MvField *tab_mvf = fc->tab.mvf;
611 1109197 const int min_pu_width = fc->ps.pps->min_pu_width;
612
613
2/2
✓ Branch 0 taken 858003 times.
✓ Branch 1 taken 251194 times.
1109197 if (!n->checked) {
614 858003 n->checked = 1;
615
4/4
✓ Branch 0 taken 87906 times.
✓ Branch 1 taken 770097 times.
✓ Branch 2 taken 87706 times.
✓ Branch 3 taken 200 times.
858003 n->available = !sps->r->sps_entropy_coding_sync_enabled_flag || ((n->x >> sps->ctb_log2_size_y) <= (cu->x0 >> sps->ctb_log2_size_y));
616
6/6
✓ Branch 0 taken 857803 times.
✓ Branch 1 taken 200 times.
✓ Branch 3 taken 818195 times.
✓ Branch 4 taken 39608 times.
✓ Branch 6 taken 762374 times.
✓ Branch 7 taken 55821 times.
858003 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);
617
2/2
✓ Branch 0 taken 682055 times.
✓ Branch 1 taken 175948 times.
858003 if (check_mer)
618
3/4
✓ Branch 0 taken 620510 times.
✓ Branch 1 taken 61545 times.
✓ Branch 3 taken 620510 times.
✗ Branch 4 not taken.
682055 n->available = n->available && !is_same_mer(fc, n->x, n->y, cu->x0, cu->y0);
619 }
620 1109197 return n->available;
621 }
622
623 523625 static const MvField *mv_merge_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand)
624 {
625 523625 const VVCFrameContext *fc = lc->fc;
626 523625 const int min_pu_width = fc->ps.pps->min_pu_width;
627 523625 const MvField* tab_mvf = fc->tab.mvf;
628 523625 const MvField *mvf = &TAB_MVF(x_cand, y_cand);
629
630 523625 return mvf;
631 }
632
633 653184 static const MvField* mv_merge_from_nb(NeighbourContext *ctx, const NeighbourIdx nb)
634 {
635 653184 const VVCLocalContext *lc = ctx->lc;
636 653184 Neighbour *n = &ctx->neighbours[nb];
637
638
2/2
✓ Branch 1 taken 523625 times.
✓ Branch 2 taken 129559 times.
653184 if (check_available(n, lc, 1))
639 523625 return mv_merge_candidate(lc, n->x, n->y);
640 129559 return 0;
641 }
642 #define MV_MERGE_FROM_NB(nb) mv_merge_from_nb(&nctx, nb)
643
644 //8.5.2.3 Derivation process for spatial merging candidates
645 295576 static int mv_merge_spatial_candidates(const VVCLocalContext *lc, const int merge_idx,
646 const MvField **nb_list, MvField *cand_list, int *nb_merge_cand)
647 {
648 const MvField *cand;
649 295576 int num_cands = 0;
650 NeighbourContext nctx;
651
652 static NeighbourIdx nbs[][2] = {
653 {B1, NB_IDX_NONE },
654 {A1, B1 },
655 {B0, B1 },
656 {A0, A1 },
657 };
658
659 295576 init_neighbour_context(&nctx, lc);
660
2/2
✓ Branch 0 taken 591596 times.
✓ Branch 1 taken 62257 times.
653853 for (int i = 0; i < FF_ARRAY_ELEMS(nbs); i++) {
661 591596 NeighbourIdx nb = nbs[i][0];
662 591596 NeighbourIdx old = nbs[i][1];
663 591596 cand = nb_list[nb] = MV_MERGE_FROM_NB(nb);
664
4/4
✓ Branch 0 taken 473386 times.
✓ Branch 1 taken 118210 times.
✓ Branch 3 taken 427396 times.
✓ Branch 4 taken 45990 times.
591596 if (cand && !compare_mv_ref_idx(cand, nb_list[old])) {
665 427396 cand_list[num_cands] = *cand;
666
2/2
✓ Branch 0 taken 233319 times.
✓ Branch 1 taken 194077 times.
427396 if (merge_idx == num_cands)
667 233319 return 1;
668 194077 num_cands++;
669 }
670 }
671
2/2
✓ Branch 0 taken 61588 times.
✓ Branch 1 taken 669 times.
62257 if (num_cands != 4) {
672 61588 cand = MV_MERGE_FROM_NB(B2);
673
4/4
✓ Branch 0 taken 50239 times.
✓ Branch 1 taken 11349 times.
✓ Branch 3 taken 30311 times.
✓ Branch 4 taken 19928 times.
61588 if (cand && !compare_mv_ref_idx(cand, nb_list[A1])
674
2/2
✓ Branch 1 taken 21532 times.
✓ Branch 2 taken 8779 times.
30311 && !compare_mv_ref_idx(cand, nb_list[B1])) {
675 21532 cand_list[num_cands] = *cand;
676
2/2
✓ Branch 0 taken 9652 times.
✓ Branch 1 taken 11880 times.
21532 if (merge_idx == num_cands)
677 9652 return 1;
678 11880 num_cands++;
679 }
680 }
681 52605 *nb_merge_cand = num_cands;
682 52605 return 0;
683 }
684
685 52605 static int mv_merge_temporal_candidate(const VVCLocalContext *lc, MvField *cand)
686 {
687 52605 const VVCFrameContext *fc = lc->fc;
688 52605 const CodingUnit *cu = lc->cu;
689
690 52605 memset(cand, 0, sizeof(*cand));
691
4/4
✓ Branch 0 taken 52458 times.
✓ Branch 1 taken 147 times.
✓ Branch 2 taken 49637 times.
✓ Branch 3 taken 2821 times.
52605 if (fc->ps.ph.r->ph_temporal_mvp_enabled_flag && (cu->cb_width * cu->cb_height > 32)) {
692 49637 int available_l0 = temporal_luma_motion_vector(lc, 0, cand->mv + 0, 0, 1, 0);
693 99274 int available_l1 = IS_B(lc->sc->sh.r) ?
694
2/2
✓ Branch 0 taken 47239 times.
✓ Branch 1 taken 2398 times.
49637 temporal_luma_motion_vector(lc, 0, cand->mv + 1, 1, 1, 0) : 0;
695 49637 cand->pred_flag = available_l0 + (available_l1 << 1);
696 }
697 52605 return cand->pred_flag;
698 }
699
700 //8.5.2.6 Derivation process for history-based merging candidates
701 32571 static int mv_merge_history_candidates(const VVCLocalContext *lc, const int merge_idx,
702 const MvField **nb_list, MvField *cand_list, int *num_cands)
703 {
704 32571 const VVCSPS *sps = lc->fc->ps.sps;
705 32571 const EntryPoint* ep = lc->ep;
706
4/4
✓ Branch 0 taken 85356 times.
✓ Branch 1 taken 1645 times.
✓ Branch 2 taken 76888 times.
✓ Branch 3 taken 8468 times.
87001 for (int i = 1; i <= ep->num_hmvp && (*num_cands < sps->max_num_merge_cand - 1); i++) {
707 76888 const MvField *h = &ep->hmvp[ep->num_hmvp - i];
708
6/6
✓ Branch 0 taken 56469 times.
✓ Branch 1 taken 20419 times.
✓ Branch 3 taken 37939 times.
✓ Branch 4 taken 18530 times.
✓ Branch 6 taken 10054 times.
✓ Branch 7 taken 27885 times.
76888 const int same_motion = i <= 2 && (compare_mv_ref_idx(h, nb_list[A1]) || compare_mv_ref_idx(h, nb_list[B1]));
709
2/2
✓ Branch 0 taken 48304 times.
✓ Branch 1 taken 28584 times.
76888 if (!same_motion) {
710 48304 cand_list[*num_cands] = *h;
711
2/2
✓ Branch 0 taken 22458 times.
✓ Branch 1 taken 25846 times.
48304 if (merge_idx == *num_cands)
712 22458 return 1;
713 25846 (*num_cands)++;
714 }
715 }
716 10113 return 0;
717 }
718
719 //8.5.2.4 Derivation process for pairwise average merging candidate
720 10113 static int mv_merge_pairwise_candidate(MvField *cand_list, const int num_cands, const int is_b)
721 {
722
2/2
✓ Branch 0 taken 9862 times.
✓ Branch 1 taken 251 times.
10113 if (num_cands > 1) {
723
2/2
✓ Branch 0 taken 9418 times.
✓ Branch 1 taken 444 times.
9862 const int num_ref_rists = is_b ? 2 : 1;
724 9862 const MvField* p0 = cand_list + 0;
725 9862 const MvField* p1 = cand_list + 1;
726 9862 MvField* cand = cand_list + num_cands;
727
728 9862 cand->pred_flag = 0;
729
2/2
✓ Branch 0 taken 19280 times.
✓ Branch 1 taken 9862 times.
29142 for (int i = 0; i < num_ref_rists; i++) {
730 19280 PredFlag mask = i + 1;
731
2/2
✓ Branch 0 taken 15983 times.
✓ Branch 1 taken 3297 times.
19280 if (p0->pred_flag & mask) {
732 15983 cand->pred_flag |= mask;
733 15983 cand->ref_idx[i] = p0->ref_idx[i];
734
2/2
✓ Branch 0 taken 14303 times.
✓ Branch 1 taken 1680 times.
15983 if (p1->pred_flag & mask) {
735 14303 Mv *mv = cand->mv + i;
736 14303 mv->x = p0->mv[i].x + p1->mv[i].x;
737 14303 mv->y = p0->mv[i].y + p1->mv[i].y;
738 14303 ff_vvc_round_mv(mv, 0, 1);
739 } else {
740 1680 cand->mv[i] = p0->mv[i];
741 }
742
2/2
✓ Branch 0 taken 1933 times.
✓ Branch 1 taken 1364 times.
3297 } else if (p1->pred_flag & mask) {
743 1933 cand->pred_flag |= mask;
744 1933 cand->mv[i] = p1->mv[i];
745 1933 cand->ref_idx[i] = p1->ref_idx[i];
746 }
747 }
748
1/2
✓ Branch 0 taken 9862 times.
✗ Branch 1 not taken.
9862 if (cand->pred_flag) {
749
2/2
✓ Branch 0 taken 9271 times.
✓ Branch 1 taken 591 times.
9862 cand->hpel_if_idx = p0->hpel_if_idx == p1->hpel_if_idx ? p0->hpel_if_idx : 0;
750 9862 cand->bcw_idx = 0;
751 9862 cand->ciip_flag = 0;
752 9862 return 1;
753 }
754 }
755 251 return 0;
756 }
757
758 //8.5.2.5 Derivation process for zero motion vector merging candidates
759 506 static void mv_merge_zero_motion_candidate(const VVCLocalContext *lc, const int merge_idx,
760 MvField *cand_list, int num_cands)
761 {
762 506 const VVCSPS *sps = lc->fc->ps.sps;
763 506 const H266RawSliceHeader *rsh = lc->sc->sh.r;
764 1012 const int num_ref_idx = IS_P(rsh) ?
765
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 472 times.
506 rsh->num_ref_idx_active[L0] : FFMIN(rsh->num_ref_idx_active[L0], rsh->num_ref_idx_active[L1]);
766 506 int zero_idx = 0;
767
768
1/2
✓ Branch 0 taken 671 times.
✗ Branch 1 not taken.
671 while (num_cands < sps->max_num_merge_cand) {
769 671 MvField *cand = cand_list + num_cands;
770
771
2/2
✓ Branch 0 taken 609 times.
✓ Branch 1 taken 62 times.
671 cand->pred_flag = PF_L0 + (IS_B(rsh) << 1);
772 671 AV_ZERO64(cand->mv + 0);
773 671 AV_ZERO64(cand->mv + 1);
774
2/2
✓ Branch 0 taken 646 times.
✓ Branch 1 taken 25 times.
671 cand->ref_idx[0] = zero_idx < num_ref_idx ? zero_idx : 0;
775
2/2
✓ Branch 0 taken 646 times.
✓ Branch 1 taken 25 times.
671 cand->ref_idx[1] = zero_idx < num_ref_idx ? zero_idx : 0;
776 671 cand->bcw_idx = 0;
777 671 cand->hpel_if_idx = 0;
778
2/2
✓ Branch 0 taken 506 times.
✓ Branch 1 taken 165 times.
671 if (merge_idx == num_cands)
779 506 return;
780 165 num_cands++;
781 165 zero_idx++;
782 }
783 }
784
785 295576 static void mv_merge_mode(const VVCLocalContext *lc, const int merge_idx, MvField *cand_list)
786 {
787 295576 int num_cands = 0;
788 295576 const MvField *nb_list[NUM_NBS + 1] = { NULL };
789
790
2/2
✓ Branch 1 taken 242971 times.
✓ Branch 2 taken 52605 times.
295576 if (mv_merge_spatial_candidates(lc, merge_idx, nb_list, cand_list, &num_cands))
791 295070 return;
792
793
2/2
✓ Branch 1 taken 41214 times.
✓ Branch 2 taken 11391 times.
52605 if (mv_merge_temporal_candidate(lc, &cand_list[num_cands])) {
794
2/2
✓ Branch 0 taken 20034 times.
✓ Branch 1 taken 21180 times.
41214 if (merge_idx == num_cands)
795 20034 return;
796 21180 num_cands++;
797 }
798
799
2/2
✓ Branch 1 taken 22458 times.
✓ Branch 2 taken 10113 times.
32571 if (mv_merge_history_candidates(lc, merge_idx, nb_list, cand_list, &num_cands))
800 22458 return;
801
802
2/2
✓ Branch 1 taken 9862 times.
✓ Branch 2 taken 251 times.
10113 if (mv_merge_pairwise_candidate(cand_list, num_cands, IS_B(lc->sc->sh.r))) {
803
2/2
✓ Branch 0 taken 9607 times.
✓ Branch 1 taken 255 times.
9862 if (merge_idx == num_cands)
804 9607 return;
805 255 num_cands++;
806 }
807
808 506 mv_merge_zero_motion_candidate(lc, merge_idx, cand_list, num_cands);
809 }
810
811 //8.5.2.2 Derivation process for luma motion vectors for merge mode
812 270839 void ff_vvc_luma_mv_merge_mode(VVCLocalContext *lc, const int merge_idx, const int ciip_flag, MvField *mv)
813 {
814 270839 const CodingUnit *cu = lc->cu;
815 MvField cand_list[MRG_MAX_NUM_CANDS];
816
817 270839 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
818 270839 mv_merge_mode(lc, merge_idx, cand_list);
819 270839 *mv = cand_list[merge_idx];
820 //ciip flag in not inhritable
821 270839 mv->ciip_flag = ciip_flag;
822 270839 }
823
824 //8.5.4.2 Derivation process for luma motion vectors for geometric partitioning merge mode
825 24737 void ff_vvc_luma_mv_merge_gpm(VVCLocalContext *lc, const int merge_gpm_idx[2], MvField *mv)
826 {
827 24737 const CodingUnit *cu = lc->cu;
828 MvField cand_list[MRG_MAX_NUM_CANDS];
829
830 24737 const int idx[] = { merge_gpm_idx[0], merge_gpm_idx[1] + (merge_gpm_idx[1] >= merge_gpm_idx[0]) };
831
832 24737 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
833 24737 mv_merge_mode(lc, FFMAX(idx[0], idx[1]), cand_list);
834 24737 memset(mv, 0, 2 * sizeof(*mv));
835
2/2
✓ Branch 0 taken 49474 times.
✓ Branch 1 taken 24737 times.
74211 for (int i = 0; i < 2; i++) {
836 49474 int lx = idx[i] & 1;
837 49474 int mask = lx + PF_L0;
838 49474 MvField *cand = cand_list + idx[i];
839
2/2
✓ Branch 0 taken 13529 times.
✓ Branch 1 taken 35945 times.
49474 if (!(cand->pred_flag & mask)) {
840 13529 lx = !lx;
841 13529 mask = lx + PF_L0;
842 }
843 49474 mv[i].pred_flag = mask;
844 49474 mv[i].ref_idx[lx] = cand->ref_idx[lx];
845 49474 mv[i].mv[lx] = cand->mv[lx];
846 }
847
848 24737 }
849
850 //8.5.5.5 Derivation process for luma affine control point motion vectors from a neighbouring block
851 28583 static void affine_cps_from_nb(const VVCLocalContext *lc,
852 const int x_nb, int y_nb, const int nbw, const int nbh, const int lx,
853 Mv *cps, int num_cps)
854 {
855 28583 const VVCFrameContext *fc = lc->fc;
856 28583 const CodingUnit *cu = lc->cu;
857 28583 const int x0 = cu->x0;
858 28583 const int y0 = cu->y0;
859 28583 const int cb_width = cu->cb_width;
860 28583 const int cb_height = cu->cb_height;
861 28583 const MvField* tab_mvf = fc->tab.mvf;
862 28583 const int min_cb_log2_size = fc->ps.sps->min_cb_log2_size_y;
863 28583 const int min_cb_width = fc->ps.pps->min_cb_width;
864
865 28583 const int log2_nbw = ff_log2(nbw);
866 28583 const int log2_nbh = ff_log2(nbh);
867
4/4
✓ Branch 0 taken 8543 times.
✓ Branch 1 taken 20040 times.
✓ Branch 2 taken 3323 times.
✓ Branch 3 taken 5220 times.
28583 const int is_ctb_boundary = !((y_nb + nbh) % fc->ps.sps->ctb_size_y) && (y_nb + nbh == y0);
868 const Mv *l, *r;
869 int mv_scale_hor, mv_scale_ver, d_hor_x, d_ver_x, d_hor_y, d_ver_y, motion_model_idc_nb;
870
2/2
✓ Branch 0 taken 3323 times.
✓ Branch 1 taken 25260 times.
28583 if (is_ctb_boundary) {
871 3323 const int min_pu_width = fc->ps.pps->min_pu_width;
872 3323 l = &TAB_MVF(x_nb, y_nb + nbh - 1).mv[lx];
873 3323 r = &TAB_MVF(x_nb + nbw - 1, y_nb + nbh - 1).mv[lx];
874 } else {
875 25260 const int x = x_nb >> min_cb_log2_size;
876 25260 const int y = y_nb >> min_cb_log2_size;
877 25260 motion_model_idc_nb = SAMPLE_CTB(fc->tab.mmi, x, y);
878
879 25260 l = &TAB_CP_MV(lx, x_nb, y_nb);
880 25260 r = &TAB_CP_MV(lx, x_nb + nbw - 1, y_nb) + 1;
881 }
882 28583 mv_scale_hor = l->x * (1 << 7);
883 28583 mv_scale_ver = l->y * (1 << 7);
884 28583 d_hor_x = (r->x - l->x) * (1 << (7 - log2_nbw));
885 28583 d_ver_x = (r->y - l->y) * (1 << (7 - log2_nbw));
886
4/4
✓ Branch 0 taken 25260 times.
✓ Branch 1 taken 3323 times.
✓ Branch 2 taken 14648 times.
✓ Branch 3 taken 10612 times.
28583 if (!is_ctb_boundary && motion_model_idc_nb == MOTION_6_PARAMS_AFFINE) {
887 14648 const Mv* lb = &TAB_CP_MV(lx, x_nb, y_nb + nbh - 1) + 2;
888 14648 d_hor_y = (lb->x - l->x) * (1 << (7 - log2_nbh));
889 14648 d_ver_y = (lb->y - l->y) * (1 << (7 - log2_nbh));
890 } else {
891 13935 d_hor_y = -d_ver_x;
892 13935 d_ver_y = d_hor_x;
893 }
894
895
2/2
✓ Branch 0 taken 3323 times.
✓ Branch 1 taken 25260 times.
28583 if (is_ctb_boundary) {
896 3323 y_nb = y0;
897 }
898 28583 cps[0].x = mv_scale_hor + d_hor_x * (x0 - x_nb) + d_hor_y * (y0 - y_nb);
899 28583 cps[0].y = mv_scale_ver + d_ver_x * (x0 - x_nb) + d_ver_y * (y0 - y_nb);
900 28583 cps[1].x = mv_scale_hor + d_hor_x * (x0 + cb_width - x_nb) + d_hor_y * (y0 - y_nb);
901 28583 cps[1].y = mv_scale_ver + d_ver_x * (x0 + cb_width - x_nb) + d_ver_y * (y0 - y_nb);
902
2/2
✓ Branch 0 taken 16190 times.
✓ Branch 1 taken 12393 times.
28583 if (num_cps == 3) {
903 16190 cps[2].x = mv_scale_hor + d_hor_x * (x0 - x_nb) + d_hor_y * (y0 + cb_height - y_nb);
904 16190 cps[2].y = mv_scale_ver + d_ver_x * (x0 - x_nb) + d_ver_y * (y0 + cb_height - y_nb);
905 }
906
2/2
✓ Branch 0 taken 73356 times.
✓ Branch 1 taken 28583 times.
101939 for (int i = 0; i < num_cps; i++) {
907 73356 ff_vvc_round_mv(cps + i, 0, 7);
908 73356 ff_vvc_clip_mv(cps + i);
909 }
910 28583 }
911
912 //derive affine neighbour's postion, width and height,
913 89753 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)
914 {
915 89753 const int log2_min_cb_size = fc->ps.sps->min_cb_log2_size_y;
916 89753 const int min_cb_width = fc->ps.pps->min_cb_width;
917 89753 const int x = x_nb >> log2_min_cb_size;
918 89753 const int y = y_nb >> log2_min_cb_size;
919 89753 const int motion_model_idc = SAMPLE_CTB(fc->tab.mmi, x, y);
920
2/2
✓ Branch 0 taken 25606 times.
✓ Branch 1 taken 64147 times.
89753 if (motion_model_idc) {
921 25606 *x_cb = SAMPLE_CTB(fc->tab.cb_pos_x[0], x, y);
922 25606 *y_cb = SAMPLE_CTB(fc->tab.cb_pos_y[0], x, y);
923 25606 *cbw = SAMPLE_CTB(fc->tab.cb_width[0], x, y);
924 25606 *cbh = SAMPLE_CTB(fc->tab.cb_height[0], x, y);
925 }
926 89753 return motion_model_idc;
927 }
928
929 //part of 8.5.5.2 Derivation process for motion vectors and reference indices in subblock merge mode
930 61797 static int affine_merge_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand, MotionInfo* mi)
931 {
932 61797 const VVCFrameContext *fc = lc->fc;
933 int x, y, w, h, motion_model_idc;
934
935 61797 motion_model_idc = affine_neighbour_cb(fc, x_cand, y_cand, &x, &y, &w, &h);
936
2/2
✓ Branch 0 taken 18558 times.
✓ Branch 1 taken 43239 times.
61797 if (motion_model_idc) {
937 18558 const int min_pu_width = fc->ps.pps->min_pu_width;
938 18558 const MvField* tab_mvf = fc->tab.mvf;
939 18558 const MvField *mvf = &TAB_MVF(x, y);
940
941 18558 mi->bcw_idx = mvf->bcw_idx;
942 18558 mi->pred_flag = mvf->pred_flag;
943
2/2
✓ Branch 0 taken 37116 times.
✓ Branch 1 taken 18558 times.
55674 for (int i = 0; i < 2; i++) {
944 37116 PredFlag mask = i + 1;
945
2/2
✓ Branch 0 taken 22881 times.
✓ Branch 1 taken 14235 times.
37116 if (mi->pred_flag & mask) {
946 22881 affine_cps_from_nb(lc, x, y, w, h, i, &mi->mv[i][0], motion_model_idc + 1);
947 }
948 37116 mi->ref_idx[i] = mvf->ref_idx[i];
949 }
950 18558 mi->motion_model_idc = motion_model_idc;
951 }
952 61797 return motion_model_idc;
953 }
954
955 41627 static int affine_merge_from_nbs(NeighbourContext *ctx, const NeighbourIdx *nbs, const int num_nbs, MotionInfo* cand)
956 {
957 41627 const VVCLocalContext *lc = ctx->lc;
958
2/2
✓ Branch 0 taken 86888 times.
✓ Branch 1 taken 23069 times.
109957 for (int i = 0; i < num_nbs; i++) {
959 86888 Neighbour *n = &ctx->neighbours[nbs[i]];
960
4/4
✓ Branch 1 taken 61797 times.
✓ Branch 2 taken 25091 times.
✓ Branch 4 taken 18558 times.
✓ Branch 5 taken 43239 times.
86888 if (check_available(n, lc, 1) && affine_merge_candidate(lc, n->x, n->y, cand))
961 18558 return 1;
962 }
963 23069 return 0;
964 }
965 #define AFFINE_MERGE_FROM_NBS(nbs) affine_merge_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), mi)
966
967
968 90370 static const MvField* derive_corner_mvf(NeighbourContext *ctx, const NeighbourIdx *neighbour, const int num_neighbour)
969 {
970 90370 const VVCFrameContext *fc = ctx->lc->fc;
971 90370 const MvField *tab_mvf = fc->tab.mvf;
972 90370 const int min_pu_width = fc->ps.pps->min_pu_width;
973
2/2
✓ Branch 0 taken 93370 times.
✓ Branch 1 taken 3777 times.
97147 for (int i = 0; i < num_neighbour; i++) {
974 93370 Neighbour *n = &ctx->neighbours[neighbour[i]];
975
2/2
✓ Branch 1 taken 86593 times.
✓ Branch 2 taken 6777 times.
93370 if (check_available(n, ctx->lc, 1)) {
976 86593 return &TAB_MVF(n->x, n->y);
977 }
978 }
979 3777 return NULL;
980 }
981
982 #define DERIVE_CORNER_MV(nbs) derive_corner_mvf(nctx, nbs, FF_ARRAY_ELEMS(nbs))
983
984 // check if the mv's and refidx are the same between A and B
985 50526 static av_always_inline int compare_pf_ref_idx(const MvField *A, const struct MvField *B, const struct MvField *C, const int lx)
986 {
987
988 50526 const PredFlag mask = (lx + 1) & A->pred_flag;
989
2/2
✓ Branch 0 taken 17963 times.
✓ Branch 1 taken 32563 times.
50526 if (!(B->pred_flag & mask))
990 17963 return 0;
991
2/2
✓ Branch 0 taken 1453 times.
✓ Branch 1 taken 31110 times.
32563 if (A->ref_idx[lx] != B->ref_idx[lx])
992 1453 return 0;
993
2/2
✓ Branch 0 taken 26281 times.
✓ Branch 1 taken 4829 times.
31110 if (C) {
994
2/2
✓ Branch 0 taken 895 times.
✓ Branch 1 taken 25386 times.
26281 if (!(C->pred_flag & mask))
995 895 return 0;
996
2/2
✓ Branch 0 taken 1007 times.
✓ Branch 1 taken 24379 times.
25386 if (A->ref_idx[lx] != C->ref_idx[lx])
997 1007 return 0;
998 }
999 29208 return 1;
1000 }
1001
1002 1254562 static av_always_inline void sb_clip_location(const VVCLocalContext *lc,
1003 const int x_ctb, const int y_ctb, const Mv* temp_mv, int *x, int *y)
1004 {
1005 1254562 const VVCFrameContext *fc = lc->fc;
1006 1254562 const VVCPPS *pps = fc->ps.pps;
1007 1254562 const int ctb_log2_size = fc->ps.sps->ctb_log2_size_y;
1008 1254562 const int subpic_idx = lc->sc->sh.r->curr_subpic_idx;
1009 1254562 const int x_end = pps->subpic_x[subpic_idx] + pps->subpic_width[subpic_idx];
1010 1254562 const int y_end = pps->subpic_y[subpic_idx] + pps->subpic_height[subpic_idx];
1011
1012 1254562 *x = av_clip(*x + temp_mv->x, x_ctb, FFMIN(x_end - 1, x_ctb + (1 << ctb_log2_size) + 3)) & ~7;
1013
2/2
✓ Branch 0 taken 1108050 times.
✓ Branch 1 taken 146512 times.
1254562 *y = av_clip(*y + temp_mv->y, y_ctb, FFMIN(y_end - 1, y_ctb + (1 << ctb_log2_size) - 1)) & ~7;
1014 1254562 }
1015
1016 1254562 static void sb_temproal_luma_motion(const VVCLocalContext *lc,
1017 const int x_ctb, const int y_ctb, const Mv *temp_mv,
1018 int x, int y, uint8_t *pred_flag, Mv *mv)
1019 {
1020 MvField temp_col;
1021 Mv* mvLXCol;
1022 1254562 const int refIdxLx = 0;
1023 1254562 const VVCFrameContext *fc = lc->fc;
1024 1254562 const VVCSH *sh = &lc->sc->sh;
1025 1254562 const int min_pu_width = fc->ps.pps->min_pu_width;
1026 1254562 VVCFrame *ref = fc->ref->collocated_ref;
1027 1254562 MvField *tab_mvf = ref->tab_dmvr_mvf;
1028 1254562 int colPic = ref->poc;
1029 1254562 int X = 0;
1030
1031 1254562 sb_clip_location(lc, x_ctb, y_ctb, temp_mv, &x, &y);
1032
1033 1254562 temp_col = TAB_MVF(x, y);
1034 1254562 mvLXCol = mv + 0;
1035 1254562 *pred_flag = DERIVE_TEMPORAL_COLOCATED_MVS(1);
1036
2/2
✓ Branch 0 taken 910078 times.
✓ Branch 1 taken 344484 times.
1254562 if (IS_B(sh->r)) {
1037 910078 X = 1;
1038 910078 mvLXCol = mv + 1;
1039 910078 *pred_flag |= (DERIVE_TEMPORAL_COLOCATED_MVS(1)) << 1;
1040 }
1041 1254562 }
1042
1043 //8.5.5.4 Derivation process for subblock-based temporal merging base motion data
1044 48634 static int sb_temporal_luma_motion_data(const VVCLocalContext *lc, const MvField *a1,
1045 const int x_ctb, const int y_ctb, MvField *ctr_mvf, Mv *temp_mv)
1046 {
1047 48634 const VVCFrameContext *fc = lc->fc;
1048 48634 const RefPicList *rpl = lc->sc->rpl;
1049 48634 const CodingUnit *cu = lc->cu;
1050 48634 const int x = cu->x0 + cu->cb_width / 2;
1051 48634 const int y = cu->y0 + cu->cb_height / 2;
1052 48634 const VVCFrame *ref = fc->ref->collocated_ref;
1053
1054 int colPic;
1055
1056 48634 memset(temp_mv, 0, sizeof(*temp_mv));
1057
1058
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48634 times.
48634 if (!ref) {
1059 memset(ctr_mvf, 0, sizeof(*ctr_mvf));
1060 return 0;
1061 }
1062
1063 48634 colPic = ref->poc;
1064
1065
2/2
✓ Branch 0 taken 46174 times.
✓ Branch 1 taken 2460 times.
48634 if (a1) {
1066
4/4
✓ Branch 0 taken 42315 times.
✓ Branch 1 taken 3859 times.
✓ Branch 2 taken 29006 times.
✓ Branch 3 taken 13309 times.
46174 if ((a1->pred_flag & PF_L0) && colPic == rpl[L0].refs[a1->ref_idx[L0]].poc)
1067 29006 *temp_mv = a1->mv[0];
1068
4/4
✓ Branch 0 taken 11915 times.
✓ Branch 1 taken 5253 times.
✓ Branch 2 taken 9756 times.
✓ Branch 3 taken 2159 times.
17168 else if ((a1->pred_flag & PF_L1) && colPic == rpl[L1].refs[a1->ref_idx[L1]].poc)
1069 9756 *temp_mv = a1->mv[1];
1070 46174 ff_vvc_round_mv(temp_mv, 0, 4);
1071 }
1072 48634 sb_temproal_luma_motion(lc, x_ctb, y_ctb, temp_mv, x, y, &ctr_mvf->pred_flag , ctr_mvf->mv);
1073
1074 48634 return ctr_mvf->pred_flag;
1075 }
1076
1077
1078 //8.5.5.3 Derivation process for subblock-based temporal merging candidates
1079 48822 static int sb_temporal_merge_candidate(const VVCLocalContext* lc, NeighbourContext *nctx, PredictionUnit *pu)
1080 {
1081 48822 const VVCFrameContext *fc = lc->fc;
1082 48822 const CodingUnit *cu = lc->cu;
1083 48822 const VVCSPS *sps = fc->ps.sps;
1084 48822 const VVCPH *ph = &fc->ps.ph;
1085 48822 MotionInfo *mi = &pu->mi;
1086 48822 const int ctb_log2_size = sps->ctb_log2_size_y;
1087 48822 const int x0 = cu->x0;
1088 48822 const int y0 = cu->y0;
1089 48822 const NeighbourIdx n = A1;
1090 const MvField *a1;
1091 MvField ctr_mvf;
1092 48822 LOCAL_ALIGNED_8(Mv, temp_mv, [1]);
1093 48822 const int x_ctb = (x0 >> ctb_log2_size) << ctb_log2_size;
1094 48822 const int y_ctb = (y0 >> ctb_log2_size) << ctb_log2_size;
1095
1096
1097
2/2
✓ Branch 0 taken 48735 times.
✓ Branch 1 taken 87 times.
48822 if (!ph->r->ph_temporal_mvp_enabled_flag ||
1098
2/2
✓ Branch 0 taken 48634 times.
✓ Branch 1 taken 101 times.
48735 !sps->r->sps_sbtmvp_enabled_flag ||
1099
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 48634 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
48634 (cu->cb_width < 8 && cu->cb_height < 8))
1100 188 return 0;
1101
1102 48634 mi->num_sb_x = cu->cb_width >> 3;
1103 48634 mi->num_sb_y = cu->cb_height >> 3;
1104
1105 48634 a1 = derive_corner_mvf(nctx, &n, 1);
1106
2/2
✓ Branch 1 taken 41506 times.
✓ Branch 2 taken 7128 times.
48634 if (sb_temporal_luma_motion_data(lc, a1, x_ctb, y_ctb, &ctr_mvf, temp_mv)) {
1107 41506 const int sbw = cu->cb_width / mi->num_sb_x;
1108 41506 const int sbh = cu->cb_height / mi->num_sb_y;
1109 41506 MvField mvf = {0};
1110
2/2
✓ Branch 0 taken 171844 times.
✓ Branch 1 taken 41506 times.
213350 for (int sby = 0; sby < mi->num_sb_y; sby++) {
1111
2/2
✓ Branch 0 taken 1205928 times.
✓ Branch 1 taken 171844 times.
1377772 for (int sbx = 0; sbx < mi->num_sb_x; sbx++) {
1112 1205928 int x = x0 + sbx * sbw;
1113 1205928 int y = y0 + sby * sbh;
1114 1205928 sb_temproal_luma_motion(lc, x_ctb, y_ctb, temp_mv, x + sbw / 2, y + sbh / 2, &mvf.pred_flag, mvf.mv);
1115
2/2
✓ Branch 0 taken 6594 times.
✓ Branch 1 taken 1199334 times.
1205928 if (!mvf.pred_flag) {
1116 6594 mvf.pred_flag = ctr_mvf.pred_flag;
1117 6594 memcpy(mvf.mv, ctr_mvf.mv, sizeof(mvf.mv));
1118 }
1119 1205928 ff_vvc_set_mvf(lc, x, y, sbw, sbh, &mvf);
1120 }
1121 }
1122 41506 return 1;
1123 }
1124 7128 return 0;
1125 }
1126
1127 13912 static int affine_merge_const1(const MvField *c0, const MvField *c1, const MvField *c2, MotionInfo *mi)
1128 {
1129
6/6
✓ Branch 0 taken 13847 times.
✓ Branch 1 taken 65 times.
✓ Branch 2 taken 13223 times.
✓ Branch 3 taken 624 times.
✓ Branch 4 taken 12722 times.
✓ Branch 5 taken 501 times.
13912 if (c0 && c1 && c2) {
1130 12722 mi->pred_flag = 0;
1131
2/2
✓ Branch 0 taken 25444 times.
✓ Branch 1 taken 12722 times.
38166 for (int i = 0; i < 2; i++) {
1132 25444 PredFlag mask = i + 1;
1133
2/2
✓ Branch 1 taken 14963 times.
✓ Branch 2 taken 10481 times.
25444 if (compare_pf_ref_idx(c0, c1, c2, i)) {
1134 14963 mi->pred_flag |= mask;
1135 14963 mi->ref_idx[i] = c0->ref_idx[i];
1136 14963 mi->mv[i][0] = c0->mv[i];
1137 14963 mi->mv[i][1] = c1->mv[i];
1138 14963 mi->mv[i][2] = c2->mv[i];
1139 }
1140 }
1141
2/2
✓ Branch 0 taken 11783 times.
✓ Branch 1 taken 939 times.
12722 if (mi->pred_flag) {
1142
2/2
✓ Branch 0 taken 3180 times.
✓ Branch 1 taken 8603 times.
11783 if (mi->pred_flag == PF_BI)
1143 3180 mi->bcw_idx = c0->bcw_idx;
1144 11783 mi->motion_model_idc = MOTION_6_PARAMS_AFFINE;
1145 11783 return 1;
1146 }
1147 }
1148 2129 return 0;
1149 }
1150
1151 7377 static int affine_merge_const2(const MvField *c0, const MvField *c1, const MvField *c3, MotionInfo *mi)
1152 {
1153
6/6
✓ Branch 0 taken 7312 times.
✓ Branch 1 taken 65 times.
✓ Branch 2 taken 6688 times.
✓ Branch 3 taken 624 times.
✓ Branch 4 taken 4528 times.
✓ Branch 5 taken 2160 times.
7377 if (c0 && c1 && c3) {
1154 4528 mi->pred_flag = 0;
1155
2/2
✓ Branch 0 taken 9056 times.
✓ Branch 1 taken 4528 times.
13584 for (int i = 0; i < 2; i++) {
1156 9056 PredFlag mask = i + 1;
1157
2/2
✓ Branch 1 taken 5330 times.
✓ Branch 2 taken 3726 times.
9056 if (compare_pf_ref_idx(c0, c1, c3, i)) {
1158 5330 mi->pred_flag |= mask;
1159 5330 mi->ref_idx[i] = c0->ref_idx[i];
1160 5330 mi->mv[i][0] = c0->mv[i];
1161 5330 mi->mv[i][1] = c1->mv[i];
1162 5330 mi->mv[i][2].x = c3->mv[i].x + c0->mv[i].x - c1->mv[i].x;
1163 5330 mi->mv[i][2].y = c3->mv[i].y + c0->mv[i].y - c1->mv[i].y;
1164 5330 ff_vvc_clip_mv(&mi->mv[i][2]);
1165 }
1166 }
1167
2/2
✓ Branch 0 taken 3961 times.
✓ Branch 1 taken 567 times.
4528 if (mi->pred_flag) {
1168
2/2
✓ Branch 0 taken 1369 times.
✓ Branch 1 taken 2592 times.
3961 mi->bcw_idx = mi->pred_flag == PF_BI ? c0->bcw_idx : 0;
1169 3961 mi->motion_model_idc = MOTION_6_PARAMS_AFFINE;
1170 3961 return 1;
1171 }
1172 }
1173 3416 return 0;
1174 }
1175
1176 5295 static int affine_merge_const3(const MvField *c0, const MvField *c2, const MvField *c3, MotionInfo *mi)
1177 {
1178
6/6
✓ Branch 0 taken 5230 times.
✓ Branch 1 taken 65 times.
✓ Branch 2 taken 4912 times.
✓ Branch 3 taken 318 times.
✓ Branch 4 taken 2768 times.
✓ Branch 5 taken 2144 times.
5295 if (c0 && c2 && c3) {
1179 2768 mi->pred_flag = 0;
1180
2/2
✓ Branch 0 taken 5536 times.
✓ Branch 1 taken 2768 times.
8304 for (int i = 0; i < 2; i++) {
1181 5536 PredFlag mask = i + 1;
1182
2/2
✓ Branch 1 taken 3174 times.
✓ Branch 2 taken 2362 times.
5536 if (compare_pf_ref_idx(c0, c2, c3, i)) {
1183 3174 mi->pred_flag |= mask;
1184 3174 mi->ref_idx[i] = c0->ref_idx[i];
1185 3174 mi->mv[i][0] = c0->mv[i];
1186 3174 mi->mv[i][1].x = c3->mv[i].x + c0->mv[i].x - c2->mv[i].x;
1187 3174 mi->mv[i][1].y = c3->mv[i].y + c0->mv[i].y - c2->mv[i].y;
1188 3174 ff_vvc_clip_mv(&mi->mv[i][1]);
1189 3174 mi->mv[i][2] = c2->mv[i];
1190 }
1191 }
1192
2/2
✓ Branch 0 taken 2348 times.
✓ Branch 1 taken 420 times.
2768 if (mi->pred_flag) {
1193
2/2
✓ Branch 0 taken 826 times.
✓ Branch 1 taken 1522 times.
2348 mi->bcw_idx = mi->pred_flag == PF_BI ? c0->bcw_idx : 0;
1194 2348 mi->motion_model_idc = MOTION_6_PARAMS_AFFINE;
1195 2348 return 1;
1196 }
1197 }
1198 2947 return 0;
1199 }
1200
1201 3707 static int affine_merge_const4(const MvField *c1, const MvField *c2, const MvField *c3, MotionInfo *mi)
1202 {
1203
6/6
✓ Branch 0 taken 3312 times.
✓ Branch 1 taken 395 times.
✓ Branch 2 taken 3000 times.
✓ Branch 3 taken 312 times.
✓ Branch 4 taken 1061 times.
✓ Branch 5 taken 1939 times.
3707 if (c1 && c2 && c3) {
1204 1061 mi->pred_flag = 0;
1205
2/2
✓ Branch 0 taken 2122 times.
✓ Branch 1 taken 1061 times.
3183 for (int i = 0; i < 2; i++) {
1206 2122 PredFlag mask = i + 1;
1207
2/2
✓ Branch 1 taken 912 times.
✓ Branch 2 taken 1210 times.
2122 if (compare_pf_ref_idx(c1, c2, c3, i)) {
1208 912 mi->pred_flag |= mask;
1209 912 mi->ref_idx[i] = c1->ref_idx[i];
1210 912 mi->mv[i][0].x = c1->mv[i].x + c2->mv[i].x - c3->mv[i].x;
1211 912 mi->mv[i][0].y = c1->mv[i].y + c2->mv[i].y - c3->mv[i].y;
1212 912 ff_vvc_clip_mv(&mi->mv[i][0]);
1213 912 mi->mv[i][1] = c1->mv[i];
1214 912 mi->mv[i][2] = c2->mv[i];
1215 }
1216 }
1217
2/2
✓ Branch 0 taken 670 times.
✓ Branch 1 taken 391 times.
1061 if (mi->pred_flag) {
1218
2/2
✓ Branch 0 taken 242 times.
✓ Branch 1 taken 428 times.
670 mi->bcw_idx = mi->pred_flag == PF_BI ? c1->bcw_idx : 0;
1219 670 mi->motion_model_idc = MOTION_6_PARAMS_AFFINE;
1220 670 return 1;
1221 }
1222 }
1223 3037 return 0;
1224 }
1225
1226 3082 static int affine_merge_const5(const MvField *c0, const MvField *c1, MotionInfo *mi)
1227 {
1228
4/4
✓ Branch 0 taken 3017 times.
✓ Branch 1 taken 65 times.
✓ Branch 2 taken 2679 times.
✓ Branch 3 taken 338 times.
3082 if (c0 && c1) {
1229 2679 mi->pred_flag = 0;
1230
2/2
✓ Branch 0 taken 5358 times.
✓ Branch 1 taken 2679 times.
8037 for (int i = 0; i < 2; i++) {
1231 5358 PredFlag mask = i + 1;
1232
2/2
✓ Branch 1 taken 3037 times.
✓ Branch 2 taken 2321 times.
5358 if (compare_pf_ref_idx(c0, c1, NULL, i)) {
1233 3037 mi->pred_flag |= mask;
1234 3037 mi->ref_idx[i] = c0->ref_idx[i];
1235 3037 mi->mv[i][0] = c0->mv[i];
1236 3037 mi->mv[i][1] = c1->mv[i];
1237 }
1238 }
1239
2/2
✓ Branch 0 taken 2406 times.
✓ Branch 1 taken 273 times.
2679 if (mi->pred_flag) {
1240
2/2
✓ Branch 0 taken 631 times.
✓ Branch 1 taken 1775 times.
2406 if (mi->pred_flag == PF_BI)
1241 631 mi->bcw_idx = c0->bcw_idx;
1242 2406 mi->motion_model_idc = MOTION_4_PARAMS_AFFINE;
1243 2406 return 1;
1244 }
1245 }
1246 676 return 0;
1247 }
1248
1249 1651 static int affine_merge_const6(const MvField* c0, const MvField* c2, const int cb_width, const int cb_height, MotionInfo *mi)
1250 {
1251
4/4
✓ Branch 0 taken 1586 times.
✓ Branch 1 taken 65 times.
✓ Branch 2 taken 1505 times.
✓ Branch 3 taken 81 times.
1651 if (c0 && c2) {
1252 1505 const int shift = 7 + av_log2(cb_width) - av_log2(cb_height);
1253 1505 mi->pred_flag = 0;
1254
2/2
✓ Branch 0 taken 3010 times.
✓ Branch 1 taken 1505 times.
4515 for (int i = 0; i < 2; i++) {
1255 3010 PredFlag mask = i + 1;
1256
2/2
✓ Branch 1 taken 1792 times.
✓ Branch 2 taken 1218 times.
3010 if (compare_pf_ref_idx(c0, c2, NULL, i)) {
1257 1792 mi->pred_flag |= mask;
1258 1792 mi->ref_idx[i] = c0->ref_idx[i];
1259 1792 mi->mv[i][0] = c0->mv[i];
1260 1792 mi->mv[i][1].x = (c0->mv[i].x * (1 << 7)) + ((c2->mv[i].y - c0->mv[i].y) * (1 << shift));
1261 1792 mi->mv[i][1].y = (c0->mv[i].y * (1 << 7)) - ((c2->mv[i].x - c0->mv[i].x) * (1 << shift));
1262 1792 ff_vvc_round_mv(&mi->mv[i][1], 0, 7);
1263 1792 ff_vvc_clip_mv(&mi->mv[i][1]);
1264 }
1265 }
1266
2/2
✓ Branch 0 taken 1411 times.
✓ Branch 1 taken 94 times.
1505 if (mi->pred_flag) {
1267
2/2
✓ Branch 0 taken 381 times.
✓ Branch 1 taken 1030 times.
1411 if (mi->pred_flag == PF_BI)
1268 381 mi->bcw_idx = c0->bcw_idx;
1269 1411 mi->motion_model_idc = MOTION_4_PARAMS_AFFINE;
1270 1411 return 1;
1271 }
1272 }
1273 240 return 0;
1274 }
1275
1276 540 static void affine_merge_zero_motion(const VVCLocalContext *lc, MotionInfo *mi)
1277 {
1278 540 const CodingUnit *cu = lc->cu;
1279
1280 540 memset(mi, 0, sizeof(*mi));
1281
2/2
✓ Branch 0 taken 418 times.
✓ Branch 1 taken 122 times.
540 mi->pred_flag = PF_L0 + (IS_B(lc->sc->sh.r) << 1);
1282 540 mi->motion_model_idc = MOTION_4_PARAMS_AFFINE;
1283 540 mi->num_sb_x = cu->cb_width >> MIN_PU_LOG2;
1284 540 mi->num_sb_y = cu->cb_height >> MIN_PU_LOG2;
1285 540 }
1286
1287 //8.5.5.6 Derivation process for constructed affine control point motion vector merging candidates
1288 13912 static int affine_merge_const_candidates(const VVCLocalContext *lc, MotionInfo *mi,
1289 NeighbourContext *nctx, const int merge_subblock_idx, int num_cands)
1290 {
1291 13912 const VVCFrameContext *fc = lc->fc;
1292 13912 const CodingUnit *cu = lc->cu;
1293 13912 const NeighbourIdx tl[] = { B2, B3, A2 };
1294 13912 const NeighbourIdx tr[] = { B1, B0};
1295 13912 const NeighbourIdx bl[] = { A1, A0};
1296 const MvField *c0, *c1, *c2;
1297
1298 13912 c0 = DERIVE_CORNER_MV(tl);
1299 13912 c1 = DERIVE_CORNER_MV(tr);
1300 13912 c2 = DERIVE_CORNER_MV(bl);
1301
1302
1/2
✓ Branch 0 taken 13912 times.
✗ Branch 1 not taken.
13912 if (fc->ps.sps->r->sps_6param_affine_enabled_flag) {
1303 13912 MvField corner3, *c3 = NULL;
1304 //Const1
1305
2/2
✓ Branch 1 taken 11783 times.
✓ Branch 2 taken 2129 times.
13912 if (affine_merge_const1(c0, c1, c2, mi)) {
1306
2/2
✓ Branch 0 taken 6535 times.
✓ Branch 1 taken 5248 times.
11783 if (merge_subblock_idx == num_cands)
1307 10830 return 1;
1308 5248 num_cands++;
1309 }
1310
1311 7377 memset(&corner3, 0, sizeof(corner3));
1312
2/2
✓ Branch 0 taken 7351 times.
✓ Branch 1 taken 26 times.
7377 if (fc->ps.ph.r->ph_temporal_mvp_enabled_flag){
1313 7351 const int available_l0 = temporal_luma_motion_vector(lc, 0, corner3.mv + 0, 0, 0, 0);
1314 14702 const int available_l1 = (lc->sc->sh.r->sh_slice_type == VVC_SLICE_TYPE_B) ?
1315
2/2
✓ Branch 0 taken 5927 times.
✓ Branch 1 taken 1424 times.
7351 temporal_luma_motion_vector(lc, 0, corner3.mv + 1, 1, 0, 0) : 0;
1316
1317 7351 corner3.pred_flag = available_l0 + (available_l1 << 1);
1318
2/2
✓ Branch 0 taken 4962 times.
✓ Branch 1 taken 2389 times.
7351 if (corner3.pred_flag)
1319 4962 c3 = &corner3;
1320 }
1321
1322 //Const2
1323
2/2
✓ Branch 1 taken 3961 times.
✓ Branch 2 taken 3416 times.
7377 if (affine_merge_const2(c0, c1, c3, mi)) {
1324
2/2
✓ Branch 0 taken 2082 times.
✓ Branch 1 taken 1879 times.
3961 if (merge_subblock_idx == num_cands)
1325 2082 return 1;
1326 1879 num_cands++;
1327 }
1328
1329 //Const3
1330
2/2
✓ Branch 1 taken 2348 times.
✓ Branch 2 taken 2947 times.
5295 if (affine_merge_const3(c0, c2, c3, mi)) {
1331
2/2
✓ Branch 0 taken 1588 times.
✓ Branch 1 taken 760 times.
2348 if (merge_subblock_idx == num_cands)
1332 1588 return 1;
1333 760 num_cands++;
1334 }
1335
1336 //Const4
1337
2/2
✓ Branch 1 taken 670 times.
✓ Branch 2 taken 3037 times.
3707 if (affine_merge_const4(c1, c2, c3, mi)) {
1338
2/2
✓ Branch 0 taken 625 times.
✓ Branch 1 taken 45 times.
670 if (merge_subblock_idx == num_cands)
1339 625 return 1;
1340 45 num_cands++;
1341 }
1342 }
1343
1344 //Const5
1345
2/2
✓ Branch 1 taken 2406 times.
✓ Branch 2 taken 676 times.
3082 if (affine_merge_const5(c0, c1, mi)) {
1346
2/2
✓ Branch 0 taken 1431 times.
✓ Branch 1 taken 975 times.
2406 if (merge_subblock_idx == num_cands)
1347 1431 return 1;
1348 975 num_cands++;
1349 }
1350
1351
2/2
✓ Branch 1 taken 1411 times.
✓ Branch 2 taken 240 times.
1651 if (affine_merge_const6(c0, c2, cu->cb_width, cu->cb_height, mi)) {
1352
2/2
✓ Branch 0 taken 1111 times.
✓ Branch 1 taken 300 times.
1411 if (merge_subblock_idx == num_cands)
1353 1111 return 1;
1354 }
1355 540 return 0;
1356 }
1357
1358 //8.5.5.2 Derivation process for motion vectors and reference indices in subblock merge mode
1359 //return 1 if candidate is SbCol
1360 48822 static int sb_mv_merge_mode(const VVCLocalContext *lc, const int merge_subblock_idx, PredictionUnit *pu)
1361 {
1362 48822 const VVCSPS *sps = lc->fc->ps.sps;
1363 48822 const CodingUnit *cu = lc->cu;
1364 48822 MotionInfo *mi = &pu->mi;
1365 48822 int num_cands = 0;
1366 NeighbourContext nctx;
1367
1368 48822 init_neighbour_context(&nctx, lc);
1369
1370 //SbCol
1371
2/2
✓ Branch 1 taken 41506 times.
✓ Branch 2 taken 7316 times.
48822 if (sb_temporal_merge_candidate(lc, &nctx, pu)) {
1372
2/2
✓ Branch 0 taken 25354 times.
✓ Branch 1 taken 16152 times.
41506 if (merge_subblock_idx == num_cands)
1373 25354 return 1;
1374 16152 num_cands++;
1375 }
1376
1377 23468 pu->inter_affine_flag = 1;
1378 23468 mi->num_sb_x = cu->cb_width >> MIN_PU_LOG2;
1379 23468 mi->num_sb_y = cu->cb_height >> MIN_PU_LOG2;
1380
1381
1/2
✓ Branch 0 taken 23468 times.
✗ Branch 1 not taken.
23468 if (sps->r->sps_affine_enabled_flag) {
1382 23468 const NeighbourIdx ak[] = { A0, A1 };
1383 23468 const NeighbourIdx bk[] = { B0, B1, B2 };
1384 //A
1385
2/2
✓ Branch 1 taken 9639 times.
✓ Branch 2 taken 13829 times.
23468 if (AFFINE_MERGE_FROM_NBS(ak)) {
1386
2/2
✓ Branch 0 taken 5309 times.
✓ Branch 1 taken 4330 times.
9639 if (merge_subblock_idx == num_cands)
1387 22928 return 0;
1388 4330 num_cands++;
1389 }
1390
1391 //B
1392
2/2
✓ Branch 1 taken 8919 times.
✓ Branch 2 taken 9240 times.
18159 if (AFFINE_MERGE_FROM_NBS(bk)) {
1393
2/2
✓ Branch 0 taken 4247 times.
✓ Branch 1 taken 4672 times.
8919 if (merge_subblock_idx == num_cands)
1394 4247 return 0;
1395 4672 num_cands++;
1396 }
1397
1398 //Const1 to Const6
1399
2/2
✓ Branch 1 taken 13372 times.
✓ Branch 2 taken 540 times.
13912 if (affine_merge_const_candidates(lc, mi, &nctx, merge_subblock_idx, num_cands))
1400 13372 return 0;
1401 }
1402 //Zero
1403 540 affine_merge_zero_motion(lc, mi);
1404 540 return 0;
1405 }
1406
1407 48822 void ff_vvc_sb_mv_merge_mode(VVCLocalContext *lc, const int merge_subblock_idx, PredictionUnit *pu)
1408 {
1409 48822 const CodingUnit *cu = lc->cu;
1410 48822 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
1411
2/2
✓ Branch 1 taken 23468 times.
✓ Branch 2 taken 25354 times.
48822 if (!sb_mv_merge_mode(lc, merge_subblock_idx, pu)) {
1412 23468 ff_vvc_store_sb_mvs(lc, pu);
1413 }
1414 48822 }
1415
1416 109342 static int mvp_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand,
1417 const int lx, const int8_t *ref_idx, Mv *mv)
1418 {
1419 109342 const VVCFrameContext *fc = lc->fc;
1420 109342 const RefPicList *rpl = lc->sc->rpl;
1421 109342 const int min_pu_width = fc->ps.pps->min_pu_width;
1422 109342 const MvField* tab_mvf = fc->tab.mvf;
1423 109342 const MvField *mvf = &TAB_MVF(x_cand, y_cand);
1424 109342 const PredFlag maskx = lx + 1;
1425 109342 const int poc = rpl[lx].refs[ref_idx[lx]].poc;
1426 109342 int available = 0;
1427
1428
4/4
✓ Branch 0 taken 85338 times.
✓ Branch 1 taken 24004 times.
✓ Branch 2 taken 63716 times.
✓ Branch 3 taken 21622 times.
109342 if ((mvf->pred_flag & maskx) && rpl[lx].refs[mvf->ref_idx[lx]].poc == poc) {
1429 63716 available = 1;
1430 63716 *mv = mvf->mv[lx];
1431 } else {
1432 45626 const int ly = !lx;
1433 45626 const PredFlag masky = ly + 1;
1434
4/4
✓ Branch 0 taken 33793 times.
✓ Branch 1 taken 11833 times.
✓ Branch 2 taken 7454 times.
✓ Branch 3 taken 26339 times.
45626 if ((mvf->pred_flag & masky) && rpl[ly].refs[mvf->ref_idx[ly]].poc == poc) {
1435 7454 available = 1;
1436 7454 *mv = mvf->mv[ly];
1437 }
1438 }
1439
1440 109342 return available;
1441 }
1442
1443 27956 static int affine_mvp_candidate(const VVCLocalContext *lc,
1444 const int x_cand, const int y_cand, const int lx, const int8_t *ref_idx,
1445 Mv *cps, const int num_cp)
1446 {
1447 27956 const VVCFrameContext *fc = lc->fc;
1448 27956 int x_nb, y_nb, nbw, nbh, motion_model_idc, available = 0;
1449
1450 27956 motion_model_idc = affine_neighbour_cb(fc, x_cand, y_cand, &x_nb, &y_nb, &nbw, &nbh);
1451
2/2
✓ Branch 0 taken 7048 times.
✓ Branch 1 taken 20908 times.
27956 if (motion_model_idc) {
1452 7048 const int min_pu_width = fc->ps.pps->min_pu_width;
1453 7048 const MvField* tab_mvf = fc->tab.mvf;
1454 7048 const MvField *mvf = &TAB_MVF(x_nb, y_nb);
1455 7048 RefPicList* rpl = lc->sc->rpl;
1456 7048 const PredFlag maskx = lx + 1;
1457 7048 const int poc = rpl[lx].refs[ref_idx[lx]].poc;
1458
1459
4/4
✓ Branch 0 taken 5968 times.
✓ Branch 1 taken 1080 times.
✓ Branch 2 taken 5017 times.
✓ Branch 3 taken 951 times.
7048 if ((mvf->pred_flag & maskx) && rpl[lx].refs[mvf->ref_idx[lx]].poc == poc) {
1460 5017 available = 1;
1461 5017 affine_cps_from_nb(lc, x_nb, y_nb, nbw, nbh, lx, cps, num_cp);
1462 } else {
1463 2031 const int ly = !lx;
1464 2031 const PredFlag masky = ly + 1;
1465
4/4
✓ Branch 0 taken 1312 times.
✓ Branch 1 taken 719 times.
✓ Branch 2 taken 685 times.
✓ Branch 3 taken 627 times.
2031 if ((mvf->pred_flag & masky) && rpl[ly].refs[mvf->ref_idx[ly]].poc == poc) {
1466 685 available = 1;
1467 685 affine_cps_from_nb(lc, x_nb, y_nb, nbw, nbh, ly, cps, num_cp);
1468 }
1469 }
1470
1471 }
1472 27956 return available;
1473 }
1474
1475 125861 static int mvp_from_nbs(NeighbourContext *ctx,
1476 const NeighbourIdx *nbs, const int num_nbs, const int lx, const int8_t *ref_idx, const int amvr_shift,
1477 Mv *cps, const int num_cps)
1478 {
1479 125861 const VVCLocalContext *lc = ctx->lc;
1480 125861 int available = 0;
1481
1482
2/2
✓ Branch 0 taken 241882 times.
✓ Branch 1 taken 48989 times.
290871 for (int i = 0; i < num_nbs; i++) {
1483 241882 Neighbour *n = &ctx->neighbours[nbs[i]];
1484
2/2
✓ Branch 1 taken 137298 times.
✓ Branch 2 taken 104584 times.
241882 if (check_available(n, lc, 0)) {
1485
2/2
✓ Branch 0 taken 27956 times.
✓ Branch 1 taken 109342 times.
137298 if (num_cps > 1)
1486 27956 available = affine_mvp_candidate(lc, n->x, n->y, lx, ref_idx, cps, num_cps);
1487 else
1488 109342 available = mvp_candidate(lc, n->x, n->y, lx, ref_idx, cps);
1489
2/2
✓ Branch 0 taken 76872 times.
✓ Branch 1 taken 60426 times.
137298 if (available) {
1490
2/2
✓ Branch 0 taken 85489 times.
✓ Branch 1 taken 76872 times.
162361 for (int c = 0; c < num_cps; c++)
1491 85489 ff_vvc_round_mv(cps + c, amvr_shift, amvr_shift);
1492 76872 return 1;
1493 }
1494 }
1495 }
1496 48989 return 0;
1497 }
1498
1499 //get mvp from neighbours
1500 #define AFFINE_MVP_FROM_NBS(nbs) \
1501 mvp_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), lx, ref_idx, amvr_shift, cps, num_cp) \
1502
1503 #define MVP_FROM_NBS(nbs) \
1504 mvp_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), lx, ref_idx, amvr_shift, mv, 1) \
1505
1506 66333 static int mvp_spatial_candidates(const VVCLocalContext *lc,
1507 const int mvp_lx_flag, const int lx, const int8_t* ref_idx, const int amvr_shift,
1508 Mv* mv, int *nb_merge_cand)
1509 {
1510 66333 const NeighbourIdx ak[] = { A0, A1 };
1511 66333 const NeighbourIdx bk[] = { B0, B1, B2 };
1512 NeighbourContext nctx;
1513 66333 int available_a, num_cands = 0;
1514 66333 LOCAL_ALIGNED_8(Mv, mv_a, [1]);
1515
1516 66333 init_neighbour_context(&nctx, lc);
1517
1518 66333 available_a = MVP_FROM_NBS(ak);
1519
2/2
✓ Branch 0 taken 44381 times.
✓ Branch 1 taken 21952 times.
66333 if (available_a) {
1520
2/2
✓ Branch 0 taken 27180 times.
✓ Branch 1 taken 17201 times.
44381 if (mvp_lx_flag == num_cands)
1521 27180 return 1;
1522 17201 num_cands++;
1523 17201 *mv_a = *mv;
1524 }
1525
2/2
✓ Branch 1 taken 26789 times.
✓ Branch 2 taken 12364 times.
39153 if (MVP_FROM_NBS(bk)) {
1526
4/4
✓ Branch 0 taken 15359 times.
✓ Branch 1 taken 11430 times.
✓ Branch 2 taken 13106 times.
✓ Branch 3 taken 2253 times.
26789 if (!available_a || !IS_SAME_MV(mv_a, mv)) {
1527
2/2
✓ Branch 0 taken 21124 times.
✓ Branch 1 taken 3412 times.
24536 if (mvp_lx_flag == num_cands)
1528 21124 return 1;
1529 3412 num_cands++;
1530 }
1531 }
1532 18029 *nb_merge_cand = num_cands;
1533 18029 return 0;
1534 }
1535
1536 18029 static int mvp_temporal_candidates(const VVCLocalContext* lc,
1537 const int mvp_lx_flag, const int lx, const int8_t *ref_idx, const int amvr_shift,
1538 Mv* mv, int *num_cands)
1539 {
1540
2/2
✓ Branch 1 taken 13123 times.
✓ Branch 2 taken 4906 times.
18029 if (temporal_luma_motion_vector(lc, ref_idx[lx], mv, lx, 1, 0)) {
1541
2/2
✓ Branch 0 taken 11318 times.
✓ Branch 1 taken 1805 times.
13123 if (mvp_lx_flag == *num_cands) {
1542 11318 ff_vvc_round_mv(mv, amvr_shift, amvr_shift);
1543 11318 return 1;
1544 }
1545 1805 (*num_cands)++;
1546 }
1547 6711 return 0;
1548
1549 }
1550
1551 6711 static int mvp_history_candidates(const VVCLocalContext *lc,
1552 const int mvp_lx_flag, const int lx, const int8_t ref_idx, const int amvr_shift,
1553 Mv *mv, int num_cands)
1554 {
1555 6711 const EntryPoint* ep = lc->ep;
1556 6711 const RefPicList* rpl = lc->sc->rpl;
1557 6711 const int poc = rpl[lx].refs[ref_idx].poc;
1558
1559
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 6439 times.
6711 if (ep->num_hmvp == 0)
1560 272 return 0;
1561
2/2
✓ Branch 0 taken 13292 times.
✓ Branch 1 taken 1530 times.
14822 for (int i = 1; i <= FFMIN(4, ep->num_hmvp); i++) {
1562 13292 const MvField* h = &ep->hmvp[i - 1];
1563
2/2
✓ Branch 0 taken 22114 times.
✓ Branch 1 taken 8383 times.
30497 for (int j = 0; j < 2; j++) {
1564
2/2
✓ Branch 0 taken 8822 times.
✓ Branch 1 taken 13292 times.
22114 const int ly = (j ? !lx : lx);
1565 22114 PredFlag mask = PF_L0 + ly;
1566
4/4
✓ Branch 0 taken 15485 times.
✓ Branch 1 taken 6629 times.
✓ Branch 2 taken 5644 times.
✓ Branch 3 taken 9841 times.
22114 if ((h->pred_flag & mask) && poc == rpl[ly].refs[h->ref_idx[ly]].poc) {
1567
2/2
✓ Branch 0 taken 4909 times.
✓ Branch 1 taken 735 times.
5644 if (mvp_lx_flag == num_cands) {
1568 4909 *mv = h->mv[ly];
1569 4909 ff_vvc_round_mv(mv, amvr_shift, amvr_shift);
1570 4909 return 1;
1571 }
1572 735 num_cands++;
1573 }
1574 }
1575 }
1576 1530 return 0;
1577 }
1578
1579 //8.5.2.8 Derivation process for luma motion vector prediction
1580 66333 static void mvp(const VVCLocalContext *lc, const int mvp_lx_flag, const int lx,
1581 const int8_t *ref_idx, const int amvr_shift, Mv *mv)
1582 {
1583 int num_cands;
1584
1585
2/2
✓ Branch 1 taken 48304 times.
✓ Branch 2 taken 18029 times.
66333 if (mvp_spatial_candidates(lc, mvp_lx_flag, lx, ref_idx, amvr_shift, mv, &num_cands))
1586 64531 return;
1587
1588
2/2
✓ Branch 1 taken 11318 times.
✓ Branch 2 taken 6711 times.
18029 if (mvp_temporal_candidates(lc, mvp_lx_flag, lx, ref_idx, amvr_shift, mv, &num_cands))
1589 11318 return;
1590
1591
2/2
✓ Branch 1 taken 4909 times.
✓ Branch 2 taken 1802 times.
6711 if (mvp_history_candidates(lc, mvp_lx_flag, lx, ref_idx[lx], amvr_shift, mv, num_cands))
1592 4909 return;
1593
1594 1802 memset(mv, 0, sizeof(*mv));
1595 }
1596
1597 50469 void ff_vvc_mvp(VVCLocalContext *lc, const int *mvp_lx_flag, const int amvr_shift, MotionInfo *mi)
1598 {
1599 50469 const CodingUnit *cu = lc->cu;
1600 50469 mi->num_sb_x = 1;
1601 50469 mi->num_sb_y = 1;
1602
1603 50469 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
1604
2/2
✓ Branch 0 taken 43298 times.
✓ Branch 1 taken 7171 times.
50469 if (mi->pred_flag != PF_L1)
1605 43298 mvp(lc, mvp_lx_flag[L0], L0, mi->ref_idx, amvr_shift, &mi->mv[L0][0]);
1606
2/2
✓ Branch 0 taken 23035 times.
✓ Branch 1 taken 27434 times.
50469 if (mi->pred_flag != PF_L0)
1607 23035 mvp(lc, mvp_lx_flag[L1], L1, mi->ref_idx, amvr_shift, &mi->mv[L1][0]);
1608 50469 }
1609
1610 1582 static int ibc_spatial_candidates(const VVCLocalContext *lc, const int merge_idx, Mv *const cand_list, int *nb_merge_cand)
1611 {
1612 1582 const CodingUnit *cu = lc->cu;
1613 1582 const VVCFrameContext *fc = lc->fc;
1614 1582 const int min_pu_width = fc->ps.pps->min_pu_width;
1615 1582 const MvField *tab_mvf = fc->tab.mvf;
1616 1582 const int is_gt4by4 = (cu->cb_width * cu->cb_height) > 16;
1617 1582 int num_cands = 0;
1618
1619 NeighbourContext nctx;
1620 1582 Neighbour *a1 = &nctx.neighbours[A1];
1621 1582 Neighbour *b1 = &nctx.neighbours[B1];
1622
1623
2/2
✓ Branch 0 taken 202 times.
✓ Branch 1 taken 1380 times.
1582 if (!is_gt4by4) {
1624 202 *nb_merge_cand = 0;
1625 202 return 0;
1626 }
1627
1628 1380 init_neighbour_context(&nctx, lc);
1629
1630
2/2
✓ Branch 1 taken 1070 times.
✓ Branch 2 taken 310 times.
1380 if (check_available(a1, lc, 1)) {
1631 1070 cand_list[num_cands++] = TAB_MVF(a1->x, a1->y).mv[L0];
1632
1/2
✓ Branch 0 taken 1070 times.
✗ Branch 1 not taken.
1070 if (num_cands > merge_idx)
1633 1070 return 1;
1634 }
1635
2/2
✓ Branch 1 taken 179 times.
✓ Branch 2 taken 131 times.
310 if (check_available(b1, lc, 1)) {
1636 179 const MvField *mvf = &TAB_MVF(b1->x, b1->y);
1637
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)) {
1638 179 cand_list[num_cands++] = mvf->mv[L0];
1639
1/2
✓ Branch 0 taken 179 times.
✗ Branch 1 not taken.
179 if (num_cands > merge_idx)
1640 179 return 1;
1641 }
1642 }
1643
1644 131 *nb_merge_cand = num_cands;
1645 131 return 0;
1646 }
1647
1648 333 static int ibc_history_candidates(const VVCLocalContext *lc,
1649 const int merge_idx, Mv *cand_list, int *nb_merge_cand)
1650 {
1651 333 const CodingUnit *cu = lc->cu;
1652 333 const EntryPoint *ep = lc->ep;
1653 333 const int is_gt4by4 = (cu->cb_width * cu->cb_height) > 16;
1654 333 int num_cands = *nb_merge_cand;
1655
1656
2/2
✓ Branch 0 taken 319 times.
✓ Branch 1 taken 14 times.
333 for (int i = 1; i <= ep->num_hmvp_ibc; i++) {
1657 319 int same_motion = 0;
1658 319 const MvField *mvf = &ep->hmvp_ibc[ep->num_hmvp_ibc - i];
1659
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 319 times.
319 for (int j = 0; j < *nb_merge_cand; j++) {
1660 same_motion = is_gt4by4 && i == 1 && IS_SAME_MV(&mvf->mv[L0], &cand_list[j]);
1661 if (same_motion)
1662 break;
1663 }
1664
1/2
✓ Branch 0 taken 319 times.
✗ Branch 1 not taken.
319 if (!same_motion) {
1665 319 cand_list[num_cands++] = mvf->mv[L0];
1666
1/2
✓ Branch 0 taken 319 times.
✗ Branch 1 not taken.
319 if (num_cands > merge_idx)
1667 319 return 1;
1668 }
1669 }
1670
1671 14 *nb_merge_cand = num_cands;
1672 14 return 0;
1673 }
1674
1675 #define MV_BITS 18
1676 #define IBC_SHIFT(v) ((v) >= (1 << (MV_BITS - 1)) ? ((v) - (1 << MV_BITS)) : (v))
1677
1678 1342 static inline void ibc_add_mvp(Mv *mv, Mv *mvp, const int amvr_shift)
1679 {
1680 1342 ff_vvc_round_mv(mv, amvr_shift, 0);
1681 1342 ff_vvc_round_mv(mvp, amvr_shift, amvr_shift);
1682
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1342 times.
1342 mv->x = IBC_SHIFT(mv->x + mvp->x);
1683
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1342 times.
1342 mv->y = IBC_SHIFT(mv->y + mvp->y);
1684 1342 }
1685
1686 1582 static void ibc_merge_candidates(VVCLocalContext *lc, const int merge_idx, Mv *mv)
1687 {
1688 1582 const CodingUnit *cu = lc->cu;
1689 1582 LOCAL_ALIGNED_8(Mv, cand_list, [MRG_MAX_NUM_CANDS]);
1690 int nb_cands;
1691
1692 1582 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
1693
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) ||
1694 333 ibc_history_candidates(lc, merge_idx, cand_list, &nb_cands)) {
1695 1568 *mv = cand_list[merge_idx];
1696 1568 return;
1697 }
1698
1699 //zero mv
1700 14 memset(mv, 0, sizeof(*mv));
1701 }
1702
1703 1582 static int ibc_check_mv(VVCLocalContext *lc, Mv *mv)
1704 {
1705 1582 const VVCFrameContext *fc = lc->fc;
1706 1582 const VVCSPS *sps = lc->fc->ps.sps;
1707 1582 const CodingUnit *cu = lc->cu;
1708 1582 const Mv *bv = &cu->pu.mi.mv[L0][0];
1709
1710
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1582 times.
1582 if (sps->ctb_size_y < ((cu->y0 + (bv->y >> 4)) & (sps->ctb_size_y - 1)) + cu->cb_height) {
1711 av_log(fc->log_ctx, AV_LOG_ERROR, "IBC region spans multiple CTBs.\n");
1712 return AVERROR_INVALIDDATA;
1713 }
1714
1715 1582 return 0;
1716 }
1717
1718 1342 int ff_vvc_mvp_ibc(VVCLocalContext *lc, const int mvp_l0_flag, const int amvr_shift, Mv *mv)
1719 {
1720 1342 LOCAL_ALIGNED_8(Mv, mvp, [1]);
1721
1722 1342 ibc_merge_candidates(lc, mvp_l0_flag, mvp);
1723 1342 ibc_add_mvp(mv, mvp, amvr_shift);
1724 1342 return ibc_check_mv(lc, mv);
1725 }
1726
1727 240 int ff_vvc_luma_mv_merge_ibc(VVCLocalContext *lc, const int merge_idx, Mv *mv)
1728 {
1729 240 ibc_merge_candidates(lc, merge_idx, mv);
1730 240 return ibc_check_mv(lc, mv);
1731 }
1732
1733 21480 static int affine_mvp_constructed_cp(NeighbourContext *ctx,
1734 const NeighbourIdx *neighbour, const int num_neighbour,
1735 const int lx, const int8_t ref_idx, const int amvr_shift, Mv *cp)
1736 {
1737 21480 const VVCLocalContext *lc = ctx->lc;
1738 21480 const VVCFrameContext *fc = lc->fc;
1739 21480 const MvField *tab_mvf = fc->tab.mvf;
1740 21480 const int min_pu_width = fc->ps.pps->min_pu_width;
1741 21480 const RefPicList* rpl = lc->sc->rpl;
1742 21480 int available = 0;
1743
1744
2/2
✓ Branch 0 taken 32183 times.
✓ Branch 1 taken 6278 times.
38461 for (int i = 0; i < num_neighbour; i++) {
1745 32183 Neighbour *n = &ctx->neighbours[neighbour[i]];
1746
2/2
✓ Branch 1 taken 21570 times.
✓ Branch 2 taken 10613 times.
32183 if (check_available(n, ctx->lc, 0)) {
1747 21570 const PredFlag maskx = lx + 1;
1748 21570 const MvField* mvf = &TAB_MVF(n->x, n->y);
1749 21570 const int poc = rpl[lx].refs[ref_idx].poc;
1750
4/4
✓ Branch 0 taken 17764 times.
✓ Branch 1 taken 3806 times.
✓ Branch 2 taken 13594 times.
✓ Branch 3 taken 4170 times.
21570 if ((mvf->pred_flag & maskx) && rpl[lx].refs[mvf->ref_idx[lx]].poc == poc) {
1751 13594 available = 1;
1752 13594 *cp = mvf->mv[lx];
1753 } else {
1754 7976 const int ly = !lx;
1755 7976 const PredFlag masky = ly + 1;
1756
4/4
✓ Branch 0 taken 5472 times.
✓ Branch 1 taken 2504 times.
✓ Branch 2 taken 1608 times.
✓ Branch 3 taken 3864 times.
7976 if ((mvf->pred_flag & masky) && rpl[ly].refs[mvf->ref_idx[ly]].poc == poc) {
1757 1608 available = 1;
1758 1608 *cp = mvf->mv[ly];
1759 }
1760 }
1761
2/2
✓ Branch 0 taken 15202 times.
✓ Branch 1 taken 6368 times.
21570 if (available) {
1762 15202 ff_vvc_round_mv(cp, amvr_shift, amvr_shift);
1763 15202 return 1;
1764 }
1765 }
1766 }
1767 6278 return 0;
1768 }
1769
1770 #define AFFINE_MVP_CONSTRUCTED_CP(cands, cp) \
1771 affine_mvp_constructed_cp(nctx, cands, FF_ARRAY_ELEMS(cands), lx, ref_idx, \
1772 amvr_shift, cp)
1773
1774 //8.5.5.8 Derivation process for constructed affine control point motion vector prediction candidates
1775 7160 static int affine_mvp_const1(NeighbourContext* nctx,
1776 const int lx, const int8_t ref_idx, const int amvr_shift,
1777 Mv *cps, int *available)
1778 {
1779 7160 const NeighbourIdx tl[] = { B2, B3, A2 };
1780 7160 const NeighbourIdx tr[] = { B1, B0 };
1781 7160 const NeighbourIdx bl[] = { A1, A0 };
1782
1783 7160 available[0] = AFFINE_MVP_CONSTRUCTED_CP(tl, cps + 0);
1784 7160 available[1] = AFFINE_MVP_CONSTRUCTED_CP(tr, cps + 1);
1785 7160 available[2] = AFFINE_MVP_CONSTRUCTED_CP(bl, cps + 2);
1786
4/4
✓ Branch 0 taken 5847 times.
✓ Branch 1 taken 1313 times.
✓ Branch 2 taken 4529 times.
✓ Branch 3 taken 1318 times.
7160 return available[0] && available[1];
1787 }
1788
1789 //8.5.5.7 item 7
1790 3315 static void affine_mvp_const2(const int idx, Mv *cps, const int num_cp)
1791 {
1792 3315 const Mv mv = cps[idx];
1793
2/2
✓ Branch 0 taken 8353 times.
✓ Branch 1 taken 3315 times.
11668 for (int j = 0; j < num_cp; j++)
1794 8353 cps[j] = mv;
1795 3315 }
1796
1797 //8.5.5.7 Derivation process for luma affine control point motion vector predictors
1798 11156 static void affine_mvp(const VVCLocalContext *lc,
1799 const int mvp_lx_flag, const int lx, const int8_t *ref_idx, const int amvr_shift,
1800 MotionModelIdc motion_model_idc, Mv *cps)
1801 {
1802 11156 const NeighbourIdx ak[] = { A0, A1 };
1803 11156 const NeighbourIdx bk[] = { B0, B1, B2 };
1804 11156 const int num_cp = motion_model_idc + 1;
1805 NeighbourContext nctx;
1806 int available[MAX_CONTROL_POINTS];
1807 11156 int num_cands = 0;
1808
1809 11156 init_neighbour_context(&nctx, lc);
1810 //Ak
1811
2/2
✓ Branch 1 taken 2883 times.
✓ Branch 2 taken 8273 times.
11156 if (AFFINE_MVP_FROM_NBS(ak)) {
1812
2/2
✓ Branch 0 taken 1937 times.
✓ Branch 1 taken 946 times.
2883 if (mvp_lx_flag == num_cands)
1813 10827 return;
1814 946 num_cands++;
1815 }
1816 //Bk
1817
2/2
✓ Branch 1 taken 2819 times.
✓ Branch 2 taken 6400 times.
9219 if (AFFINE_MVP_FROM_NBS(bk)) {
1818
2/2
✓ Branch 0 taken 2059 times.
✓ Branch 1 taken 760 times.
2819 if (mvp_lx_flag == num_cands)
1819 2059 return;
1820 760 num_cands++;
1821 }
1822
1823 //Const1
1824
2/2
✓ Branch 1 taken 4529 times.
✓ Branch 2 taken 2631 times.
7160 if (affine_mvp_const1(&nctx, lx, ref_idx[lx], amvr_shift, cps, available)) {
1825
4/4
✓ Branch 0 taken 1151 times.
✓ Branch 1 taken 3378 times.
✓ Branch 2 taken 604 times.
✓ Branch 3 taken 547 times.
4529 if (available[2] || motion_model_idc == MOTION_4_PARAMS_AFFINE) {
1826
2/2
✓ Branch 0 taken 2775 times.
✓ Branch 1 taken 1207 times.
3982 if (mvp_lx_flag == num_cands)
1827 2775 return;
1828 1207 num_cands++;
1829 }
1830 }
1831
1832 //Const2
1833
2/2
✓ Branch 0 taken 8317 times.
✓ Branch 1 taken 1070 times.
9387 for (int i = 2; i >= 0; i--) {
1834
2/2
✓ Branch 0 taken 3766 times.
✓ Branch 1 taken 4551 times.
8317 if (available[i]) {
1835
2/2
✓ Branch 0 taken 3315 times.
✓ Branch 1 taken 451 times.
3766 if (mvp_lx_flag == num_cands) {
1836 3315 affine_mvp_const2(i, cps, num_cp);
1837 3315 return;
1838 }
1839 451 num_cands++;
1840 }
1841 }
1842
2/2
✓ Branch 1 taken 848 times.
✓ Branch 2 taken 222 times.
1070 if (temporal_luma_motion_vector(lc, ref_idx[lx], cps, lx, 1, 0)) {
1843
2/2
✓ Branch 0 taken 741 times.
✓ Branch 1 taken 107 times.
848 if (mvp_lx_flag == num_cands) {
1844 741 ff_vvc_round_mv(cps, amvr_shift, amvr_shift);
1845
2/2
✓ Branch 0 taken 1022 times.
✓ Branch 1 taken 741 times.
1763 for (int i = 1; i < num_cp; i++)
1846 1022 cps[i] = cps[0];
1847 741 return;
1848 }
1849 107 num_cands++;
1850 }
1851
1852 //Zero Mv
1853 329 memset(cps, 0, num_cp * sizeof(Mv));
1854 }
1855
1856 9109 void ff_vvc_affine_mvp(VVCLocalContext *lc, const int *mvp_lx_flag, const int amvr_shift, MotionInfo *mi)
1857 {
1858 9109 const CodingUnit *cu = lc->cu;
1859
1860 9109 mi->num_sb_x = cu->cb_width >> MIN_PU_LOG2;
1861 9109 mi->num_sb_y = cu->cb_height >> MIN_PU_LOG2;
1862
1863 9109 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
1864
2/2
✓ Branch 0 taken 8138 times.
✓ Branch 1 taken 971 times.
9109 if (mi->pred_flag != PF_L1)
1865 8138 affine_mvp(lc, mvp_lx_flag[L0], L0, mi->ref_idx, amvr_shift, mi->motion_model_idc, &mi->mv[L0][0]);
1866
2/2
✓ Branch 0 taken 3018 times.
✓ Branch 1 taken 6091 times.
9109 if (mi->pred_flag != PF_L0)
1867 3018 affine_mvp(lc, mvp_lx_flag[L1], L1, mi->ref_idx, amvr_shift, mi->motion_model_idc, &mi->mv[L1][0]);
1868 9109 }
1869
1870 //8.5.2.14 Rounding process for motion vectors
1871 7164488 void ff_vvc_round_mv(Mv *mv, const int lshift, const int rshift)
1872 {
1873
2/2
✓ Branch 0 taken 7161930 times.
✓ Branch 1 taken 2558 times.
7164488 if (rshift) {
1874 7161930 const int offset = 1 << (rshift - 1);
1875 7161930 mv->x = ((mv->x + offset - (mv->x >= 0)) >> rshift) * (1 << lshift);
1876 7161930 mv->y = ((mv->y + offset - (mv->y >= 0)) >> rshift) * (1 << lshift);
1877 } else {
1878 2558 mv->x = mv->x * (1 << lshift);
1879 2558 mv->y = mv->y * (1 << lshift);
1880 }
1881 7164488 }
1882
1883 5021892 void ff_vvc_clip_mv(Mv *mv)
1884 {
1885 5021892 mv->x = av_clip(mv->x, -(1 << 17), (1 << 17) - 1);
1886 5021892 mv->y = av_clip(mv->y, -(1 << 17), (1 << 17) - 1);
1887 5021892 }
1888
1889 //8.5.2.1 Derivation process for motion vector components and reference indices
1890 321308 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)
1891 {
1892 321308 const uint8_t plevel = fc->ps.sps->log2_parallel_merge_level;
1893
1894
1/2
✓ Branch 0 taken 321308 times.
✗ Branch 1 not taken.
642616 return x0_br >> plevel > x0 >> plevel &&
1895
1/2
✓ Branch 0 taken 321308 times.
✗ Branch 1 not taken.
321308 y0_br >> plevel > y0 >> plevel;
1896 }
1897
1898 322688 static void update_hmvp(MvField *hmvp, int *num_hmvp, const MvField *mvf,
1899 int (*compare)(const MvField *n, const MvField *o))
1900 {
1901 int i;
1902
2/2
✓ Branch 0 taken 1369425 times.
✓ Branch 1 taken 174144 times.
1543569 for (i = 0; i < *num_hmvp; i++) {
1903
2/2
✓ Branch 1 taken 148544 times.
✓ Branch 2 taken 1220881 times.
1369425 if (compare(mvf, hmvp + i)) {
1904 148544 (*num_hmvp)--;
1905 148544 break;
1906 }
1907 }
1908
2/2
✓ Branch 0 taken 155579 times.
✓ Branch 1 taken 167109 times.
322688 if (i == MAX_NUM_HMVP_CANDS) {
1909 155579 (*num_hmvp)--;
1910 155579 i = 0;
1911 }
1912
1913 322688 memmove(hmvp + i, hmvp + i + 1, (*num_hmvp - i) * sizeof(MvField));
1914 322688 hmvp[(*num_hmvp)++] = *mvf;
1915 322688 }
1916
1917 6255 static int compare_l0_mv(const MvField *n, const MvField *o)
1918 {
1919 6255 return IS_SAME_MV(&n->mv[L0], &o->mv[L0]);
1920 }
1921
1922 //8.6.2.4 Derivation process for IBC history-based block vector candidates
1923 //8.5.2.16 Updating process for the history-based motion vector predictor candidate list
1924 322890 void ff_vvc_update_hmvp(VVCLocalContext *lc, const MotionInfo *mi)
1925 {
1926 322890 const VVCFrameContext *fc = lc->fc;
1927 322890 const CodingUnit *cu = lc->cu;
1928 322890 const int min_pu_width = fc->ps.pps->min_pu_width;
1929 322890 const MvField *tab_mvf = fc->tab.mvf;
1930 322890 EntryPoint *ep = lc->ep;
1931
1932
2/2
✓ Branch 0 taken 1582 times.
✓ Branch 1 taken 321308 times.
322890 if (cu->pred_mode == MODE_IBC) {
1933
2/2
✓ Branch 0 taken 202 times.
✓ Branch 1 taken 1380 times.
1582 if (cu->cb_width * cu->cb_height <= 16)
1934 202 return;
1935 1380 update_hmvp(ep->hmvp_ibc, &ep->num_hmvp_ibc, &TAB_MVF(cu->x0, cu->y0), compare_l0_mv);
1936 } else {
1937
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 321308 times.
321308 if (!is_greater_mer(fc, cu->x0, cu->y0, cu->x0 + cu->cb_width, cu->y0 + cu->cb_height))
1938 return;
1939 321308 update_hmvp(ep->hmvp, &ep->num_hmvp, &TAB_MVF(cu->x0, cu->y0), compare_mv_ref_idx);
1940 }
1941 }
1942
1943 11748362 MvField* ff_vvc_get_mvf(const VVCFrameContext *fc, const int x0, const int y0)
1944 {
1945 11748362 const int min_pu_width = fc->ps.pps->min_pu_width;
1946 11748362 MvField* tab_mvf = fc->tab.mvf;
1947
1948 11748362 return &TAB_MVF(x0, y0);
1949 }
1950