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 | 673964 | 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 | 673964 | const uint8_t plevel = fc->ps.sps->log2_parallel_merge_level; | |
34 | |||
35 |
2/2✓ Branch 0 taken 42122 times.
✓ Branch 1 taken 631842 times.
|
716086 | return xN >> plevel == xP >> plevel && |
36 |
2/2✓ Branch 0 taken 6192 times.
✓ Branch 1 taken 35930 times.
|
42122 | yN >> plevel == yP >> plevel; |
37 | } | ||
38 | |||
39 | //return true if we have same mvs and ref_idxs | ||
40 | 2181523 | static av_always_inline int compare_mv_ref_idx(const MvField *n, const MvField *o) | |
41 | { | ||
42 |
4/4✓ Branch 0 taken 1834419 times.
✓ Branch 1 taken 347104 times.
✓ Branch 2 taken 575073 times.
✓ Branch 3 taken 1259346 times.
|
2181523 | if (!o || n->pred_flag != o->pred_flag) |
43 | 922177 | return 0; | |
44 |
2/2✓ Branch 0 taken 1591840 times.
✓ Branch 1 taken 276092 times.
|
1867932 | for (int i = 0; i < 2; i++) { |
45 | 1591840 | PredFlag mask = i + 1; | |
46 |
2/2✓ Branch 0 taken 1431644 times.
✓ Branch 1 taken 160196 times.
|
1591840 | if (n->pred_flag & mask) { |
47 | 1431644 | const int same_ref_idx = n->ref_idx[i] == o->ref_idx[i]; | |
48 | 1431644 | const int same_mv = IS_SAME_MV(n->mv + i, o->mv + i); | |
49 |
4/4✓ Branch 0 taken 1295338 times.
✓ Branch 1 taken 136306 times.
✓ Branch 2 taken 846948 times.
✓ Branch 3 taken 448390 times.
|
1431644 | if (!same_ref_idx || !same_mv) |
50 | 983254 | return 0; | |
51 | } | ||
52 | } | ||
53 | 276092 | return 1; | |
54 | } | ||
55 | |||
56 | // 8.5.2.15 Temporal motion buffer compression process for collocated motion vectors | ||
57 | 2405588 | static av_always_inline void mv_compression(Mv *motion) | |
58 | { | ||
59 | 2405588 | int mv[2] = {motion->x, motion->y}; | |
60 |
2/2✓ Branch 0 taken 4811176 times.
✓ Branch 1 taken 2405588 times.
|
7216764 | for (int i = 0; i < 2; i++) { |
61 | 4811176 | const int s = mv[i] >> 17; | |
62 | 4811176 | const int f = av_log2((mv[i] ^ s) | 31) - 4; | |
63 | 4811176 | const int mask = (-1 * (1 << f)) >> 1; | |
64 | 4811176 | const int round = (1 << f) >> 2; | |
65 | 4811176 | mv[i] = (mv[i] + round) & mask; | |
66 | } | ||
67 | 2405588 | motion->x = mv[0]; | |
68 | 2405588 | motion->y = mv[1]; | |
69 | 2405588 | } | |
70 | |||
71 | 1986374 | void ff_vvc_mv_scale(Mv *dst, const Mv *src, int td, int tb) | |
72 | { | ||
73 | int tx, scale_factor; | ||
74 | |||
75 | 1986374 | td = av_clip_int8(td); | |
76 | 1986374 | tb = av_clip_int8(tb); | |
77 | 1986374 | tx = (0x4000 + (abs(td) >> 1)) / td; | |
78 | 1986374 | scale_factor = av_clip_intp2((tb * tx + 32) >> 6, 12); | |
79 | 1986374 | dst->x = av_clip_intp2((scale_factor * src->x + 127 + | |
80 | 1986374 | (scale_factor * src->x < 0)) >> 8, 17); | |
81 | 1986374 | dst->y = av_clip_intp2((scale_factor * src->y + 127 + | |
82 | 1986374 | (scale_factor * src->y < 0)) >> 8, 17); | |
83 | 1986374 | } | |
84 | |||
85 | //part of 8.5.2.12 Derivation process for collocated motion vectors | ||
86 | 2417657 | 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 | 2417657 | int cur_lt = refPicList[X].refs[refIdxLx].is_lt; | |
92 | 2417657 | 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 2405588 times.
|
2417657 | if (cur_lt != col_lt) { |
96 | 12069 | mvLXCol->x = 0; | |
97 | 12069 | mvLXCol->y = 0; | |
98 | 12069 | return 0; | |
99 | } | ||
100 | |||
101 | 2405588 | col_poc_diff = colPic - refPicList_col[listCol].refs[refidxCol].poc; | |
102 | 2405588 | cur_poc_diff = poc - refPicList[X].refs[refIdxLx].poc; | |
103 | |||
104 | 2405588 | mv_compression(mvCol); | |
105 |
4/4✓ Branch 0 taken 2397370 times.
✓ Branch 1 taken 8218 times.
✓ Branch 2 taken 426838 times.
✓ Branch 3 taken 1970532 times.
|
2405588 | if (cur_lt || col_poc_diff == cur_poc_diff) { |
106 | 435056 | mvLXCol->x = av_clip_intp2(mvCol->x, 17); | |
107 | 435056 | mvLXCol->y = av_clip_intp2(mvCol->y, 17); | |
108 | } else { | ||
109 | 1970532 | ff_vvc_mv_scale(mvLXCol, mvCol, col_poc_diff, cur_poc_diff); | |
110 | } | ||
111 | 2405588 | 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 | 598319 | int ff_vvc_no_backward_pred_flag(const VVCLocalContext *lc) | |
122 | { | ||
123 | 598319 | int check_diffpicount = 0; | |
124 | int i, j; | ||
125 | 598319 | const RefPicList *rpl = lc->sc->rpl; | |
126 | |||
127 |
2/2✓ Branch 0 taken 1196638 times.
✓ Branch 1 taken 598319 times.
|
1794957 | for (j = 0; j < 2; j++) { |
128 |
2/2✓ Branch 0 taken 1893247 times.
✓ Branch 1 taken 528377 times.
|
2421624 | for (i = 0; i < lc->sc->sh.r->num_ref_idx_active[j]; i++) { |
129 |
2/2✓ Branch 0 taken 668261 times.
✓ Branch 1 taken 1224986 times.
|
1893247 | if (rpl[j].refs[i].poc > lc->fc->ps.ph.poc) { |
130 | 668261 | check_diffpicount++; | |
131 | 668261 | break; | |
132 | } | ||
133 | } | ||
134 | } | ||
135 | 598319 | return !check_diffpicount; | |
136 | } | ||
137 | |||
138 | //8.5.2.12 Derivation process for collocated motion vectors | ||
139 | 2969656 | 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 | 2969656 | const VVCFrameContext *fc = lc->fc; | |
144 | 2969656 | const SliceContext *sc = lc->sc; | |
145 | 2969656 | RefPicList* refPicList = sc->rpl; | |
146 | |||
147 |
2/2✓ Branch 0 taken 2890891 times.
✓ Branch 1 taken 78765 times.
|
2969656 | if (temp_col.pred_flag == PF_INTRA || |
148 |
2/2✓ Branch 0 taken 2886391 times.
✓ Branch 1 taken 4500 times.
|
2890891 | temp_col.pred_flag == PF_IBC || |
149 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2886391 times.
|
2886391 | temp_col.pred_flag == PF_PLT) |
150 | 83265 | return 0; | |
151 | |||
152 |
2/2✓ Branch 0 taken 2762815 times.
✓ Branch 1 taken 123576 times.
|
2886391 | if (sb_flag){ |
153 |
2/2✓ Branch 0 taken 1553780 times.
✓ Branch 1 taken 1209035 times.
|
2762815 | if (X == 0) { |
154 |
2/2✓ Branch 0 taken 1366124 times.
✓ Branch 1 taken 187656 times.
|
1553780 | if (temp_col.pred_flag & PF_L0) |
155 | 1366124 | return CHECK_MVSET(0); | |
156 |
3/4✓ Branch 1 taken 2349 times.
✓ Branch 2 taken 185307 times.
✓ Branch 3 taken 2349 times.
✗ Branch 4 not taken.
|
187656 | else if (ff_vvc_no_backward_pred_flag(lc) && (temp_col.pred_flag & PF_L1)) |
157 | 2349 | return CHECK_MVSET(1); | |
158 | } else { | ||
159 |
2/2✓ Branch 0 taken 861972 times.
✓ Branch 1 taken 347063 times.
|
1209035 | if (temp_col.pred_flag & PF_L1) |
160 | 861972 | return CHECK_MVSET(1); | |
161 |
3/4✓ Branch 1 taken 63636 times.
✓ Branch 2 taken 283427 times.
✓ Branch 3 taken 63636 times.
✗ Branch 4 not taken.
|
347063 | else if (ff_vvc_no_backward_pred_flag(lc) && (temp_col.pred_flag & PF_L0)) |
162 | 63636 | return CHECK_MVSET(0); | |
163 | } | ||
164 | } else { | ||
165 |
2/2✓ Branch 0 taken 15706 times.
✓ Branch 1 taken 107870 times.
|
123576 | if (!(temp_col.pred_flag & PF_L0)) |
166 | 15706 | return CHECK_MVSET(1); | |
167 |
2/2✓ Branch 0 taken 56415 times.
✓ Branch 1 taken 51455 times.
|
107870 | else if (temp_col.pred_flag == PF_L0) |
168 | 56415 | return CHECK_MVSET(0); | |
169 |
1/2✓ Branch 0 taken 51455 times.
✗ Branch 1 not taken.
|
51455 | else if (temp_col.pred_flag == PF_BI) { |
170 |
2/2✓ Branch 1 taken 9703 times.
✓ Branch 2 taken 41752 times.
|
51455 | if (ff_vvc_no_backward_pred_flag(lc)) { |
171 |
2/2✓ Branch 0 taken 5087 times.
✓ Branch 1 taken 4616 times.
|
9703 | if (X == 0) |
172 | 5087 | return CHECK_MVSET(0); | |
173 | else | ||
174 | 4616 | return CHECK_MVSET(1); | |
175 | } else { | ||
176 |
2/2✓ Branch 0 taken 23178 times.
✓ Branch 1 taken 18574 times.
|
41752 | if (!lc->sc->sh.r->sh_collocated_from_l0_flag) |
177 | 23178 | return CHECK_MVSET(0); | |
178 | else | ||
179 | 18574 | return CHECK_MVSET(1); | |
180 | } | ||
181 | } | ||
182 | } | ||
183 | 468734 | return 0; | |
184 | } | ||
185 | |||
186 | #define TAB_MVF(x, y) \ | ||
187 | tab_mvf[((y) >> MIN_PU_LOG2) * min_pu_width + ((x) >> MIN_PU_LOG2)] | ||
188 | |||
189 | #define TAB_MVF_PU(v) \ | ||
190 | TAB_MVF(x ## v, y ## v) | ||
191 | |||
192 | #define TAB_CP_MV(lx, x, y) \ | ||
193 | fc->tab.cp_mv[lx][((((y) >> min_cb_log2_size) * min_cb_width + ((x) >> min_cb_log2_size)) ) * MAX_CONTROL_POINTS] | ||
194 | |||
195 | |||
196 | #define DERIVE_TEMPORAL_COLOCATED_MVS(sb_flag) \ | ||
197 | derive_temporal_colocated_mvs(lc, temp_col, \ | ||
198 | refIdxLx, mvLXCol, X, colPic, \ | ||
199 | ff_vvc_get_ref_list(fc, ref, x, y), sb_flag) | ||
200 | |||
201 | //8.5.2.11 Derivation process for temporal luma motion vector prediction | ||
202 | 153072 | static int temporal_luma_motion_vector(const VVCLocalContext *lc, | |
203 | const int refIdxLx, Mv *mvLXCol, const int X, int check_center, int sb_flag) | ||
204 | { | ||
205 | 153072 | const VVCFrameContext *fc = lc->fc; | |
206 | 153072 | const VVCSPS *sps = fc->ps.sps; | |
207 | 153072 | const VVCPPS *pps = fc->ps.pps; | |
208 | 153072 | const CodingUnit *cu = lc->cu; | |
209 | 153072 | const int subpic_idx = lc->sc->sh.r->curr_subpic_idx; | |
210 | 153072 | int x, y, x_end, y_end, colPic, availableFlagLXCol = 0; | |
211 | 153072 | int min_pu_width = fc->ps.pps->min_pu_width; | |
212 | 153072 | VVCFrame *ref = fc->ref->collocated_ref; | |
213 | MvField *tab_mvf; | ||
214 | MvField temp_col; | ||
215 | |||
216 |
2/2✓ Branch 0 taken 66 times.
✓ Branch 1 taken 153006 times.
|
153072 | if (!ref) { |
217 | 66 | memset(mvLXCol, 0, sizeof(*mvLXCol)); | |
218 | 66 | return 0; | |
219 | } | ||
220 | |||
221 |
3/4✓ Branch 0 taken 153006 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4749 times.
✓ Branch 3 taken 148257 times.
|
153006 | if (!fc->ps.ph.r->ph_temporal_mvp_enabled_flag || (cu->cb_width * cu->cb_height <= 32)) |
222 | 4749 | return 0; | |
223 | |||
224 | 148257 | tab_mvf = ref->tab_dmvr_mvf; | |
225 | 148257 | colPic = ref->poc; | |
226 | |||
227 | //bottom right collocated motion vector | ||
228 | 148257 | x = cu->x0 + cu->cb_width; | |
229 | 148257 | y = cu->y0 + cu->cb_height; | |
230 | |||
231 | 148257 | x_end = pps->subpic_x[subpic_idx] + pps->subpic_width[subpic_idx]; | |
232 | 148257 | y_end = pps->subpic_y[subpic_idx] + pps->subpic_height[subpic_idx]; | |
233 | |||
234 |
1/2✓ Branch 0 taken 148257 times.
✗ Branch 1 not taken.
|
148257 | if (tab_mvf && |
235 |
4/4✓ Branch 0 taken 125422 times.
✓ Branch 1 taken 22835 times.
✓ Branch 2 taken 123069 times.
✓ Branch 3 taken 2353 times.
|
148257 | (cu->y0 >> sps->ctb_log2_size_y) == (y >> sps->ctb_log2_size_y) && |
236 |
2/2✓ Branch 0 taken 119041 times.
✓ Branch 1 taken 4028 times.
|
123069 | x < x_end && y < y_end) { |
237 | 119041 | x &= ~7; | |
238 | 119041 | y &= ~7; | |
239 | 119041 | temp_col = TAB_MVF(x, y); | |
240 | 119041 | availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS(sb_flag); | |
241 | } | ||
242 |
2/2✓ Branch 0 taken 134433 times.
✓ Branch 1 taken 13824 times.
|
148257 | if (check_center) { |
243 | // derive center collocated motion vector | ||
244 |
3/4✓ Branch 0 taken 134433 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 57611 times.
✓ Branch 3 taken 76822 times.
|
134433 | if (tab_mvf && !availableFlagLXCol) { |
245 | 57611 | x = cu->x0 + (cu->cb_width >> 1); | |
246 | 57611 | y = cu->y0 + (cu->cb_height >> 1); | |
247 | 57611 | x &= ~7; | |
248 | 57611 | y &= ~7; | |
249 | 57611 | temp_col = TAB_MVF(x, y); | |
250 | 57611 | availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS(sb_flag); | |
251 | } | ||
252 | } | ||
253 | 148257 | return availableFlagLXCol; | |
254 | } | ||
255 | |||
256 | 6093322 | void ff_vvc_set_mvf(const VVCLocalContext *lc, const int x0, const int y0, const int w, const int h, const MvField *mvf) | |
257 | { | ||
258 | 6093322 | const VVCFrameContext *fc = lc->fc; | |
259 | 6093322 | MvField *tab_mvf = fc->tab.mvf; | |
260 | 6093322 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
261 | 6093322 | const int min_pu_size = 1 << MIN_PU_LOG2; | |
262 |
2/2✓ Branch 0 taken 9702737 times.
✓ Branch 1 taken 6093322 times.
|
15796059 | for (int dy = 0; dy < h; dy += min_pu_size) { |
263 |
2/2✓ Branch 0 taken 43669017 times.
✓ Branch 1 taken 9702737 times.
|
53371754 | for (int dx = 0; dx < w; dx += min_pu_size) { |
264 | 43669017 | const int x = x0 + dx; | |
265 | 43669017 | const int y = y0 + dy; | |
266 | 43669017 | TAB_MVF(x, y) = *mvf; | |
267 | } | ||
268 | } | ||
269 | 6093322 | } | |
270 | |||
271 | 696757 | void ff_vvc_set_intra_mvf(const VVCLocalContext *lc, const bool dmvr, const PredFlag pf, const bool ciip_flag) | |
272 | { | ||
273 | 696757 | const VVCFrameContext *fc = lc->fc; | |
274 | 696757 | const CodingUnit *cu = lc->cu; | |
275 |
2/2✓ Branch 0 taken 67240 times.
✓ Branch 1 taken 629517 times.
|
696757 | MvField *tab_mvf = dmvr ? fc->ref->tab_dmvr_mvf : fc->tab.mvf; |
276 | 696757 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
277 | 696757 | const int min_pu_size = 1 << MIN_PU_LOG2; | |
278 |
2/2✓ Branch 0 taken 1738299 times.
✓ Branch 1 taken 696757 times.
|
2435056 | for (int dy = 0; dy < cu->cb_height; dy += min_pu_size) { |
279 |
2/2✓ Branch 0 taken 7126442 times.
✓ Branch 1 taken 1738299 times.
|
8864741 | for (int dx = 0; dx < cu->cb_width; dx += min_pu_size) { |
280 | 7126442 | const int x = cu->x0 + dx; | |
281 | 7126442 | const int y = cu->y0 + dy; | |
282 | 7126442 | MvField *mv = &TAB_MVF(x, y); | |
283 | |||
284 | 7126442 | mv->pred_flag = pf; | |
285 | 7126442 | mv->ciip_flag = ciip_flag; | |
286 | } | ||
287 | } | ||
288 | 696757 | } | |
289 | |||
290 | //cbProfFlagLX from 8.5.5.9 Derivation process for motion vector arrays from affine control point motion vectors | ||
291 | 46434 | static int derive_cb_prof_flag_lx(const VVCLocalContext *lc, const PredictionUnit* pu, int lx, int is_fallback) | |
292 | { | ||
293 | 46434 | const MotionInfo* mi = &pu->mi; | |
294 | 46434 | const Mv* cp_mv = &mi->mv[lx][0]; | |
295 |
4/4✓ Branch 0 taken 46267 times.
✓ Branch 1 taken 167 times.
✓ Branch 2 taken 1104 times.
✓ Branch 3 taken 45163 times.
|
46434 | if (lc->fc->ps.ph.r->ph_prof_disabled_flag || is_fallback) |
296 | 1271 | return 0; | |
297 |
2/2✓ Branch 0 taken 19026 times.
✓ Branch 1 taken 26137 times.
|
45163 | if (mi->motion_model_idc == MOTION_4_PARAMS_AFFINE) { |
298 |
2/2✓ Branch 0 taken 5534 times.
✓ Branch 1 taken 13492 times.
|
19026 | if (IS_SAME_MV(cp_mv, cp_mv + 1)) |
299 | 5534 | return 0; | |
300 | } | ||
301 |
2/2✓ Branch 0 taken 26137 times.
✓ Branch 1 taken 13492 times.
|
39629 | if (mi->motion_model_idc == MOTION_6_PARAMS_AFFINE) { |
302 |
4/4✓ Branch 0 taken 4643 times.
✓ Branch 1 taken 21494 times.
✓ Branch 2 taken 1152 times.
✓ Branch 3 taken 3491 times.
|
26137 | if (IS_SAME_MV(cp_mv, cp_mv + 1) && IS_SAME_MV(cp_mv, cp_mv + 2)) |
303 | 1152 | return 0; | |
304 | } | ||
305 |
2/2✓ Branch 0 taken 137 times.
✓ Branch 1 taken 38340 times.
|
38477 | if (lc->sc->rpl[lx].refs[mi->ref_idx[lx]].is_scaled) |
306 | 137 | return 0; | |
307 | 38340 | return 1; | |
308 | } | ||
309 | |||
310 | typedef struct SubblockParams { | ||
311 | int d_hor_x; | ||
312 | int d_ver_x; | ||
313 | int d_hor_y; | ||
314 | int d_ver_y; | ||
315 | int mv_scale_hor; | ||
316 | int mv_scale_ver; | ||
317 | int is_fallback; | ||
318 | |||
319 | int cb_width; | ||
320 | int cb_height; | ||
321 | } SubblockParams; | ||
322 | |||
323 | 46434 | static int is_fallback_mode(const SubblockParams *sp, const PredFlag pred_flag) | |
324 | { | ||
325 | 46434 | const int a = 4 * (2048 + sp->d_hor_x); | |
326 | 46434 | const int b = 4 * sp->d_hor_y; | |
327 | 46434 | const int c = 4 * (2048 + sp->d_ver_y); | |
328 | 46434 | const int d = 4 * sp->d_ver_x; | |
329 |
2/2✓ Branch 0 taken 20940 times.
✓ Branch 1 taken 25494 times.
|
46434 | if (pred_flag == PF_BI) { |
330 |
2/2✓ Branch 0 taken 20829 times.
✓ Branch 1 taken 111 times.
|
20940 | const int max_w4 = FFMAX(0, FFMAX(a, FFMAX(b, a + b))); |
331 |
2/2✓ Branch 0 taken 111 times.
✓ Branch 1 taken 20829 times.
|
20940 | const int min_w4 = FFMIN(0, FFMIN(a, FFMIN(b, a + b))); |
332 |
2/2✓ Branch 0 taken 20840 times.
✓ Branch 1 taken 100 times.
|
20940 | const int max_h4 = FFMAX(0, FFMAX(c, FFMAX(d, c + d))); |
333 |
2/2✓ Branch 0 taken 100 times.
✓ Branch 1 taken 20840 times.
|
20940 | const int min_h4 = FFMIN(0, FFMIN(c, FFMIN(d, c + d))); |
334 | 20940 | const int bx_wx4 = ((max_w4 - min_w4) >> 11) + 9; | |
335 | 20940 | const int bx_hx4 = ((max_h4 - min_h4) >> 11) + 9; | |
336 | 20940 | return bx_wx4 * bx_hx4 > 225; | |
337 | } else { | ||
338 | 25494 | const int bx_wxh = (FFABS(a) >> 11) + 9; | |
339 | 25494 | const int bx_hxh = (FFABS(d) >> 11) + 9; | |
340 | 25494 | const int bx_wxv = (FFABS(b) >> 11) + 9; | |
341 | 25494 | const int bx_hxv = (FFABS(c) >> 11) + 9; | |
342 |
4/4✓ Branch 0 taken 24827 times.
✓ Branch 1 taken 667 times.
✓ Branch 2 taken 24733 times.
✓ Branch 3 taken 94 times.
|
25494 | if (bx_wxh * bx_hxh <= 165 && bx_wxv * bx_hxv <= 165) |
343 | 24733 | return 0; | |
344 | } | ||
345 | 761 | return 1; | |
346 | } | ||
347 | |||
348 | 46434 | static void init_subblock_params(SubblockParams *sp, const MotionInfo* mi, | |
349 | const int cb_width, const int cb_height, const int lx) | ||
350 | { | ||
351 | 46434 | const int log2_cbw = av_log2(cb_width); | |
352 | 46434 | const int log2_cbh = av_log2(cb_height); | |
353 | 46434 | const Mv* cp_mv = mi->mv[lx]; | |
354 | 46434 | const int num_cp_mv = mi->motion_model_idc + 1; | |
355 | 46434 | sp->d_hor_x = (cp_mv[1].x - cp_mv[0].x) * (1 << (MAX_CU_DEPTH - log2_cbw)); | |
356 | 46434 | sp->d_ver_x = (cp_mv[1].y - cp_mv[0].y) * (1 << (MAX_CU_DEPTH - log2_cbw)); | |
357 |
2/2✓ Branch 0 taken 26530 times.
✓ Branch 1 taken 19904 times.
|
46434 | if (num_cp_mv == 3) { |
358 | 26530 | sp->d_hor_y = (cp_mv[2].x - cp_mv[0].x) * (1 << (MAX_CU_DEPTH - log2_cbh)); | |
359 | 26530 | sp->d_ver_y = (cp_mv[2].y - cp_mv[0].y) * (1 << (MAX_CU_DEPTH - log2_cbh)); | |
360 | } else { | ||
361 | 19904 | sp->d_hor_y = -sp->d_ver_x; | |
362 | 19904 | sp->d_ver_y = sp->d_hor_x; | |
363 | } | ||
364 | 46434 | sp->mv_scale_hor = (cp_mv[0].x) * (1 << MAX_CU_DEPTH); | |
365 | 46434 | sp->mv_scale_ver = (cp_mv[0].y) * (1 << MAX_CU_DEPTH); | |
366 | 46434 | sp->cb_width = cb_width; | |
367 | 46434 | sp->cb_height = cb_height; | |
368 | 46434 | sp->is_fallback = is_fallback_mode(sp, mi->pred_flag); | |
369 | 46434 | } | |
370 | |||
371 | 46434 | static void derive_subblock_diff_mvs(const VVCLocalContext *lc, PredictionUnit* pu, const SubblockParams* sp, const int lx) | |
372 | { | ||
373 | 46434 | pu->cb_prof_flag[lx] = derive_cb_prof_flag_lx(lc, pu, lx, sp->is_fallback); | |
374 |
2/2✓ Branch 0 taken 38340 times.
✓ Branch 1 taken 8094 times.
|
46434 | if (pu->cb_prof_flag[lx]) { |
375 | 38340 | const int dmv_limit = 1 << 5; | |
376 | 38340 | const int pos_offset_x = 6 * (sp->d_hor_x + sp->d_hor_y); | |
377 | 38340 | const int pos_offset_y = 6 * (sp->d_ver_x + sp->d_ver_y); | |
378 |
2/2✓ Branch 0 taken 153360 times.
✓ Branch 1 taken 38340 times.
|
191700 | for (int x = 0; x < AFFINE_MIN_BLOCK_SIZE; x++) { |
379 |
2/2✓ Branch 0 taken 613440 times.
✓ Branch 1 taken 153360 times.
|
766800 | for (int y = 0; y < AFFINE_MIN_BLOCK_SIZE; y++) { |
380 | 613440 | LOCAL_ALIGNED_8(Mv, diff, [1]); | |
381 | 613440 | diff->x = x * (sp->d_hor_x * (1 << 2)) + y * (sp->d_hor_y * (1 << 2)) - pos_offset_x; | |
382 | 613440 | diff->y = x * (sp->d_ver_x * (1 << 2)) + y * (sp->d_ver_y * (1 << 2)) - pos_offset_y; | |
383 | 613440 | ff_vvc_round_mv(diff, 0, 8); | |
384 | 613440 | pu->diff_mv_x[lx][AFFINE_MIN_BLOCK_SIZE * y + x] = av_clip(diff->x, -dmv_limit + 1, dmv_limit - 1); | |
385 | 613440 | pu->diff_mv_y[lx][AFFINE_MIN_BLOCK_SIZE * y + x] = av_clip(diff->y, -dmv_limit + 1, dmv_limit - 1); | |
386 | } | ||
387 | } | ||
388 | } | ||
389 | 46434 | } | |
390 | |||
391 | 46434 | static void store_cp_mv(const VVCLocalContext *lc, const MotionInfo *mi, const int lx) | |
392 | { | ||
393 | 46434 | VVCFrameContext *fc = lc->fc; | |
394 | 46434 | const CodingUnit *cu = lc->cu; | |
395 | 46434 | const int log2_min_cb_size = fc->ps.sps->min_cb_log2_size_y; | |
396 | 46434 | const int min_cb_size = fc->ps.sps->min_cb_size_y; | |
397 | 46434 | const int min_cb_width = fc->ps.pps->min_cb_width; | |
398 | 46434 | const int num_cp_mv = mi->motion_model_idc + 1; | |
399 | |||
400 |
2/2✓ Branch 0 taken 364970 times.
✓ Branch 1 taken 46434 times.
|
411404 | for (int dy = 0; dy < cu->cb_height; dy += min_cb_size) { |
401 |
2/2✓ Branch 0 taken 4579736 times.
✓ Branch 1 taken 364970 times.
|
4944706 | for (int dx = 0; dx < cu->cb_width; dx += min_cb_size) { |
402 | 4579736 | const int x_cb = (cu->x0 + dx) >> log2_min_cb_size; | |
403 | 4579736 | const int y_cb = (cu->y0 + dy) >> log2_min_cb_size; | |
404 | 4579736 | const int offset = (y_cb * min_cb_width + x_cb) * MAX_CONTROL_POINTS; | |
405 | |||
406 | 4579736 | memcpy(&fc->tab.cp_mv[lx][offset], mi->mv[lx], sizeof(Mv) * num_cp_mv); | |
407 | } | ||
408 | } | ||
409 | 46434 | } | |
410 | |||
411 | //8.5.5.9 Derivation process for motion vector arrays from affine control point motion vectors | ||
412 | 35964 | void ff_vvc_store_sb_mvs(const VVCLocalContext *lc, PredictionUnit *pu) | |
413 | { | ||
414 | 35964 | const CodingUnit *cu = lc->cu; | |
415 | 35964 | const MotionInfo *mi = &pu->mi; | |
416 | 35964 | const int sbw = cu->cb_width / mi->num_sb_x; | |
417 | 35964 | const int sbh = cu->cb_height / mi->num_sb_y; | |
418 | SubblockParams params[2]; | ||
419 | 35964 | MvField mvf = {0}; | |
420 | |||
421 | 35964 | mvf.pred_flag = mi->pred_flag; | |
422 | 35964 | mvf.bcw_idx = mi->bcw_idx; | |
423 | 35964 | mvf.hpel_if_idx = mi->hpel_if_idx; | |
424 |
2/2✓ Branch 0 taken 71928 times.
✓ Branch 1 taken 35964 times.
|
107892 | for (int i = 0; i < 2; i++) { |
425 | 71928 | const PredFlag mask = i + 1; | |
426 |
2/2✓ Branch 0 taken 46434 times.
✓ Branch 1 taken 25494 times.
|
71928 | if (mi->pred_flag & mask) { |
427 | 46434 | store_cp_mv(lc, mi, i); | |
428 | 46434 | init_subblock_params(params + i, mi, cu->cb_width, cu->cb_height, i); | |
429 | 46434 | derive_subblock_diff_mvs(lc, pu, params + i, i); | |
430 | 46434 | mvf.ref_idx[i] = mi->ref_idx[i]; | |
431 | } | ||
432 | } | ||
433 | |||
434 |
2/2✓ Branch 0 taken 284102 times.
✓ Branch 1 taken 35964 times.
|
320066 | for (int sby = 0; sby < mi->num_sb_y; sby++) { |
435 |
2/2✓ Branch 0 taken 3527044 times.
✓ Branch 1 taken 284102 times.
|
3811146 | for (int sbx = 0; sbx < mi->num_sb_x; sbx++) { |
436 | 3527044 | const int x0 = cu->x0 + sbx * sbw; | |
437 | 3527044 | const int y0 = cu->y0 + sby * sbh; | |
438 |
2/2✓ Branch 0 taken 7054088 times.
✓ Branch 1 taken 3527044 times.
|
10581132 | for (int i = 0; i < 2; i++) { |
439 | 7054088 | const PredFlag mask = i + 1; | |
440 |
2/2✓ Branch 0 taken 4579736 times.
✓ Branch 1 taken 2474352 times.
|
7054088 | if (mi->pred_flag & mask) { |
441 | 4579736 | const SubblockParams* sp = params + i; | |
442 |
2/2✓ Branch 0 taken 141736 times.
✓ Branch 1 taken 4438000 times.
|
4579736 | const int x_pos_cb = sp->is_fallback ? (cu->cb_width >> 1) : (2 + (sbx << MIN_CU_LOG2)); |
443 |
2/2✓ Branch 0 taken 141736 times.
✓ Branch 1 taken 4438000 times.
|
4579736 | const int y_pos_cb = sp->is_fallback ? (cu->cb_height >> 1) : (2 + (sby << MIN_CU_LOG2)); |
444 | 4579736 | Mv *mv = mvf.mv + i; | |
445 | |||
446 | 4579736 | mv->x = sp->mv_scale_hor + sp->d_hor_x * x_pos_cb + sp->d_hor_y * y_pos_cb; | |
447 | 4579736 | mv->y = sp->mv_scale_ver + sp->d_ver_x * x_pos_cb + sp->d_ver_y * y_pos_cb; | |
448 | 4579736 | ff_vvc_round_mv(mv, 0, MAX_CU_DEPTH); | |
449 | 4579736 | ff_vvc_clip_mv(mv); | |
450 | } | ||
451 | } | ||
452 | 3527044 | ff_vvc_set_mvf(lc, x0, y0, sbw, sbh, &mvf); | |
453 | } | ||
454 | } | ||
455 | 35964 | } | |
456 | |||
457 | 27591 | void ff_vvc_store_gpm_mvf(const VVCLocalContext *lc, const PredictionUnit *pu) | |
458 | { | ||
459 | 27591 | const CodingUnit *cu = lc->cu; | |
460 | 27591 | const int angle_idx = ff_vvc_gpm_angle_idx[pu->gpm_partition_idx]; | |
461 | 27591 | const int distance_idx = ff_vvc_gpm_distance_idx[pu->gpm_partition_idx]; | |
462 | 27591 | const int displacement_x = ff_vvc_gpm_distance_lut[angle_idx]; | |
463 | 27591 | const int displacement_y = ff_vvc_gpm_distance_lut[(angle_idx + 8) % 32]; | |
464 |
4/4✓ Branch 0 taken 14493 times.
✓ Branch 1 taken 13098 times.
✓ Branch 2 taken 11692 times.
✓ Branch 3 taken 2801 times.
|
27591 | const int is_flip = angle_idx >= 13 &&angle_idx <= 27; |
465 |
6/6✓ Branch 0 taken 25441 times.
✓ Branch 1 taken 2150 times.
✓ Branch 2 taken 22418 times.
✓ Branch 3 taken 3023 times.
✓ Branch 4 taken 5658 times.
✓ Branch 5 taken 16760 times.
|
27591 | const int shift_hor = (angle_idx % 16 == 8 || (angle_idx % 16 && cu->cb_height >= cu->cb_width)) ? 0 : 1; |
466 |
2/2✓ Branch 0 taken 16162 times.
✓ Branch 1 taken 11429 times.
|
27591 | const int sign = angle_idx < 16 ? 1 : -1; |
467 | 27591 | const int block_size = 4; | |
468 | 27591 | int offset_x = (-cu->cb_width) >> 1; | |
469 | 27591 | int offset_y = (-cu->cb_height) >> 1; | |
470 | |||
471 |
2/2✓ Branch 0 taken 18910 times.
✓ Branch 1 taken 8681 times.
|
27591 | if (!shift_hor) |
472 | 18910 | offset_y += sign * ((distance_idx * cu->cb_height) >> 3); | |
473 | else | ||
474 | 8681 | offset_x += sign * ((distance_idx * cu->cb_width) >> 3); | |
475 | |||
476 |
2/2✓ Branch 0 taken 124750 times.
✓ Branch 1 taken 27591 times.
|
152341 | for (int y = 0; y < cu->cb_height; y += block_size) { |
477 |
2/2✓ Branch 0 taken 615676 times.
✓ Branch 1 taken 124750 times.
|
740426 | for (int x = 0; x < cu->cb_width; x += block_size) { |
478 | 615676 | const int motion_idx = (((x + offset_x) * (1 << 1)) + 5) * displacement_x + | |
479 | 615676 | (((y + offset_y) * (1 << 1)) + 5) * displacement_y; | |
480 |
6/6✓ Branch 0 taken 305044 times.
✓ Branch 1 taken 310632 times.
✓ Branch 2 taken 188260 times.
✓ Branch 3 taken 116784 times.
✓ Branch 4 taken 310632 times.
✓ Branch 5 taken 188260 times.
|
615676 | const int s_type = FFABS(motion_idx) < 32 ? 2 : (motion_idx <= 0 ? (1 - is_flip) : is_flip); |
481 | 615676 | const int pred_flag = pu->gpm_mv[0].pred_flag | pu->gpm_mv[1].pred_flag; | |
482 | 615676 | const int x0 = cu->x0 + x; | |
483 | 615676 | const int y0 = cu->y0 + y; | |
484 | |||
485 |
2/2✓ Branch 0 taken 243965 times.
✓ Branch 1 taken 371711 times.
|
615676 | if (!s_type) |
486 | 243965 | ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, pu->gpm_mv + 0); | |
487 |
5/6✓ Branch 0 taken 116784 times.
✓ Branch 1 taken 254927 times.
✓ Branch 2 taken 116784 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 61459 times.
✓ Branch 5 taken 55325 times.
|
371711 | else if (s_type == 1 || (s_type == 2 && pred_flag != PF_BI)) |
488 | 316386 | ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, pu->gpm_mv + 1); | |
489 | else { | ||
490 | 55325 | MvField mvf = pu->gpm_mv[0]; | |
491 | 55325 | const MvField *mv1 = &pu->gpm_mv[1]; | |
492 | 55325 | const int lx = mv1->pred_flag - PF_L0; | |
493 | 55325 | mvf.pred_flag = PF_BI; | |
494 | 55325 | mvf.ref_idx[lx] = mv1->ref_idx[lx]; | |
495 | 55325 | mvf.mv[lx] = mv1->mv[lx]; | |
496 | 55325 | ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, &mvf); | |
497 | } | ||
498 | } | ||
499 | } | ||
500 | 27591 | } | |
501 | |||
502 | 297332 | void ff_vvc_store_mvf(const VVCLocalContext *lc, const MvField *mvf) | |
503 | { | ||
504 | 297332 | const CodingUnit *cu = lc->cu; | |
505 | 297332 | ff_vvc_set_mvf(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height, mvf); | |
506 | 297332 | } | |
507 | |||
508 | 137668 | void ff_vvc_store_mv(const VVCLocalContext *lc, const MotionInfo *mi) | |
509 | { | ||
510 | 137668 | const CodingUnit *cu = lc->cu; | |
511 | 137668 | MvField mvf = {0}; | |
512 | |||
513 | 137668 | mvf.hpel_if_idx = mi->hpel_if_idx; | |
514 | 137668 | mvf.bcw_idx = mi->bcw_idx; | |
515 | 137668 | mvf.pred_flag = mi->pred_flag; | |
516 | |||
517 |
2/2✓ Branch 0 taken 275336 times.
✓ Branch 1 taken 137668 times.
|
413004 | for (int i = 0; i < 2; i++) { |
518 | 275336 | const PredFlag mask = i + 1; | |
519 |
2/2✓ Branch 0 taken 157079 times.
✓ Branch 1 taken 118257 times.
|
275336 | if (mvf.pred_flag & mask) { |
520 | 157079 | mvf.mv[i] = mi->mv[i][0]; | |
521 | 157079 | mvf.ref_idx[i] = mi->ref_idx[i]; | |
522 | } | ||
523 | } | ||
524 | 137668 | ff_vvc_set_mvf(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height, &mvf); | |
525 | 137668 | } | |
526 | |||
527 | typedef enum NeighbourIdx { | ||
528 | A0, | ||
529 | A1, | ||
530 | A2, | ||
531 | B0, | ||
532 | B1, | ||
533 | B2, | ||
534 | B3, | ||
535 | NUM_NBS, | ||
536 | NB_IDX_NONE = NUM_NBS, | ||
537 | } NeighbourIdx; | ||
538 | |||
539 | typedef struct Neighbour { | ||
540 | int x; | ||
541 | int y; | ||
542 | |||
543 | int checked; | ||
544 | int available; | ||
545 | } Neighbour; | ||
546 | |||
547 | typedef struct NeighbourContext { | ||
548 | Neighbour neighbours[NUM_NBS]; | ||
549 | const VVCLocalContext *lc; | ||
550 | } NeighbourContext; | ||
551 | |||
552 | 1476472 | static int is_available(const VVCFrameContext *fc, const int x0, const int y0) | |
553 | { | ||
554 | 1476472 | const VVCSPS *sps = fc->ps.sps; | |
555 | 1476472 | const int x = x0 >> sps->min_cb_log2_size_y; | |
556 | 1476472 | const int y = y0 >> sps->min_cb_log2_size_y; | |
557 | 1476472 | const int min_cb_width = fc->ps.pps->min_cb_width; | |
558 | |||
559 | 1476472 | return SAMPLE_CTB(fc->tab.cb_width[0], x, y) != 0; | |
560 | } | ||
561 | |||
562 | 527621 | static int is_a0_available(const VVCLocalContext *lc, const CodingUnit *cu) | |
563 | { | ||
564 | 527621 | const VVCFrameContext *fc = lc->fc; | |
565 | 527621 | const VVCSPS *sps = fc->ps.sps; | |
566 | 527621 | const int x0b = av_zero_extend(cu->x0, sps->ctb_log2_size_y); | |
567 | int cand_bottom_left; | ||
568 | |||
569 |
4/4✓ Branch 0 taken 114515 times.
✓ Branch 1 taken 413106 times.
✓ Branch 2 taken 15913 times.
✓ Branch 3 taken 98602 times.
|
527621 | if (!x0b && !lc->ctb_left_flag) { |
570 | 15913 | cand_bottom_left = 0; | |
571 | } else { | ||
572 | 511708 | const int max_y = FFMIN(fc->ps.pps->height, ((cu->y0 >> sps->ctb_log2_size_y) + 1) << sps->ctb_log2_size_y); | |
573 |
2/2✓ Branch 0 taken 104485 times.
✓ Branch 1 taken 407223 times.
|
511708 | if (cu->y0 + cu->cb_height >= max_y) |
574 | 104485 | cand_bottom_left = 0; | |
575 | else | ||
576 | 407223 | cand_bottom_left = is_available(fc, cu->x0 - 1, cu->y0 + cu->cb_height); | |
577 | } | ||
578 | 527621 | return cand_bottom_left; | |
579 | } | ||
580 | |||
581 | 527621 | static void init_neighbour_context(NeighbourContext *ctx, const VVCLocalContext *lc) | |
582 | { | ||
583 | 527621 | const CodingUnit *cu = lc->cu; | |
584 | 527621 | const NeighbourAvailable *na = &lc->na; | |
585 | 527621 | const int x0 = cu->x0; | |
586 | 527621 | const int y0 = cu->y0; | |
587 | 527621 | const int cb_width = cu->cb_width; | |
588 | 527621 | const int cb_height = cu->cb_height; | |
589 | 527621 | const int a0_available = is_a0_available(lc, cu); | |
590 | |||
591 | 527621 | Neighbour neighbours[NUM_NBS] = { | |
592 | 527621 | { x0 - 1, y0 + cb_height, !a0_available }, //A0 | |
593 | 527621 | { x0 - 1, y0 + cb_height - 1, !na->cand_left }, //A1 | |
594 | 527621 | { x0 - 1, y0, !na->cand_left }, //A2 | |
595 | 527621 | { x0 + cb_width, y0 - 1, !na->cand_up_right }, //B0 | |
596 | 527621 | { x0 + cb_width - 1, y0 - 1, !na->cand_up }, //B1 | |
597 | 527621 | { x0 - 1, y0 - 1, !na->cand_up_left }, //B2 | |
598 | 527621 | { x0, y0 - 1, !na->cand_up }, //B3 | |
599 | }; | ||
600 | |||
601 | 527621 | memcpy(ctx->neighbours, neighbours, sizeof(neighbours)); | |
602 | 527621 | ctx->lc = lc; | |
603 | 527621 | } | |
604 | |||
605 | 1019121 | static av_always_inline PredMode pred_flag_to_mode(PredFlag pred) | |
606 | { | ||
607 | static const PredMode lut[] = { | ||
608 | MODE_INTRA, // PF_INTRA | ||
609 | MODE_INTER, // PF_L0 | ||
610 | MODE_INTER, // PF_L1 | ||
611 | MODE_INTER, // PF_BI | ||
612 | 0, // invalid | ||
613 | MODE_IBC, // PF_IBC | ||
614 | 0, // invalid | ||
615 | 0, // invalid | ||
616 | MODE_PLT, // PF_PLT | ||
617 | }; | ||
618 | |||
619 | 1019121 | return lut[pred]; | |
620 | } | ||
621 | |||
622 | 1369450 | static int check_available(Neighbour *n, const VVCLocalContext *lc, const int check_mer) | |
623 | { | ||
624 | 1369450 | const VVCFrameContext *fc = lc->fc; | |
625 | 1369450 | const VVCSPS *sps = fc->ps.sps; | |
626 | 1369450 | const CodingUnit *cu = lc->cu; | |
627 | 1369450 | const MvField *tab_mvf = fc->tab.mvf; | |
628 | 1369450 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
629 | |||
630 |
2/2✓ Branch 0 taken 1069449 times.
✓ Branch 1 taken 300001 times.
|
1369450 | if (!n->checked) { |
631 | 1069449 | n->checked = 1; | |
632 |
4/4✓ Branch 0 taken 87906 times.
✓ Branch 1 taken 981543 times.
✓ Branch 2 taken 87706 times.
✓ Branch 3 taken 200 times.
|
1069449 | n->available = !sps->r->sps_entropy_coding_sync_enabled_flag || ((n->x >> sps->ctb_log2_size_y) <= (cu->x0 >> sps->ctb_log2_size_y)); |
633 |
6/6✓ Branch 0 taken 1069249 times.
✓ Branch 1 taken 200 times.
✓ Branch 3 taken 1019121 times.
✓ Branch 4 taken 50128 times.
✓ Branch 6 taken 903541 times.
✓ Branch 7 taken 115580 times.
|
1069449 | 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); |
634 |
2/2✓ Branch 0 taken 748152 times.
✓ Branch 1 taken 321297 times.
|
1069449 | if (check_mer) |
635 |
4/4✓ Branch 0 taken 673964 times.
✓ Branch 1 taken 74188 times.
✓ Branch 3 taken 667772 times.
✓ Branch 4 taken 6192 times.
|
748152 | n->available = n->available && !is_same_mer(fc, n->x, n->y, cu->x0, cu->y0); |
636 | } | ||
637 | 1369450 | return n->available; | |
638 | } | ||
639 | |||
640 | 564533 | static const MvField *mv_merge_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand) | |
641 | { | ||
642 | 564533 | const VVCFrameContext *fc = lc->fc; | |
643 | 564533 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
644 | 564533 | const MvField* tab_mvf = fc->tab.mvf; | |
645 | 564533 | const MvField *mvf = &TAB_MVF(x_cand, y_cand); | |
646 | |||
647 | 564533 | return mvf; | |
648 | } | ||
649 | |||
650 | 716161 | static const MvField* mv_merge_from_nb(NeighbourContext *ctx, const NeighbourIdx nb) | |
651 | { | ||
652 | 716161 | const VVCLocalContext *lc = ctx->lc; | |
653 | 716161 | Neighbour *n = &ctx->neighbours[nb]; | |
654 | |||
655 |
2/2✓ Branch 1 taken 564533 times.
✓ Branch 2 taken 151628 times.
|
716161 | if (check_available(n, lc, 1)) |
656 | 564533 | return mv_merge_candidate(lc, n->x, n->y); | |
657 | 151628 | return 0; | |
658 | } | ||
659 | #define MV_MERGE_FROM_NB(nb) mv_merge_from_nb(&nctx, nb) | ||
660 | |||
661 | //8.5.2.3 Derivation process for spatial merging candidates | ||
662 | 324923 | static int mv_merge_spatial_candidates(const VVCLocalContext *lc, const int merge_idx, | |
663 | const MvField **nb_list, MvField *cand_list, int *nb_merge_cand) | ||
664 | { | ||
665 | const MvField *cand; | ||
666 | 324923 | int num_cands = 0; | |
667 | NeighbourContext nctx; | ||
668 | |||
669 | static NeighbourIdx nbs[][2] = { | ||
670 | {B1, NB_IDX_NONE }, | ||
671 | {A1, B1 }, | ||
672 | {B0, B1 }, | ||
673 | {A0, A1 }, | ||
674 | }; | ||
675 | |||
676 | 324923 | init_neighbour_context(&nctx, lc); | |
677 |
2/2✓ Branch 0 taken 648531 times.
✓ Branch 1 taken 68317 times.
|
716848 | for (int i = 0; i < FF_ARRAY_ELEMS(nbs); i++) { |
678 | 648531 | NeighbourIdx nb = nbs[i][0]; | |
679 | 648531 | NeighbourIdx old = nbs[i][1]; | |
680 | 648531 | cand = nb_list[nb] = MV_MERGE_FROM_NB(nb); | |
681 |
4/4✓ Branch 0 taken 511344 times.
✓ Branch 1 taken 137187 times.
✓ Branch 3 taken 462802 times.
✓ Branch 4 taken 48542 times.
|
648531 | if (cand && !compare_mv_ref_idx(cand, nb_list[old])) { |
682 | 462802 | cand_list[num_cands] = *cand; | |
683 |
2/2✓ Branch 0 taken 256606 times.
✓ Branch 1 taken 206196 times.
|
462802 | if (merge_idx == num_cands) |
684 | 256606 | return 1; | |
685 | 206196 | num_cands++; | |
686 | } | ||
687 | } | ||
688 |
2/2✓ Branch 0 taken 67630 times.
✓ Branch 1 taken 687 times.
|
68317 | if (num_cands != 4) { |
689 | 67630 | cand = MV_MERGE_FROM_NB(B2); | |
690 |
4/4✓ Branch 0 taken 53189 times.
✓ Branch 1 taken 14441 times.
✓ Branch 3 taken 32216 times.
✓ Branch 4 taken 20973 times.
|
67630 | if (cand && !compare_mv_ref_idx(cand, nb_list[A1]) |
691 |
2/2✓ Branch 1 taken 22671 times.
✓ Branch 2 taken 9545 times.
|
32216 | && !compare_mv_ref_idx(cand, nb_list[B1])) { |
692 | 22671 | cand_list[num_cands] = *cand; | |
693 |
2/2✓ Branch 0 taken 10164 times.
✓ Branch 1 taken 12507 times.
|
22671 | if (merge_idx == num_cands) |
694 | 10164 | return 1; | |
695 | 12507 | num_cands++; | |
696 | } | ||
697 | } | ||
698 | 58153 | *nb_merge_cand = num_cands; | |
699 | 58153 | return 0; | |
700 | } | ||
701 | |||
702 | 58153 | static int mv_merge_temporal_candidate(const VVCLocalContext *lc, MvField *cand) | |
703 | { | ||
704 | 58153 | const VVCFrameContext *fc = lc->fc; | |
705 | 58153 | const CodingUnit *cu = lc->cu; | |
706 | |||
707 | 58153 | memset(cand, 0, sizeof(*cand)); | |
708 |
4/4✓ Branch 0 taken 58006 times.
✓ Branch 1 taken 147 times.
✓ Branch 2 taken 54207 times.
✓ Branch 3 taken 3799 times.
|
58153 | if (fc->ps.ph.r->ph_temporal_mvp_enabled_flag && (cu->cb_width * cu->cb_height > 32)) { |
709 | 54207 | int available_l0 = temporal_luma_motion_vector(lc, 0, cand->mv + 0, 0, 1, 0); | |
710 | 108414 | int available_l1 = IS_B(lc->sc->sh.r) ? | |
711 |
2/2✓ Branch 0 taken 51418 times.
✓ Branch 1 taken 2789 times.
|
54207 | temporal_luma_motion_vector(lc, 0, cand->mv + 1, 1, 1, 0) : 0; |
712 | 54207 | cand->pred_flag = available_l0 + (available_l1 << 1); | |
713 | } | ||
714 | 58153 | return cand->pred_flag; | |
715 | } | ||
716 | |||
717 | //8.5.2.6 Derivation process for history-based merging candidates | ||
718 | 37069 | static int mv_merge_history_candidates(const VVCLocalContext *lc, const int merge_idx, | |
719 | const MvField **nb_list, MvField *cand_list, int *num_cands) | ||
720 | { | ||
721 | 37069 | const VVCSPS *sps = lc->fc->ps.sps; | |
722 | 37069 | const EntryPoint* ep = lc->ep; | |
723 |
4/4✓ Branch 0 taken 94908 times.
✓ Branch 1 taken 2779 times.
✓ Branch 2 taken 86096 times.
✓ Branch 3 taken 8812 times.
|
97687 | for (int i = 1; i <= ep->num_hmvp && (*num_cands < sps->max_num_merge_cand - 1); i++) { |
724 | 86096 | const MvField *h = &ep->hmvp[ep->num_hmvp - i]; | |
725 |
6/6✓ Branch 0 taken 63271 times.
✓ Branch 1 taken 22825 times.
✓ Branch 3 taken 43601 times.
✓ Branch 4 taken 19670 times.
✓ Branch 6 taken 10824 times.
✓ Branch 7 taken 32777 times.
|
86096 | const int same_motion = i <= 2 && (compare_mv_ref_idx(h, nb_list[A1]) || compare_mv_ref_idx(h, nb_list[B1])); |
726 |
2/2✓ Branch 0 taken 55602 times.
✓ Branch 1 taken 30494 times.
|
86096 | if (!same_motion) { |
727 | 55602 | cand_list[*num_cands] = *h; | |
728 |
2/2✓ Branch 0 taken 25478 times.
✓ Branch 1 taken 30124 times.
|
55602 | if (merge_idx == *num_cands) |
729 | 25478 | return 1; | |
730 | 30124 | (*num_cands)++; | |
731 | } | ||
732 | } | ||
733 | 11591 | return 0; | |
734 | } | ||
735 | |||
736 | //8.5.2.4 Derivation process for pairwise average merging candidate | ||
737 | 11591 | static int mv_merge_pairwise_candidate(MvField *cand_list, const int num_cands, const int is_b) | |
738 | { | ||
739 |
2/2✓ Branch 0 taken 10783 times.
✓ Branch 1 taken 808 times.
|
11591 | if (num_cands > 1) { |
740 |
2/2✓ Branch 0 taken 10259 times.
✓ Branch 1 taken 524 times.
|
10783 | const int num_ref_rists = is_b ? 2 : 1; |
741 | 10783 | const MvField* p0 = cand_list + 0; | |
742 | 10783 | const MvField* p1 = cand_list + 1; | |
743 | 10783 | MvField* cand = cand_list + num_cands; | |
744 | |||
745 | 10783 | cand->pred_flag = 0; | |
746 |
2/2✓ Branch 0 taken 21042 times.
✓ Branch 1 taken 10783 times.
|
31825 | for (int i = 0; i < num_ref_rists; i++) { |
747 | 21042 | PredFlag mask = i + 1; | |
748 |
2/2✓ Branch 0 taken 17251 times.
✓ Branch 1 taken 3791 times.
|
21042 | if (p0->pred_flag & mask) { |
749 | 17251 | cand->pred_flag |= mask; | |
750 | 17251 | cand->ref_idx[i] = p0->ref_idx[i]; | |
751 |
2/2✓ Branch 0 taken 15285 times.
✓ Branch 1 taken 1966 times.
|
17251 | if (p1->pred_flag & mask) { |
752 | 15285 | Mv *mv = cand->mv + i; | |
753 | 15285 | mv->x = p0->mv[i].x + p1->mv[i].x; | |
754 | 15285 | mv->y = p0->mv[i].y + p1->mv[i].y; | |
755 | 15285 | ff_vvc_round_mv(mv, 0, 1); | |
756 | } else { | ||
757 | 1966 | cand->mv[i] = p0->mv[i]; | |
758 | } | ||
759 |
2/2✓ Branch 0 taken 2253 times.
✓ Branch 1 taken 1538 times.
|
3791 | } else if (p1->pred_flag & mask) { |
760 | 2253 | cand->pred_flag |= mask; | |
761 | 2253 | cand->mv[i] = p1->mv[i]; | |
762 | 2253 | cand->ref_idx[i] = p1->ref_idx[i]; | |
763 | } | ||
764 | } | ||
765 |
1/2✓ Branch 0 taken 10783 times.
✗ Branch 1 not taken.
|
10783 | if (cand->pred_flag) { |
766 |
2/2✓ Branch 0 taken 10014 times.
✓ Branch 1 taken 769 times.
|
10783 | cand->hpel_if_idx = p0->hpel_if_idx == p1->hpel_if_idx ? p0->hpel_if_idx : 0; |
767 | 10783 | cand->bcw_idx = 0; | |
768 | 10783 | cand->ciip_flag = 0; | |
769 | 10783 | return 1; | |
770 | } | ||
771 | } | ||
772 | 808 | return 0; | |
773 | } | ||
774 | |||
775 | //8.5.2.5 Derivation process for zero motion vector merging candidates | ||
776 | 1381 | static void mv_merge_zero_motion_candidate(const VVCLocalContext *lc, const int merge_idx, | |
777 | MvField *cand_list, int num_cands) | ||
778 | { | ||
779 | 1381 | const VVCSPS *sps = lc->fc->ps.sps; | |
780 | 1381 | const H266RawSliceHeader *rsh = lc->sc->sh.r; | |
781 | 2762 | const int num_ref_idx = IS_P(rsh) ? | |
782 |
2/2✓ Branch 0 taken 210 times.
✓ Branch 1 taken 1171 times.
|
1381 | rsh->num_ref_idx_active[L0] : FFMIN(rsh->num_ref_idx_active[L0], rsh->num_ref_idx_active[L1]); |
783 | 1381 | int zero_idx = 0; | |
784 | |||
785 |
1/2✓ Branch 0 taken 2772 times.
✗ Branch 1 not taken.
|
2772 | while (num_cands < sps->max_num_merge_cand) { |
786 | 2772 | MvField *cand = cand_list + num_cands; | |
787 | |||
788 |
2/2✓ Branch 0 taken 2335 times.
✓ Branch 1 taken 437 times.
|
2772 | cand->pred_flag = PF_L0 + (IS_B(rsh) << 1); |
789 | 2772 | AV_ZERO64(cand->mv + 0); | |
790 | 2772 | AV_ZERO64(cand->mv + 1); | |
791 |
2/2✓ Branch 0 taken 2539 times.
✓ Branch 1 taken 233 times.
|
2772 | cand->ref_idx[0] = zero_idx < num_ref_idx ? zero_idx : 0; |
792 |
2/2✓ Branch 0 taken 2539 times.
✓ Branch 1 taken 233 times.
|
2772 | cand->ref_idx[1] = zero_idx < num_ref_idx ? zero_idx : 0; |
793 | 2772 | cand->bcw_idx = 0; | |
794 | 2772 | cand->hpel_if_idx = 0; | |
795 |
2/2✓ Branch 0 taken 1381 times.
✓ Branch 1 taken 1391 times.
|
2772 | if (merge_idx == num_cands) |
796 | 1381 | return; | |
797 | 1391 | num_cands++; | |
798 | 1391 | zero_idx++; | |
799 | } | ||
800 | } | ||
801 | |||
802 | 324923 | static void mv_merge_mode(const VVCLocalContext *lc, const int merge_idx, MvField *cand_list) | |
803 | { | ||
804 | 324923 | int num_cands = 0; | |
805 | 324923 | const MvField *nb_list[NUM_NBS + 1] = { NULL }; | |
806 | |||
807 |
2/2✓ Branch 1 taken 266770 times.
✓ Branch 2 taken 58153 times.
|
324923 | if (mv_merge_spatial_candidates(lc, merge_idx, nb_list, cand_list, &num_cands)) |
808 | 323542 | return; | |
809 | |||
810 |
2/2✓ Branch 1 taken 44181 times.
✓ Branch 2 taken 13972 times.
|
58153 | if (mv_merge_temporal_candidate(lc, &cand_list[num_cands])) { |
811 |
2/2✓ Branch 0 taken 21084 times.
✓ Branch 1 taken 23097 times.
|
44181 | if (merge_idx == num_cands) |
812 | 21084 | return; | |
813 | 23097 | num_cands++; | |
814 | } | ||
815 | |||
816 |
2/2✓ Branch 1 taken 25478 times.
✓ Branch 2 taken 11591 times.
|
37069 | if (mv_merge_history_candidates(lc, merge_idx, nb_list, cand_list, &num_cands)) |
817 | 25478 | return; | |
818 | |||
819 |
2/2✓ Branch 1 taken 10783 times.
✓ Branch 2 taken 808 times.
|
11591 | if (mv_merge_pairwise_candidate(cand_list, num_cands, IS_B(lc->sc->sh.r))) { |
820 |
2/2✓ Branch 0 taken 10210 times.
✓ Branch 1 taken 573 times.
|
10783 | if (merge_idx == num_cands) |
821 | 10210 | return; | |
822 | 573 | num_cands++; | |
823 | } | ||
824 | |||
825 | 1381 | mv_merge_zero_motion_candidate(lc, merge_idx, cand_list, num_cands); | |
826 | } | ||
827 | |||
828 | //8.5.2.2 Derivation process for luma motion vectors for merge mode | ||
829 | 297332 | void ff_vvc_luma_mv_merge_mode(VVCLocalContext *lc, const int merge_idx, const int ciip_flag, MvField *mv) | |
830 | { | ||
831 | 297332 | const CodingUnit *cu = lc->cu; | |
832 | MvField cand_list[MRG_MAX_NUM_CANDS]; | ||
833 | |||
834 | 297332 | ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height); | |
835 | 297332 | mv_merge_mode(lc, merge_idx, cand_list); | |
836 | 297332 | *mv = cand_list[merge_idx]; | |
837 | //ciip flag in not inhritable | ||
838 | 297332 | mv->ciip_flag = ciip_flag; | |
839 | 297332 | } | |
840 | |||
841 | //8.5.4.2 Derivation process for luma motion vectors for geometric partitioning merge mode | ||
842 | 27591 | void ff_vvc_luma_mv_merge_gpm(VVCLocalContext *lc, const int merge_gpm_idx[2], MvField *mv) | |
843 | { | ||
844 | 27591 | const CodingUnit *cu = lc->cu; | |
845 | MvField cand_list[MRG_MAX_NUM_CANDS]; | ||
846 | |||
847 | 27591 | const int idx[] = { merge_gpm_idx[0], merge_gpm_idx[1] + (merge_gpm_idx[1] >= merge_gpm_idx[0]) }; | |
848 | |||
849 | 27591 | ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height); | |
850 | 27591 | mv_merge_mode(lc, FFMAX(idx[0], idx[1]), cand_list); | |
851 | 27591 | memset(mv, 0, 2 * sizeof(*mv)); | |
852 |
2/2✓ Branch 0 taken 55182 times.
✓ Branch 1 taken 27591 times.
|
82773 | for (int i = 0; i < 2; i++) { |
853 | 55182 | int lx = idx[i] & 1; | |
854 | 55182 | int mask = lx + PF_L0; | |
855 | 55182 | MvField *cand = cand_list + idx[i]; | |
856 |
2/2✓ Branch 0 taken 15183 times.
✓ Branch 1 taken 39999 times.
|
55182 | if (!(cand->pred_flag & mask)) { |
857 | 15183 | lx = !lx; | |
858 | 15183 | mask = lx + PF_L0; | |
859 | } | ||
860 | 55182 | mv[i].pred_flag = mask; | |
861 | 55182 | mv[i].ref_idx[lx] = cand->ref_idx[lx]; | |
862 | 55182 | mv[i].mv[lx] = cand->mv[lx]; | |
863 | } | ||
864 | |||
865 | 27591 | } | |
866 | |||
867 | //8.5.5.5 Derivation process for luma affine control point motion vectors from a neighbouring block | ||
868 | 30529 | static void affine_cps_from_nb(const VVCLocalContext *lc, | |
869 | const int x_nb, int y_nb, const int nbw, const int nbh, const int lx, | ||
870 | Mv *cps, int num_cps) | ||
871 | { | ||
872 | 30529 | const VVCFrameContext *fc = lc->fc; | |
873 | 30529 | const CodingUnit *cu = lc->cu; | |
874 | 30529 | const int x0 = cu->x0; | |
875 | 30529 | const int y0 = cu->y0; | |
876 | 30529 | const int cb_width = cu->cb_width; | |
877 | 30529 | const int cb_height = cu->cb_height; | |
878 | 30529 | const MvField* tab_mvf = fc->tab.mvf; | |
879 | 30529 | const int min_cb_log2_size = fc->ps.sps->min_cb_log2_size_y; | |
880 | 30529 | const int min_cb_width = fc->ps.pps->min_cb_width; | |
881 | |||
882 | 30529 | const int log2_nbw = ff_log2(nbw); | |
883 | 30529 | const int log2_nbh = ff_log2(nbh); | |
884 |
4/4✓ Branch 0 taken 9069 times.
✓ Branch 1 taken 21460 times.
✓ Branch 2 taken 3464 times.
✓ Branch 3 taken 5605 times.
|
30529 | const int is_ctb_boundary = !((y_nb + nbh) % fc->ps.sps->ctb_size_y) && (y_nb + nbh == y0); |
885 | const Mv *l, *r; | ||
886 | int mv_scale_hor, mv_scale_ver, d_hor_x, d_ver_x, d_hor_y, d_ver_y, motion_model_idc_nb; | ||
887 |
2/2✓ Branch 0 taken 3464 times.
✓ Branch 1 taken 27065 times.
|
30529 | if (is_ctb_boundary) { |
888 | 3464 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
889 | 3464 | l = &TAB_MVF(x_nb, y_nb + nbh - 1).mv[lx]; | |
890 | 3464 | r = &TAB_MVF(x_nb + nbw - 1, y_nb + nbh - 1).mv[lx]; | |
891 | } else { | ||
892 | 27065 | const int x = x_nb >> min_cb_log2_size; | |
893 | 27065 | const int y = y_nb >> min_cb_log2_size; | |
894 | 27065 | motion_model_idc_nb = SAMPLE_CTB(fc->tab.mmi, x, y); | |
895 | |||
896 | 27065 | l = &TAB_CP_MV(lx, x_nb, y_nb); | |
897 | 27065 | r = &TAB_CP_MV(lx, x_nb + nbw - 1, y_nb) + 1; | |
898 | } | ||
899 | 30529 | mv_scale_hor = l->x * (1 << 7); | |
900 | 30529 | mv_scale_ver = l->y * (1 << 7); | |
901 | 30529 | d_hor_x = (r->x - l->x) * (1 << (7 - log2_nbw)); | |
902 | 30529 | d_ver_x = (r->y - l->y) * (1 << (7 - log2_nbw)); | |
903 |
4/4✓ Branch 0 taken 27065 times.
✓ Branch 1 taken 3464 times.
✓ Branch 2 taken 15176 times.
✓ Branch 3 taken 11889 times.
|
30529 | if (!is_ctb_boundary && motion_model_idc_nb == MOTION_6_PARAMS_AFFINE) { |
904 | 15176 | const Mv* lb = &TAB_CP_MV(lx, x_nb, y_nb + nbh - 1) + 2; | |
905 | 15176 | d_hor_y = (lb->x - l->x) * (1 << (7 - log2_nbh)); | |
906 | 15176 | d_ver_y = (lb->y - l->y) * (1 << (7 - log2_nbh)); | |
907 | } else { | ||
908 | 15353 | d_hor_y = -d_ver_x; | |
909 | 15353 | d_ver_y = d_hor_x; | |
910 | } | ||
911 | |||
912 |
2/2✓ Branch 0 taken 3464 times.
✓ Branch 1 taken 27065 times.
|
30529 | if (is_ctb_boundary) { |
913 | 3464 | y_nb = y0; | |
914 | } | ||
915 | 30529 | cps[0].x = mv_scale_hor + d_hor_x * (x0 - x_nb) + d_hor_y * (y0 - y_nb); | |
916 | 30529 | cps[0].y = mv_scale_ver + d_ver_x * (x0 - x_nb) + d_ver_y * (y0 - y_nb); | |
917 | 30529 | cps[1].x = mv_scale_hor + d_hor_x * (x0 + cb_width - x_nb) + d_hor_y * (y0 - y_nb); | |
918 | 30529 | cps[1].y = mv_scale_ver + d_ver_x * (x0 + cb_width - x_nb) + d_ver_y * (y0 - y_nb); | |
919 |
2/2✓ Branch 0 taken 16740 times.
✓ Branch 1 taken 13789 times.
|
30529 | if (num_cps == 3) { |
920 | 16740 | cps[2].x = mv_scale_hor + d_hor_x * (x0 - x_nb) + d_hor_y * (y0 + cb_height - y_nb); | |
921 | 16740 | cps[2].y = mv_scale_ver + d_ver_x * (x0 - x_nb) + d_ver_y * (y0 + cb_height - y_nb); | |
922 | } | ||
923 |
2/2✓ Branch 0 taken 77798 times.
✓ Branch 1 taken 30529 times.
|
108327 | for (int i = 0; i < num_cps; i++) { |
924 | 77798 | ff_vvc_round_mv(cps + i, 0, 7); | |
925 | 77798 | ff_vvc_clip_mv(cps + i); | |
926 | } | ||
927 | 30529 | } | |
928 | |||
929 | //derive affine neighbour's position, width and height, | ||
930 | 96279 | 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) | |
931 | { | ||
932 | 96279 | const int log2_min_cb_size = fc->ps.sps->min_cb_log2_size_y; | |
933 | 96279 | const int min_cb_width = fc->ps.pps->min_cb_width; | |
934 | 96279 | const int x = x_nb >> log2_min_cb_size; | |
935 | 96279 | const int y = y_nb >> log2_min_cb_size; | |
936 | 96279 | const int motion_model_idc = SAMPLE_CTB(fc->tab.mmi, x, y); | |
937 |
2/2✓ Branch 0 taken 27227 times.
✓ Branch 1 taken 69052 times.
|
96279 | if (motion_model_idc) { |
938 | 27227 | *x_cb = SAMPLE_CTB(fc->tab.cb_pos_x[0], x, y); | |
939 | 27227 | *y_cb = SAMPLE_CTB(fc->tab.cb_pos_y[0], x, y); | |
940 | 27227 | *cbw = SAMPLE_CTB(fc->tab.cb_width[0], x, y); | |
941 | 27227 | *cbh = SAMPLE_CTB(fc->tab.cb_height[0], x, y); | |
942 | } | ||
943 | 96279 | return motion_model_idc; | |
944 | } | ||
945 | |||
946 | //part of 8.5.5.2 Derivation process for motion vectors and reference indices in subblock merge mode | ||
947 | 65575 | static int affine_merge_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand, MotionInfo* mi) | |
948 | { | ||
949 | 65575 | const VVCFrameContext *fc = lc->fc; | |
950 | int x, y, w, h, motion_model_idc; | ||
951 | |||
952 | 65575 | motion_model_idc = affine_neighbour_cb(fc, x_cand, y_cand, &x, &y, &w, &h); | |
953 |
2/2✓ Branch 0 taken 19540 times.
✓ Branch 1 taken 46035 times.
|
65575 | if (motion_model_idc) { |
954 | 19540 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
955 | 19540 | const MvField* tab_mvf = fc->tab.mvf; | |
956 | 19540 | const MvField *mvf = &TAB_MVF(x, y); | |
957 | |||
958 | 19540 | mi->bcw_idx = mvf->bcw_idx; | |
959 | 19540 | mi->pred_flag = mvf->pred_flag; | |
960 |
2/2✓ Branch 0 taken 39080 times.
✓ Branch 1 taken 19540 times.
|
58620 | for (int i = 0; i < 2; i++) { |
961 | 39080 | PredFlag mask = i + 1; | |
962 |
2/2✓ Branch 0 taken 24491 times.
✓ Branch 1 taken 14589 times.
|
39080 | if (mi->pred_flag & mask) { |
963 | 24491 | affine_cps_from_nb(lc, x, y, w, h, i, &mi->mv[i][0], motion_model_idc + 1); | |
964 | } | ||
965 | 39080 | mi->ref_idx[i] = mvf->ref_idx[i]; | |
966 | } | ||
967 | 19540 | mi->motion_model_idc = motion_model_idc; | |
968 | } | ||
969 | 65575 | return motion_model_idc; | |
970 | } | ||
971 | |||
972 | 45834 | static int affine_merge_from_nbs(NeighbourContext *ctx, const NeighbourIdx *nbs, const int num_nbs, MotionInfo* cand) | |
973 | { | ||
974 | 45834 | const VVCLocalContext *lc = ctx->lc; | |
975 |
2/2✓ Branch 0 taken 96548 times.
✓ Branch 1 taken 26294 times.
|
122842 | for (int i = 0; i < num_nbs; i++) { |
976 | 96548 | Neighbour *n = &ctx->neighbours[nbs[i]]; | |
977 |
4/4✓ Branch 1 taken 65575 times.
✓ Branch 2 taken 30973 times.
✓ Branch 4 taken 19540 times.
✓ Branch 5 taken 46035 times.
|
96548 | if (check_available(n, lc, 1) && affine_merge_candidate(lc, n->x, n->y, cand)) |
978 | 19540 | return 1; | |
979 | } | ||
980 | 26294 | return 0; | |
981 | } | ||
982 | #define AFFINE_MERGE_FROM_NBS(nbs) affine_merge_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), mi) | ||
983 | |||
984 | |||
985 | 101312 | static const MvField* derive_corner_mvf(NeighbourContext *ctx, const NeighbourIdx *neighbour, const int num_neighbour) | |
986 | { | ||
987 | 101312 | const VVCFrameContext *fc = ctx->lc->fc; | |
988 | 101312 | const MvField *tab_mvf = fc->tab.mvf; | |
989 | 101312 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
990 |
2/2✓ Branch 0 taken 107959 times.
✓ Branch 1 taken 7529 times.
|
115488 | for (int i = 0; i < num_neighbour; i++) { |
991 | 107959 | Neighbour *n = &ctx->neighbours[neighbour[i]]; | |
992 |
2/2✓ Branch 1 taken 93783 times.
✓ Branch 2 taken 14176 times.
|
107959 | if (check_available(n, ctx->lc, 1)) { |
993 | 93783 | return &TAB_MVF(n->x, n->y); | |
994 | } | ||
995 | } | ||
996 | 7529 | return NULL; | |
997 | } | ||
998 | |||
999 | #define DERIVE_CORNER_MV(nbs) derive_corner_mvf(nctx, nbs, FF_ARRAY_ELEMS(nbs)) | ||
1000 | |||
1001 | // check if the mv's and refidx are the same between A and B | ||
1002 | 53520 | static av_always_inline int compare_pf_ref_idx(const MvField *A, const struct MvField *B, const struct MvField *C, const int lx) | |
1003 | { | ||
1004 | |||
1005 | 53520 | const PredFlag mask = (lx + 1) & A->pred_flag; | |
1006 |
2/2✓ Branch 0 taken 18975 times.
✓ Branch 1 taken 34545 times.
|
53520 | if (!(B->pred_flag & mask)) |
1007 | 18975 | return 0; | |
1008 |
2/2✓ Branch 0 taken 1763 times.
✓ Branch 1 taken 32782 times.
|
34545 | if (A->ref_idx[lx] != B->ref_idx[lx]) |
1009 | 1763 | return 0; | |
1010 |
2/2✓ Branch 0 taken 27134 times.
✓ Branch 1 taken 5648 times.
|
32782 | if (C) { |
1011 |
2/2✓ Branch 0 taken 941 times.
✓ Branch 1 taken 26193 times.
|
27134 | if (!(C->pred_flag & mask)) |
1012 | 941 | return 0; | |
1013 |
2/2✓ Branch 0 taken 1083 times.
✓ Branch 1 taken 25110 times.
|
26193 | if (A->ref_idx[lx] != C->ref_idx[lx]) |
1014 | 1083 | return 0; | |
1015 | } | ||
1016 | 30758 | return 1; | |
1017 | } | ||
1018 | |||
1019 | 1569976 | static av_always_inline void sb_clip_location(const VVCLocalContext *lc, | |
1020 | const int x_ctb, const int y_ctb, const Mv* temp_mv, int *x, int *y) | ||
1021 | { | ||
1022 | 1569976 | const VVCFrameContext *fc = lc->fc; | |
1023 | 1569976 | const VVCPPS *pps = fc->ps.pps; | |
1024 | 1569976 | const int ctb_log2_size = fc->ps.sps->ctb_log2_size_y; | |
1025 | 1569976 | const int subpic_idx = lc->sc->sh.r->curr_subpic_idx; | |
1026 | 1569976 | const int x_end = pps->subpic_x[subpic_idx] + pps->subpic_width[subpic_idx]; | |
1027 | 1569976 | const int y_end = pps->subpic_y[subpic_idx] + pps->subpic_height[subpic_idx]; | |
1028 | |||
1029 | 1569976 | *x = av_clip(*x + temp_mv->x, x_ctb, FFMIN(x_end - 1, x_ctb + (1 << ctb_log2_size) + 3)) & ~7; | |
1030 |
2/2✓ Branch 0 taken 1386025 times.
✓ Branch 1 taken 183951 times.
|
1569976 | *y = av_clip(*y + temp_mv->y, y_ctb, FFMIN(y_end - 1, y_ctb + (1 << ctb_log2_size) - 1)) & ~7; |
1031 | 1569976 | } | |
1032 | |||
1033 | 1569976 | static void sb_temproal_luma_motion(const VVCLocalContext *lc, | |
1034 | const int x_ctb, const int y_ctb, const Mv *temp_mv, | ||
1035 | int x, int y, uint8_t *pred_flag, Mv *mv) | ||
1036 | { | ||
1037 | MvField temp_col; | ||
1038 | Mv* mvLXCol; | ||
1039 | 1569976 | const int refIdxLx = 0; | |
1040 | 1569976 | const VVCFrameContext *fc = lc->fc; | |
1041 | 1569976 | const VVCSH *sh = &lc->sc->sh; | |
1042 | 1569976 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
1043 | 1569976 | VVCFrame *ref = fc->ref->collocated_ref; | |
1044 | 1569976 | MvField *tab_mvf = ref->tab_dmvr_mvf; | |
1045 | 1569976 | int colPic = ref->poc; | |
1046 | 1569976 | int X = 0; | |
1047 | |||
1048 | 1569976 | sb_clip_location(lc, x_ctb, y_ctb, temp_mv, &x, &y); | |
1049 | |||
1050 | 1569976 | temp_col = TAB_MVF(x, y); | |
1051 | 1569976 | mvLXCol = mv + 0; | |
1052 | 1569976 | *pred_flag = DERIVE_TEMPORAL_COLOCATED_MVS(1); | |
1053 |
2/2✓ Branch 0 taken 1223028 times.
✓ Branch 1 taken 346948 times.
|
1569976 | if (IS_B(sh->r)) { |
1054 | 1223028 | X = 1; | |
1055 | 1223028 | mvLXCol = mv + 1; | |
1056 | 1223028 | *pred_flag |= (DERIVE_TEMPORAL_COLOCATED_MVS(1)) << 1; | |
1057 | } | ||
1058 | 1569976 | } | |
1059 | |||
1060 | //8.5.5.4 Derivation process for subblock-based temporal merging base motion data | ||
1061 | 54374 | static int sb_temporal_luma_motion_data(const VVCLocalContext *lc, const MvField *a1, | |
1062 | const int x_ctb, const int y_ctb, MvField *ctr_mvf, Mv *temp_mv) | ||
1063 | { | ||
1064 | 54374 | const VVCFrameContext *fc = lc->fc; | |
1065 | 54374 | const RefPicList *rpl = lc->sc->rpl; | |
1066 | 54374 | const CodingUnit *cu = lc->cu; | |
1067 | 54374 | const int x = cu->x0 + cu->cb_width / 2; | |
1068 | 54374 | const int y = cu->y0 + cu->cb_height / 2; | |
1069 | 54374 | const VVCFrame *ref = fc->ref->collocated_ref; | |
1070 | |||
1071 | int colPic; | ||
1072 | |||
1073 | 54374 | memset(temp_mv, 0, sizeof(*temp_mv)); | |
1074 | |||
1075 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 54374 times.
|
54374 | if (!ref) { |
1076 | ✗ | memset(ctr_mvf, 0, sizeof(*ctr_mvf)); | |
1077 | ✗ | return 0; | |
1078 | } | ||
1079 | |||
1080 | 54374 | colPic = ref->poc; | |
1081 | |||
1082 |
2/2✓ Branch 0 taken 50698 times.
✓ Branch 1 taken 3676 times.
|
54374 | if (a1) { |
1083 |
4/4✓ Branch 0 taken 45811 times.
✓ Branch 1 taken 4887 times.
✓ Branch 2 taken 30778 times.
✓ Branch 3 taken 15033 times.
|
50698 | if ((a1->pred_flag & PF_L0) && colPic == rpl[L0].refs[a1->ref_idx[L0]].poc) |
1084 | 30778 | *temp_mv = a1->mv[0]; | |
1085 |
4/4✓ Branch 0 taken 14068 times.
✓ Branch 1 taken 5852 times.
✓ Branch 2 taken 11218 times.
✓ Branch 3 taken 2850 times.
|
19920 | else if ((a1->pred_flag & PF_L1) && colPic == rpl[L1].refs[a1->ref_idx[L1]].poc) |
1086 | 11218 | *temp_mv = a1->mv[1]; | |
1087 | 50698 | ff_vvc_round_mv(temp_mv, 0, 4); | |
1088 | } | ||
1089 | 54374 | sb_temproal_luma_motion(lc, x_ctb, y_ctb, temp_mv, x, y, &ctr_mvf->pred_flag , ctr_mvf->mv); | |
1090 | |||
1091 | 54374 | return ctr_mvf->pred_flag; | |
1092 | } | ||
1093 | |||
1094 | |||
1095 | //8.5.5.3 Derivation process for subblock-based temporal merging candidates | ||
1096 | 54562 | static int sb_temporal_merge_candidate(const VVCLocalContext* lc, NeighbourContext *nctx, PredictionUnit *pu) | |
1097 | { | ||
1098 | 54562 | const VVCFrameContext *fc = lc->fc; | |
1099 | 54562 | const CodingUnit *cu = lc->cu; | |
1100 | 54562 | const VVCSPS *sps = fc->ps.sps; | |
1101 | 54562 | const VVCPH *ph = &fc->ps.ph; | |
1102 | 54562 | MotionInfo *mi = &pu->mi; | |
1103 | 54562 | const int ctb_log2_size = sps->ctb_log2_size_y; | |
1104 | 54562 | const int x0 = cu->x0; | |
1105 | 54562 | const int y0 = cu->y0; | |
1106 | 54562 | const NeighbourIdx n = A1; | |
1107 | const MvField *a1; | ||
1108 | MvField ctr_mvf; | ||
1109 | 54562 | LOCAL_ALIGNED_8(Mv, temp_mv, [1]); | |
1110 | 54562 | const int x_ctb = (x0 >> ctb_log2_size) << ctb_log2_size; | |
1111 | 54562 | const int y_ctb = (y0 >> ctb_log2_size) << ctb_log2_size; | |
1112 | |||
1113 | |||
1114 |
2/2✓ Branch 0 taken 54475 times.
✓ Branch 1 taken 87 times.
|
54562 | if (!ph->r->ph_temporal_mvp_enabled_flag || |
1115 |
2/2✓ Branch 0 taken 54374 times.
✓ Branch 1 taken 101 times.
|
54475 | !sps->r->sps_sbtmvp_enabled_flag || |
1116 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 54374 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
54374 | (cu->cb_width < 8 && cu->cb_height < 8)) |
1117 | 188 | return 0; | |
1118 | |||
1119 | 54374 | mi->num_sb_x = cu->cb_width >> 3; | |
1120 | 54374 | mi->num_sb_y = cu->cb_height >> 3; | |
1121 | |||
1122 | 54374 | a1 = derive_corner_mvf(nctx, &n, 1); | |
1123 |
2/2✓ Branch 1 taken 45965 times.
✓ Branch 2 taken 8409 times.
|
54374 | if (sb_temporal_luma_motion_data(lc, a1, x_ctb, y_ctb, &ctr_mvf, temp_mv)) { |
1124 | 45965 | const int sbw = cu->cb_width / mi->num_sb_x; | |
1125 | 45965 | const int sbh = cu->cb_height / mi->num_sb_y; | |
1126 | 45965 | MvField mvf = {0}; | |
1127 |
2/2✓ Branch 0 taken 199371 times.
✓ Branch 1 taken 45965 times.
|
245336 | for (int sby = 0; sby < mi->num_sb_y; sby++) { |
1128 |
2/2✓ Branch 0 taken 1515602 times.
✓ Branch 1 taken 199371 times.
|
1714973 | for (int sbx = 0; sbx < mi->num_sb_x; sbx++) { |
1129 | 1515602 | int x = x0 + sbx * sbw; | |
1130 | 1515602 | int y = y0 + sby * sbh; | |
1131 | 1515602 | sb_temproal_luma_motion(lc, x_ctb, y_ctb, temp_mv, x + sbw / 2, y + sbh / 2, &mvf.pred_flag, mvf.mv); | |
1132 |
2/2✓ Branch 0 taken 8588 times.
✓ Branch 1 taken 1507014 times.
|
1515602 | if (!mvf.pred_flag) { |
1133 | 8588 | mvf.pred_flag = ctr_mvf.pred_flag; | |
1134 | 8588 | memcpy(mvf.mv, ctr_mvf.mv, sizeof(mvf.mv)); | |
1135 | } | ||
1136 | 1515602 | ff_vvc_set_mvf(lc, x, y, sbw, sbh, &mvf); | |
1137 | } | ||
1138 | } | ||
1139 | 45965 | return 1; | |
1140 | } | ||
1141 | 8409 | return 0; | |
1142 | } | ||
1143 | |||
1144 | 14380 | static int affine_merge_const1(const MvField *c0, const MvField *c1, const MvField *c2, MotionInfo *mi) | |
1145 | { | ||
1146 |
6/6✓ Branch 0 taken 14307 times.
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 13627 times.
✓ Branch 3 taken 680 times.
✓ Branch 4 taken 13105 times.
✓ Branch 5 taken 522 times.
|
14380 | if (c0 && c1 && c2) { |
1147 | 13105 | mi->pred_flag = 0; | |
1148 |
2/2✓ Branch 0 taken 26210 times.
✓ Branch 1 taken 13105 times.
|
39315 | for (int i = 0; i < 2; i++) { |
1149 | 26210 | PredFlag mask = i + 1; | |
1150 |
2/2✓ Branch 1 taken 15429 times.
✓ Branch 2 taken 10781 times.
|
26210 | if (compare_pf_ref_idx(c0, c1, c2, i)) { |
1151 | 15429 | mi->pred_flag |= mask; | |
1152 | 15429 | mi->ref_idx[i] = c0->ref_idx[i]; | |
1153 | 15429 | mi->mv[i][0] = c0->mv[i]; | |
1154 | 15429 | mi->mv[i][1] = c1->mv[i]; | |
1155 | 15429 | mi->mv[i][2] = c2->mv[i]; | |
1156 | } | ||
1157 | } | ||
1158 |
2/2✓ Branch 0 taken 12106 times.
✓ Branch 1 taken 999 times.
|
13105 | if (mi->pred_flag) { |
1159 |
2/2✓ Branch 0 taken 3323 times.
✓ Branch 1 taken 8783 times.
|
12106 | if (mi->pred_flag == PF_BI) |
1160 | 3323 | mi->bcw_idx = c0->bcw_idx; | |
1161 | 12106 | mi->motion_model_idc = MOTION_6_PARAMS_AFFINE; | |
1162 | 12106 | return 1; | |
1163 | } | ||
1164 | } | ||
1165 | 2274 | return 0; | |
1166 | } | ||
1167 | |||
1168 | 7650 | static int affine_merge_const2(const MvField *c0, const MvField *c1, const MvField *c3, MotionInfo *mi) | |
1169 | { | ||
1170 |
6/6✓ Branch 0 taken 7577 times.
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 6897 times.
✓ Branch 3 taken 680 times.
✓ Branch 4 taken 4656 times.
✓ Branch 5 taken 2241 times.
|
7650 | if (c0 && c1 && c3) { |
1171 | 4656 | mi->pred_flag = 0; | |
1172 |
2/2✓ Branch 0 taken 9312 times.
✓ Branch 1 taken 4656 times.
|
13968 | for (int i = 0; i < 2; i++) { |
1173 | 9312 | PredFlag mask = i + 1; | |
1174 |
2/2✓ Branch 1 taken 5464 times.
✓ Branch 2 taken 3848 times.
|
9312 | if (compare_pf_ref_idx(c0, c1, c3, i)) { |
1175 | 5464 | mi->pred_flag |= mask; | |
1176 | 5464 | mi->ref_idx[i] = c0->ref_idx[i]; | |
1177 | 5464 | mi->mv[i][0] = c0->mv[i]; | |
1178 | 5464 | mi->mv[i][1] = c1->mv[i]; | |
1179 | 5464 | mi->mv[i][2].x = c3->mv[i].x + c0->mv[i].x - c1->mv[i].x; | |
1180 | 5464 | mi->mv[i][2].y = c3->mv[i].y + c0->mv[i].y - c1->mv[i].y; | |
1181 | 5464 | ff_vvc_clip_mv(&mi->mv[i][2]); | |
1182 | } | ||
1183 | } | ||
1184 |
2/2✓ Branch 0 taken 4056 times.
✓ Branch 1 taken 600 times.
|
4656 | if (mi->pred_flag) { |
1185 |
2/2✓ Branch 0 taken 1408 times.
✓ Branch 1 taken 2648 times.
|
4056 | mi->bcw_idx = mi->pred_flag == PF_BI ? c0->bcw_idx : 0; |
1186 | 4056 | mi->motion_model_idc = MOTION_6_PARAMS_AFFINE; | |
1187 | 4056 | return 1; | |
1188 | } | ||
1189 | } | ||
1190 | 3594 | return 0; | |
1191 | } | ||
1192 | |||
1193 | 5525 | static int affine_merge_const3(const MvField *c0, const MvField *c2, const MvField *c3, MotionInfo *mi) | |
1194 | { | ||
1195 |
6/6✓ Branch 0 taken 5452 times.
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 5118 times.
✓ Branch 3 taken 334 times.
✓ Branch 4 taken 2877 times.
✓ Branch 5 taken 2241 times.
|
5525 | if (c0 && c2 && c3) { |
1196 | 2877 | mi->pred_flag = 0; | |
1197 |
2/2✓ Branch 0 taken 5754 times.
✓ Branch 1 taken 2877 times.
|
8631 | for (int i = 0; i < 2; i++) { |
1198 | 5754 | PredFlag mask = i + 1; | |
1199 |
2/2✓ Branch 1 taken 3288 times.
✓ Branch 2 taken 2466 times.
|
5754 | if (compare_pf_ref_idx(c0, c2, c3, i)) { |
1200 | 3288 | mi->pred_flag |= mask; | |
1201 | 3288 | mi->ref_idx[i] = c0->ref_idx[i]; | |
1202 | 3288 | mi->mv[i][0] = c0->mv[i]; | |
1203 | 3288 | mi->mv[i][1].x = c3->mv[i].x + c0->mv[i].x - c2->mv[i].x; | |
1204 | 3288 | mi->mv[i][1].y = c3->mv[i].y + c0->mv[i].y - c2->mv[i].y; | |
1205 | 3288 | ff_vvc_clip_mv(&mi->mv[i][1]); | |
1206 | 3288 | mi->mv[i][2] = c2->mv[i]; | |
1207 | } | ||
1208 | } | ||
1209 |
2/2✓ Branch 0 taken 2427 times.
✓ Branch 1 taken 450 times.
|
2877 | if (mi->pred_flag) { |
1210 |
2/2✓ Branch 0 taken 861 times.
✓ Branch 1 taken 1566 times.
|
2427 | mi->bcw_idx = mi->pred_flag == PF_BI ? c0->bcw_idx : 0; |
1211 | 2427 | mi->motion_model_idc = MOTION_6_PARAMS_AFFINE; | |
1212 | 2427 | return 1; | |
1213 | } | ||
1214 | } | ||
1215 | 3098 | return 0; | |
1216 | } | ||
1217 | |||
1218 | 3890 | static int affine_merge_const4(const MvField *c1, const MvField *c2, const MvField *c3, MotionInfo *mi) | |
1219 | { | ||
1220 |
6/6✓ Branch 0 taken 3442 times.
✓ Branch 1 taken 448 times.
✓ Branch 2 taken 3116 times.
✓ Branch 3 taken 326 times.
✓ Branch 4 taken 1105 times.
✓ Branch 5 taken 2011 times.
|
3890 | if (c1 && c2 && c3) { |
1221 | 1105 | mi->pred_flag = 0; | |
1222 |
2/2✓ Branch 0 taken 2210 times.
✓ Branch 1 taken 1105 times.
|
3315 | for (int i = 0; i < 2; i++) { |
1223 | 2210 | PredFlag mask = i + 1; | |
1224 |
2/2✓ Branch 1 taken 929 times.
✓ Branch 2 taken 1281 times.
|
2210 | if (compare_pf_ref_idx(c1, c2, c3, i)) { |
1225 | 929 | mi->pred_flag |= mask; | |
1226 | 929 | mi->ref_idx[i] = c1->ref_idx[i]; | |
1227 | 929 | mi->mv[i][0].x = c1->mv[i].x + c2->mv[i].x - c3->mv[i].x; | |
1228 | 929 | mi->mv[i][0].y = c1->mv[i].y + c2->mv[i].y - c3->mv[i].y; | |
1229 | 929 | ff_vvc_clip_mv(&mi->mv[i][0]); | |
1230 | 929 | mi->mv[i][1] = c1->mv[i]; | |
1231 | 929 | mi->mv[i][2] = c2->mv[i]; | |
1232 | } | ||
1233 | } | ||
1234 |
2/2✓ Branch 0 taken 685 times.
✓ Branch 1 taken 420 times.
|
1105 | if (mi->pred_flag) { |
1235 |
2/2✓ Branch 0 taken 244 times.
✓ Branch 1 taken 441 times.
|
685 | mi->bcw_idx = mi->pred_flag == PF_BI ? c1->bcw_idx : 0; |
1236 | 685 | mi->motion_model_idc = MOTION_6_PARAMS_AFFINE; | |
1237 | 685 | return 1; | |
1238 | } | ||
1239 | } | ||
1240 | 3205 | return 0; | |
1241 | } | ||
1242 | |||
1243 | 4520 | static int affine_merge_const5(const MvField *c0, const MvField *c1, MotionInfo *mi) | |
1244 | { | ||
1245 |
4/4✓ Branch 0 taken 3754 times.
✓ Branch 1 taken 766 times.
✓ Branch 2 taken 3120 times.
✓ Branch 3 taken 634 times.
|
4520 | if (c0 && c1) { |
1246 | 3120 | mi->pred_flag = 0; | |
1247 |
2/2✓ Branch 0 taken 6240 times.
✓ Branch 1 taken 3120 times.
|
9360 | for (int i = 0; i < 2; i++) { |
1248 | 6240 | PredFlag mask = i + 1; | |
1249 |
2/2✓ Branch 1 taken 3449 times.
✓ Branch 2 taken 2791 times.
|
6240 | if (compare_pf_ref_idx(c0, c1, NULL, i)) { |
1250 | 3449 | mi->pred_flag |= mask; | |
1251 | 3449 | mi->ref_idx[i] = c0->ref_idx[i]; | |
1252 | 3449 | mi->mv[i][0] = c0->mv[i]; | |
1253 | 3449 | mi->mv[i][1] = c1->mv[i]; | |
1254 | } | ||
1255 | } | ||
1256 |
2/2✓ Branch 0 taken 2716 times.
✓ Branch 1 taken 404 times.
|
3120 | if (mi->pred_flag) { |
1257 |
2/2✓ Branch 0 taken 733 times.
✓ Branch 1 taken 1983 times.
|
2716 | if (mi->pred_flag == PF_BI) |
1258 | 733 | mi->bcw_idx = c0->bcw_idx; | |
1259 | 2716 | mi->motion_model_idc = MOTION_4_PARAMS_AFFINE; | |
1260 | 2716 | return 1; | |
1261 | } | ||
1262 | } | ||
1263 | 1804 | return 0; | |
1264 | } | ||
1265 | |||
1266 | 2975 | static int affine_merge_const6(const MvField* c0, const MvField* c2, const int cb_width, const int cb_height, MotionInfo *mi) | |
1267 | { | ||
1268 |
4/4✓ Branch 0 taken 2209 times.
✓ Branch 1 taken 766 times.
✓ Branch 2 taken 1897 times.
✓ Branch 3 taken 312 times.
|
2975 | if (c0 && c2) { |
1269 | 1897 | const int shift = 7 + av_log2(cb_width) - av_log2(cb_height); | |
1270 | 1897 | mi->pred_flag = 0; | |
1271 |
2/2✓ Branch 0 taken 3794 times.
✓ Branch 1 taken 1897 times.
|
5691 | for (int i = 0; i < 2; i++) { |
1272 | 3794 | PredFlag mask = i + 1; | |
1273 |
2/2✓ Branch 1 taken 2199 times.
✓ Branch 2 taken 1595 times.
|
3794 | if (compare_pf_ref_idx(c0, c2, NULL, i)) { |
1274 | 2199 | mi->pred_flag |= mask; | |
1275 | 2199 | mi->ref_idx[i] = c0->ref_idx[i]; | |
1276 | 2199 | mi->mv[i][0] = c0->mv[i]; | |
1277 | 2199 | mi->mv[i][1].x = (c0->mv[i].x * (1 << 7)) + ((c2->mv[i].y - c0->mv[i].y) * (1 << shift)); | |
1278 | 2199 | mi->mv[i][1].y = (c0->mv[i].y * (1 << 7)) - ((c2->mv[i].x - c0->mv[i].x) * (1 << shift)); | |
1279 | 2199 | ff_vvc_round_mv(&mi->mv[i][1], 0, 7); | |
1280 | 2199 | ff_vvc_clip_mv(&mi->mv[i][1]); | |
1281 | } | ||
1282 | } | ||
1283 |
2/2✓ Branch 0 taken 1709 times.
✓ Branch 1 taken 188 times.
|
1897 | if (mi->pred_flag) { |
1284 |
2/2✓ Branch 0 taken 490 times.
✓ Branch 1 taken 1219 times.
|
1709 | if (mi->pred_flag == PF_BI) |
1285 | 490 | mi->bcw_idx = c0->bcw_idx; | |
1286 | 1709 | mi->motion_model_idc = MOTION_4_PARAMS_AFFINE; | |
1287 | 1709 | return 1; | |
1288 | } | ||
1289 | } | ||
1290 | 1266 | return 0; | |
1291 | } | ||
1292 | |||
1293 | 1733 | static void affine_merge_zero_motion(const VVCLocalContext *lc, MotionInfo *mi) | |
1294 | { | ||
1295 | 1733 | const CodingUnit *cu = lc->cu; | |
1296 | |||
1297 | 1733 | memset(mi, 0, sizeof(*mi)); | |
1298 |
2/2✓ Branch 0 taken 1279 times.
✓ Branch 1 taken 454 times.
|
1733 | mi->pred_flag = PF_L0 + (IS_B(lc->sc->sh.r) << 1); |
1299 | 1733 | mi->motion_model_idc = MOTION_4_PARAMS_AFFINE; | |
1300 | 1733 | mi->num_sb_x = cu->cb_width >> MIN_PU_LOG2; | |
1301 | 1733 | mi->num_sb_y = cu->cb_height >> MIN_PU_LOG2; | |
1302 | 1733 | } | |
1303 | |||
1304 | //8.5.5.6 Derivation process for constructed affine control point motion vector merging candidates | ||
1305 | 15646 | static int affine_merge_const_candidates(const VVCLocalContext *lc, MotionInfo *mi, | |
1306 | NeighbourContext *nctx, const int merge_subblock_idx, int num_cands) | ||
1307 | { | ||
1308 | 15646 | const VVCFrameContext *fc = lc->fc; | |
1309 | 15646 | const CodingUnit *cu = lc->cu; | |
1310 | 15646 | const NeighbourIdx tl[] = { B2, B3, A2 }; | |
1311 | 15646 | const NeighbourIdx tr[] = { B1, B0}; | |
1312 | 15646 | const NeighbourIdx bl[] = { A1, A0}; | |
1313 | const MvField *c0, *c1, *c2; | ||
1314 | |||
1315 | 15646 | c0 = DERIVE_CORNER_MV(tl); | |
1316 | 15646 | c1 = DERIVE_CORNER_MV(tr); | |
1317 | 15646 | c2 = DERIVE_CORNER_MV(bl); | |
1318 | |||
1319 |
2/2✓ Branch 0 taken 14380 times.
✓ Branch 1 taken 1266 times.
|
15646 | if (fc->ps.sps->r->sps_6param_affine_enabled_flag) { |
1320 | 14380 | MvField corner3, *c3 = NULL; | |
1321 | //Const1 | ||
1322 |
2/2✓ Branch 1 taken 12106 times.
✓ Branch 2 taken 2274 times.
|
14380 | if (affine_merge_const1(c0, c1, c2, mi)) { |
1323 |
2/2✓ Branch 0 taken 6730 times.
✓ Branch 1 taken 5376 times.
|
12106 | if (merge_subblock_idx == num_cands) |
1324 | 11126 | return 1; | |
1325 | 5376 | num_cands++; | |
1326 | } | ||
1327 | |||
1328 | 7650 | memset(&corner3, 0, sizeof(corner3)); | |
1329 |
2/2✓ Branch 0 taken 7624 times.
✓ Branch 1 taken 26 times.
|
7650 | if (fc->ps.ph.r->ph_temporal_mvp_enabled_flag){ |
1330 | 7624 | const int available_l0 = temporal_luma_motion_vector(lc, 0, corner3.mv + 0, 0, 0, 0); | |
1331 | 15248 | const int available_l1 = (lc->sc->sh.r->sh_slice_type == VVC_SLICE_TYPE_B) ? | |
1332 |
2/2✓ Branch 0 taken 6200 times.
✓ Branch 1 taken 1424 times.
|
7624 | temporal_luma_motion_vector(lc, 0, corner3.mv + 1, 1, 0, 0) : 0; |
1333 | |||
1334 | 7624 | corner3.pred_flag = available_l0 + (available_l1 << 1); | |
1335 |
2/2✓ Branch 0 taken 5122 times.
✓ Branch 1 taken 2502 times.
|
7624 | if (corner3.pred_flag) |
1336 | 5122 | c3 = &corner3; | |
1337 | } | ||
1338 | |||
1339 | //Const2 | ||
1340 |
2/2✓ Branch 1 taken 4056 times.
✓ Branch 2 taken 3594 times.
|
7650 | if (affine_merge_const2(c0, c1, c3, mi)) { |
1341 |
2/2✓ Branch 0 taken 2125 times.
✓ Branch 1 taken 1931 times.
|
4056 | if (merge_subblock_idx == num_cands) |
1342 | 2125 | return 1; | |
1343 | 1931 | num_cands++; | |
1344 | } | ||
1345 | |||
1346 | //Const3 | ||
1347 |
2/2✓ Branch 1 taken 2427 times.
✓ Branch 2 taken 3098 times.
|
5525 | if (affine_merge_const3(c0, c2, c3, mi)) { |
1348 |
2/2✓ Branch 0 taken 1635 times.
✓ Branch 1 taken 792 times.
|
2427 | if (merge_subblock_idx == num_cands) |
1349 | 1635 | return 1; | |
1350 | 792 | num_cands++; | |
1351 | } | ||
1352 | |||
1353 | //Const4 | ||
1354 |
2/2✓ Branch 1 taken 685 times.
✓ Branch 2 taken 3205 times.
|
3890 | if (affine_merge_const4(c1, c2, c3, mi)) { |
1355 |
2/2✓ Branch 0 taken 636 times.
✓ Branch 1 taken 49 times.
|
685 | if (merge_subblock_idx == num_cands) |
1356 | 636 | return 1; | |
1357 | 49 | num_cands++; | |
1358 | } | ||
1359 | } | ||
1360 | |||
1361 | //Const5 | ||
1362 |
2/2✓ Branch 1 taken 2716 times.
✓ Branch 2 taken 1804 times.
|
4520 | if (affine_merge_const5(c0, c1, mi)) { |
1363 |
2/2✓ Branch 0 taken 1545 times.
✓ Branch 1 taken 1171 times.
|
2716 | if (merge_subblock_idx == num_cands) |
1364 | 1545 | return 1; | |
1365 | 1171 | num_cands++; | |
1366 | } | ||
1367 | |||
1368 |
2/2✓ Branch 1 taken 1709 times.
✓ Branch 2 taken 1266 times.
|
2975 | if (affine_merge_const6(c0, c2, cu->cb_width, cu->cb_height, mi)) { |
1369 |
2/2✓ Branch 0 taken 1242 times.
✓ Branch 1 taken 467 times.
|
1709 | if (merge_subblock_idx == num_cands) |
1370 | 1242 | return 1; | |
1371 | } | ||
1372 | 1733 | return 0; | |
1373 | } | ||
1374 | |||
1375 | //8.5.5.2 Derivation process for motion vectors and reference indices in subblock merge mode | ||
1376 | //return 1 if candidate is SbCol | ||
1377 | 54562 | static int sb_mv_merge_mode(const VVCLocalContext *lc, const int merge_subblock_idx, PredictionUnit *pu) | |
1378 | { | ||
1379 | 54562 | const VVCSPS *sps = lc->fc->ps.sps; | |
1380 | 54562 | const CodingUnit *cu = lc->cu; | |
1381 | 54562 | MotionInfo *mi = &pu->mi; | |
1382 | 54562 | int num_cands = 0; | |
1383 | NeighbourContext nctx; | ||
1384 | |||
1385 | 54562 | init_neighbour_context(&nctx, lc); | |
1386 | |||
1387 | //SbCol | ||
1388 |
2/2✓ Branch 1 taken 45965 times.
✓ Branch 2 taken 8597 times.
|
54562 | if (sb_temporal_merge_candidate(lc, &nctx, pu)) { |
1389 |
2/2✓ Branch 0 taken 28768 times.
✓ Branch 1 taken 17197 times.
|
45965 | if (merge_subblock_idx == num_cands) |
1390 | 28768 | return 1; | |
1391 | 17197 | num_cands++; | |
1392 | } | ||
1393 | |||
1394 | 25794 | pu->inter_affine_flag = 1; | |
1395 | 25794 | mi->num_sb_x = cu->cb_width >> MIN_PU_LOG2; | |
1396 | 25794 | mi->num_sb_y = cu->cb_height >> MIN_PU_LOG2; | |
1397 | |||
1398 |
1/2✓ Branch 0 taken 25794 times.
✗ Branch 1 not taken.
|
25794 | if (sps->r->sps_affine_enabled_flag) { |
1399 | 25794 | const NeighbourIdx ak[] = { A0, A1 }; | |
1400 | 25794 | const NeighbourIdx bk[] = { B0, B1, B2 }; | |
1401 | //A | ||
1402 |
2/2✓ Branch 1 taken 10242 times.
✓ Branch 2 taken 15552 times.
|
25794 | if (AFFINE_MERGE_FROM_NBS(ak)) { |
1403 |
2/2✓ Branch 0 taken 5754 times.
✓ Branch 1 taken 4488 times.
|
10242 | if (merge_subblock_idx == num_cands) |
1404 | 24061 | return 0; | |
1405 | 4488 | num_cands++; | |
1406 | } | ||
1407 | |||
1408 | //B | ||
1409 |
2/2✓ Branch 1 taken 9298 times.
✓ Branch 2 taken 10742 times.
|
20040 | if (AFFINE_MERGE_FROM_NBS(bk)) { |
1410 |
2/2✓ Branch 0 taken 4394 times.
✓ Branch 1 taken 4904 times.
|
9298 | if (merge_subblock_idx == num_cands) |
1411 | 4394 | return 0; | |
1412 | 4904 | num_cands++; | |
1413 | } | ||
1414 | |||
1415 | //Const1 to Const6 | ||
1416 |
2/2✓ Branch 1 taken 13913 times.
✓ Branch 2 taken 1733 times.
|
15646 | if (affine_merge_const_candidates(lc, mi, &nctx, merge_subblock_idx, num_cands)) |
1417 | 13913 | return 0; | |
1418 | } | ||
1419 | //Zero | ||
1420 | 1733 | affine_merge_zero_motion(lc, mi); | |
1421 | 1733 | return 0; | |
1422 | } | ||
1423 | |||
1424 | 54562 | void ff_vvc_sb_mv_merge_mode(VVCLocalContext *lc, const int merge_subblock_idx, PredictionUnit *pu) | |
1425 | { | ||
1426 | 54562 | const CodingUnit *cu = lc->cu; | |
1427 | 54562 | ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height); | |
1428 |
2/2✓ Branch 1 taken 25794 times.
✓ Branch 2 taken 28768 times.
|
54562 | if (!sb_mv_merge_mode(lc, merge_subblock_idx, pu)) { |
1429 | 25794 | ff_vvc_store_sb_mvs(lc, pu); | |
1430 | } | ||
1431 | 54562 | } | |
1432 | |||
1433 | 150731 | static int mvp_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand, | |
1434 | const int lx, const int8_t *ref_idx, Mv *mv) | ||
1435 | { | ||
1436 | 150731 | const VVCFrameContext *fc = lc->fc; | |
1437 | 150731 | const RefPicList *rpl = lc->sc->rpl; | |
1438 | 150731 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
1439 | 150731 | const MvField* tab_mvf = fc->tab.mvf; | |
1440 | 150731 | const MvField *mvf = &TAB_MVF(x_cand, y_cand); | |
1441 | 150731 | const PredFlag maskx = lx + 1; | |
1442 | 150731 | const int poc = rpl[lx].refs[ref_idx[lx]].poc; | |
1443 | 150731 | int available = 0; | |
1444 | |||
1445 |
4/4✓ Branch 0 taken 115750 times.
✓ Branch 1 taken 34981 times.
✓ Branch 2 taken 76895 times.
✓ Branch 3 taken 38855 times.
|
150731 | if ((mvf->pred_flag & maskx) && rpl[lx].refs[mvf->ref_idx[lx]].poc == poc) { |
1446 | 76895 | available = 1; | |
1447 | 76895 | *mv = mvf->mv[lx]; | |
1448 | } else { | ||
1449 | 73836 | const int ly = !lx; | |
1450 | 73836 | const PredFlag masky = ly + 1; | |
1451 |
4/4✓ Branch 0 taken 50175 times.
✓ Branch 1 taken 23661 times.
✓ Branch 2 taken 10524 times.
✓ Branch 3 taken 39651 times.
|
73836 | if ((mvf->pred_flag & masky) && rpl[ly].refs[mvf->ref_idx[ly]].poc == poc) { |
1452 | 10524 | available = 1; | |
1453 | 10524 | *mv = mvf->mv[ly]; | |
1454 | } | ||
1455 | } | ||
1456 | |||
1457 | 150731 | return available; | |
1458 | } | ||
1459 | |||
1460 | 30704 | static int affine_mvp_candidate(const VVCLocalContext *lc, | |
1461 | const int x_cand, const int y_cand, const int lx, const int8_t *ref_idx, | ||
1462 | Mv *cps, const int num_cp) | ||
1463 | { | ||
1464 | 30704 | const VVCFrameContext *fc = lc->fc; | |
1465 | 30704 | int x_nb, y_nb, nbw, nbh, motion_model_idc, available = 0; | |
1466 | |||
1467 | 30704 | motion_model_idc = affine_neighbour_cb(fc, x_cand, y_cand, &x_nb, &y_nb, &nbw, &nbh); | |
1468 |
2/2✓ Branch 0 taken 7687 times.
✓ Branch 1 taken 23017 times.
|
30704 | if (motion_model_idc) { |
1469 | 7687 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
1470 | 7687 | const MvField* tab_mvf = fc->tab.mvf; | |
1471 | 7687 | const MvField *mvf = &TAB_MVF(x_nb, y_nb); | |
1472 | 7687 | RefPicList* rpl = lc->sc->rpl; | |
1473 | 7687 | const PredFlag maskx = lx + 1; | |
1474 | 7687 | const int poc = rpl[lx].refs[ref_idx[lx]].poc; | |
1475 | |||
1476 |
4/4✓ Branch 0 taken 6481 times.
✓ Branch 1 taken 1206 times.
✓ Branch 2 taken 5259 times.
✓ Branch 3 taken 1222 times.
|
7687 | if ((mvf->pred_flag & maskx) && rpl[lx].refs[mvf->ref_idx[lx]].poc == poc) { |
1477 | 5259 | available = 1; | |
1478 | 5259 | affine_cps_from_nb(lc, x_nb, y_nb, nbw, nbh, lx, cps, num_cp); | |
1479 | } else { | ||
1480 | 2428 | const int ly = !lx; | |
1481 | 2428 | const PredFlag masky = ly + 1; | |
1482 |
4/4✓ Branch 0 taken 1586 times.
✓ Branch 1 taken 842 times.
✓ Branch 2 taken 779 times.
✓ Branch 3 taken 807 times.
|
2428 | if ((mvf->pred_flag & masky) && rpl[ly].refs[mvf->ref_idx[ly]].poc == poc) { |
1483 | 779 | available = 1; | |
1484 | 779 | affine_cps_from_nb(lc, x_nb, y_nb, nbw, nbh, ly, cps, num_cp); | |
1485 | } | ||
1486 | } | ||
1487 | |||
1488 | } | ||
1489 | 30704 | return available; | |
1490 | } | ||
1491 | |||
1492 | 170491 | static int mvp_from_nbs(NeighbourContext *ctx, | |
1493 | const NeighbourIdx *nbs, const int num_nbs, const int lx, const int8_t *ref_idx, const int amvr_shift, | ||
1494 | Mv *cps, const int num_cps) | ||
1495 | { | ||
1496 | 170491 | const VVCLocalContext *lc = ctx->lc; | |
1497 | 170491 | int available = 0; | |
1498 | |||
1499 |
2/2✓ Branch 0 taken 337866 times.
✓ Branch 1 taken 77034 times.
|
414900 | for (int i = 0; i < num_nbs; i++) { |
1500 | 337866 | Neighbour *n = &ctx->neighbours[nbs[i]]; | |
1501 |
2/2✓ Branch 1 taken 181435 times.
✓ Branch 2 taken 156431 times.
|
337866 | if (check_available(n, lc, 0)) { |
1502 |
2/2✓ Branch 0 taken 30704 times.
✓ Branch 1 taken 150731 times.
|
181435 | if (num_cps > 1) |
1503 | 30704 | available = affine_mvp_candidate(lc, n->x, n->y, lx, ref_idx, cps, num_cps); | |
1504 | else | ||
1505 | 150731 | available = mvp_candidate(lc, n->x, n->y, lx, ref_idx, cps); | |
1506 |
2/2✓ Branch 0 taken 93457 times.
✓ Branch 1 taken 87978 times.
|
181435 | if (available) { |
1507 |
2/2✓ Branch 0 taken 102475 times.
✓ Branch 1 taken 93457 times.
|
195932 | for (int c = 0; c < num_cps; c++) |
1508 | 102475 | ff_vvc_round_mv(cps + c, amvr_shift, amvr_shift); | |
1509 | 93457 | return 1; | |
1510 | } | ||
1511 | } | ||
1512 | } | ||
1513 | 77034 | return 0; | |
1514 | } | ||
1515 | |||
1516 | //get mvp from neighbours | ||
1517 | #define AFFINE_MVP_FROM_NBS(nbs) \ | ||
1518 | mvp_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), lx, ref_idx, amvr_shift, cps, num_cp) \ | ||
1519 | |||
1520 | #define MVP_FROM_NBS(nbs) \ | ||
1521 | mvp_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), lx, ref_idx, amvr_shift, mv, 1) \ | ||
1522 | |||
1523 | 89839 | static int mvp_spatial_candidates(const VVCLocalContext *lc, | |
1524 | const int mvp_lx_flag, const int lx, const int8_t* ref_idx, const int amvr_shift, | ||
1525 | Mv* mv, int *nb_merge_cand) | ||
1526 | { | ||
1527 | 89839 | const NeighbourIdx ak[] = { A0, A1 }; | |
1528 | 89839 | const NeighbourIdx bk[] = { B0, B1, B2 }; | |
1529 | NeighbourContext nctx; | ||
1530 | 89839 | int available_a, num_cands = 0; | |
1531 | 89839 | LOCAL_ALIGNED_8(Mv, mv_a, [1]); | |
1532 | |||
1533 | 89839 | init_neighbour_context(&nctx, lc); | |
1534 | |||
1535 | 89839 | available_a = MVP_FROM_NBS(ak); | |
1536 |
2/2✓ Branch 0 taken 53099 times.
✓ Branch 1 taken 36740 times.
|
89839 | if (available_a) { |
1537 |
2/2✓ Branch 0 taken 32192 times.
✓ Branch 1 taken 20907 times.
|
53099 | if (mvp_lx_flag == num_cands) |
1538 | 32192 | return 1; | |
1539 | 20907 | num_cands++; | |
1540 | 20907 | *mv_a = *mv; | |
1541 | } | ||
1542 |
2/2✓ Branch 1 taken 34320 times.
✓ Branch 2 taken 23327 times.
|
57647 | if (MVP_FROM_NBS(bk)) { |
1543 |
4/4✓ Branch 0 taken 17878 times.
✓ Branch 1 taken 16442 times.
✓ Branch 2 taken 14978 times.
✓ Branch 3 taken 2900 times.
|
34320 | if (!available_a || !IS_SAME_MV(mv_a, mv)) { |
1544 |
2/2✓ Branch 0 taken 25685 times.
✓ Branch 1 taken 5735 times.
|
31420 | if (mvp_lx_flag == num_cands) |
1545 | 25685 | return 1; | |
1546 | 5735 | num_cands++; | |
1547 | } | ||
1548 | } | ||
1549 | 31962 | *nb_merge_cand = num_cands; | |
1550 | 31962 | return 0; | |
1551 | } | ||
1552 | |||
1553 | 31962 | static int mvp_temporal_candidates(const VVCLocalContext* lc, | |
1554 | const int mvp_lx_flag, const int lx, const int8_t *ref_idx, const int amvr_shift, | ||
1555 | Mv* mv, int *num_cands) | ||
1556 | { | ||
1557 |
2/2✓ Branch 1 taken 18573 times.
✓ Branch 2 taken 13389 times.
|
31962 | if (temporal_luma_motion_vector(lc, ref_idx[lx], mv, lx, 1, 0)) { |
1558 |
2/2✓ Branch 0 taken 15019 times.
✓ Branch 1 taken 3554 times.
|
18573 | if (mvp_lx_flag == *num_cands) { |
1559 | 15019 | ff_vvc_round_mv(mv, amvr_shift, amvr_shift); | |
1560 | 15019 | return 1; | |
1561 | } | ||
1562 | 3554 | (*num_cands)++; | |
1563 | } | ||
1564 | 16943 | return 0; | |
1565 | |||
1566 | } | ||
1567 | |||
1568 | 16943 | static int mvp_history_candidates(const VVCLocalContext *lc, | |
1569 | const int mvp_lx_flag, const int lx, const int8_t ref_idx, const int amvr_shift, | ||
1570 | Mv *mv, int num_cands) | ||
1571 | { | ||
1572 | 16943 | const EntryPoint* ep = lc->ep; | |
1573 | 16943 | const RefPicList* rpl = lc->sc->rpl; | |
1574 | 16943 | const int poc = rpl[lx].refs[ref_idx].poc; | |
1575 | |||
1576 |
2/2✓ Branch 0 taken 1945 times.
✓ Branch 1 taken 14998 times.
|
16943 | if (ep->num_hmvp == 0) |
1577 | 1945 | return 0; | |
1578 |
2/2✓ Branch 0 taken 31451 times.
✓ Branch 1 taken 4725 times.
|
36176 | for (int i = 1; i <= FFMIN(4, ep->num_hmvp); i++) { |
1579 | 31451 | const MvField* h = &ep->hmvp[i - 1]; | |
1580 |
2/2✓ Branch 0 taken 54057 times.
✓ Branch 1 taken 21178 times.
|
75235 | for (int j = 0; j < 2; j++) { |
1581 |
2/2✓ Branch 0 taken 22606 times.
✓ Branch 1 taken 31451 times.
|
54057 | const int ly = (j ? !lx : lx); |
1582 | 54057 | PredFlag mask = PF_L0 + ly; | |
1583 |
4/4✓ Branch 0 taken 36934 times.
✓ Branch 1 taken 17123 times.
✓ Branch 2 taken 12531 times.
✓ Branch 3 taken 24403 times.
|
54057 | if ((h->pred_flag & mask) && poc == rpl[ly].refs[h->ref_idx[ly]].poc) { |
1584 |
2/2✓ Branch 0 taken 10273 times.
✓ Branch 1 taken 2258 times.
|
12531 | if (mvp_lx_flag == num_cands) { |
1585 | 10273 | *mv = h->mv[ly]; | |
1586 | 10273 | ff_vvc_round_mv(mv, amvr_shift, amvr_shift); | |
1587 | 10273 | return 1; | |
1588 | } | ||
1589 | 2258 | num_cands++; | |
1590 | } | ||
1591 | } | ||
1592 | } | ||
1593 | 4725 | return 0; | |
1594 | } | ||
1595 | |||
1596 | //8.5.2.8 Derivation process for luma motion vector prediction | ||
1597 | 89839 | static void mvp(const VVCLocalContext *lc, const int mvp_lx_flag, const int lx, | |
1598 | const int8_t *ref_idx, const int amvr_shift, Mv *mv) | ||
1599 | { | ||
1600 | int num_cands; | ||
1601 | |||
1602 |
2/2✓ Branch 1 taken 57877 times.
✓ Branch 2 taken 31962 times.
|
89839 | if (mvp_spatial_candidates(lc, mvp_lx_flag, lx, ref_idx, amvr_shift, mv, &num_cands)) |
1603 | 83169 | return; | |
1604 | |||
1605 |
2/2✓ Branch 1 taken 15019 times.
✓ Branch 2 taken 16943 times.
|
31962 | if (mvp_temporal_candidates(lc, mvp_lx_flag, lx, ref_idx, amvr_shift, mv, &num_cands)) |
1606 | 15019 | return; | |
1607 | |||
1608 |
2/2✓ Branch 1 taken 10273 times.
✓ Branch 2 taken 6670 times.
|
16943 | if (mvp_history_candidates(lc, mvp_lx_flag, lx, ref_idx[lx], amvr_shift, mv, num_cands)) |
1609 | 10273 | return; | |
1610 | |||
1611 | 6670 | memset(mv, 0, sizeof(*mv)); | |
1612 | } | ||
1613 | |||
1614 | 70428 | void ff_vvc_mvp(VVCLocalContext *lc, const int *mvp_lx_flag, const int amvr_shift, MotionInfo *mi) | |
1615 | { | ||
1616 | 70428 | const CodingUnit *cu = lc->cu; | |
1617 | 70428 | mi->num_sb_x = 1; | |
1618 | 70428 | mi->num_sb_y = 1; | |
1619 | |||
1620 | 70428 | ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height); | |
1621 |
2/2✓ Branch 0 taken 57970 times.
✓ Branch 1 taken 12458 times.
|
70428 | if (mi->pred_flag != PF_L1) |
1622 | 57970 | mvp(lc, mvp_lx_flag[L0], L0, mi->ref_idx, amvr_shift, &mi->mv[L0][0]); | |
1623 |
2/2✓ Branch 0 taken 31869 times.
✓ Branch 1 taken 38559 times.
|
70428 | if (mi->pred_flag != PF_L0) |
1624 | 31869 | mvp(lc, mvp_lx_flag[L1], L1, mi->ref_idx, amvr_shift, &mi->mv[L1][0]); | |
1625 | 70428 | } | |
1626 | |||
1627 | 67240 | static int ibc_spatial_candidates(const VVCLocalContext *lc, const int merge_idx, Mv *const cand_list, int *nb_merge_cand) | |
1628 | { | ||
1629 | 67240 | const CodingUnit *cu = lc->cu; | |
1630 | 67240 | const VVCFrameContext *fc = lc->fc; | |
1631 | 67240 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
1632 | 67240 | const MvField *tab_mvf = fc->tab.mvf; | |
1633 | 67240 | const int is_gt4by4 = (cu->cb_width * cu->cb_height) > 16; | |
1634 | 67240 | int num_cands = 0; | |
1635 | |||
1636 | NeighbourContext nctx; | ||
1637 | 67240 | Neighbour *a1 = &nctx.neighbours[A1]; | |
1638 | 67240 | Neighbour *b1 = &nctx.neighbours[B1]; | |
1639 | |||
1640 |
2/2✓ Branch 0 taken 21469 times.
✓ Branch 1 taken 45771 times.
|
67240 | if (!is_gt4by4) { |
1641 | 21469 | *nb_merge_cand = 0; | |
1642 | 21469 | return 0; | |
1643 | } | ||
1644 | |||
1645 | 45771 | init_neighbour_context(&nctx, lc); | |
1646 | |||
1647 |
2/2✓ Branch 1 taken 28927 times.
✓ Branch 2 taken 16844 times.
|
45771 | if (check_available(a1, lc, 0)) { |
1648 | 28927 | cand_list[num_cands++] = TAB_MVF(a1->x, a1->y).mv[L0]; | |
1649 |
2/2✓ Branch 0 taken 19533 times.
✓ Branch 1 taken 9394 times.
|
28927 | if (num_cands > merge_idx) |
1650 | 19533 | return 1; | |
1651 | } | ||
1652 |
2/2✓ Branch 1 taken 13791 times.
✓ Branch 2 taken 12447 times.
|
26238 | if (check_available(b1, lc, 0)) { |
1653 | 13791 | const MvField *mvf = &TAB_MVF(b1->x, b1->y); | |
1654 |
4/4✓ Branch 0 taken 6779 times.
✓ Branch 1 taken 7012 times.
✓ Branch 2 taken 6134 times.
✓ Branch 3 taken 645 times.
|
13791 | if (!num_cands || !IS_SAME_MV(&cand_list[0], mvf->mv)) { |
1655 | 13146 | cand_list[num_cands++] = mvf->mv[L0]; | |
1656 |
2/2✓ Branch 0 taken 10406 times.
✓ Branch 1 taken 2740 times.
|
13146 | if (num_cands > merge_idx) |
1657 | 10406 | return 1; | |
1658 | } | ||
1659 | } | ||
1660 | |||
1661 | 15832 | *nb_merge_cand = num_cands; | |
1662 | 15832 | return 0; | |
1663 | } | ||
1664 | |||
1665 | 37301 | static int ibc_history_candidates(const VVCLocalContext *lc, | |
1666 | const int merge_idx, Mv *cand_list, int *nb_merge_cand) | ||
1667 | { | ||
1668 | 37301 | const CodingUnit *cu = lc->cu; | |
1669 | 37301 | const EntryPoint *ep = lc->ep; | |
1670 | 37301 | const int is_gt4by4 = (cu->cb_width * cu->cb_height) > 16; | |
1671 | 37301 | int num_cands = *nb_merge_cand; | |
1672 | |||
1673 |
2/2✓ Branch 0 taken 57271 times.
✓ Branch 1 taken 1612 times.
|
58883 | for (int i = 1; i <= ep->num_hmvp_ibc; i++) { |
1674 | 57271 | int same_motion = 0; | |
1675 | 57271 | const MvField *mvf = &ep->hmvp_ibc[ep->num_hmvp_ibc - i]; | |
1676 |
2/2✓ Branch 0 taken 14282 times.
✓ Branch 1 taken 53419 times.
|
67701 | for (int j = 0; j < *nb_merge_cand; j++) { |
1677 |
5/6✓ Branch 0 taken 14282 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6342 times.
✓ Branch 3 taken 7940 times.
✓ Branch 4 taken 3852 times.
✓ Branch 5 taken 2490 times.
|
14282 | same_motion = is_gt4by4 && i == 1 && IS_SAME_MV(&mvf->mv[L0], &cand_list[j]); |
1678 |
2/2✓ Branch 0 taken 3852 times.
✓ Branch 1 taken 10430 times.
|
14282 | if (same_motion) |
1679 | 3852 | break; | |
1680 | } | ||
1681 |
2/2✓ Branch 0 taken 53419 times.
✓ Branch 1 taken 3852 times.
|
57271 | if (!same_motion) { |
1682 | 53419 | cand_list[num_cands++] = mvf->mv[L0]; | |
1683 |
2/2✓ Branch 0 taken 35689 times.
✓ Branch 1 taken 17730 times.
|
53419 | if (num_cands > merge_idx) |
1684 | 35689 | return 1; | |
1685 | } | ||
1686 | } | ||
1687 | |||
1688 | 1612 | *nb_merge_cand = num_cands; | |
1689 | 1612 | return 0; | |
1690 | } | ||
1691 | |||
1692 | #define MV_BITS 18 | ||
1693 | #define IBC_SHIFT(v) ((v) >= (1 << (MV_BITS - 1)) ? ((v) - (1 << MV_BITS)) : (v)) | ||
1694 | |||
1695 | 39050 | static inline void ibc_add_mvp(Mv *mv, Mv *mvp, const int amvr_shift) | |
1696 | { | ||
1697 | 39050 | ff_vvc_round_mv(mv, amvr_shift, 0); | |
1698 | 39050 | ff_vvc_round_mv(mvp, amvr_shift, amvr_shift); | |
1699 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 39050 times.
|
39050 | mv->x = IBC_SHIFT(mv->x + mvp->x); |
1700 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 39050 times.
|
39050 | mv->y = IBC_SHIFT(mv->y + mvp->y); |
1701 | 39050 | } | |
1702 | |||
1703 | 67240 | static void ibc_merge_candidates(VVCLocalContext *lc, const int merge_idx, Mv *mv) | |
1704 | { | ||
1705 | 67240 | const CodingUnit *cu = lc->cu; | |
1706 | 67240 | LOCAL_ALIGNED_8(Mv, cand_list, [MRG_MAX_NUM_CANDS]); | |
1707 | int nb_cands; | ||
1708 | |||
1709 | 67240 | ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height); | |
1710 |
4/4✓ Branch 1 taken 37301 times.
✓ Branch 2 taken 29939 times.
✓ Branch 3 taken 35689 times.
✓ Branch 4 taken 1612 times.
|
104541 | if (ibc_spatial_candidates(lc, merge_idx, cand_list, &nb_cands) || |
1711 | 37301 | ibc_history_candidates(lc, merge_idx, cand_list, &nb_cands)) { | |
1712 | 65628 | *mv = cand_list[merge_idx]; | |
1713 | 65628 | return; | |
1714 | } | ||
1715 | |||
1716 | //zero mv | ||
1717 | 1612 | memset(mv, 0, sizeof(*mv)); | |
1718 | } | ||
1719 | |||
1720 | 67240 | static int ibc_check_mv(VVCLocalContext *lc, Mv *mv) | |
1721 | { | ||
1722 | 67240 | const VVCFrameContext *fc = lc->fc; | |
1723 | 67240 | const VVCSPS *sps = lc->fc->ps.sps; | |
1724 | 67240 | const CodingUnit *cu = lc->cu; | |
1725 | 67240 | const Mv *bv = &cu->pu.mi.mv[L0][0]; | |
1726 | |||
1727 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 67240 times.
|
67240 | if (sps->ctb_size_y < ((cu->y0 + (bv->y >> 4)) & (sps->ctb_size_y - 1)) + cu->cb_height) { |
1728 | ✗ | av_log(fc->log_ctx, AV_LOG_ERROR, "IBC region spans multiple CTBs.\n"); | |
1729 | ✗ | return AVERROR_INVALIDDATA; | |
1730 | } | ||
1731 | |||
1732 | 67240 | return 0; | |
1733 | } | ||
1734 | |||
1735 | 39050 | int ff_vvc_mvp_ibc(VVCLocalContext *lc, const int mvp_l0_flag, const int amvr_shift, Mv *mv) | |
1736 | { | ||
1737 | 39050 | LOCAL_ALIGNED_8(Mv, mvp, [1]); | |
1738 | |||
1739 | 39050 | ibc_merge_candidates(lc, mvp_l0_flag, mvp); | |
1740 | 39050 | ibc_add_mvp(mv, mvp, amvr_shift); | |
1741 | 39050 | return ibc_check_mv(lc, mv); | |
1742 | } | ||
1743 | |||
1744 | 28190 | int ff_vvc_luma_mv_merge_ibc(VVCLocalContext *lc, const int merge_idx, Mv *mv) | |
1745 | { | ||
1746 | 28190 | ibc_merge_candidates(lc, merge_idx, mv); | |
1747 | 28190 | return ibc_check_mv(lc, mv); | |
1748 | } | ||
1749 | |||
1750 | 24930 | static int affine_mvp_constructed_cp(NeighbourContext *ctx, | |
1751 | const NeighbourIdx *neighbour, const int num_neighbour, | ||
1752 | const int lx, const int8_t ref_idx, const int amvr_shift, Mv *cp) | ||
1753 | { | ||
1754 | 24930 | const VVCLocalContext *lc = ctx->lc; | |
1755 | 24930 | const VVCFrameContext *fc = lc->fc; | |
1756 | 24930 | const MvField *tab_mvf = fc->tab.mvf; | |
1757 | 24930 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
1758 | 24930 | const RefPicList* rpl = lc->sc->rpl; | |
1759 | 24930 | int available = 0; | |
1760 | |||
1761 |
2/2✓ Branch 0 taken 38907 times.
✓ Branch 1 taken 8478 times.
|
47385 | for (int i = 0; i < num_neighbour; i++) { |
1762 | 38907 | Neighbour *n = &ctx->neighbours[neighbour[i]]; | |
1763 |
2/2✓ Branch 1 taken 24498 times.
✓ Branch 2 taken 14409 times.
|
38907 | if (check_available(n, ctx->lc, 0)) { |
1764 | 24498 | const PredFlag maskx = lx + 1; | |
1765 | 24498 | const MvField* mvf = &TAB_MVF(n->x, n->y); | |
1766 | 24498 | const int poc = rpl[lx].refs[ref_idx].poc; | |
1767 |
4/4✓ Branch 0 taken 20002 times.
✓ Branch 1 taken 4496 times.
✓ Branch 2 taken 14579 times.
✓ Branch 3 taken 5423 times.
|
24498 | if ((mvf->pred_flag & maskx) && rpl[lx].refs[mvf->ref_idx[lx]].poc == poc) { |
1768 | 14579 | available = 1; | |
1769 | 14579 | *cp = mvf->mv[lx]; | |
1770 | } else { | ||
1771 | 9919 | const int ly = !lx; | |
1772 | 9919 | const PredFlag masky = ly + 1; | |
1773 |
4/4✓ Branch 0 taken 6735 times.
✓ Branch 1 taken 3184 times.
✓ Branch 2 taken 1873 times.
✓ Branch 3 taken 4862 times.
|
9919 | if ((mvf->pred_flag & masky) && rpl[ly].refs[mvf->ref_idx[ly]].poc == poc) { |
1774 | 1873 | available = 1; | |
1775 | 1873 | *cp = mvf->mv[ly]; | |
1776 | } | ||
1777 | } | ||
1778 |
2/2✓ Branch 0 taken 16452 times.
✓ Branch 1 taken 8046 times.
|
24498 | if (available) { |
1779 | 16452 | ff_vvc_round_mv(cp, amvr_shift, amvr_shift); | |
1780 | 16452 | return 1; | |
1781 | } | ||
1782 | } | ||
1783 | } | ||
1784 | 8478 | return 0; | |
1785 | } | ||
1786 | |||
1787 | #define AFFINE_MVP_CONSTRUCTED_CP(cands, cp) \ | ||
1788 | affine_mvp_constructed_cp(nctx, cands, FF_ARRAY_ELEMS(cands), lx, ref_idx, \ | ||
1789 | amvr_shift, cp) | ||
1790 | |||
1791 | //8.5.5.8 Derivation process for constructed affine control point motion vector prediction candidates | ||
1792 | 8310 | static int affine_mvp_const1(NeighbourContext* nctx, | |
1793 | const int lx, const int8_t ref_idx, const int amvr_shift, | ||
1794 | Mv *cps, int *available) | ||
1795 | { | ||
1796 | 8310 | const NeighbourIdx tl[] = { B2, B3, A2 }; | |
1797 | 8310 | const NeighbourIdx tr[] = { B1, B0 }; | |
1798 | 8310 | const NeighbourIdx bl[] = { A1, A0 }; | |
1799 | |||
1800 | 8310 | available[0] = AFFINE_MVP_CONSTRUCTED_CP(tl, cps + 0); | |
1801 | 8310 | available[1] = AFFINE_MVP_CONSTRUCTED_CP(tr, cps + 1); | |
1802 | 8310 | available[2] = AFFINE_MVP_CONSTRUCTED_CP(bl, cps + 2); | |
1803 |
4/4✓ Branch 0 taken 6372 times.
✓ Branch 1 taken 1938 times.
✓ Branch 2 taken 4831 times.
✓ Branch 3 taken 1541 times.
|
8310 | return available[0] && available[1]; |
1804 | } | ||
1805 | |||
1806 | //8.5.5.7 item 7 | ||
1807 | 3698 | static void affine_mvp_const2(const int idx, Mv *cps, const int num_cp) | |
1808 | { | ||
1809 | 3698 | const Mv mv = cps[idx]; | |
1810 |
2/2✓ Branch 0 taken 9160 times.
✓ Branch 1 taken 3698 times.
|
12858 | for (int j = 0; j < num_cp; j++) |
1811 | 9160 | cps[j] = mv; | |
1812 | 3698 | } | |
1813 | |||
1814 | //8.5.5.7 Derivation process for luma affine control point motion vector predictors | ||
1815 | 12526 | static void affine_mvp(const VVCLocalContext *lc, | |
1816 | const int mvp_lx_flag, const int lx, const int8_t *ref_idx, const int amvr_shift, | ||
1817 | MotionModelIdc motion_model_idc, Mv *cps) | ||
1818 | { | ||
1819 | 12526 | const NeighbourIdx ak[] = { A0, A1 }; | |
1820 | 12526 | const NeighbourIdx bk[] = { B0, B1, B2 }; | |
1821 | 12526 | const int num_cp = motion_model_idc + 1; | |
1822 | NeighbourContext nctx; | ||
1823 | int available[MAX_CONTROL_POINTS]; | ||
1824 | 12526 | int num_cands = 0; | |
1825 | |||
1826 | 12526 | init_neighbour_context(&nctx, lc); | |
1827 | //Ak | ||
1828 |
2/2✓ Branch 1 taken 3048 times.
✓ Branch 2 taken 9478 times.
|
12526 | if (AFFINE_MVP_FROM_NBS(ak)) { |
1829 |
2/2✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 1001 times.
|
3048 | if (mvp_lx_flag == num_cands) |
1830 | 11769 | return; | |
1831 | 1001 | num_cands++; | |
1832 | } | ||
1833 | //Bk | ||
1834 |
2/2✓ Branch 1 taken 2990 times.
✓ Branch 2 taken 7489 times.
|
10479 | if (AFFINE_MVP_FROM_NBS(bk)) { |
1835 |
2/2✓ Branch 0 taken 2169 times.
✓ Branch 1 taken 821 times.
|
2990 | if (mvp_lx_flag == num_cands) |
1836 | 2169 | return; | |
1837 | 821 | num_cands++; | |
1838 | } | ||
1839 | |||
1840 | //Const1 | ||
1841 |
2/2✓ Branch 1 taken 4831 times.
✓ Branch 2 taken 3479 times.
|
8310 | if (affine_mvp_const1(&nctx, lx, ref_idx[lx], amvr_shift, cps, available)) { |
1842 |
4/4✓ Branch 0 taken 1293 times.
✓ Branch 1 taken 3538 times.
✓ Branch 2 taken 739 times.
✓ Branch 3 taken 554 times.
|
4831 | if (available[2] || motion_model_idc == MOTION_4_PARAMS_AFFINE) { |
1843 |
2/2✓ Branch 0 taken 2951 times.
✓ Branch 1 taken 1326 times.
|
4277 | if (mvp_lx_flag == num_cands) |
1844 | 2951 | return; | |
1845 | 1326 | num_cands++; | |
1846 | } | ||
1847 | } | ||
1848 | |||
1849 | //Const2 | ||
1850 |
2/2✓ Branch 0 taken 10743 times.
✓ Branch 1 taken 1661 times.
|
12404 | for (int i = 2; i >= 0; i--) { |
1851 |
2/2✓ Branch 0 taken 4276 times.
✓ Branch 1 taken 6467 times.
|
10743 | if (available[i]) { |
1852 |
2/2✓ Branch 0 taken 3698 times.
✓ Branch 1 taken 578 times.
|
4276 | if (mvp_lx_flag == num_cands) { |
1853 | 3698 | affine_mvp_const2(i, cps, num_cp); | |
1854 | 3698 | return; | |
1855 | } | ||
1856 | 578 | num_cands++; | |
1857 | } | ||
1858 | } | ||
1859 |
2/2✓ Branch 1 taken 1127 times.
✓ Branch 2 taken 534 times.
|
1661 | if (temporal_luma_motion_vector(lc, ref_idx[lx], cps, lx, 1, 0)) { |
1860 |
2/2✓ Branch 0 taken 904 times.
✓ Branch 1 taken 223 times.
|
1127 | if (mvp_lx_flag == num_cands) { |
1861 | 904 | ff_vvc_round_mv(cps, amvr_shift, amvr_shift); | |
1862 |
2/2✓ Branch 0 taken 1197 times.
✓ Branch 1 taken 904 times.
|
2101 | for (int i = 1; i < num_cp; i++) |
1863 | 1197 | cps[i] = cps[0]; | |
1864 | 904 | return; | |
1865 | } | ||
1866 | 223 | num_cands++; | |
1867 | } | ||
1868 | |||
1869 | //Zero Mv | ||
1870 | 757 | memset(cps, 0, num_cp * sizeof(Mv)); | |
1871 | } | ||
1872 | |||
1873 | 10170 | void ff_vvc_affine_mvp(VVCLocalContext *lc, const int *mvp_lx_flag, const int amvr_shift, MotionInfo *mi) | |
1874 | { | ||
1875 | 10170 | const CodingUnit *cu = lc->cu; | |
1876 | |||
1877 | 10170 | mi->num_sb_x = cu->cb_width >> MIN_PU_LOG2; | |
1878 | 10170 | mi->num_sb_y = cu->cb_height >> MIN_PU_LOG2; | |
1879 | |||
1880 | 10170 | ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height); | |
1881 |
2/2✓ Branch 0 taken 8973 times.
✓ Branch 1 taken 1197 times.
|
10170 | if (mi->pred_flag != PF_L1) |
1882 | 8973 | affine_mvp(lc, mvp_lx_flag[L0], L0, mi->ref_idx, amvr_shift, mi->motion_model_idc, &mi->mv[L0][0]); | |
1883 |
2/2✓ Branch 0 taken 3553 times.
✓ Branch 1 taken 6617 times.
|
10170 | if (mi->pred_flag != PF_L0) |
1884 | 3553 | affine_mvp(lc, mvp_lx_flag[L1], L1, mi->ref_idx, amvr_shift, mi->motion_model_idc, &mi->mv[L1][0]); | |
1885 | 10170 | } | |
1886 | |||
1887 | //8.5.2.14 Rounding process for motion vectors | ||
1888 | 8197349 | void ff_vvc_round_mv(Mv *mv, const int lshift, const int rshift) | |
1889 | { | ||
1890 |
2/2✓ Branch 0 taken 8156623 times.
✓ Branch 1 taken 40726 times.
|
8197349 | if (rshift) { |
1891 | 8156623 | const int offset = 1 << (rshift - 1); | |
1892 | 8156623 | mv->x = ((mv->x + offset - (mv->x >= 0)) >> rshift) * (1 << lshift); | |
1893 | 8156623 | mv->y = ((mv->y + offset - (mv->y >= 0)) >> rshift) * (1 << lshift); | |
1894 | } else { | ||
1895 | 40726 | mv->x = mv->x * (1 << lshift); | |
1896 | 40726 | mv->y = mv->y * (1 << lshift); | |
1897 | } | ||
1898 | 8197349 | } | |
1899 | |||
1900 | 5586456 | void ff_vvc_clip_mv(Mv *mv) | |
1901 | { | ||
1902 | 5586456 | mv->x = av_clip(mv->x, -(1 << 17), (1 << 17) - 1); | |
1903 | 5586456 | mv->y = av_clip(mv->y, -(1 << 17), (1 << 17) - 1); | |
1904 | 5586456 | } | |
1905 | |||
1906 | //8.5.2.1 Derivation process for motion vector components and reference indices | ||
1907 | 367760 | 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) | |
1908 | { | ||
1909 | 367760 | const uint8_t plevel = fc->ps.sps->log2_parallel_merge_level; | |
1910 | |||
1911 |
2/2✓ Branch 0 taken 357636 times.
✓ Branch 1 taken 10124 times.
|
725396 | return x0_br >> plevel > x0 >> plevel && |
1912 |
2/2✓ Branch 0 taken 352864 times.
✓ Branch 1 taken 4772 times.
|
357636 | y0_br >> plevel > y0 >> plevel; |
1913 | } | ||
1914 | |||
1915 | 398635 | static void update_hmvp(MvField *hmvp, int *num_hmvp, const MvField *mvf, | |
1916 | int (*compare)(const MvField *n, const MvField *o)) | ||
1917 | { | ||
1918 | int i; | ||
1919 |
2/2✓ Branch 0 taken 1667639 times.
✓ Branch 1 taken 206411 times.
|
1874050 | for (i = 0; i < *num_hmvp; i++) { |
1920 |
2/2✓ Branch 1 taken 192224 times.
✓ Branch 2 taken 1475415 times.
|
1667639 | if (compare(mvf, hmvp + i)) { |
1921 | 192224 | (*num_hmvp)--; | |
1922 | 192224 | break; | |
1923 | } | ||
1924 | } | ||
1925 |
2/2✓ Branch 0 taken 182149 times.
✓ Branch 1 taken 216486 times.
|
398635 | if (i == MAX_NUM_HMVP_CANDS) { |
1926 | 182149 | (*num_hmvp)--; | |
1927 | 182149 | i = 0; | |
1928 | } | ||
1929 | |||
1930 | 398635 | memmove(hmvp + i, hmvp + i + 1, (*num_hmvp - i) * sizeof(MvField)); | |
1931 | 398635 | hmvp[(*num_hmvp)++] = *mvf; | |
1932 | 398635 | } | |
1933 | |||
1934 | 189737 | static int compare_l0_mv(const MvField *n, const MvField *o) | |
1935 | { | ||
1936 | 189737 | return IS_SAME_MV(&n->mv[L0], &o->mv[L0]); | |
1937 | } | ||
1938 | |||
1939 | //8.6.2.4 Derivation process for IBC history-based block vector candidates | ||
1940 | //8.5.2.16 Updating process for the history-based motion vector predictor candidate list | ||
1941 | 435000 | void ff_vvc_update_hmvp(VVCLocalContext *lc, const MotionInfo *mi) | |
1942 | { | ||
1943 | 435000 | const VVCFrameContext *fc = lc->fc; | |
1944 | 435000 | const CodingUnit *cu = lc->cu; | |
1945 | 435000 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
1946 | 435000 | const MvField *tab_mvf = fc->tab.mvf; | |
1947 | 435000 | EntryPoint *ep = lc->ep; | |
1948 | |||
1949 |
2/2✓ Branch 0 taken 67240 times.
✓ Branch 1 taken 367760 times.
|
435000 | if (cu->pred_mode == MODE_IBC) { |
1950 |
2/2✓ Branch 0 taken 21469 times.
✓ Branch 1 taken 45771 times.
|
67240 | if (cu->cb_width * cu->cb_height <= 16) |
1951 | 21469 | return; | |
1952 | 45771 | update_hmvp(ep->hmvp_ibc, &ep->num_hmvp_ibc, &TAB_MVF(cu->x0, cu->y0), compare_l0_mv); | |
1953 | } else { | ||
1954 |
2/2✓ Branch 1 taken 14896 times.
✓ Branch 2 taken 352864 times.
|
367760 | if (!is_greater_mer(fc, cu->x0, cu->y0, cu->x0 + cu->cb_width, cu->y0 + cu->cb_height)) |
1955 | 14896 | return; | |
1956 | 352864 | update_hmvp(ep->hmvp, &ep->num_hmvp, &TAB_MVF(cu->x0, cu->y0), compare_mv_ref_idx); | |
1957 | } | ||
1958 | } | ||
1959 | |||
1960 | 13587731 | MvField* ff_vvc_get_mvf(const VVCFrameContext *fc, const int x0, const int y0) | |
1961 | { | ||
1962 | 13587731 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
1963 | 13587731 | MvField* tab_mvf = fc->tab.mvf; | |
1964 | |||
1965 | 13587731 | return &TAB_MVF(x0, y0); | |
1966 | } | ||
1967 |