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