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 | 629997 | 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 | 629997 | const uint8_t plevel = fc->ps.sps->log2_parallel_merge_level; | |
34 | |||
35 |
2/2✓ Branch 0 taken 40744 times.
✓ Branch 1 taken 589253 times.
|
670741 | return xN >> plevel == xP >> plevel && |
36 |
2/2✓ Branch 0 taken 6192 times.
✓ Branch 1 taken 34552 times.
|
40744 | yN >> plevel == yP >> plevel; |
37 | } | ||
38 | |||
39 | //return true if we have same mvs and ref_idxs | ||
40 | 2028140 | static av_always_inline int compare_mv_ref_idx(const MvField *n, const MvField *o) | |
41 | { | ||
42 |
4/4✓ Branch 0 taken 1708169 times.
✓ Branch 1 taken 319971 times.
✓ Branch 2 taken 527706 times.
✓ Branch 3 taken 1180463 times.
|
2028140 | if (!o || n->pred_flag != o->pred_flag) |
43 | 847677 | return 0; | |
44 |
2/2✓ Branch 0 taken 1482452 times.
✓ Branch 1 taken 252424 times.
|
1734876 | for (int i = 0; i < 2; i++) { |
45 | 1482452 | PredFlag mask = i + 1; | |
46 |
2/2✓ Branch 0 taken 1343220 times.
✓ Branch 1 taken 139232 times.
|
1482452 | if (n->pred_flag & mask) { |
47 | 1343220 | const int same_ref_idx = n->ref_idx[i] == o->ref_idx[i]; | |
48 | 1343220 | const int same_mv = IS_SAME_MV(n->mv + i, o->mv + i); | |
49 |
4/4✓ Branch 0 taken 1222760 times.
✓ Branch 1 taken 120460 times.
✓ Branch 2 taken 807579 times.
✓ Branch 3 taken 415181 times.
|
1343220 | if (!same_ref_idx || !same_mv) |
50 | 928039 | return 0; | |
51 | } | ||
52 | } | ||
53 | 252424 | return 1; | |
54 | } | ||
55 | |||
56 | // 8.5.2.15 Temporal motion buffer compression process for collocated motion vectors | ||
57 | 1912770 | static av_always_inline void mv_compression(Mv *motion) | |
58 | { | ||
59 | 1912770 | int mv[2] = {motion->x, motion->y}; | |
60 |
2/2✓ Branch 0 taken 3825540 times.
✓ Branch 1 taken 1912770 times.
|
5738310 | for (int i = 0; i < 2; i++) { |
61 | 3825540 | const int s = mv[i] >> 17; | |
62 | 3825540 | const int f = av_log2((mv[i] ^ s) | 31) - 4; | |
63 | 3825540 | const int mask = (-1 * (1 << f)) >> 1; | |
64 | 3825540 | const int round = (1 << f) >> 2; | |
65 | 3825540 | mv[i] = (mv[i] + round) & mask; | |
66 | } | ||
67 | 1912770 | motion->x = mv[0]; | |
68 | 1912770 | motion->y = mv[1]; | |
69 | 1912770 | } | |
70 | |||
71 | 1512837 | void ff_vvc_mv_scale(Mv *dst, const Mv *src, int td, int tb) | |
72 | { | ||
73 | int tx, scale_factor; | ||
74 | |||
75 | 1512837 | td = av_clip_int8(td); | |
76 | 1512837 | tb = av_clip_int8(tb); | |
77 | 1512837 | tx = (0x4000 + (abs(td) >> 1)) / td; | |
78 | 1512837 | scale_factor = av_clip_intp2((tb * tx + 32) >> 6, 12); | |
79 | 1512837 | dst->x = av_clip_intp2((scale_factor * src->x + 127 + | |
80 | 1512837 | (scale_factor * src->x < 0)) >> 8, 17); | |
81 | 1512837 | dst->y = av_clip_intp2((scale_factor * src->y + 127 + | |
82 | 1512837 | (scale_factor * src->y < 0)) >> 8, 17); | |
83 | 1512837 | } | |
84 | |||
85 | //part of 8.5.2.12 Derivation process for collocated motion vectors | ||
86 | 1924839 | 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 | 1924839 | int cur_lt = refPicList[X].refs[refIdxLx].is_lt; | |
92 | 1924839 | int col_lt = refPicList_col[listCol].refs[refidxCol].is_lt; | |
93 | int col_poc_diff, cur_poc_diff; | ||
94 | |||
95 |
2/2✓ Branch 0 taken 12069 times.
✓ Branch 1 taken 1912770 times.
|
1924839 | if (cur_lt != col_lt) { |
96 | 12069 | mvLXCol->x = 0; | |
97 | 12069 | mvLXCol->y = 0; | |
98 | 12069 | return 0; | |
99 | } | ||
100 | |||
101 | 1912770 | col_poc_diff = colPic - refPicList_col[listCol].refs[refidxCol].poc; | |
102 | 1912770 | cur_poc_diff = poc - refPicList[X].refs[refIdxLx].poc; | |
103 | |||
104 | 1912770 | mv_compression(mvCol); | |
105 |
4/4✓ Branch 0 taken 1904552 times.
✓ Branch 1 taken 8218 times.
✓ Branch 2 taken 406776 times.
✓ Branch 3 taken 1497776 times.
|
1912770 | if (cur_lt || col_poc_diff == cur_poc_diff) { |
106 | 414994 | mvLXCol->x = av_clip_intp2(mvCol->x, 17); | |
107 | 414994 | mvLXCol->y = av_clip_intp2(mvCol->y, 17); | |
108 | } else { | ||
109 | 1497776 | ff_vvc_mv_scale(mvLXCol, mvCol, col_poc_diff, cur_poc_diff); | |
110 | } | ||
111 | 1912770 | 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 | 452494 | int ff_vvc_no_backward_pred_flag(const VVCLocalContext *lc) | |
122 | { | ||
123 | 452494 | int check_diffpicount = 0; | |
124 | int i, j; | ||
125 | 452494 | const RefPicList *rpl = lc->sc->rpl; | |
126 | |||
127 |
2/2✓ Branch 0 taken 904988 times.
✓ Branch 1 taken 452494 times.
|
1357482 | for (j = 0; j < 2; j++) { |
128 |
2/2✓ Branch 0 taken 1448759 times.
✓ Branch 1 taken 408999 times.
|
1857758 | for (i = 0; i < lc->sc->sh.r->num_ref_idx_active[j]; i++) { |
129 |
2/2✓ Branch 0 taken 495989 times.
✓ Branch 1 taken 952770 times.
|
1448759 | if (rpl[j].refs[i].poc > lc->fc->ps.ph.poc) { |
130 | 495989 | check_diffpicount++; | |
131 | 495989 | break; | |
132 | } | ||
133 | } | ||
134 | } | ||
135 | 452494 | return !check_diffpicount; | |
136 | } | ||
137 | |||
138 | //8.5.2.12 Derivation process for collocated motion vectors | ||
139 | 2328424 | 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 | 2328424 | const VVCFrameContext *fc = lc->fc; | |
144 | 2328424 | const SliceContext *sc = lc->sc; | |
145 | 2328424 | RefPicList* refPicList = sc->rpl; | |
146 | |||
147 |
2/2✓ Branch 0 taken 76990 times.
✓ Branch 1 taken 2251434 times.
|
2328424 | if (temp_col.pred_flag == PF_INTRA) |
148 | 76990 | return 0; | |
149 | |||
150 |
2/2✓ Branch 0 taken 2133993 times.
✓ Branch 1 taken 117441 times.
|
2251434 | if (sb_flag){ |
151 |
2/2✓ Branch 0 taken 1239369 times.
✓ Branch 1 taken 894624 times.
|
2133993 | if (X == 0) { |
152 |
2/2✓ Branch 0 taken 1123381 times.
✓ Branch 1 taken 115988 times.
|
1239369 | if (temp_col.pred_flag & PF_L0) |
153 | 1123381 | return CHECK_MVSET(0); | |
154 |
3/4✓ Branch 1 taken 2338 times.
✓ Branch 2 taken 113650 times.
✓ Branch 3 taken 2338 times.
✗ Branch 4 not taken.
|
115988 | else if (ff_vvc_no_backward_pred_flag(lc) && (temp_col.pred_flag & PF_L1)) |
155 | 2338 | return CHECK_MVSET(1); | |
156 | } else { | ||
157 |
2/2✓ Branch 0 taken 618500 times.
✓ Branch 1 taken 276124 times.
|
894624 | if (temp_col.pred_flag & PF_L1) |
158 | 618500 | return CHECK_MVSET(1); | |
159 |
3/4✓ Branch 1 taken 63179 times.
✓ Branch 2 taken 212945 times.
✓ Branch 3 taken 63179 times.
✗ Branch 4 not taken.
|
276124 | else if (ff_vvc_no_backward_pred_flag(lc) && (temp_col.pred_flag & PF_L0)) |
160 | 63179 | return CHECK_MVSET(0); | |
161 | } | ||
162 | } else { | ||
163 |
2/2✓ Branch 0 taken 14563 times.
✓ Branch 1 taken 102878 times.
|
117441 | if (!(temp_col.pred_flag & PF_L0)) |
164 | 14563 | return CHECK_MVSET(1); | |
165 |
2/2✓ Branch 0 taken 53741 times.
✓ Branch 1 taken 49137 times.
|
102878 | else if (temp_col.pred_flag == PF_L0) |
166 | 53741 | return CHECK_MVSET(0); | |
167 |
1/2✓ Branch 0 taken 49137 times.
✗ Branch 1 not taken.
|
49137 | else if (temp_col.pred_flag == PF_BI) { |
168 |
2/2✓ Branch 1 taken 9308 times.
✓ Branch 2 taken 39829 times.
|
49137 | if (ff_vvc_no_backward_pred_flag(lc)) { |
169 |
2/2✓ Branch 0 taken 4853 times.
✓ Branch 1 taken 4455 times.
|
9308 | if (X == 0) |
170 | 4853 | return CHECK_MVSET(0); | |
171 | else | ||
172 | 4455 | return CHECK_MVSET(1); | |
173 | } else { | ||
174 |
2/2✓ Branch 0 taken 22401 times.
✓ Branch 1 taken 17428 times.
|
39829 | if (!lc->sc->sh.r->sh_collocated_from_l0_flag) |
175 | 22401 | return CHECK_MVSET(0); | |
176 | else | ||
177 | 17428 | return CHECK_MVSET(1); | |
178 | } | ||
179 | } | ||
180 | } | ||
181 | 326595 | 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 | 144928 | 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 | 144928 | const VVCFrameContext *fc = lc->fc; | |
204 | 144928 | const VVCSPS *sps = fc->ps.sps; | |
205 | 144928 | const VVCPPS *pps = fc->ps.pps; | |
206 | 144928 | const CodingUnit *cu = lc->cu; | |
207 | 144928 | const int subpic_idx = lc->sc->sh.r->curr_subpic_idx; | |
208 | 144928 | int x, y, x_end, y_end, colPic, availableFlagLXCol = 0; | |
209 | 144928 | int min_pu_width = fc->ps.pps->min_pu_width; | |
210 | 144928 | VVCFrame *ref = fc->ref->collocated_ref; | |
211 | MvField *tab_mvf; | ||
212 | MvField temp_col; | ||
213 | |||
214 |
2/2✓ Branch 0 taken 66 times.
✓ Branch 1 taken 144862 times.
|
144928 | if (!ref) { |
215 | 66 | memset(mvLXCol, 0, sizeof(*mvLXCol)); | |
216 | 66 | return 0; | |
217 | } | ||
218 | |||
219 |
3/4✓ Branch 0 taken 144862 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4440 times.
✓ Branch 3 taken 140422 times.
|
144862 | if (!fc->ps.ph.r->ph_temporal_mvp_enabled_flag || (cu->cb_width * cu->cb_height <= 32)) |
220 | 4440 | return 0; | |
221 | |||
222 | 140422 | tab_mvf = ref->tab_dmvr_mvf; | |
223 | 140422 | colPic = ref->poc; | |
224 | |||
225 | //bottom right collocated motion vector | ||
226 | 140422 | x = cu->x0 + cu->cb_width; | |
227 | 140422 | y = cu->y0 + cu->cb_height; | |
228 | |||
229 | 140422 | x_end = pps->subpic_x[subpic_idx] + pps->subpic_width[subpic_idx]; | |
230 | 140422 | y_end = pps->subpic_y[subpic_idx] + pps->subpic_height[subpic_idx]; | |
231 | |||
232 |
1/2✓ Branch 0 taken 140422 times.
✗ Branch 1 not taken.
|
140422 | if (tab_mvf && |
233 |
4/4✓ Branch 0 taken 118672 times.
✓ Branch 1 taken 21750 times.
✓ Branch 2 taken 116378 times.
✓ Branch 3 taken 2294 times.
|
140422 | (cu->y0 >> sps->ctb_log2_size_y) == (y >> sps->ctb_log2_size_y) && |
234 |
2/2✓ Branch 0 taken 112486 times.
✓ Branch 1 taken 3892 times.
|
116378 | x < x_end && y < y_end) { |
235 | 112486 | x &= ~7; | |
236 | 112486 | y &= ~7; | |
237 | 112486 | temp_col = TAB_MVF(x, y); | |
238 | 112486 | availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS(sb_flag); | |
239 | } | ||
240 |
2/2✓ Branch 0 taken 127148 times.
✓ Branch 1 taken 13274 times.
|
140422 | if (check_center) { |
241 | // derive center collocated motion vector | ||
242 |
3/4✓ Branch 0 taken 127148 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54820 times.
✓ Branch 3 taken 72328 times.
|
127148 | if (tab_mvf && !availableFlagLXCol) { |
243 | 54820 | x = cu->x0 + (cu->cb_width >> 1); | |
244 | 54820 | y = cu->y0 + (cu->cb_height >> 1); | |
245 | 54820 | x &= ~7; | |
246 | 54820 | y &= ~7; | |
247 | 54820 | temp_col = TAB_MVF(x, y); | |
248 | 54820 | availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS(sb_flag); | |
249 | } | ||
250 | } | ||
251 | 140422 | return availableFlagLXCol; | |
252 | } | ||
253 | |||
254 | 5486429 | 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 | 5486429 | const VVCFrameContext *fc = lc->fc; | |
257 | 5486429 | MvField *tab_mvf = fc->tab.mvf; | |
258 | 5486429 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
259 | 5486429 | const int min_pu_size = 1 << MIN_PU_LOG2; | |
260 |
2/2✓ Branch 0 taken 8527283 times.
✓ Branch 1 taken 5486429 times.
|
14013712 | for (int dy = 0; dy < h; dy += min_pu_size) { |
261 |
2/2✓ Branch 0 taken 37531700 times.
✓ Branch 1 taken 8527283 times.
|
46058983 | for (int dx = 0; dx < w; dx += min_pu_size) { |
262 | 37531700 | const int x = x0 + dx; | |
263 | 37531700 | const int y = y0 + dy; | |
264 | 37531700 | TAB_MVF(x, y) = *mvf; | |
265 | } | ||
266 | } | ||
267 | 5486429 | } | |
268 | |||
269 | 627242 | void ff_vvc_set_intra_mvf(const VVCLocalContext *lc, const int dmvr) | |
270 | { | ||
271 | 627242 | const VVCFrameContext *fc = lc->fc; | |
272 | 627242 | const CodingUnit *cu = lc->cu; | |
273 |
2/2✓ Branch 0 taken 31182 times.
✓ Branch 1 taken 596060 times.
|
627242 | MvField *tab_mvf = dmvr ? fc->ref->tab_dmvr_mvf : fc->tab.mvf; |
274 | 627242 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
275 | 627242 | const int min_pu_size = 1 << MIN_PU_LOG2; | |
276 |
2/2✓ Branch 0 taken 1564871 times.
✓ Branch 1 taken 627242 times.
|
2192113 | for (int dy = 0; dy < cu->cb_height; dy += min_pu_size) { |
277 |
2/2✓ Branch 0 taken 6534032 times.
✓ Branch 1 taken 1564871 times.
|
8098903 | for (int dx = 0; dx < cu->cb_width; dx += min_pu_size) { |
278 | 6534032 | const int x = cu->x0 + dx; | |
279 | 6534032 | const int y = cu->y0 + dy; | |
280 | 6534032 | TAB_MVF(x, y).pred_flag = PF_INTRA; | |
281 | } | ||
282 | } | ||
283 | 627242 | } | |
284 | |||
285 | //cbProfFlagLX from 8.5.5.9 Derivation process for motion vector arrays from affine control point motion vectors | ||
286 | 44339 | static int derive_cb_prof_flag_lx(const VVCLocalContext *lc, const PredictionUnit* pu, int lx, int is_fallback) | |
287 | { | ||
288 | 44339 | const MotionInfo* mi = &pu->mi; | |
289 | 44339 | const Mv* cp_mv = &mi->mv[lx][0]; | |
290 |
4/4✓ Branch 0 taken 44172 times.
✓ Branch 1 taken 167 times.
✓ Branch 2 taken 1090 times.
✓ Branch 3 taken 43082 times.
|
44339 | if (lc->fc->ps.ph.r->ph_prof_disabled_flag || is_fallback) |
291 | 1257 | return 0; | |
292 |
2/2✓ Branch 0 taken 17858 times.
✓ Branch 1 taken 25224 times.
|
43082 | if (mi->motion_model_idc == MOTION_4_PARAMS_AFFINE) { |
293 |
2/2✓ Branch 0 taken 4720 times.
✓ Branch 1 taken 13138 times.
|
17858 | if (IS_SAME_MV(cp_mv, cp_mv + 1)) |
294 | 4720 | return 0; | |
295 | } | ||
296 |
2/2✓ Branch 0 taken 25224 times.
✓ Branch 1 taken 13138 times.
|
38362 | if (mi->motion_model_idc == MOTION_6_PARAMS_AFFINE) { |
297 |
4/4✓ Branch 0 taken 4237 times.
✓ Branch 1 taken 20987 times.
✓ Branch 2 taken 891 times.
✓ Branch 3 taken 3346 times.
|
25224 | if (IS_SAME_MV(cp_mv, cp_mv + 1) && IS_SAME_MV(cp_mv, cp_mv + 2)) |
298 | 891 | return 0; | |
299 | } | ||
300 |
2/2✓ Branch 0 taken 137 times.
✓ Branch 1 taken 37334 times.
|
37471 | if (lc->sc->rpl[lx].refs[mi->ref_idx[lx]].is_scaled) |
301 | 137 | return 0; | |
302 | 37334 | return 1; | |
303 | } | ||
304 | |||
305 | typedef struct SubblockParams { | ||
306 | int d_hor_x; | ||
307 | int d_ver_x; | ||
308 | int d_hor_y; | ||
309 | int d_ver_y; | ||
310 | int mv_scale_hor; | ||
311 | int mv_scale_ver; | ||
312 | int is_fallback; | ||
313 | |||
314 | int cb_width; | ||
315 | int cb_height; | ||
316 | } SubblockParams; | ||
317 | |||
318 | 44339 | static int is_fallback_mode(const SubblockParams *sp, const PredFlag pred_flag) | |
319 | { | ||
320 | 44339 | const int a = 4 * (2048 + sp->d_hor_x); | |
321 | 44339 | const int b = 4 * sp->d_hor_y; | |
322 | 44339 | const int c = 4 * (2048 + sp->d_ver_y); | |
323 | 44339 | const int d = 4 * sp->d_ver_x; | |
324 |
2/2✓ Branch 0 taken 19232 times.
✓ Branch 1 taken 25107 times.
|
44339 | if (pred_flag == PF_BI) { |
325 |
2/2✓ Branch 0 taken 19124 times.
✓ Branch 1 taken 108 times.
|
19232 | const int max_w4 = FFMAX(0, FFMAX(a, FFMAX(b, a + b))); |
326 |
2/2✓ Branch 0 taken 108 times.
✓ Branch 1 taken 19124 times.
|
19232 | const int min_w4 = FFMIN(0, FFMIN(a, FFMIN(b, a + b))); |
327 |
2/2✓ Branch 0 taken 19133 times.
✓ Branch 1 taken 99 times.
|
19232 | const int max_h4 = FFMAX(0, FFMAX(c, FFMAX(d, c + d))); |
328 |
2/2✓ Branch 0 taken 99 times.
✓ Branch 1 taken 19133 times.
|
19232 | const int min_h4 = FFMIN(0, FFMIN(c, FFMIN(d, c + d))); |
329 | 19232 | const int bx_wx4 = ((max_w4 - min_w4) >> 11) + 9; | |
330 | 19232 | const int bx_hx4 = ((max_h4 - min_h4) >> 11) + 9; | |
331 | 19232 | return bx_wx4 * bx_hx4 > 225; | |
332 | } else { | ||
333 | 25107 | const int bx_wxh = (FFABS(a) >> 11) + 9; | |
334 | 25107 | const int bx_hxh = (FFABS(d) >> 11) + 9; | |
335 | 25107 | const int bx_wxv = (FFABS(b) >> 11) + 9; | |
336 | 25107 | const int bx_hxv = (FFABS(c) >> 11) + 9; | |
337 |
4/4✓ Branch 0 taken 24445 times.
✓ Branch 1 taken 662 times.
✓ Branch 2 taken 24355 times.
✓ Branch 3 taken 90 times.
|
25107 | if (bx_wxh * bx_hxh <= 165 && bx_wxv * bx_hxv <= 165) |
338 | 24355 | return 0; | |
339 | } | ||
340 | 752 | return 1; | |
341 | } | ||
342 | |||
343 | 44339 | static void init_subblock_params(SubblockParams *sp, const MotionInfo* mi, | |
344 | const int cb_width, const int cb_height, const int lx) | ||
345 | { | ||
346 | 44339 | const int log2_cbw = av_log2(cb_width); | |
347 | 44339 | const int log2_cbh = av_log2(cb_height); | |
348 | 44339 | const Mv* cp_mv = mi->mv[lx]; | |
349 | 44339 | const int num_cp_mv = mi->motion_model_idc + 1; | |
350 | 44339 | sp->d_hor_x = (cp_mv[1].x - cp_mv[0].x) * (1 << (MAX_CU_DEPTH - log2_cbw)); | |
351 | 44339 | sp->d_ver_x = (cp_mv[1].y - cp_mv[0].y) * (1 << (MAX_CU_DEPTH - log2_cbw)); | |
352 |
2/2✓ Branch 0 taken 25604 times.
✓ Branch 1 taken 18735 times.
|
44339 | if (num_cp_mv == 3) { |
353 | 25604 | sp->d_hor_y = (cp_mv[2].x - cp_mv[0].x) * (1 << (MAX_CU_DEPTH - log2_cbh)); | |
354 | 25604 | sp->d_ver_y = (cp_mv[2].y - cp_mv[0].y) * (1 << (MAX_CU_DEPTH - log2_cbh)); | |
355 | } else { | ||
356 | 18735 | sp->d_hor_y = -sp->d_ver_x; | |
357 | 18735 | sp->d_ver_y = sp->d_hor_x; | |
358 | } | ||
359 | 44339 | sp->mv_scale_hor = (cp_mv[0].x) * (1 << MAX_CU_DEPTH); | |
360 | 44339 | sp->mv_scale_ver = (cp_mv[0].y) * (1 << MAX_CU_DEPTH); | |
361 | 44339 | sp->cb_width = cb_width; | |
362 | 44339 | sp->cb_height = cb_height; | |
363 | 44339 | sp->is_fallback = is_fallback_mode(sp, mi->pred_flag); | |
364 | 44339 | } | |
365 | |||
366 | 44339 | static void derive_subblock_diff_mvs(const VVCLocalContext *lc, PredictionUnit* pu, const SubblockParams* sp, const int lx) | |
367 | { | ||
368 | 44339 | pu->cb_prof_flag[lx] = derive_cb_prof_flag_lx(lc, pu, lx, sp->is_fallback); | |
369 |
2/2✓ Branch 0 taken 37334 times.
✓ Branch 1 taken 7005 times.
|
44339 | if (pu->cb_prof_flag[lx]) { |
370 | 37334 | const int dmv_limit = 1 << 5; | |
371 | 37334 | const int pos_offset_x = 6 * (sp->d_hor_x + sp->d_hor_y); | |
372 | 37334 | const int pos_offset_y = 6 * (sp->d_ver_x + sp->d_ver_y); | |
373 |
2/2✓ Branch 0 taken 149336 times.
✓ Branch 1 taken 37334 times.
|
186670 | for (int x = 0; x < AFFINE_MIN_BLOCK_SIZE; x++) { |
374 |
2/2✓ Branch 0 taken 597344 times.
✓ Branch 1 taken 149336 times.
|
746680 | for (int y = 0; y < AFFINE_MIN_BLOCK_SIZE; y++) { |
375 | 597344 | LOCAL_ALIGNED_8(Mv, diff, [1]); | |
376 | 597344 | diff->x = x * (sp->d_hor_x * (1 << 2)) + y * (sp->d_hor_y * (1 << 2)) - pos_offset_x; | |
377 | 597344 | diff->y = x * (sp->d_ver_x * (1 << 2)) + y * (sp->d_ver_y * (1 << 2)) - pos_offset_y; | |
378 | 597344 | ff_vvc_round_mv(diff, 0, 8); | |
379 | 597344 | pu->diff_mv_x[lx][AFFINE_MIN_BLOCK_SIZE * y + x] = av_clip(diff->x, -dmv_limit + 1, dmv_limit - 1); | |
380 | 597344 | pu->diff_mv_y[lx][AFFINE_MIN_BLOCK_SIZE * y + x] = av_clip(diff->y, -dmv_limit + 1, dmv_limit - 1); | |
381 | } | ||
382 | } | ||
383 | } | ||
384 | 44339 | } | |
385 | |||
386 | 44339 | static void store_cp_mv(const VVCLocalContext *lc, const MotionInfo *mi, const int lx) | |
387 | { | ||
388 | 44339 | VVCFrameContext *fc = lc->fc; | |
389 | 44339 | const CodingUnit *cu = lc->cu; | |
390 | 44339 | const int log2_min_cb_size = fc->ps.sps->min_cb_log2_size_y; | |
391 | 44339 | const int min_cb_size = fc->ps.sps->min_cb_size_y; | |
392 | 44339 | const int min_cb_width = fc->ps.pps->min_cb_width; | |
393 | 44339 | const int num_cp_mv = mi->motion_model_idc + 1; | |
394 | |||
395 |
2/2✓ Branch 0 taken 348128 times.
✓ Branch 1 taken 44339 times.
|
392467 | for (int dy = 0; dy < cu->cb_height; dy += min_cb_size) { |
396 |
2/2✓ Branch 0 taken 4317728 times.
✓ Branch 1 taken 348128 times.
|
4665856 | for (int dx = 0; dx < cu->cb_width; dx += min_cb_size) { |
397 | 4317728 | const int x_cb = (cu->x0 + dx) >> log2_min_cb_size; | |
398 | 4317728 | const int y_cb = (cu->y0 + dy) >> log2_min_cb_size; | |
399 | 4317728 | const int offset = (y_cb * min_cb_width + x_cb) * MAX_CONTROL_POINTS; | |
400 | |||
401 | 4317728 | memcpy(&fc->tab.cp_mv[lx][offset], mi->mv[lx], sizeof(Mv) * num_cp_mv); | |
402 | } | ||
403 | } | ||
404 | 44339 | } | |
405 | |||
406 | //8.5.5.9 Derivation process for motion vector arrays from affine control point motion vectors | ||
407 | 34723 | void ff_vvc_store_sb_mvs(const VVCLocalContext *lc, PredictionUnit *pu) | |
408 | { | ||
409 | 34723 | const CodingUnit *cu = lc->cu; | |
410 | 34723 | const MotionInfo *mi = &pu->mi; | |
411 | 34723 | const int sbw = cu->cb_width / mi->num_sb_x; | |
412 | 34723 | const int sbh = cu->cb_height / mi->num_sb_y; | |
413 | SubblockParams params[2]; | ||
414 | 34723 | MvField mvf = {0}; | |
415 | |||
416 | 34723 | mvf.pred_flag = mi->pred_flag; | |
417 | 34723 | mvf.bcw_idx = mi->bcw_idx; | |
418 | 34723 | mvf.hpel_if_idx = mi->hpel_if_idx; | |
419 |
2/2✓ Branch 0 taken 69446 times.
✓ Branch 1 taken 34723 times.
|
104169 | for (int i = 0; i < 2; i++) { |
420 | 69446 | const PredFlag mask = i + 1; | |
421 |
2/2✓ Branch 0 taken 44339 times.
✓ Branch 1 taken 25107 times.
|
69446 | if (mi->pred_flag & mask) { |
422 | 44339 | store_cp_mv(lc, mi, i); | |
423 | 44339 | init_subblock_params(params + i, mi, cu->cb_width, cu->cb_height, i); | |
424 | 44339 | derive_subblock_diff_mvs(lc, pu, params + i, i); | |
425 | 44339 | mvf.ref_idx[i] = mi->ref_idx[i]; | |
426 | } | ||
427 | } | ||
428 | |||
429 |
2/2✓ Branch 0 taken 274454 times.
✓ Branch 1 taken 34723 times.
|
309177 | for (int sby = 0; sby < mi->num_sb_y; sby++) { |
430 |
2/2✓ Branch 0 taken 3378072 times.
✓ Branch 1 taken 274454 times.
|
3652526 | for (int sbx = 0; sbx < mi->num_sb_x; sbx++) { |
431 | 3378072 | const int x0 = cu->x0 + sbx * sbw; | |
432 | 3378072 | const int y0 = cu->y0 + sby * sbh; | |
433 |
2/2✓ Branch 0 taken 6756144 times.
✓ Branch 1 taken 3378072 times.
|
10134216 | for (int i = 0; i < 2; i++) { |
434 | 6756144 | const PredFlag mask = i + 1; | |
435 |
2/2✓ Branch 0 taken 4317728 times.
✓ Branch 1 taken 2438416 times.
|
6756144 | if (mi->pred_flag & mask) { |
436 | 4317728 | const SubblockParams* sp = params + i; | |
437 |
2/2✓ Branch 0 taken 141368 times.
✓ Branch 1 taken 4176360 times.
|
4317728 | const int x_pos_cb = sp->is_fallback ? (cu->cb_width >> 1) : (2 + (sbx << MIN_CU_LOG2)); |
438 |
2/2✓ Branch 0 taken 141368 times.
✓ Branch 1 taken 4176360 times.
|
4317728 | const int y_pos_cb = sp->is_fallback ? (cu->cb_height >> 1) : (2 + (sby << MIN_CU_LOG2)); |
439 | 4317728 | Mv *mv = mvf.mv + i; | |
440 | |||
441 | 4317728 | mv->x = sp->mv_scale_hor + sp->d_hor_x * x_pos_cb + sp->d_hor_y * y_pos_cb; | |
442 | 4317728 | mv->y = sp->mv_scale_ver + sp->d_ver_x * x_pos_cb + sp->d_ver_y * y_pos_cb; | |
443 | 4317728 | ff_vvc_round_mv(mv, 0, MAX_CU_DEPTH); | |
444 | 4317728 | ff_vvc_clip_mv(mv); | |
445 | } | ||
446 | } | ||
447 | 3378072 | ff_vvc_set_mvf(lc, x0, y0, sbw, sbh, &mvf); | |
448 | } | ||
449 | } | ||
450 | 34723 | } | |
451 | |||
452 | 25615 | void ff_vvc_store_gpm_mvf(const VVCLocalContext *lc, const PredictionUnit *pu) | |
453 | { | ||
454 | 25615 | const CodingUnit *cu = lc->cu; | |
455 | 25615 | const int angle_idx = ff_vvc_gpm_angle_idx[pu->gpm_partition_idx]; | |
456 | 25615 | const int distance_idx = ff_vvc_gpm_distance_idx[pu->gpm_partition_idx]; | |
457 | 25615 | const int displacement_x = ff_vvc_gpm_distance_lut[angle_idx]; | |
458 | 25615 | const int displacement_y = ff_vvc_gpm_distance_lut[(angle_idx + 8) % 32]; | |
459 |
4/4✓ Branch 0 taken 13514 times.
✓ Branch 1 taken 12101 times.
✓ Branch 2 taken 10810 times.
✓ Branch 3 taken 2704 times.
|
25615 | const int is_flip = angle_idx >= 13 &&angle_idx <= 27; |
460 |
6/6✓ Branch 0 taken 24018 times.
✓ Branch 1 taken 1597 times.
✓ Branch 2 taken 21262 times.
✓ Branch 3 taken 2756 times.
✓ Branch 4 taken 5180 times.
✓ Branch 5 taken 16082 times.
|
25615 | const int shift_hor = (angle_idx % 16 == 8 || (angle_idx % 16 && cu->cb_height >= cu->cb_width)) ? 0 : 1; |
461 |
2/2✓ Branch 0 taken 15033 times.
✓ Branch 1 taken 10582 times.
|
25615 | const int sign = angle_idx < 16 ? 1 : -1; |
462 | 25615 | const int block_size = 4; | |
463 | 25615 | int offset_x = (-cu->cb_width) >> 1; | |
464 | 25615 | int offset_y = (-cu->cb_height) >> 1; | |
465 | |||
466 |
2/2✓ Branch 0 taken 17679 times.
✓ Branch 1 taken 7936 times.
|
25615 | if (!shift_hor) |
467 | 17679 | offset_y += sign * ((distance_idx * cu->cb_height) >> 3); | |
468 | else | ||
469 | 7936 | offset_x += sign * ((distance_idx * cu->cb_width) >> 3); | |
470 | |||
471 |
2/2✓ Branch 0 taken 115142 times.
✓ Branch 1 taken 25615 times.
|
140757 | for (int y = 0; y < cu->cb_height; y += block_size) { |
472 |
2/2✓ Branch 0 taken 534628 times.
✓ Branch 1 taken 115142 times.
|
649770 | for (int x = 0; x < cu->cb_width; x += block_size) { |
473 | 534628 | const int motion_idx = (((x + offset_x) * (1 << 1)) + 5) * displacement_x + | |
474 | 534628 | (((y + offset_y) * (1 << 1)) + 5) * displacement_y; | |
475 |
6/6✓ Branch 0 taken 267838 times.
✓ Branch 1 taken 266790 times.
✓ Branch 2 taken 162504 times.
✓ Branch 3 taken 105334 times.
✓ Branch 4 taken 266790 times.
✓ Branch 5 taken 162504 times.
|
534628 | const int s_type = FFABS(motion_idx) < 32 ? 2 : (motion_idx <= 0 ? (1 - is_flip) : is_flip); |
476 | 534628 | const int pred_flag = pu->gpm_mv[0].pred_flag | pu->gpm_mv[1].pred_flag; | |
477 | 534628 | const int x0 = cu->x0 + x; | |
478 | 534628 | const int y0 = cu->y0 + y; | |
479 | |||
480 |
2/2✓ Branch 0 taken 208313 times.
✓ Branch 1 taken 326315 times.
|
534628 | if (!s_type) |
481 | 208313 | ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, pu->gpm_mv + 0); | |
482 |
5/6✓ Branch 0 taken 105334 times.
✓ Branch 1 taken 220981 times.
✓ Branch 2 taken 105334 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 56236 times.
✓ Branch 5 taken 49098 times.
|
326315 | else if (s_type == 1 || (s_type == 2 && pred_flag != PF_BI)) |
483 | 277217 | ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, pu->gpm_mv + 1); | |
484 | else { | ||
485 | 49098 | MvField mvf = pu->gpm_mv[0]; | |
486 | 49098 | const MvField *mv1 = &pu->gpm_mv[1]; | |
487 | 49098 | const int lx = mv1->pred_flag - PF_L0; | |
488 | 49098 | mvf.pred_flag = PF_BI; | |
489 | 49098 | mvf.ref_idx[lx] = mv1->ref_idx[lx]; | |
490 | 49098 | mvf.mv[lx] = mv1->mv[lx]; | |
491 | 49098 | ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, &mvf); | |
492 | } | ||
493 | } | ||
494 | } | ||
495 | 25615 | } | |
496 | |||
497 | 273411 | void ff_vvc_store_mvf(const VVCLocalContext *lc, const MvField *mvf) | |
498 | { | ||
499 | 273411 | const CodingUnit *cu = lc->cu; | |
500 | 273411 | ff_vvc_set_mvf(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height, mvf); | |
501 | 273411 | } | |
502 | |||
503 | 96186 | void ff_vvc_store_mv(const VVCLocalContext *lc, const MotionInfo *mi) | |
504 | { | ||
505 | 96186 | const CodingUnit *cu = lc->cu; | |
506 | 96186 | MvField mvf = {0}; | |
507 | |||
508 | 96186 | mvf.hpel_if_idx = mi->hpel_if_idx; | |
509 | 96186 | mvf.bcw_idx = mi->bcw_idx; | |
510 | 96186 | mvf.pred_flag = mi->pred_flag; | |
511 | |||
512 |
2/2✓ Branch 0 taken 192372 times.
✓ Branch 1 taken 96186 times.
|
288558 | for (int i = 0; i < 2; i++) { |
513 | 192372 | const PredFlag mask = i + 1; | |
514 |
2/2✓ Branch 0 taken 114541 times.
✓ Branch 1 taken 77831 times.
|
192372 | if (mvf.pred_flag & mask) { |
515 | 114541 | mvf.mv[i] = mi->mv[i][0]; | |
516 | 114541 | mvf.ref_idx[i] = mi->ref_idx[i]; | |
517 | } | ||
518 | } | ||
519 | 96186 | ff_vvc_set_mvf(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height, &mvf); | |
520 | 96186 | } | |
521 | |||
522 | typedef enum NeighbourIdx { | ||
523 | A0, | ||
524 | A1, | ||
525 | A2, | ||
526 | B0, | ||
527 | B1, | ||
528 | B2, | ||
529 | B3, | ||
530 | NUM_NBS, | ||
531 | NB_IDX_NONE = NUM_NBS, | ||
532 | } NeighbourIdx; | ||
533 | |||
534 | typedef struct Neighbour { | ||
535 | int x; | ||
536 | int y; | ||
537 | |||
538 | int checked; | ||
539 | int available; | ||
540 | } Neighbour; | ||
541 | |||
542 | typedef struct NeighbourContext { | ||
543 | Neighbour neighbours[NUM_NBS]; | ||
544 | const VVCLocalContext *lc; | ||
545 | } NeighbourContext; | ||
546 | |||
547 | 1305319 | static int is_available(const VVCFrameContext *fc, const int x0, const int y0) | |
548 | { | ||
549 | 1305319 | const VVCSPS *sps = fc->ps.sps; | |
550 | 1305319 | const int x = x0 >> sps->min_cb_log2_size_y; | |
551 | 1305319 | const int y = y0 >> sps->min_cb_log2_size_y; | |
552 | 1305319 | const int min_cb_width = fc->ps.pps->min_cb_width; | |
553 | |||
554 | 1305319 | return SAMPLE_CTB(fc->tab.cb_width[0], x, y) != 0; | |
555 | } | ||
556 | |||
557 | 458240 | static int is_a0_available(const VVCLocalContext *lc, const CodingUnit *cu) | |
558 | { | ||
559 | 458240 | const VVCFrameContext *fc = lc->fc; | |
560 | 458240 | const VVCSPS *sps = fc->ps.sps; | |
561 | 458240 | const int x0b = av_zero_extend(cu->x0, sps->ctb_log2_size_y); | |
562 | int cand_bottom_left; | ||
563 | |||
564 |
4/4✓ Branch 0 taken 99484 times.
✓ Branch 1 taken 358756 times.
✓ Branch 2 taken 14751 times.
✓ Branch 3 taken 84733 times.
|
458240 | if (!x0b && !lc->ctb_left_flag) { |
565 | 14751 | cand_bottom_left = 0; | |
566 | } else { | ||
567 | 443489 | const int max_y = FFMIN(fc->ps.pps->height, ((cu->y0 >> sps->ctb_log2_size_y) + 1) << sps->ctb_log2_size_y); | |
568 |
2/2✓ Branch 0 taken 92400 times.
✓ Branch 1 taken 351089 times.
|
443489 | if (cu->y0 + cu->cb_height >= max_y) |
569 | 92400 | cand_bottom_left = 0; | |
570 | else | ||
571 | 351089 | cand_bottom_left = is_available(fc, cu->x0 - 1, cu->y0 + cu->cb_height); | |
572 | } | ||
573 | 458240 | return cand_bottom_left; | |
574 | } | ||
575 | |||
576 | 458240 | static void init_neighbour_context(NeighbourContext *ctx, const VVCLocalContext *lc) | |
577 | { | ||
578 | 458240 | const CodingUnit *cu = lc->cu; | |
579 | 458240 | const NeighbourAvailable *na = &lc->na; | |
580 | 458240 | const int x0 = cu->x0; | |
581 | 458240 | const int y0 = cu->y0; | |
582 | 458240 | const int cb_width = cu->cb_width; | |
583 | 458240 | const int cb_height = cu->cb_height; | |
584 | 458240 | const int a0_available = is_a0_available(lc, cu); | |
585 | |||
586 | 458240 | Neighbour neighbours[NUM_NBS] = { | |
587 | 458240 | { x0 - 1, y0 + cb_height, !a0_available }, //A0 | |
588 | 458240 | { x0 - 1, y0 + cb_height - 1, !na->cand_left }, //A1 | |
589 | 458240 | { x0 - 1, y0, !na->cand_left }, //A2 | |
590 | 458240 | { x0 + cb_width, y0 - 1, !na->cand_up_right }, //B0 | |
591 | 458240 | { x0 + cb_width - 1, y0 - 1, !na->cand_up }, //B1 | |
592 | 458240 | { x0 - 1, y0 - 1, !na->cand_up_left }, //B2 | |
593 | 458240 | { x0, y0 - 1, !na->cand_up }, //B3 | |
594 | }; | ||
595 | |||
596 | 458240 | memcpy(ctx->neighbours, neighbours, sizeof(neighbours)); | |
597 | 458240 | ctx->lc = lc; | |
598 | 458240 | } | |
599 | |||
600 | 907066 | static av_always_inline PredMode pred_flag_to_mode(PredFlag pred) | |
601 | { | ||
602 |
2/2✓ Branch 0 taken 891780 times.
✓ Branch 1 taken 15286 times.
|
907066 | return pred == PF_IBC ? MODE_IBC : (pred == PF_INTRA ? MODE_INTRA : MODE_INTER); |
603 | } | ||
604 | |||
605 | 1240586 | static int check_available(Neighbour *n, const VVCLocalContext *lc, const int check_mer) | |
606 | { | ||
607 | 1240586 | const VVCFrameContext *fc = lc->fc; | |
608 | 1240586 | const VVCSPS *sps = fc->ps.sps; | |
609 | 1240586 | const CodingUnit *cu = lc->cu; | |
610 | 1240586 | const MvField *tab_mvf = fc->tab.mvf; | |
611 | 1240586 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
612 | |||
613 |
2/2✓ Branch 0 taken 954430 times.
✓ Branch 1 taken 286156 times.
|
1240586 | if (!n->checked) { |
614 | 954430 | n->checked = 1; | |
615 |
4/4✓ Branch 0 taken 87906 times.
✓ Branch 1 taken 866524 times.
✓ Branch 2 taken 87706 times.
✓ Branch 3 taken 200 times.
|
954430 | n->available = !sps->r->sps_entropy_coding_sync_enabled_flag || ((n->x >> sps->ctb_log2_size_y) <= (cu->x0 >> sps->ctb_log2_size_y)); |
616 |
6/6✓ Branch 0 taken 954230 times.
✓ Branch 1 taken 200 times.
✓ Branch 3 taken 907066 times.
✓ Branch 4 taken 47164 times.
✓ Branch 6 taken 810137 times.
✓ Branch 7 taken 96929 times.
|
954430 | n->available = n->available && is_available(fc, n->x, n->y) && cu->pred_mode == pred_flag_to_mode(TAB_MVF(n->x, n->y).pred_flag); |
617 |
2/2✓ Branch 0 taken 699451 times.
✓ Branch 1 taken 254979 times.
|
954430 | if (check_mer) |
618 |
4/4✓ Branch 0 taken 629997 times.
✓ Branch 1 taken 69454 times.
✓ Branch 3 taken 623805 times.
✓ Branch 4 taken 6192 times.
|
699451 | n->available = n->available && !is_same_mer(fc, n->x, n->y, cu->x0, cu->y0); |
619 | } | ||
620 | 1240586 | return n->available; | |
621 | } | ||
622 | |||
623 | 526431 | static const MvField *mv_merge_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand) | |
624 | { | ||
625 | 526431 | const VVCFrameContext *fc = lc->fc; | |
626 | 526431 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
627 | 526431 | const MvField* tab_mvf = fc->tab.mvf; | |
628 | 526431 | const MvField *mvf = &TAB_MVF(x_cand, y_cand); | |
629 | |||
630 | 526431 | return mvf; | |
631 | } | ||
632 | |||
633 | 669541 | static const MvField* mv_merge_from_nb(NeighbourContext *ctx, const NeighbourIdx nb) | |
634 | { | ||
635 | 669541 | const VVCLocalContext *lc = ctx->lc; | |
636 | 669541 | Neighbour *n = &ctx->neighbours[nb]; | |
637 | |||
638 |
2/2✓ Branch 1 taken 526431 times.
✓ Branch 2 taken 143110 times.
|
669541 | if (check_available(n, lc, 1)) |
639 | 526431 | return mv_merge_candidate(lc, n->x, n->y); | |
640 | 143110 | return 0; | |
641 | } | ||
642 | #define MV_MERGE_FROM_NB(nb) mv_merge_from_nb(&nctx, nb) | ||
643 | |||
644 | //8.5.2.3 Derivation process for spatial merging candidates | ||
645 | 299026 | static int mv_merge_spatial_candidates(const VVCLocalContext *lc, const int merge_idx, | |
646 | const MvField **nb_list, MvField *cand_list, int *nb_merge_cand) | ||
647 | { | ||
648 | const MvField *cand; | ||
649 | 299026 | int num_cands = 0; | |
650 | NeighbourContext nctx; | ||
651 | |||
652 | static NeighbourIdx nbs[][2] = { | ||
653 | {B1, NB_IDX_NONE }, | ||
654 | {A1, B1 }, | ||
655 | {B0, B1 }, | ||
656 | {A0, A1 }, | ||
657 | }; | ||
658 | |||
659 | 299026 | init_neighbour_context(&nctx, lc); | |
660 |
2/2✓ Branch 0 taken 604840 times.
✓ Branch 1 taken 65371 times.
|
670211 | for (int i = 0; i < FF_ARRAY_ELEMS(nbs); i++) { |
661 | 604840 | NeighbourIdx nb = nbs[i][0]; | |
662 | 604840 | NeighbourIdx old = nbs[i][1]; | |
663 | 604840 | cand = nb_list[nb] = MV_MERGE_FROM_NB(nb); | |
664 |
4/4✓ Branch 0 taken 475502 times.
✓ Branch 1 taken 129338 times.
✓ Branch 3 taken 429048 times.
✓ Branch 4 taken 46454 times.
|
604840 | if (cand && !compare_mv_ref_idx(cand, nb_list[old])) { |
665 | 429048 | cand_list[num_cands] = *cand; | |
666 |
2/2✓ Branch 0 taken 233655 times.
✓ Branch 1 taken 195393 times.
|
429048 | if (merge_idx == num_cands) |
667 | 233655 | return 1; | |
668 | 195393 | num_cands++; | |
669 | } | ||
670 | } | ||
671 |
2/2✓ Branch 0 taken 64701 times.
✓ Branch 1 taken 670 times.
|
65371 | if (num_cands != 4) { |
672 | 64701 | cand = MV_MERGE_FROM_NB(B2); | |
673 |
4/4✓ Branch 0 taken 50929 times.
✓ Branch 1 taken 13772 times.
✓ Branch 3 taken 30808 times.
✓ Branch 4 taken 20121 times.
|
64701 | if (cand && !compare_mv_ref_idx(cand, nb_list[A1]) |
674 |
2/2✓ Branch 1 taken 21848 times.
✓ Branch 2 taken 8960 times.
|
30808 | && !compare_mv_ref_idx(cand, nb_list[B1])) { |
675 | 21848 | cand_list[num_cands] = *cand; | |
676 |
2/2✓ Branch 0 taken 9748 times.
✓ Branch 1 taken 12100 times.
|
21848 | if (merge_idx == num_cands) |
677 | 9748 | return 1; | |
678 | 12100 | num_cands++; | |
679 | } | ||
680 | } | ||
681 | 55623 | *nb_merge_cand = num_cands; | |
682 | 55623 | return 0; | |
683 | } | ||
684 | |||
685 | 55623 | static int mv_merge_temporal_candidate(const VVCLocalContext *lc, MvField *cand) | |
686 | { | ||
687 | 55623 | const VVCFrameContext *fc = lc->fc; | |
688 | 55623 | const CodingUnit *cu = lc->cu; | |
689 | |||
690 | 55623 | memset(cand, 0, sizeof(*cand)); | |
691 |
4/4✓ Branch 0 taken 55476 times.
✓ Branch 1 taken 147 times.
✓ Branch 2 taken 51853 times.
✓ Branch 3 taken 3623 times.
|
55623 | if (fc->ps.ph.r->ph_temporal_mvp_enabled_flag && (cu->cb_width * cu->cb_height > 32)) { |
692 | 51853 | int available_l0 = temporal_luma_motion_vector(lc, 0, cand->mv + 0, 0, 1, 0); | |
693 | 103706 | int available_l1 = IS_B(lc->sc->sh.r) ? | |
694 |
2/2✓ Branch 0 taken 49064 times.
✓ Branch 1 taken 2789 times.
|
51853 | temporal_luma_motion_vector(lc, 0, cand->mv + 1, 1, 1, 0) : 0; |
695 | 51853 | cand->pred_flag = available_l0 + (available_l1 << 1); | |
696 | } | ||
697 | 55623 | return cand->pred_flag; | |
698 | } | ||
699 | |||
700 | //8.5.2.6 Derivation process for history-based merging candidates | ||
701 | 35237 | static int mv_merge_history_candidates(const VVCLocalContext *lc, const int merge_idx, | |
702 | const MvField **nb_list, MvField *cand_list, int *num_cands) | ||
703 | { | ||
704 | 35237 | const VVCSPS *sps = lc->fc->ps.sps; | |
705 | 35237 | const EntryPoint* ep = lc->ep; | |
706 |
4/4✓ Branch 0 taken 90135 times.
✓ Branch 1 taken 2704 times.
✓ Branch 2 taken 81538 times.
✓ Branch 3 taken 8597 times.
|
92839 | for (int i = 1; i <= ep->num_hmvp && (*num_cands < sps->max_num_merge_cand - 1); i++) { |
707 | 81538 | const MvField *h = &ep->hmvp[ep->num_hmvp - i]; | |
708 |
6/6✓ Branch 0 taken 59969 times.
✓ Branch 1 taken 21569 times.
✓ Branch 3 taken 41301 times.
✓ Branch 4 taken 18668 times.
✓ Branch 6 taken 10171 times.
✓ Branch 7 taken 31130 times.
|
81538 | const int same_motion = i <= 2 && (compare_mv_ref_idx(h, nb_list[A1]) || compare_mv_ref_idx(h, nb_list[B1])); |
709 |
2/2✓ Branch 0 taken 52699 times.
✓ Branch 1 taken 28839 times.
|
81538 | if (!same_motion) { |
710 | 52699 | cand_list[*num_cands] = *h; | |
711 |
2/2✓ Branch 0 taken 23936 times.
✓ Branch 1 taken 28763 times.
|
52699 | if (merge_idx == *num_cands) |
712 | 23936 | return 1; | |
713 | 28763 | (*num_cands)++; | |
714 | } | ||
715 | } | ||
716 | 11301 | return 0; | |
717 | } | ||
718 | |||
719 | //8.5.2.4 Derivation process for pairwise average merging candidate | ||
720 | 11301 | static int mv_merge_pairwise_candidate(MvField *cand_list, const int num_cands, const int is_b) | |
721 | { | ||
722 |
2/2✓ Branch 0 taken 10499 times.
✓ Branch 1 taken 802 times.
|
11301 | if (num_cands > 1) { |
723 |
2/2✓ Branch 0 taken 9975 times.
✓ Branch 1 taken 524 times.
|
10499 | const int num_ref_rists = is_b ? 2 : 1; |
724 | 10499 | const MvField* p0 = cand_list + 0; | |
725 | 10499 | const MvField* p1 = cand_list + 1; | |
726 | 10499 | MvField* cand = cand_list + num_cands; | |
727 | |||
728 | 10499 | cand->pred_flag = 0; | |
729 |
2/2✓ Branch 0 taken 20474 times.
✓ Branch 1 taken 10499 times.
|
30973 | for (int i = 0; i < num_ref_rists; i++) { |
730 | 20474 | PredFlag mask = i + 1; | |
731 |
2/2✓ Branch 0 taken 16838 times.
✓ Branch 1 taken 3636 times.
|
20474 | if (p0->pred_flag & mask) { |
732 | 16838 | cand->pred_flag |= mask; | |
733 | 16838 | cand->ref_idx[i] = p0->ref_idx[i]; | |
734 |
2/2✓ Branch 0 taken 14930 times.
✓ Branch 1 taken 1908 times.
|
16838 | if (p1->pred_flag & mask) { |
735 | 14930 | Mv *mv = cand->mv + i; | |
736 | 14930 | mv->x = p0->mv[i].x + p1->mv[i].x; | |
737 | 14930 | mv->y = p0->mv[i].y + p1->mv[i].y; | |
738 | 14930 | ff_vvc_round_mv(mv, 0, 1); | |
739 | } else { | ||
740 | 1908 | cand->mv[i] = p0->mv[i]; | |
741 | } | ||
742 |
2/2✓ Branch 0 taken 2170 times.
✓ Branch 1 taken 1466 times.
|
3636 | } else if (p1->pred_flag & mask) { |
743 | 2170 | cand->pred_flag |= mask; | |
744 | 2170 | cand->mv[i] = p1->mv[i]; | |
745 | 2170 | cand->ref_idx[i] = p1->ref_idx[i]; | |
746 | } | ||
747 | } | ||
748 |
1/2✓ Branch 0 taken 10499 times.
✗ Branch 1 not taken.
|
10499 | if (cand->pred_flag) { |
749 |
2/2✓ Branch 0 taken 9739 times.
✓ Branch 1 taken 760 times.
|
10499 | cand->hpel_if_idx = p0->hpel_if_idx == p1->hpel_if_idx ? p0->hpel_if_idx : 0; |
750 | 10499 | cand->bcw_idx = 0; | |
751 | 10499 | cand->ciip_flag = 0; | |
752 | 10499 | return 1; | |
753 | } | ||
754 | } | ||
755 | 802 | return 0; | |
756 | } | ||
757 | |||
758 | //8.5.2.5 Derivation process for zero motion vector merging candidates | ||
759 | 1353 | static void mv_merge_zero_motion_candidate(const VVCLocalContext *lc, const int merge_idx, | |
760 | MvField *cand_list, int num_cands) | ||
761 | { | ||
762 | 1353 | const VVCSPS *sps = lc->fc->ps.sps; | |
763 | 1353 | const H266RawSliceHeader *rsh = lc->sc->sh.r; | |
764 | 2706 | const int num_ref_idx = IS_P(rsh) ? | |
765 |
2/2✓ Branch 0 taken 210 times.
✓ Branch 1 taken 1143 times.
|
1353 | rsh->num_ref_idx_active[L0] : FFMIN(rsh->num_ref_idx_active[L0], rsh->num_ref_idx_active[L1]); |
766 | 1353 | int zero_idx = 0; | |
767 | |||
768 |
1/2✓ Branch 0 taken 2727 times.
✗ Branch 1 not taken.
|
2727 | while (num_cands < sps->max_num_merge_cand) { |
769 | 2727 | MvField *cand = cand_list + num_cands; | |
770 | |||
771 |
2/2✓ Branch 0 taken 2290 times.
✓ Branch 1 taken 437 times.
|
2727 | cand->pred_flag = PF_L0 + (IS_B(rsh) << 1); |
772 | 2727 | AV_ZERO64(cand->mv + 0); | |
773 | 2727 | AV_ZERO64(cand->mv + 1); | |
774 |
2/2✓ Branch 0 taken 2494 times.
✓ Branch 1 taken 233 times.
|
2727 | cand->ref_idx[0] = zero_idx < num_ref_idx ? zero_idx : 0; |
775 |
2/2✓ Branch 0 taken 2494 times.
✓ Branch 1 taken 233 times.
|
2727 | cand->ref_idx[1] = zero_idx < num_ref_idx ? zero_idx : 0; |
776 | 2727 | cand->bcw_idx = 0; | |
777 | 2727 | cand->hpel_if_idx = 0; | |
778 |
2/2✓ Branch 0 taken 1353 times.
✓ Branch 1 taken 1374 times.
|
2727 | if (merge_idx == num_cands) |
779 | 1353 | return; | |
780 | 1374 | num_cands++; | |
781 | 1374 | zero_idx++; | |
782 | } | ||
783 | } | ||
784 | |||
785 | 299026 | static void mv_merge_mode(const VVCLocalContext *lc, const int merge_idx, MvField *cand_list) | |
786 | { | ||
787 | 299026 | int num_cands = 0; | |
788 | 299026 | const MvField *nb_list[NUM_NBS + 1] = { NULL }; | |
789 | |||
790 |
2/2✓ Branch 1 taken 243403 times.
✓ Branch 2 taken 55623 times.
|
299026 | if (mv_merge_spatial_candidates(lc, merge_idx, nb_list, cand_list, &num_cands)) |
791 | 297673 | return; | |
792 | |||
793 |
2/2✓ Branch 1 taken 42428 times.
✓ Branch 2 taken 13195 times.
|
55623 | if (mv_merge_temporal_candidate(lc, &cand_list[num_cands])) { |
794 |
2/2✓ Branch 0 taken 20386 times.
✓ Branch 1 taken 22042 times.
|
42428 | if (merge_idx == num_cands) |
795 | 20386 | return; | |
796 | 22042 | num_cands++; | |
797 | } | ||
798 | |||
799 |
2/2✓ Branch 1 taken 23936 times.
✓ Branch 2 taken 11301 times.
|
35237 | if (mv_merge_history_candidates(lc, merge_idx, nb_list, cand_list, &num_cands)) |
800 | 23936 | return; | |
801 | |||
802 |
2/2✓ Branch 1 taken 10499 times.
✓ Branch 2 taken 802 times.
|
11301 | if (mv_merge_pairwise_candidate(cand_list, num_cands, IS_B(lc->sc->sh.r))) { |
803 |
2/2✓ Branch 0 taken 9948 times.
✓ Branch 1 taken 551 times.
|
10499 | if (merge_idx == num_cands) |
804 | 9948 | return; | |
805 | 551 | num_cands++; | |
806 | } | ||
807 | |||
808 | 1353 | mv_merge_zero_motion_candidate(lc, merge_idx, cand_list, num_cands); | |
809 | } | ||
810 | |||
811 | //8.5.2.2 Derivation process for luma motion vectors for merge mode | ||
812 | 273411 | void ff_vvc_luma_mv_merge_mode(VVCLocalContext *lc, const int merge_idx, const int ciip_flag, MvField *mv) | |
813 | { | ||
814 | 273411 | const CodingUnit *cu = lc->cu; | |
815 | MvField cand_list[MRG_MAX_NUM_CANDS]; | ||
816 | |||
817 | 273411 | ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height); | |
818 | 273411 | mv_merge_mode(lc, merge_idx, cand_list); | |
819 | 273411 | *mv = cand_list[merge_idx]; | |
820 | //ciip flag in not inhritable | ||
821 | 273411 | mv->ciip_flag = ciip_flag; | |
822 | 273411 | } | |
823 | |||
824 | //8.5.4.2 Derivation process for luma motion vectors for geometric partitioning merge mode | ||
825 | 25615 | void ff_vvc_luma_mv_merge_gpm(VVCLocalContext *lc, const int merge_gpm_idx[2], MvField *mv) | |
826 | { | ||
827 | 25615 | const CodingUnit *cu = lc->cu; | |
828 | MvField cand_list[MRG_MAX_NUM_CANDS]; | ||
829 | |||
830 | 25615 | const int idx[] = { merge_gpm_idx[0], merge_gpm_idx[1] + (merge_gpm_idx[1] >= merge_gpm_idx[0]) }; | |
831 | |||
832 | 25615 | ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height); | |
833 | 25615 | mv_merge_mode(lc, FFMAX(idx[0], idx[1]), cand_list); | |
834 | 25615 | memset(mv, 0, 2 * sizeof(*mv)); | |
835 |
2/2✓ Branch 0 taken 51230 times.
✓ Branch 1 taken 25615 times.
|
76845 | for (int i = 0; i < 2; i++) { |
836 | 51230 | int lx = idx[i] & 1; | |
837 | 51230 | int mask = lx + PF_L0; | |
838 | 51230 | MvField *cand = cand_list + idx[i]; | |
839 |
2/2✓ Branch 0 taken 13878 times.
✓ Branch 1 taken 37352 times.
|
51230 | if (!(cand->pred_flag & mask)) { |
840 | 13878 | lx = !lx; | |
841 | 13878 | mask = lx + PF_L0; | |
842 | } | ||
843 | 51230 | mv[i].pred_flag = mask; | |
844 | 51230 | mv[i].ref_idx[lx] = cand->ref_idx[lx]; | |
845 | 51230 | mv[i].mv[lx] = cand->mv[lx]; | |
846 | } | ||
847 | |||
848 | 25615 | } | |
849 | |||
850 | //8.5.5.5 Derivation process for luma affine control point motion vectors from a neighbouring block | ||
851 | 29163 | static void affine_cps_from_nb(const VVCLocalContext *lc, | |
852 | const int x_nb, int y_nb, const int nbw, const int nbh, const int lx, | ||
853 | Mv *cps, int num_cps) | ||
854 | { | ||
855 | 29163 | const VVCFrameContext *fc = lc->fc; | |
856 | 29163 | const CodingUnit *cu = lc->cu; | |
857 | 29163 | const int x0 = cu->x0; | |
858 | 29163 | const int y0 = cu->y0; | |
859 | 29163 | const int cb_width = cu->cb_width; | |
860 | 29163 | const int cb_height = cu->cb_height; | |
861 | 29163 | const MvField* tab_mvf = fc->tab.mvf; | |
862 | 29163 | const int min_cb_log2_size = fc->ps.sps->min_cb_log2_size_y; | |
863 | 29163 | const int min_cb_width = fc->ps.pps->min_cb_width; | |
864 | |||
865 | 29163 | const int log2_nbw = ff_log2(nbw); | |
866 | 29163 | const int log2_nbh = ff_log2(nbh); | |
867 |
4/4✓ Branch 0 taken 8724 times.
✓ Branch 1 taken 20439 times.
✓ Branch 2 taken 3398 times.
✓ Branch 3 taken 5326 times.
|
29163 | const int is_ctb_boundary = !((y_nb + nbh) % fc->ps.sps->ctb_size_y) && (y_nb + nbh == y0); |
868 | const Mv *l, *r; | ||
869 | int mv_scale_hor, mv_scale_ver, d_hor_x, d_ver_x, d_hor_y, d_ver_y, motion_model_idc_nb; | ||
870 |
2/2✓ Branch 0 taken 3398 times.
✓ Branch 1 taken 25765 times.
|
29163 | if (is_ctb_boundary) { |
871 | 3398 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
872 | 3398 | l = &TAB_MVF(x_nb, y_nb + nbh - 1).mv[lx]; | |
873 | 3398 | r = &TAB_MVF(x_nb + nbw - 1, y_nb + nbh - 1).mv[lx]; | |
874 | } else { | ||
875 | 25765 | const int x = x_nb >> min_cb_log2_size; | |
876 | 25765 | const int y = y_nb >> min_cb_log2_size; | |
877 | 25765 | motion_model_idc_nb = SAMPLE_CTB(fc->tab.mmi, x, y); | |
878 | |||
879 | 25765 | l = &TAB_CP_MV(lx, x_nb, y_nb); | |
880 | 25765 | r = &TAB_CP_MV(lx, x_nb + nbw - 1, y_nb) + 1; | |
881 | } | ||
882 | 29163 | mv_scale_hor = l->x * (1 << 7); | |
883 | 29163 | mv_scale_ver = l->y * (1 << 7); | |
884 | 29163 | d_hor_x = (r->x - l->x) * (1 << (7 - log2_nbw)); | |
885 | 29163 | d_ver_x = (r->y - l->y) * (1 << (7 - log2_nbw)); | |
886 |
4/4✓ Branch 0 taken 25765 times.
✓ Branch 1 taken 3398 times.
✓ Branch 2 taken 14644 times.
✓ Branch 3 taken 11121 times.
|
29163 | if (!is_ctb_boundary && motion_model_idc_nb == MOTION_6_PARAMS_AFFINE) { |
887 | 14644 | const Mv* lb = &TAB_CP_MV(lx, x_nb, y_nb + nbh - 1) + 2; | |
888 | 14644 | d_hor_y = (lb->x - l->x) * (1 << (7 - log2_nbh)); | |
889 | 14644 | d_ver_y = (lb->y - l->y) * (1 << (7 - log2_nbh)); | |
890 | } else { | ||
891 | 14519 | d_hor_y = -d_ver_x; | |
892 | 14519 | d_ver_y = d_hor_x; | |
893 | } | ||
894 | |||
895 |
2/2✓ Branch 0 taken 3398 times.
✓ Branch 1 taken 25765 times.
|
29163 | if (is_ctb_boundary) { |
896 | 3398 | y_nb = y0; | |
897 | } | ||
898 | 29163 | cps[0].x = mv_scale_hor + d_hor_x * (x0 - x_nb) + d_hor_y * (y0 - y_nb); | |
899 | 29163 | cps[0].y = mv_scale_ver + d_ver_x * (x0 - x_nb) + d_ver_y * (y0 - y_nb); | |
900 | 29163 | cps[1].x = mv_scale_hor + d_hor_x * (x0 + cb_width - x_nb) + d_hor_y * (y0 - y_nb); | |
901 | 29163 | cps[1].y = mv_scale_ver + d_ver_x * (x0 + cb_width - x_nb) + d_ver_y * (y0 - y_nb); | |
902 |
2/2✓ Branch 0 taken 16185 times.
✓ Branch 1 taken 12978 times.
|
29163 | if (num_cps == 3) { |
903 | 16185 | cps[2].x = mv_scale_hor + d_hor_x * (x0 - x_nb) + d_hor_y * (y0 + cb_height - y_nb); | |
904 | 16185 | cps[2].y = mv_scale_ver + d_ver_x * (x0 - x_nb) + d_ver_y * (y0 + cb_height - y_nb); | |
905 | } | ||
906 |
2/2✓ Branch 0 taken 74511 times.
✓ Branch 1 taken 29163 times.
|
103674 | for (int i = 0; i < num_cps; i++) { |
907 | 74511 | ff_vvc_round_mv(cps + i, 0, 7); | |
908 | 74511 | ff_vvc_clip_mv(cps + i); | |
909 | } | ||
910 | 29163 | } | |
911 | |||
912 | //derive affine neighbour's postion, width and height, | ||
913 | 92967 | static int affine_neighbour_cb(const VVCFrameContext *fc, const int x_nb, const int y_nb, int *x_cb, int *y_cb, int *cbw, int *cbh) | |
914 | { | ||
915 | 92967 | const int log2_min_cb_size = fc->ps.sps->min_cb_log2_size_y; | |
916 | 92967 | const int min_cb_width = fc->ps.pps->min_cb_width; | |
917 | 92967 | const int x = x_nb >> log2_min_cb_size; | |
918 | 92967 | const int y = y_nb >> log2_min_cb_size; | |
919 | 92967 | const int motion_model_idc = SAMPLE_CTB(fc->tab.mmi, x, y); | |
920 |
2/2✓ Branch 0 taken 26328 times.
✓ Branch 1 taken 66639 times.
|
92967 | if (motion_model_idc) { |
921 | 26328 | *x_cb = SAMPLE_CTB(fc->tab.cb_pos_x[0], x, y); | |
922 | 26328 | *y_cb = SAMPLE_CTB(fc->tab.cb_pos_y[0], x, y); | |
923 | 26328 | *cbw = SAMPLE_CTB(fc->tab.cb_width[0], x, y); | |
924 | 26328 | *cbh = SAMPLE_CTB(fc->tab.cb_height[0], x, y); | |
925 | } | ||
926 | 92967 | return motion_model_idc; | |
927 | } | ||
928 | |||
929 | //part of 8.5.5.2 Derivation process for motion vectors and reference indices in subblock merge mode | ||
930 | 63288 | static int affine_merge_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand, MotionInfo* mi) | |
931 | { | ||
932 | 63288 | const VVCFrameContext *fc = lc->fc; | |
933 | int x, y, w, h, motion_model_idc; | ||
934 | |||
935 | 63288 | motion_model_idc = affine_neighbour_cb(fc, x_cand, y_cand, &x, &y, &w, &h); | |
936 |
2/2✓ Branch 0 taken 18839 times.
✓ Branch 1 taken 44449 times.
|
63288 | if (motion_model_idc) { |
937 | 18839 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
938 | 18839 | const MvField* tab_mvf = fc->tab.mvf; | |
939 | 18839 | const MvField *mvf = &TAB_MVF(x, y); | |
940 | |||
941 | 18839 | mi->bcw_idx = mvf->bcw_idx; | |
942 | 18839 | mi->pred_flag = mvf->pred_flag; | |
943 |
2/2✓ Branch 0 taken 37678 times.
✓ Branch 1 taken 18839 times.
|
56517 | for (int i = 0; i < 2; i++) { |
944 | 37678 | PredFlag mask = i + 1; | |
945 |
2/2✓ Branch 0 taken 23264 times.
✓ Branch 1 taken 14414 times.
|
37678 | if (mi->pred_flag & mask) { |
946 | 23264 | affine_cps_from_nb(lc, x, y, w, h, i, &mi->mv[i][0], motion_model_idc + 1); | |
947 | } | ||
948 | 37678 | mi->ref_idx[i] = mvf->ref_idx[i]; | |
949 | } | ||
950 | 18839 | mi->motion_model_idc = motion_model_idc; | |
951 | } | ||
952 | 63288 | return motion_model_idc; | |
953 | } | ||
954 | |||
955 | 44229 | static int affine_merge_from_nbs(NeighbourContext *ctx, const NeighbourIdx *nbs, const int num_nbs, MotionInfo* cand) | |
956 | { | ||
957 | 44229 | const VVCLocalContext *lc = ctx->lc; | |
958 |
2/2✓ Branch 0 taken 93127 times.
✓ Branch 1 taken 25390 times.
|
118517 | for (int i = 0; i < num_nbs; i++) { |
959 | 93127 | Neighbour *n = &ctx->neighbours[nbs[i]]; | |
960 |
4/4✓ Branch 1 taken 63288 times.
✓ Branch 2 taken 29839 times.
✓ Branch 4 taken 18839 times.
✓ Branch 5 taken 44449 times.
|
93127 | if (check_available(n, lc, 1) && affine_merge_candidate(lc, n->x, n->y, cand)) |
961 | 18839 | return 1; | |
962 | } | ||
963 | 25390 | return 0; | |
964 | } | ||
965 | #define AFFINE_MERGE_FROM_NBS(nbs) affine_merge_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), mi) | ||
966 | |||
967 | |||
968 | 95426 | static const MvField* derive_corner_mvf(NeighbourContext *ctx, const NeighbourIdx *neighbour, const int num_neighbour) | |
969 | { | ||
970 | 95426 | const VVCFrameContext *fc = ctx->lc->fc; | |
971 | 95426 | const MvField *tab_mvf = fc->tab.mvf; | |
972 | 95426 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
973 |
2/2✓ Branch 0 taken 101859 times.
✓ Branch 1 taken 7203 times.
|
109062 | for (int i = 0; i < num_neighbour; i++) { |
974 | 101859 | Neighbour *n = &ctx->neighbours[neighbour[i]]; | |
975 |
2/2✓ Branch 1 taken 88223 times.
✓ Branch 2 taken 13636 times.
|
101859 | if (check_available(n, ctx->lc, 1)) { |
976 | 88223 | return &TAB_MVF(n->x, n->y); | |
977 | } | ||
978 | } | ||
979 | 7203 | return NULL; | |
980 | } | ||
981 | |||
982 | #define DERIVE_CORNER_MV(nbs) derive_corner_mvf(nctx, nbs, FF_ARRAY_ELEMS(nbs)) | ||
983 | |||
984 | // check if the mv's and refidx are the same between A and B | ||
985 | 51704 | static av_always_inline int compare_pf_ref_idx(const MvField *A, const struct MvField *B, const struct MvField *C, const int lx) | |
986 | { | ||
987 | |||
988 | 51704 | const PredFlag mask = (lx + 1) & A->pred_flag; | |
989 |
2/2✓ Branch 0 taken 18464 times.
✓ Branch 1 taken 33240 times.
|
51704 | if (!(B->pred_flag & mask)) |
990 | 18464 | return 0; | |
991 |
2/2✓ Branch 0 taken 1615 times.
✓ Branch 1 taken 31625 times.
|
33240 | if (A->ref_idx[lx] != B->ref_idx[lx]) |
992 | 1615 | return 0; | |
993 |
2/2✓ Branch 0 taken 26272 times.
✓ Branch 1 taken 5353 times.
|
31625 | if (C) { |
994 |
2/2✓ Branch 0 taken 895 times.
✓ Branch 1 taken 25377 times.
|
26272 | if (!(C->pred_flag & mask)) |
995 | 895 | return 0; | |
996 |
2/2✓ Branch 0 taken 1007 times.
✓ Branch 1 taken 24370 times.
|
25377 | if (A->ref_idx[lx] != C->ref_idx[lx]) |
997 | 1007 | return 0; | |
998 | } | ||
999 | 29723 | return 1; | |
1000 | } | ||
1001 | |||
1002 | 1254033 | static av_always_inline void sb_clip_location(const VVCLocalContext *lc, | |
1003 | const int x_ctb, const int y_ctb, const Mv* temp_mv, int *x, int *y) | ||
1004 | { | ||
1005 | 1254033 | const VVCFrameContext *fc = lc->fc; | |
1006 | 1254033 | const VVCPPS *pps = fc->ps.pps; | |
1007 | 1254033 | const int ctb_log2_size = fc->ps.sps->ctb_log2_size_y; | |
1008 | 1254033 | const int subpic_idx = lc->sc->sh.r->curr_subpic_idx; | |
1009 | 1254033 | const int x_end = pps->subpic_x[subpic_idx] + pps->subpic_width[subpic_idx]; | |
1010 | 1254033 | const int y_end = pps->subpic_y[subpic_idx] + pps->subpic_height[subpic_idx]; | |
1011 | |||
1012 | 1254033 | *x = av_clip(*x + temp_mv->x, x_ctb, FFMIN(x_end - 1, x_ctb + (1 << ctb_log2_size) + 3)) & ~7; | |
1013 |
2/2✓ Branch 0 taken 1109275 times.
✓ Branch 1 taken 144758 times.
|
1254033 | *y = av_clip(*y + temp_mv->y, y_ctb, FFMIN(y_end - 1, y_ctb + (1 << ctb_log2_size) - 1)) & ~7; |
1014 | 1254033 | } | |
1015 | |||
1016 | 1254033 | static void sb_temproal_luma_motion(const VVCLocalContext *lc, | |
1017 | const int x_ctb, const int y_ctb, const Mv *temp_mv, | ||
1018 | int x, int y, uint8_t *pred_flag, Mv *mv) | ||
1019 | { | ||
1020 | MvField temp_col; | ||
1021 | Mv* mvLXCol; | ||
1022 | 1254033 | const int refIdxLx = 0; | |
1023 | 1254033 | const VVCFrameContext *fc = lc->fc; | |
1024 | 1254033 | const VVCSH *sh = &lc->sc->sh; | |
1025 | 1254033 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
1026 | 1254033 | VVCFrame *ref = fc->ref->collocated_ref; | |
1027 | 1254033 | MvField *tab_mvf = ref->tab_dmvr_mvf; | |
1028 | 1254033 | int colPic = ref->poc; | |
1029 | 1254033 | int X = 0; | |
1030 | |||
1031 | 1254033 | sb_clip_location(lc, x_ctb, y_ctb, temp_mv, &x, &y); | |
1032 | |||
1033 | 1254033 | temp_col = TAB_MVF(x, y); | |
1034 | 1254033 | mvLXCol = mv + 0; | |
1035 | 1254033 | *pred_flag = DERIVE_TEMPORAL_COLOCATED_MVS(1); | |
1036 |
2/2✓ Branch 0 taken 907085 times.
✓ Branch 1 taken 346948 times.
|
1254033 | if (IS_B(sh->r)) { |
1037 | 907085 | X = 1; | |
1038 | 907085 | mvLXCol = mv + 1; | |
1039 | 907085 | *pred_flag |= (DERIVE_TEMPORAL_COLOCATED_MVS(1)) << 1; | |
1040 | } | ||
1041 | 1254033 | } | |
1042 | |||
1043 | //8.5.5.4 Derivation process for subblock-based temporal merging base motion data | ||
1044 | 49901 | static int sb_temporal_luma_motion_data(const VVCLocalContext *lc, const MvField *a1, | |
1045 | const int x_ctb, const int y_ctb, MvField *ctr_mvf, Mv *temp_mv) | ||
1046 | { | ||
1047 | 49901 | const VVCFrameContext *fc = lc->fc; | |
1048 | 49901 | const RefPicList *rpl = lc->sc->rpl; | |
1049 | 49901 | const CodingUnit *cu = lc->cu; | |
1050 | 49901 | const int x = cu->x0 + cu->cb_width / 2; | |
1051 | 49901 | const int y = cu->y0 + cu->cb_height / 2; | |
1052 | 49901 | const VVCFrame *ref = fc->ref->collocated_ref; | |
1053 | |||
1054 | int colPic; | ||
1055 | |||
1056 | 49901 | memset(temp_mv, 0, sizeof(*temp_mv)); | |
1057 | |||
1058 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 49901 times.
|
49901 | if (!ref) { |
1059 | ✗ | memset(ctr_mvf, 0, sizeof(*ctr_mvf)); | |
1060 | ✗ | return 0; | |
1061 | } | ||
1062 | |||
1063 | 49901 | colPic = ref->poc; | |
1064 | |||
1065 |
2/2✓ Branch 0 taken 46448 times.
✓ Branch 1 taken 3453 times.
|
49901 | if (a1) { |
1066 |
4/4✓ Branch 0 taken 42491 times.
✓ Branch 1 taken 3957 times.
✓ Branch 2 taken 29079 times.
✓ Branch 3 taken 13412 times.
|
46448 | if ((a1->pred_flag & PF_L0) && colPic == rpl[L0].refs[a1->ref_idx[L0]].poc) |
1067 | 29079 | *temp_mv = a1->mv[0]; | |
1068 |
4/4✓ Branch 0 taken 12025 times.
✓ Branch 1 taken 5344 times.
✓ Branch 2 taken 9770 times.
✓ Branch 3 taken 2255 times.
|
17369 | else if ((a1->pred_flag & PF_L1) && colPic == rpl[L1].refs[a1->ref_idx[L1]].poc) |
1069 | 9770 | *temp_mv = a1->mv[1]; | |
1070 | 46448 | ff_vvc_round_mv(temp_mv, 0, 4); | |
1071 | } | ||
1072 | 49901 | sb_temproal_luma_motion(lc, x_ctb, y_ctb, temp_mv, x, y, &ctr_mvf->pred_flag , ctr_mvf->mv); | |
1073 | |||
1074 | 49901 | return ctr_mvf->pred_flag; | |
1075 | } | ||
1076 | |||
1077 | |||
1078 | //8.5.5.3 Derivation process for subblock-based temporal merging candidates | ||
1079 | 50089 | static int sb_temporal_merge_candidate(const VVCLocalContext* lc, NeighbourContext *nctx, PredictionUnit *pu) | |
1080 | { | ||
1081 | 50089 | const VVCFrameContext *fc = lc->fc; | |
1082 | 50089 | const CodingUnit *cu = lc->cu; | |
1083 | 50089 | const VVCSPS *sps = fc->ps.sps; | |
1084 | 50089 | const VVCPH *ph = &fc->ps.ph; | |
1085 | 50089 | MotionInfo *mi = &pu->mi; | |
1086 | 50089 | const int ctb_log2_size = sps->ctb_log2_size_y; | |
1087 | 50089 | const int x0 = cu->x0; | |
1088 | 50089 | const int y0 = cu->y0; | |
1089 | 50089 | const NeighbourIdx n = A1; | |
1090 | const MvField *a1; | ||
1091 | MvField ctr_mvf; | ||
1092 | 50089 | LOCAL_ALIGNED_8(Mv, temp_mv, [1]); | |
1093 | 50089 | const int x_ctb = (x0 >> ctb_log2_size) << ctb_log2_size; | |
1094 | 50089 | const int y_ctb = (y0 >> ctb_log2_size) << ctb_log2_size; | |
1095 | |||
1096 | |||
1097 |
2/2✓ Branch 0 taken 50002 times.
✓ Branch 1 taken 87 times.
|
50089 | if (!ph->r->ph_temporal_mvp_enabled_flag || |
1098 |
2/2✓ Branch 0 taken 49901 times.
✓ Branch 1 taken 101 times.
|
50002 | !sps->r->sps_sbtmvp_enabled_flag || |
1099 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 49901 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
49901 | (cu->cb_width < 8 && cu->cb_height < 8)) |
1100 | 188 | return 0; | |
1101 | |||
1102 | 49901 | mi->num_sb_x = cu->cb_width >> 3; | |
1103 | 49901 | mi->num_sb_y = cu->cb_height >> 3; | |
1104 | |||
1105 | 49901 | a1 = derive_corner_mvf(nctx, &n, 1); | |
1106 |
2/2✓ Branch 1 taken 41932 times.
✓ Branch 2 taken 7969 times.
|
49901 | if (sb_temporal_luma_motion_data(lc, a1, x_ctb, y_ctb, &ctr_mvf, temp_mv)) { |
1107 | 41932 | const int sbw = cu->cb_width / mi->num_sb_x; | |
1108 | 41932 | const int sbh = cu->cb_height / mi->num_sb_y; | |
1109 | 41932 | MvField mvf = {0}; | |
1110 |
2/2✓ Branch 0 taken 172498 times.
✓ Branch 1 taken 41932 times.
|
214430 | for (int sby = 0; sby < mi->num_sb_y; sby++) { |
1111 |
2/2✓ Branch 0 taken 1204132 times.
✓ Branch 1 taken 172498 times.
|
1376630 | for (int sbx = 0; sbx < mi->num_sb_x; sbx++) { |
1112 | 1204132 | int x = x0 + sbx * sbw; | |
1113 | 1204132 | int y = y0 + sby * sbh; | |
1114 | 1204132 | sb_temproal_luma_motion(lc, x_ctb, y_ctb, temp_mv, x + sbw / 2, y + sbh / 2, &mvf.pred_flag, mvf.mv); | |
1115 |
2/2✓ Branch 0 taken 7496 times.
✓ Branch 1 taken 1196636 times.
|
1204132 | if (!mvf.pred_flag) { |
1116 | 7496 | mvf.pred_flag = ctr_mvf.pred_flag; | |
1117 | 7496 | memcpy(mvf.mv, ctr_mvf.mv, sizeof(mvf.mv)); | |
1118 | } | ||
1119 | 1204132 | ff_vvc_set_mvf(lc, x, y, sbw, sbh, &mvf); | |
1120 | } | ||
1121 | } | ||
1122 | 41932 | return 1; | |
1123 | } | ||
1124 | 7969 | return 0; | |
1125 | } | ||
1126 | |||
1127 | 13909 | static int affine_merge_const1(const MvField *c0, const MvField *c1, const MvField *c2, MotionInfo *mi) | |
1128 | { | ||
1129 |
6/6✓ Branch 0 taken 13844 times.
✓ Branch 1 taken 65 times.
✓ Branch 2 taken 13220 times.
✓ Branch 3 taken 624 times.
✓ Branch 4 taken 12719 times.
✓ Branch 5 taken 501 times.
|
13909 | if (c0 && c1 && c2) { |
1130 | 12719 | mi->pred_flag = 0; | |
1131 |
2/2✓ Branch 0 taken 25438 times.
✓ Branch 1 taken 12719 times.
|
38157 | for (int i = 0; i < 2; i++) { |
1132 | 25438 | PredFlag mask = i + 1; | |
1133 |
2/2✓ Branch 1 taken 14958 times.
✓ Branch 2 taken 10480 times.
|
25438 | if (compare_pf_ref_idx(c0, c1, c2, i)) { |
1134 | 14958 | mi->pred_flag |= mask; | |
1135 | 14958 | mi->ref_idx[i] = c0->ref_idx[i]; | |
1136 | 14958 | mi->mv[i][0] = c0->mv[i]; | |
1137 | 14958 | mi->mv[i][1] = c1->mv[i]; | |
1138 | 14958 | mi->mv[i][2] = c2->mv[i]; | |
1139 | } | ||
1140 | } | ||
1141 |
2/2✓ Branch 0 taken 11780 times.
✓ Branch 1 taken 939 times.
|
12719 | if (mi->pred_flag) { |
1142 |
2/2✓ Branch 0 taken 3178 times.
✓ Branch 1 taken 8602 times.
|
11780 | if (mi->pred_flag == PF_BI) |
1143 | 3178 | mi->bcw_idx = c0->bcw_idx; | |
1144 | 11780 | mi->motion_model_idc = MOTION_6_PARAMS_AFFINE; | |
1145 | 11780 | return 1; | |
1146 | } | ||
1147 | } | ||
1148 | 2129 | return 0; | |
1149 | } | ||
1150 | |||
1151 | 7375 | static int affine_merge_const2(const MvField *c0, const MvField *c1, const MvField *c3, MotionInfo *mi) | |
1152 | { | ||
1153 |
6/6✓ Branch 0 taken 7310 times.
✓ Branch 1 taken 65 times.
✓ Branch 2 taken 6686 times.
✓ Branch 3 taken 624 times.
✓ Branch 4 taken 4527 times.
✓ Branch 5 taken 2159 times.
|
7375 | if (c0 && c1 && c3) { |
1154 | 4527 | mi->pred_flag = 0; | |
1155 |
2/2✓ Branch 0 taken 9054 times.
✓ Branch 1 taken 4527 times.
|
13581 | for (int i = 0; i < 2; i++) { |
1156 | 9054 | PredFlag mask = i + 1; | |
1157 |
2/2✓ Branch 1 taken 5328 times.
✓ Branch 2 taken 3726 times.
|
9054 | if (compare_pf_ref_idx(c0, c1, c3, i)) { |
1158 | 5328 | mi->pred_flag |= mask; | |
1159 | 5328 | mi->ref_idx[i] = c0->ref_idx[i]; | |
1160 | 5328 | mi->mv[i][0] = c0->mv[i]; | |
1161 | 5328 | mi->mv[i][1] = c1->mv[i]; | |
1162 | 5328 | mi->mv[i][2].x = c3->mv[i].x + c0->mv[i].x - c1->mv[i].x; | |
1163 | 5328 | mi->mv[i][2].y = c3->mv[i].y + c0->mv[i].y - c1->mv[i].y; | |
1164 | 5328 | ff_vvc_clip_mv(&mi->mv[i][2]); | |
1165 | } | ||
1166 | } | ||
1167 |
2/2✓ Branch 0 taken 3960 times.
✓ Branch 1 taken 567 times.
|
4527 | if (mi->pred_flag) { |
1168 |
2/2✓ Branch 0 taken 1368 times.
✓ Branch 1 taken 2592 times.
|
3960 | mi->bcw_idx = mi->pred_flag == PF_BI ? c0->bcw_idx : 0; |
1169 | 3960 | mi->motion_model_idc = MOTION_6_PARAMS_AFFINE; | |
1170 | 3960 | return 1; | |
1171 | } | ||
1172 | } | ||
1173 | 3415 | return 0; | |
1174 | } | ||
1175 | |||
1176 | 5293 | static int affine_merge_const3(const MvField *c0, const MvField *c2, const MvField *c3, MotionInfo *mi) | |
1177 | { | ||
1178 |
6/6✓ Branch 0 taken 5228 times.
✓ Branch 1 taken 65 times.
✓ Branch 2 taken 4910 times.
✓ Branch 3 taken 318 times.
✓ Branch 4 taken 2767 times.
✓ Branch 5 taken 2143 times.
|
5293 | if (c0 && c2 && c3) { |
1179 | 2767 | mi->pred_flag = 0; | |
1180 |
2/2✓ Branch 0 taken 5534 times.
✓ Branch 1 taken 2767 times.
|
8301 | for (int i = 0; i < 2; i++) { |
1181 | 5534 | PredFlag mask = i + 1; | |
1182 |
2/2✓ Branch 1 taken 3172 times.
✓ Branch 2 taken 2362 times.
|
5534 | if (compare_pf_ref_idx(c0, c2, c3, i)) { |
1183 | 3172 | mi->pred_flag |= mask; | |
1184 | 3172 | mi->ref_idx[i] = c0->ref_idx[i]; | |
1185 | 3172 | mi->mv[i][0] = c0->mv[i]; | |
1186 | 3172 | mi->mv[i][1].x = c3->mv[i].x + c0->mv[i].x - c2->mv[i].x; | |
1187 | 3172 | mi->mv[i][1].y = c3->mv[i].y + c0->mv[i].y - c2->mv[i].y; | |
1188 | 3172 | ff_vvc_clip_mv(&mi->mv[i][1]); | |
1189 | 3172 | mi->mv[i][2] = c2->mv[i]; | |
1190 | } | ||
1191 | } | ||
1192 |
2/2✓ Branch 0 taken 2347 times.
✓ Branch 1 taken 420 times.
|
2767 | if (mi->pred_flag) { |
1193 |
2/2✓ Branch 0 taken 825 times.
✓ Branch 1 taken 1522 times.
|
2347 | mi->bcw_idx = mi->pred_flag == PF_BI ? c0->bcw_idx : 0; |
1194 | 2347 | mi->motion_model_idc = MOTION_6_PARAMS_AFFINE; | |
1195 | 2347 | return 1; | |
1196 | } | ||
1197 | } | ||
1198 | 2946 | return 0; | |
1199 | } | ||
1200 | |||
1201 | 3706 | static int affine_merge_const4(const MvField *c1, const MvField *c2, const MvField *c3, MotionInfo *mi) | |
1202 | { | ||
1203 |
6/6✓ Branch 0 taken 3311 times.
✓ Branch 1 taken 395 times.
✓ Branch 2 taken 2999 times.
✓ Branch 3 taken 312 times.
✓ Branch 4 taken 1061 times.
✓ Branch 5 taken 1938 times.
|
3706 | if (c1 && c2 && c3) { |
1204 | 1061 | mi->pred_flag = 0; | |
1205 |
2/2✓ Branch 0 taken 2122 times.
✓ Branch 1 taken 1061 times.
|
3183 | for (int i = 0; i < 2; i++) { |
1206 | 2122 | PredFlag mask = i + 1; | |
1207 |
2/2✓ Branch 1 taken 912 times.
✓ Branch 2 taken 1210 times.
|
2122 | if (compare_pf_ref_idx(c1, c2, c3, i)) { |
1208 | 912 | mi->pred_flag |= mask; | |
1209 | 912 | mi->ref_idx[i] = c1->ref_idx[i]; | |
1210 | 912 | mi->mv[i][0].x = c1->mv[i].x + c2->mv[i].x - c3->mv[i].x; | |
1211 | 912 | mi->mv[i][0].y = c1->mv[i].y + c2->mv[i].y - c3->mv[i].y; | |
1212 | 912 | ff_vvc_clip_mv(&mi->mv[i][0]); | |
1213 | 912 | mi->mv[i][1] = c1->mv[i]; | |
1214 | 912 | mi->mv[i][2] = c2->mv[i]; | |
1215 | } | ||
1216 | } | ||
1217 |
2/2✓ Branch 0 taken 670 times.
✓ Branch 1 taken 391 times.
|
1061 | if (mi->pred_flag) { |
1218 |
2/2✓ Branch 0 taken 242 times.
✓ Branch 1 taken 428 times.
|
670 | mi->bcw_idx = mi->pred_flag == PF_BI ? c1->bcw_idx : 0; |
1219 | 670 | mi->motion_model_idc = MOTION_6_PARAMS_AFFINE; | |
1220 | 670 | return 1; | |
1221 | } | ||
1222 | } | ||
1223 | 3036 | return 0; | |
1224 | } | ||
1225 | |||
1226 | 4347 | static int affine_merge_const5(const MvField *c0, const MvField *c1, MotionInfo *mi) | |
1227 | { | ||
1228 |
4/4✓ Branch 0 taken 3589 times.
✓ Branch 1 taken 758 times.
✓ Branch 2 taken 3000 times.
✓ Branch 3 taken 589 times.
|
4347 | if (c0 && c1) { |
1229 | 3000 | mi->pred_flag = 0; | |
1230 |
2/2✓ Branch 0 taken 6000 times.
✓ Branch 1 taken 3000 times.
|
9000 | for (int i = 0; i < 2; i++) { |
1231 | 6000 | PredFlag mask = i + 1; | |
1232 |
2/2✓ Branch 1 taken 3316 times.
✓ Branch 2 taken 2684 times.
|
6000 | if (compare_pf_ref_idx(c0, c1, NULL, i)) { |
1233 | 3316 | mi->pred_flag |= mask; | |
1234 | 3316 | mi->ref_idx[i] = c0->ref_idx[i]; | |
1235 | 3316 | mi->mv[i][0] = c0->mv[i]; | |
1236 | 3316 | mi->mv[i][1] = c1->mv[i]; | |
1237 | } | ||
1238 | } | ||
1239 |
2/2✓ Branch 0 taken 2623 times.
✓ Branch 1 taken 377 times.
|
3000 | if (mi->pred_flag) { |
1240 |
2/2✓ Branch 0 taken 693 times.
✓ Branch 1 taken 1930 times.
|
2623 | if (mi->pred_flag == PF_BI) |
1241 | 693 | mi->bcw_idx = c0->bcw_idx; | |
1242 | 2623 | mi->motion_model_idc = MOTION_4_PARAMS_AFFINE; | |
1243 | 2623 | return 1; | |
1244 | } | ||
1245 | } | ||
1246 | 1724 | return 0; | |
1247 | } | ||
1248 | |||
1249 | 2837 | static int affine_merge_const6(const MvField* c0, const MvField* c2, const int cb_width, const int cb_height, MotionInfo *mi) | |
1250 | { | ||
1251 |
4/4✓ Branch 0 taken 2079 times.
✓ Branch 1 taken 758 times.
✓ Branch 2 taken 1778 times.
✓ Branch 3 taken 301 times.
|
2837 | if (c0 && c2) { |
1252 | 1778 | const int shift = 7 + av_log2(cb_width) - av_log2(cb_height); | |
1253 | 1778 | mi->pred_flag = 0; | |
1254 |
2/2✓ Branch 0 taken 3556 times.
✓ Branch 1 taken 1778 times.
|
5334 | for (int i = 0; i < 2; i++) { |
1255 | 3556 | PredFlag mask = i + 1; | |
1256 |
2/2✓ Branch 1 taken 2037 times.
✓ Branch 2 taken 1519 times.
|
3556 | if (compare_pf_ref_idx(c0, c2, NULL, i)) { |
1257 | 2037 | mi->pred_flag |= mask; | |
1258 | 2037 | mi->ref_idx[i] = c0->ref_idx[i]; | |
1259 | 2037 | mi->mv[i][0] = c0->mv[i]; | |
1260 | 2037 | mi->mv[i][1].x = (c0->mv[i].x * (1 << 7)) + ((c2->mv[i].y - c0->mv[i].y) * (1 << shift)); | |
1261 | 2037 | mi->mv[i][1].y = (c0->mv[i].y * (1 << 7)) - ((c2->mv[i].x - c0->mv[i].x) * (1 << shift)); | |
1262 | 2037 | ff_vvc_round_mv(&mi->mv[i][1], 0, 7); | |
1263 | 2037 | ff_vvc_clip_mv(&mi->mv[i][1]); | |
1264 | } | ||
1265 | } | ||
1266 |
2/2✓ Branch 0 taken 1606 times.
✓ Branch 1 taken 172 times.
|
1778 | if (mi->pred_flag) { |
1267 |
2/2✓ Branch 0 taken 431 times.
✓ Branch 1 taken 1175 times.
|
1606 | if (mi->pred_flag == PF_BI) |
1268 | 431 | mi->bcw_idx = c0->bcw_idx; | |
1269 | 1606 | mi->motion_model_idc = MOTION_4_PARAMS_AFFINE; | |
1270 | 1606 | return 1; | |
1271 | } | ||
1272 | } | ||
1273 | 1231 | return 0; | |
1274 | } | ||
1275 | |||
1276 | 1661 | static void affine_merge_zero_motion(const VVCLocalContext *lc, MotionInfo *mi) | |
1277 | { | ||
1278 | 1661 | const CodingUnit *cu = lc->cu; | |
1279 | |||
1280 | 1661 | memset(mi, 0, sizeof(*mi)); | |
1281 |
2/2✓ Branch 0 taken 1207 times.
✓ Branch 1 taken 454 times.
|
1661 | mi->pred_flag = PF_L0 + (IS_B(lc->sc->sh.r) << 1); |
1282 | 1661 | mi->motion_model_idc = MOTION_4_PARAMS_AFFINE; | |
1283 | 1661 | mi->num_sb_x = cu->cb_width >> MIN_PU_LOG2; | |
1284 | 1661 | mi->num_sb_y = cu->cb_height >> MIN_PU_LOG2; | |
1285 | 1661 | } | |
1286 | |||
1287 | //8.5.5.6 Derivation process for constructed affine control point motion vector merging candidates | ||
1288 | 15175 | static int affine_merge_const_candidates(const VVCLocalContext *lc, MotionInfo *mi, | |
1289 | NeighbourContext *nctx, const int merge_subblock_idx, int num_cands) | ||
1290 | { | ||
1291 | 15175 | const VVCFrameContext *fc = lc->fc; | |
1292 | 15175 | const CodingUnit *cu = lc->cu; | |
1293 | 15175 | const NeighbourIdx tl[] = { B2, B3, A2 }; | |
1294 | 15175 | const NeighbourIdx tr[] = { B1, B0}; | |
1295 | 15175 | const NeighbourIdx bl[] = { A1, A0}; | |
1296 | const MvField *c0, *c1, *c2; | ||
1297 | |||
1298 | 15175 | c0 = DERIVE_CORNER_MV(tl); | |
1299 | 15175 | c1 = DERIVE_CORNER_MV(tr); | |
1300 | 15175 | c2 = DERIVE_CORNER_MV(bl); | |
1301 | |||
1302 |
2/2✓ Branch 0 taken 13909 times.
✓ Branch 1 taken 1266 times.
|
15175 | if (fc->ps.sps->r->sps_6param_affine_enabled_flag) { |
1303 | 13909 | MvField corner3, *c3 = NULL; | |
1304 | //Const1 | ||
1305 |
2/2✓ Branch 1 taken 11780 times.
✓ Branch 2 taken 2129 times.
|
13909 | if (affine_merge_const1(c0, c1, c2, mi)) { |
1306 |
2/2✓ Branch 0 taken 6534 times.
✓ Branch 1 taken 5246 times.
|
11780 | if (merge_subblock_idx == num_cands) |
1307 | 10828 | return 1; | |
1308 | 5246 | num_cands++; | |
1309 | } | ||
1310 | |||
1311 | 7375 | memset(&corner3, 0, sizeof(corner3)); | |
1312 |
2/2✓ Branch 0 taken 7349 times.
✓ Branch 1 taken 26 times.
|
7375 | if (fc->ps.ph.r->ph_temporal_mvp_enabled_flag){ |
1313 | 7349 | const int available_l0 = temporal_luma_motion_vector(lc, 0, corner3.mv + 0, 0, 0, 0); | |
1314 | 14698 | const int available_l1 = (lc->sc->sh.r->sh_slice_type == VVC_SLICE_TYPE_B) ? | |
1315 |
2/2✓ Branch 0 taken 5925 times.
✓ Branch 1 taken 1424 times.
|
7349 | temporal_luma_motion_vector(lc, 0, corner3.mv + 1, 1, 0, 0) : 0; |
1316 | |||
1317 | 7349 | corner3.pred_flag = available_l0 + (available_l1 << 1); | |
1318 |
2/2✓ Branch 0 taken 4961 times.
✓ Branch 1 taken 2388 times.
|
7349 | if (corner3.pred_flag) |
1319 | 4961 | c3 = &corner3; | |
1320 | } | ||
1321 | |||
1322 | //Const2 | ||
1323 |
2/2✓ Branch 1 taken 3960 times.
✓ Branch 2 taken 3415 times.
|
7375 | if (affine_merge_const2(c0, c1, c3, mi)) { |
1324 |
2/2✓ Branch 0 taken 2082 times.
✓ Branch 1 taken 1878 times.
|
3960 | if (merge_subblock_idx == num_cands) |
1325 | 2082 | return 1; | |
1326 | 1878 | num_cands++; | |
1327 | } | ||
1328 | |||
1329 | //Const3 | ||
1330 |
2/2✓ Branch 1 taken 2347 times.
✓ Branch 2 taken 2946 times.
|
5293 | if (affine_merge_const3(c0, c2, c3, mi)) { |
1331 |
2/2✓ Branch 0 taken 1587 times.
✓ Branch 1 taken 760 times.
|
2347 | if (merge_subblock_idx == num_cands) |
1332 | 1587 | return 1; | |
1333 | 760 | num_cands++; | |
1334 | } | ||
1335 | |||
1336 | //Const4 | ||
1337 |
2/2✓ Branch 1 taken 670 times.
✓ Branch 2 taken 3036 times.
|
3706 | if (affine_merge_const4(c1, c2, c3, mi)) { |
1338 |
2/2✓ Branch 0 taken 625 times.
✓ Branch 1 taken 45 times.
|
670 | if (merge_subblock_idx == num_cands) |
1339 | 625 | return 1; | |
1340 | 45 | num_cands++; | |
1341 | } | ||
1342 | } | ||
1343 | |||
1344 | //Const5 | ||
1345 |
2/2✓ Branch 1 taken 2623 times.
✓ Branch 2 taken 1724 times.
|
4347 | if (affine_merge_const5(c0, c1, mi)) { |
1346 |
2/2✓ Branch 0 taken 1510 times.
✓ Branch 1 taken 1113 times.
|
2623 | if (merge_subblock_idx == num_cands) |
1347 | 1510 | return 1; | |
1348 | 1113 | num_cands++; | |
1349 | } | ||
1350 | |||
1351 |
2/2✓ Branch 1 taken 1606 times.
✓ Branch 2 taken 1231 times.
|
2837 | if (affine_merge_const6(c0, c2, cu->cb_width, cu->cb_height, mi)) { |
1352 |
2/2✓ Branch 0 taken 1176 times.
✓ Branch 1 taken 430 times.
|
1606 | if (merge_subblock_idx == num_cands) |
1353 | 1176 | return 1; | |
1354 | } | ||
1355 | 1661 | return 0; | |
1356 | } | ||
1357 | |||
1358 | //8.5.5.2 Derivation process for motion vectors and reference indices in subblock merge mode | ||
1359 | //return 1 if candidate is SbCol | ||
1360 | 50089 | static int sb_mv_merge_mode(const VVCLocalContext *lc, const int merge_subblock_idx, PredictionUnit *pu) | |
1361 | { | ||
1362 | 50089 | const VVCSPS *sps = lc->fc->ps.sps; | |
1363 | 50089 | const CodingUnit *cu = lc->cu; | |
1364 | 50089 | MotionInfo *mi = &pu->mi; | |
1365 | 50089 | int num_cands = 0; | |
1366 | NeighbourContext nctx; | ||
1367 | |||
1368 | 50089 | init_neighbour_context(&nctx, lc); | |
1369 | |||
1370 | //SbCol | ||
1371 |
2/2✓ Branch 1 taken 41932 times.
✓ Branch 2 taken 8157 times.
|
50089 | if (sb_temporal_merge_candidate(lc, &nctx, pu)) { |
1372 |
2/2✓ Branch 0 taken 25313 times.
✓ Branch 1 taken 16619 times.
|
41932 | if (merge_subblock_idx == num_cands) |
1373 | 25313 | return 1; | |
1374 | 16619 | num_cands++; | |
1375 | } | ||
1376 | |||
1377 | 24776 | pu->inter_affine_flag = 1; | |
1378 | 24776 | mi->num_sb_x = cu->cb_width >> MIN_PU_LOG2; | |
1379 | 24776 | mi->num_sb_y = cu->cb_height >> MIN_PU_LOG2; | |
1380 | |||
1381 |
1/2✓ Branch 0 taken 24776 times.
✗ Branch 1 not taken.
|
24776 | if (sps->r->sps_affine_enabled_flag) { |
1382 | 24776 | const NeighbourIdx ak[] = { A0, A1 }; | |
1383 | 24776 | const NeighbourIdx bk[] = { B0, B1, B2 }; | |
1384 | //A | ||
1385 |
2/2✓ Branch 1 taken 9737 times.
✓ Branch 2 taken 15039 times.
|
24776 | if (AFFINE_MERGE_FROM_NBS(ak)) { |
1386 |
2/2✓ Branch 0 taken 5323 times.
✓ Branch 1 taken 4414 times.
|
9737 | if (merge_subblock_idx == num_cands) |
1387 | 23115 | return 0; | |
1388 | 4414 | num_cands++; | |
1389 | } | ||
1390 | |||
1391 | //B | ||
1392 |
2/2✓ Branch 1 taken 9102 times.
✓ Branch 2 taken 10351 times.
|
19453 | if (AFFINE_MERGE_FROM_NBS(bk)) { |
1393 |
2/2✓ Branch 0 taken 4278 times.
✓ Branch 1 taken 4824 times.
|
9102 | if (merge_subblock_idx == num_cands) |
1394 | 4278 | return 0; | |
1395 | 4824 | num_cands++; | |
1396 | } | ||
1397 | |||
1398 | //Const1 to Const6 | ||
1399 |
2/2✓ Branch 1 taken 13514 times.
✓ Branch 2 taken 1661 times.
|
15175 | if (affine_merge_const_candidates(lc, mi, &nctx, merge_subblock_idx, num_cands)) |
1400 | 13514 | return 0; | |
1401 | } | ||
1402 | //Zero | ||
1403 | 1661 | affine_merge_zero_motion(lc, mi); | |
1404 | 1661 | return 0; | |
1405 | } | ||
1406 | |||
1407 | 50089 | void ff_vvc_sb_mv_merge_mode(VVCLocalContext *lc, const int merge_subblock_idx, PredictionUnit *pu) | |
1408 | { | ||
1409 | 50089 | const CodingUnit *cu = lc->cu; | |
1410 | 50089 | ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height); | |
1411 |
2/2✓ Branch 1 taken 24776 times.
✓ Branch 2 taken 25313 times.
|
50089 | if (!sb_mv_merge_mode(lc, merge_subblock_idx, pu)) { |
1412 | 24776 | ff_vvc_store_sb_mvs(lc, pu); | |
1413 | } | ||
1414 | 50089 | } | |
1415 | |||
1416 | 137853 | static int mvp_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand, | |
1417 | const int lx, const int8_t *ref_idx, Mv *mv) | ||
1418 | { | ||
1419 | 137853 | const VVCFrameContext *fc = lc->fc; | |
1420 | 137853 | const RefPicList *rpl = lc->sc->rpl; | |
1421 | 137853 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
1422 | 137853 | const MvField* tab_mvf = fc->tab.mvf; | |
1423 | 137853 | const MvField *mvf = &TAB_MVF(x_cand, y_cand); | |
1424 | 137853 | const PredFlag maskx = lx + 1; | |
1425 | 137853 | const int poc = rpl[lx].refs[ref_idx[lx]].poc; | |
1426 | 137853 | int available = 0; | |
1427 | |||
1428 |
4/4✓ Branch 0 taken 106839 times.
✓ Branch 1 taken 31014 times.
✓ Branch 2 taken 72038 times.
✓ Branch 3 taken 34801 times.
|
137853 | if ((mvf->pred_flag & maskx) && rpl[lx].refs[mvf->ref_idx[lx]].poc == poc) { |
1429 | 72038 | available = 1; | |
1430 | 72038 | *mv = mvf->mv[lx]; | |
1431 | } else { | ||
1432 | 65815 | const int ly = !lx; | |
1433 | 65815 | const PredFlag masky = ly + 1; | |
1434 |
4/4✓ Branch 0 taken 44824 times.
✓ Branch 1 taken 20991 times.
✓ Branch 2 taken 10165 times.
✓ Branch 3 taken 34659 times.
|
65815 | if ((mvf->pred_flag & masky) && rpl[ly].refs[mvf->ref_idx[ly]].poc == poc) { |
1435 | 10165 | available = 1; | |
1436 | 10165 | *mv = mvf->mv[ly]; | |
1437 | } | ||
1438 | } | ||
1439 | |||
1440 | 137853 | return available; | |
1441 | } | ||
1442 | |||
1443 | 29679 | static int affine_mvp_candidate(const VVCLocalContext *lc, | |
1444 | const int x_cand, const int y_cand, const int lx, const int8_t *ref_idx, | ||
1445 | Mv *cps, const int num_cp) | ||
1446 | { | ||
1447 | 29679 | const VVCFrameContext *fc = lc->fc; | |
1448 | 29679 | int x_nb, y_nb, nbw, nbh, motion_model_idc, available = 0; | |
1449 | |||
1450 | 29679 | motion_model_idc = affine_neighbour_cb(fc, x_cand, y_cand, &x_nb, &y_nb, &nbw, &nbh); | |
1451 |
2/2✓ Branch 0 taken 7489 times.
✓ Branch 1 taken 22190 times.
|
29679 | if (motion_model_idc) { |
1452 | 7489 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
1453 | 7489 | const MvField* tab_mvf = fc->tab.mvf; | |
1454 | 7489 | const MvField *mvf = &TAB_MVF(x_nb, y_nb); | |
1455 | 7489 | RefPicList* rpl = lc->sc->rpl; | |
1456 | 7489 | const PredFlag maskx = lx + 1; | |
1457 | 7489 | const int poc = rpl[lx].refs[ref_idx[lx]].poc; | |
1458 | |||
1459 |
4/4✓ Branch 0 taken 6315 times.
✓ Branch 1 taken 1174 times.
✓ Branch 2 taken 5145 times.
✓ Branch 3 taken 1170 times.
|
7489 | if ((mvf->pred_flag & maskx) && rpl[lx].refs[mvf->ref_idx[lx]].poc == poc) { |
1460 | 5145 | available = 1; | |
1461 | 5145 | affine_cps_from_nb(lc, x_nb, y_nb, nbw, nbh, lx, cps, num_cp); | |
1462 | } else { | ||
1463 | 2344 | const int ly = !lx; | |
1464 | 2344 | const PredFlag masky = ly + 1; | |
1465 |
4/4✓ Branch 0 taken 1522 times.
✓ Branch 1 taken 822 times.
✓ Branch 2 taken 754 times.
✓ Branch 3 taken 768 times.
|
2344 | if ((mvf->pred_flag & masky) && rpl[ly].refs[mvf->ref_idx[ly]].poc == poc) { |
1466 | 754 | available = 1; | |
1467 | 754 | affine_cps_from_nb(lc, x_nb, y_nb, nbw, nbh, ly, cps, num_cp); | |
1468 | } | ||
1469 | } | ||
1470 | |||
1471 | } | ||
1472 | 29679 | return available; | |
1473 | } | ||
1474 | |||
1475 | 159161 | static int mvp_from_nbs(NeighbourContext *ctx, | |
1476 | const NeighbourIdx *nbs, const int num_nbs, const int lx, const int8_t *ref_idx, const int amvr_shift, | ||
1477 | Mv *cps, const int num_cps) | ||
1478 | { | ||
1479 | 159161 | const VVCLocalContext *lc = ctx->lc; | |
1480 | 159161 | int available = 0; | |
1481 | |||
1482 |
2/2✓ Branch 0 taken 314623 times.
✓ Branch 1 taken 71059 times.
|
385682 | for (int i = 0; i < num_nbs; i++) { |
1483 | 314623 | Neighbour *n = &ctx->neighbours[nbs[i]]; | |
1484 |
2/2✓ Branch 1 taken 167532 times.
✓ Branch 2 taken 147091 times.
|
314623 | if (check_available(n, lc, 0)) { |
1485 |
2/2✓ Branch 0 taken 29679 times.
✓ Branch 1 taken 137853 times.
|
167532 | if (num_cps > 1) |
1486 | 29679 | available = affine_mvp_candidate(lc, n->x, n->y, lx, ref_idx, cps, num_cps); | |
1487 | else | ||
1488 | 137853 | available = mvp_candidate(lc, n->x, n->y, lx, ref_idx, cps); | |
1489 |
2/2✓ Branch 0 taken 88102 times.
✓ Branch 1 taken 79430 times.
|
167532 | if (available) { |
1490 |
2/2✓ Branch 0 taken 96915 times.
✓ Branch 1 taken 88102 times.
|
185017 | for (int c = 0; c < num_cps; c++) |
1491 | 96915 | ff_vvc_round_mv(cps + c, amvr_shift, amvr_shift); | |
1492 | 88102 | return 1; | |
1493 | } | ||
1494 | } | ||
1495 | } | ||
1496 | 71059 | return 0; | |
1497 | } | ||
1498 | |||
1499 | //get mvp from neighbours | ||
1500 | #define AFFINE_MVP_FROM_NBS(nbs) \ | ||
1501 | mvp_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), lx, ref_idx, amvr_shift, cps, num_cp) \ | ||
1502 | |||
1503 | #define MVP_FROM_NBS(nbs) \ | ||
1504 | mvp_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), lx, ref_idx, amvr_shift, mv, 1) \ | ||
1505 | |||
1506 | 83359 | static int mvp_spatial_candidates(const VVCLocalContext *lc, | |
1507 | const int mvp_lx_flag, const int lx, const int8_t* ref_idx, const int amvr_shift, | ||
1508 | Mv* mv, int *nb_merge_cand) | ||
1509 | { | ||
1510 | 83359 | const NeighbourIdx ak[] = { A0, A1 }; | |
1511 | 83359 | const NeighbourIdx bk[] = { B0, B1, B2 }; | |
1512 | NeighbourContext nctx; | ||
1513 | 83359 | int available_a, num_cands = 0; | |
1514 | 83359 | LOCAL_ALIGNED_8(Mv, mv_a, [1]); | |
1515 | |||
1516 | 83359 | init_neighbour_context(&nctx, lc); | |
1517 | |||
1518 | 83359 | available_a = MVP_FROM_NBS(ak); | |
1519 |
2/2✓ Branch 0 taken 49764 times.
✓ Branch 1 taken 33595 times.
|
83359 | if (available_a) { |
1520 |
2/2✓ Branch 0 taken 29899 times.
✓ Branch 1 taken 19865 times.
|
49764 | if (mvp_lx_flag == num_cands) |
1521 | 29899 | return 1; | |
1522 | 19865 | num_cands++; | |
1523 | 19865 | *mv_a = *mv; | |
1524 | } | ||
1525 |
2/2✓ Branch 1 taken 32439 times.
✓ Branch 2 taken 21021 times.
|
53460 | if (MVP_FROM_NBS(bk)) { |
1526 |
4/4✓ Branch 0 taken 17126 times.
✓ Branch 1 taken 15313 times.
✓ Branch 2 taken 14397 times.
✓ Branch 3 taken 2729 times.
|
32439 | if (!available_a || !IS_SAME_MV(mv_a, mv)) { |
1527 |
2/2✓ Branch 0 taken 24323 times.
✓ Branch 1 taken 5387 times.
|
29710 | if (mvp_lx_flag == num_cands) |
1528 | 24323 | return 1; | |
1529 | 5387 | num_cands++; | |
1530 | } | ||
1531 | } | ||
1532 | 29137 | *nb_merge_cand = num_cands; | |
1533 | 29137 | return 0; | |
1534 | } | ||
1535 | |||
1536 | 29137 | static int mvp_temporal_candidates(const VVCLocalContext* lc, | |
1537 | const int mvp_lx_flag, const int lx, const int8_t *ref_idx, const int amvr_shift, | ||
1538 | Mv* mv, int *num_cands) | ||
1539 | { | ||
1540 |
2/2✓ Branch 1 taken 16320 times.
✓ Branch 2 taken 12817 times.
|
29137 | if (temporal_luma_motion_vector(lc, ref_idx[lx], mv, lx, 1, 0)) { |
1541 |
2/2✓ Branch 0 taken 13381 times.
✓ Branch 1 taken 2939 times.
|
16320 | if (mvp_lx_flag == *num_cands) { |
1542 | 13381 | ff_vvc_round_mv(mv, amvr_shift, amvr_shift); | |
1543 | 13381 | return 1; | |
1544 | } | ||
1545 | 2939 | (*num_cands)++; | |
1546 | } | ||
1547 | 15756 | return 0; | |
1548 | |||
1549 | } | ||
1550 | |||
1551 | 15756 | static int mvp_history_candidates(const VVCLocalContext *lc, | |
1552 | const int mvp_lx_flag, const int lx, const int8_t ref_idx, const int amvr_shift, | ||
1553 | Mv *mv, int num_cands) | ||
1554 | { | ||
1555 | 15756 | const EntryPoint* ep = lc->ep; | |
1556 | 15756 | const RefPicList* rpl = lc->sc->rpl; | |
1557 | 15756 | const int poc = rpl[lx].refs[ref_idx].poc; | |
1558 | |||
1559 |
2/2✓ Branch 0 taken 1928 times.
✓ Branch 1 taken 13828 times.
|
15756 | if (ep->num_hmvp == 0) |
1560 | 1928 | return 0; | |
1561 |
2/2✓ Branch 0 taken 28639 times.
✓ Branch 1 taken 4349 times.
|
32988 | for (int i = 1; i <= FFMIN(4, ep->num_hmvp); i++) { |
1562 | 28639 | const MvField* h = &ep->hmvp[i - 1]; | |
1563 |
2/2✓ Branch 0 taken 49182 times.
✓ Branch 1 taken 19160 times.
|
68342 | for (int j = 0; j < 2; j++) { |
1564 |
2/2✓ Branch 0 taken 20543 times.
✓ Branch 1 taken 28639 times.
|
49182 | const int ly = (j ? !lx : lx); |
1565 | 49182 | PredFlag mask = PF_L0 + ly; | |
1566 |
4/4✓ Branch 0 taken 33745 times.
✓ Branch 1 taken 15437 times.
✓ Branch 2 taken 11626 times.
✓ Branch 3 taken 22119 times.
|
49182 | if ((h->pred_flag & mask) && poc == rpl[ly].refs[h->ref_idx[ly]].poc) { |
1567 |
2/2✓ Branch 0 taken 9479 times.
✓ Branch 1 taken 2147 times.
|
11626 | if (mvp_lx_flag == num_cands) { |
1568 | 9479 | *mv = h->mv[ly]; | |
1569 | 9479 | ff_vvc_round_mv(mv, amvr_shift, amvr_shift); | |
1570 | 9479 | return 1; | |
1571 | } | ||
1572 | 2147 | num_cands++; | |
1573 | } | ||
1574 | } | ||
1575 | } | ||
1576 | 4349 | return 0; | |
1577 | } | ||
1578 | |||
1579 | //8.5.2.8 Derivation process for luma motion vector prediction | ||
1580 | 83359 | static void mvp(const VVCLocalContext *lc, const int mvp_lx_flag, const int lx, | |
1581 | const int8_t *ref_idx, const int amvr_shift, Mv *mv) | ||
1582 | { | ||
1583 | int num_cands; | ||
1584 | |||
1585 |
2/2✓ Branch 1 taken 54222 times.
✓ Branch 2 taken 29137 times.
|
83359 | if (mvp_spatial_candidates(lc, mvp_lx_flag, lx, ref_idx, amvr_shift, mv, &num_cands)) |
1586 | 77082 | return; | |
1587 | |||
1588 |
2/2✓ Branch 1 taken 13381 times.
✓ Branch 2 taken 15756 times.
|
29137 | if (mvp_temporal_candidates(lc, mvp_lx_flag, lx, ref_idx, amvr_shift, mv, &num_cands)) |
1589 | 13381 | return; | |
1590 | |||
1591 |
2/2✓ Branch 1 taken 9479 times.
✓ Branch 2 taken 6277 times.
|
15756 | if (mvp_history_candidates(lc, mvp_lx_flag, lx, ref_idx[lx], amvr_shift, mv, num_cands)) |
1592 | 9479 | return; | |
1593 | |||
1594 | 6277 | memset(mv, 0, sizeof(*mv)); | |
1595 | } | ||
1596 | |||
1597 | 65004 | void ff_vvc_mvp(VVCLocalContext *lc, const int *mvp_lx_flag, const int amvr_shift, MotionInfo *mi) | |
1598 | { | ||
1599 | 65004 | const CodingUnit *cu = lc->cu; | |
1600 | 65004 | mi->num_sb_x = 1; | |
1601 | 65004 | mi->num_sb_y = 1; | |
1602 | |||
1603 | 65004 | ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height); | |
1604 |
2/2✓ Branch 0 taken 53651 times.
✓ Branch 1 taken 11353 times.
|
65004 | if (mi->pred_flag != PF_L1) |
1605 | 53651 | mvp(lc, mvp_lx_flag[L0], L0, mi->ref_idx, amvr_shift, &mi->mv[L0][0]); | |
1606 |
2/2✓ Branch 0 taken 29708 times.
✓ Branch 1 taken 35296 times.
|
65004 | if (mi->pred_flag != PF_L0) |
1607 | 29708 | mvp(lc, mvp_lx_flag[L1], L1, mi->ref_idx, amvr_shift, &mi->mv[L1][0]); | |
1608 | 65004 | } | |
1609 | |||
1610 | 31182 | static int ibc_spatial_candidates(const VVCLocalContext *lc, const int merge_idx, Mv *const cand_list, int *nb_merge_cand) | |
1611 | { | ||
1612 | 31182 | const CodingUnit *cu = lc->cu; | |
1613 | 31182 | const VVCFrameContext *fc = lc->fc; | |
1614 | 31182 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
1615 | 31182 | const MvField *tab_mvf = fc->tab.mvf; | |
1616 | 31182 | const int is_gt4by4 = (cu->cb_width * cu->cb_height) > 16; | |
1617 | 31182 | int num_cands = 0; | |
1618 | |||
1619 | NeighbourContext nctx; | ||
1620 | 31182 | Neighbour *a1 = &nctx.neighbours[A1]; | |
1621 | 31182 | Neighbour *b1 = &nctx.neighbours[B1]; | |
1622 | |||
1623 |
2/2✓ Branch 0 taken 17582 times.
✓ Branch 1 taken 13600 times.
|
31182 | if (!is_gt4by4) { |
1624 | 17582 | *nb_merge_cand = 0; | |
1625 | 17582 | return 0; | |
1626 | } | ||
1627 | |||
1628 | 13600 | init_neighbour_context(&nctx, lc); | |
1629 | |||
1630 |
2/2✓ Branch 1 taken 4658 times.
✓ Branch 2 taken 8942 times.
|
13600 | if (check_available(a1, lc, 0)) { |
1631 | 4658 | cand_list[num_cands++] = TAB_MVF(a1->x, a1->y).mv[L0]; | |
1632 |
2/2✓ Branch 0 taken 3424 times.
✓ Branch 1 taken 1234 times.
|
4658 | if (num_cands > merge_idx) |
1633 | 3424 | return 1; | |
1634 | } | ||
1635 |
2/2✓ Branch 1 taken 2741 times.
✓ Branch 2 taken 7435 times.
|
10176 | if (check_available(b1, lc, 0)) { |
1636 | 2741 | const MvField *mvf = &TAB_MVF(b1->x, b1->y); | |
1637 |
4/4✓ Branch 0 taken 366 times.
✓ Branch 1 taken 2375 times.
✓ Branch 2 taken 295 times.
✓ Branch 3 taken 71 times.
|
2741 | if (!num_cands || !IS_SAME_MV(&cand_list[0], mvf->mv)) { |
1638 | 2670 | cand_list[num_cands++] = mvf->mv[L0]; | |
1639 |
2/2✓ Branch 0 taken 1850 times.
✓ Branch 1 taken 820 times.
|
2670 | if (num_cands > merge_idx) |
1640 | 1850 | return 1; | |
1641 | } | ||
1642 | } | ||
1643 | |||
1644 | 8326 | *nb_merge_cand = num_cands; | |
1645 | 8326 | return 0; | |
1646 | } | ||
1647 | |||
1648 | 25908 | static int ibc_history_candidates(const VVCLocalContext *lc, | |
1649 | const int merge_idx, Mv *cand_list, int *nb_merge_cand) | ||
1650 | { | ||
1651 | 25908 | const CodingUnit *cu = lc->cu; | |
1652 | 25908 | const EntryPoint *ep = lc->ep; | |
1653 | 25908 | const int is_gt4by4 = (cu->cb_width * cu->cb_height) > 16; | |
1654 | 25908 | int num_cands = *nb_merge_cand; | |
1655 | |||
1656 |
2/2✓ Branch 0 taken 37561 times.
✓ Branch 1 taken 1397 times.
|
38958 | for (int i = 1; i <= ep->num_hmvp_ibc; i++) { |
1657 | 37561 | int same_motion = 0; | |
1658 | 37561 | const MvField *mvf = &ep->hmvp_ibc[ep->num_hmvp_ibc - i]; | |
1659 |
2/2✓ Branch 0 taken 3490 times.
✓ Branch 1 taken 36530 times.
|
40020 | for (int j = 0; j < *nb_merge_cand; j++) { |
1660 |
5/6✓ Branch 0 taken 3490 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1774 times.
✓ Branch 3 taken 1716 times.
✓ Branch 4 taken 1031 times.
✓ Branch 5 taken 743 times.
|
3490 | same_motion = is_gt4by4 && i == 1 && IS_SAME_MV(&mvf->mv[L0], &cand_list[j]); |
1661 |
2/2✓ Branch 0 taken 1031 times.
✓ Branch 1 taken 2459 times.
|
3490 | if (same_motion) |
1662 | 1031 | break; | |
1663 | } | ||
1664 |
2/2✓ Branch 0 taken 36530 times.
✓ Branch 1 taken 1031 times.
|
37561 | if (!same_motion) { |
1665 | 36530 | cand_list[num_cands++] = mvf->mv[L0]; | |
1666 |
2/2✓ Branch 0 taken 24511 times.
✓ Branch 1 taken 12019 times.
|
36530 | if (num_cands > merge_idx) |
1667 | 24511 | return 1; | |
1668 | } | ||
1669 | } | ||
1670 | |||
1671 | 1397 | *nb_merge_cand = num_cands; | |
1672 | 1397 | return 0; | |
1673 | } | ||
1674 | |||
1675 | #define MV_BITS 18 | ||
1676 | #define IBC_SHIFT(v) ((v) >= (1 << (MV_BITS - 1)) ? ((v) - (1 << MV_BITS)) : (v)) | ||
1677 | |||
1678 | 17036 | static inline void ibc_add_mvp(Mv *mv, Mv *mvp, const int amvr_shift) | |
1679 | { | ||
1680 | 17036 | ff_vvc_round_mv(mv, amvr_shift, 0); | |
1681 | 17036 | ff_vvc_round_mv(mvp, amvr_shift, amvr_shift); | |
1682 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17036 times.
|
17036 | mv->x = IBC_SHIFT(mv->x + mvp->x); |
1683 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17036 times.
|
17036 | mv->y = IBC_SHIFT(mv->y + mvp->y); |
1684 | 17036 | } | |
1685 | |||
1686 | 31182 | static void ibc_merge_candidates(VVCLocalContext *lc, const int merge_idx, Mv *mv) | |
1687 | { | ||
1688 | 31182 | const CodingUnit *cu = lc->cu; | |
1689 | 31182 | LOCAL_ALIGNED_8(Mv, cand_list, [MRG_MAX_NUM_CANDS]); | |
1690 | int nb_cands; | ||
1691 | |||
1692 | 31182 | ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height); | |
1693 |
4/4✓ Branch 1 taken 25908 times.
✓ Branch 2 taken 5274 times.
✓ Branch 3 taken 24511 times.
✓ Branch 4 taken 1397 times.
|
57090 | if (ibc_spatial_candidates(lc, merge_idx, cand_list, &nb_cands) || |
1694 | 25908 | ibc_history_candidates(lc, merge_idx, cand_list, &nb_cands)) { | |
1695 | 29785 | *mv = cand_list[merge_idx]; | |
1696 | 29785 | return; | |
1697 | } | ||
1698 | |||
1699 | //zero mv | ||
1700 | 1397 | memset(mv, 0, sizeof(*mv)); | |
1701 | } | ||
1702 | |||
1703 | 31182 | static int ibc_check_mv(VVCLocalContext *lc, Mv *mv) | |
1704 | { | ||
1705 | 31182 | const VVCFrameContext *fc = lc->fc; | |
1706 | 31182 | const VVCSPS *sps = lc->fc->ps.sps; | |
1707 | 31182 | const CodingUnit *cu = lc->cu; | |
1708 | 31182 | const Mv *bv = &cu->pu.mi.mv[L0][0]; | |
1709 | |||
1710 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 31182 times.
|
31182 | if (sps->ctb_size_y < ((cu->y0 + (bv->y >> 4)) & (sps->ctb_size_y - 1)) + cu->cb_height) { |
1711 | ✗ | av_log(fc->log_ctx, AV_LOG_ERROR, "IBC region spans multiple CTBs.\n"); | |
1712 | ✗ | return AVERROR_INVALIDDATA; | |
1713 | } | ||
1714 | |||
1715 | 31182 | return 0; | |
1716 | } | ||
1717 | |||
1718 | 17036 | int ff_vvc_mvp_ibc(VVCLocalContext *lc, const int mvp_l0_flag, const int amvr_shift, Mv *mv) | |
1719 | { | ||
1720 | 17036 | LOCAL_ALIGNED_8(Mv, mvp, [1]); | |
1721 | |||
1722 | 17036 | ibc_merge_candidates(lc, mvp_l0_flag, mvp); | |
1723 | 17036 | ibc_add_mvp(mv, mvp, amvr_shift); | |
1724 | 17036 | return ibc_check_mv(lc, mv); | |
1725 | } | ||
1726 | |||
1727 | 14146 | int ff_vvc_luma_mv_merge_ibc(VVCLocalContext *lc, const int merge_idx, Mv *mv) | |
1728 | { | ||
1729 | 14146 | ibc_merge_candidates(lc, merge_idx, mv); | |
1730 | 14146 | return ibc_check_mv(lc, mv); | |
1731 | } | ||
1732 | |||
1733 | 24168 | static int affine_mvp_constructed_cp(NeighbourContext *ctx, | |
1734 | const NeighbourIdx *neighbour, const int num_neighbour, | ||
1735 | const int lx, const int8_t ref_idx, const int amvr_shift, Mv *cp) | ||
1736 | { | ||
1737 | 24168 | const VVCLocalContext *lc = ctx->lc; | |
1738 | 24168 | const VVCFrameContext *fc = lc->fc; | |
1739 | 24168 | const MvField *tab_mvf = fc->tab.mvf; | |
1740 | 24168 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
1741 | 24168 | const RefPicList* rpl = lc->sc->rpl; | |
1742 | 24168 | int available = 0; | |
1743 | |||
1744 |
2/2✓ Branch 0 taken 37660 times.
✓ Branch 1 taken 8187 times.
|
45847 | for (int i = 0; i < num_neighbour; i++) { |
1745 | 37660 | Neighbour *n = &ctx->neighbours[neighbour[i]]; | |
1746 |
2/2✓ Branch 1 taken 23602 times.
✓ Branch 2 taken 14058 times.
|
37660 | if (check_available(n, ctx->lc, 0)) { |
1747 | 23602 | const PredFlag maskx = lx + 1; | |
1748 | 23602 | const MvField* mvf = &TAB_MVF(n->x, n->y); | |
1749 | 23602 | const int poc = rpl[lx].refs[ref_idx].poc; | |
1750 |
4/4✓ Branch 0 taken 19262 times.
✓ Branch 1 taken 4340 times.
✓ Branch 2 taken 14169 times.
✓ Branch 3 taken 5093 times.
|
23602 | if ((mvf->pred_flag & maskx) && rpl[lx].refs[mvf->ref_idx[lx]].poc == poc) { |
1751 | 14169 | available = 1; | |
1752 | 14169 | *cp = mvf->mv[lx]; | |
1753 | } else { | ||
1754 | 9433 | const int ly = !lx; | |
1755 | 9433 | const PredFlag masky = ly + 1; | |
1756 |
4/4✓ Branch 0 taken 6356 times.
✓ Branch 1 taken 3077 times.
✓ Branch 2 taken 1812 times.
✓ Branch 3 taken 4544 times.
|
9433 | if ((mvf->pred_flag & masky) && rpl[ly].refs[mvf->ref_idx[ly]].poc == poc) { |
1757 | 1812 | available = 1; | |
1758 | 1812 | *cp = mvf->mv[ly]; | |
1759 | } | ||
1760 | } | ||
1761 |
2/2✓ Branch 0 taken 15981 times.
✓ Branch 1 taken 7621 times.
|
23602 | if (available) { |
1762 | 15981 | ff_vvc_round_mv(cp, amvr_shift, amvr_shift); | |
1763 | 15981 | return 1; | |
1764 | } | ||
1765 | } | ||
1766 | } | ||
1767 | 8187 | return 0; | |
1768 | } | ||
1769 | |||
1770 | #define AFFINE_MVP_CONSTRUCTED_CP(cands, cp) \ | ||
1771 | affine_mvp_constructed_cp(nctx, cands, FF_ARRAY_ELEMS(cands), lx, ref_idx, \ | ||
1772 | amvr_shift, cp) | ||
1773 | |||
1774 | //8.5.5.8 Derivation process for constructed affine control point motion vector prediction candidates | ||
1775 | 8056 | static int affine_mvp_const1(NeighbourContext* nctx, | |
1776 | const int lx, const int8_t ref_idx, const int amvr_shift, | ||
1777 | Mv *cps, int *available) | ||
1778 | { | ||
1779 | 8056 | const NeighbourIdx tl[] = { B2, B3, A2 }; | |
1780 | 8056 | const NeighbourIdx tr[] = { B1, B0 }; | |
1781 | 8056 | const NeighbourIdx bl[] = { A1, A0 }; | |
1782 | |||
1783 | 8056 | available[0] = AFFINE_MVP_CONSTRUCTED_CP(tl, cps + 0); | |
1784 | 8056 | available[1] = AFFINE_MVP_CONSTRUCTED_CP(tr, cps + 1); | |
1785 | 8056 | available[2] = AFFINE_MVP_CONSTRUCTED_CP(bl, cps + 2); | |
1786 |
4/4✓ Branch 0 taken 6186 times.
✓ Branch 1 taken 1870 times.
✓ Branch 2 taken 4713 times.
✓ Branch 3 taken 1473 times.
|
8056 | return available[0] && available[1]; |
1787 | } | ||
1788 | |||
1789 | //8.5.5.7 item 7 | ||
1790 | 3579 | static void affine_mvp_const2(const int idx, Mv *cps, const int num_cp) | |
1791 | { | ||
1792 | 3579 | const Mv mv = cps[idx]; | |
1793 |
2/2✓ Branch 0 taken 8879 times.
✓ Branch 1 taken 3579 times.
|
12458 | for (int j = 0; j < num_cp; j++) |
1794 | 8879 | cps[j] = mv; | |
1795 | 3579 | } | |
1796 | |||
1797 | //8.5.5.7 Derivation process for luma affine control point motion vector predictors | ||
1798 | 12166 | static void affine_mvp(const VVCLocalContext *lc, | |
1799 | const int mvp_lx_flag, const int lx, const int8_t *ref_idx, const int amvr_shift, | ||
1800 | MotionModelIdc motion_model_idc, Mv *cps) | ||
1801 | { | ||
1802 | 12166 | const NeighbourIdx ak[] = { A0, A1 }; | |
1803 | 12166 | const NeighbourIdx bk[] = { B0, B1, B2 }; | |
1804 | 12166 | const int num_cp = motion_model_idc + 1; | |
1805 | NeighbourContext nctx; | ||
1806 | int available[MAX_CONTROL_POINTS]; | ||
1807 | 12166 | int num_cands = 0; | |
1808 | |||
1809 | 12166 | init_neighbour_context(&nctx, lc); | |
1810 | //Ak | ||
1811 |
2/2✓ Branch 1 taken 2972 times.
✓ Branch 2 taken 9194 times.
|
12166 | if (AFFINE_MVP_FROM_NBS(ak)) { |
1812 |
2/2✓ Branch 0 taken 1990 times.
✓ Branch 1 taken 982 times.
|
2972 | if (mvp_lx_flag == num_cands) |
1813 | 11435 | return; | |
1814 | 982 | num_cands++; | |
1815 | } | ||
1816 | //Bk | ||
1817 |
2/2✓ Branch 1 taken 2927 times.
✓ Branch 2 taken 7249 times.
|
10176 | if (AFFINE_MVP_FROM_NBS(bk)) { |
1818 |
2/2✓ Branch 0 taken 2120 times.
✓ Branch 1 taken 807 times.
|
2927 | if (mvp_lx_flag == num_cands) |
1819 | 2120 | return; | |
1820 | 807 | num_cands++; | |
1821 | } | ||
1822 | |||
1823 | //Const1 | ||
1824 |
2/2✓ Branch 1 taken 4713 times.
✓ Branch 2 taken 3343 times.
|
8056 | if (affine_mvp_const1(&nctx, lx, ref_idx[lx], amvr_shift, cps, available)) { |
1825 |
4/4✓ Branch 0 taken 1270 times.
✓ Branch 1 taken 3443 times.
✓ Branch 2 taken 725 times.
✓ Branch 3 taken 545 times.
|
4713 | if (available[2] || motion_model_idc == MOTION_4_PARAMS_AFFINE) { |
1826 |
2/2✓ Branch 0 taken 2877 times.
✓ Branch 1 taken 1291 times.
|
4168 | if (mvp_lx_flag == num_cands) |
1827 | 2877 | return; | |
1828 | 1291 | num_cands++; | |
1829 | } | ||
1830 | } | ||
1831 | |||
1832 | //Const2 | ||
1833 |
2/2✓ Branch 0 taken 10400 times.
✓ Branch 1 taken 1600 times.
|
12000 | for (int i = 2; i >= 0; i--) { |
1834 |
2/2✓ Branch 0 taken 4140 times.
✓ Branch 1 taken 6260 times.
|
10400 | if (available[i]) { |
1835 |
2/2✓ Branch 0 taken 3579 times.
✓ Branch 1 taken 561 times.
|
4140 | if (mvp_lx_flag == num_cands) { |
1836 | 3579 | affine_mvp_const2(i, cps, num_cp); | |
1837 | 3579 | return; | |
1838 | } | ||
1839 | 561 | num_cands++; | |
1840 | } | ||
1841 | } | ||
1842 |
2/2✓ Branch 1 taken 1073 times.
✓ Branch 2 taken 527 times.
|
1600 | if (temporal_luma_motion_vector(lc, ref_idx[lx], cps, lx, 1, 0)) { |
1843 |
2/2✓ Branch 0 taken 869 times.
✓ Branch 1 taken 204 times.
|
1073 | if (mvp_lx_flag == num_cands) { |
1844 | 869 | ff_vvc_round_mv(cps, amvr_shift, amvr_shift); | |
1845 |
2/2✓ Branch 0 taken 1150 times.
✓ Branch 1 taken 869 times.
|
2019 | for (int i = 1; i < num_cp; i++) |
1846 | 1150 | cps[i] = cps[0]; | |
1847 | 869 | return; | |
1848 | } | ||
1849 | 204 | num_cands++; | |
1850 | } | ||
1851 | |||
1852 | //Zero Mv | ||
1853 | 731 | memset(cps, 0, num_cp * sizeof(Mv)); | |
1854 | } | ||
1855 | |||
1856 | 9947 | void ff_vvc_affine_mvp(VVCLocalContext *lc, const int *mvp_lx_flag, const int amvr_shift, MotionInfo *mi) | |
1857 | { | ||
1858 | 9947 | const CodingUnit *cu = lc->cu; | |
1859 | |||
1860 | 9947 | mi->num_sb_x = cu->cb_width >> MIN_PU_LOG2; | |
1861 | 9947 | mi->num_sb_y = cu->cb_height >> MIN_PU_LOG2; | |
1862 | |||
1863 | 9947 | ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height); | |
1864 |
2/2✓ Branch 0 taken 8767 times.
✓ Branch 1 taken 1180 times.
|
9947 | if (mi->pred_flag != PF_L1) |
1865 | 8767 | affine_mvp(lc, mvp_lx_flag[L0], L0, mi->ref_idx, amvr_shift, mi->motion_model_idc, &mi->mv[L0][0]); | |
1866 |
2/2✓ Branch 0 taken 3399 times.
✓ Branch 1 taken 6548 times.
|
9947 | if (mi->pred_flag != PF_L0) |
1867 | 3399 | affine_mvp(lc, mvp_lx_flag[L1], L1, mi->ref_idx, amvr_shift, mi->motion_model_idc, &mi->mv[L1][0]); | |
1868 | 9947 | } | |
1869 | |||
1870 | //8.5.2.14 Rounding process for motion vectors | ||
1871 | 7602307 | void ff_vvc_round_mv(Mv *mv, const int lshift, const int rshift) | |
1872 | { | ||
1873 |
2/2✓ Branch 0 taken 7583633 times.
✓ Branch 1 taken 18674 times.
|
7602307 | if (rshift) { |
1874 | 7583633 | const int offset = 1 << (rshift - 1); | |
1875 | 7583633 | mv->x = ((mv->x + offset - (mv->x >= 0)) >> rshift) * (1 << lshift); | |
1876 | 7583633 | mv->y = ((mv->y + offset - (mv->y >= 0)) >> rshift) * (1 << lshift); | |
1877 | } else { | ||
1878 | 18674 | mv->x = mv->x * (1 << lshift); | |
1879 | 18674 | mv->y = mv->y * (1 << lshift); | |
1880 | } | ||
1881 | 7602307 | } | |
1882 | |||
1883 | 5299524 | void ff_vvc_clip_mv(Mv *mv) | |
1884 | { | ||
1885 | 5299524 | mv->x = av_clip(mv->x, -(1 << 17), (1 << 17) - 1); | |
1886 | 5299524 | mv->y = av_clip(mv->y, -(1 << 17), (1 << 17) - 1); | |
1887 | 5299524 | } | |
1888 | |||
1889 | //8.5.2.1 Derivation process for motion vector components and reference indices | ||
1890 | 338415 | static av_always_inline int is_greater_mer(const VVCFrameContext *fc, const int x0, const int y0, const int x0_br, const int y0_br) | |
1891 | { | ||
1892 | 338415 | const uint8_t plevel = fc->ps.sps->log2_parallel_merge_level; | |
1893 | |||
1894 |
2/2✓ Branch 0 taken 328291 times.
✓ Branch 1 taken 10124 times.
|
666706 | return x0_br >> plevel > x0 >> plevel && |
1895 |
2/2✓ Branch 0 taken 323519 times.
✓ Branch 1 taken 4772 times.
|
328291 | y0_br >> plevel > y0 >> plevel; |
1896 | } | ||
1897 | |||
1898 | 337119 | static void update_hmvp(MvField *hmvp, int *num_hmvp, const MvField *mvf, | |
1899 | int (*compare)(const MvField *n, const MvField *o)) | ||
1900 | { | ||
1901 | int i; | ||
1902 |
2/2✓ Branch 0 taken 1418063 times.
✓ Branch 1 taken 180843 times.
|
1598906 | for (i = 0; i < *num_hmvp; i++) { |
1903 |
2/2✓ Branch 1 taken 156276 times.
✓ Branch 2 taken 1261787 times.
|
1418063 | if (compare(mvf, hmvp + i)) { |
1904 | 156276 | (*num_hmvp)--; | |
1905 | 156276 | break; | |
1906 | } | ||
1907 | } | ||
1908 |
2/2✓ Branch 0 taken 158975 times.
✓ Branch 1 taken 178144 times.
|
337119 | if (i == MAX_NUM_HMVP_CANDS) { |
1909 | 158975 | (*num_hmvp)--; | |
1910 | 158975 | i = 0; | |
1911 | } | ||
1912 | |||
1913 | 337119 | memmove(hmvp + i, hmvp + i + 1, (*num_hmvp - i) * sizeof(MvField)); | |
1914 | 337119 | hmvp[(*num_hmvp)++] = *mvf; | |
1915 | 337119 | } | |
1916 | |||
1917 | 48432 | static int compare_l0_mv(const MvField *n, const MvField *o) | |
1918 | { | ||
1919 | 48432 | return IS_SAME_MV(&n->mv[L0], &o->mv[L0]); | |
1920 | } | ||
1921 | |||
1922 | //8.6.2.4 Derivation process for IBC history-based block vector candidates | ||
1923 | //8.5.2.16 Updating process for the history-based motion vector predictor candidate list | ||
1924 | 369597 | void ff_vvc_update_hmvp(VVCLocalContext *lc, const MotionInfo *mi) | |
1925 | { | ||
1926 | 369597 | const VVCFrameContext *fc = lc->fc; | |
1927 | 369597 | const CodingUnit *cu = lc->cu; | |
1928 | 369597 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
1929 | 369597 | const MvField *tab_mvf = fc->tab.mvf; | |
1930 | 369597 | EntryPoint *ep = lc->ep; | |
1931 | |||
1932 |
2/2✓ Branch 0 taken 31182 times.
✓ Branch 1 taken 338415 times.
|
369597 | if (cu->pred_mode == MODE_IBC) { |
1933 |
2/2✓ Branch 0 taken 17582 times.
✓ Branch 1 taken 13600 times.
|
31182 | if (cu->cb_width * cu->cb_height <= 16) |
1934 | 17582 | return; | |
1935 | 13600 | update_hmvp(ep->hmvp_ibc, &ep->num_hmvp_ibc, &TAB_MVF(cu->x0, cu->y0), compare_l0_mv); | |
1936 | } else { | ||
1937 |
2/2✓ Branch 1 taken 14896 times.
✓ Branch 2 taken 323519 times.
|
338415 | if (!is_greater_mer(fc, cu->x0, cu->y0, cu->x0 + cu->cb_width, cu->y0 + cu->cb_height)) |
1938 | 14896 | return; | |
1939 | 323519 | update_hmvp(ep->hmvp, &ep->num_hmvp, &TAB_MVF(cu->x0, cu->y0), compare_mv_ref_idx); | |
1940 | } | ||
1941 | } | ||
1942 | |||
1943 | 12257218 | MvField* ff_vvc_get_mvf(const VVCFrameContext *fc, const int x0, const int y0) | |
1944 | { | ||
1945 | 12257218 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
1946 | 12257218 | MvField* tab_mvf = fc->tab.mvf; | |
1947 | |||
1948 | 12257218 | return &TAB_MVF(x0, y0); | |
1949 | } | ||
1950 |