FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/vvc/mvs.c
Date: 2024-07-16 12:46:59
Exec Total Coverage
Lines: 1188 1199 99.1%
Functions: 80 80 100.0%
Branches: 628 670 93.7%

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 673046 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 673046 const uint8_t plevel = fc->ps.sps->log2_parallel_merge_level;
34
35
2/2
✓ Branch 0 taken 35511 times.
✓ Branch 1 taken 637535 times.
708557 return xN >> plevel == xP >> plevel &&
36
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35511 times.
35511 yN >> plevel == yP >> plevel;
37 }
38
39 //return true if we have same mvs and ref_idxs
40 1974717 static av_always_inline int compare_mv_ref_idx(const MvField *n, const MvField *o)
41 {
42
4/4
✓ Branch 0 taken 1667738 times.
✓ Branch 1 taken 306979 times.
✓ Branch 2 taken 512195 times.
✓ Branch 3 taken 1155543 times.
1974717 if (!o || n->pred_flag != o->pred_flag)
43 819174 return 0;
44
2/2
✓ Branch 0 taken 1450205 times.
✓ Branch 1 taken 246139 times.
1696344 for (int i = 0; i < 2; i++) {
45 1450205 PredFlag mask = i + 1;
46
2/2
✓ Branch 0 taken 1313950 times.
✓ Branch 1 taken 136255 times.
1450205 if (n->pred_flag & mask) {
47 1313950 const int same_ref_idx = n->ref_idx[i] == o->ref_idx[i];
48 1313950 const int same_mv = IS_SAME_MV(n->mv + i, o->mv + i);
49
4/4
✓ Branch 0 taken 1197537 times.
✓ Branch 1 taken 116413 times.
✓ Branch 2 taken 792991 times.
✓ Branch 3 taken 404546 times.
1313950 if (!same_ref_idx || !same_mv)
50 909404 return 0;
51 }
52 }
53 246139 return 1;
54 }
55
56 // 8.5.2.15 Temporal motion buffer compression process for collocated motion vectors
57 1912301 static av_always_inline void mv_compression(Mv *motion)
58 {
59 1912301 int mv[2] = {motion->x, motion->y};
60
2/2
✓ Branch 0 taken 3824602 times.
✓ Branch 1 taken 1912301 times.
5736903 for (int i = 0; i < 2; i++) {
61 3824602 const int s = mv[i] >> 17;
62 3824602 const int f = av_log2((mv[i] ^ s) | 31) - 4;
63 3824602 const int mask = (-1 * (1 << f)) >> 1;
64 3824602 const int round = (1 << f) >> 2;
65 3824602 mv[i] = (mv[i] + round) & mask;
66 }
67 1912301 motion->x = mv[0];
68 1912301 motion->y = mv[1];
69 1912301 }
70
71 1520757 void ff_vvc_mv_scale(Mv *dst, const Mv *src, int td, int tb)
72 {
73 int tx, scale_factor;
74
75 1520757 td = av_clip_int8(td);
76 1520757 tb = av_clip_int8(tb);
77 1520757 tx = (0x4000 + (abs(td) >> 1)) / td;
78 1520757 scale_factor = av_clip_intp2((tb * tx + 32) >> 6, 12);
79 1520757 dst->x = av_clip_intp2((scale_factor * src->x + 127 +
80 1520757 (scale_factor * src->x < 0)) >> 8, 17);
81 1520757 dst->y = av_clip_intp2((scale_factor * src->y + 127 +
82 1520757 (scale_factor * src->y < 0)) >> 8, 17);
83 1520757 }
84
85 //part of 8.5.2.12 Derivation process for collocated motion vectors
86 1912301 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 1912301 int cur_lt = refPicList[X].refs[refIdxLx].is_lt;
92 1912301 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 1912301 times.
1912301 if (cur_lt != col_lt) {
96 mvLXCol->x = 0;
97 mvLXCol->y = 0;
98 return 0;
99 }
100
101 1912301 col_poc_diff = colPic - refPicList_col[listCol].refs[refidxCol].poc;
102 1912301 cur_poc_diff = poc - refPicList[X].refs[refIdxLx].poc;
103
104 1912301 mv_compression(mvCol);
105
3/4
✓ Branch 0 taken 1912301 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 406549 times.
✓ Branch 3 taken 1505752 times.
1912301 if (cur_lt || col_poc_diff == cur_poc_diff) {
106 406549 mvLXCol->x = av_clip_intp2(mvCol->x, 17);
107 406549 mvLXCol->y = av_clip_intp2(mvCol->y, 17);
108 } else {
109 1505752 ff_vvc_mv_scale(mvLXCol, mvCol, col_poc_diff, cur_poc_diff);
110 }
111 1912301 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 448486 int ff_vvc_no_backward_pred_flag(const VVCLocalContext *lc)
122 {
123 448486 int check_diffpicount = 0;
124 int i, j;
125 448486 const RefPicList *rpl = lc->sc->rpl;
126
127
2/2
✓ Branch 0 taken 896972 times.
✓ Branch 1 taken 448486 times.
1345458 for (j = 0; j < 2; j++) {
128
2/2
✓ Branch 0 taken 1391254 times.
✓ Branch 1 taken 406710 times.
1797964 for (i = 0; i < lc->sc->sh.r->num_ref_idx_active[j]; i++) {
129
2/2
✓ Branch 0 taken 490262 times.
✓ Branch 1 taken 900992 times.
1391254 if (rpl[j].refs[i].poc > lc->fc->ps.ph.poc) {
130 490262 check_diffpicount++;
131 490262 break;
132 }
133 }
134 }
135 448486 return !check_diffpicount;
136 }
137
138 //8.5.2.12 Derivation process for collocated motion vectors
139 2309470 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 2309470 const VVCFrameContext *fc = lc->fc;
144 2309470 const SliceContext *sc = lc->sc;
145 2309470 RefPicList* refPicList = sc->rpl;
146
147
2/2
✓ Branch 0 taken 68726 times.
✓ Branch 1 taken 2240744 times.
2309470 if (temp_col.pred_flag == PF_INTRA)
148 68726 return 0;
149
150
2/2
✓ Branch 0 taken 2139046 times.
✓ Branch 1 taken 101698 times.
2240744 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 11710 times.
✓ Branch 1 taken 89988 times.
101698 if (!(temp_col.pred_flag & PF_L0))
164 11710 return CHECK_MVSET(1);
165
2/2
✓ Branch 0 taken 44919 times.
✓ Branch 1 taken 45069 times.
89988 else if (temp_col.pred_flag == PF_L0)
166 44919 return CHECK_MVSET(0);
167
1/2
✓ Branch 0 taken 45069 times.
✗ Branch 1 not taken.
45069 else if (temp_col.pred_flag == PF_BI) {
168
2/2
✓ Branch 1 taken 8672 times.
✓ Branch 2 taken 36397 times.
45069 if (ff_vvc_no_backward_pred_flag(lc)) {
169
2/2
✓ Branch 0 taken 4464 times.
✓ Branch 1 taken 4208 times.
8672 if (X == 0)
170 4464 return CHECK_MVSET(0);
171 else
172 4208 return CHECK_MVSET(1);
173 } else {
174
2/2
✓ Branch 0 taken 21698 times.
✓ Branch 1 taken 14699 times.
36397 if (!lc->sc->sh.r->sh_collocated_from_l0_flag)
175 21698 return CHECK_MVSET(0);
176 else
177 14699 return CHECK_MVSET(1);
178 }
179 }
180 }
181 328443 return 0;
182 }
183
184 #define TAB_MVF(x, y) \
185 tab_mvf[((y) >> MIN_PU_LOG2) * min_pu_width + ((x) >> MIN_PU_LOG2)]
186
187 #define TAB_MVF_PU(v) \
188 TAB_MVF(x ## v, y ## v)
189
190 #define TAB_CP_MV(lx, x, y) \
191 fc->tab.cp_mv[lx][((((y) >> min_cb_log2_size) * min_cb_width + ((x) >> min_cb_log2_size)) ) * MAX_CONTROL_POINTS]
192
193
194 #define DERIVE_TEMPORAL_COLOCATED_MVS(sb_flag) \
195 derive_temporal_colocated_mvs(lc, temp_col, \
196 refIdxLx, mvLXCol, X, colPic, \
197 ff_vvc_get_ref_list(fc, ref, x, y), sb_flag)
198
199 //8.5.2.11 Derivation process for temporal luma motion vector prediction
200 127499 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 127499 const VVCFrameContext *fc = lc->fc;
204 127499 const VVCSPS *sps = fc->ps.sps;
205 127499 const VVCPPS *pps = fc->ps.pps;
206 127499 const CodingUnit *cu = lc->cu;
207 127499 const int subpic_idx = lc->sc->sh.r->curr_subpic_idx;
208 127499 int x, y, x_end, y_end, colPic, availableFlagLXCol = 0;
209 127499 int min_pu_width = fc->ps.pps->min_pu_width;
210 127499 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 127433 times.
127499 if (!ref) {
215 66 memset(mvLXCol, 0, sizeof(*mvLXCol));
216 66 return 0;
217 }
218
219
3/4
✓ Branch 0 taken 127433 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1672 times.
✓ Branch 3 taken 125761 times.
127433 if (!fc->ps.ph.r->ph_temporal_mvp_enabled_flag || (cu->cb_width * cu->cb_height <= 32))
220 1672 return 0;
221
222 125761 tab_mvf = ref->tab_dmvr_mvf;
223 125761 colPic = ref->poc;
224
225 //bottom right collocated motion vector
226 125761 x = cu->x0 + cu->cb_width;
227 125761 y = cu->y0 + cu->cb_height;
228
229 125761 x_end = pps->subpic_x[subpic_idx] + pps->subpic_width[subpic_idx];
230 125761 y_end = pps->subpic_y[subpic_idx] + pps->subpic_height[subpic_idx];
231
232
1/2
✓ Branch 0 taken 125761 times.
✗ Branch 1 not taken.
125761 if (tab_mvf &&
233
4/4
✓ Branch 0 taken 105767 times.
✓ Branch 1 taken 19994 times.
✓ Branch 2 taken 103875 times.
✓ Branch 3 taken 1892 times.
125761 (cu->y0 >> sps->ctb_log2_size_y) == (y >> sps->ctb_log2_size_y) &&
234
2/2
✓ Branch 0 taken 100239 times.
✓ Branch 1 taken 3636 times.
103875 x < x_end && y < y_end) {
235 100239 x &= ~7;
236 100239 y &= ~7;
237 100239 temp_col = TAB_MVF(x, y);
238 100239 availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS(sb_flag);
239 }
240
2/2
✓ Branch 0 taken 112537 times.
✓ Branch 1 taken 13224 times.
125761 if (check_center) {
241 // derive center collocated motion vector
242
3/4
✓ Branch 0 taken 112537 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44591 times.
✓ Branch 3 taken 67946 times.
112537 if (tab_mvf && !availableFlagLXCol) {
243 44591 x = cu->x0 + (cu->cb_width >> 1);
244 44591 y = cu->y0 + (cu->cb_height >> 1);
245 44591 x &= ~7;
246 44591 y &= ~7;
247 44591 temp_col = TAB_MVF(x, y);
248 44591 availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS(sb_flag);
249 }
250 }
251 125761 return availableFlagLXCol;
252 }
253
254 5201248 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 5201248 const VVCFrameContext *fc = lc->fc;
257 5201248 MvField *tab_mvf = fc->tab.mvf;
258 5201248 const int min_pu_width = fc->ps.pps->min_pu_width;
259 5201248 const int min_pu_size = 1 << MIN_PU_LOG2;
260
2/2
✓ Branch 0 taken 8168425 times.
✓ Branch 1 taken 5201248 times.
13369673 for (int dy = 0; dy < h; dy += min_pu_size) {
261
2/2
✓ Branch 0 taken 36651288 times.
✓ Branch 1 taken 8168425 times.
44819713 for (int dx = 0; dx < w; dx += min_pu_size) {
262 36651288 const int x = x0 + dx;
263 36651288 const int y = y0 + dy;
264 36651288 TAB_MVF(x, y) = *mvf;
265 }
266 }
267 5201248 }
268
269 412243 void ff_vvc_set_intra_mvf(const VVCLocalContext *lc, const int dmvr)
270 {
271 412243 const VVCFrameContext *fc = lc->fc;
272 412243 const CodingUnit *cu = lc->cu;
273
2/2
✓ Branch 0 taken 1582 times.
✓ Branch 1 taken 410661 times.
412243 MvField *tab_mvf = dmvr ? fc->ref->tab_dmvr_mvf : fc->tab.mvf;
274 412243 const int min_pu_width = fc->ps.pps->min_pu_width;
275 412243 const int min_pu_size = 1 << MIN_PU_LOG2;
276
2/2
✓ Branch 0 taken 1116681 times.
✓ Branch 1 taken 412243 times.
1528924 for (int dy = 0; dy < cu->cb_height; dy += min_pu_size) {
277
2/2
✓ Branch 0 taken 5014180 times.
✓ Branch 1 taken 1116681 times.
6130861 for (int dx = 0; dx < cu->cb_width; dx += min_pu_size) {
278 5014180 const int x = cu->x0 + dx;
279 5014180 const int y = cu->y0 + dy;
280 5014180 TAB_MVF(x, y).pred_flag = PF_INTRA;
281 }
282 }
283 412243 }
284
285 //cbProfFlagLX from 8.5.5.9 Derivation process for motion vector arrays from affine control point motion vectors
286 41015 static int derive_cb_prof_flag_lx(const VVCLocalContext *lc, const PredictionUnit* pu, int lx, int is_fallback)
287 {
288 41015 const MotionInfo* mi = &pu->mi;
289 41015 const Mv* cp_mv = &mi->mv[lx][0];
290
3/4
✓ Branch 0 taken 41015 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 237 times.
✓ Branch 3 taken 40778 times.
41015 if (lc->fc->ps.ph.r->ph_prof_disabled_flag || is_fallback)
291 237 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 41015 static int is_fallback_mode(const SubblockParams *sp, const PredFlag pred_flag)
319 {
320 41015 const int a = 4 * (2048 + sp->d_hor_x);
321 41015 const int b = 4 * sp->d_hor_y;
322 41015 const int c = 4 * (2048 + sp->d_ver_y);
323 41015 const int d = 4 * sp->d_ver_x;
324
2/2
✓ Branch 0 taken 17092 times.
✓ Branch 1 taken 23923 times.
41015 if (pred_flag == PF_BI) {
325
2/2
✓ Branch 0 taken 17079 times.
✓ Branch 1 taken 13 times.
17092 const int max_w4 = FFMAX(0, FFMAX(a, FFMAX(b, a + b)));
326
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 17079 times.
17092 const int min_w4 = FFMIN(0, FFMIN(a, FFMIN(b, a + b)));
327
2/2
✓ Branch 0 taken 17086 times.
✓ Branch 1 taken 6 times.
17092 const int max_h4 = FFMAX(0, FFMAX(c, FFMAX(d, c + d)));
328
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 17086 times.
17092 const int min_h4 = FFMIN(0, FFMIN(c, FFMIN(d, c + d)));
329 17092 const int bx_wx4 = ((max_w4 - min_w4) >> 11) + 9;
330 17092 const int bx_hx4 = ((max_h4 - min_h4) >> 11) + 9;
331 17092 return bx_wx4 * bx_hx4 > 225;
332 } else {
333 23923 const int bx_wxh = (FFABS(a) >> 11) + 9;
334 23923 const int bx_hxh = (FFABS(d) >> 11) + 9;
335 23923 const int bx_wxv = (FFABS(b) >> 11) + 9;
336 23923 const int bx_hxv = (FFABS(c) >> 11) + 9;
337
4/4
✓ Branch 0 taken 23839 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 23749 times.
✓ Branch 3 taken 90 times.
23923 if (bx_wxh * bx_hxh <= 165 && bx_wxv * bx_hxv <= 165)
338 23749 return 0;
339 }
340 174 return 1;
341 }
342
343 41015 static void init_subblock_params(SubblockParams *sp, const MotionInfo* mi,
344 const int cb_width, const int cb_height, const int lx)
345 {
346 41015 const int log2_cbw = av_log2(cb_width);
347 41015 const int log2_cbh = av_log2(cb_height);
348 41015 const Mv* cp_mv = mi->mv[lx];
349 41015 const int num_cp_mv = mi->motion_model_idc + 1;
350 41015 sp->d_hor_x = (cp_mv[1].x - cp_mv[0].x) * (1 << (MAX_CU_DEPTH - log2_cbw));
351 41015 sp->d_ver_x = (cp_mv[1].y - cp_mv[0].y) * (1 << (MAX_CU_DEPTH - log2_cbw));
352
2/2
✓ Branch 0 taken 25459 times.
✓ Branch 1 taken 15556 times.
41015 if (num_cp_mv == 3) {
353 25459 sp->d_hor_y = (cp_mv[2].x - cp_mv[0].x) * (1 << (MAX_CU_DEPTH - log2_cbh));
354 25459 sp->d_ver_y = (cp_mv[2].y - cp_mv[0].y) * (1 << (MAX_CU_DEPTH - log2_cbh));
355 } else {
356 15556 sp->d_hor_y = -sp->d_ver_x;
357 15556 sp->d_ver_y = sp->d_hor_x;
358 }
359 41015 sp->mv_scale_hor = (cp_mv[0].x) * (1 << MAX_CU_DEPTH);
360 41015 sp->mv_scale_ver = (cp_mv[0].y) * (1 << MAX_CU_DEPTH);
361 41015 sp->cb_width = cb_width;
362 41015 sp->cb_height = cb_height;
363 41015 sp->is_fallback = is_fallback_mode(sp, mi->pred_flag);
364 41015 }
365
366 41015 static void derive_subblock_diff_mvs(const VVCLocalContext *lc, PredictionUnit* pu, const SubblockParams* sp, const int lx)
367 {
368 41015 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 3712 times.
41015 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 41015 }
385
386 41015 static void store_cp_mv(const VVCLocalContext *lc, const MotionInfo *mi, const int lx)
387 {
388 41015 VVCFrameContext *fc = lc->fc;
389 41015 const CodingUnit *cu = lc->cu;
390 41015 const int log2_min_cb_size = fc->ps.sps->min_cb_log2_size_y;
391 41015 const int min_cb_size = fc->ps.sps->min_cb_size_y;
392 41015 const int min_cb_width = fc->ps.pps->min_cb_width;
393 41015 const int num_cp_mv = mi->motion_model_idc + 1;
394
395
2/2
✓ Branch 0 taken 324896 times.
✓ Branch 1 taken 41015 times.
365911 for (int dy = 0; dy < cu->cb_height; dy += min_cb_size) {
396
2/2
✓ Branch 0 taken 4035176 times.
✓ Branch 1 taken 324896 times.
4360072 for (int dx = 0; dx < cu->cb_width; dx += min_cb_size) {
397 4035176 const int x_cb = (cu->x0 + dx) >> log2_min_cb_size;
398 4035176 const int y_cb = (cu->y0 + dy) >> log2_min_cb_size;
399 4035176 const int offset = (y_cb * min_cb_width + x_cb) * MAX_CONTROL_POINTS;
400
401 4035176 memcpy(&fc->tab.cp_mv[lx][offset], mi->mv[lx], sizeof(Mv) * num_cp_mv);
402 4035176 SAMPLE_CTB(fc->tab.mmi, x_cb, y_cb) = mi->motion_model_idc;
403 }
404 }
405 41015 }
406
407 //8.5.5.9 Derivation process for motion vector arrays from affine control point motion vectors
408 32469 void ff_vvc_store_sb_mvs(const VVCLocalContext *lc, PredictionUnit *pu)
409 {
410 32469 const CodingUnit *cu = lc->cu;
411 32469 const MotionInfo *mi = &pu->mi;
412 32469 const int sbw = cu->cb_width / mi->num_sb_x;
413 32469 const int sbh = cu->cb_height / mi->num_sb_y;
414 SubblockParams params[2];
415 32469 MvField mvf = {0};
416
417 32469 mvf.pred_flag = mi->pred_flag;
418 32469 mvf.bcw_idx = mi->bcw_idx;
419 32469 mvf.hpel_if_idx = mi->hpel_if_idx;
420
2/2
✓ Branch 0 taken 64938 times.
✓ Branch 1 taken 32469 times.
97407 for (int i = 0; i < 2; i++) {
421 64938 const PredFlag mask = i + 1;
422
2/2
✓ Branch 0 taken 41015 times.
✓ Branch 1 taken 23923 times.
64938 if (mi->pred_flag & mask) {
423 41015 store_cp_mv(lc, mi, i);
424 41015 init_subblock_params(params + i, mi, cu->cb_width, cu->cb_height, i);
425 41015 derive_subblock_diff_mvs(lc, pu, params + i, i);
426 41015 mvf.ref_idx[i] = mi->ref_idx[i];
427 }
428 }
429
430
2/2
✓ Branch 0 taken 257776 times.
✓ Branch 1 taken 32469 times.
290245 for (int sby = 0; sby < mi->num_sb_y; sby++) {
431
2/2
✓ Branch 0 taken 3167824 times.
✓ Branch 1 taken 257776 times.
3425600 for (int sbx = 0; sbx < mi->num_sb_x; sbx++) {
432 3167824 const int x0 = cu->x0 + sbx * sbw;
433 3167824 const int y0 = cu->y0 + sby * sbh;
434
2/2
✓ Branch 0 taken 6335648 times.
✓ Branch 1 taken 3167824 times.
9503472 for (int i = 0; i < 2; i++) {
435 6335648 const PredFlag mask = i + 1;
436
2/2
✓ Branch 0 taken 4035176 times.
✓ Branch 1 taken 2300472 times.
6335648 if (mi->pred_flag & mask) {
437 4035176 const SubblockParams* sp = params + i;
438
2/2
✓ Branch 0 taken 7652 times.
✓ Branch 1 taken 4027524 times.
4035176 const int x_pos_cb = sp->is_fallback ? (cu->cb_width >> 1) : (2 + (sbx << MIN_CU_LOG2));
439
2/2
✓ Branch 0 taken 7652 times.
✓ Branch 1 taken 4027524 times.
4035176 const int y_pos_cb = sp->is_fallback ? (cu->cb_height >> 1) : (2 + (sby << MIN_CU_LOG2));
440 4035176 Mv *mv = mvf.mv + i;
441
442 4035176 mv->x = sp->mv_scale_hor + sp->d_hor_x * x_pos_cb + sp->d_hor_y * y_pos_cb;
443 4035176 mv->y = sp->mv_scale_ver + sp->d_ver_x * x_pos_cb + sp->d_ver_y * y_pos_cb;
444 4035176 ff_vvc_round_mv(mv, 0, MAX_CU_DEPTH);
445 4035176 ff_vvc_clip_mv(mv);
446 }
447 }
448 3167824 ff_vvc_set_mvf(lc, x0, y0, sbw, sbh, &mvf);
449 }
450 }
451 32469 }
452
453 24737 void ff_vvc_store_gpm_mvf(const VVCLocalContext *lc, const PredictionUnit *pu)
454 {
455 24737 const CodingUnit *cu = lc->cu;
456 24737 const int angle_idx = ff_vvc_gpm_angle_idx[pu->gpm_partition_idx];
457 24737 const int distance_idx = ff_vvc_gpm_distance_idx[pu->gpm_partition_idx];
458 24737 const int displacement_x = ff_vvc_gpm_distance_lut[angle_idx];
459 24737 const int displacement_y = ff_vvc_gpm_distance_lut[(angle_idx + 8) % 32];
460
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;
461
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;
462
2/2
✓ Branch 0 taken 14571 times.
✓ Branch 1 taken 10166 times.
24737 const int sign = angle_idx < 16 ? 1 : -1;
463 24737 const int block_size = 4;
464 24737 int offset_x = (-cu->cb_width) >> 1;
465 24737 int offset_y = (-cu->cb_height) >> 1;
466
467
2/2
✓ Branch 0 taken 17110 times.
✓ Branch 1 taken 7627 times.
24737 if (!shift_hor)
468 17110 offset_y += sign * ((distance_idx * cu->cb_height) >> 3);
469 else
470 7627 offset_x += sign * ((distance_idx * cu->cb_width) >> 3);
471
472
2/2
✓ Branch 0 taken 111242 times.
✓ Branch 1 taken 24737 times.
135979 for (int y = 0; y < cu->cb_height; y += block_size) {
473
2/2
✓ Branch 0 taken 511556 times.
✓ Branch 1 taken 111242 times.
622798 for (int x = 0; x < cu->cb_width; x += block_size) {
474 511556 const int motion_idx = (((x + offset_x) * (1 << 1)) + 5) * displacement_x +
475 511556 (((y + offset_y) * (1 << 1)) + 5) * displacement_y;
476
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);
477 511556 const int pred_flag = pu->gpm_mv[0].pred_flag | pu->gpm_mv[1].pred_flag;
478 511556 const int x0 = cu->x0 + x;
479 511556 const int y0 = cu->y0 + y;
480
481
2/2
✓ Branch 0 taken 199134 times.
✓ Branch 1 taken 312422 times.
511556 if (!s_type)
482 199134 ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, pu->gpm_mv + 0);
483
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))
484 265337 ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, pu->gpm_mv + 1);
485 else {
486 47085 MvField mvf = pu->gpm_mv[0];
487 47085 const MvField *mv1 = &pu->gpm_mv[1];
488 47085 const int lx = mv1->pred_flag - PF_L0;
489 47085 mvf.pred_flag = PF_BI;
490 47085 mvf.ref_idx[lx] = mv1->ref_idx[lx];
491 47085 mvf.mv[lx] = mv1->mv[lx];
492 47085 ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, &mvf);
493 }
494 }
495 }
496 24737 }
497
498 265675 void ff_vvc_store_mvf(const VVCLocalContext *lc, const MvField *mvf)
499 {
500 265675 const CodingUnit *cu = lc->cu;
501 265675 ff_vvc_set_mvf(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height, mvf);
502 265675 }
503
504 50265 void ff_vvc_store_mv(const VVCLocalContext *lc, const MotionInfo *mi)
505 {
506 50265 const CodingUnit *cu = lc->cu;
507 50265 MvField mvf = {0};
508
509 50265 mvf.hpel_if_idx = mi->hpel_if_idx;
510 50265 mvf.bcw_idx = mi->bcw_idx;
511 50265 mvf.pred_flag = mi->pred_flag;
512
513
2/2
✓ Branch 0 taken 100530 times.
✓ Branch 1 taken 50265 times.
150795 for (int i = 0; i < 2; i++) {
514 100530 const PredFlag mask = i + 1;
515
2/2
✓ Branch 0 taken 65293 times.
✓ Branch 1 taken 35237 times.
100530 if (mvf.pred_flag & mask) {
516 65293 mvf.mv[i] = mi->mv[i][0];
517 65293 mvf.ref_idx[i] = mi->ref_idx[i];
518 }
519 }
520 50265 ff_vvc_set_mvf(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height, &mvf);
521 50265 }
522
523 typedef enum NeighbourIdx {
524 A0,
525 A1,
526 A2,
527 B0,
528 B1,
529 B2,
530 B3,
531 NUM_NBS,
532 NB_IDX_NONE = NUM_NBS,
533 } NeighbourIdx;
534
535 typedef struct Neighbour {
536 int x;
537 int y;
538
539 int checked;
540 int available;
541 } Neighbour;
542
543 typedef struct NeighbourContext {
544 Neighbour neighbours[NUM_NBS];
545 const VVCLocalContext *lc;
546 } NeighbourContext;
547
548 415373 static int is_a0_available(const VVCLocalContext *lc, const CodingUnit *cu)
549 {
550 415373 const VVCFrameContext *fc = lc->fc;
551 415373 const VVCSPS *sps = fc->ps.sps;
552 415373 const int x0b = av_zero_extend(cu->x0, sps->ctb_log2_size_y);
553 int cand_bottom_left;
554
555
4/4
✓ Branch 0 taken 93145 times.
✓ Branch 1 taken 322228 times.
✓ Branch 2 taken 12165 times.
✓ Branch 3 taken 80980 times.
415373 if (!x0b && !lc->ctb_left_flag) {
556 12165 cand_bottom_left = 0;
557 } else {
558 403208 const int log2_min_cb_size = sps->min_cb_log2_size_y;
559 403208 const int min_cb_width = fc->ps.pps->min_cb_width;
560 403208 const int x = (cu->x0 - 1) >> log2_min_cb_size;
561 403208 const int y = (cu->y0 + cu->cb_height) >> log2_min_cb_size;
562 403208 const int max_y = FFMIN(fc->ps.pps->height, ((cu->y0 >> sps->ctb_log2_size_y) + 1) << sps->ctb_log2_size_y);
563
2/2
✓ Branch 0 taken 87544 times.
✓ Branch 1 taken 315664 times.
403208 if (cu->y0 + cu->cb_height >= max_y)
564 87544 cand_bottom_left = 0;
565 else
566 315664 cand_bottom_left = SAMPLE_CTB(fc->tab.cb_width[0], x, y) != 0;
567 }
568 415373 return cand_bottom_left;
569 }
570
571 415373 static void init_neighbour_context(NeighbourContext *ctx, const VVCLocalContext *lc)
572 {
573 415373 const CodingUnit *cu = lc->cu;
574 415373 const NeighbourAvailable *na = &lc->na;
575 415373 const int x0 = cu->x0;
576 415373 const int y0 = cu->y0;
577 415373 const int cb_width = cu->cb_width;
578 415373 const int cb_height = cu->cb_height;
579 415373 const int a0_available = is_a0_available(lc, cu);
580
581 415373 Neighbour neighbours[NUM_NBS] = {
582 415373 { x0 - 1, y0 + cb_height, !a0_available }, //A0
583 415373 { x0 - 1, y0 + cb_height - 1, !na->cand_left }, //A1
584 415373 { x0 - 1, y0, !na->cand_left }, //A2
585 415373 { x0 + cb_width, y0 - 1, !na->cand_up_right }, //B0
586 415373 { x0 + cb_width - 1, y0 - 1, !na->cand_up }, //B1
587 415373 { x0 - 1, y0 - 1, !na->cand_up_left }, //B2
588 415373 { x0, y0 - 1, !na->cand_up }, //B3
589 };
590
591 415373 memcpy(ctx->neighbours, neighbours, sizeof(neighbours));
592 415373 ctx->lc = lc;
593 415373 }
594
595 843943 static av_always_inline PredMode pred_flag_to_mode(PredFlag pred)
596 {
597
2/2
✓ Branch 0 taken 842627 times.
✓ Branch 1 taken 1316 times.
843943 return pred == PF_IBC ? MODE_IBC : (pred == PF_INTRA ? MODE_INTRA : MODE_INTER);
598 }
599
600 1091731 static int check_available(Neighbour *n, const VVCLocalContext *lc, const int check_mer)
601 {
602 1091731 const VVCFrameContext *fc = lc->fc;
603 1091731 const VVCSPS *sps = fc->ps.sps;
604 1091731 const CodingUnit *cu = lc->cu;
605 1091731 const MvField *tab_mvf = fc->tab.mvf;
606 1091731 const int min_pu_width = fc->ps.pps->min_pu_width;
607
608
2/2
✓ Branch 0 taken 843943 times.
✓ Branch 1 taken 247788 times.
1091731 if (!n->checked) {
609 843943 n->checked = 1;
610
4/4
✓ Branch 0 taken 87906 times.
✓ Branch 1 taken 756037 times.
✓ Branch 2 taken 87706 times.
✓ Branch 3 taken 200 times.
843943 n->available = !sps->r->sps_entropy_coding_sync_enabled_flag || ((n->x >> sps->ctb_log2_size_y) <= (cu->x0 >> sps->ctb_log2_size_y));
611 843943 n->available &= cu->pred_mode == pred_flag_to_mode(TAB_MVF(n->x, n->y).pred_flag);
612
2/2
✓ Branch 0 taken 673046 times.
✓ Branch 1 taken 170897 times.
843943 if (check_mer)
613 673046 n->available &= !is_same_mer(fc, n->x, n->y, cu->x0, cu->y0);
614 }
615 1091731 return n->available;
616 }
617
618 515551 static const MvField *mv_merge_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand)
619 {
620 515551 const VVCFrameContext *fc = lc->fc;
621 515551 const int min_pu_width = fc->ps.pps->min_pu_width;
622 515551 const MvField* tab_mvf = fc->tab.mvf;
623 515551 const MvField *mvf = &TAB_MVF(x_cand, y_cand);
624
625 515551 return mvf;
626 }
627
628 643523 static const MvField* mv_merge_from_nb(NeighbourContext *ctx, const NeighbourIdx nb)
629 {
630 643523 const VVCLocalContext *lc = ctx->lc;
631 643523 Neighbour *n = &ctx->neighbours[nb];
632
633
2/2
✓ Branch 1 taken 515551 times.
✓ Branch 2 taken 127972 times.
643523 if (check_available(n, lc, 1))
634 515551 return mv_merge_candidate(lc, n->x, n->y);
635 127972 return 0;
636 }
637 #define MV_MERGE_FROM_NB(nb) mv_merge_from_nb(&nctx, nb)
638
639 //8.5.2.3 Derivation process for spatial merging candidates
640 290412 static int mv_merge_spatial_candidates(const VVCLocalContext *lc, const int merge_idx,
641 const MvField **nb_list, MvField *cand_list, int *nb_merge_cand)
642 {
643 const MvField *cand;
644 290412 int num_cands = 0;
645 NeighbourContext nctx;
646
647 static NeighbourIdx nbs[][2] = {
648 {B1, NB_IDX_NONE },
649 {A1, B1 },
650 {B0, B1 },
651 {A0, A1 },
652 };
653
654 290412 init_neighbour_context(&nctx, lc);
655
2/2
✓ Branch 0 taken 582661 times.
✓ Branch 1 taken 61505 times.
644166 for (int i = 0; i < FF_ARRAY_ELEMS(nbs); i++) {
656 582661 NeighbourIdx nb = nbs[i][0];
657 582661 NeighbourIdx old = nbs[i][1];
658 582661 cand = nb_list[nb] = MV_MERGE_FROM_NB(nb);
659
4/4
✓ Branch 0 taken 465934 times.
✓ Branch 1 taken 116727 times.
✓ Branch 3 taken 420454 times.
✓ Branch 4 taken 45480 times.
582661 if (cand && !compare_mv_ref_idx(cand, nb_list[old])) {
660 420454 cand_list[num_cands] = *cand;
661
2/2
✓ Branch 0 taken 228907 times.
✓ Branch 1 taken 191547 times.
420454 if (merge_idx == num_cands)
662 228907 return 1;
663 191547 num_cands++;
664 }
665 }
666
2/2
✓ Branch 0 taken 60862 times.
✓ Branch 1 taken 643 times.
61505 if (num_cands != 4) {
667 60862 cand = MV_MERGE_FROM_NB(B2);
668
4/4
✓ Branch 0 taken 49617 times.
✓ Branch 1 taken 11245 times.
✓ Branch 3 taken 29928 times.
✓ Branch 4 taken 19689 times.
60862 if (cand && !compare_mv_ref_idx(cand, nb_list[A1])
669
2/2
✓ Branch 1 taken 21230 times.
✓ Branch 2 taken 8698 times.
29928 && !compare_mv_ref_idx(cand, nb_list[B1])) {
670 21230 cand_list[num_cands] = *cand;
671
2/2
✓ Branch 0 taken 9565 times.
✓ Branch 1 taken 11665 times.
21230 if (merge_idx == num_cands)
672 9565 return 1;
673 11665 num_cands++;
674 }
675 }
676 51940 *nb_merge_cand = num_cands;
677 51940 return 0;
678 }
679
680 51940 static int mv_merge_temporal_candidate(const VVCLocalContext *lc, MvField *cand)
681 {
682 51940 const VVCFrameContext *fc = lc->fc;
683 51940 const CodingUnit *cu = lc->cu;
684
685 51940 memset(cand, 0, sizeof(*cand));
686
4/4
✓ Branch 0 taken 51793 times.
✓ Branch 1 taken 147 times.
✓ Branch 2 taken 48972 times.
✓ Branch 3 taken 2821 times.
51940 if (fc->ps.ph.r->ph_temporal_mvp_enabled_flag && (cu->cb_width * cu->cb_height > 32)) {
687 48972 int available_l0 = temporal_luma_motion_vector(lc, 0, cand->mv + 0, 0, 1, 0);
688 97944 int available_l1 = IS_B(lc->sc->sh.r) ?
689
2/2
✓ Branch 0 taken 46574 times.
✓ Branch 1 taken 2398 times.
48972 temporal_luma_motion_vector(lc, 0, cand->mv + 1, 1, 1, 0) : 0;
690 48972 cand->pred_flag = available_l0 + (available_l1 << 1);
691 }
692 51940 return cand->pred_flag;
693 }
694
695 //8.5.2.6 Derivation process for history-based merging candidates
696 32164 static int mv_merge_history_candidates(const VVCLocalContext *lc, const int merge_idx,
697 const MvField **nb_list, MvField *cand_list, int *num_cands)
698 {
699 32164 const VVCSPS *sps = lc->fc->ps.sps;
700 32164 const EntryPoint* ep = lc->ep;
701
4/4
✓ Branch 0 taken 84273 times.
✓ Branch 1 taken 1605 times.
✓ Branch 2 taken 76001 times.
✓ Branch 3 taken 8272 times.
85878 for (int i = 1; i <= ep->num_hmvp && (*num_cands < sps->max_num_merge_cand - 1); i++) {
702 76001 const MvField *h = &ep->hmvp[ep->num_hmvp - i];
703
6/6
✓ Branch 0 taken 55830 times.
✓ Branch 1 taken 20171 times.
✓ Branch 3 taken 37540 times.
✓ Branch 4 taken 18290 times.
✓ Branch 6 taken 9954 times.
✓ Branch 7 taken 27586 times.
76001 const int same_motion = i <= 2 && (compare_mv_ref_idx(h, nb_list[A1]) || compare_mv_ref_idx(h, nb_list[B1]));
704
2/2
✓ Branch 0 taken 47757 times.
✓ Branch 1 taken 28244 times.
76001 if (!same_motion) {
705 47757 cand_list[*num_cands] = *h;
706
2/2
✓ Branch 0 taken 22287 times.
✓ Branch 1 taken 25470 times.
47757 if (merge_idx == *num_cands)
707 22287 return 1;
708 25470 (*num_cands)++;
709 }
710 }
711 9877 return 0;
712 }
713
714 //8.5.2.4 Derivation process for pairwise average merging candidate
715 9877 static int mv_merge_pairwise_candidate(MvField *cand_list, const int num_cands, const int is_b)
716 {
717
2/2
✓ Branch 0 taken 9629 times.
✓ Branch 1 taken 248 times.
9877 if (num_cands > 1) {
718
2/2
✓ Branch 0 taken 9185 times.
✓ Branch 1 taken 444 times.
9629 const int num_ref_rists = is_b ? 2 : 1;
719 9629 const MvField* p0 = cand_list + 0;
720 9629 const MvField* p1 = cand_list + 1;
721 9629 MvField* cand = cand_list + num_cands;
722
723 9629 cand->pred_flag = 0;
724
2/2
✓ Branch 0 taken 18814 times.
✓ Branch 1 taken 9629 times.
28443 for (int i = 0; i < num_ref_rists; i++) {
725 18814 PredFlag mask = i + 1;
726
2/2
✓ Branch 0 taken 15567 times.
✓ Branch 1 taken 3247 times.
18814 if (p0->pred_flag & mask) {
727 15567 cand->pred_flag |= mask;
728 15567 cand->ref_idx[i] = p0->ref_idx[i];
729
2/2
✓ Branch 0 taken 13928 times.
✓ Branch 1 taken 1639 times.
15567 if (p1->pred_flag & mask) {
730 13928 Mv *mv = cand->mv + i;
731 13928 mv->x = p0->mv[i].x + p1->mv[i].x;
732 13928 mv->y = p0->mv[i].y + p1->mv[i].y;
733 13928 ff_vvc_round_mv(mv, 0, 1);
734 } else {
735 1639 cand->mv[i] = p0->mv[i];
736 }
737
2/2
✓ Branch 0 taken 1901 times.
✓ Branch 1 taken 1346 times.
3247 } else if (p1->pred_flag & mask) {
738 1901 cand->pred_flag |= mask;
739 1901 cand->mv[i] = p1->mv[i];
740 1901 cand->ref_idx[i] = p1->ref_idx[i];
741 }
742 }
743
1/2
✓ Branch 0 taken 9629 times.
✗ Branch 1 not taken.
9629 if (cand->pred_flag) {
744
2/2
✓ Branch 0 taken 9038 times.
✓ Branch 1 taken 591 times.
9629 cand->hpel_if_idx = p0->hpel_if_idx == p1->hpel_if_idx ? p0->hpel_if_idx : 0;
745 9629 cand->bcw_idx = 0;
746 9629 cand->ciip_flag = 0;
747 9629 return 1;
748 }
749 }
750 248 return 0;
751 }
752
753 //8.5.2.5 Derivation process for zero motion vector merging candidates
754 496 static void mv_merge_zero_motion_candidate(const VVCLocalContext *lc, const int merge_idx,
755 MvField *cand_list, int num_cands)
756 {
757 496 const VVCSPS *sps = lc->fc->ps.sps;
758 496 const H266RawSliceHeader *rsh = lc->sc->sh.r;
759 992 const int num_ref_idx = IS_P(rsh) ?
760
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 462 times.
496 rsh->num_ref_idx_active[L0] : FFMIN(rsh->num_ref_idx_active[L0], rsh->num_ref_idx_active[L1]);
761 496 int zero_idx = 0;
762
763
1/2
✓ Branch 0 taken 654 times.
✗ Branch 1 not taken.
654 while (num_cands < sps->max_num_merge_cand) {
764 654 MvField *cand = cand_list + num_cands;
765
766
2/2
✓ Branch 0 taken 592 times.
✓ Branch 1 taken 62 times.
654 cand->pred_flag = PF_L0 + (IS_B(rsh) << 1);
767 654 AV_ZERO64(cand->mv + 0);
768 654 AV_ZERO64(cand->mv + 1);
769
2/2
✓ Branch 0 taken 629 times.
✓ Branch 1 taken 25 times.
654 cand->ref_idx[0] = zero_idx < num_ref_idx ? zero_idx : 0;
770
2/2
✓ Branch 0 taken 629 times.
✓ Branch 1 taken 25 times.
654 cand->ref_idx[1] = zero_idx < num_ref_idx ? zero_idx : 0;
771 654 cand->bcw_idx = 0;
772 654 cand->hpel_if_idx = 0;
773
2/2
✓ Branch 0 taken 496 times.
✓ Branch 1 taken 158 times.
654 if (merge_idx == num_cands)
774 496 return;
775 158 num_cands++;
776 158 zero_idx++;
777 }
778 }
779
780 290412 static void mv_merge_mode(const VVCLocalContext *lc, const int merge_idx, MvField *cand_list)
781 {
782 290412 int num_cands = 0;
783 290412 const MvField *nb_list[NUM_NBS + 1] = { NULL };
784
785
2/2
✓ Branch 1 taken 238472 times.
✓ Branch 2 taken 51940 times.
290412 if (mv_merge_spatial_candidates(lc, merge_idx, nb_list, cand_list, &num_cands))
786 289916 return;
787
788
2/2
✓ Branch 1 taken 40673 times.
✓ Branch 2 taken 11267 times.
51940 if (mv_merge_temporal_candidate(lc, &cand_list[num_cands])) {
789
2/2
✓ Branch 0 taken 19776 times.
✓ Branch 1 taken 20897 times.
40673 if (merge_idx == num_cands)
790 19776 return;
791 20897 num_cands++;
792 }
793
794
2/2
✓ Branch 1 taken 22287 times.
✓ Branch 2 taken 9877 times.
32164 if (mv_merge_history_candidates(lc, merge_idx, nb_list, cand_list, &num_cands))
795 22287 return;
796
797
2/2
✓ Branch 1 taken 9629 times.
✓ Branch 2 taken 248 times.
9877 if (mv_merge_pairwise_candidate(cand_list, num_cands, IS_B(lc->sc->sh.r))) {
798
2/2
✓ Branch 0 taken 9381 times.
✓ Branch 1 taken 248 times.
9629 if (merge_idx == num_cands)
799 9381 return;
800 248 num_cands++;
801 }
802
803 496 mv_merge_zero_motion_candidate(lc, merge_idx, cand_list, num_cands);
804 }
805
806 //8.5.2.2 Derivation process for luma motion vectors for merge mode
807 265675 void ff_vvc_luma_mv_merge_mode(VVCLocalContext *lc, const int merge_idx, const int ciip_flag, MvField *mv)
808 {
809 265675 const CodingUnit *cu = lc->cu;
810 MvField cand_list[MRG_MAX_NUM_CANDS];
811
812 265675 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
813 265675 mv_merge_mode(lc, merge_idx, cand_list);
814 265675 *mv = cand_list[merge_idx];
815 //ciip flag in not inhritable
816 265675 mv->ciip_flag = ciip_flag;
817 265675 }
818
819 //8.5.4.2 Derivation process for luma motion vectors for geometric partitioning merge mode
820 24737 void ff_vvc_luma_mv_merge_gpm(VVCLocalContext *lc, const int merge_gpm_idx[2], MvField *mv)
821 {
822 24737 const CodingUnit *cu = lc->cu;
823 MvField cand_list[MRG_MAX_NUM_CANDS];
824
825 24737 const int idx[] = { merge_gpm_idx[0], merge_gpm_idx[1] + (merge_gpm_idx[1] >= merge_gpm_idx[0]) };
826
827 24737 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
828 24737 mv_merge_mode(lc, FFMAX(idx[0], idx[1]), cand_list);
829 24737 memset(mv, 0, 2 * sizeof(*mv));
830
2/2
✓ Branch 0 taken 49474 times.
✓ Branch 1 taken 24737 times.
74211 for (int i = 0; i < 2; i++) {
831 49474 int lx = idx[i] & 1;
832 49474 int mask = lx + PF_L0;
833 49474 MvField *cand = cand_list + idx[i];
834
2/2
✓ Branch 0 taken 13529 times.
✓ Branch 1 taken 35945 times.
49474 if (!(cand->pred_flag & mask)) {
835 13529 lx = !lx;
836 13529 mask = lx + PF_L0;
837 }
838 49474 mv[i].pred_flag = mask;
839 49474 mv[i].ref_idx[lx] = cand->ref_idx[lx];
840 49474 mv[i].mv[lx] = cand->mv[lx];
841 }
842
843 24737 }
844
845 //8.5.5.5 Derivation process for luma affine control point motion vectors from a neighbouring block
846 28522 static void affine_cps_from_nb(const VVCLocalContext *lc,
847 const int x_nb, int y_nb, const int nbw, const int nbh, const int lx,
848 Mv *cps, int num_cps)
849 {
850 28522 const VVCFrameContext *fc = lc->fc;
851 28522 const CodingUnit *cu = lc->cu;
852 28522 const int x0 = cu->x0;
853 28522 const int y0 = cu->y0;
854 28522 const int cb_width = cu->cb_width;
855 28522 const int cb_height = cu->cb_height;
856 28522 const MvField* tab_mvf = fc->tab.mvf;
857 28522 const int min_cb_log2_size = fc->ps.sps->min_cb_log2_size_y;
858 28522 const int min_cb_width = fc->ps.pps->min_cb_width;
859
860 28522 const int log2_nbw = ff_log2(nbw);
861 28522 const int log2_nbh = ff_log2(nbh);
862
4/4
✓ Branch 0 taken 8526 times.
✓ Branch 1 taken 19996 times.
✓ Branch 2 taken 3317 times.
✓ Branch 3 taken 5209 times.
28522 const int is_ctb_boundary = !((y_nb + nbh) % fc->ps.sps->ctb_size_y) && (y_nb + nbh == y0);
863 const Mv *l, *r;
864 int mv_scale_hor, mv_scale_ver, d_hor_x, d_ver_x, d_hor_y, d_ver_y, motion_model_idc_nb;
865
2/2
✓ Branch 0 taken 3317 times.
✓ Branch 1 taken 25205 times.
28522 if (is_ctb_boundary) {
866 3317 const int min_pu_width = fc->ps.pps->min_pu_width;
867 3317 l = &TAB_MVF(x_nb, y_nb + nbh - 1).mv[lx];
868 3317 r = &TAB_MVF(x_nb + nbw - 1, y_nb + nbh - 1).mv[lx];
869 } else {
870 25205 const int x = x_nb >> min_cb_log2_size;
871 25205 const int y = y_nb >> min_cb_log2_size;
872 25205 motion_model_idc_nb = SAMPLE_CTB(fc->tab.mmi, x, y);
873
874 25205 l = &TAB_CP_MV(lx, x_nb, y_nb);
875 25205 r = &TAB_CP_MV(lx, x_nb + nbw - 1, y_nb) + 1;
876 }
877 28522 mv_scale_hor = l->x * (1 << 7);
878 28522 mv_scale_ver = l->y * (1 << 7);
879 28522 d_hor_x = (r->x - l->x) * (1 << (7 - log2_nbw));
880 28522 d_ver_x = (r->y - l->y) * (1 << (7 - log2_nbw));
881
4/4
✓ Branch 0 taken 25205 times.
✓ Branch 1 taken 3317 times.
✓ Branch 2 taken 14598 times.
✓ Branch 3 taken 10607 times.
28522 if (!is_ctb_boundary && motion_model_idc_nb == MOTION_6_PARAMS_AFFINE) {
882 14598 const Mv* lb = &TAB_CP_MV(lx, x_nb, y_nb + nbh - 1) + 2;
883 14598 d_hor_y = (lb->x - l->x) * (1 << (7 - log2_nbh));
884 14598 d_ver_y = (lb->y - l->y) * (1 << (7 - log2_nbh));
885 } else {
886 13924 d_hor_y = -d_ver_x;
887 13924 d_ver_y = d_hor_x;
888 }
889
890
2/2
✓ Branch 0 taken 3317 times.
✓ Branch 1 taken 25205 times.
28522 if (is_ctb_boundary) {
891 3317 y_nb = y0;
892 }
893 28522 cps[0].x = mv_scale_hor + d_hor_x * (x0 - x_nb) + d_hor_y * (y0 - y_nb);
894 28522 cps[0].y = mv_scale_ver + d_ver_x * (x0 - x_nb) + d_ver_y * (y0 - y_nb);
895 28522 cps[1].x = mv_scale_hor + d_hor_x * (x0 + cb_width - x_nb) + d_hor_y * (y0 - y_nb);
896 28522 cps[1].y = mv_scale_ver + d_ver_x * (x0 + cb_width - x_nb) + d_ver_y * (y0 - y_nb);
897
2/2
✓ Branch 0 taken 16137 times.
✓ Branch 1 taken 12385 times.
28522 if (num_cps == 3) {
898 16137 cps[2].x = mv_scale_hor + d_hor_x * (x0 - x_nb) + d_hor_y * (y0 + cb_height - y_nb);
899 16137 cps[2].y = mv_scale_ver + d_ver_x * (x0 - x_nb) + d_ver_y * (y0 + cb_height - y_nb);
900 }
901
2/2
✓ Branch 0 taken 73181 times.
✓ Branch 1 taken 28522 times.
101703 for (int i = 0; i < num_cps; i++) {
902 73181 ff_vvc_round_mv(cps + i, 0, 7);
903 73181 ff_vvc_clip_mv(cps + i);
904 }
905 28522 }
906
907 //derive affine neighbour's postion, width and height,
908 89409 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)
909 {
910 89409 const int log2_min_cb_size = fc->ps.sps->min_cb_log2_size_y;
911 89409 const int min_cb_width = fc->ps.pps->min_cb_width;
912 89409 const int x = x_nb >> log2_min_cb_size;
913 89409 const int y = y_nb >> log2_min_cb_size;
914 89409 const int motion_model_idc = SAMPLE_CTB(fc->tab.mmi, x, y);
915
2/2
✓ Branch 0 taken 25563 times.
✓ Branch 1 taken 63846 times.
89409 if (motion_model_idc) {
916 25563 *x_cb = SAMPLE_CTB(fc->tab.cb_pos_x[0], x, y);
917 25563 *y_cb = SAMPLE_CTB(fc->tab.cb_pos_y[0], x, y);
918 25563 *cbw = SAMPLE_CTB(fc->tab.cb_width[0], x, y);
919 25563 *cbh = SAMPLE_CTB(fc->tab.cb_height[0], x, y);
920 }
921 89409 return motion_model_idc;
922 }
923
924 //part of 8.5.5.2 Derivation process for motion vectors and reference indices in subblock merge mode
925 61468 static int affine_merge_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand, MotionInfo* mi)
926 {
927 61468 const VVCFrameContext *fc = lc->fc;
928 int x, y, w, h, motion_model_idc;
929
930 61468 motion_model_idc = affine_neighbour_cb(fc, x_cand, y_cand, &x, &y, &w, &h);
931
2/2
✓ Branch 0 taken 18523 times.
✓ Branch 1 taken 42945 times.
61468 if (motion_model_idc) {
932 18523 const int min_pu_width = fc->ps.pps->min_pu_width;
933 18523 const MvField* tab_mvf = fc->tab.mvf;
934 18523 const MvField *mvf = &TAB_MVF(x, y);
935
936 18523 mi->bcw_idx = mvf->bcw_idx;
937 18523 mi->pred_flag = mvf->pred_flag;
938
2/2
✓ Branch 0 taken 37046 times.
✓ Branch 1 taken 18523 times.
55569 for (int i = 0; i < 2; i++) {
939 37046 PredFlag mask = i + 1;
940
2/2
✓ Branch 0 taken 22827 times.
✓ Branch 1 taken 14219 times.
37046 if (mi->pred_flag & mask) {
941 22827 affine_cps_from_nb(lc, x, y, w, h, i, &mi->mv[i][0], motion_model_idc + 1);
942 }
943 37046 mi->ref_idx[i] = mvf->ref_idx[i];
944 }
945 18523 mi->motion_model_idc = motion_model_idc;
946 }
947 61468 return motion_model_idc;
948 }
949
950 41431 static int affine_merge_from_nbs(NeighbourContext *ctx, const NeighbourIdx *nbs, const int num_nbs, MotionInfo* cand)
951 {
952 41431 const VVCLocalContext *lc = ctx->lc;
953
2/2
✓ Branch 0 taken 86429 times.
✓ Branch 1 taken 22908 times.
109337 for (int i = 0; i < num_nbs; i++) {
954 86429 Neighbour *n = &ctx->neighbours[nbs[i]];
955
4/4
✓ Branch 1 taken 61468 times.
✓ Branch 2 taken 24961 times.
✓ Branch 4 taken 18523 times.
✓ Branch 5 taken 42945 times.
86429 if (check_available(n, lc, 1) && affine_merge_candidate(lc, n->x, n->y, cand))
956 18523 return 1;
957 }
958 22908 return 0;
959 }
960 #define AFFINE_MERGE_FROM_NBS(nbs) affine_merge_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), mi)
961
962
963 90100 static const MvField* derive_corner_mvf(NeighbourContext *ctx, const NeighbourIdx *neighbour, const int num_neighbour)
964 {
965 90100 const VVCFrameContext *fc = ctx->lc->fc;
966 90100 const MvField *tab_mvf = fc->tab.mvf;
967 90100 const int min_pu_width = fc->ps.pps->min_pu_width;
968
2/2
✓ Branch 0 taken 93100 times.
✓ Branch 1 taken 3777 times.
96877 for (int i = 0; i < num_neighbour; i++) {
969 93100 Neighbour *n = &ctx->neighbours[neighbour[i]];
970
2/2
✓ Branch 1 taken 86323 times.
✓ Branch 2 taken 6777 times.
93100 if (check_available(n, ctx->lc, 1)) {
971 86323 return &TAB_MVF(n->x, n->y);
972 }
973 }
974 3777 return NULL;
975 }
976
977 #define DERIVE_CORNER_MV(nbs) derive_corner_mvf(nctx, nbs, FF_ARRAY_ELEMS(nbs))
978
979 // check if the mv's and refidx are the same between A and B
980 50286 static av_always_inline int compare_pf_ref_idx(const MvField *A, const struct MvField *B, const struct MvField *C, const int lx)
981 {
982
983 50286 const PredFlag mask = (lx + 1) & A->pred_flag;
984
2/2
✓ Branch 0 taken 17918 times.
✓ Branch 1 taken 32368 times.
50286 if (!(B->pred_flag & mask))
985 17918 return 0;
986
2/2
✓ Branch 0 taken 1445 times.
✓ Branch 1 taken 30923 times.
32368 if (A->ref_idx[lx] != B->ref_idx[lx])
987 1445 return 0;
988
2/2
✓ Branch 0 taken 26102 times.
✓ Branch 1 taken 4821 times.
30923 if (C) {
989
2/2
✓ Branch 0 taken 888 times.
✓ Branch 1 taken 25214 times.
26102 if (!(C->pred_flag & mask))
990 888 return 0;
991
2/2
✓ Branch 0 taken 1006 times.
✓ Branch 1 taken 24208 times.
25214 if (A->ref_idx[lx] != C->ref_idx[lx])
992 1006 return 0;
993 }
994 29029 return 1;
995 }
996
997 1254562 static av_always_inline void sb_clip_location(const VVCLocalContext *lc,
998 const int x_ctb, const int y_ctb, const Mv* temp_mv, int *x, int *y)
999 {
1000 1254562 const VVCFrameContext *fc = lc->fc;
1001 1254562 const VVCPPS *pps = fc->ps.pps;
1002 1254562 const int ctb_log2_size = fc->ps.sps->ctb_log2_size_y;
1003 1254562 const int subpic_idx = lc->sc->sh.r->curr_subpic_idx;
1004 1254562 const int x_end = pps->subpic_x[subpic_idx] + pps->subpic_width[subpic_idx];
1005 1254562 const int y_end = pps->subpic_y[subpic_idx] + pps->subpic_height[subpic_idx];
1006
1007 1254562 *x = av_clip(*x + temp_mv->x, x_ctb, FFMIN(x_end - 1, x_ctb + (1 << ctb_log2_size) + 3)) & ~7;
1008
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;
1009 1254562 }
1010
1011 1254562 static void sb_temproal_luma_motion(const VVCLocalContext *lc,
1012 const int x_ctb, const int y_ctb, const Mv *temp_mv,
1013 int x, int y, uint8_t *pred_flag, Mv *mv)
1014 {
1015 MvField temp_col;
1016 Mv* mvLXCol;
1017 1254562 const int refIdxLx = 0;
1018 1254562 const VVCFrameContext *fc = lc->fc;
1019 1254562 const VVCSH *sh = &lc->sc->sh;
1020 1254562 const int min_pu_width = fc->ps.pps->min_pu_width;
1021 1254562 VVCFrame *ref = fc->ref->collocated_ref;
1022 1254562 MvField *tab_mvf = ref->tab_dmvr_mvf;
1023 1254562 int colPic = ref->poc;
1024 1254562 int X = 0;
1025
1026 1254562 sb_clip_location(lc, x_ctb, y_ctb, temp_mv, &x, &y);
1027
1028 1254562 temp_col = TAB_MVF(x, y);
1029 1254562 mvLXCol = mv + 0;
1030 1254562 *pred_flag = DERIVE_TEMPORAL_COLOCATED_MVS(1);
1031
2/2
✓ Branch 0 taken 910078 times.
✓ Branch 1 taken 344484 times.
1254562 if (IS_B(sh->r)) {
1032 910078 X = 1;
1033 910078 mvLXCol = mv + 1;
1034 910078 *pred_flag |= (DERIVE_TEMPORAL_COLOCATED_MVS(1)) << 1;
1035 }
1036 1254562 }
1037
1038 //8.5.5.4 Derivation process for subblock-based temporal merging base motion data
1039 48634 static int sb_temporal_luma_motion_data(const VVCLocalContext *lc, const MvField *a1,
1040 const int x_ctb, const int y_ctb, MvField *ctr_mvf, Mv *temp_mv)
1041 {
1042 48634 const VVCFrameContext *fc = lc->fc;
1043 48634 const RefPicList *rpl = lc->sc->rpl;
1044 48634 const CodingUnit *cu = lc->cu;
1045 48634 const int x = cu->x0 + cu->cb_width / 2;
1046 48634 const int y = cu->y0 + cu->cb_height / 2;
1047 48634 const VVCFrame *ref = fc->ref->collocated_ref;
1048
1049 int colPic;
1050
1051 48634 memset(temp_mv, 0, sizeof(*temp_mv));
1052
1053
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48634 times.
48634 if (!ref) {
1054 memset(ctr_mvf, 0, sizeof(*ctr_mvf));
1055 return 0;
1056 }
1057
1058 48634 colPic = ref->poc;
1059
1060
2/2
✓ Branch 0 taken 46174 times.
✓ Branch 1 taken 2460 times.
48634 if (a1) {
1061
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)
1062 29006 *temp_mv = a1->mv[0];
1063
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)
1064 9756 *temp_mv = a1->mv[1];
1065 46174 ff_vvc_round_mv(temp_mv, 0, 4);
1066 }
1067 48634 sb_temproal_luma_motion(lc, x_ctb, y_ctb, temp_mv, x, y, &ctr_mvf->pred_flag , ctr_mvf->mv);
1068
1069 48634 return ctr_mvf->pred_flag;
1070 }
1071
1072
1073 //8.5.5.3 Derivation process for subblock-based temporal merging candidates
1074 48721 static int sb_temporal_merge_candidate(const VVCLocalContext* lc, NeighbourContext *nctx, PredictionUnit *pu)
1075 {
1076 48721 const VVCFrameContext *fc = lc->fc;
1077 48721 const CodingUnit *cu = lc->cu;
1078 48721 const VVCSPS *sps = fc->ps.sps;
1079 48721 const VVCPH *ph = &fc->ps.ph;
1080 48721 MotionInfo *mi = &pu->mi;
1081 48721 const int ctb_log2_size = sps->ctb_log2_size_y;
1082 48721 const int x0 = cu->x0;
1083 48721 const int y0 = cu->y0;
1084 48721 const NeighbourIdx n = A1;
1085 const MvField *a1;
1086 MvField ctr_mvf;
1087 48721 LOCAL_ALIGNED_8(Mv, temp_mv, [1]);
1088 48721 const int x_ctb = (x0 >> ctb_log2_size) << ctb_log2_size;
1089 48721 const int y_ctb = (y0 >> ctb_log2_size) << ctb_log2_size;
1090
1091
1092
2/2
✓ Branch 0 taken 48634 times.
✓ Branch 1 taken 87 times.
48721 if (!ph->r->ph_temporal_mvp_enabled_flag ||
1093
1/2
✓ Branch 0 taken 48634 times.
✗ Branch 1 not taken.
48634 !sps->r->sps_sbtmvp_enabled_flag ||
1094
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))
1095 87 return 0;
1096
1097 48634 mi->num_sb_x = cu->cb_width >> 3;
1098 48634 mi->num_sb_y = cu->cb_height >> 3;
1099
1100 48634 a1 = derive_corner_mvf(nctx, &n, 1);
1101
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)) {
1102 41506 const int sbw = cu->cb_width / mi->num_sb_x;
1103 41506 const int sbh = cu->cb_height / mi->num_sb_y;
1104 41506 MvField mvf = {0};
1105
2/2
✓ Branch 0 taken 171844 times.
✓ Branch 1 taken 41506 times.
213350 for (int sby = 0; sby < mi->num_sb_y; sby++) {
1106
2/2
✓ Branch 0 taken 1205928 times.
✓ Branch 1 taken 171844 times.
1377772 for (int sbx = 0; sbx < mi->num_sb_x; sbx++) {
1107 1205928 int x = x0 + sbx * sbw;
1108 1205928 int y = y0 + sby * sbh;
1109 1205928 sb_temproal_luma_motion(lc, x_ctb, y_ctb, temp_mv, x + sbw / 2, y + sbh / 2, &mvf.pred_flag, mvf.mv);
1110
2/2
✓ Branch 0 taken 6594 times.
✓ Branch 1 taken 1199334 times.
1205928 if (!mvf.pred_flag) {
1111 6594 mvf.pred_flag = ctr_mvf.pred_flag;
1112 6594 memcpy(mvf.mv, ctr_mvf.mv, sizeof(mvf.mv));
1113 }
1114 1205928 ff_vvc_set_mvf(lc, x, y, sbw, sbh, &mvf);
1115 }
1116 }
1117 41506 return 1;
1118 }
1119 7128 return 0;
1120 }
1121
1122 13822 static int affine_merge_const1(const MvField *c0, const MvField *c1, const MvField *c2, MotionInfo *mi)
1123 {
1124
6/6
✓ Branch 0 taken 13757 times.
✓ Branch 1 taken 65 times.
✓ Branch 2 taken 13133 times.
✓ Branch 3 taken 624 times.
✓ Branch 4 taken 12632 times.
✓ Branch 5 taken 501 times.
13822 if (c0 && c1 && c2) {
1125 12632 mi->pred_flag = 0;
1126
2/2
✓ Branch 0 taken 25264 times.
✓ Branch 1 taken 12632 times.
37896 for (int i = 0; i < 2; i++) {
1127 25264 PredFlag mask = i + 1;
1128
2/2
✓ Branch 1 taken 14831 times.
✓ Branch 2 taken 10433 times.
25264 if (compare_pf_ref_idx(c0, c1, c2, i)) {
1129 14831 mi->pred_flag |= mask;
1130 14831 mi->ref_idx[i] = c0->ref_idx[i];
1131 14831 mi->mv[i][0] = c0->mv[i];
1132 14831 mi->mv[i][1] = c1->mv[i];
1133 14831 mi->mv[i][2] = c2->mv[i];
1134 }
1135 }
1136
2/2
✓ Branch 0 taken 11695 times.
✓ Branch 1 taken 937 times.
12632 if (mi->pred_flag) {
1137
2/2
✓ Branch 0 taken 3136 times.
✓ Branch 1 taken 8559 times.
11695 if (mi->pred_flag == PF_BI)
1138 3136 mi->bcw_idx = c0->bcw_idx;
1139 11695 mi->motion_model_idc = MOTION_6_PARAMS_AFFINE;
1140 11695 return 1;
1141 }
1142 }
1143 2127 return 0;
1144 }
1145
1146 7350 static int affine_merge_const2(const MvField *c0, const MvField *c1, const MvField *c3, MotionInfo *mi)
1147 {
1148
6/6
✓ Branch 0 taken 7285 times.
✓ Branch 1 taken 65 times.
✓ Branch 2 taken 6661 times.
✓ Branch 3 taken 624 times.
✓ Branch 4 taken 4507 times.
✓ Branch 5 taken 2154 times.
7350 if (c0 && c1 && c3) {
1149 4507 mi->pred_flag = 0;
1150
2/2
✓ Branch 0 taken 9014 times.
✓ Branch 1 taken 4507 times.
13521 for (int i = 0; i < 2; i++) {
1151 9014 PredFlag mask = i + 1;
1152
2/2
✓ Branch 1 taken 5295 times.
✓ Branch 2 taken 3719 times.
9014 if (compare_pf_ref_idx(c0, c1, c3, i)) {
1153 5295 mi->pred_flag |= mask;
1154 5295 mi->ref_idx[i] = c0->ref_idx[i];
1155 5295 mi->mv[i][0] = c0->mv[i];
1156 5295 mi->mv[i][1] = c1->mv[i];
1157 5295 mi->mv[i][2].x = c3->mv[i].x + c0->mv[i].x - c1->mv[i].x;
1158 5295 mi->mv[i][2].y = c3->mv[i].y + c0->mv[i].y - c1->mv[i].y;
1159 5295 ff_vvc_clip_mv(&mi->mv[i][2]);
1160 }
1161 }
1162
2/2
✓ Branch 0 taken 3942 times.
✓ Branch 1 taken 565 times.
4507 if (mi->pred_flag) {
1163
2/2
✓ Branch 0 taken 1353 times.
✓ Branch 1 taken 2589 times.
3942 mi->bcw_idx = mi->pred_flag == PF_BI ? c0->bcw_idx : 0;
1164 3942 mi->motion_model_idc = MOTION_6_PARAMS_AFFINE;
1165 3942 return 1;
1166 }
1167 }
1168 3408 return 0;
1169 }
1170
1171 5287 static int affine_merge_const3(const MvField *c0, const MvField *c2, const MvField *c3, MotionInfo *mi)
1172 {
1173
6/6
✓ Branch 0 taken 5222 times.
✓ Branch 1 taken 65 times.
✓ Branch 2 taken 4904 times.
✓ Branch 3 taken 318 times.
✓ Branch 4 taken 2766 times.
✓ Branch 5 taken 2138 times.
5287 if (c0 && c2 && c3) {
1174 2766 mi->pred_flag = 0;
1175
2/2
✓ Branch 0 taken 5532 times.
✓ Branch 1 taken 2766 times.
8298 for (int i = 0; i < 2; i++) {
1176 5532 PredFlag mask = i + 1;
1177
2/2
✓ Branch 1 taken 3172 times.
✓ Branch 2 taken 2360 times.
5532 if (compare_pf_ref_idx(c0, c2, c3, i)) {
1178 3172 mi->pred_flag |= mask;
1179 3172 mi->ref_idx[i] = c0->ref_idx[i];
1180 3172 mi->mv[i][0] = c0->mv[i];
1181 3172 mi->mv[i][1].x = c3->mv[i].x + c0->mv[i].x - c2->mv[i].x;
1182 3172 mi->mv[i][1].y = c3->mv[i].y + c0->mv[i].y - c2->mv[i].y;
1183 3172 ff_vvc_clip_mv(&mi->mv[i][1]);
1184 3172 mi->mv[i][2] = c2->mv[i];
1185 }
1186 }
1187
2/2
✓ Branch 0 taken 2347 times.
✓ Branch 1 taken 419 times.
2766 if (mi->pred_flag) {
1188
2/2
✓ Branch 0 taken 825 times.
✓ Branch 1 taken 1522 times.
2347 mi->bcw_idx = mi->pred_flag == PF_BI ? c0->bcw_idx : 0;
1189 2347 mi->motion_model_idc = MOTION_6_PARAMS_AFFINE;
1190 2347 return 1;
1191 }
1192 }
1193 2940 return 0;
1194 }
1195
1196 3700 static int affine_merge_const4(const MvField *c1, const MvField *c2, const MvField *c3, MotionInfo *mi)
1197 {
1198
6/6
✓ Branch 0 taken 3305 times.
✓ Branch 1 taken 395 times.
✓ Branch 2 taken 2993 times.
✓ Branch 3 taken 312 times.
✓ Branch 4 taken 1060 times.
✓ Branch 5 taken 1933 times.
3700 if (c1 && c2 && c3) {
1199 1060 mi->pred_flag = 0;
1200
2/2
✓ Branch 0 taken 2120 times.
✓ Branch 1 taken 1060 times.
3180 for (int i = 0; i < 2; i++) {
1201 2120 PredFlag mask = i + 1;
1202
2/2
✓ Branch 1 taken 910 times.
✓ Branch 2 taken 1210 times.
2120 if (compare_pf_ref_idx(c1, c2, c3, i)) {
1203 910 mi->pred_flag |= mask;
1204 910 mi->ref_idx[i] = c1->ref_idx[i];
1205 910 mi->mv[i][0].x = c1->mv[i].x + c2->mv[i].x - c3->mv[i].x;
1206 910 mi->mv[i][0].y = c1->mv[i].y + c2->mv[i].y - c3->mv[i].y;
1207 910 ff_vvc_clip_mv(&mi->mv[i][0]);
1208 910 mi->mv[i][1] = c1->mv[i];
1209 910 mi->mv[i][2] = c2->mv[i];
1210 }
1211 }
1212
2/2
✓ Branch 0 taken 669 times.
✓ Branch 1 taken 391 times.
1060 if (mi->pred_flag) {
1213
2/2
✓ Branch 0 taken 241 times.
✓ Branch 1 taken 428 times.
669 mi->bcw_idx = mi->pred_flag == PF_BI ? c1->bcw_idx : 0;
1214 669 mi->motion_model_idc = MOTION_6_PARAMS_AFFINE;
1215 669 return 1;
1216 }
1217 }
1218 3031 return 0;
1219 }
1220
1221 3076 static int affine_merge_const5(const MvField *c0, const MvField *c1, MotionInfo *mi)
1222 {
1223
4/4
✓ Branch 0 taken 3011 times.
✓ Branch 1 taken 65 times.
✓ Branch 2 taken 2673 times.
✓ Branch 3 taken 338 times.
3076 if (c0 && c1) {
1224 2673 mi->pred_flag = 0;
1225
2/2
✓ Branch 0 taken 5346 times.
✓ Branch 1 taken 2673 times.
8019 for (int i = 0; i < 2; i++) {
1226 5346 PredFlag mask = i + 1;
1227
2/2
✓ Branch 1 taken 3029 times.
✓ Branch 2 taken 2317 times.
5346 if (compare_pf_ref_idx(c0, c1, NULL, i)) {
1228 3029 mi->pred_flag |= mask;
1229 3029 mi->ref_idx[i] = c0->ref_idx[i];
1230 3029 mi->mv[i][0] = c0->mv[i];
1231 3029 mi->mv[i][1] = c1->mv[i];
1232 }
1233 }
1234
2/2
✓ Branch 0 taken 2400 times.
✓ Branch 1 taken 273 times.
2673 if (mi->pred_flag) {
1235
2/2
✓ Branch 0 taken 629 times.
✓ Branch 1 taken 1771 times.
2400 if (mi->pred_flag == PF_BI)
1236 629 mi->bcw_idx = c0->bcw_idx;
1237 2400 mi->motion_model_idc = MOTION_4_PARAMS_AFFINE;
1238 2400 return 1;
1239 }
1240 }
1241 676 return 0;
1242 }
1243
1244 1651 static int affine_merge_const6(const MvField* c0, const MvField* c2, const int cb_width, const int cb_height, MotionInfo *mi)
1245 {
1246
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) {
1247 1505 const int shift = 7 + av_log2(cb_width) - av_log2(cb_height);
1248 1505 mi->pred_flag = 0;
1249
2/2
✓ Branch 0 taken 3010 times.
✓ Branch 1 taken 1505 times.
4515 for (int i = 0; i < 2; i++) {
1250 3010 PredFlag mask = i + 1;
1251
2/2
✓ Branch 1 taken 1792 times.
✓ Branch 2 taken 1218 times.
3010 if (compare_pf_ref_idx(c0, c2, NULL, i)) {
1252 1792 mi->pred_flag |= mask;
1253 1792 mi->ref_idx[i] = c0->ref_idx[i];
1254 1792 mi->mv[i][0] = c0->mv[i];
1255 1792 mi->mv[i][1].x = (c0->mv[i].x * (1 << 7)) + ((c2->mv[i].y - c0->mv[i].y) * (1 << shift));
1256 1792 mi->mv[i][1].y = (c0->mv[i].y * (1 << 7)) - ((c2->mv[i].x - c0->mv[i].x) * (1 << shift));
1257 1792 ff_vvc_round_mv(&mi->mv[i][1], 0, 7);
1258 1792 ff_vvc_clip_mv(&mi->mv[i][1]);
1259 }
1260 }
1261
2/2
✓ Branch 0 taken 1411 times.
✓ Branch 1 taken 94 times.
1505 if (mi->pred_flag) {
1262
2/2
✓ Branch 0 taken 381 times.
✓ Branch 1 taken 1030 times.
1411 if (mi->pred_flag == PF_BI)
1263 381 mi->bcw_idx = c0->bcw_idx;
1264 1411 mi->motion_model_idc = MOTION_4_PARAMS_AFFINE;
1265 1411 return 1;
1266 }
1267 }
1268 240 return 0;
1269 }
1270
1271 540 static void affine_merge_zero_motion(const VVCLocalContext *lc, MotionInfo *mi)
1272 {
1273 540 const CodingUnit *cu = lc->cu;
1274
1275 540 memset(mi, 0, sizeof(*mi));
1276
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);
1277 540 mi->motion_model_idc = MOTION_4_PARAMS_AFFINE;
1278 540 mi->num_sb_x = cu->cb_width >> MIN_PU_LOG2;
1279 540 mi->num_sb_y = cu->cb_height >> MIN_PU_LOG2;
1280 540 }
1281
1282 //8.5.5.6 Derivation process for constructed affine control point motion vector merging candidates
1283 13822 static int affine_merge_const_candidates(const VVCLocalContext *lc, MotionInfo *mi,
1284 NeighbourContext *nctx, const int merge_subblock_idx, int num_cands)
1285 {
1286 13822 const VVCFrameContext *fc = lc->fc;
1287 13822 const CodingUnit *cu = lc->cu;
1288 13822 const NeighbourIdx tl[] = { B2, B3, A2 };
1289 13822 const NeighbourIdx tr[] = { B1, B0};
1290 13822 const NeighbourIdx bl[] = { A1, A0};
1291 const MvField *c0, *c1, *c2;
1292
1293 13822 c0 = DERIVE_CORNER_MV(tl);
1294 13822 c1 = DERIVE_CORNER_MV(tr);
1295 13822 c2 = DERIVE_CORNER_MV(bl);
1296
1297
1/2
✓ Branch 0 taken 13822 times.
✗ Branch 1 not taken.
13822 if (fc->ps.sps->r->sps_6param_affine_enabled_flag) {
1298 13822 MvField corner3, *c3 = NULL;
1299 //Const1
1300
2/2
✓ Branch 1 taken 11695 times.
✓ Branch 2 taken 2127 times.
13822 if (affine_merge_const1(c0, c1, c2, mi)) {
1301
2/2
✓ Branch 0 taken 6472 times.
✓ Branch 1 taken 5223 times.
11695 if (merge_subblock_idx == num_cands)
1302 10746 return 1;
1303 5223 num_cands++;
1304 }
1305
1306 7350 memset(&corner3, 0, sizeof(corner3));
1307
2/2
✓ Branch 0 taken 7324 times.
✓ Branch 1 taken 26 times.
7350 if (fc->ps.ph.r->ph_temporal_mvp_enabled_flag){
1308 7324 const int available_l0 = temporal_luma_motion_vector(lc, 0, corner3.mv + 0, 0, 0, 0);
1309 14648 const int available_l1 = (lc->sc->sh.r->sh_slice_type == VVC_SLICE_TYPE_B) ?
1310
2/2
✓ Branch 0 taken 5900 times.
✓ Branch 1 taken 1424 times.
7324 temporal_luma_motion_vector(lc, 0, corner3.mv + 1, 1, 0, 0) : 0;
1311
1312 7324 corner3.pred_flag = available_l0 + (available_l1 << 1);
1313
2/2
✓ Branch 0 taken 4941 times.
✓ Branch 1 taken 2383 times.
7324 if (corner3.pred_flag)
1314 4941 c3 = &corner3;
1315 }
1316
1317 //Const2
1318
2/2
✓ Branch 1 taken 3942 times.
✓ Branch 2 taken 3408 times.
7350 if (affine_merge_const2(c0, c1, c3, mi)) {
1319
2/2
✓ Branch 0 taken 2063 times.
✓ Branch 1 taken 1879 times.
3942 if (merge_subblock_idx == num_cands)
1320 2063 return 1;
1321 1879 num_cands++;
1322 }
1323
1324 //Const3
1325
2/2
✓ Branch 1 taken 2347 times.
✓ Branch 2 taken 2940 times.
5287 if (affine_merge_const3(c0, c2, c3, mi)) {
1326
2/2
✓ Branch 0 taken 1587 times.
✓ Branch 1 taken 760 times.
2347 if (merge_subblock_idx == num_cands)
1327 1587 return 1;
1328 760 num_cands++;
1329 }
1330
1331 //Const4
1332
2/2
✓ Branch 1 taken 669 times.
✓ Branch 2 taken 3031 times.
3700 if (affine_merge_const4(c1, c2, c3, mi)) {
1333
2/2
✓ Branch 0 taken 624 times.
✓ Branch 1 taken 45 times.
669 if (merge_subblock_idx == num_cands)
1334 624 return 1;
1335 45 num_cands++;
1336 }
1337 }
1338
1339 //Const5
1340
2/2
✓ Branch 1 taken 2400 times.
✓ Branch 2 taken 676 times.
3076 if (affine_merge_const5(c0, c1, mi)) {
1341
2/2
✓ Branch 0 taken 1425 times.
✓ Branch 1 taken 975 times.
2400 if (merge_subblock_idx == num_cands)
1342 1425 return 1;
1343 975 num_cands++;
1344 }
1345
1346
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)) {
1347
2/2
✓ Branch 0 taken 1111 times.
✓ Branch 1 taken 300 times.
1411 if (merge_subblock_idx == num_cands)
1348 1111 return 1;
1349 }
1350 540 return 0;
1351 }
1352
1353 //8.5.5.2 Derivation process for motion vectors and reference indices in subblock merge mode
1354 //return 1 if candidate is SbCol
1355 48721 static int sb_mv_merge_mode(const VVCLocalContext *lc, const int merge_subblock_idx, PredictionUnit *pu)
1356 {
1357 48721 const VVCSPS *sps = lc->fc->ps.sps;
1358 48721 const CodingUnit *cu = lc->cu;
1359 48721 MotionInfo *mi = &pu->mi;
1360 48721 int num_cands = 0;
1361 NeighbourContext nctx;
1362
1363 48721 init_neighbour_context(&nctx, lc);
1364
1365 //SbCol
1366
2/2
✓ Branch 1 taken 41506 times.
✓ Branch 2 taken 7215 times.
48721 if (sb_temporal_merge_candidate(lc, &nctx, pu)) {
1367
2/2
✓ Branch 0 taken 25354 times.
✓ Branch 1 taken 16152 times.
41506 if (merge_subblock_idx == num_cands)
1368 25354 return 1;
1369 16152 num_cands++;
1370 }
1371
1372 23367 pu->inter_affine_flag = 1;
1373 23367 mi->num_sb_x = cu->cb_width >> MIN_PU_LOG2;
1374 23367 mi->num_sb_y = cu->cb_height >> MIN_PU_LOG2;
1375
1376
1/2
✓ Branch 0 taken 23367 times.
✗ Branch 1 not taken.
23367 if (sps->r->sps_affine_enabled_flag) {
1377 23367 const NeighbourIdx ak[] = { A0, A1 };
1378 23367 const NeighbourIdx bk[] = { B0, B1, B2 };
1379 //A
1380
2/2
✓ Branch 1 taken 9624 times.
✓ Branch 2 taken 13743 times.
23367 if (AFFINE_MERGE_FROM_NBS(ak)) {
1381
2/2
✓ Branch 0 taken 5303 times.
✓ Branch 1 taken 4321 times.
9624 if (merge_subblock_idx == num_cands)
1382 22827 return 0;
1383 4321 num_cands++;
1384 }
1385
1386 //B
1387
2/2
✓ Branch 1 taken 8899 times.
✓ Branch 2 taken 9165 times.
18064 if (AFFINE_MERGE_FROM_NBS(bk)) {
1388
2/2
✓ Branch 0 taken 4242 times.
✓ Branch 1 taken 4657 times.
8899 if (merge_subblock_idx == num_cands)
1389 4242 return 0;
1390 4657 num_cands++;
1391 }
1392
1393 //Const1 to Const6
1394
2/2
✓ Branch 1 taken 13282 times.
✓ Branch 2 taken 540 times.
13822 if (affine_merge_const_candidates(lc, mi, &nctx, merge_subblock_idx, num_cands))
1395 13282 return 0;
1396 }
1397 //Zero
1398 540 affine_merge_zero_motion(lc, mi);
1399 540 return 0;
1400 }
1401
1402 48721 void ff_vvc_sb_mv_merge_mode(VVCLocalContext *lc, const int merge_subblock_idx, PredictionUnit *pu)
1403 {
1404 48721 const CodingUnit *cu = lc->cu;
1405 48721 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
1406
2/2
✓ Branch 1 taken 23367 times.
✓ Branch 2 taken 25354 times.
48721 if (!sb_mv_merge_mode(lc, merge_subblock_idx, pu)) {
1407 23367 ff_vvc_store_sb_mvs(lc, pu);
1408 }
1409 48721 }
1410
1411 105141 static int mvp_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand,
1412 const int lx, const int8_t *ref_idx, Mv *mv)
1413 {
1414 105141 const VVCFrameContext *fc = lc->fc;
1415 105141 const RefPicList *rpl = lc->sc->rpl;
1416 105141 const int min_pu_width = fc->ps.pps->min_pu_width;
1417 105141 const MvField* tab_mvf = fc->tab.mvf;
1418 105141 const MvField *mvf = &TAB_MVF(x_cand, y_cand);
1419 105141 const PredFlag maskx = lx + 1;
1420 105141 const int poc = rpl[lx].refs[ref_idx[lx]].poc;
1421 105141 int available = 0;
1422
1423
4/4
✓ Branch 0 taken 81718 times.
✓ Branch 1 taken 23423 times.
✓ Branch 2 taken 60674 times.
✓ Branch 3 taken 21044 times.
105141 if ((mvf->pred_flag & maskx) && rpl[lx].refs[mvf->ref_idx[lx]].poc == poc) {
1424 60674 available = 1;
1425 60674 *mv = mvf->mv[lx];
1426 } else {
1427 44467 const int ly = !lx;
1428 44467 const PredFlag masky = ly + 1;
1429
4/4
✓ Branch 0 taken 32791 times.
✓ Branch 1 taken 11676 times.
✓ Branch 2 taken 7026 times.
✓ Branch 3 taken 25765 times.
44467 if ((mvf->pred_flag & masky) && rpl[ly].refs[mvf->ref_idx[ly]].poc == poc) {
1430 7026 available = 1;
1431 7026 *mv = mvf->mv[ly];
1432 }
1433 }
1434
1435 105141 return available;
1436 }
1437
1438 27941 static int affine_mvp_candidate(const VVCLocalContext *lc,
1439 const int x_cand, const int y_cand, const int lx, const int8_t *ref_idx,
1440 Mv *cps, const int num_cp)
1441 {
1442 27941 const VVCFrameContext *fc = lc->fc;
1443 27941 int x_nb, y_nb, nbw, nbh, motion_model_idc, available = 0;
1444
1445 27941 motion_model_idc = affine_neighbour_cb(fc, x_cand, y_cand, &x_nb, &y_nb, &nbw, &nbh);
1446
2/2
✓ Branch 0 taken 7040 times.
✓ Branch 1 taken 20901 times.
27941 if (motion_model_idc) {
1447 7040 const int min_pu_width = fc->ps.pps->min_pu_width;
1448 7040 const MvField* tab_mvf = fc->tab.mvf;
1449 7040 const MvField *mvf = &TAB_MVF(x_nb, y_nb);
1450 7040 RefPicList* rpl = lc->sc->rpl;
1451 7040 const PredFlag maskx = lx + 1;
1452 7040 const int poc = rpl[lx].refs[ref_idx[lx]].poc;
1453
1454
4/4
✓ Branch 0 taken 5961 times.
✓ Branch 1 taken 1079 times.
✓ Branch 2 taken 5010 times.
✓ Branch 3 taken 951 times.
7040 if ((mvf->pred_flag & maskx) && rpl[lx].refs[mvf->ref_idx[lx]].poc == poc) {
1455 5010 available = 1;
1456 5010 affine_cps_from_nb(lc, x_nb, y_nb, nbw, nbh, lx, cps, num_cp);
1457 } else {
1458 2030 const int ly = !lx;
1459 2030 const PredFlag masky = ly + 1;
1460
4/4
✓ Branch 0 taken 1311 times.
✓ Branch 1 taken 719 times.
✓ Branch 2 taken 685 times.
✓ Branch 3 taken 626 times.
2030 if ((mvf->pred_flag & masky) && rpl[ly].refs[mvf->ref_idx[ly]].poc == poc) {
1461 685 available = 1;
1462 685 affine_cps_from_nb(lc, x_nb, y_nb, nbw, nbh, ly, cps, num_cp);
1463 }
1464 }
1465
1466 }
1467 27941 return available;
1468 }
1469
1470 121746 static int mvp_from_nbs(NeighbourContext *ctx,
1471 const NeighbourIdx *nbs, const int num_nbs, const int lx, const int8_t *ref_idx, const int amvr_shift,
1472 Mv *cps, const int num_cps)
1473 {
1474 121746 const VVCLocalContext *lc = ctx->lc;
1475 121746 int available = 0;
1476
1477
2/2
✓ Branch 0 taken 234816 times.
✓ Branch 1 taken 48351 times.
283167 for (int i = 0; i < num_nbs; i++) {
1478 234816 Neighbour *n = &ctx->neighbours[nbs[i]];
1479
2/2
✓ Branch 1 taken 133082 times.
✓ Branch 2 taken 101734 times.
234816 if (check_available(n, lc, 0)) {
1480
2/2
✓ Branch 0 taken 27941 times.
✓ Branch 1 taken 105141 times.
133082 if (num_cps > 1)
1481 27941 available = affine_mvp_candidate(lc, n->x, n->y, lx, ref_idx, cps, num_cps);
1482 else
1483 105141 available = mvp_candidate(lc, n->x, n->y, lx, ref_idx, cps);
1484
2/2
✓ Branch 0 taken 73395 times.
✓ Branch 1 taken 59687 times.
133082 if (available) {
1485
2/2
✓ Branch 0 taken 82002 times.
✓ Branch 1 taken 73395 times.
155397 for (int c = 0; c < num_cps; c++)
1486 82002 ff_vvc_round_mv(cps + c, amvr_shift, amvr_shift);
1487 73395 return 1;
1488 }
1489 }
1490 }
1491 48351 return 0;
1492 }
1493
1494 //get mvp from neighbours
1495 #define AFFINE_MVP_FROM_NBS(nbs) \
1496 mvp_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), lx, ref_idx, amvr_shift, cps, num_cp) \
1497
1498 #define MVP_FROM_NBS(nbs) \
1499 mvp_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), lx, ref_idx, amvr_shift, mv, 1) \
1500
1501 63711 static int mvp_spatial_candidates(const VVCLocalContext *lc,
1502 const int mvp_lx_flag, const int lx, const int8_t* ref_idx, const int amvr_shift,
1503 Mv* mv, int *nb_merge_cand)
1504 {
1505 63711 const NeighbourIdx ak[] = { A0, A1 };
1506 63711 const NeighbourIdx bk[] = { B0, B1, B2 };
1507 NeighbourContext nctx;
1508 63711 int available_a, num_cands = 0;
1509 63711 LOCAL_ALIGNED_8(Mv, mv_a, [1]);
1510
1511 63711 init_neighbour_context(&nctx, lc);
1512
1513 63711 available_a = MVP_FROM_NBS(ak);
1514
2/2
✓ Branch 0 taken 42223 times.
✓ Branch 1 taken 21488 times.
63711 if (available_a) {
1515
2/2
✓ Branch 0 taken 26040 times.
✓ Branch 1 taken 16183 times.
42223 if (mvp_lx_flag == num_cands)
1516 26040 return 1;
1517 16183 num_cands++;
1518 16183 *mv_a = *mv;
1519 }
1520
2/2
✓ Branch 1 taken 25477 times.
✓ Branch 2 taken 12194 times.
37671 if (MVP_FROM_NBS(bk)) {
1521
4/4
✓ Branch 0 taken 14364 times.
✓ Branch 1 taken 11113 times.
✓ Branch 2 taken 12203 times.
✓ Branch 3 taken 2161 times.
25477 if (!available_a || !IS_SAME_MV(mv_a, mv)) {
1522
2/2
✓ Branch 0 taken 20012 times.
✓ Branch 1 taken 3304 times.
23316 if (mvp_lx_flag == num_cands)
1523 20012 return 1;
1524 3304 num_cands++;
1525 }
1526 }
1527 17659 *nb_merge_cand = num_cands;
1528 17659 return 0;
1529 }
1530
1531 17659 static int mvp_temporal_candidates(const VVCLocalContext* lc,
1532 const int mvp_lx_flag, const int lx, const int8_t *ref_idx, const int amvr_shift,
1533 Mv* mv, int *num_cands)
1534 {
1535
2/2
✓ Branch 1 taken 12848 times.
✓ Branch 2 taken 4811 times.
17659 if (temporal_luma_motion_vector(lc, ref_idx[lx], mv, lx, 1, 0)) {
1536
2/2
✓ Branch 0 taken 11075 times.
✓ Branch 1 taken 1773 times.
12848 if (mvp_lx_flag == *num_cands) {
1537 11075 ff_vvc_round_mv(mv, amvr_shift, amvr_shift);
1538 11075 return 1;
1539 }
1540 1773 (*num_cands)++;
1541 }
1542 6584 return 0;
1543
1544 }
1545
1546 6584 static int mvp_history_candidates(const VVCLocalContext *lc,
1547 const int mvp_lx_flag, const int lx, const int8_t ref_idx, const int amvr_shift,
1548 Mv *mv, int num_cands)
1549 {
1550 6584 const EntryPoint* ep = lc->ep;
1551 6584 const RefPicList* rpl = lc->sc->rpl;
1552 6584 const int poc = rpl[lx].refs[ref_idx].poc;
1553
1554
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 6312 times.
6584 if (ep->num_hmvp == 0)
1555 272 return 0;
1556
2/2
✓ Branch 0 taken 13062 times.
✓ Branch 1 taken 1503 times.
14565 for (int i = 1; i <= FFMIN(4, ep->num_hmvp); i++) {
1557 13062 const MvField* h = &ep->hmvp[i - 1];
1558
2/2
✓ Branch 0 taken 21733 times.
✓ Branch 1 taken 8253 times.
29986 for (int j = 0; j < 2; j++) {
1559
2/2
✓ Branch 0 taken 8671 times.
✓ Branch 1 taken 13062 times.
21733 const int ly = (j ? !lx : lx);
1560 21733 PredFlag mask = PF_L0 + ly;
1561
4/4
✓ Branch 0 taken 15185 times.
✓ Branch 1 taken 6548 times.
✓ Branch 2 taken 5533 times.
✓ Branch 3 taken 9652 times.
21733 if ((h->pred_flag & mask) && poc == rpl[ly].refs[h->ref_idx[ly]].poc) {
1562
2/2
✓ Branch 0 taken 4809 times.
✓ Branch 1 taken 724 times.
5533 if (mvp_lx_flag == num_cands) {
1563 4809 *mv = h->mv[ly];
1564 4809 ff_vvc_round_mv(mv, amvr_shift, amvr_shift);
1565 4809 return 1;
1566 }
1567 724 num_cands++;
1568 }
1569 }
1570 }
1571 1503 return 0;
1572 }
1573
1574 //8.5.2.8 Derivation process for luma motion vector prediction
1575 63711 static void mvp(const VVCLocalContext *lc, const int mvp_lx_flag, const int lx,
1576 const int8_t *ref_idx, const int amvr_shift, Mv *mv)
1577 {
1578 int num_cands;
1579
1580
2/2
✓ Branch 1 taken 46052 times.
✓ Branch 2 taken 17659 times.
63711 if (mvp_spatial_candidates(lc, mvp_lx_flag, lx, ref_idx, amvr_shift, mv, &num_cands))
1581 61936 return;
1582
1583
2/2
✓ Branch 1 taken 11075 times.
✓ Branch 2 taken 6584 times.
17659 if (mvp_temporal_candidates(lc, mvp_lx_flag, lx, ref_idx, amvr_shift, mv, &num_cands))
1584 11075 return;
1585
1586
2/2
✓ Branch 1 taken 4809 times.
✓ Branch 2 taken 1775 times.
6584 if (mvp_history_candidates(lc, mvp_lx_flag, lx, ref_idx[lx], amvr_shift, mv, num_cands))
1587 4809 return;
1588
1589 1775 memset(mv, 0, sizeof(*mv));
1590 }
1591
1592 48683 void ff_vvc_mvp(VVCLocalContext *lc, const int *mvp_lx_flag, const int amvr_shift, MotionInfo *mi)
1593 {
1594 48683 const CodingUnit *cu = lc->cu;
1595 48683 mi->num_sb_x = 1;
1596 48683 mi->num_sb_y = 1;
1597
1598 48683 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
1599
2/2
✓ Branch 0 taken 41673 times.
✓ Branch 1 taken 7010 times.
48683 if (mi->pred_flag != PF_L1)
1600 41673 mvp(lc, mvp_lx_flag[L0], L0, mi->ref_idx, amvr_shift, &mi->mv[L0][0]);
1601
2/2
✓ Branch 0 taken 22038 times.
✓ Branch 1 taken 26645 times.
48683 if (mi->pred_flag != PF_L0)
1602 22038 mvp(lc, mvp_lx_flag[L1], L1, mi->ref_idx, amvr_shift, &mi->mv[L1][0]);
1603 48683 }
1604
1605 1582 static int ibc_spatial_candidates(const VVCLocalContext *lc, const int merge_idx, Mv *const cand_list, int *nb_merge_cand)
1606 {
1607 1582 const CodingUnit *cu = lc->cu;
1608 1582 const VVCFrameContext *fc = lc->fc;
1609 1582 const int min_pu_width = fc->ps.pps->min_pu_width;
1610 1582 const MvField *tab_mvf = fc->tab.mvf;
1611 1582 const int is_gt4by4 = (cu->cb_width * cu->cb_height) > 16;
1612 1582 int num_cands = 0;
1613
1614 NeighbourContext nctx;
1615 1582 Neighbour *a1 = &nctx.neighbours[A1];
1616 1582 Neighbour *b1 = &nctx.neighbours[B1];
1617
1618
2/2
✓ Branch 0 taken 202 times.
✓ Branch 1 taken 1380 times.
1582 if (!is_gt4by4) {
1619 202 *nb_merge_cand = 0;
1620 202 return 0;
1621 }
1622
1623 1380 init_neighbour_context(&nctx, lc);
1624
1625
2/2
✓ Branch 1 taken 1070 times.
✓ Branch 2 taken 310 times.
1380 if (check_available(a1, lc, 1)) {
1626 1070 cand_list[num_cands++] = TAB_MVF(a1->x, a1->y).mv[L0];
1627
1/2
✓ Branch 0 taken 1070 times.
✗ Branch 1 not taken.
1070 if (num_cands > merge_idx)
1628 1070 return 1;
1629 }
1630
2/2
✓ Branch 1 taken 179 times.
✓ Branch 2 taken 131 times.
310 if (check_available(b1, lc, 1)) {
1631 179 const MvField *mvf = &TAB_MVF(b1->x, b1->y);
1632
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)) {
1633 179 cand_list[num_cands++] = mvf->mv[L0];
1634
1/2
✓ Branch 0 taken 179 times.
✗ Branch 1 not taken.
179 if (num_cands > merge_idx)
1635 179 return 1;
1636 }
1637 }
1638
1639 131 *nb_merge_cand = num_cands;
1640 131 return 0;
1641 }
1642
1643 333 static int ibc_history_candidates(const VVCLocalContext *lc,
1644 const int merge_idx, Mv *cand_list, int *nb_merge_cand)
1645 {
1646 333 const CodingUnit *cu = lc->cu;
1647 333 const EntryPoint *ep = lc->ep;
1648 333 const int is_gt4by4 = (cu->cb_width * cu->cb_height) > 16;
1649 333 int num_cands = *nb_merge_cand;
1650
1651
2/2
✓ Branch 0 taken 319 times.
✓ Branch 1 taken 14 times.
333 for (int i = 1; i <= ep->num_hmvp_ibc; i++) {
1652 319 int same_motion = 0;
1653 319 const MvField *mvf = &ep->hmvp_ibc[ep->num_hmvp_ibc - i];
1654
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 319 times.
319 for (int j = 0; j < *nb_merge_cand; j++) {
1655 same_motion = is_gt4by4 && i == 1 && IS_SAME_MV(&mvf->mv[L0], &cand_list[j]);
1656 if (same_motion)
1657 break;
1658 }
1659
1/2
✓ Branch 0 taken 319 times.
✗ Branch 1 not taken.
319 if (!same_motion) {
1660 319 cand_list[num_cands++] = mvf->mv[L0];
1661
1/2
✓ Branch 0 taken 319 times.
✗ Branch 1 not taken.
319 if (num_cands > merge_idx)
1662 319 return 1;
1663 }
1664 }
1665
1666 14 *nb_merge_cand = num_cands;
1667 14 return 0;
1668 }
1669
1670 #define MV_BITS 18
1671 #define IBC_SHIFT(v) ((v) >= (1 << (MV_BITS - 1)) ? ((v) - (1 << MV_BITS)) : (v))
1672
1673 1342 static inline void ibc_add_mvp(Mv *mv, Mv *mvp, const int amvr_shift)
1674 {
1675 1342 ff_vvc_round_mv(mv, amvr_shift, 0);
1676 1342 ff_vvc_round_mv(mvp, amvr_shift, amvr_shift);
1677
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1342 times.
1342 mv->x = IBC_SHIFT(mv->x + mvp->x);
1678
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1342 times.
1342 mv->y = IBC_SHIFT(mv->y + mvp->y);
1679 1342 }
1680
1681 1582 static void ibc_merge_candidates(VVCLocalContext *lc, const int merge_idx, Mv *mv)
1682 {
1683 1582 const CodingUnit *cu = lc->cu;
1684 1582 LOCAL_ALIGNED_8(Mv, cand_list, [MRG_MAX_NUM_CANDS]);
1685 int nb_cands;
1686
1687 1582 ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
1688
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) ||
1689 333 ibc_history_candidates(lc, merge_idx, cand_list, &nb_cands)) {
1690 1568 *mv = cand_list[merge_idx];
1691 1568 return;
1692 }
1693
1694 //zero mv
1695 14 memset(mv, 0, sizeof(*mv));
1696 }
1697
1698 1582 static int ibc_check_mv(VVCLocalContext *lc, Mv *mv)
1699 {
1700 1582 const VVCFrameContext *fc = lc->fc;
1701 1582 const VVCSPS *sps = lc->fc->ps.sps;
1702 1582 const CodingUnit *cu = lc->cu;
1703 1582 const Mv *bv = &cu->pu.mi.mv[L0][0];
1704
1705
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) {
1706 av_log(fc->log_ctx, AV_LOG_ERROR, "IBC region spans multiple CTBs.\n");
1707 return AVERROR_INVALIDDATA;
1708 }
1709
1710 1582 return 0;
1711 }
1712
1713 1342 int ff_vvc_mvp_ibc(VVCLocalContext *lc, const int mvp_l0_flag, const int amvr_shift, Mv *mv)
1714 {
1715 1342 LOCAL_ALIGNED_8(Mv, mvp, [1]);
1716
1717 1342 ibc_merge_candidates(lc, mvp_l0_flag, mvp);
1718 1342 ibc_add_mvp(mv, mvp, amvr_shift);
1719 1342 return ibc_check_mv(lc, mv);
1720 }
1721
1722 240 int ff_vvc_luma_mv_merge_ibc(VVCLocalContext *lc, const int merge_idx, Mv *mv)
1723 {
1724 240 ibc_merge_candidates(lc, merge_idx, mv);
1725 240 return ibc_check_mv(lc, mv);
1726 }
1727
1728 21471 static int affine_mvp_constructed_cp(NeighbourContext *ctx,
1729 const NeighbourIdx *neighbour, const int num_neighbour,
1730 const int lx, const int8_t ref_idx, const int amvr_shift, Mv *cp)
1731 {
1732 21471 const VVCLocalContext *lc = ctx->lc;
1733 21471 const VVCFrameContext *fc = lc->fc;
1734 21471 const MvField *tab_mvf = fc->tab.mvf;
1735 21471 const int min_pu_width = fc->ps.pps->min_pu_width;
1736 21471 const RefPicList* rpl = lc->sc->rpl;
1737 21471 int available = 0;
1738
1739
2/2
✓ Branch 0 taken 32173 times.
✓ Branch 1 taken 6277 times.
38450 for (int i = 0; i < num_neighbour; i++) {
1740 32173 Neighbour *n = &ctx->neighbours[neighbour[i]];
1741
2/2
✓ Branch 1 taken 21561 times.
✓ Branch 2 taken 10612 times.
32173 if (check_available(n, ctx->lc, 0)) {
1742 21561 const PredFlag maskx = lx + 1;
1743 21561 const MvField* mvf = &TAB_MVF(n->x, n->y);
1744 21561 const int poc = rpl[lx].refs[ref_idx].poc;
1745
4/4
✓ Branch 0 taken 17756 times.
✓ Branch 1 taken 3805 times.
✓ Branch 2 taken 13586 times.
✓ Branch 3 taken 4170 times.
21561 if ((mvf->pred_flag & maskx) && rpl[lx].refs[mvf->ref_idx[lx]].poc == poc) {
1746 13586 available = 1;
1747 13586 *cp = mvf->mv[lx];
1748 } else {
1749 7975 const int ly = !lx;
1750 7975 const PredFlag masky = ly + 1;
1751
4/4
✓ Branch 0 taken 5471 times.
✓ Branch 1 taken 2504 times.
✓ Branch 2 taken 1608 times.
✓ Branch 3 taken 3863 times.
7975 if ((mvf->pred_flag & masky) && rpl[ly].refs[mvf->ref_idx[ly]].poc == poc) {
1752 1608 available = 1;
1753 1608 *cp = mvf->mv[ly];
1754 }
1755 }
1756
2/2
✓ Branch 0 taken 15194 times.
✓ Branch 1 taken 6367 times.
21561 if (available) {
1757 15194 ff_vvc_round_mv(cp, amvr_shift, amvr_shift);
1758 15194 return 1;
1759 }
1760 }
1761 }
1762 6277 return 0;
1763 }
1764
1765 #define AFFINE_MVP_CONSTRUCTED_CP(cands, cp) \
1766 affine_mvp_constructed_cp(nctx, cands, FF_ARRAY_ELEMS(cands), lx, ref_idx, \
1767 amvr_shift, cp)
1768
1769 //8.5.5.8 Derivation process for constructed affine control point motion vector prediction candidates
1770 7157 static int affine_mvp_const1(NeighbourContext* nctx,
1771 const int lx, const int8_t ref_idx, const int amvr_shift,
1772 Mv *cps, int *available)
1773 {
1774 7157 const NeighbourIdx tl[] = { B2, B3, A2 };
1775 7157 const NeighbourIdx tr[] = { B1, B0 };
1776 7157 const NeighbourIdx bl[] = { A1, A0 };
1777
1778 7157 available[0] = AFFINE_MVP_CONSTRUCTED_CP(tl, cps + 0);
1779 7157 available[1] = AFFINE_MVP_CONSTRUCTED_CP(tr, cps + 1);
1780 7157 available[2] = AFFINE_MVP_CONSTRUCTED_CP(bl, cps + 2);
1781
4/4
✓ Branch 0 taken 5844 times.
✓ Branch 1 taken 1313 times.
✓ Branch 2 taken 4527 times.
✓ Branch 3 taken 1317 times.
7157 return available[0] && available[1];
1782 }
1783
1784 //8.5.5.7 item 7
1785 3314 static void affine_mvp_const2(const int idx, Mv *cps, const int num_cp)
1786 {
1787 3314 const Mv mv = cps[idx];
1788
2/2
✓ Branch 0 taken 8350 times.
✓ Branch 1 taken 3314 times.
11664 for (int j = 0; j < num_cp; j++)
1789 8350 cps[j] = mv;
1790 3314 }
1791
1792 //8.5.5.7 Derivation process for luma affine control point motion vector predictors
1793 11149 static void affine_mvp(const VVCLocalContext *lc,
1794 const int mvp_lx_flag, const int lx, const int8_t *ref_idx, const int amvr_shift,
1795 MotionModelIdc motion_model_idc, Mv *cps)
1796 {
1797 11149 const NeighbourIdx ak[] = { A0, A1 };
1798 11149 const NeighbourIdx bk[] = { B0, B1, B2 };
1799 11149 const int num_cp = motion_model_idc + 1;
1800 NeighbourContext nctx;
1801 int available[MAX_CONTROL_POINTS];
1802 11149 int num_cands = 0;
1803
1804 11149 init_neighbour_context(&nctx, lc);
1805 //Ak
1806
2/2
✓ Branch 1 taken 2879 times.
✓ Branch 2 taken 8270 times.
11149 if (AFFINE_MVP_FROM_NBS(ak)) {
1807
2/2
✓ Branch 0 taken 1934 times.
✓ Branch 1 taken 945 times.
2879 if (mvp_lx_flag == num_cands)
1808 10820 return;
1809 945 num_cands++;
1810 }
1811 //Bk
1812
2/2
✓ Branch 1 taken 2816 times.
✓ Branch 2 taken 6399 times.
9215 if (AFFINE_MVP_FROM_NBS(bk)) {
1813
2/2
✓ Branch 0 taken 2058 times.
✓ Branch 1 taken 758 times.
2816 if (mvp_lx_flag == num_cands)
1814 2058 return;
1815 758 num_cands++;
1816 }
1817
1818 //Const1
1819
2/2
✓ Branch 1 taken 4527 times.
✓ Branch 2 taken 2630 times.
7157 if (affine_mvp_const1(&nctx, lx, ref_idx[lx], amvr_shift, cps, available)) {
1820
4/4
✓ Branch 0 taken 1151 times.
✓ Branch 1 taken 3376 times.
✓ Branch 2 taken 604 times.
✓ Branch 3 taken 547 times.
4527 if (available[2] || motion_model_idc == MOTION_4_PARAMS_AFFINE) {
1821
2/2
✓ Branch 0 taken 2773 times.
✓ Branch 1 taken 1207 times.
3980 <