| 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 | 674439 | 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 | 674439 | const uint8_t plevel = fc->ps.sps->log2_parallel_merge_level; | |
| 34 | |||
| 35 |
2/2✓ Branch 0 taken 42122 times.
✓ Branch 1 taken 632317 times.
|
716561 | 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 | 2182533 | static av_always_inline int compare_mv_ref_idx(const MvField *n, const MvField *o) | |
| 41 | { | ||
| 42 |
4/4✓ Branch 0 taken 1835170 times.
✓ Branch 1 taken 347363 times.
✓ Branch 2 taken 575312 times.
✓ Branch 3 taken 1259858 times.
|
2182533 | if (!o || n->pred_flag != o->pred_flag) |
| 43 | 922675 | return 0; | |
| 44 |
2/2✓ Branch 0 taken 1592629 times.
✓ Branch 1 taken 276315 times.
|
1868944 | for (int i = 0; i < 2; i++) { |
| 45 | 1592629 | PredFlag mask = i + 1; | |
| 46 |
2/2✓ Branch 0 taken 1432327 times.
✓ Branch 1 taken 160302 times.
|
1592629 | if (n->pred_flag & mask) { |
| 47 | 1432327 | const int same_ref_idx = n->ref_idx[i] == o->ref_idx[i]; | |
| 48 | 1432327 | const int same_mv = IS_SAME_MV(n->mv + i, o->mv + i); | |
| 49 |
4/4✓ Branch 0 taken 1296021 times.
✓ Branch 1 taken 136306 times.
✓ Branch 2 taken 847237 times.
✓ Branch 3 taken 448784 times.
|
1432327 | if (!same_ref_idx || !same_mv) |
| 50 | 983543 | return 0; | |
| 51 | } | ||
| 52 | } | ||
| 53 | 276315 | return 1; | |
| 54 | } | ||
| 55 | |||
| 56 | // 8.5.2.15 Temporal motion buffer compression process for collocated motion vectors | ||
| 57 | 2418101 | static av_always_inline void mv_compression(Mv *motion) | |
| 58 | { | ||
| 59 | 2418101 | int mv[2] = {motion->x, motion->y}; | |
| 60 |
2/2✓ Branch 0 taken 4836202 times.
✓ Branch 1 taken 2418101 times.
|
7254303 | for (int i = 0; i < 2; i++) { |
| 61 | 4836202 | const int s = mv[i] >> 17; | |
| 62 | 4836202 | const int f = av_log2((mv[i] ^ s) | 31) - 4; | |
| 63 | 4836202 | const int mask = (-1 * (1 << f)) >> 1; | |
| 64 | 4836202 | const int round = (1 << f) >> 2; | |
| 65 | 4836202 | mv[i] = (mv[i] + round) & mask; | |
| 66 | } | ||
| 67 | 2418101 | motion->x = mv[0]; | |
| 68 | 2418101 | motion->y = mv[1]; | |
| 69 | 2418101 | } | |
| 70 | |||
| 71 | 1998887 | void ff_vvc_mv_scale(Mv *dst, const Mv *src, int td, int tb) | |
| 72 | { | ||
| 73 | int tx, scale_factor; | ||
| 74 | |||
| 75 | 1998887 | td = av_clip_int8(td); | |
| 76 | 1998887 | tb = av_clip_int8(tb); | |
| 77 | 1998887 | tx = (0x4000 + (abs(td) >> 1)) / td; | |
| 78 | 1998887 | scale_factor = av_clip_intp2((tb * tx + 32) >> 6, 12); | |
| 79 | 1998887 | dst->x = av_clip_intp2((scale_factor * src->x + 127 + | |
| 80 | 1998887 | (scale_factor * src->x < 0)) >> 8, 17); | |
| 81 | 1998887 | dst->y = av_clip_intp2((scale_factor * src->y + 127 + | |
| 82 | 1998887 | (scale_factor * src->y < 0)) >> 8, 17); | |
| 83 | 1998887 | } | |
| 84 | |||
| 85 | //part of 8.5.2.12 Derivation process for collocated motion vectors | ||
| 86 | 2430170 | 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 | 2430170 | int cur_lt = refPicList[X].refs[refIdxLx].is_lt; | |
| 92 | 2430170 | 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 2418101 times.
|
2430170 | if (cur_lt != col_lt) { |
| 96 | 12069 | mvLXCol->x = 0; | |
| 97 | 12069 | mvLXCol->y = 0; | |
| 98 | 12069 | return 0; | |
| 99 | } | ||
| 100 | |||
| 101 | 2418101 | col_poc_diff = colPic - refPicList_col[listCol].refs[refidxCol].poc; | |
| 102 | 2418101 | cur_poc_diff = poc - refPicList[X].refs[refIdxLx].poc; | |
| 103 | |||
| 104 | 2418101 | mv_compression(mvCol); | |
| 105 |
4/4✓ Branch 0 taken 2409883 times.
✓ Branch 1 taken 8218 times.
✓ Branch 2 taken 426838 times.
✓ Branch 3 taken 1983045 times.
|
2418101 | 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 | 1983045 | ff_vvc_mv_scale(mvLXCol, mvCol, col_poc_diff, cur_poc_diff); | |
| 110 | } | ||
| 111 | 2418101 | 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 | 602433 | int ff_vvc_no_backward_pred_flag(const VVCLocalContext *lc) | |
| 122 | { | ||
| 123 | 602433 | int check_diffpicount = 0; | |
| 124 | int i, j; | ||
| 125 | 602433 | const RefPicList *rpl = lc->sc->rpl; | |
| 126 | |||
| 127 |
2/2✓ Branch 0 taken 1204866 times.
✓ Branch 1 taken 602433 times.
|
1807299 | for (j = 0; j < 2; j++) { |
| 128 |
2/2✓ Branch 0 taken 1905589 times.
✓ Branch 1 taken 531958 times.
|
2437547 | for (i = 0; i < lc->sc->sh.r->num_ref_idx_active[j]; i++) { |
| 129 |
2/2✓ Branch 0 taken 672908 times.
✓ Branch 1 taken 1232681 times.
|
1905589 | if (rpl[j].refs[i].poc > lc->fc->ps.ph.poc) { |
| 130 | 672908 | check_diffpicount++; | |
| 131 | 672908 | break; | |
| 132 | } | ||
| 133 | } | ||
| 134 | } | ||
| 135 | 602433 | return !check_diffpicount; | |
| 136 | } | ||
| 137 | |||
| 138 | //8.5.2.12 Derivation process for collocated motion vectors | ||
| 139 | 2986291 | 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 | 2986291 | const VVCFrameContext *fc = lc->fc; | |
| 144 | 2986291 | const SliceContext *sc = lc->sc; | |
| 145 | 2986291 | RefPicList* refPicList = sc->rpl; | |
| 146 | |||
| 147 |
2/2✓ Branch 0 taken 2907492 times.
✓ Branch 1 taken 78799 times.
|
2986291 | if (temp_col.pred_flag == PF_INTRA || |
| 148 |
2/2✓ Branch 0 taken 2902992 times.
✓ Branch 1 taken 4500 times.
|
2907492 | temp_col.pred_flag == PF_IBC || |
| 149 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2902992 times.
|
2902992 | temp_col.pred_flag == PF_PLT) |
| 150 | 83299 | return 0; | |
| 151 | |||
| 152 |
2/2✓ Branch 0 taken 2779343 times.
✓ Branch 1 taken 123649 times.
|
2902992 | if (sb_flag){ |
| 153 |
2/2✓ Branch 0 taken 1562044 times.
✓ Branch 1 taken 1217299 times.
|
2779343 | if (X == 0) { |
| 154 |
2/2✓ Branch 0 taken 1372600 times.
✓ Branch 1 taken 189444 times.
|
1562044 | if (temp_col.pred_flag & PF_L0) |
| 155 | 1372600 | return CHECK_MVSET(0); | |
| 156 |
3/4✓ Branch 1 taken 2349 times.
✓ Branch 2 taken 187095 times.
✓ Branch 3 taken 2349 times.
✗ Branch 4 not taken.
|
189444 | 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 867936 times.
✓ Branch 1 taken 349363 times.
|
1217299 | if (temp_col.pred_flag & PF_L1) |
| 160 | 867936 | return CHECK_MVSET(1); | |
| 161 |
3/4✓ Branch 1 taken 63636 times.
✓ Branch 2 taken 285727 times.
✓ Branch 3 taken 63636 times.
✗ Branch 4 not taken.
|
349363 | 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 15716 times.
✓ Branch 1 taken 107933 times.
|
123649 | if (!(temp_col.pred_flag & PF_L0)) |
| 166 | 15716 | return CHECK_MVSET(1); | |
| 167 |
2/2✓ Branch 0 taken 56454 times.
✓ Branch 1 taken 51479 times.
|
107933 | else if (temp_col.pred_flag == PF_L0) |
| 168 | 56454 | return CHECK_MVSET(0); | |
| 169 |
1/2✓ Branch 0 taken 51479 times.
✗ Branch 1 not taken.
|
51479 | else if (temp_col.pred_flag == PF_BI) { |
| 170 |
2/2✓ Branch 1 taken 9703 times.
✓ Branch 2 taken 41776 times.
|
51479 | 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 23186 times.
✓ Branch 1 taken 18590 times.
|
41776 | if (!lc->sc->sh.r->sh_collocated_from_l0_flag) |
| 177 | 23186 | return CHECK_MVSET(0); | |
| 178 | else | ||
| 179 | 18590 | return CHECK_MVSET(1); | |
| 180 | } | ||
| 181 | } | ||
| 182 | } | ||
| 183 | 472822 | 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 | 153160 | 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 | 153160 | const VVCFrameContext *fc = lc->fc; | |
| 206 | 153160 | const VVCSPS *sps = fc->ps.sps; | |
| 207 | 153160 | const VVCPPS *pps = fc->ps.pps; | |
| 208 | 153160 | const CodingUnit *cu = lc->cu; | |
| 209 | 153160 | const int subpic_idx = lc->sc->sh.r->curr_subpic_idx; | |
| 210 | 153160 | int x, y, x_end, y_end, colPic, availableFlagLXCol = 0; | |
| 211 | 153160 | int min_pu_width = fc->ps.pps->min_pu_width; | |
| 212 | 153160 | 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 153094 times.
|
153160 | if (!ref) { |
| 217 | 66 | memset(mvLXCol, 0, sizeof(*mvLXCol)); | |
| 218 | 66 | return 0; | |
| 219 | } | ||
| 220 | |||
| 221 |
3/4✓ Branch 0 taken 153094 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4749 times.
✓ Branch 3 taken 148345 times.
|
153094 | if (!fc->ps.ph.r->ph_temporal_mvp_enabled_flag || (cu->cb_width * cu->cb_height <= 32)) |
| 222 | 4749 | return 0; | |
| 223 | |||
| 224 | 148345 | tab_mvf = ref->tab_dmvr_mvf; | |
| 225 | 148345 | colPic = ref->poc; | |
| 226 | |||
| 227 | //bottom right collocated motion vector | ||
| 228 | 148345 | x = cu->x0 + cu->cb_width; | |
| 229 | 148345 | y = cu->y0 + cu->cb_height; | |
| 230 | |||
| 231 | 148345 | x_end = pps->subpic_x[subpic_idx] + pps->subpic_width[subpic_idx]; | |
| 232 | 148345 | y_end = pps->subpic_y[subpic_idx] + pps->subpic_height[subpic_idx]; | |
| 233 | |||
| 234 |
1/2✓ Branch 0 taken 148345 times.
✗ Branch 1 not taken.
|
148345 | if (tab_mvf && |
| 235 |
4/4✓ Branch 0 taken 125462 times.
✓ Branch 1 taken 22883 times.
✓ Branch 2 taken 123105 times.
✓ Branch 3 taken 2357 times.
|
148345 | (cu->y0 >> sps->ctb_log2_size_y) == (y >> sps->ctb_log2_size_y) && |
| 236 |
2/2✓ Branch 0 taken 119077 times.
✓ Branch 1 taken 4028 times.
|
123105 | x < x_end && y < y_end) { |
| 237 | 119077 | x &= ~7; | |
| 238 | 119077 | y &= ~7; | |
| 239 | 119077 | temp_col = TAB_MVF(x, y); | |
| 240 | 119077 | availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS(sb_flag); | |
| 241 | } | ||
| 242 |
2/2✓ Branch 0 taken 134517 times.
✓ Branch 1 taken 13828 times.
|
148345 | if (check_center) { |
| 243 | // derive center collocated motion vector | ||
| 244 |
3/4✓ Branch 0 taken 134517 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 57670 times.
✓ Branch 3 taken 76847 times.
|
134517 | if (tab_mvf && !availableFlagLXCol) { |
| 245 | 57670 | x = cu->x0 + (cu->cb_width >> 1); | |
| 246 | 57670 | y = cu->y0 + (cu->cb_height >> 1); | |
| 247 | 57670 | x &= ~7; | |
| 248 | 57670 | y &= ~7; | |
| 249 | 57670 | temp_col = TAB_MVF(x, y); | |
| 250 | 57670 | availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS(sb_flag); | |
| 251 | } | ||
| 252 | } | ||
| 253 | 148345 | return availableFlagLXCol; | |
| 254 | } | ||
| 255 | |||
| 256 | 6104430 | 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 | 6104430 | const VVCFrameContext *fc = lc->fc; | |
| 259 | 6104430 | MvField *tab_mvf = fc->tab.mvf; | |
| 260 | 6104430 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
| 261 | 6104430 | const int min_pu_size = 1 << MIN_PU_LOG2; | |
| 262 |
2/2✓ Branch 0 taken 9725229 times.
✓ Branch 1 taken 6104430 times.
|
15829659 | for (int dy = 0; dy < h; dy += min_pu_size) { |
| 263 |
2/2✓ Branch 0 taken 43762617 times.
✓ Branch 1 taken 9725229 times.
|
53487846 | for (int dx = 0; dx < w; dx += min_pu_size) { |
| 264 | 43762617 | const int x = x0 + dx; | |
| 265 | 43762617 | const int y = y0 + dy; | |
| 266 | 43762617 | TAB_MVF(x, y) = *mvf; | |
| 267 | } | ||
| 268 | } | ||
| 269 | 6104430 | } | |
| 270 | |||
| 271 | 696759 | void ff_vvc_set_intra_mvf(const VVCLocalContext *lc, const bool dmvr, const PredFlag pf, const bool ciip_flag) | |
| 272 | { | ||
| 273 | 696759 | const VVCFrameContext *fc = lc->fc; | |
| 274 | 696759 | const CodingUnit *cu = lc->cu; | |
| 275 |
2/2✓ Branch 0 taken 67240 times.
✓ Branch 1 taken 629519 times.
|
696759 | MvField *tab_mvf = dmvr ? fc->ref->tab_dmvr_mvf : fc->tab.mvf; |
| 276 | 696759 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
| 277 | 696759 | const int min_pu_size = 1 << MIN_PU_LOG2; | |
| 278 |
2/2✓ Branch 0 taken 1738331 times.
✓ Branch 1 taken 696759 times.
|
2435090 | for (int dy = 0; dy < cu->cb_height; dy += min_pu_size) { |
| 279 |
2/2✓ Branch 0 taken 7126954 times.
✓ Branch 1 taken 1738331 times.
|
8865285 | for (int dx = 0; dx < cu->cb_width; dx += min_pu_size) { |
| 280 | 7126954 | const int x = cu->x0 + dx; | |
| 281 | 7126954 | const int y = cu->y0 + dy; | |
| 282 | 7126954 | MvField *mv = &TAB_MVF(x, y); | |
| 283 | |||
| 284 | 7126954 | mv->pred_flag = pf; | |
| 285 | 7126954 | mv->ciip_flag = ciip_flag; | |
| 286 | } | ||
| 287 | } | ||
| 288 | 696759 | } | |
| 289 | |||
| 290 | //cbProfFlagLX from 8.5.5.9 Derivation process for motion vector arrays from affine control point motion vectors | ||
| 291 | 46450 | static int derive_cb_prof_flag_lx(const VVCLocalContext *lc, const PredictionUnit* pu, int lx, int is_fallback) | |
| 292 | { | ||
| 293 | 46450 | const MotionInfo* mi = &pu->mi; | |
| 294 | 46450 | const Mv* cp_mv = &mi->mv[lx][0]; | |
| 295 |
4/4✓ Branch 0 taken 46283 times.
✓ Branch 1 taken 167 times.
✓ Branch 2 taken 1104 times.
✓ Branch 3 taken 45179 times.
|
46450 | if (lc->fc->ps.ph.r->ph_prof_disabled_flag || is_fallback) |
| 296 | 1271 | return 0; | |
| 297 |
2/2✓ Branch 0 taken 19032 times.
✓ Branch 1 taken 26147 times.
|
45179 | if (mi->motion_model_idc == MOTION_4_PARAMS_AFFINE) { |
| 298 |
2/2✓ Branch 0 taken 5535 times.
✓ Branch 1 taken 13497 times.
|
19032 | if (IS_SAME_MV(cp_mv, cp_mv + 1)) |
| 299 | 5535 | return 0; | |
| 300 | } | ||
| 301 |
2/2✓ Branch 0 taken 26147 times.
✓ Branch 1 taken 13497 times.
|
39644 | if (mi->motion_model_idc == MOTION_6_PARAMS_AFFINE) { |
| 302 |
4/4✓ Branch 0 taken 4645 times.
✓ Branch 1 taken 21502 times.
✓ Branch 2 taken 1152 times.
✓ Branch 3 taken 3493 times.
|
26147 | 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 38355 times.
|
38492 | if (lc->sc->rpl[lx].refs[mi->ref_idx[lx]].is_scaled) |
| 306 | 137 | return 0; | |
| 307 | 38355 | 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 | 46450 | static int is_fallback_mode(const SubblockParams *sp, const PredFlag pred_flag) | |
| 324 | { | ||
| 325 | 46450 | const int a = 4 * (2048 + sp->d_hor_x); | |
| 326 | 46450 | const int b = 4 * sp->d_hor_y; | |
| 327 | 46450 | const int c = 4 * (2048 + sp->d_ver_y); | |
| 328 | 46450 | const int d = 4 * sp->d_ver_x; | |
| 329 |
2/2✓ Branch 0 taken 20944 times.
✓ Branch 1 taken 25506 times.
|
46450 | if (pred_flag == PF_BI) { |
| 330 |
2/2✓ Branch 0 taken 20833 times.
✓ Branch 1 taken 111 times.
|
20944 | const int max_w4 = FFMAX(0, FFMAX(a, FFMAX(b, a + b))); |
| 331 |
2/2✓ Branch 0 taken 111 times.
✓ Branch 1 taken 20833 times.
|
20944 | const int min_w4 = FFMIN(0, FFMIN(a, FFMIN(b, a + b))); |
| 332 |
2/2✓ Branch 0 taken 20844 times.
✓ Branch 1 taken 100 times.
|
20944 | const int max_h4 = FFMAX(0, FFMAX(c, FFMAX(d, c + d))); |
| 333 |
2/2✓ Branch 0 taken 100 times.
✓ Branch 1 taken 20844 times.
|
20944 | const int min_h4 = FFMIN(0, FFMIN(c, FFMIN(d, c + d))); |
| 334 | 20944 | const int bx_wx4 = ((max_w4 - min_w4) >> 11) + 9; | |
| 335 | 20944 | const int bx_hx4 = ((max_h4 - min_h4) >> 11) + 9; | |
| 336 | 20944 | return bx_wx4 * bx_hx4 > 225; | |
| 337 | } else { | ||
| 338 | 25506 | const int bx_wxh = (FFABS(a) >> 11) + 9; | |
| 339 | 25506 | const int bx_hxh = (FFABS(d) >> 11) + 9; | |
| 340 | 25506 | const int bx_wxv = (FFABS(b) >> 11) + 9; | |
| 341 | 25506 | const int bx_hxv = (FFABS(c) >> 11) + 9; | |
| 342 |
4/4✓ Branch 0 taken 24839 times.
✓ Branch 1 taken 667 times.
✓ Branch 2 taken 24745 times.
✓ Branch 3 taken 94 times.
|
25506 | if (bx_wxh * bx_hxh <= 165 && bx_wxv * bx_hxv <= 165) |
| 343 | 24745 | return 0; | |
| 344 | } | ||
| 345 | 761 | return 1; | |
| 346 | } | ||
| 347 | |||
| 348 | 46450 | static void init_subblock_params(SubblockParams *sp, const MotionInfo* mi, | |
| 349 | const int cb_width, const int cb_height, const int lx) | ||
| 350 | { | ||
| 351 | 46450 | const int log2_cbw = av_log2(cb_width); | |
| 352 | 46450 | const int log2_cbh = av_log2(cb_height); | |
| 353 | 46450 | const Mv* cp_mv = mi->mv[lx]; | |
| 354 | 46450 | const int num_cp_mv = mi->motion_model_idc + 1; | |
| 355 | 46450 | sp->d_hor_x = (cp_mv[1].x - cp_mv[0].x) * (1 << (MAX_CU_DEPTH - log2_cbw)); | |
| 356 | 46450 | sp->d_ver_x = (cp_mv[1].y - cp_mv[0].y) * (1 << (MAX_CU_DEPTH - log2_cbw)); | |
| 357 |
2/2✓ Branch 0 taken 26540 times.
✓ Branch 1 taken 19910 times.
|
46450 | if (num_cp_mv == 3) { |
| 358 | 26540 | sp->d_hor_y = (cp_mv[2].x - cp_mv[0].x) * (1 << (MAX_CU_DEPTH - log2_cbh)); | |
| 359 | 26540 | sp->d_ver_y = (cp_mv[2].y - cp_mv[0].y) * (1 << (MAX_CU_DEPTH - log2_cbh)); | |
| 360 | } else { | ||
| 361 | 19910 | sp->d_hor_y = -sp->d_ver_x; | |
| 362 | 19910 | sp->d_ver_y = sp->d_hor_x; | |
| 363 | } | ||
| 364 | 46450 | sp->mv_scale_hor = (cp_mv[0].x) * (1 << MAX_CU_DEPTH); | |
| 365 | 46450 | sp->mv_scale_ver = (cp_mv[0].y) * (1 << MAX_CU_DEPTH); | |
| 366 | 46450 | sp->cb_width = cb_width; | |
| 367 | 46450 | sp->cb_height = cb_height; | |
| 368 | 46450 | sp->is_fallback = is_fallback_mode(sp, mi->pred_flag); | |
| 369 | 46450 | } | |
| 370 | |||
| 371 | 46450 | static void derive_subblock_diff_mvs(const VVCLocalContext *lc, PredictionUnit* pu, const SubblockParams* sp, const int lx) | |
| 372 | { | ||
| 373 | 46450 | pu->cb_prof_flag[lx] = derive_cb_prof_flag_lx(lc, pu, lx, sp->is_fallback); | |
| 374 |
2/2✓ Branch 0 taken 38355 times.
✓ Branch 1 taken 8095 times.
|
46450 | if (pu->cb_prof_flag[lx]) { |
| 375 | 38355 | const int dmv_limit = 1 << 5; | |
| 376 | 38355 | const int pos_offset_x = 6 * (sp->d_hor_x + sp->d_hor_y); | |
| 377 | 38355 | const int pos_offset_y = 6 * (sp->d_ver_x + sp->d_ver_y); | |
| 378 |
2/2✓ Branch 0 taken 153420 times.
✓ Branch 1 taken 38355 times.
|
191775 | for (int x = 0; x < AFFINE_MIN_BLOCK_SIZE; x++) { |
| 379 |
2/2✓ Branch 0 taken 613680 times.
✓ Branch 1 taken 153420 times.
|
767100 | for (int y = 0; y < AFFINE_MIN_BLOCK_SIZE; y++) { |
| 380 | 613680 | LOCAL_ALIGNED_8(Mv, diff, [1]); | |
| 381 | 613680 | diff->x = x * (sp->d_hor_x * (1 << 2)) + y * (sp->d_hor_y * (1 << 2)) - pos_offset_x; | |
| 382 | 613680 | diff->y = x * (sp->d_ver_x * (1 << 2)) + y * (sp->d_ver_y * (1 << 2)) - pos_offset_y; | |
| 383 | 613680 | ff_vvc_round_mv(diff, 0, 8); | |
| 384 | 613680 | pu->diff_mv_x[lx][AFFINE_MIN_BLOCK_SIZE * y + x] = av_clip(diff->x, -dmv_limit + 1, dmv_limit - 1); | |
| 385 | 613680 | 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 | 46450 | } | |
| 390 | |||
| 391 | 46450 | static void store_cp_mv(const VVCLocalContext *lc, const MotionInfo *mi, const int lx) | |
| 392 | { | ||
| 393 | 46450 | VVCFrameContext *fc = lc->fc; | |
| 394 | 46450 | const CodingUnit *cu = lc->cu; | |
| 395 | 46450 | const int log2_min_cb_size = fc->ps.sps->min_cb_log2_size_y; | |
| 396 | 46450 | const int min_cb_size = fc->ps.sps->min_cb_size_y; | |
| 397 | 46450 | const int min_cb_width = fc->ps.pps->min_cb_width; | |
| 398 | 46450 | const int num_cp_mv = mi->motion_model_idc + 1; | |
| 399 | |||
| 400 |
2/2✓ Branch 0 taken 365186 times.
✓ Branch 1 taken 46450 times.
|
411636 | for (int dy = 0; dy < cu->cb_height; dy += min_cb_size) { |
| 401 |
2/2✓ Branch 0 taken 4582504 times.
✓ Branch 1 taken 365186 times.
|
4947690 | for (int dx = 0; dx < cu->cb_width; dx += min_cb_size) { |
| 402 | 4582504 | const int x_cb = (cu->x0 + dx) >> log2_min_cb_size; | |
| 403 | 4582504 | const int y_cb = (cu->y0 + dy) >> log2_min_cb_size; | |
| 404 | 4582504 | const int offset = (y_cb * min_cb_width + x_cb) * MAX_CONTROL_POINTS; | |
| 405 | |||
| 406 | 4582504 | memcpy(&fc->tab.cp_mv[lx][offset], mi->mv[lx], sizeof(Mv) * num_cp_mv); | |
| 407 | } | ||
| 408 | } | ||
| 409 | 46450 | } | |
| 410 | |||
| 411 | //8.5.5.9 Derivation process for motion vector arrays from affine control point motion vectors | ||
| 412 | 35978 | void ff_vvc_store_sb_mvs(const VVCLocalContext *lc, PredictionUnit *pu) | |
| 413 | { | ||
| 414 | 35978 | const CodingUnit *cu = lc->cu; | |
| 415 | 35978 | const MotionInfo *mi = &pu->mi; | |
| 416 | 35978 | const int sbw = cu->cb_width / mi->num_sb_x; | |
| 417 | 35978 | const int sbh = cu->cb_height / mi->num_sb_y; | |
| 418 | SubblockParams params[2]; | ||
| 419 | 35978 | MvField mvf = {0}; | |
| 420 | |||
| 421 | 35978 | mvf.pred_flag = mi->pred_flag; | |
| 422 | 35978 | mvf.bcw_idx = mi->bcw_idx; | |
| 423 | 35978 | mvf.hpel_if_idx = mi->hpel_if_idx; | |
| 424 |
2/2✓ Branch 0 taken 71956 times.
✓ Branch 1 taken 35978 times.
|
107934 | for (int i = 0; i < 2; i++) { |
| 425 | 71956 | const PredFlag mask = i + 1; | |
| 426 |
2/2✓ Branch 0 taken 46450 times.
✓ Branch 1 taken 25506 times.
|
71956 | if (mi->pred_flag & mask) { |
| 427 | 46450 | store_cp_mv(lc, mi, i); | |
| 428 | 46450 | init_subblock_params(params + i, mi, cu->cb_width, cu->cb_height, i); | |
| 429 | 46450 | derive_subblock_diff_mvs(lc, pu, params + i, i); | |
| 430 | 46450 | mvf.ref_idx[i] = mi->ref_idx[i]; | |
| 431 | } | ||
| 432 | } | ||
| 433 | |||
| 434 |
2/2✓ Branch 0 taken 284286 times.
✓ Branch 1 taken 35978 times.
|
320264 | for (int sby = 0; sby < mi->num_sb_y; sby++) { |
| 435 |
2/2✓ Branch 0 taken 3529300 times.
✓ Branch 1 taken 284286 times.
|
3813586 | for (int sbx = 0; sbx < mi->num_sb_x; sbx++) { |
| 436 | 3529300 | const int x0 = cu->x0 + sbx * sbw; | |
| 437 | 3529300 | const int y0 = cu->y0 + sby * sbh; | |
| 438 |
2/2✓ Branch 0 taken 7058600 times.
✓ Branch 1 taken 3529300 times.
|
10587900 | for (int i = 0; i < 2; i++) { |
| 439 | 7058600 | const PredFlag mask = i + 1; | |
| 440 |
2/2✓ Branch 0 taken 4582504 times.
✓ Branch 1 taken 2476096 times.
|
7058600 | if (mi->pred_flag & mask) { |
| 441 | 4582504 | const SubblockParams* sp = params + i; | |
| 442 |
2/2✓ Branch 0 taken 141736 times.
✓ Branch 1 taken 4440768 times.
|
4582504 | 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 4440768 times.
|
4582504 | const int y_pos_cb = sp->is_fallback ? (cu->cb_height >> 1) : (2 + (sby << MIN_CU_LOG2)); |
| 444 | 4582504 | Mv *mv = mvf.mv + i; | |
| 445 | |||
| 446 | 4582504 | mv->x = sp->mv_scale_hor + sp->d_hor_x * x_pos_cb + sp->d_hor_y * y_pos_cb; | |
| 447 | 4582504 | mv->y = sp->mv_scale_ver + sp->d_ver_x * x_pos_cb + sp->d_ver_y * y_pos_cb; | |
| 448 | 4582504 | ff_vvc_round_mv(mv, 0, MAX_CU_DEPTH); | |
| 449 | 4582504 | ff_vvc_clip_mv(mv); | |
| 450 | } | ||
| 451 | } | ||
| 452 | 3529300 | ff_vvc_set_mvf(lc, x0, y0, sbw, sbh, &mvf); | |
| 453 | } | ||
| 454 | } | ||
| 455 | 35978 | } | |
| 456 | |||
| 457 | 27594 | void ff_vvc_store_gpm_mvf(const VVCLocalContext *lc, const PredictionUnit *pu) | |
| 458 | { | ||
| 459 | 27594 | const CodingUnit *cu = lc->cu; | |
| 460 | 27594 | const int angle_idx = ff_vvc_gpm_angle_idx[pu->gpm_partition_idx]; | |
| 461 | 27594 | const int distance_idx = ff_vvc_gpm_distance_idx[pu->gpm_partition_idx]; | |
| 462 | 27594 | const int displacement_x = ff_vvc_gpm_distance_lut[angle_idx]; | |
| 463 | 27594 | const int displacement_y = ff_vvc_gpm_distance_lut[(angle_idx + 8) % 32]; | |
| 464 |
4/4✓ Branch 0 taken 14495 times.
✓ Branch 1 taken 13099 times.
✓ Branch 2 taken 11694 times.
✓ Branch 3 taken 2801 times.
|
27594 | const int is_flip = angle_idx >= 13 &&angle_idx <= 27; |
| 465 |
6/6✓ Branch 0 taken 25444 times.
✓ Branch 1 taken 2150 times.
✓ Branch 2 taken 22421 times.
✓ Branch 3 taken 3023 times.
✓ Branch 4 taken 5659 times.
✓ Branch 5 taken 16762 times.
|
27594 | 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 16164 times.
✓ Branch 1 taken 11430 times.
|
27594 | const int sign = angle_idx < 16 ? 1 : -1; |
| 467 | 27594 | const int block_size = 4; | |
| 468 | 27594 | int offset_x = (-cu->cb_width) >> 1; | |
| 469 | 27594 | int offset_y = (-cu->cb_height) >> 1; | |
| 470 | |||
| 471 |
2/2✓ Branch 0 taken 18912 times.
✓ Branch 1 taken 8682 times.
|
27594 | if (!shift_hor) |
| 472 | 18912 | offset_y += sign * ((distance_idx * cu->cb_height) >> 3); | |
| 473 | else | ||
| 474 | 8682 | offset_x += sign * ((distance_idx * cu->cb_width) >> 3); | |
| 475 | |||
| 476 |
2/2✓ Branch 0 taken 124790 times.
✓ Branch 1 taken 27594 times.
|
152384 | for (int y = 0; y < cu->cb_height; y += block_size) { |
| 477 |
2/2✓ Branch 0 taken 616124 times.
✓ Branch 1 taken 124790 times.
|
740914 | for (int x = 0; x < cu->cb_width; x += block_size) { |
| 478 | 616124 | const int motion_idx = (((x + offset_x) * (1 << 1)) + 5) * displacement_x + | |
| 479 | 616124 | (((y + offset_y) * (1 << 1)) + 5) * displacement_y; | |
| 480 |
6/6✓ Branch 0 taken 305244 times.
✓ Branch 1 taken 310880 times.
✓ Branch 2 taken 188428 times.
✓ Branch 3 taken 116816 times.
✓ Branch 4 taken 310880 times.
✓ Branch 5 taken 188428 times.
|
616124 | const int s_type = FFABS(motion_idx) < 32 ? 2 : (motion_idx <= 0 ? (1 - is_flip) : is_flip); |
| 481 | 616124 | const int pred_flag = pu->gpm_mv[0].pred_flag | pu->gpm_mv[1].pred_flag; | |
| 482 | 616124 | const int x0 = cu->x0 + x; | |
| 483 | 616124 | const int y0 = cu->y0 + y; | |
| 484 | |||
| 485 |
2/2✓ Branch 0 taken 244245 times.
✓ Branch 1 taken 371879 times.
|
616124 | if (!s_type) |
| 486 | 244245 | ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, pu->gpm_mv + 0); | |
| 487 |
5/6✓ Branch 0 taken 116816 times.
✓ Branch 1 taken 255063 times.
✓ Branch 2 taken 116816 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 61483 times.
✓ Branch 5 taken 55333 times.
|
371879 | else if (s_type == 1 || (s_type == 2 && pred_flag != PF_BI)) |
| 488 | 316546 | ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, pu->gpm_mv + 1); | |
| 489 | else { | ||
| 490 | 55333 | MvField mvf = pu->gpm_mv[0]; | |
| 491 | 55333 | const MvField *mv1 = &pu->gpm_mv[1]; | |
| 492 | 55333 | const int lx = mv1->pred_flag - PF_L0; | |
| 493 | 55333 | mvf.pred_flag = PF_BI; | |
| 494 | 55333 | mvf.ref_idx[lx] = mv1->ref_idx[lx]; | |
| 495 | 55333 | mvf.mv[lx] = mv1->mv[lx]; | |
| 496 | 55333 | ff_vvc_set_mvf(lc, x0, y0, block_size, block_size, &mvf); | |
| 497 | } | ||
| 498 | } | ||
| 499 | } | ||
| 500 | 27594 | } | |
| 501 | |||
| 502 | 297591 | void ff_vvc_store_mvf(const VVCLocalContext *lc, const MvField *mvf) | |
| 503 | { | ||
| 504 | 297591 | const CodingUnit *cu = lc->cu; | |
| 505 | 297591 | ff_vvc_set_mvf(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height, mvf); | |
| 506 | 297591 | } | |
| 507 | |||
| 508 | 137701 | void ff_vvc_store_mv(const VVCLocalContext *lc, const MotionInfo *mi) | |
| 509 | { | ||
| 510 | 137701 | const CodingUnit *cu = lc->cu; | |
| 511 | 137701 | MvField mvf = {0}; | |
| 512 | |||
| 513 | 137701 | mvf.hpel_if_idx = mi->hpel_if_idx; | |
| 514 | 137701 | mvf.bcw_idx = mi->bcw_idx; | |
| 515 | 137701 | mvf.pred_flag = mi->pred_flag; | |
| 516 | |||
| 517 |
2/2✓ Branch 0 taken 275402 times.
✓ Branch 1 taken 137701 times.
|
413103 | for (int i = 0; i < 2; i++) { |
| 518 | 275402 | const PredFlag mask = i + 1; | |
| 519 |
2/2✓ Branch 0 taken 157114 times.
✓ Branch 1 taken 118288 times.
|
275402 | if (mvf.pred_flag & mask) { |
| 520 | 157114 | mvf.mv[i] = mi->mv[i][0]; | |
| 521 | 157114 | mvf.ref_idx[i] = mi->ref_idx[i]; | |
| 522 | } | ||
| 523 | } | ||
| 524 | 137701 | ff_vvc_set_mvf(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height, &mvf); | |
| 525 | 137701 | } | |
| 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 | 1477261 | static int is_available(const VVCFrameContext *fc, const int x0, const int y0) | |
| 553 | { | ||
| 554 | 1477261 | const VVCSPS *sps = fc->ps.sps; | |
| 555 | 1477261 | const int x = x0 >> sps->min_cb_log2_size_y; | |
| 556 | 1477261 | const int y = y0 >> sps->min_cb_log2_size_y; | |
| 557 | 1477261 | const int min_cb_width = fc->ps.pps->min_cb_width; | |
| 558 | |||
| 559 | 1477261 | return SAMPLE_CTB(fc->tab.cb_width[0], x, y) != 0; | |
| 560 | } | ||
| 561 | |||
| 562 | 528082 | static int is_a0_available(const VVCLocalContext *lc, const CodingUnit *cu) | |
| 563 | { | ||
| 564 | 528082 | const VVCFrameContext *fc = lc->fc; | |
| 565 | 528082 | const VVCSPS *sps = fc->ps.sps; | |
| 566 | 528082 | 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 114787 times.
✓ Branch 1 taken 413295 times.
✓ Branch 2 taken 15977 times.
✓ Branch 3 taken 98810 times.
|
528082 | if (!x0b && !lc->ctb_left_flag) { |
| 570 | 15977 | cand_bottom_left = 0; | |
| 571 | } else { | ||
| 572 | 512105 | 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 104641 times.
✓ Branch 1 taken 407464 times.
|
512105 | if (cu->y0 + cu->cb_height >= max_y) |
| 574 | 104641 | cand_bottom_left = 0; | |
| 575 | else | ||
| 576 | 407464 | cand_bottom_left = is_available(fc, cu->x0 - 1, cu->y0 + cu->cb_height); | |
| 577 | } | ||
| 578 | 528082 | return cand_bottom_left; | |
| 579 | } | ||
| 580 | |||
| 581 | 528082 | static void init_neighbour_context(NeighbourContext *ctx, const VVCLocalContext *lc) | |
| 582 | { | ||
| 583 | 528082 | const CodingUnit *cu = lc->cu; | |
| 584 | 528082 | const NeighbourAvailable *na = &lc->na; | |
| 585 | 528082 | const int x0 = cu->x0; | |
| 586 | 528082 | const int y0 = cu->y0; | |
| 587 | 528082 | const int cb_width = cu->cb_width; | |
| 588 | 528082 | const int cb_height = cu->cb_height; | |
| 589 | 528082 | const int a0_available = is_a0_available(lc, cu); | |
| 590 | |||
| 591 | 528082 | Neighbour neighbours[NUM_NBS] = { | |
| 592 | 528082 | { x0 - 1, y0 + cb_height, !a0_available }, //A0 | |
| 593 | 528082 | { x0 - 1, y0 + cb_height - 1, !na->cand_left }, //A1 | |
| 594 | 528082 | { x0 - 1, y0, !na->cand_left }, //A2 | |
| 595 | 528082 | { x0 + cb_width, y0 - 1, !na->cand_up_right }, //B0 | |
| 596 | 528082 | { x0 + cb_width - 1, y0 - 1, !na->cand_up }, //B1 | |
| 597 | 528082 | { x0 - 1, y0 - 1, !na->cand_up_left }, //B2 | |
| 598 | 528082 | { x0, y0 - 1, !na->cand_up }, //B3 | |
| 599 | }; | ||
| 600 | |||
| 601 | 528082 | memcpy(ctx->neighbours, neighbours, sizeof(neighbours)); | |
| 602 | 528082 | ctx->lc = lc; | |
| 603 | 528082 | } | |
| 604 | |||
| 605 | 1019665 | 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 | 1019665 | return lut[pred]; | |
| 620 | } | ||
| 621 | |||
| 622 | 1370258 | static int check_available(Neighbour *n, const VVCLocalContext *lc, const int check_mer) | |
| 623 | { | ||
| 624 | 1370258 | const VVCFrameContext *fc = lc->fc; | |
| 625 | 1370258 | const VVCSPS *sps = fc->ps.sps; | |
| 626 | 1370258 | const CodingUnit *cu = lc->cu; | |
| 627 | 1370258 | const MvField *tab_mvf = fc->tab.mvf; | |
| 628 | 1370258 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
| 629 | |||
| 630 |
2/2✓ Branch 0 taken 1069997 times.
✓ Branch 1 taken 300261 times.
|
1370258 | if (!n->checked) { |
| 631 | 1069997 | n->checked = 1; | |
| 632 |
4/4✓ Branch 0 taken 87906 times.
✓ Branch 1 taken 982091 times.
✓ Branch 2 taken 87706 times.
✓ Branch 3 taken 200 times.
|
1069997 | 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 1069797 times.
✓ Branch 1 taken 200 times.
✓ Branch 3 taken 1019665 times.
✓ Branch 4 taken 50132 times.
✓ Branch 6 taken 904083 times.
✓ Branch 7 taken 115582 times.
|
1069997 | 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 748629 times.
✓ Branch 1 taken 321368 times.
|
1069997 | if (check_mer) |
| 635 |
4/4✓ Branch 0 taken 674439 times.
✓ Branch 1 taken 74190 times.
✓ Branch 3 taken 668247 times.
✓ Branch 4 taken 6192 times.
|
748629 | n->available = n->available && !is_same_mer(fc, n->x, n->y, cu->x0, cu->y0); |
| 636 | } | ||
| 637 | 1370258 | return n->available; | |
| 638 | } | ||
| 639 | |||
| 640 | 564857 | static const MvField *mv_merge_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand) | |
| 641 | { | ||
| 642 | 564857 | const VVCFrameContext *fc = lc->fc; | |
| 643 | 564857 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
| 644 | 564857 | const MvField* tab_mvf = fc->tab.mvf; | |
| 645 | 564857 | const MvField *mvf = &TAB_MVF(x_cand, y_cand); | |
| 646 | |||
| 647 | 564857 | return mvf; | |
| 648 | } | ||
| 649 | |||
| 650 | 716610 | static const MvField* mv_merge_from_nb(NeighbourContext *ctx, const NeighbourIdx nb) | |
| 651 | { | ||
| 652 | 716610 | const VVCLocalContext *lc = ctx->lc; | |
| 653 | 716610 | Neighbour *n = &ctx->neighbours[nb]; | |
| 654 | |||
| 655 |
2/2✓ Branch 1 taken 564857 times.
✓ Branch 2 taken 151753 times.
|
716610 | if (check_available(n, lc, 1)) |
| 656 | 564857 | return mv_merge_candidate(lc, n->x, n->y); | |
| 657 | 151753 | 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 | 325185 | 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 | 325185 | 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 | 325185 | init_neighbour_context(&nctx, lc); | |
| 677 |
2/2✓ Branch 0 taken 648943 times.
✓ Branch 1 taken 68354 times.
|
717297 | for (int i = 0; i < FF_ARRAY_ELEMS(nbs); i++) { |
| 678 | 648943 | NeighbourIdx nb = nbs[i][0]; | |
| 679 | 648943 | NeighbourIdx old = nbs[i][1]; | |
| 680 | 648943 | cand = nb_list[nb] = MV_MERGE_FROM_NB(nb); | |
| 681 |
4/4✓ Branch 0 taken 511652 times.
✓ Branch 1 taken 137291 times.
✓ Branch 3 taken 463096 times.
✓ Branch 4 taken 48556 times.
|
648943 | if (cand && !compare_mv_ref_idx(cand, nb_list[old])) { |
| 682 | 463096 | cand_list[num_cands] = *cand; | |
| 683 |
2/2✓ Branch 0 taken 256831 times.
✓ Branch 1 taken 206265 times.
|
463096 | if (merge_idx == num_cands) |
| 684 | 256831 | return 1; | |
| 685 | 206265 | num_cands++; | |
| 686 | } | ||
| 687 | } | ||
| 688 |
2/2✓ Branch 0 taken 67667 times.
✓ Branch 1 taken 687 times.
|
68354 | if (num_cands != 4) { |
| 689 | 67667 | cand = MV_MERGE_FROM_NB(B2); | |
| 690 |
4/4✓ Branch 0 taken 53205 times.
✓ Branch 1 taken 14462 times.
✓ Branch 3 taken 32222 times.
✓ Branch 4 taken 20983 times.
|
67667 | if (cand && !compare_mv_ref_idx(cand, nb_list[A1]) |
| 691 |
2/2✓ Branch 1 taken 22675 times.
✓ Branch 2 taken 9547 times.
|
32222 | && !compare_mv_ref_idx(cand, nb_list[B1])) { |
| 692 | 22675 | cand_list[num_cands] = *cand; | |
| 693 |
2/2✓ Branch 0 taken 10166 times.
✓ Branch 1 taken 12509 times.
|
22675 | if (merge_idx == num_cands) |
| 694 | 10166 | return 1; | |
| 695 | 12509 | num_cands++; | |
| 696 | } | ||
| 697 | } | ||
| 698 | 58188 | *nb_merge_cand = num_cands; | |
| 699 | 58188 | return 0; | |
| 700 | } | ||
| 701 | |||
| 702 | 58188 | static int mv_merge_temporal_candidate(const VVCLocalContext *lc, MvField *cand) | |
| 703 | { | ||
| 704 | 58188 | const VVCFrameContext *fc = lc->fc; | |
| 705 | 58188 | const CodingUnit *cu = lc->cu; | |
| 706 | |||
| 707 | 58188 | memset(cand, 0, sizeof(*cand)); | |
| 708 |
4/4✓ Branch 0 taken 58041 times.
✓ Branch 1 taken 147 times.
✓ Branch 2 taken 54242 times.
✓ Branch 3 taken 3799 times.
|
58188 | if (fc->ps.ph.r->ph_temporal_mvp_enabled_flag && (cu->cb_width * cu->cb_height > 32)) { |
| 709 | 54242 | int available_l0 = temporal_luma_motion_vector(lc, 0, cand->mv + 0, 0, 1, 0); | |
| 710 | 108484 | int available_l1 = IS_B(lc->sc->sh.r) ? | |
| 711 |
2/2✓ Branch 0 taken 51453 times.
✓ Branch 1 taken 2789 times.
|
54242 | temporal_luma_motion_vector(lc, 0, cand->mv + 1, 1, 1, 0) : 0; |
| 712 | 54242 | cand->pred_flag = available_l0 + (available_l1 << 1); | |
| 713 | } | ||
| 714 | 58188 | return cand->pred_flag; | |
| 715 | } | ||
| 716 | |||
| 717 | //8.5.2.6 Derivation process for history-based merging candidates | ||
| 718 | 37081 | 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 | 37081 | const VVCSPS *sps = lc->fc->ps.sps; | |
| 722 | 37081 | const EntryPoint* ep = lc->ep; | |
| 723 |
4/4✓ Branch 0 taken 94934 times.
✓ Branch 1 taken 2784 times.
✓ Branch 2 taken 86119 times.
✓ Branch 3 taken 8815 times.
|
97718 | for (int i = 1; i <= ep->num_hmvp && (*num_cands < sps->max_num_merge_cand - 1); i++) { |
| 724 | 86119 | const MvField *h = &ep->hmvp[ep->num_hmvp - i]; | |
| 725 |
6/6✓ Branch 0 taken 63289 times.
✓ Branch 1 taken 22830 times.
✓ Branch 3 taken 43610 times.
✓ Branch 4 taken 19679 times.
✓ Branch 6 taken 10826 times.
✓ Branch 7 taken 32784 times.
|
86119 | 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 55614 times.
✓ Branch 1 taken 30505 times.
|
86119 | if (!same_motion) { |
| 727 | 55614 | cand_list[*num_cands] = *h; | |
| 728 |
2/2✓ Branch 0 taken 25482 times.
✓ Branch 1 taken 30132 times.
|
55614 | if (merge_idx == *num_cands) |
| 729 | 25482 | return 1; | |
| 730 | 30132 | (*num_cands)++; | |
| 731 | } | ||
| 732 | } | ||
| 733 | 11599 | return 0; | |
| 734 | } | ||
| 735 | |||
| 736 | //8.5.2.4 Derivation process for pairwise average merging candidate | ||
| 737 | 11599 | static int mv_merge_pairwise_candidate(MvField *cand_list, const int num_cands, const int is_b) | |
| 738 | { | ||
| 739 |
2/2✓ Branch 0 taken 10791 times.
✓ Branch 1 taken 808 times.
|
11599 | if (num_cands > 1) { |
| 740 |
2/2✓ Branch 0 taken 10267 times.
✓ Branch 1 taken 524 times.
|
10791 | const int num_ref_rists = is_b ? 2 : 1; |
| 741 | 10791 | const MvField* p0 = cand_list + 0; | |
| 742 | 10791 | const MvField* p1 = cand_list + 1; | |
| 743 | 10791 | MvField* cand = cand_list + num_cands; | |
| 744 | |||
| 745 | 10791 | cand->pred_flag = 0; | |
| 746 |
2/2✓ Branch 0 taken 21058 times.
✓ Branch 1 taken 10791 times.
|
31849 | for (int i = 0; i < num_ref_rists; i++) { |
| 747 | 21058 | PredFlag mask = i + 1; | |
| 748 |
2/2✓ Branch 0 taken 17264 times.
✓ Branch 1 taken 3794 times.
|
21058 | if (p0->pred_flag & mask) { |
| 749 | 17264 | cand->pred_flag |= mask; | |
| 750 | 17264 | cand->ref_idx[i] = p0->ref_idx[i]; | |
| 751 |
2/2✓ Branch 0 taken 15297 times.
✓ Branch 1 taken 1967 times.
|
17264 | if (p1->pred_flag & mask) { |
| 752 | 15297 | Mv *mv = cand->mv + i; | |
| 753 | 15297 | mv->x = p0->mv[i].x + p1->mv[i].x; | |
| 754 | 15297 | mv->y = p0->mv[i].y + p1->mv[i].y; | |
| 755 | 15297 | ff_vvc_round_mv(mv, 0, 1); | |
| 756 | } else { | ||
| 757 | 1967 | cand->mv[i] = p0->mv[i]; | |
| 758 | } | ||
| 759 |
2/2✓ Branch 0 taken 2255 times.
✓ Branch 1 taken 1539 times.
|
3794 | } else if (p1->pred_flag & mask) { |
| 760 | 2255 | cand->pred_flag |= mask; | |
| 761 | 2255 | cand->mv[i] = p1->mv[i]; | |
| 762 | 2255 | cand->ref_idx[i] = p1->ref_idx[i]; | |
| 763 | } | ||
| 764 | } | ||
| 765 |
1/2✓ Branch 0 taken 10791 times.
✗ Branch 1 not taken.
|
10791 | if (cand->pred_flag) { |
| 766 |
2/2✓ Branch 0 taken 10021 times.
✓ Branch 1 taken 770 times.
|
10791 | cand->hpel_if_idx = p0->hpel_if_idx == p1->hpel_if_idx ? p0->hpel_if_idx : 0; |
| 767 | 10791 | cand->bcw_idx = 0; | |
| 768 | 10791 | cand->ciip_flag = 0; | |
| 769 | 10791 | return 1; | |
| 770 | } | ||
| 771 | } | ||
| 772 | 808 | return 0; | |
| 773 | } | ||
| 774 | |||
| 775 | //8.5.2.5 Derivation process for zero motion vector merging candidates | ||
| 776 | 1384 | static void mv_merge_zero_motion_candidate(const VVCLocalContext *lc, const int merge_idx, | |
| 777 | MvField *cand_list, int num_cands) | ||
| 778 | { | ||
| 779 | 1384 | const VVCSPS *sps = lc->fc->ps.sps; | |
| 780 | 1384 | const H266RawSliceHeader *rsh = lc->sc->sh.r; | |
| 781 | 2768 | const int num_ref_idx = IS_P(rsh) ? | |
| 782 |
2/2✓ Branch 0 taken 210 times.
✓ Branch 1 taken 1174 times.
|
1384 | rsh->num_ref_idx_active[L0] : FFMIN(rsh->num_ref_idx_active[L0], rsh->num_ref_idx_active[L1]); |
| 783 | 1384 | int zero_idx = 0; | |
| 784 | |||
| 785 |
1/2✓ Branch 0 taken 2775 times.
✗ Branch 1 not taken.
|
2775 | while (num_cands < sps->max_num_merge_cand) { |
| 786 | 2775 | MvField *cand = cand_list + num_cands; | |
| 787 | |||
| 788 |
2/2✓ Branch 0 taken 2338 times.
✓ Branch 1 taken 437 times.
|
2775 | cand->pred_flag = PF_L0 + (IS_B(rsh) << 1); |
| 789 | 2775 | AV_ZERO64(cand->mv + 0); | |
| 790 | 2775 | AV_ZERO64(cand->mv + 1); | |
| 791 |
2/2✓ Branch 0 taken 2542 times.
✓ Branch 1 taken 233 times.
|
2775 | cand->ref_idx[0] = zero_idx < num_ref_idx ? zero_idx : 0; |
| 792 |
2/2✓ Branch 0 taken 2542 times.
✓ Branch 1 taken 233 times.
|
2775 | cand->ref_idx[1] = zero_idx < num_ref_idx ? zero_idx : 0; |
| 793 | 2775 | cand->bcw_idx = 0; | |
| 794 | 2775 | cand->hpel_if_idx = 0; | |
| 795 |
2/2✓ Branch 0 taken 1384 times.
✓ Branch 1 taken 1391 times.
|
2775 | if (merge_idx == num_cands) |
| 796 | 1384 | return; | |
| 797 | 1391 | num_cands++; | |
| 798 | 1391 | zero_idx++; | |
| 799 | } | ||
| 800 | } | ||
| 801 | |||
| 802 | 325185 | static void mv_merge_mode(const VVCLocalContext *lc, const int merge_idx, MvField *cand_list) | |
| 803 | { | ||
| 804 | 325185 | int num_cands = 0; | |
| 805 | 325185 | const MvField *nb_list[NUM_NBS + 1] = { NULL }; | |
| 806 | |||
| 807 |
2/2✓ Branch 1 taken 266997 times.
✓ Branch 2 taken 58188 times.
|
325185 | if (mv_merge_spatial_candidates(lc, merge_idx, nb_list, cand_list, &num_cands)) |
| 808 | 323801 | return; | |
| 809 | |||
| 810 |
2/2✓ Branch 1 taken 44212 times.
✓ Branch 2 taken 13976 times.
|
58188 | if (mv_merge_temporal_candidate(lc, &cand_list[num_cands])) { |
| 811 |
2/2✓ Branch 0 taken 21107 times.
✓ Branch 1 taken 23105 times.
|
44212 | if (merge_idx == num_cands) |
| 812 | 21107 | return; | |
| 813 | 23105 | num_cands++; | |
| 814 | } | ||
| 815 | |||
| 816 |
2/2✓ Branch 1 taken 25482 times.
✓ Branch 2 taken 11599 times.
|
37081 | if (mv_merge_history_candidates(lc, merge_idx, nb_list, cand_list, &num_cands)) |
| 817 | 25482 | return; | |
| 818 | |||
| 819 |
2/2✓ Branch 1 taken 10791 times.
✓ Branch 2 taken 808 times.
|
11599 | if (mv_merge_pairwise_candidate(cand_list, num_cands, IS_B(lc->sc->sh.r))) { |
| 820 |
2/2✓ Branch 0 taken 10215 times.
✓ Branch 1 taken 576 times.
|
10791 | if (merge_idx == num_cands) |
| 821 | 10215 | return; | |
| 822 | 576 | num_cands++; | |
| 823 | } | ||
| 824 | |||
| 825 | 1384 | 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 | 297591 | void ff_vvc_luma_mv_merge_mode(VVCLocalContext *lc, const int merge_idx, const int ciip_flag, MvField *mv) | |
| 830 | { | ||
| 831 | 297591 | const CodingUnit *cu = lc->cu; | |
| 832 | MvField cand_list[MRG_MAX_NUM_CANDS]; | ||
| 833 | |||
| 834 | 297591 | ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height); | |
| 835 | 297591 | mv_merge_mode(lc, merge_idx, cand_list); | |
| 836 | 297591 | *mv = cand_list[merge_idx]; | |
| 837 | //ciip flag in not inhritable | ||
| 838 | 297591 | mv->ciip_flag = ciip_flag; | |
| 839 | 297591 | } | |
| 840 | |||
| 841 | //8.5.4.2 Derivation process for luma motion vectors for geometric partitioning merge mode | ||
| 842 | 27594 | void ff_vvc_luma_mv_merge_gpm(VVCLocalContext *lc, const int merge_gpm_idx[2], MvField *mv) | |
| 843 | { | ||
| 844 | 27594 | const CodingUnit *cu = lc->cu; | |
| 845 | MvField cand_list[MRG_MAX_NUM_CANDS]; | ||
| 846 | |||
| 847 | 27594 | const int idx[] = { merge_gpm_idx[0], merge_gpm_idx[1] + (merge_gpm_idx[1] >= merge_gpm_idx[0]) }; | |
| 848 | |||
| 849 | 27594 | ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height); | |
| 850 | 27594 | mv_merge_mode(lc, FFMAX(idx[0], idx[1]), cand_list); | |
| 851 | 27594 | memset(mv, 0, 2 * sizeof(*mv)); | |
| 852 |
2/2✓ Branch 0 taken 55188 times.
✓ Branch 1 taken 27594 times.
|
82782 | for (int i = 0; i < 2; i++) { |
| 853 | 55188 | int lx = idx[i] & 1; | |
| 854 | 55188 | int mask = lx + PF_L0; | |
| 855 | 55188 | MvField *cand = cand_list + idx[i]; | |
| 856 |
2/2✓ Branch 0 taken 15186 times.
✓ Branch 1 taken 40002 times.
|
55188 | if (!(cand->pred_flag & mask)) { |
| 857 | 15186 | lx = !lx; | |
| 858 | 15186 | mask = lx + PF_L0; | |
| 859 | } | ||
| 860 | 55188 | mv[i].pred_flag = mask; | |
| 861 | 55188 | mv[i].ref_idx[lx] = cand->ref_idx[lx]; | |
| 862 | 55188 | mv[i].mv[lx] = cand->mv[lx]; | |
| 863 | } | ||
| 864 | |||
| 865 | 27594 | } | |
| 866 | |||
| 867 | //8.5.5.5 Derivation process for luma affine control point motion vectors from a neighbouring block | ||
| 868 | 30538 | 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 | 30538 | const VVCFrameContext *fc = lc->fc; | |
| 873 | 30538 | const CodingUnit *cu = lc->cu; | |
| 874 | 30538 | const int x0 = cu->x0; | |
| 875 | 30538 | const int y0 = cu->y0; | |
| 876 | 30538 | const int cb_width = cu->cb_width; | |
| 877 | 30538 | const int cb_height = cu->cb_height; | |
| 878 | 30538 | const MvField* tab_mvf = fc->tab.mvf; | |
| 879 | 30538 | const int min_cb_log2_size = fc->ps.sps->min_cb_log2_size_y; | |
| 880 | 30538 | const int min_cb_width = fc->ps.pps->min_cb_width; | |
| 881 | |||
| 882 | 30538 | const int log2_nbw = ff_log2(nbw); | |
| 883 | 30538 | const int log2_nbh = ff_log2(nbh); | |
| 884 |
4/4✓ Branch 0 taken 9071 times.
✓ Branch 1 taken 21467 times.
✓ Branch 2 taken 3464 times.
✓ Branch 3 taken 5607 times.
|
30538 | 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 27074 times.
|
30538 | 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 | 27074 | const int x = x_nb >> min_cb_log2_size; | |
| 893 | 27074 | const int y = y_nb >> min_cb_log2_size; | |
| 894 | 27074 | motion_model_idc_nb = SAMPLE_CTB(fc->tab.mmi, x, y); | |
| 895 | |||
| 896 | 27074 | l = &TAB_CP_MV(lx, x_nb, y_nb); | |
| 897 | 27074 | r = &TAB_CP_MV(lx, x_nb + nbw - 1, y_nb) + 1; | |
| 898 | } | ||
| 899 | 30538 | mv_scale_hor = l->x * (1 << 7); | |
| 900 | 30538 | mv_scale_ver = l->y * (1 << 7); | |
| 901 | 30538 | d_hor_x = (r->x - l->x) * (1 << (7 - log2_nbw)); | |
| 902 | 30538 | d_ver_x = (r->y - l->y) * (1 << (7 - log2_nbw)); | |
| 903 |
4/4✓ Branch 0 taken 27074 times.
✓ Branch 1 taken 3464 times.
✓ Branch 2 taken 15180 times.
✓ Branch 3 taken 11894 times.
|
30538 | if (!is_ctb_boundary && motion_model_idc_nb == MOTION_6_PARAMS_AFFINE) { |
| 904 | 15180 | const Mv* lb = &TAB_CP_MV(lx, x_nb, y_nb + nbh - 1) + 2; | |
| 905 | 15180 | d_hor_y = (lb->x - l->x) * (1 << (7 - log2_nbh)); | |
| 906 | 15180 | d_ver_y = (lb->y - l->y) * (1 << (7 - log2_nbh)); | |
| 907 | } else { | ||
| 908 | 15358 | d_hor_y = -d_ver_x; | |
| 909 | 15358 | d_ver_y = d_hor_x; | |
| 910 | } | ||
| 911 | |||
| 912 |
2/2✓ Branch 0 taken 3464 times.
✓ Branch 1 taken 27074 times.
|
30538 | if (is_ctb_boundary) { |
| 913 | 3464 | y_nb = y0; | |
| 914 | } | ||
| 915 | 30538 | cps[0].x = mv_scale_hor + d_hor_x * (x0 - x_nb) + d_hor_y * (y0 - y_nb); | |
| 916 | 30538 | cps[0].y = mv_scale_ver + d_ver_x * (x0 - x_nb) + d_ver_y * (y0 - y_nb); | |
| 917 | 30538 | cps[1].x = mv_scale_hor + d_hor_x * (x0 + cb_width - x_nb) + d_hor_y * (y0 - y_nb); | |
| 918 | 30538 | 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 16745 times.
✓ Branch 1 taken 13793 times.
|
30538 | if (num_cps == 3) { |
| 920 | 16745 | cps[2].x = mv_scale_hor + d_hor_x * (x0 - x_nb) + d_hor_y * (y0 + cb_height - y_nb); | |
| 921 | 16745 | 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 77821 times.
✓ Branch 1 taken 30538 times.
|
108359 | for (int i = 0; i < num_cps; i++) { |
| 924 | 77821 | ff_vvc_round_mv(cps + i, 0, 7); | |
| 925 | 77821 | ff_vvc_clip_mv(cps + i); | |
| 926 | } | ||
| 927 | 30538 | } | |
| 928 | |||
| 929 | //derive affine neighbour's position, width and height, | ||
| 930 | 96305 | 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 | 96305 | const int log2_min_cb_size = fc->ps.sps->min_cb_log2_size_y; | |
| 933 | 96305 | const int min_cb_width = fc->ps.pps->min_cb_width; | |
| 934 | 96305 | const int x = x_nb >> log2_min_cb_size; | |
| 935 | 96305 | const int y = y_nb >> log2_min_cb_size; | |
| 936 | 96305 | const int motion_model_idc = SAMPLE_CTB(fc->tab.mmi, x, y); | |
| 937 |
2/2✓ Branch 0 taken 27236 times.
✓ Branch 1 taken 69069 times.
|
96305 | if (motion_model_idc) { |
| 938 | 27236 | *x_cb = SAMPLE_CTB(fc->tab.cb_pos_x[0], x, y); | |
| 939 | 27236 | *y_cb = SAMPLE_CTB(fc->tab.cb_pos_y[0], x, y); | |
| 940 | 27236 | *cbw = SAMPLE_CTB(fc->tab.cb_width[0], x, y); | |
| 941 | 27236 | *cbh = SAMPLE_CTB(fc->tab.cb_height[0], x, y); | |
| 942 | } | ||
| 943 | 96305 | 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 | 65594 | static int affine_merge_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand, MotionInfo* mi) | |
| 948 | { | ||
| 949 | 65594 | const VVCFrameContext *fc = lc->fc; | |
| 950 | int x, y, w, h, motion_model_idc; | ||
| 951 | |||
| 952 | 65594 | motion_model_idc = affine_neighbour_cb(fc, x_cand, y_cand, &x, &y, &w, &h); | |
| 953 |
2/2✓ Branch 0 taken 19546 times.
✓ Branch 1 taken 46048 times.
|
65594 | if (motion_model_idc) { |
| 954 | 19546 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
| 955 | 19546 | const MvField* tab_mvf = fc->tab.mvf; | |
| 956 | 19546 | const MvField *mvf = &TAB_MVF(x, y); | |
| 957 | |||
| 958 | 19546 | mi->bcw_idx = mvf->bcw_idx; | |
| 959 | 19546 | mi->pred_flag = mvf->pred_flag; | |
| 960 |
2/2✓ Branch 0 taken 39092 times.
✓ Branch 1 taken 19546 times.
|
58638 | for (int i = 0; i < 2; i++) { |
| 961 | 39092 | PredFlag mask = i + 1; | |
| 962 |
2/2✓ Branch 0 taken 24497 times.
✓ Branch 1 taken 14595 times.
|
39092 | if (mi->pred_flag & mask) { |
| 963 | 24497 | affine_cps_from_nb(lc, x, y, w, h, i, &mi->mv[i][0], motion_model_idc + 1); | |
| 964 | } | ||
| 965 | 39092 | mi->ref_idx[i] = mvf->ref_idx[i]; | |
| 966 | } | ||
| 967 | 19546 | mi->motion_model_idc = motion_model_idc; | |
| 968 | } | ||
| 969 | 65594 | return motion_model_idc; | |
| 970 | } | ||
| 971 | |||
| 972 | 45847 | static int affine_merge_from_nbs(NeighbourContext *ctx, const NeighbourIdx *nbs, const int num_nbs, MotionInfo* cand) | |
| 973 | { | ||
| 974 | 45847 | const VVCLocalContext *lc = ctx->lc; | |
| 975 |
2/2✓ Branch 0 taken 96575 times.
✓ Branch 1 taken 26301 times.
|
122876 | for (int i = 0; i < num_nbs; i++) { |
| 976 | 96575 | Neighbour *n = &ctx->neighbours[nbs[i]]; | |
| 977 |
4/4✓ Branch 1 taken 65594 times.
✓ Branch 2 taken 30981 times.
✓ Branch 4 taken 19546 times.
✓ Branch 5 taken 46048 times.
|
96575 | if (check_available(n, lc, 1) && affine_merge_candidate(lc, n->x, n->y, cand)) |
| 978 | 19546 | return 1; | |
| 979 | } | ||
| 980 | 26301 | return 0; | |
| 981 | } | ||
| 982 | #define AFFINE_MERGE_FROM_NBS(nbs) affine_merge_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), mi) | ||
| 983 | |||
| 984 | |||
| 985 | 101479 | static const MvField* derive_corner_mvf(NeighbourContext *ctx, const NeighbourIdx *neighbour, const int num_neighbour) | |
| 986 | { | ||
| 987 | 101479 | const VVCFrameContext *fc = ctx->lc->fc; | |
| 988 | 101479 | const MvField *tab_mvf = fc->tab.mvf; | |
| 989 | 101479 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
| 990 |
2/2✓ Branch 0 taken 108126 times.
✓ Branch 1 taken 7549 times.
|
115675 | for (int i = 0; i < num_neighbour; i++) { |
| 991 | 108126 | Neighbour *n = &ctx->neighbours[neighbour[i]]; | |
| 992 |
2/2✓ Branch 1 taken 93930 times.
✓ Branch 2 taken 14196 times.
|
108126 | if (check_available(n, ctx->lc, 1)) { |
| 993 | 93930 | return &TAB_MVF(n->x, n->y); | |
| 994 | } | ||
| 995 | } | ||
| 996 | 7549 | 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 | 53532 | 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 | 53532 | const PredFlag mask = (lx + 1) & A->pred_flag; | |
| 1006 |
2/2✓ Branch 0 taken 18977 times.
✓ Branch 1 taken 34555 times.
|
53532 | if (!(B->pred_flag & mask)) |
| 1007 | 18977 | return 0; | |
| 1008 |
2/2✓ Branch 0 taken 1763 times.
✓ Branch 1 taken 32792 times.
|
34555 | if (A->ref_idx[lx] != B->ref_idx[lx]) |
| 1009 | 1763 | return 0; | |
| 1010 |
2/2✓ Branch 0 taken 27143 times.
✓ Branch 1 taken 5649 times.
|
32792 | if (C) { |
| 1011 |
2/2✓ Branch 0 taken 941 times.
✓ Branch 1 taken 26202 times.
|
27143 | if (!(C->pred_flag & mask)) |
| 1012 | 941 | return 0; | |
| 1013 |
2/2✓ Branch 0 taken 1083 times.
✓ Branch 1 taken 25119 times.
|
26202 | if (A->ref_idx[lx] != C->ref_idx[lx]) |
| 1014 | 1083 | return 0; | |
| 1015 | } | ||
| 1016 | 30768 | return 1; | |
| 1017 | } | ||
| 1018 | |||
| 1019 | 1578246 | 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 | 1578246 | const VVCFrameContext *fc = lc->fc; | |
| 1023 | 1578246 | const VVCPPS *pps = fc->ps.pps; | |
| 1024 | 1578246 | const int ctb_log2_size = fc->ps.sps->ctb_log2_size_y; | |
| 1025 | 1578246 | const int subpic_idx = lc->sc->sh.r->curr_subpic_idx; | |
| 1026 | 1578246 | const int x_end = pps->subpic_x[subpic_idx] + pps->subpic_width[subpic_idx]; | |
| 1027 | 1578246 | const int y_end = pps->subpic_y[subpic_idx] + pps->subpic_height[subpic_idx]; | |
| 1028 | |||
| 1029 | 1578246 | *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 1390448 times.
✓ Branch 1 taken 187798 times.
|
1578246 | *y = av_clip(*y + temp_mv->y, y_ctb, FFMIN(y_end - 1, y_ctb + (1 << ctb_log2_size) - 1)) & ~7; |
| 1031 | 1578246 | } | |
| 1032 | |||
| 1033 | 1578246 | 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 | 1578246 | const int refIdxLx = 0; | |
| 1040 | 1578246 | const VVCFrameContext *fc = lc->fc; | |
| 1041 | 1578246 | const VVCSH *sh = &lc->sc->sh; | |
| 1042 | 1578246 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
| 1043 | 1578246 | VVCFrame *ref = fc->ref->collocated_ref; | |
| 1044 | 1578246 | MvField *tab_mvf = ref->tab_dmvr_mvf; | |
| 1045 | 1578246 | int colPic = ref->poc; | |
| 1046 | 1578246 | int X = 0; | |
| 1047 | |||
| 1048 | 1578246 | sb_clip_location(lc, x_ctb, y_ctb, temp_mv, &x, &y); | |
| 1049 | |||
| 1050 | 1578246 | temp_col = TAB_MVF(x, y); | |
| 1051 | 1578246 | mvLXCol = mv + 0; | |
| 1052 | 1578246 | *pred_flag = DERIVE_TEMPORAL_COLOCATED_MVS(1); | |
| 1053 |
2/2✓ Branch 0 taken 1231298 times.
✓ Branch 1 taken 346948 times.
|
1578246 | if (IS_B(sh->r)) { |
| 1054 | 1231298 | X = 1; | |
| 1055 | 1231298 | mvLXCol = mv + 1; | |
| 1056 | 1231298 | *pred_flag |= (DERIVE_TEMPORAL_COLOCATED_MVS(1)) << 1; | |
| 1057 | } | ||
| 1058 | 1578246 | } | |
| 1059 | |||
| 1060 | //8.5.5.4 Derivation process for subblock-based temporal merging base motion data | ||
| 1061 | 54532 | 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 | 54532 | const VVCFrameContext *fc = lc->fc; | |
| 1065 | 54532 | const RefPicList *rpl = lc->sc->rpl; | |
| 1066 | 54532 | const CodingUnit *cu = lc->cu; | |
| 1067 | 54532 | const int x = cu->x0 + cu->cb_width / 2; | |
| 1068 | 54532 | const int y = cu->y0 + cu->cb_height / 2; | |
| 1069 | 54532 | const VVCFrame *ref = fc->ref->collocated_ref; | |
| 1070 | |||
| 1071 | int colPic; | ||
| 1072 | |||
| 1073 | 54532 | memset(temp_mv, 0, sizeof(*temp_mv)); | |
| 1074 | |||
| 1075 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 54532 times.
|
54532 | if (!ref) { |
| 1076 | ✗ | memset(ctr_mvf, 0, sizeof(*ctr_mvf)); | |
| 1077 | ✗ | return 0; | |
| 1078 | } | ||
| 1079 | |||
| 1080 | 54532 | colPic = ref->poc; | |
| 1081 | |||
| 1082 |
2/2✓ Branch 0 taken 50836 times.
✓ Branch 1 taken 3696 times.
|
54532 | if (a1) { |
| 1083 |
4/4✓ Branch 0 taken 45938 times.
✓ Branch 1 taken 4898 times.
✓ Branch 2 taken 30828 times.
✓ Branch 3 taken 15110 times.
|
50836 | if ((a1->pred_flag & PF_L0) && colPic == rpl[L0].refs[a1->ref_idx[L0]].poc) |
| 1084 | 30828 | *temp_mv = a1->mv[0]; | |
| 1085 |
4/4✓ Branch 0 taken 14127 times.
✓ Branch 1 taken 5881 times.
✓ Branch 2 taken 11271 times.
✓ Branch 3 taken 2856 times.
|
20008 | else if ((a1->pred_flag & PF_L1) && colPic == rpl[L1].refs[a1->ref_idx[L1]].poc) |
| 1086 | 11271 | *temp_mv = a1->mv[1]; | |
| 1087 | 50836 | ff_vvc_round_mv(temp_mv, 0, 4); | |
| 1088 | } | ||
| 1089 | 54532 | sb_temproal_luma_motion(lc, x_ctb, y_ctb, temp_mv, x, y, &ctr_mvf->pred_flag , ctr_mvf->mv); | |
| 1090 | |||
| 1091 | 54532 | return ctr_mvf->pred_flag; | |
| 1092 | } | ||
| 1093 | |||
| 1094 | |||
| 1095 | //8.5.5.3 Derivation process for subblock-based temporal merging candidates | ||
| 1096 | 54720 | static int sb_temporal_merge_candidate(const VVCLocalContext* lc, NeighbourContext *nctx, PredictionUnit *pu) | |
| 1097 | { | ||
| 1098 | 54720 | const VVCFrameContext *fc = lc->fc; | |
| 1099 | 54720 | const CodingUnit *cu = lc->cu; | |
| 1100 | 54720 | const VVCSPS *sps = fc->ps.sps; | |
| 1101 | 54720 | const VVCPH *ph = &fc->ps.ph; | |
| 1102 | 54720 | MotionInfo *mi = &pu->mi; | |
| 1103 | 54720 | const int ctb_log2_size = sps->ctb_log2_size_y; | |
| 1104 | 54720 | const int x0 = cu->x0; | |
| 1105 | 54720 | const int y0 = cu->y0; | |
| 1106 | 54720 | const NeighbourIdx n = A1; | |
| 1107 | const MvField *a1; | ||
| 1108 | MvField ctr_mvf; | ||
| 1109 | 54720 | LOCAL_ALIGNED_8(Mv, temp_mv, [1]); | |
| 1110 | 54720 | const int x_ctb = (x0 >> ctb_log2_size) << ctb_log2_size; | |
| 1111 | 54720 | const int y_ctb = (y0 >> ctb_log2_size) << ctb_log2_size; | |
| 1112 | |||
| 1113 | |||
| 1114 |
2/2✓ Branch 0 taken 54633 times.
✓ Branch 1 taken 87 times.
|
54720 | if (!ph->r->ph_temporal_mvp_enabled_flag || |
| 1115 |
2/2✓ Branch 0 taken 54532 times.
✓ Branch 1 taken 101 times.
|
54633 | !sps->r->sps_sbtmvp_enabled_flag || |
| 1116 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 54532 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
54532 | (cu->cb_width < 8 && cu->cb_height < 8)) |
| 1117 | 188 | return 0; | |
| 1118 | |||
| 1119 | 54532 | mi->num_sb_x = cu->cb_width >> 3; | |
| 1120 | 54532 | mi->num_sb_y = cu->cb_height >> 3; | |
| 1121 | |||
| 1122 | 54532 | a1 = derive_corner_mvf(nctx, &n, 1); | |
| 1123 |
2/2✓ Branch 1 taken 46117 times.
✓ Branch 2 taken 8415 times.
|
54532 | if (sb_temporal_luma_motion_data(lc, a1, x_ctb, y_ctb, &ctr_mvf, temp_mv)) { |
| 1124 | 46117 | const int sbw = cu->cb_width / mi->num_sb_x; | |
| 1125 | 46117 | const int sbh = cu->cb_height / mi->num_sb_y; | |
| 1126 | 46117 | MvField mvf = {0}; | |
| 1127 |
2/2✓ Branch 0 taken 200275 times.
✓ Branch 1 taken 46117 times.
|
246392 | for (int sby = 0; sby < mi->num_sb_y; sby++) { |
| 1128 |
2/2✓ Branch 0 taken 1523714 times.
✓ Branch 1 taken 200275 times.
|
1723989 | for (int sbx = 0; sbx < mi->num_sb_x; sbx++) { |
| 1129 | 1523714 | int x = x0 + sbx * sbw; | |
| 1130 | 1523714 | int y = y0 + sby * sbh; | |
| 1131 | 1523714 | 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 1515126 times.
|
1523714 | 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 | 1523714 | ff_vvc_set_mvf(lc, x, y, sbw, sbh, &mvf); | |
| 1137 | } | ||
| 1138 | } | ||
| 1139 | 46117 | return 1; | |
| 1140 | } | ||
| 1141 | 8415 | return 0; | |
| 1142 | } | ||
| 1143 | |||
| 1144 | 14383 | static int affine_merge_const1(const MvField *c0, const MvField *c1, const MvField *c2, MotionInfo *mi) | |
| 1145 | { | ||
| 1146 |
6/6✓ Branch 0 taken 14310 times.
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 13630 times.
✓ Branch 3 taken 680 times.
✓ Branch 4 taken 13108 times.
✓ Branch 5 taken 522 times.
|
14383 | if (c0 && c1 && c2) { |
| 1147 | 13108 | mi->pred_flag = 0; | |
| 1148 |
2/2✓ Branch 0 taken 26216 times.
✓ Branch 1 taken 13108 times.
|
39324 | for (int i = 0; i < 2; i++) { |
| 1149 | 26216 | PredFlag mask = i + 1; | |
| 1150 |
2/2✓ Branch 1 taken 15434 times.
✓ Branch 2 taken 10782 times.
|
26216 | if (compare_pf_ref_idx(c0, c1, c2, i)) { |
| 1151 | 15434 | mi->pred_flag |= mask; | |
| 1152 | 15434 | mi->ref_idx[i] = c0->ref_idx[i]; | |
| 1153 | 15434 | mi->mv[i][0] = c0->mv[i]; | |
| 1154 | 15434 | mi->mv[i][1] = c1->mv[i]; | |
| 1155 | 15434 | mi->mv[i][2] = c2->mv[i]; | |
| 1156 | } | ||
| 1157 | } | ||
| 1158 |
2/2✓ Branch 0 taken 12109 times.
✓ Branch 1 taken 999 times.
|
13108 | if (mi->pred_flag) { |
| 1159 |
2/2✓ Branch 0 taken 3325 times.
✓ Branch 1 taken 8784 times.
|
12109 | if (mi->pred_flag == PF_BI) |
| 1160 | 3325 | mi->bcw_idx = c0->bcw_idx; | |
| 1161 | 12109 | mi->motion_model_idc = MOTION_6_PARAMS_AFFINE; | |
| 1162 | 12109 | return 1; | |
| 1163 | } | ||
| 1164 | } | ||
| 1165 | 2274 | return 0; | |
| 1166 | } | ||
| 1167 | |||
| 1168 | 7652 | static int affine_merge_const2(const MvField *c0, const MvField *c1, const MvField *c3, MotionInfo *mi) | |
| 1169 | { | ||
| 1170 |
6/6✓ Branch 0 taken 7579 times.
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 6899 times.
✓ Branch 3 taken 680 times.
✓ Branch 4 taken 4657 times.
✓ Branch 5 taken 2242 times.
|
7652 | if (c0 && c1 && c3) { |
| 1171 | 4657 | mi->pred_flag = 0; | |
| 1172 |
2/2✓ Branch 0 taken 9314 times.
✓ Branch 1 taken 4657 times.
|
13971 | for (int i = 0; i < 2; i++) { |
| 1173 | 9314 | PredFlag mask = i + 1; | |
| 1174 |
2/2✓ Branch 1 taken 5466 times.
✓ Branch 2 taken 3848 times.
|
9314 | if (compare_pf_ref_idx(c0, c1, c3, i)) { |
| 1175 | 5466 | mi->pred_flag |= mask; | |
| 1176 | 5466 | mi->ref_idx[i] = c0->ref_idx[i]; | |
| 1177 | 5466 | mi->mv[i][0] = c0->mv[i]; | |
| 1178 | 5466 | mi->mv[i][1] = c1->mv[i]; | |
| 1179 | 5466 | mi->mv[i][2].x = c3->mv[i].x + c0->mv[i].x - c1->mv[i].x; | |
| 1180 | 5466 | mi->mv[i][2].y = c3->mv[i].y + c0->mv[i].y - c1->mv[i].y; | |
| 1181 | 5466 | ff_vvc_clip_mv(&mi->mv[i][2]); | |
| 1182 | } | ||
| 1183 | } | ||
| 1184 |
2/2✓ Branch 0 taken 4057 times.
✓ Branch 1 taken 600 times.
|
4657 | if (mi->pred_flag) { |
| 1185 |
2/2✓ Branch 0 taken 1409 times.
✓ Branch 1 taken 2648 times.
|
4057 | mi->bcw_idx = mi->pred_flag == PF_BI ? c0->bcw_idx : 0; |
| 1186 | 4057 | mi->motion_model_idc = MOTION_6_PARAMS_AFFINE; | |
| 1187 | 4057 | return 1; | |
| 1188 | } | ||
| 1189 | } | ||
| 1190 | 3595 | return 0; | |
| 1191 | } | ||
| 1192 | |||
| 1193 | 5527 | static int affine_merge_const3(const MvField *c0, const MvField *c2, const MvField *c3, MotionInfo *mi) | |
| 1194 | { | ||
| 1195 |
6/6✓ Branch 0 taken 5454 times.
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 5120 times.
✓ Branch 3 taken 334 times.
✓ Branch 4 taken 2878 times.
✓ Branch 5 taken 2242 times.
|
5527 | if (c0 && c2 && c3) { |
| 1196 | 2878 | mi->pred_flag = 0; | |
| 1197 |
2/2✓ Branch 0 taken 5756 times.
✓ Branch 1 taken 2878 times.
|
8634 | for (int i = 0; i < 2; i++) { |
| 1198 | 5756 | PredFlag mask = i + 1; | |
| 1199 |
2/2✓ Branch 1 taken 3290 times.
✓ Branch 2 taken 2466 times.
|
5756 | if (compare_pf_ref_idx(c0, c2, c3, i)) { |
| 1200 | 3290 | mi->pred_flag |= mask; | |
| 1201 | 3290 | mi->ref_idx[i] = c0->ref_idx[i]; | |
| 1202 | 3290 | mi->mv[i][0] = c0->mv[i]; | |
| 1203 | 3290 | mi->mv[i][1].x = c3->mv[i].x + c0->mv[i].x - c2->mv[i].x; | |
| 1204 | 3290 | mi->mv[i][1].y = c3->mv[i].y + c0->mv[i].y - c2->mv[i].y; | |
| 1205 | 3290 | ff_vvc_clip_mv(&mi->mv[i][1]); | |
| 1206 | 3290 | mi->mv[i][2] = c2->mv[i]; | |
| 1207 | } | ||
| 1208 | } | ||
| 1209 |
2/2✓ Branch 0 taken 2428 times.
✓ Branch 1 taken 450 times.
|
2878 | if (mi->pred_flag) { |
| 1210 |
2/2✓ Branch 0 taken 862 times.
✓ Branch 1 taken 1566 times.
|
2428 | mi->bcw_idx = mi->pred_flag == PF_BI ? c0->bcw_idx : 0; |
| 1211 | 2428 | mi->motion_model_idc = MOTION_6_PARAMS_AFFINE; | |
| 1212 | 2428 | return 1; | |
| 1213 | } | ||
| 1214 | } | ||
| 1215 | 3099 | return 0; | |
| 1216 | } | ||
| 1217 | |||
| 1218 | 3891 | static int affine_merge_const4(const MvField *c1, const MvField *c2, const MvField *c3, MotionInfo *mi) | |
| 1219 | { | ||
| 1220 |
6/6✓ Branch 0 taken 3443 times.
✓ Branch 1 taken 448 times.
✓ Branch 2 taken 3117 times.
✓ Branch 3 taken 326 times.
✓ Branch 4 taken 1105 times.
✓ Branch 5 taken 2012 times.
|
3891 | 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 | 3206 | return 0; | |
| 1241 | } | ||
| 1242 | |||
| 1243 | 4521 | static int affine_merge_const5(const MvField *c0, const MvField *c1, MotionInfo *mi) | |
| 1244 | { | ||
| 1245 |
4/4✓ Branch 0 taken 3755 times.
✓ Branch 1 taken 766 times.
✓ Branch 2 taken 3121 times.
✓ Branch 3 taken 634 times.
|
4521 | if (c0 && c1) { |
| 1246 | 3121 | mi->pred_flag = 0; | |
| 1247 |
2/2✓ Branch 0 taken 6242 times.
✓ Branch 1 taken 3121 times.
|
9363 | for (int i = 0; i < 2; i++) { |
| 1248 | 6242 | PredFlag mask = i + 1; | |
| 1249 |
2/2✓ Branch 1 taken 3450 times.
✓ Branch 2 taken 2792 times.
|
6242 | if (compare_pf_ref_idx(c0, c1, NULL, i)) { |
| 1250 | 3450 | mi->pred_flag |= mask; | |
| 1251 | 3450 | mi->ref_idx[i] = c0->ref_idx[i]; | |
| 1252 | 3450 | mi->mv[i][0] = c0->mv[i]; | |
| 1253 | 3450 | mi->mv[i][1] = c1->mv[i]; | |
| 1254 | } | ||
| 1255 | } | ||
| 1256 |
2/2✓ Branch 0 taken 2717 times.
✓ Branch 1 taken 404 times.
|
3121 | if (mi->pred_flag) { |
| 1257 |
2/2✓ Branch 0 taken 733 times.
✓ Branch 1 taken 1984 times.
|
2717 | if (mi->pred_flag == PF_BI) |
| 1258 | 733 | mi->bcw_idx = c0->bcw_idx; | |
| 1259 | 2717 | mi->motion_model_idc = MOTION_4_PARAMS_AFFINE; | |
| 1260 | 2717 | 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 | 15649 | static int affine_merge_const_candidates(const VVCLocalContext *lc, MotionInfo *mi, | |
| 1306 | NeighbourContext *nctx, const int merge_subblock_idx, int num_cands) | ||
| 1307 | { | ||
| 1308 | 15649 | const VVCFrameContext *fc = lc->fc; | |
| 1309 | 15649 | const CodingUnit *cu = lc->cu; | |
| 1310 | 15649 | const NeighbourIdx tl[] = { B2, B3, A2 }; | |
| 1311 | 15649 | const NeighbourIdx tr[] = { B1, B0}; | |
| 1312 | 15649 | const NeighbourIdx bl[] = { A1, A0}; | |
| 1313 | const MvField *c0, *c1, *c2; | ||
| 1314 | |||
| 1315 | 15649 | c0 = DERIVE_CORNER_MV(tl); | |
| 1316 | 15649 | c1 = DERIVE_CORNER_MV(tr); | |
| 1317 | 15649 | c2 = DERIVE_CORNER_MV(bl); | |
| 1318 | |||
| 1319 |
2/2✓ Branch 0 taken 14383 times.
✓ Branch 1 taken 1266 times.
|
15649 | if (fc->ps.sps->r->sps_6param_affine_enabled_flag) { |
| 1320 | 14383 | MvField corner3, *c3 = NULL; | |
| 1321 | //Const1 | ||
| 1322 |
2/2✓ Branch 1 taken 12109 times.
✓ Branch 2 taken 2274 times.
|
14383 | if (affine_merge_const1(c0, c1, c2, mi)) { |
| 1323 |
2/2✓ Branch 0 taken 6731 times.
✓ Branch 1 taken 5378 times.
|
12109 | if (merge_subblock_idx == num_cands) |
| 1324 | 11128 | return 1; | |
| 1325 | 5378 | num_cands++; | |
| 1326 | } | ||
| 1327 | |||
| 1328 | 7652 | memset(&corner3, 0, sizeof(corner3)); | |
| 1329 |
2/2✓ Branch 0 taken 7626 times.
✓ Branch 1 taken 26 times.
|
7652 | if (fc->ps.ph.r->ph_temporal_mvp_enabled_flag){ |
| 1330 | 7626 | const int available_l0 = temporal_luma_motion_vector(lc, 0, corner3.mv + 0, 0, 0, 0); | |
| 1331 | 15252 | const int available_l1 = (lc->sc->sh.r->sh_slice_type == VVC_SLICE_TYPE_B) ? | |
| 1332 |
2/2✓ Branch 0 taken 6202 times.
✓ Branch 1 taken 1424 times.
|
7626 | temporal_luma_motion_vector(lc, 0, corner3.mv + 1, 1, 0, 0) : 0; |
| 1333 | |||
| 1334 | 7626 | corner3.pred_flag = available_l0 + (available_l1 << 1); | |
| 1335 |
2/2✓ Branch 0 taken 5123 times.
✓ Branch 1 taken 2503 times.
|
7626 | if (corner3.pred_flag) |
| 1336 | 5123 | c3 = &corner3; | |
| 1337 | } | ||
| 1338 | |||
| 1339 | //Const2 | ||
| 1340 |
2/2✓ Branch 1 taken 4057 times.
✓ Branch 2 taken 3595 times.
|
7652 | if (affine_merge_const2(c0, c1, c3, mi)) { |
| 1341 |
2/2✓ Branch 0 taken 2125 times.
✓ Branch 1 taken 1932 times.
|
4057 | if (merge_subblock_idx == num_cands) |
| 1342 | 2125 | return 1; | |
| 1343 | 1932 | num_cands++; | |
| 1344 | } | ||
| 1345 | |||
| 1346 | //Const3 | ||
| 1347 |
2/2✓ Branch 1 taken 2428 times.
✓ Branch 2 taken 3099 times.
|
5527 | if (affine_merge_const3(c0, c2, c3, mi)) { |
| 1348 |
2/2✓ Branch 0 taken 1636 times.
✓ Branch 1 taken 792 times.
|
2428 | if (merge_subblock_idx == num_cands) |
| 1349 | 1636 | return 1; | |
| 1350 | 792 | num_cands++; | |
| 1351 | } | ||
| 1352 | |||
| 1353 | //Const4 | ||
| 1354 |
2/2✓ Branch 1 taken 685 times.
✓ Branch 2 taken 3206 times.
|
3891 | 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 2717 times.
✓ Branch 2 taken 1804 times.
|
4521 | if (affine_merge_const5(c0, c1, mi)) { |
| 1363 |
2/2✓ Branch 0 taken 1546 times.
✓ Branch 1 taken 1171 times.
|
2717 | if (merge_subblock_idx == num_cands) |
| 1364 | 1546 | 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 | 54720 | static int sb_mv_merge_mode(const VVCLocalContext *lc, const int merge_subblock_idx, PredictionUnit *pu) | |
| 1378 | { | ||
| 1379 | 54720 | const VVCSPS *sps = lc->fc->ps.sps; | |
| 1380 | 54720 | const CodingUnit *cu = lc->cu; | |
| 1381 | 54720 | MotionInfo *mi = &pu->mi; | |
| 1382 | 54720 | int num_cands = 0; | |
| 1383 | NeighbourContext nctx; | ||
| 1384 | |||
| 1385 | 54720 | init_neighbour_context(&nctx, lc); | |
| 1386 | |||
| 1387 | //SbCol | ||
| 1388 |
2/2✓ Branch 1 taken 46117 times.
✓ Branch 2 taken 8603 times.
|
54720 | if (sb_temporal_merge_candidate(lc, &nctx, pu)) { |
| 1389 |
2/2✓ Branch 0 taken 28918 times.
✓ Branch 1 taken 17199 times.
|
46117 | if (merge_subblock_idx == num_cands) |
| 1390 | 28918 | return 1; | |
| 1391 | 17199 | num_cands++; | |
| 1392 | } | ||
| 1393 | |||
| 1394 | 25802 | pu->inter_affine_flag = 1; | |
| 1395 | 25802 | mi->num_sb_x = cu->cb_width >> MIN_PU_LOG2; | |
| 1396 | 25802 | mi->num_sb_y = cu->cb_height >> MIN_PU_LOG2; | |
| 1397 | |||
| 1398 |
1/2✓ Branch 0 taken 25802 times.
✗ Branch 1 not taken.
|
25802 | if (sps->r->sps_affine_enabled_flag) { |
| 1399 | 25802 | const NeighbourIdx ak[] = { A0, A1 }; | |
| 1400 | 25802 | const NeighbourIdx bk[] = { B0, B1, B2 }; | |
| 1401 | //A | ||
| 1402 |
2/2✓ Branch 1 taken 10246 times.
✓ Branch 2 taken 15556 times.
|
25802 | if (AFFINE_MERGE_FROM_NBS(ak)) { |
| 1403 |
2/2✓ Branch 0 taken 5757 times.
✓ Branch 1 taken 4489 times.
|
10246 | if (merge_subblock_idx == num_cands) |
| 1404 | 24069 | return 0; | |
| 1405 | 4489 | num_cands++; | |
| 1406 | } | ||
| 1407 | |||
| 1408 | //B | ||
| 1409 |
2/2✓ Branch 1 taken 9300 times.
✓ Branch 2 taken 10745 times.
|
20045 | if (AFFINE_MERGE_FROM_NBS(bk)) { |
| 1410 |
2/2✓ Branch 0 taken 4396 times.
✓ Branch 1 taken 4904 times.
|
9300 | if (merge_subblock_idx == num_cands) |
| 1411 | 4396 | return 0; | |
| 1412 | 4904 | num_cands++; | |
| 1413 | } | ||
| 1414 | |||
| 1415 | //Const1 to Const6 | ||
| 1416 |
2/2✓ Branch 1 taken 13916 times.
✓ Branch 2 taken 1733 times.
|
15649 | if (affine_merge_const_candidates(lc, mi, &nctx, merge_subblock_idx, num_cands)) |
| 1417 | 13916 | return 0; | |
| 1418 | } | ||
| 1419 | //Zero | ||
| 1420 | 1733 | affine_merge_zero_motion(lc, mi); | |
| 1421 | 1733 | return 0; | |
| 1422 | } | ||
| 1423 | |||
| 1424 | 54720 | void ff_vvc_sb_mv_merge_mode(VVCLocalContext *lc, const int merge_subblock_idx, PredictionUnit *pu) | |
| 1425 | { | ||
| 1426 | 54720 | const CodingUnit *cu = lc->cu; | |
| 1427 | 54720 | ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height); | |
| 1428 |
2/2✓ Branch 1 taken 25802 times.
✓ Branch 2 taken 28918 times.
|
54720 | if (!sb_mv_merge_mode(lc, merge_subblock_idx, pu)) { |
| 1429 | 25802 | ff_vvc_store_sb_mvs(lc, pu); | |
| 1430 | } | ||
| 1431 | 54720 | } | |
| 1432 | |||
| 1433 | 150787 | 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 | 150787 | const VVCFrameContext *fc = lc->fc; | |
| 1437 | 150787 | const RefPicList *rpl = lc->sc->rpl; | |
| 1438 | 150787 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
| 1439 | 150787 | const MvField* tab_mvf = fc->tab.mvf; | |
| 1440 | 150787 | const MvField *mvf = &TAB_MVF(x_cand, y_cand); | |
| 1441 | 150787 | const PredFlag maskx = lx + 1; | |
| 1442 | 150787 | const int poc = rpl[lx].refs[ref_idx[lx]].poc; | |
| 1443 | 150787 | int available = 0; | |
| 1444 | |||
| 1445 |
4/4✓ Branch 0 taken 115784 times.
✓ Branch 1 taken 35003 times.
✓ Branch 2 taken 76929 times.
✓ Branch 3 taken 38855 times.
|
150787 | if ((mvf->pred_flag & maskx) && rpl[lx].refs[mvf->ref_idx[lx]].poc == poc) { |
| 1446 | 76929 | available = 1; | |
| 1447 | 76929 | *mv = mvf->mv[lx]; | |
| 1448 | } else { | ||
| 1449 | 73858 | const int ly = !lx; | |
| 1450 | 73858 | const PredFlag masky = ly + 1; | |
| 1451 |
4/4✓ Branch 0 taken 50197 times.
✓ Branch 1 taken 23661 times.
✓ Branch 2 taken 10524 times.
✓ Branch 3 taken 39673 times.
|
73858 | 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 | 150787 | return available; | |
| 1458 | } | ||
| 1459 | |||
| 1460 | 30711 | 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 | 30711 | const VVCFrameContext *fc = lc->fc; | |
| 1465 | 30711 | int x_nb, y_nb, nbw, nbh, motion_model_idc, available = 0; | |
| 1466 | |||
| 1467 | 30711 | motion_model_idc = affine_neighbour_cb(fc, x_cand, y_cand, &x_nb, &y_nb, &nbw, &nbh); | |
| 1468 |
2/2✓ Branch 0 taken 7690 times.
✓ Branch 1 taken 23021 times.
|
30711 | if (motion_model_idc) { |
| 1469 | 7690 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
| 1470 | 7690 | const MvField* tab_mvf = fc->tab.mvf; | |
| 1471 | 7690 | const MvField *mvf = &TAB_MVF(x_nb, y_nb); | |
| 1472 | 7690 | RefPicList* rpl = lc->sc->rpl; | |
| 1473 | 7690 | const PredFlag maskx = lx + 1; | |
| 1474 | 7690 | const int poc = rpl[lx].refs[ref_idx[lx]].poc; | |
| 1475 | |||
| 1476 |
4/4✓ Branch 0 taken 6484 times.
✓ Branch 1 taken 1206 times.
✓ Branch 2 taken 5262 times.
✓ Branch 3 taken 1222 times.
|
7690 | if ((mvf->pred_flag & maskx) && rpl[lx].refs[mvf->ref_idx[lx]].poc == poc) { |
| 1477 | 5262 | available = 1; | |
| 1478 | 5262 | 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 | 30711 | return available; | |
| 1490 | } | ||
| 1491 | |||
| 1492 | 170563 | 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 | 170563 | const VVCLocalContext *lc = ctx->lc; | |
| 1497 | 170563 | int available = 0; | |
| 1498 | |||
| 1499 |
2/2✓ Branch 0 taken 338007 times.
✓ Branch 1 taken 77069 times.
|
415076 | for (int i = 0; i < num_nbs; i++) { |
| 1500 | 338007 | Neighbour *n = &ctx->neighbours[nbs[i]]; | |
| 1501 |
2/2✓ Branch 1 taken 181498 times.
✓ Branch 2 taken 156509 times.
|
338007 | if (check_available(n, lc, 0)) { |
| 1502 |
2/2✓ Branch 0 taken 30711 times.
✓ Branch 1 taken 150787 times.
|
181498 | if (num_cps > 1) |
| 1503 | 30711 | available = affine_mvp_candidate(lc, n->x, n->y, lx, ref_idx, cps, num_cps); | |
| 1504 | else | ||
| 1505 | 150787 | available = mvp_candidate(lc, n->x, n->y, lx, ref_idx, cps); | |
| 1506 |
2/2✓ Branch 0 taken 93494 times.
✓ Branch 1 taken 88004 times.
|
181498 | if (available) { |
| 1507 |
2/2✓ Branch 0 taken 102516 times.
✓ Branch 1 taken 93494 times.
|
196010 | for (int c = 0; c < num_cps; c++) |
| 1508 | 102516 | ff_vvc_round_mv(cps + c, amvr_shift, amvr_shift); | |
| 1509 | 93494 | return 1; | |
| 1510 | } | ||
| 1511 | } | ||
| 1512 | } | ||
| 1513 | 77069 | 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 | 89874 | 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 | 89874 | const NeighbourIdx ak[] = { A0, A1 }; | |
| 1528 | 89874 | const NeighbourIdx bk[] = { B0, B1, B2 }; | |
| 1529 | NeighbourContext nctx; | ||
| 1530 | 89874 | int available_a, num_cands = 0; | |
| 1531 | 89874 | LOCAL_ALIGNED_8(Mv, mv_a, [1]); | |
| 1532 | |||
| 1533 | 89874 | init_neighbour_context(&nctx, lc); | |
| 1534 | |||
| 1535 | 89874 | available_a = MVP_FROM_NBS(ak); | |
| 1536 |
2/2✓ Branch 0 taken 53118 times.
✓ Branch 1 taken 36756 times.
|
89874 | if (available_a) { |
| 1537 |
2/2✓ Branch 0 taken 32201 times.
✓ Branch 1 taken 20917 times.
|
53118 | if (mvp_lx_flag == num_cands) |
| 1538 | 32201 | return 1; | |
| 1539 | 20917 | num_cands++; | |
| 1540 | 20917 | *mv_a = *mv; | |
| 1541 | } | ||
| 1542 |
2/2✓ Branch 1 taken 34335 times.
✓ Branch 2 taken 23338 times.
|
57673 | if (MVP_FROM_NBS(bk)) { |
| 1543 |
4/4✓ Branch 0 taken 17886 times.
✓ Branch 1 taken 16449 times.
✓ Branch 2 taken 14986 times.
✓ Branch 3 taken 2900 times.
|
34335 | if (!available_a || !IS_SAME_MV(mv_a, mv)) { |
| 1544 |
2/2✓ Branch 0 taken 25699 times.
✓ Branch 1 taken 5736 times.
|
31435 | if (mvp_lx_flag == num_cands) |
| 1545 | 25699 | return 1; | |
| 1546 | 5736 | num_cands++; | |
| 1547 | } | ||
| 1548 | } | ||
| 1549 | 31974 | *nb_merge_cand = num_cands; | |
| 1550 | 31974 | return 0; | |
| 1551 | } | ||
| 1552 | |||
| 1553 | 31974 | 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 18582 times.
✓ Branch 2 taken 13392 times.
|
31974 | if (temporal_luma_motion_vector(lc, ref_idx[lx], mv, lx, 1, 0)) { |
| 1558 |
2/2✓ Branch 0 taken 15028 times.
✓ Branch 1 taken 3554 times.
|
18582 | if (mvp_lx_flag == *num_cands) { |
| 1559 | 15028 | ff_vvc_round_mv(mv, amvr_shift, amvr_shift); | |
| 1560 | 15028 | return 1; | |
| 1561 | } | ||
| 1562 | 3554 | (*num_cands)++; | |
| 1563 | } | ||
| 1564 | 16946 | return 0; | |
| 1565 | |||
| 1566 | } | ||
| 1567 | |||
| 1568 | 16946 | 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 | 16946 | const EntryPoint* ep = lc->ep; | |
| 1573 | 16946 | const RefPicList* rpl = lc->sc->rpl; | |
| 1574 | 16946 | const int poc = rpl[lx].refs[ref_idx].poc; | |
| 1575 | |||
| 1576 |
2/2✓ Branch 0 taken 1946 times.
✓ Branch 1 taken 15000 times.
|
16946 | if (ep->num_hmvp == 0) |
| 1577 | 1946 | return 0; | |
| 1578 |
2/2✓ Branch 0 taken 31459 times.
✓ Branch 1 taken 4727 times.
|
36186 | for (int i = 1; i <= FFMIN(4, ep->num_hmvp); i++) { |
| 1579 | 31459 | const MvField* h = &ep->hmvp[i - 1]; | |
| 1580 |
2/2✓ Branch 0 taken 54073 times.
✓ Branch 1 taken 21186 times.
|
75259 | for (int j = 0; j < 2; j++) { |
| 1581 |
2/2✓ Branch 0 taken 22614 times.
✓ Branch 1 taken 31459 times.
|
54073 | const int ly = (j ? !lx : lx); |
| 1582 | 54073 | PredFlag mask = PF_L0 + ly; | |
| 1583 |
4/4✓ Branch 0 taken 36942 times.
✓ Branch 1 taken 17131 times.
✓ Branch 2 taken 12531 times.
✓ Branch 3 taken 24411 times.
|
54073 | 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 | 4727 | return 0; | |
| 1594 | } | ||
| 1595 | |||
| 1596 | //8.5.2.8 Derivation process for luma motion vector prediction | ||
| 1597 | 89874 | 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 57900 times.
✓ Branch 2 taken 31974 times.
|
89874 | if (mvp_spatial_candidates(lc, mvp_lx_flag, lx, ref_idx, amvr_shift, mv, &num_cands)) |
| 1603 | 83201 | return; | |
| 1604 | |||
| 1605 |
2/2✓ Branch 1 taken 15028 times.
✓ Branch 2 taken 16946 times.
|
31974 | if (mvp_temporal_candidates(lc, mvp_lx_flag, lx, ref_idx, amvr_shift, mv, &num_cands)) |
| 1606 | 15028 | return; | |
| 1607 | |||
| 1608 |
2/2✓ Branch 1 taken 10273 times.
✓ Branch 2 taken 6673 times.
|
16946 | if (mvp_history_candidates(lc, mvp_lx_flag, lx, ref_idx[lx], amvr_shift, mv, num_cands)) |
| 1609 | 10273 | return; | |
| 1610 | |||
| 1611 | 6673 | memset(mv, 0, sizeof(*mv)); | |
| 1612 | } | ||
| 1613 | |||
| 1614 | 70461 | void ff_vvc_mvp(VVCLocalContext *lc, const int *mvp_lx_flag, const int amvr_shift, MotionInfo *mi) | |
| 1615 | { | ||
| 1616 | 70461 | const CodingUnit *cu = lc->cu; | |
| 1617 | 70461 | mi->num_sb_x = 1; | |
| 1618 | 70461 | mi->num_sb_y = 1; | |
| 1619 | |||
| 1620 | 70461 | ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height); | |
| 1621 |
2/2✓ Branch 0 taken 57986 times.
✓ Branch 1 taken 12475 times.
|
70461 | if (mi->pred_flag != PF_L1) |
| 1622 | 57986 | mvp(lc, mvp_lx_flag[L0], L0, mi->ref_idx, amvr_shift, &mi->mv[L0][0]); | |
| 1623 |
2/2✓ Branch 0 taken 31888 times.
✓ Branch 1 taken 38573 times.
|
70461 | if (mi->pred_flag != PF_L0) |
| 1624 | 31888 | mvp(lc, mvp_lx_flag[L1], L1, mi->ref_idx, amvr_shift, &mi->mv[L1][0]); | |
| 1625 | 70461 | } | |
| 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 | 24942 | 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 | 24942 | const VVCLocalContext *lc = ctx->lc; | |
| 1755 | 24942 | const VVCFrameContext *fc = lc->fc; | |
| 1756 | 24942 | const MvField *tab_mvf = fc->tab.mvf; | |
| 1757 | 24942 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
| 1758 | 24942 | const RefPicList* rpl = lc->sc->rpl; | |
| 1759 | 24942 | int available = 0; | |
| 1760 | |||
| 1761 |
2/2✓ Branch 0 taken 38931 times.
✓ Branch 1 taken 8486 times.
|
47417 | for (int i = 0; i < num_neighbour; i++) { |
| 1762 | 38931 | Neighbour *n = &ctx->neighbours[neighbour[i]]; | |
| 1763 |
2/2✓ Branch 1 taken 24505 times.
✓ Branch 2 taken 14426 times.
|
38931 | if (check_available(n, ctx->lc, 0)) { |
| 1764 | 24505 | const PredFlag maskx = lx + 1; | |
| 1765 | 24505 | const MvField* mvf = &TAB_MVF(n->x, n->y); | |
| 1766 | 24505 | const int poc = rpl[lx].refs[ref_idx].poc; | |
| 1767 |
4/4✓ Branch 0 taken 20006 times.
✓ Branch 1 taken 4499 times.
✓ Branch 2 taken 14583 times.
✓ Branch 3 taken 5423 times.
|
24505 | if ((mvf->pred_flag & maskx) && rpl[lx].refs[mvf->ref_idx[lx]].poc == poc) { |
| 1768 | 14583 | available = 1; | |
| 1769 | 14583 | *cp = mvf->mv[lx]; | |
| 1770 | } else { | ||
| 1771 | 9922 | const int ly = !lx; | |
| 1772 | 9922 | const PredFlag masky = ly + 1; | |
| 1773 |
4/4✓ Branch 0 taken 6738 times.
✓ Branch 1 taken 3184 times.
✓ Branch 2 taken 1873 times.
✓ Branch 3 taken 4865 times.
|
9922 | 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 16456 times.
✓ Branch 1 taken 8049 times.
|
24505 | if (available) { |
| 1779 | 16456 | ff_vvc_round_mv(cp, amvr_shift, amvr_shift); | |
| 1780 | 16456 | return 1; | |
| 1781 | } | ||
| 1782 | } | ||
| 1783 | } | ||
| 1784 | 8486 | 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 | 8314 | 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 | 8314 | const NeighbourIdx tl[] = { B2, B3, A2 }; | |
| 1797 | 8314 | const NeighbourIdx tr[] = { B1, B0 }; | |
| 1798 | 8314 | const NeighbourIdx bl[] = { A1, A0 }; | |
| 1799 | |||
| 1800 | 8314 | available[0] = AFFINE_MVP_CONSTRUCTED_CP(tl, cps + 0); | |
| 1801 | 8314 | available[1] = AFFINE_MVP_CONSTRUCTED_CP(tr, cps + 1); | |
| 1802 | 8314 | available[2] = AFFINE_MVP_CONSTRUCTED_CP(bl, cps + 2); | |
| 1803 |
4/4✓ Branch 0 taken 6374 times.
✓ Branch 1 taken 1940 times.
✓ Branch 2 taken 4833 times.
✓ Branch 3 taken 1541 times.
|
8314 | return available[0] && available[1]; |
| 1804 | } | ||
| 1805 | |||
| 1806 | //8.5.5.7 item 7 | ||
| 1807 | 3700 | static void affine_mvp_const2(const int idx, Mv *cps, const int num_cp) | |
| 1808 | { | ||
| 1809 | 3700 | const Mv mv = cps[idx]; | |
| 1810 |
2/2✓ Branch 0 taken 9166 times.
✓ Branch 1 taken 3700 times.
|
12866 | for (int j = 0; j < num_cp; j++) |
| 1811 | 9166 | cps[j] = mv; | |
| 1812 | 3700 | } | |
| 1813 | |||
| 1814 | //8.5.5.7 Derivation process for luma affine control point motion vector predictors | ||
| 1815 | 12532 | 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 | 12532 | const NeighbourIdx ak[] = { A0, A1 }; | |
| 1820 | 12532 | const NeighbourIdx bk[] = { B0, B1, B2 }; | |
| 1821 | 12532 | const int num_cp = motion_model_idc + 1; | |
| 1822 | NeighbourContext nctx; | ||
| 1823 | int available[MAX_CONTROL_POINTS]; | ||
| 1824 | 12532 | int num_cands = 0; | |
| 1825 | |||
| 1826 | 12532 | init_neighbour_context(&nctx, lc); | |
| 1827 | //Ak | ||
| 1828 |
2/2✓ Branch 1 taken 3049 times.
✓ Branch 2 taken 9483 times.
|
12532 | if (AFFINE_MVP_FROM_NBS(ak)) { |
| 1829 |
2/2✓ Branch 0 taken 2048 times.
✓ Branch 1 taken 1001 times.
|
3049 | if (mvp_lx_flag == num_cands) |
| 1830 | 11773 | return; | |
| 1831 | 1001 | num_cands++; | |
| 1832 | } | ||
| 1833 | //Bk | ||
| 1834 |
2/2✓ Branch 1 taken 2992 times.
✓ Branch 2 taken 7492 times.
|
10484 | if (AFFINE_MVP_FROM_NBS(bk)) { |
| 1835 |
2/2✓ Branch 0 taken 2170 times.
✓ Branch 1 taken 822 times.
|
2992 | if (mvp_lx_flag == num_cands) |
| 1836 | 2170 | return; | |
| 1837 | 822 | num_cands++; | |
| 1838 | } | ||
| 1839 | |||
| 1840 | //Const1 | ||
| 1841 |
2/2✓ Branch 1 taken 4833 times.
✓ Branch 2 taken 3481 times.
|
8314 | if (affine_mvp_const1(&nctx, lx, ref_idx[lx], amvr_shift, cps, available)) { |
| 1842 |
4/4✓ Branch 0 taken 1295 times.
✓ Branch 1 taken 3538 times.
✓ Branch 2 taken 739 times.
✓ Branch 3 taken 556 times.
|
4833 | 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 10753 times.
✓ Branch 1 taken 1663 times.
|
12416 | for (int i = 2; i >= 0; i--) { |
| 1851 |
2/2✓ Branch 0 taken 4278 times.
✓ Branch 1 taken 6475 times.
|
10753 | if (available[i]) { |
| 1852 |
2/2✓ Branch 0 taken 3700 times.
✓ Branch 1 taken 578 times.
|
4278 | if (mvp_lx_flag == num_cands) { |
| 1853 | 3700 | affine_mvp_const2(i, cps, num_cp); | |
| 1854 | 3700 | return; | |
| 1855 | } | ||
| 1856 | 578 | num_cands++; | |
| 1857 | } | ||
| 1858 | } | ||
| 1859 |
2/2✓ Branch 1 taken 1127 times.
✓ Branch 2 taken 536 times.
|
1663 | 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 | 759 | memset(cps, 0, num_cp * sizeof(Mv)); | |
| 1871 | } | ||
| 1872 | |||
| 1873 | 10176 | void ff_vvc_affine_mvp(VVCLocalContext *lc, const int *mvp_lx_flag, const int amvr_shift, MotionInfo *mi) | |
| 1874 | { | ||
| 1875 | 10176 | const CodingUnit *cu = lc->cu; | |
| 1876 | |||
| 1877 | 10176 | mi->num_sb_x = cu->cb_width >> MIN_PU_LOG2; | |
| 1878 | 10176 | mi->num_sb_y = cu->cb_height >> MIN_PU_LOG2; | |
| 1879 | |||
| 1880 | 10176 | ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height); | |
| 1881 |
2/2✓ Branch 0 taken 8979 times.
✓ Branch 1 taken 1197 times.
|
10176 | if (mi->pred_flag != PF_L1) |
| 1882 | 8979 | 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 6623 times.
|
10176 | 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 | 10176 | } | |
| 1886 | |||
| 1887 | //8.5.2.14 Rounding process for motion vectors | ||
| 1888 | 8201712 | void ff_vvc_round_mv(Mv *mv, const int lshift, const int rshift) | |
| 1889 | { | ||
| 1890 |
2/2✓ Branch 0 taken 8160986 times.
✓ Branch 1 taken 40726 times.
|
8201712 | if (rshift) { |
| 1891 | 8160986 | const int offset = 1 << (rshift - 1); | |
| 1892 | 8160986 | mv->x = ((mv->x + offset - (mv->x >= 0)) >> rshift) * (1 << lshift); | |
| 1893 | 8160986 | 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 | 8201712 | } | |
| 1899 | |||
| 1900 | 5593275 | void ff_vvc_clip_mv(Mv *mv) | |
| 1901 | { | ||
| 1902 | 5593275 | mv->x = av_clip(mv->x, -(1 << 17), (1 << 17) - 1); | |
| 1903 | 5593275 | mv->y = av_clip(mv->y, -(1 << 17), (1 << 17) - 1); | |
| 1904 | 5593275 | } | |
| 1905 | |||
| 1906 | //8.5.2.1 Derivation process for motion vector components and reference indices | ||
| 1907 | 368052 | 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 | 368052 | const uint8_t plevel = fc->ps.sps->log2_parallel_merge_level; | |
| 1910 | |||
| 1911 |
2/2✓ Branch 0 taken 357928 times.
✓ Branch 1 taken 10124 times.
|
725980 | return x0_br >> plevel > x0 >> plevel && |
| 1912 |
2/2✓ Branch 0 taken 353156 times.
✓ Branch 1 taken 4772 times.
|
357928 | y0_br >> plevel > y0 >> plevel; |
| 1913 | } | ||
| 1914 | |||
| 1915 | 398927 | 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 1668292 times.
✓ Branch 1 taken 206517 times.
|
1874809 | for (i = 0; i < *num_hmvp; i++) { |
| 1920 |
2/2✓ Branch 1 taken 192410 times.
✓ Branch 2 taken 1475882 times.
|
1668292 | if (compare(mvf, hmvp + i)) { |
| 1921 | 192410 | (*num_hmvp)--; | |
| 1922 | 192410 | break; | |
| 1923 | } | ||
| 1924 | } | ||
| 1925 |
2/2✓ Branch 0 taken 182172 times.
✓ Branch 1 taken 216755 times.
|
398927 | if (i == MAX_NUM_HMVP_CANDS) { |
| 1926 | 182172 | (*num_hmvp)--; | |
| 1927 | 182172 | i = 0; | |
| 1928 | } | ||
| 1929 | |||
| 1930 | 398927 | memmove(hmvp + i, hmvp + i + 1, (*num_hmvp - i) * sizeof(MvField)); | |
| 1931 | 398927 | hmvp[(*num_hmvp)++] = *mvf; | |
| 1932 | 398927 | } | |
| 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 | 435292 | void ff_vvc_update_hmvp(VVCLocalContext *lc, const MotionInfo *mi) | |
| 1942 | { | ||
| 1943 | 435292 | const VVCFrameContext *fc = lc->fc; | |
| 1944 | 435292 | const CodingUnit *cu = lc->cu; | |
| 1945 | 435292 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
| 1946 | 435292 | const MvField *tab_mvf = fc->tab.mvf; | |
| 1947 | 435292 | EntryPoint *ep = lc->ep; | |
| 1948 | |||
| 1949 |
2/2✓ Branch 0 taken 67240 times.
✓ Branch 1 taken 368052 times.
|
435292 | 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 353156 times.
|
368052 | if (!is_greater_mer(fc, cu->x0, cu->y0, cu->x0 + cu->cb_width, cu->y0 + cu->cb_height)) |
| 1955 | 14896 | return; | |
| 1956 | 353156 | update_hmvp(ep->hmvp, &ep->num_hmvp, &TAB_MVF(cu->x0, cu->y0), compare_mv_ref_idx); | |
| 1957 | } | ||
| 1958 | } | ||
| 1959 | |||
| 1960 | 13614955 | MvField* ff_vvc_get_mvf(const VVCFrameContext *fc, const int x0, const int y0) | |
| 1961 | { | ||
| 1962 | 13614955 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
| 1963 | 13614955 | MvField* tab_mvf = fc->tab.mvf; | |
| 1964 | |||
| 1965 | 13614955 | return &TAB_MVF(x0, y0); | |
| 1966 | } | ||
| 1967 |