| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * VVC intra prediction DSP | ||
| 3 | * | ||
| 4 | * Copyright (C) 2021-2023 Nuomi | ||
| 5 | * | ||
| 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 "libavcodec/bit_depth_template.c" | ||
| 24 | |||
| 25 | #include "intra.h" | ||
| 26 | |||
| 27 | #define POS(x, y) src[(x) + stride * (y)] | ||
| 28 | |||
| 29 | 202616 | static av_always_inline void FUNC(cclm_linear_pred)(VVCFrameContext *fc, const int x0, const int y0, | |
| 30 | const int w, const int h, const pixel* pdsy, const int *a, const int *b, const int *k) | ||
| 31 | { | ||
| 32 | 202616 | const VVCSPS *sps = fc->ps.sps; | |
| 33 |
2/2✓ Branch 0 taken 202616 times.
✓ Branch 1 taken 101308 times.
|
607848 | for (int i = 0; i < VVC_MAX_SAMPLE_ARRAYS - 1; i++) { |
| 34 | 405232 | const int c_idx = i + 1; | |
| 35 | 405232 | const int x = x0 >> sps->hshift[c_idx]; | |
| 36 | 405232 | const int y = y0 >> sps->vshift[c_idx]; | |
| 37 | 405232 | const ptrdiff_t stride = fc->frame->linesize[c_idx] / sizeof(pixel); | |
| 38 | 405232 | pixel *src = (pixel*)fc->frame->data[c_idx] + x + y * stride; | |
| 39 |
2/2✓ Branch 0 taken 1960264 times.
✓ Branch 1 taken 202616 times.
|
4325760 | for (int y = 0; y < h; y++) { |
| 40 |
2/2✓ Branch 0 taken 28840160 times.
✓ Branch 1 taken 1960264 times.
|
61600848 | for (int x = 0; x < w; x++) { |
| 41 | 57680320 | const int dsy = pdsy[y * w + x]; | |
| 42 | 57680320 | const int pred = ((dsy * a[i]) >> k[i]) + b[i]; | |
| 43 | 57680320 | POS(x, y) = CLIP(pred); | |
| 44 | } | ||
| 45 | } | ||
| 46 | } | ||
| 47 | 202616 | } | |
| 48 | |||
| 49 | #define MAX_PICK_POS 4 | ||
| 50 | #define TOP 0 | ||
| 51 | #define LEFT 1 | ||
| 52 | |||
| 53 | 1632 | static av_always_inline void FUNC(cclm_get_params_default)(int *a, int *b, int *k) | |
| 54 | { | ||
| 55 |
2/2✓ Branch 0 taken 1632 times.
✓ Branch 1 taken 816 times.
|
4896 | for (int i = 0; i < 2; i++) { |
| 56 | 3264 | a[i] = k[i] = 0; | |
| 57 | 3264 | b[i] = 1 << (BIT_DEPTH - 1); | |
| 58 | } | ||
| 59 | 1632 | } | |
| 60 | |||
| 61 | 202616 | static av_always_inline int FUNC(cclm_get_select_pos)(const VVCLocalContext *lc, | |
| 62 | const int x, const int y, const int w, const int h, const int avail_t, const int avail_l, | ||
| 63 | int cnt[2], int pos[2][MAX_PICK_POS]) | ||
| 64 | { | ||
| 65 | 202616 | const enum IntraPredMode mode = lc->cu->intra_pred_mode_c; | |
| 66 |
6/6✓ Branch 0 taken 97921 times.
✓ Branch 1 taken 3387 times.
✓ Branch 2 taken 95258 times.
✓ Branch 3 taken 2663 times.
✓ Branch 4 taken 42383 times.
✓ Branch 5 taken 52875 times.
|
202616 | const int num_is4 = !avail_t || !avail_l || mode != INTRA_LT_CCLM; |
| 67 | int num_samp[2]; | ||
| 68 | |||
| 69 |
2/2✓ Branch 0 taken 56994 times.
✓ Branch 1 taken 44314 times.
|
202616 | if (mode == INTRA_LT_CCLM) { |
| 70 |
2/2✓ Branch 0 taken 54500 times.
✓ Branch 1 taken 2494 times.
|
113988 | num_samp[TOP] = avail_t ? w : 0; |
| 71 |
2/2✓ Branch 0 taken 55369 times.
✓ Branch 1 taken 1625 times.
|
113988 | num_samp[LEFT] = avail_l ? h : 0; |
| 72 | } else { | ||
| 73 |
4/4✓ Branch 0 taken 43421 times.
✓ Branch 1 taken 893 times.
✓ Branch 2 taken 22977 times.
✓ Branch 3 taken 20444 times.
|
88628 | num_samp[TOP] = (avail_t && mode == INTRA_T_CCLM) ? ff_vvc_get_top_available(lc, x, y, w + FFMIN(w, h), 1) : 0; |
| 74 |
4/4✓ Branch 0 taken 43276 times.
✓ Branch 1 taken 1038 times.
✓ Branch 2 taken 20521 times.
✓ Branch 3 taken 22755 times.
|
88628 | num_samp[LEFT] = (avail_l && mode == INTRA_L_CCLM) ? ff_vvc_get_left_available(lc, x, y, h + FFMIN(w, h), 1) : 0; |
| 75 | } | ||
| 76 |
4/4✓ Branch 0 taken 23831 times.
✓ Branch 1 taken 77477 times.
✓ Branch 2 taken 816 times.
✓ Branch 3 taken 23015 times.
|
202616 | if (!num_samp[TOP] && !num_samp[LEFT]) { |
| 77 | 1632 | return 0; | |
| 78 | } | ||
| 79 |
2/2✓ Branch 0 taken 200984 times.
✓ Branch 1 taken 100492 times.
|
602952 | for (int i = TOP; i <= LEFT; i++) { |
| 80 | 401968 | const int start = num_samp[i] >> (2 + num_is4); | |
| 81 | 401968 | const int step = FFMAX(1, num_samp[i] >> (1 + num_is4)) ; | |
| 82 | 401968 | cnt[i] = FFMIN(num_samp[i], (1 + num_is4) << 1); | |
| 83 |
2/2✓ Branch 0 taken 400574 times.
✓ Branch 1 taken 200984 times.
|
1203116 | for (int c = 0; c < cnt[i]; c++) |
| 84 | 801148 | pos[i][c] = start + c * step; | |
| 85 | } | ||
| 86 | 200984 | return 1; | |
| 87 | } | ||
| 88 | |||
| 89 | 52040 | static av_always_inline void FUNC(cclm_select_luma_444)(const pixel *src, const int step, | |
| 90 | const int cnt, const int pos[MAX_PICK_POS], pixel *sel_luma) | ||
| 91 | { | ||
| 92 |
2/2✓ Branch 0 taken 52040 times.
✓ Branch 1 taken 26020 times.
|
156120 | for (int i = 0; i < cnt; i++) |
| 93 | 104080 | sel_luma[i] = src[pos[i] * step]; | |
| 94 | 52040 | } | |
| 95 | |||
| 96 | 200984 | static av_always_inline void FUNC(cclm_select_luma)(const VVCFrameContext *fc, | |
| 97 | const int x0, const int y0, const int avail_t, const int avail_l, const int cnt[2], const int pos[2][MAX_PICK_POS], | ||
| 98 | pixel *sel_luma) | ||
| 99 | { | ||
| 100 | 200984 | const VVCSPS *sps = fc->ps.sps; | |
| 101 | |||
| 102 | 200984 | const int b_ctu_boundary = !av_zero_extend(y0, sps->ctb_log2_size_y); | |
| 103 | 200984 | const int hs = sps->hshift[1]; | |
| 104 | 200984 | const int vs = sps->vshift[1]; | |
| 105 | 200984 | const ptrdiff_t stride = fc->frame->linesize[0] / sizeof(pixel); | |
| 106 | |||
| 107 |
3/4✓ Branch 0 taken 13010 times.
✓ Branch 1 taken 87482 times.
✓ Branch 2 taken 13010 times.
✗ Branch 3 not taken.
|
227004 | if (!hs && !vs) { |
| 108 | 26020 | const pixel* src = (pixel*)fc->frame->data[0] + x0 + y0 * stride; | |
| 109 | 26020 | FUNC(cclm_select_luma_444)(src - avail_t * stride, 1, cnt[TOP], pos[TOP], sel_luma); | |
| 110 | 26020 | FUNC(cclm_select_luma_444)(src - avail_l, stride, cnt[LEFT], pos[LEFT], sel_luma + cnt[TOP]); | |
| 111 | } else { | ||
| 112 | // top | ||
| 113 |
4/4✓ Branch 0 taken 79555 times.
✓ Branch 1 taken 7927 times.
✓ Branch 2 taken 67948 times.
✓ Branch 3 taken 11607 times.
|
310860 | if (vs && !b_ctu_boundary) { |
| 114 | 135896 | const pixel *source = (pixel *)fc->frame->data[0] + x0 + (y0 - 2) * stride; | |
| 115 |
2/2✓ Branch 0 taken 142024 times.
✓ Branch 1 taken 67948 times.
|
419944 | for (int i = 0; i < cnt[TOP]; i++) { |
| 116 | 284048 | const int x = pos[TOP][i] << hs; | |
| 117 | 284048 | const pixel *src = source + x; | |
| 118 |
4/4✓ Branch 0 taken 2703 times.
✓ Branch 1 taken 139321 times.
✓ Branch 2 taken 2456 times.
✓ Branch 3 taken 247 times.
|
284048 | const int has_left = x || avail_l; |
| 119 |
2/2✓ Branch 0 taken 141777 times.
✓ Branch 1 taken 247 times.
|
284048 | const pixel l = has_left ? POS(-1, 0) : POS(0, 0); |
| 120 |
2/2✓ Branch 0 taken 4240 times.
✓ Branch 1 taken 137784 times.
|
284048 | if (sps->r->sps_chroma_vertical_collocated_flag) { |
| 121 | 8480 | sel_luma[i] = (POS(0, -1) + l + 4 * POS(0, 0) + POS(1, 0) + POS(0, 1) + 4) >> 3; | |
| 122 | } else { | ||
| 123 |
2/2✓ Branch 0 taken 137537 times.
✓ Branch 1 taken 247 times.
|
275568 | const pixel l1 = has_left ? POS(-1, 1) : POS(0, 1); |
| 124 | 275568 | sel_luma[i] = (l + l1 + 2 * (POS(0, 0) + POS(0, 1)) + POS(1, 0) + POS(1, 1) + 4) >> 3; | |
| 125 | } | ||
| 126 | } | ||
| 127 | } else { | ||
| 128 | 39068 | const pixel *source = (pixel*)fc->frame->data[0] + x0 + (y0 - 1) * stride; | |
| 129 |
2/2✓ Branch 0 taken 35452 times.
✓ Branch 1 taken 19534 times.
|
109972 | for (int i = 0; i < cnt[TOP]; i++) { |
| 130 | 70904 | const int x = pos[TOP][i] << hs; | |
| 131 | 70904 | const pixel *src = source + x; | |
| 132 |
4/4✓ Branch 0 taken 653 times.
✓ Branch 1 taken 34799 times.
✓ Branch 2 taken 608 times.
✓ Branch 3 taken 45 times.
|
70904 | const int has_left = x || avail_l; |
| 133 |
2/2✓ Branch 0 taken 35407 times.
✓ Branch 1 taken 45 times.
|
70904 | const pixel l = has_left ? POS(-1, 0) : POS(0, 0); |
| 134 | 70904 | sel_luma[i] = (l + 2 * POS(0, 0) + POS(1, 0) + 2) >> 2; | |
| 135 | } | ||
| 136 | } | ||
| 137 | |||
| 138 | // left | ||
| 139 | { | ||
| 140 | const pixel *left; | ||
| 141 | 174964 | const pixel *source = (pixel *)fc->frame->data[0] + x0 + y0 * stride - (1 + hs) * avail_l; | |
| 142 | 174964 | left = source - avail_l; | |
| 143 | |||
| 144 |
2/2✓ Branch 0 taken 171058 times.
✓ Branch 1 taken 87482 times.
|
517080 | for (int i = 0; i < cnt[LEFT]; i++) { |
| 145 | 342116 | const int y = pos[LEFT][i] << vs; | |
| 146 | 342116 | const int offset = y * stride; | |
| 147 | 342116 | const pixel *l = left + offset; | |
| 148 | 342116 | const pixel *src = source + offset; | |
| 149 | pixel pred; | ||
| 150 |
2/2✓ Branch 0 taken 14282 times.
✓ Branch 1 taken 156776 times.
|
342116 | if (!vs) { |
| 151 | 28564 | pred = (*l + 2 * POS(0, 0) + POS(1, 0) + 2) >> 2; | |
| 152 | } else { | ||
| 153 |
2/2✓ Branch 0 taken 6058 times.
✓ Branch 1 taken 150718 times.
|
313552 | if (sps->r->sps_chroma_vertical_collocated_flag) { |
| 154 |
3/4✓ Branch 0 taken 94 times.
✓ Branch 1 taken 5964 times.
✓ Branch 2 taken 94 times.
✗ Branch 3 not taken.
|
12116 | const int has_top = y || avail_t; |
| 155 |
1/2✓ Branch 0 taken 6058 times.
✗ Branch 1 not taken.
|
12116 | const pixel t = has_top ? POS(0, -1) : POS(0, 0); |
| 156 | 12116 | pred = (*l + t + 4 * POS(0, 0) + POS(1, 0) + POS(0, 1) + 4) >> 3; | |
| 157 | } else { | ||
| 158 | 301436 | pred = (*l + *(l + stride) + 2 * POS(0, 0) + 2 * POS(0, 1) + POS(1, 0) + POS(1, 1) + 4) >> 3; | |
| 159 | } | ||
| 160 | } | ||
| 161 | 342116 | sel_luma[i + cnt[TOP]] = pred; | |
| 162 | } | ||
| 163 | } | ||
| 164 | } | ||
| 165 | 200984 | } | |
| 166 | |||
| 167 | 200984 | static av_always_inline void FUNC(cclm_select_chroma)(const VVCFrameContext *fc, | |
| 168 | const int x, const int y, const int cnt[2], const int pos[2][MAX_PICK_POS], | ||
| 169 | pixel sel[][MAX_PICK_POS * 2]) | ||
| 170 | { | ||
| 171 |
2/2✓ Branch 0 taken 200984 times.
✓ Branch 1 taken 100492 times.
|
602952 | for (int c_idx = 1; c_idx < VVC_MAX_SAMPLE_ARRAYS; c_idx++) { |
| 172 | 401968 | const ptrdiff_t stride = fc->frame->linesize[c_idx] / sizeof(pixel); | |
| 173 | |||
| 174 | //top | ||
| 175 | 401968 | const pixel *src = (pixel*)fc->frame->data[c_idx] + x + (y - 1)* stride; | |
| 176 |
2/2✓ Branch 0 taken 408316 times.
✓ Branch 1 taken 200984 times.
|
1218600 | for (int i = 0; i < cnt[TOP]; i++) { |
| 177 | 816632 | sel[c_idx][i] = src[pos[TOP][i]]; | |
| 178 | } | ||
| 179 | |||
| 180 | //left | ||
| 181 | 401968 | src = (pixel*)fc->frame->data[c_idx] + x - 1 + y * stride; | |
| 182 |
2/2✓ Branch 0 taken 392832 times.
✓ Branch 1 taken 200984 times.
|
1187632 | for (int i = 0; i < cnt[LEFT]; i++) { |
| 183 | 785664 | sel[c_idx][i + cnt[TOP]] = src[pos[LEFT][i] * stride]; | |
| 184 | } | ||
| 185 | } | ||
| 186 | 200984 | } | |
| 187 | |||
| 188 | 202616 | static av_always_inline int FUNC(cclm_select_samples)(const VVCLocalContext *lc, | |
| 189 | const int x0, const int y0, const int w, const int h, const int avail_t, const int avail_l, | ||
| 190 | pixel sel[][MAX_PICK_POS * 2]) | ||
| 191 | { | ||
| 192 | 202616 | const VVCFrameContext *fc = lc->fc; | |
| 193 | 202616 | const VVCSPS *sps = fc->ps.sps; | |
| 194 | 202616 | const int x = x0 >> sps->hshift[1]; | |
| 195 | 202616 | const int y = y0 >> sps->vshift[1]; | |
| 196 | int cnt[2], pos[2][MAX_PICK_POS]; | ||
| 197 | |||
| 198 |
2/2✓ Branch 1 taken 816 times.
✓ Branch 2 taken 100492 times.
|
202616 | if (!FUNC(cclm_get_select_pos)(lc, x, y, w, h, avail_t, avail_l, cnt, pos)) |
| 199 | 1632 | return 0; | |
| 200 | |||
| 201 | 200984 | FUNC(cclm_select_luma)(fc, x0, y0, avail_t, avail_l, cnt, pos, sel[LUMA]); | |
| 202 | 200984 | FUNC(cclm_select_chroma)(fc, x, y, cnt, pos, sel); | |
| 203 | |||
| 204 |
2/2✓ Branch 0 taken 697 times.
✓ Branch 1 taken 99795 times.
|
200984 | if (cnt[TOP] + cnt[LEFT] == 2) { |
| 205 |
2/2✓ Branch 0 taken 2091 times.
✓ Branch 1 taken 697 times.
|
5576 | for (int c_idx = 0; c_idx < VVC_MAX_SAMPLE_ARRAYS; c_idx++) { |
| 206 | 4182 | sel[c_idx][3] = sel[c_idx][0]; | |
| 207 | 4182 | sel[c_idx][2] = sel[c_idx][1]; | |
| 208 | 4182 | sel[c_idx][0] = sel[c_idx][1]; | |
| 209 | 4182 | sel[c_idx][1] = sel[c_idx][3]; | |
| 210 | } | ||
| 211 | } | ||
| 212 | 200984 | return 1; | |
| 213 | } | ||
| 214 | |||
| 215 | 200984 | static av_always_inline void FUNC(cclm_get_min_max)( | |
| 216 | const pixel sel[][MAX_PICK_POS * 2], int *min, int *max) | ||
| 217 | { | ||
| 218 | 200984 | int min_grp_idx[] = { 0, 2 }; | |
| 219 | 200984 | int max_grp_idx[] = { 1, 3 }; | |
| 220 | |||
| 221 |
2/2✓ Branch 0 taken 46411 times.
✓ Branch 1 taken 54081 times.
|
200984 | if (sel[LUMA][min_grp_idx[0]] > sel[LUMA][min_grp_idx[1]]) |
| 222 | 92822 | FFSWAP(int, min_grp_idx[0], min_grp_idx[1]); | |
| 223 |
2/2✓ Branch 0 taken 46983 times.
✓ Branch 1 taken 53509 times.
|
200984 | if (sel[LUMA][max_grp_idx[0]] > sel[LUMA][max_grp_idx[1]]) |
| 224 | 93966 | FFSWAP(int, max_grp_idx[0], max_grp_idx[1]); | |
| 225 |
2/2✓ Branch 0 taken 9441 times.
✓ Branch 1 taken 91051 times.
|
200984 | if (sel[LUMA][min_grp_idx[0]] > sel[LUMA][max_grp_idx[1]]) { |
| 226 | 18882 | FFSWAP(int, min_grp_idx[0], max_grp_idx[0]); | |
| 227 | 18882 | FFSWAP(int, min_grp_idx[1], max_grp_idx[1]); | |
| 228 | } | ||
| 229 |
2/2✓ Branch 0 taken 73841 times.
✓ Branch 1 taken 26651 times.
|
200984 | if (sel[LUMA][min_grp_idx[1]] > sel[LUMA][max_grp_idx[0]]) |
| 230 | 147682 | FFSWAP(int, min_grp_idx[1], max_grp_idx[0]); | |
| 231 |
2/2✓ Branch 0 taken 301476 times.
✓ Branch 1 taken 100492 times.
|
803936 | for (int c_idx = 0; c_idx < VVC_MAX_SAMPLE_ARRAYS; c_idx++) { |
| 232 | 602952 | max[c_idx] = (sel[c_idx][max_grp_idx[0]] + sel[c_idx][max_grp_idx[1]] + 1) >> 1; | |
| 233 | 602952 | min[c_idx] = (sel[c_idx][min_grp_idx[0]] + sel[c_idx][min_grp_idx[1]] + 1) >> 1; | |
| 234 | } | ||
| 235 | 200984 | } | |
| 236 | |||
| 237 | 202616 | static av_always_inline void FUNC(cclm_get_params)(const VVCLocalContext *lc, | |
| 238 | const int x0, const int y0, const int w, const int h, const int avail_t, const int avail_l, | ||
| 239 | int *a, int *b, int *k) | ||
| 240 | { | ||
| 241 | pixel sel[VVC_MAX_SAMPLE_ARRAYS][MAX_PICK_POS * 2]; | ||
| 242 | int max[VVC_MAX_SAMPLE_ARRAYS], min[VVC_MAX_SAMPLE_ARRAYS]; | ||
| 243 | int diff; | ||
| 244 | |||
| 245 |
2/2✓ Branch 1 taken 816 times.
✓ Branch 2 taken 100492 times.
|
202616 | if (!FUNC(cclm_select_samples)(lc, x0, y0, w, h, avail_t, avail_l, sel)) { |
| 246 | 1632 | FUNC(cclm_get_params_default)(a, b, k); | |
| 247 | 13950 | return; | |
| 248 | } | ||
| 249 | |||
| 250 | 200984 | FUNC(cclm_get_min_max)(sel, min, max); | |
| 251 | |||
| 252 | 200984 | diff = max[LUMA] - min[LUMA]; | |
| 253 |
2/2✓ Branch 0 taken 6159 times.
✓ Branch 1 taken 94333 times.
|
200984 | if (diff == 0) { |
| 254 |
2/2✓ Branch 0 taken 12318 times.
✓ Branch 1 taken 6159 times.
|
36954 | for (int i = 0; i < 2; i++) { |
| 255 | 24636 | a[i] = k[i] = 0; | |
| 256 | 24636 | b[i] = min[i + 1]; | |
| 257 | } | ||
| 258 | 12318 | return; | |
| 259 | } | ||
| 260 |
2/2✓ Branch 0 taken 188666 times.
✓ Branch 1 taken 94333 times.
|
565998 | for (int i = 0; i < 2; i++) { |
| 261 | const static int div_sig_table[] = {0, 7, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 1, 1, 0}; | ||
| 262 | 377332 | const int diffc = max[i + 1] - min[i + 1]; | |
| 263 | 377332 | int x = av_log2(diff); | |
| 264 | int y, v, sign, add; | ||
| 265 | 377332 | const int norm_diff = ((diff << 4) >> x) & 15; | |
| 266 | 377332 | x += (norm_diff) ? 1 : 0; | |
| 267 |
2/2✓ Branch 0 taken 168701 times.
✓ Branch 1 taken 19965 times.
|
377332 | y = abs(diffc) > 0 ? av_log2(abs(diffc)) + 1 : 0; |
| 268 | 377332 | v = div_sig_table[norm_diff] | 8; | |
| 269 | 377332 | add = (1 << y >> 1); | |
| 270 | 377332 | a[i] = (diffc * v + add) >> y; | |
| 271 | 377332 | k[i] = FFMAX(1, 3 + x -y); | |
| 272 |
2/2✓ Branch 0 taken 83688 times.
✓ Branch 1 taken 104978 times.
|
377332 | sign = a[i] < 0 ? -1 : (a[i] > 0); |
| 273 |
2/2✓ Branch 0 taken 1731 times.
✓ Branch 1 taken 186935 times.
|
377332 | a[i] = ((3 + x - y) < 1) ? sign * 15 : a[i]; |
| 274 | 377332 | b[i] = min[i + 1] - ((a[i] * min[0]) >> k[i]); | |
| 275 | } | ||
| 276 | |||
| 277 | } | ||
| 278 | |||
| 279 | #undef TOP | ||
| 280 | #undef LEFT | ||
| 281 | |||
| 282 | 202616 | static av_always_inline void FUNC(cclm_get_luma_rec_pixels)(const VVCFrameContext *fc, | |
| 283 | const int x0, const int y0, const int w, const int h, const int avail_t, const int avail_l, | ||
| 284 | pixel *pdsy) | ||
| 285 | { | ||
| 286 | 202616 | const int hs = fc->ps.sps->hshift[1]; | |
| 287 | 202616 | const int vs = fc->ps.sps->vshift[1]; | |
| 288 | 202616 | const ptrdiff_t stride = fc->frame->linesize[0] / sizeof(pixel); | |
| 289 | 202616 | const pixel *source = (pixel*)fc->frame->data[0] + x0 + y0 * stride; | |
| 290 | 202616 | const pixel *left = source - avail_l; | |
| 291 | 202616 | const pixel *top = source - avail_t * stride; | |
| 292 | |||
| 293 | 202616 | const VVCSPS *sps = fc->ps.sps; | |
| 294 |
3/4✓ Branch 0 taken 13013 times.
✓ Branch 1 taken 88295 times.
✓ Branch 2 taken 13013 times.
✗ Branch 3 not taken.
|
202616 | if (!hs && !vs) { |
| 295 |
2/2✓ Branch 0 taken 179928 times.
✓ Branch 1 taken 13013 times.
|
385882 | for (int i = 0; i < h; i++) |
| 296 | 359856 | memcpy(pdsy + i * w, source + i * stride, w * sizeof(pixel)); | |
| 297 | 26026 | return; | |
| 298 | } | ||
| 299 |
2/2✓ Branch 0 taken 800204 times.
✓ Branch 1 taken 88295 times.
|
1776998 | for (int i = 0; i < h; i++) { |
| 300 | 1600408 | const pixel *src = source; | |
| 301 | 1600408 | const pixel *l = left; | |
| 302 | 1600408 | const pixel *t = top; | |
| 303 |
2/2✓ Branch 0 taken 93912 times.
✓ Branch 1 taken 706292 times.
|
1600408 | if (!vs) { |
| 304 |
2/2✓ Branch 0 taken 657504 times.
✓ Branch 1 taken 93912 times.
|
1502832 | for (int j = 0; j < w; j++) { |
| 305 | 1315008 | pixel pred = (*l + 2 * POS(0, 0) + POS(1, 0) + 2) >> 2; | |
| 306 | 1315008 | pdsy[i * w + j] = pred; | |
| 307 | 1315008 | src += 2; | |
| 308 | 1315008 | l = src - 1; | |
| 309 | } | ||
| 310 | |||
| 311 | } else { | ||
| 312 |
2/2✓ Branch 0 taken 54676 times.
✓ Branch 1 taken 651616 times.
|
1412584 | if (sps->r->sps_chroma_vertical_collocated_flag) { |
| 313 |
2/2✓ Branch 0 taken 1396000 times.
✓ Branch 1 taken 54676 times.
|
2901352 | for (int j = 0; j < w; j++) { |
| 314 | 2792000 | pixel pred = (*l + *t + 4 * POS(0, 0) + POS(1, 0) + POS(0, 1) + 4) >> 3; | |
| 315 | 2792000 | pdsy[i * w + j] = pred; | |
| 316 | 2792000 | src += 2; | |
| 317 | 2792000 | t += 2; | |
| 318 | 2792000 | l = src - 1; | |
| 319 | } | ||
| 320 | } else { | ||
| 321 |
2/2✓ Branch 0 taken 8911872 times.
✓ Branch 1 taken 651616 times.
|
19126976 | for (int j = 0; j < w; j++) { |
| 322 | 17823744 | pixel pred = (*l + *(l + stride) + 2 * POS(0, 0) + 2 * POS(0, 1) + POS(1, 0) + POS(1, 1) + 4) >> 3; | |
| 323 | |||
| 324 | 17823744 | pdsy[i * w + j] = pred; | |
| 325 | 17823744 | src += 2; | |
| 326 | 17823744 | l = src - 1; | |
| 327 | } | ||
| 328 | } | ||
| 329 | } | ||
| 330 | 1600408 | source += (stride << vs); | |
| 331 | 1600408 | left += (stride << vs); | |
| 332 | 1600408 | top = source - stride; | |
| 333 | } | ||
| 334 | } | ||
| 335 | |||
| 336 | 582 | static av_always_inline void FUNC(cclm_pred_default)(VVCFrameContext *fc, | |
| 337 | const int x, const int y, const int w, const int h, const int avail_t, const int avail_l) | ||
| 338 | { | ||
| 339 |
2/2✓ Branch 0 taken 582 times.
✓ Branch 1 taken 291 times.
|
1746 | for (int c_idx = 1; c_idx < VVC_MAX_SAMPLE_ARRAYS; c_idx++) { |
| 340 | 1164 | const ptrdiff_t stride = fc->frame->linesize[c_idx] / sizeof(pixel); | |
| 341 | 1164 | pixel *dst = (pixel*)fc->frame->data[c_idx] + x + y * stride; | |
| 342 |
2/2✓ Branch 0 taken 10432 times.
✓ Branch 1 taken 582 times.
|
22028 | for (int i = 0; i < h; i++) { |
| 343 |
2/2✓ Branch 0 taken 268096 times.
✓ Branch 1 taken 10432 times.
|
557056 | for (int j = 0; j < w; j++) { |
| 344 | 536192 | dst[j] = 1 << (BIT_DEPTH - 1); | |
| 345 | } | ||
| 346 | 20864 | dst += stride; | |
| 347 | } | ||
| 348 | } | ||
| 349 | 582 | } | |
| 350 | |||
| 351 | //8.4.5.2.14 Specification of INTRA_LT_CCLM, INTRA_L_CCLM and INTRA_T_CCLM intra prediction mode | ||
| 352 | 203198 | static void FUNC(intra_cclm_pred)(const VVCLocalContext *lc, const int x0, const int y0, | |
| 353 | const int width, const int height) | ||
| 354 | { | ||
| 355 | 203198 | VVCFrameContext *fc = lc->fc; | |
| 356 | 203198 | const VVCSPS *sps = fc->ps.sps; | |
| 357 | 203198 | const int avail_t = ff_vvc_get_top_available(lc, x0, y0, 1, 0); | |
| 358 | 203198 | const int avail_l = ff_vvc_get_left_available(lc, x0, y0, 1, 0); | |
| 359 | 203198 | const int hs = sps->hshift[1]; | |
| 360 | 203198 | const int vs = sps->vshift[1]; | |
| 361 | 203198 | const int x = x0 >> hs; | |
| 362 | 203198 | const int y = y0 >> vs; | |
| 363 | 203198 | const int w = width >> hs; | |
| 364 | 203198 | const int h = height >> vs; | |
| 365 | int a[2], b[2], k[2]; | ||
| 366 | |||
| 367 | pixel dsy[MAX_TB_SIZE * MAX_TB_SIZE]; | ||
| 368 |
4/4✓ Branch 0 taken 3678 times.
✓ Branch 1 taken 97921 times.
✓ Branch 2 taken 291 times.
✓ Branch 3 taken 3387 times.
|
203198 | if (!avail_t && !avail_l) { |
| 369 | 582 | FUNC(cclm_pred_default)(fc, x, y, w, h, avail_t, avail_l); | |
| 370 | 582 | return; | |
| 371 | } | ||
| 372 | 202616 | FUNC(cclm_get_luma_rec_pixels)(fc, x0, y0, w, h, avail_t, avail_l, dsy); | |
| 373 | 202616 | FUNC(cclm_get_params) (lc, x0, y0, w, h, avail_t, avail_l, a, b, k); | |
| 374 | 202616 | FUNC(cclm_linear_pred)(fc, x0, y0, w, h, dsy, a, b, k); | |
| 375 | } | ||
| 376 | |||
| 377 | 43518 | static int FUNC(lmcs_sum_samples)(const pixel *start, ptrdiff_t stride, const int avail, const int target_size) | |
| 378 | { | ||
| 379 | 43518 | const int size = FFMIN(avail, target_size); | |
| 380 | 43518 | int sum = 0; | |
| 381 |
2/2✓ Branch 0 taken 1368440 times.
✓ Branch 1 taken 21759 times.
|
2780398 | for (int i = 0; i < size; i++) { |
| 382 | 2736880 | sum += *start; | |
| 383 | 2736880 | start += stride; | |
| 384 | } | ||
| 385 | 43518 | sum += *(start - stride) * (target_size - size); | |
| 386 | 43518 | return sum; | |
| 387 | } | ||
| 388 | |||
| 389 | // 8.7.5.3 Picture reconstruction with luma dependent chroma residual scaling process for chroma samples | ||
| 390 | 315532 | static int FUNC(lmcs_derive_chroma_scale)(VVCLocalContext *lc, const int x0, const int y0) | |
| 391 | { | ||
| 392 | 315532 | VVCFrameContext *fc = lc->fc; | |
| 393 | 315532 | const VVCLMCS *lmcs = &fc->ps.lmcs; | |
| 394 | 315532 | const int size_y = FFMIN(fc->ps.sps->ctb_size_y, 64); | |
| 395 | |||
| 396 | 315532 | const int x = x0 & ~(size_y - 1); | |
| 397 | 315532 | const int y = y0 & ~(size_y - 1); | |
| 398 |
4/4✓ Branch 0 taken 146229 times.
✓ Branch 1 taken 11537 times.
✓ Branch 2 taken 930 times.
✓ Branch 3 taken 145299 times.
|
315532 | if (lc->lmcs.x_vpdu != x || lc->lmcs.y_vpdu != y) { |
| 399 | 24934 | int cnt = 0, luma = 0, i; | |
| 400 | 24934 | const pixel *src = (const pixel *)(fc->frame->data[LUMA] + y * fc->frame->linesize[LUMA] + (x << fc->ps.sps->pixel_shift)); | |
| 401 | 24934 | const ptrdiff_t stride = fc->frame->linesize[LUMA] / sizeof(pixel); | |
| 402 | 24934 | const int avail_t = ff_vvc_get_top_available (lc, x, y, 1, 0); | |
| 403 | 24934 | const int avail_l = ff_vvc_get_left_available(lc, x, y, 1, 0); | |
| 404 |
2/2✓ Branch 0 taken 11112 times.
✓ Branch 1 taken 1355 times.
|
24934 | if (avail_l) { |
| 405 | 22224 | luma += FUNC(lmcs_sum_samples)(src - 1, stride, fc->ps.pps->height - y, size_y); | |
| 406 | 22224 | cnt = size_y; | |
| 407 | } | ||
| 408 |
2/2✓ Branch 0 taken 10647 times.
✓ Branch 1 taken 1820 times.
|
24934 | if (avail_t) { |
| 409 | 21294 | luma += FUNC(lmcs_sum_samples)(src - stride, 1, fc->ps.pps->width - x, size_y); | |
| 410 | 21294 | cnt += size_y; | |
| 411 | } | ||
| 412 |
2/2✓ Branch 0 taken 12127 times.
✓ Branch 1 taken 340 times.
|
24934 | if (cnt) |
| 413 | 24254 | luma = (luma + (cnt >> 1)) >> av_log2(cnt); | |
| 414 | else | ||
| 415 | 680 | luma = 1 << (BIT_DEPTH - 1); | |
| 416 | |||
| 417 |
2/2✓ Branch 0 taken 81442 times.
✓ Branch 1 taken 466 times.
|
163816 | for (i = lmcs->min_bin_idx; i <= lmcs->max_bin_idx; i++) { |
| 418 |
2/2✓ Branch 0 taken 12001 times.
✓ Branch 1 taken 69441 times.
|
162884 | if (luma < lmcs->pivot[i + 1]) |
| 419 | 24002 | break; | |
| 420 | } | ||
| 421 | 24934 | i = FFMIN(i, LMCS_MAX_BIN_SIZE - 1); | |
| 422 | |||
| 423 | 24934 | lc->lmcs.chroma_scale = lmcs->chroma_scale_coeff[i]; | |
| 424 | 24934 | lc->lmcs.x_vpdu = x; | |
| 425 | 24934 | lc->lmcs.y_vpdu = y; | |
| 426 | } | ||
| 427 | 315532 | return lc->lmcs.chroma_scale; | |
| 428 | } | ||
| 429 | |||
| 430 | // 8.7.5.3 Picture reconstruction with luma dependent chroma residual scaling process for chroma samples | ||
| 431 | 315532 | static void FUNC(lmcs_scale_chroma)(VVCLocalContext *lc, int *coeff, | |
| 432 | const int width, const int height, const int x0_cu, const int y0_cu) | ||
| 433 | { | ||
| 434 | 315532 | const int chroma_scale = FUNC(lmcs_derive_chroma_scale)(lc, x0_cu, y0_cu); | |
| 435 | |||
| 436 |
2/2✓ Branch 0 taken 1659712 times.
✓ Branch 1 taken 157766 times.
|
3634956 | for (int y = 0; y < height; y++) { |
| 437 |
2/2✓ Branch 0 taken 25263528 times.
✓ Branch 1 taken 1659712 times.
|
53846480 | for (int x = 0; x < width; x++) { |
| 438 | 50527056 | const int c = av_clip_intp2(*coeff, BIT_DEPTH); | |
| 439 | |||
| 440 |
2/2✓ Branch 0 taken 11317251 times.
✓ Branch 1 taken 13946277 times.
|
50527056 | if (c > 0) |
| 441 | 22634502 | *coeff = (c * chroma_scale + (1 << 10)) >> 11; | |
| 442 | else | ||
| 443 | 27892554 | *coeff = -((-c * chroma_scale + (1 << 10)) >> 11); | |
| 444 | 50527056 | coeff++; | |
| 445 | } | ||
| 446 | } | ||
| 447 | 315532 | } | |
| 448 | |||
| 449 | 239758 | static av_always_inline void FUNC(ref_filter)(const pixel *left, const pixel *top, | |
| 450 | pixel *filtered_left, pixel *filtered_top, const int left_size, const int top_size, | ||
| 451 | const int unfilter_last_one) | ||
| 452 | { | ||
| 453 | 239758 | filtered_left[-1] = filtered_top[-1] = (left[0] + 2 * left[-1] + top[0] + 2 ) >> 2; | |
| 454 |
2/2✓ Branch 0 taken 1999979 times.
✓ Branch 1 taken 119879 times.
|
4239716 | for (int i = 0; i < left_size - unfilter_last_one; i++) { |
| 455 | 3999958 | filtered_left[i] = (left[i- 1] + 2 * left[i] + left[i + 1] + 2) >> 2; | |
| 456 | } | ||
| 457 |
2/2✓ Branch 0 taken 2320875 times.
✓ Branch 1 taken 119879 times.
|
4881508 | for (int i = 0; i < top_size - unfilter_last_one; i++) { |
| 458 | 4641750 | filtered_top[i] = (top[i-1] + 2 * top[i] + top[i + 1] + 2) >> 2; | |
| 459 | } | ||
| 460 |
2/2✓ Branch 0 taken 5449 times.
✓ Branch 1 taken 114430 times.
|
239758 | if (unfilter_last_one) { |
| 461 | 10898 | filtered_top[top_size - 1] = top[top_size - 1]; | |
| 462 | 10898 | filtered_left[left_size - 1] = left[left_size - 1]; | |
| 463 | } | ||
| 464 | 239758 | } | |
| 465 | |||
| 466 | 2278186 | static av_always_inline void FUNC(prepare_intra_edge_params)(const VVCLocalContext *lc, | |
| 467 | IntraEdgeParams* edge, const pixel *src, const ptrdiff_t stride, | ||
| 468 | const int x, int y, int w, int h, int c_idx, const int is_intra_mip, | ||
| 469 | const int mode, const int ref_idx, const int need_pdpc) | ||
| 470 | { | ||
| 471 | #define EXTEND(ptr, val, len) \ | ||
| 472 | do { \ | ||
| 473 | for (i = 0; i < (len); i++) \ | ||
| 474 | *(ptr + i) = val; \ | ||
| 475 | } while (0) | ||
| 476 | 2278186 | const CodingUnit *cu = lc->cu; | |
| 477 |
2/2✓ Branch 0 taken 1025442 times.
✓ Branch 1 taken 113651 times.
|
2278186 | const int ref_filter_flag = is_intra_mip ? 0 : ff_vvc_ref_filter_flag_derive(mode); |
| 478 |
4/4✓ Branch 0 taken 566427 times.
✓ Branch 1 taken 527386 times.
✓ Branch 2 taken 388223 times.
✓ Branch 3 taken 178204 times.
|
2187626 | const int filter_flag = !ref_idx && w * h > 32 && !c_idx && |
| 479 |
6/6✓ Branch 0 taken 1093813 times.
✓ Branch 1 taken 45280 times.
✓ Branch 2 taken 331335 times.
✓ Branch 3 taken 56888 times.
✓ Branch 4 taken 119879 times.
✓ Branch 5 taken 211456 times.
|
4465812 | cu->isp_split_type == ISP_NO_SPLIT && ref_filter_flag; |
| 480 | 2278186 | int cand_up_left = lc->na.cand_up_left; | |
| 481 | 2278186 | pixel *left = (pixel*)edge->left_array + MAX_TB_SIZE + 3; | |
| 482 | 2278186 | pixel *top = (pixel*)edge->top_array + MAX_TB_SIZE + 3; | |
| 483 | 2278186 | pixel *filtered_left = (pixel*)edge->filtered_left_array + MAX_TB_SIZE + 3; | |
| 484 | 2278186 | pixel *filtered_top = (pixel*)edge->filtered_top_array + MAX_TB_SIZE + 3; | |
| 485 | 2278186 | const int ref_line = ref_idx == 3 ? -4 : (-1 - ref_idx); | |
| 486 | int left_size, top_size, unfilter_left_size, unfilter_top_size; | ||
| 487 | int left_available, top_available; | ||
| 488 | int refw, refh; | ||
| 489 | int intra_pred_angle, inv_angle; | ||
| 490 | int i; | ||
| 491 | |||
| 492 |
4/4✓ Branch 0 taken 1025442 times.
✓ Branch 1 taken 113651 times.
✓ Branch 2 taken 371636 times.
✓ Branch 3 taken 653806 times.
|
2278186 | if (is_intra_mip || mode == INTRA_PLANAR) { |
| 493 | 970574 | left_size = h + 1; | |
| 494 | 970574 | top_size = w + 1; | |
| 495 | 970574 | unfilter_left_size = left_size + filter_flag; | |
| 496 | 970574 | unfilter_top_size = top_size + filter_flag; | |
| 497 |
2/2✓ Branch 0 taken 76730 times.
✓ Branch 1 taken 577076 times.
|
1307612 | } else if (mode == INTRA_DC) { |
| 498 | 153460 | unfilter_left_size = left_size = h; | |
| 499 | 153460 | unfilter_top_size = top_size = w; | |
| 500 |
2/2✓ Branch 0 taken 86599 times.
✓ Branch 1 taken 490477 times.
|
1154152 | } else if (mode == INTRA_VERT) { |
| 501 | //we may need 1 pixel to predict the top left. | ||
| 502 |
2/2✓ Branch 0 taken 66744 times.
✓ Branch 1 taken 19855 times.
|
173198 | unfilter_left_size = left_size = need_pdpc ? h : 1; |
| 503 | 173198 | unfilter_top_size = top_size = w; | |
| 504 |
2/2✓ Branch 0 taken 87594 times.
✓ Branch 1 taken 402883 times.
|
980954 | } else if (mode == INTRA_HORZ) { |
| 505 | 175188 | unfilter_left_size = left_size = h; | |
| 506 | //even need_pdpc == 0, we may need 1 pixel to predict the top left. | ||
| 507 |
2/2✓ Branch 0 taken 64222 times.
✓ Branch 1 taken 23372 times.
|
175188 | unfilter_top_size = top_size = need_pdpc ? w : 1; |
| 508 | } else { | ||
| 509 |
4/4✓ Branch 0 taken 92584 times.
✓ Branch 1 taken 310299 times.
✓ Branch 2 taken 3012 times.
✓ Branch 3 taken 89572 times.
|
805766 | if (cu->isp_split_type == ISP_NO_SPLIT || c_idx) { |
| 510 | 626622 | refw = w * 2; | |
| 511 | 626622 | refh = h * 2; | |
| 512 | } else { | ||
| 513 | 179144 | refw = cu->cb_width + w; | |
| 514 | 179144 | refh = cu->cb_height + h; | |
| 515 | } | ||
| 516 | 805766 | intra_pred_angle = ff_vvc_intra_pred_angle_derive(mode); | |
| 517 | 805766 | inv_angle = ff_vvc_intra_inv_angle_derive(intra_pred_angle); | |
| 518 | 805766 | unfilter_top_size = top_size = refw; | |
| 519 | 805766 | unfilter_left_size = left_size = refh; | |
| 520 | } | ||
| 521 | |||
| 522 | 2278186 | left_available = ff_vvc_get_left_available(lc, x, y, unfilter_left_size, c_idx); | |
| 523 |
2/2✓ Branch 0 taken 11729372 times.
✓ Branch 1 taken 1139093 times.
|
25736930 | for (i = 0; i < left_available; i++) |
| 524 | 23458744 | left[i] = POS(ref_line, i); | |
| 525 | |||
| 526 | 2278186 | top_available = ff_vvc_get_top_available(lc, x, y, unfilter_top_size, c_idx); | |
| 527 | 2278186 | memcpy(top, src + ref_line * stride, top_available * sizeof(pixel)); | |
| 528 | |||
| 529 |
2/2✓ Branch 0 taken 1211163 times.
✓ Branch 1 taken 1139093 times.
|
4700512 | for (int i = -1; i >= ref_line; i--) { |
| 530 |
2/2✓ Branch 0 taken 1158883 times.
✓ Branch 1 taken 52280 times.
|
2422326 | if (cand_up_left) { |
| 531 | 2317766 | left[i] = POS(ref_line, i); | |
| 532 | 2317766 | top[i] = POS(i, ref_line); | |
| 533 |
2/2✓ Branch 0 taken 24071 times.
✓ Branch 1 taken 28209 times.
|
104560 | } else if (left_available) { |
| 534 | 48142 | left[i] = top[i] = left[0]; | |
| 535 |
2/2✓ Branch 0 taken 27175 times.
✓ Branch 1 taken 1034 times.
|
56418 | } else if (top_available) { |
| 536 | 54350 | left[i] = top[i] = top[0]; | |
| 537 | } else { | ||
| 538 | 2068 | left[i] = top[i] = 1 << (BIT_DEPTH - 1); | |
| 539 | } | ||
| 540 | } | ||
| 541 | |||
| 542 |
2/2✓ Branch 0 taken 3647959 times.
✓ Branch 1 taken 1139093 times.
|
9574104 | EXTEND(top + top_available, top[top_available-1], unfilter_top_size - top_available); |
| 543 |
2/2✓ Branch 0 taken 2809088 times.
✓ Branch 1 taken 1139093 times.
|
7896362 | EXTEND(left + left_available, left[left_available-1], unfilter_left_size - left_available); |
| 544 | |||
| 545 |
2/2✓ Branch 0 taken 399232 times.
✓ Branch 1 taken 739861 times.
|
2278186 | if (ref_filter_flag) { |
| 546 |
8/8✓ Branch 0 taken 398275 times.
✓ Branch 1 taken 957 times.
✓ Branch 2 taken 221817 times.
✓ Branch 3 taken 176458 times.
✓ Branch 4 taken 146899 times.
✓ Branch 5 taken 74918 times.
✓ Branch 6 taken 119879 times.
✓ Branch 7 taken 27020 times.
|
798464 | if (!ref_idx && w * h > 32 && !c_idx && cu->isp_split_type == ISP_NO_SPLIT ) { |
| 547 | 239758 | const int unfilter_last_one = left_size == unfilter_left_size; | |
| 548 | 239758 | FUNC(ref_filter)(left, top, filtered_left, filtered_top, unfilter_left_size, unfilter_top_size, unfilter_last_one); | |
| 549 | 239758 | left = filtered_left; | |
| 550 | 239758 | top = filtered_top; | |
| 551 | } | ||
| 552 | } | ||
| 553 |
6/6✓ Branch 0 taken 1025442 times.
✓ Branch 1 taken 113651 times.
✓ Branch 2 taken 653806 times.
✓ Branch 3 taken 371636 times.
✓ Branch 4 taken 577076 times.
✓ Branch 5 taken 76730 times.
|
2278186 | if (!is_intra_mip && mode != INTRA_PLANAR && mode != INTRA_DC) { |
| 554 |
6/6✓ Branch 0 taken 549480 times.
✓ Branch 1 taken 27596 times.
✓ Branch 2 taken 511248 times.
✓ Branch 3 taken 38232 times.
✓ Branch 4 taken 112443 times.
✓ Branch 5 taken 398805 times.
|
1154152 | if (ref_filter_flag || ref_idx || cu->isp_split_type != ISP_NO_SPLIT) { |
| 555 | 356542 | edge->filter_flag = 0; | |
| 556 | } else { | ||
| 557 | 797610 | const int min_dist_ver_hor = FFMIN(abs(mode - 50), abs(mode - 18)); | |
| 558 | 797610 | const int intra_hor_ver_dist_thres[] = {24, 14, 2, 0, 0}; | |
| 559 | 797610 | const int ntbs = (av_log2(w) + av_log2(h)) >> 1; | |
| 560 | 797610 | edge->filter_flag = min_dist_ver_hor > intra_hor_ver_dist_thres[ntbs - 2]; | |
| 561 | } | ||
| 562 | |||
| 563 |
4/4✓ Branch 0 taken 490477 times.
✓ Branch 1 taken 86599 times.
✓ Branch 2 taken 402883 times.
✓ Branch 3 taken 87594 times.
|
1154152 | if (mode != INTRA_VERT && mode != INTRA_HORZ) { |
| 564 |
2/2✓ Branch 0 taken 210828 times.
✓ Branch 1 taken 192055 times.
|
805766 | if (mode >= INTRA_DIAG) { |
| 565 |
2/2✓ Branch 0 taken 107473 times.
✓ Branch 1 taken 103355 times.
|
421656 | if (intra_pred_angle < 0) { |
| 566 | 214946 | pixel *p = top - (ref_idx + 1); | |
| 567 |
2/2✓ Branch 0 taken 875624 times.
✓ Branch 1 taken 107473 times.
|
1966194 | for (int x = -h; x < 0; x++) { |
| 568 | 1751248 | const int idx = -1 - ref_idx + FFMIN((x*inv_angle + 256) >> 9, h); | |
| 569 | 1751248 | p[x] = left[idx]; | |
| 570 | } | ||
| 571 | } else { | ||
| 572 |
2/2✓ Branch 0 taken 225281 times.
✓ Branch 1 taken 103355 times.
|
657272 | for (int i = refw; i <= refw + FFMAX(1, w/h) * ref_idx + 1; i++) |
| 573 | 450562 | top[i] = top[refw - 1]; | |
| 574 | } | ||
| 575 | } else { | ||
| 576 |
2/2✓ Branch 0 taken 99692 times.
✓ Branch 1 taken 92363 times.
|
384110 | if (intra_pred_angle < 0) { |
| 577 | 199384 | pixel *p = left - (ref_idx + 1); | |
| 578 |
2/2✓ Branch 0 taken 1461044 times.
✓ Branch 1 taken 99692 times.
|
3121472 | for (int x = -w; x < 0; x++) { |
| 579 | 2922088 | const int idx = -1 - ref_idx + FFMIN((x*inv_angle + 256) >> 9, w); | |
| 580 | 2922088 | p[x] = top[idx]; | |
| 581 | } | ||
| 582 | } else { | ||
| 583 |
2/2✓ Branch 0 taken 201466 times.
✓ Branch 1 taken 92363 times.
|
587658 | for (int i = refh; i <= refh + FFMAX(1, h/w) * ref_idx + 1; i++) |
| 584 | 402932 | left[i] = left[refh - 1]; | |
| 585 | } | ||
| 586 | } | ||
| 587 | } | ||
| 588 | } | ||
| 589 | 2278186 | edge->left = (uint8_t*)left; | |
| 590 | 2278186 | edge->top = (uint8_t*)top; | |
| 591 | 2278186 | } | |
| 592 | |||
| 593 | //8.4.1 General decoding process for coding units coded in intra prediction mode | ||
| 594 | 2278186 | static void FUNC(intra_pred)(const VVCLocalContext *lc, int x0, int y0, | |
| 595 | const int width, const int height, int c_idx) | ||
| 596 | { | ||
| 597 | 2278186 | VVCFrameContext *fc = lc->fc; | |
| 598 | 2278186 | const VVCSPS *sps = fc->ps.sps; | |
| 599 | 2278186 | const VVCPPS *pps = fc->ps.pps; | |
| 600 | 2278186 | const CodingUnit *cu = lc->cu; | |
| 601 | 2278186 | const int log2_min_cb_size = sps->min_cb_log2_size_y; | |
| 602 | 2278186 | const int min_cb_width = pps->min_cb_width; | |
| 603 | 2278186 | const int x_cb = x0 >> log2_min_cb_size; | |
| 604 | 2278186 | const int y_cb = y0 >> log2_min_cb_size; | |
| 605 | |||
| 606 | 2278186 | const int hshift = fc->ps.sps->hshift[c_idx]; | |
| 607 | 2278186 | const int vshift = fc->ps.sps->vshift[c_idx]; | |
| 608 | 2278186 | const int x = x0 >> hshift; | |
| 609 | 2278186 | const int y = y0 >> vshift; | |
| 610 | 2278186 | const int w = width >> hshift; | |
| 611 | 2278186 | const int h = height >> vshift; | |
| 612 | 2278186 | const ptrdiff_t stride = fc->frame->linesize[c_idx] / sizeof(pixel); | |
| 613 | |||
| 614 |
2/2✓ Branch 0 taken 352736 times.
✓ Branch 1 taken 786357 times.
|
2278186 | const int pred_mode = c_idx ? cu->intra_pred_mode_c : cu->intra_pred_mode_y; |
| 615 | 2278186 | const int mode = ff_vvc_wide_angle_mode_mapping(cu, w, h, c_idx, pred_mode); | |
| 616 | |||
| 617 | 2278186 | const int intra_mip_flag = SAMPLE_CTB(fc->tab.imf, x_cb, y_cb); | |
| 618 |
6/6✓ Branch 0 taken 168305 times.
✓ Branch 1 taken 970788 times.
✓ Branch 2 taken 56290 times.
✓ Branch 3 taken 112015 times.
✓ Branch 4 taken 1636 times.
✓ Branch 5 taken 54654 times.
|
2278186 | const int is_intra_mip = intra_mip_flag && (!c_idx || cu->mip_chroma_direct_flag); |
| 619 |
2/2✓ Branch 0 taken 786357 times.
✓ Branch 1 taken 352736 times.
|
2278186 | const int ref_idx = c_idx ? 0 : cu->intra_luma_ref_idx; |
| 620 | 2278186 | const int need_pdpc = ff_vvc_need_pdpc(w, h, cu->bdpcm_flag[c_idx], mode, ref_idx); | |
| 621 | |||
| 622 | |||
| 623 | 2278186 | pixel *src = (pixel*)fc->frame->data[c_idx] + x + y * stride; | |
| 624 | IntraEdgeParams edge; | ||
| 625 | |||
| 626 | 2278186 | FUNC(prepare_intra_edge_params)(lc, &edge, src, stride, x, y, w, h, c_idx, is_intra_mip, mode, ref_idx, need_pdpc); | |
| 627 | |||
| 628 |
2/2✓ Branch 0 taken 113651 times.
✓ Branch 1 taken 1025442 times.
|
2278186 | if (is_intra_mip) { |
| 629 | int intra_mip_transposed_flag; | ||
| 630 | int intra_mip_mode; | ||
| 631 | 227302 | unpack_mip_info(&intra_mip_transposed_flag, &intra_mip_mode, intra_mip_flag); | |
| 632 | |||
| 633 | 227302 | fc->vvcdsp.intra.pred_mip((uint8_t *)src, edge.top, edge.left, | |
| 634 | w, h, stride, intra_mip_mode, intra_mip_transposed_flag); | ||
| 635 |
2/2✓ Branch 0 taken 371636 times.
✓ Branch 1 taken 653806 times.
|
2050884 | } else if (mode == INTRA_PLANAR) { |
| 636 | 743272 | fc->vvcdsp.intra.pred_planar((uint8_t *)src, edge.top, edge.left, w, h, stride); | |
| 637 |
2/2✓ Branch 0 taken 76730 times.
✓ Branch 1 taken 577076 times.
|
1307612 | } else if (mode == INTRA_DC) { |
| 638 | 153460 | fc->vvcdsp.intra.pred_dc((uint8_t *)src, edge.top, edge.left, w, h, stride); | |
| 639 |
2/2✓ Branch 0 taken 86599 times.
✓ Branch 1 taken 490477 times.
|
1154152 | } else if (mode == INTRA_VERT) { |
| 640 | 173198 | fc->vvcdsp.intra.pred_v((uint8_t *)src, edge.top, w, h, stride); | |
| 641 |
2/2✓ Branch 0 taken 87594 times.
✓ Branch 1 taken 402883 times.
|
980954 | } else if (mode == INTRA_HORZ) { |
| 642 | 175188 | fc->vvcdsp.intra.pred_h((uint8_t *)src, edge.left, w, h, stride); | |
| 643 | } else { | ||
| 644 |
2/2✓ Branch 0 taken 210828 times.
✓ Branch 1 taken 192055 times.
|
805766 | if (mode >= INTRA_DIAG) { |
| 645 | 421656 | fc->vvcdsp.intra.pred_angular_v((uint8_t *)src, edge.top, edge.left, | |
| 646 | w, h, stride, c_idx, mode, ref_idx, | ||
| 647 | edge.filter_flag, need_pdpc); | ||
| 648 | } else { | ||
| 649 | 384110 | fc->vvcdsp.intra.pred_angular_h((uint8_t *)src, edge.top, edge.left, | |
| 650 | w, h, stride, c_idx, mode, ref_idx, | ||
| 651 | edge.filter_flag, need_pdpc); | ||
| 652 | } | ||
| 653 | } | ||
| 654 |
2/2✓ Branch 0 taken 707981 times.
✓ Branch 1 taken 431112 times.
|
2278186 | if (need_pdpc) { |
| 655 | //8.4.5.2.15 Position-dependent intra prediction sample filtering process | ||
| 656 |
8/8✓ Branch 0 taken 612759 times.
✓ Branch 1 taken 95222 times.
✓ Branch 2 taken 277701 times.
✓ Branch 3 taken 335058 times.
✓ Branch 4 taken 213060 times.
✓ Branch 5 taken 64641 times.
✓ Branch 6 taken 146316 times.
✓ Branch 7 taken 66744 times.
|
1415962 | if (!is_intra_mip && (mode == INTRA_PLANAR || mode == INTRA_DC || |
| 657 |
2/2✓ Branch 0 taken 64222 times.
✓ Branch 1 taken 82094 times.
|
292632 | mode == INTRA_VERT || mode == INTRA_HORZ)) { |
| 658 | 1061330 | const int scale = (av_log2(w) + av_log2(h) - 2) >> 2; | |
| 659 | 1061330 | const pixel *left = (pixel*)edge.left; | |
| 660 | 1061330 | const pixel *top = (pixel*)edge.top; | |
| 661 |
2/2✓ Branch 0 taken 5655028 times.
✓ Branch 1 taken 530665 times.
|
12371386 | for (int y = 0; y < h; y++) { |
| 662 |
2/2✓ Branch 0 taken 91357200 times.
✓ Branch 1 taken 5655028 times.
|
194024456 | for (int x = 0; x < w; x++) { |
| 663 | int l, t, wl, wt, pred; | ||
| 664 | pixel val; | ||
| 665 |
4/4✓ Branch 0 taken 30800256 times.
✓ Branch 1 taken 60556944 times.
✓ Branch 2 taken 10351840 times.
✓ Branch 3 taken 20448416 times.
|
182714400 | if (mode == INTRA_PLANAR || mode == INTRA_DC) { |
| 666 | 141817568 | l = left[y]; | |
| 667 | 141817568 | t = top[x]; | |
| 668 | 141817568 | wl = 32 >> FFMIN((x << 1) >> scale, 31); | |
| 669 | 141817568 | wt = 32 >> FFMIN((y << 1) >> scale, 31); | |
| 670 | } else { | ||
| 671 | 40896832 | l = left[y] - left[-1] + POS(x,y); | |
| 672 | 40896832 | t = top[x] - top[-1] + POS(x,y); | |
| 673 |
2/2✓ Branch 0 taken 9110448 times.
✓ Branch 1 taken 11337968 times.
|
40896832 | wl = (mode == INTRA_VERT) ? (32 >> FFMIN((x << 1) >> scale, 31)) : 0; |
| 674 |
2/2✓ Branch 0 taken 11337968 times.
✓ Branch 1 taken 9110448 times.
|
40896832 | wt = (mode == INTRA_HORZ) ? (32 >> FFMIN((y << 1) >> scale, 31)) : 0; |
| 675 | } | ||
| 676 | 182714400 | val = POS(x, y); | |
| 677 | 182714400 | pred = val + ((wl * (l - val) + wt * (t - val) + 32) >> 6); | |
| 678 | 182714400 | POS(x, y) = CLIP(pred); | |
| 679 | } | ||
| 680 | } | ||
| 681 | } | ||
| 682 | } | ||
| 683 | 2278186 | } | |
| 684 | |||
| 685 | //8.4.5.2.11 Specification of INTRA_PLANAR intra prediction mode | ||
| 686 | 743272 | static av_always_inline void FUNC(pred_planar)(uint8_t *_src, const uint8_t *_top, | |
| 687 | const uint8_t *_left, const int w, const int h, const ptrdiff_t stride) | ||
| 688 | { | ||
| 689 | int x, y; | ||
| 690 | 743272 | pixel *src = (pixel *)_src; | |
| 691 | 743272 | const pixel *top = (const pixel *)_top; | |
| 692 | 743272 | const pixel *left = (const pixel *)_left; | |
| 693 | 743272 | const int logw = av_log2(w); | |
| 694 | 743272 | const int logh = av_log2(h); | |
| 695 | 743272 | const int size = w * h; | |
| 696 | 743272 | const int shift = (logw + logh + 1); | |
| 697 |
2/2✓ Branch 0 taken 3663996 times.
✓ Branch 1 taken 371636 times.
|
8071264 | for (y = 0; y < h; y++) { |
| 698 |
2/2✓ Branch 0 taken 61480144 times.
✓ Branch 1 taken 3663996 times.
|
130288280 | for (x = 0; x < w; x++) { |
| 699 | 122960288 | const int pred_v = ((h - 1 - y) * top[x] + (y + 1) * left[h]) << logw; | |
| 700 | 122960288 | const int pred_h = ((w - 1 - x) * left[y] + (x + 1) * top[w]) << logh; | |
| 701 | 122960288 | const int pred = (pred_v + pred_h + size) >> shift; | |
| 702 | 122960288 | POS(x, y) = pred; | |
| 703 | } | ||
| 704 | } | ||
| 705 | 743272 | } | |
| 706 | |||
| 707 | //8.4.5.2.3 MIP boundary sample downsampling process | ||
| 708 | 454604 | static av_always_inline void FUNC(mip_downsampling)(int *reduced, const int boundary_size, | |
| 709 | const pixel *ref, const int n_tb_s) | ||
| 710 | { | ||
| 711 | 454604 | const int b_dwn = n_tb_s / boundary_size; | |
| 712 | 454604 | const int log2 = av_log2(b_dwn); | |
| 713 | |||
| 714 |
2/2✓ Branch 0 taken 41094 times.
✓ Branch 1 taken 186208 times.
|
454604 | if (boundary_size == n_tb_s) { |
| 715 |
2/2✓ Branch 0 taken 164376 times.
✓ Branch 1 taken 41094 times.
|
410940 | for (int i = 0; i < n_tb_s; i++) |
| 716 | 328752 | reduced[i] = ref[i]; | |
| 717 | 82188 | return; | |
| 718 | } | ||
| 719 |
2/2✓ Branch 0 taken 678744 times.
✓ Branch 1 taken 186208 times.
|
1729904 | for (int i = 0; i < boundary_size; i++) { |
| 720 | int r; | ||
| 721 | 1357488 | r = *ref++; | |
| 722 |
2/2✓ Branch 0 taken 1897216 times.
✓ Branch 1 taken 678744 times.
|
5151920 | for (int j = 1; j < b_dwn; j++) |
| 723 | 3794432 | r += *ref++; | |
| 724 | 1357488 | reduced[i] = (r + (1 << (log2 - 1))) >> log2; | |
| 725 | } | ||
| 726 | } | ||
| 727 | |||
| 728 | 227302 | static av_always_inline void FUNC(mip_reduced_pred)(pixel *src, const ptrdiff_t stride, | |
| 729 | const int up_hor, const int up_ver, const int pred_size, const int *reduced, const int reduced_size, | ||
| 730 | const int ow, const int temp0, const uint8_t *matrix, int is_transposed) | ||
| 731 | { | ||
| 732 | 227302 | src = &POS(up_hor - 1, up_ver - 1); | |
| 733 |
2/2✓ Branch 0 taken 634908 times.
✓ Branch 1 taken 113651 times.
|
1497118 | for (int y = 0; y < pred_size; y++) { |
| 734 |
2/2✓ Branch 0 taken 3982064 times.
✓ Branch 1 taken 634908 times.
|
9233944 | for (int x = 0; x < pred_size; x++) { |
| 735 | 7964128 | int pred = 0; | |
| 736 |
2/2✓ Branch 0 taken 27914240 times.
✓ Branch 1 taken 3982064 times.
|
63792608 | for (int i = 0; i < reduced_size; i++) |
| 737 | 55828480 | pred += reduced[i] * matrix[i]; | |
| 738 | 7964128 | matrix += reduced_size; | |
| 739 | 7964128 | pred = ((pred + ow) >> 6) + temp0; | |
| 740 | 7964128 | pred = av_clip(pred, 0, (1<<BIT_DEPTH) - 1); | |
| 741 |
2/2✓ Branch 0 taken 2004240 times.
✓ Branch 1 taken 1977824 times.
|
7964128 | if (is_transposed) |
| 742 | 4008480 | POS(y * up_hor, x * up_ver) = pred; | |
| 743 | else | ||
| 744 | 3955648 | POS(x * up_hor, y * up_ver) = pred; | |
| 745 | } | ||
| 746 | } | ||
| 747 | 227302 | } | |
| 748 | |||
| 749 | 258818 | static av_always_inline void FUNC(mip_upsampling_1d)(pixel *dst, const int dst_step, const int dst_stride, const int dst_height, const int factor, | |
| 750 | const pixel *boundary, const int boundary_step, const int pred_size) | ||
| 751 | { | ||
| 752 | |||
| 753 |
2/2✓ Branch 0 taken 1230636 times.
✓ Branch 1 taken 129409 times.
|
2720090 | for (int i = 0; i < dst_height; i++) { |
| 754 | 2461272 | const pixel *before = boundary; | |
| 755 | 2461272 | const pixel *after = dst - dst_step; | |
| 756 | 2461272 | pixel *d = dst; | |
| 757 |
2/2✓ Branch 0 taken 8661552 times.
✓ Branch 1 taken 1230636 times.
|
19784376 | for (int j = 0; j < pred_size; j++) { |
| 758 | 17323104 | after += dst_step * factor; | |
| 759 |
2/2✓ Branch 0 taken 18351088 times.
✓ Branch 1 taken 8661552 times.
|
54025280 | for (int k = 1; k < factor; k++) { |
| 760 | 36702176 | int mid = (factor - k) * (*before) + k * (*after); | |
| 761 | 36702176 | *d = (mid + factor / 2) / factor; | |
| 762 | 36702176 | d += dst_step; | |
| 763 | } | ||
| 764 | 17323104 | before = after; | |
| 765 | 17323104 | d += dst_step; | |
| 766 | } | ||
| 767 | 2461272 | boundary += boundary_step; | |
| 768 | 2461272 | dst += dst_stride; | |
| 769 | } | ||
| 770 | 258818 | } | |
| 771 | |||
| 772 | //8.4.5.2.2 Matrix-based intra sample prediction | ||
| 773 | 227302 | static av_always_inline void FUNC(pred_mip)(uint8_t *_src, const uint8_t *_top, | |
| 774 | const uint8_t *_left, const int w, const int h, const ptrdiff_t stride, | ||
| 775 | int mode_id, int is_transposed) | ||
| 776 | { | ||
| 777 | 227302 | pixel *src = (pixel *)_src; | |
| 778 | 227302 | const pixel *top = (const pixel *)_top; | |
| 779 | 227302 | const pixel *left = (const pixel *)_left; | |
| 780 | |||
| 781 | 227302 | const int size_id = ff_vvc_get_mip_size_id(w, h); | |
| 782 | static const int boundary_sizes[] = {2, 4, 4}; | ||
| 783 | static const int pred_sizes[] = {4, 4, 8}; | ||
| 784 | 227302 | const int boundary_size = boundary_sizes[size_id]; | |
| 785 | 227302 | const int pred_size = pred_sizes[size_id]; | |
| 786 | 227302 | const int in_size = 2 * boundary_size - ((size_id == 2) ? 1 : 0); | |
| 787 | 227302 | const uint8_t *matrix = ff_vvc_get_mip_matrix(size_id, mode_id); | |
| 788 | 227302 | const int up_hor = w / pred_size; | |
| 789 | 227302 | const int up_ver = h / pred_size; | |
| 790 | |||
| 791 | int reduced[16]; | ||
| 792 | 227302 | int *red_t = reduced; | |
| 793 | 227302 | int *red_l = reduced + boundary_size; | |
| 794 | 227302 | int off = 1, ow = 0; | |
| 795 | int temp0; | ||
| 796 | |||
| 797 |
2/2✓ Branch 0 taken 57975 times.
✓ Branch 1 taken 55676 times.
|
227302 | if (is_transposed) { |
| 798 | 115950 | FFSWAP(int*, red_t, red_l); | |
| 799 | } | ||
| 800 | 227302 | FUNC(mip_downsampling)(red_t, boundary_size, top, w); | |
| 801 | 227302 | FUNC(mip_downsampling)(red_l, boundary_size, left, h); | |
| 802 | |||
| 803 | 227302 | temp0 = reduced[0]; | |
| 804 |
2/2✓ Branch 0 taken 68575 times.
✓ Branch 1 taken 45076 times.
|
227302 | if (size_id != 2) { |
| 805 | 137150 | off = 0; | |
| 806 | 137150 | ow = (1 << (BIT_DEPTH - 1)) - temp0; | |
| 807 | } else { | ||
| 808 | 90152 | ow = reduced[1] - temp0; | |
| 809 | } | ||
| 810 | 227302 | reduced[0] = ow; | |
| 811 |
2/2✓ Branch 0 taken 684393 times.
✓ Branch 1 taken 113651 times.
|
1596088 | for (int i = 1; i < in_size; i++) { |
| 812 | 1368786 | reduced[i] = reduced[i + off] - temp0; | |
| 813 | 1368786 | ow += reduced[i]; | |
| 814 | } | ||
| 815 | 227302 | ow = 32 - 32 * ow; | |
| 816 | |||
| 817 | 227302 | FUNC(mip_reduced_pred)(src, stride, up_hor, up_ver, pred_size, reduced, in_size, ow, temp0, matrix, is_transposed); | |
| 818 |
4/4✓ Branch 0 taken 40694 times.
✓ Branch 1 taken 72957 times.
✓ Branch 2 taken 24172 times.
✓ Branch 3 taken 16522 times.
|
227302 | if (up_hor > 1 || up_ver > 1) { |
| 819 |
2/2✓ Branch 0 taken 72957 times.
✓ Branch 1 taken 24172 times.
|
194258 | if (up_hor > 1) |
| 820 | 145914 | FUNC(mip_upsampling_1d)(&POS(0, up_ver - 1), 1, up_ver * stride, pred_size, up_hor, left + up_ver - 1, up_ver, pred_size); | |
| 821 |
2/2✓ Branch 0 taken 56452 times.
✓ Branch 1 taken 40677 times.
|
194258 | if (up_ver > 1) |
| 822 | 112904 | FUNC(mip_upsampling_1d)(src, stride, 1, w, up_ver, top, 1, pred_size); | |
| 823 | } | ||
| 824 | 227302 | } | |
| 825 | |||
| 826 | 153460 | static av_always_inline pixel FUNC(pred_dc_val)(const pixel *top, const pixel *left, | |
| 827 | const int w, const int h) | ||
| 828 | { | ||
| 829 | pixel dc_val; | ||
| 830 | 153460 | int sum = 0; | |
| 831 |
2/2✓ Branch 0 taken 26570 times.
✓ Branch 1 taken 50160 times.
|
153460 | unsigned int offset = (w == h) ? (w << 1) : FFMAX(w, h); |
| 832 | 153460 | const int shift = av_log2(offset); | |
| 833 | 153460 | offset >>= 1; | |
| 834 |
2/2✓ Branch 0 taken 58110 times.
✓ Branch 1 taken 18620 times.
|
153460 | if (w >= h) { |
| 835 |
2/2✓ Branch 0 taken 808496 times.
✓ Branch 1 taken 58110 times.
|
1733212 | for (int i = 0; i < w; i++) |
| 836 | 1616992 | sum += top[i]; | |
| 837 | } | ||
| 838 |
2/2✓ Branch 0 taken 45190 times.
✓ Branch 1 taken 31540 times.
|
153460 | if (w <= h) { |
| 839 |
2/2✓ Branch 0 taken 539672 times.
✓ Branch 1 taken 45190 times.
|
1169724 | for (int i = 0; i < h; i++) |
| 840 | 1079344 | sum += left[i]; | |
| 841 | } | ||
| 842 | 153460 | dc_val = (sum + offset) >> shift; | |
| 843 | 153460 | return dc_val; | |
| 844 | } | ||
| 845 | |||
| 846 | //8.4.5.2.12 Specification of INTRA_DC intra prediction mode | ||
| 847 | 153460 | static av_always_inline void FUNC(pred_dc)(uint8_t *_src, const uint8_t *_top, | |
| 848 | const uint8_t *_left, const int w, const int h, const ptrdiff_t stride) | ||
| 849 | { | ||
| 850 | int x, y; | ||
| 851 | 153460 | pixel *src = (pixel *)_src; | |
| 852 | 153460 | const pixel *top = (const pixel *)_top; | |
| 853 | 153460 | const pixel *left = (const pixel *)_left; | |
| 854 | 153460 | const pixel dc = FUNC(pred_dc_val)(top, left, w, h); | |
| 855 | 153460 | const pixel4 a = PIXEL_SPLAT_X4(dc); | |
| 856 |
2/2✓ Branch 0 taken 712008 times.
✓ Branch 1 taken 76730 times.
|
1577476 | for (y = 0; y < h; y++) { |
| 857 | 1424016 | pixel *s = src; | |
| 858 |
2/2✓ Branch 0 taken 2817672 times.
✓ Branch 1 taken 712008 times.
|
7059360 | for (x = 0; x < w; x += 4) { |
| 859 | 5635344 | AV_WN4P(s, a); | |
| 860 | 5635344 | s += 4; | |
| 861 | } | ||
| 862 | 1424016 | src += stride; | |
| 863 | } | ||
| 864 | 153460 | } | |
| 865 | |||
| 866 | 173198 | static av_always_inline void FUNC(pred_v)(uint8_t *_src, const uint8_t *_top, | |
| 867 | const int w, const int h, const ptrdiff_t stride) | ||
| 868 | { | ||
| 869 | 173198 | pixel *src = (pixel *)_src; | |
| 870 | 173198 | const pixel *top = (const pixel *)_top; | |
| 871 |
2/2✓ Branch 0 taken 912552 times.
✓ Branch 1 taken 86599 times.
|
1998302 | for (int y = 0; y < h; y++) { |
| 872 | 1825104 | memcpy(src, top, sizeof(pixel) * w); | |
| 873 | 1825104 | src += stride; | |
| 874 | } | ||
| 875 | 173198 | } | |
| 876 | |||
| 877 | 175188 | static void FUNC(pred_h)(uint8_t *_src, const uint8_t *_left, const int w, const int h, | |
| 878 | const ptrdiff_t stride) | ||
| 879 | { | ||
| 880 | 175188 | pixel *src = (pixel *)_src; | |
| 881 | 175188 | const pixel *left = (const pixel *)_left; | |
| 882 |
2/2✓ Branch 0 taken 827780 times.
✓ Branch 1 taken 87594 times.
|
1830748 | for (int y = 0; y < h; y++) { |
| 883 | 1655560 | const pixel4 a = PIXEL_SPLAT_X4(left[y]); | |
| 884 |
2/2✓ Branch 0 taken 3421868 times.
✓ Branch 1 taken 827780 times.
|
8499296 | for (int x = 0; x < w; x += 4) { |
| 885 | 6843736 | AV_WN4P(&POS(x, y), a); | |
| 886 | } | ||
| 887 | } | ||
| 888 | 175188 | } | |
| 889 | |||
| 890 | #define INTRA_LUMA_FILTER(p) CLIP((p[0] * f[0] + p[1] * f[1] + p[2] * f[2] + p[3] * f[3] + 32) >> 6) | ||
| 891 | #define INTRA_CHROMA_FILTER(p) (((32 - fact) * p[1] + fact * p[2] + 16) >> 5) | ||
| 892 | |||
| 893 | //8.4.5.2.13 Specification of INTRA_ANGULAR2..INTRA_ANGULAR66 intra prediction modes | ||
| 894 | 421656 | static void FUNC(pred_angular_v)(uint8_t *_src, const uint8_t *_top, const uint8_t *_left, | |
| 895 | const int w, const int h, const ptrdiff_t stride, const int c_idx, const int mode, | ||
| 896 | const int ref_idx, const int filter_flag, const int need_pdpc) | ||
| 897 | { | ||
| 898 | 421656 | pixel *src = (pixel *)_src; | |
| 899 | 421656 | const pixel *left = (const pixel *)_left; | |
| 900 | 421656 | const pixel *top = (const pixel *)_top - (1 + ref_idx); | |
| 901 | 421656 | const int intra_pred_angle = ff_vvc_intra_pred_angle_derive(mode); | |
| 902 | 421656 | int pos = (1 + ref_idx) * intra_pred_angle; | |
| 903 | 421656 | const int dp = intra_pred_angle; | |
| 904 | 421656 | const int is_luma = !c_idx; | |
| 905 | int nscale, inv_angle; | ||
| 906 | |||
| 907 |
2/2✓ Branch 0 taken 44528 times.
✓ Branch 1 taken 166300 times.
|
421656 | if (need_pdpc) { |
| 908 | 89056 | inv_angle = ff_vvc_intra_inv_angle_derive(intra_pred_angle); | |
| 909 | 89056 | nscale = ff_vvc_nscale_derive(w, h, mode); | |
| 910 | } | ||
| 911 | |||
| 912 |
2/2✓ Branch 0 taken 1602288 times.
✓ Branch 1 taken 210828 times.
|
3626232 | for (int y = 0; y < h; y++) { |
| 913 | 3204576 | const int idx = (pos >> 5) + ref_idx; | |
| 914 | 3204576 | const int fact = pos & 31; | |
| 915 |
6/6✓ Branch 0 taken 247119 times.
✓ Branch 1 taken 1355169 times.
✓ Branch 2 taken 152853 times.
✓ Branch 3 taken 94266 times.
✓ Branch 4 taken 128229 times.
✓ Branch 5 taken 24624 times.
|
3204576 | if (!fact && (!is_luma || !filter_flag)) { |
| 916 |
2/2✓ Branch 0 taken 2330216 times.
✓ Branch 1 taken 222495 times.
|
5105422 | for (int x = 0; x < w; x++) { |
| 917 | 4660432 | const pixel *p = top + x + idx + 1; | |
| 918 | 4660432 | POS(x, y) = *p; | |
| 919 | } | ||
| 920 | } else { | ||
| 921 |
2/2✓ Branch 0 taken 1084655 times.
✓ Branch 1 taken 295138 times.
|
2759586 | if (!c_idx) { |
| 922 | 2169310 | const int8_t *f = ff_vvc_intra_luma_filter[filter_flag][fact]; | |
| 923 |
2/2✓ Branch 0 taken 11856240 times.
✓ Branch 1 taken 1084655 times.
|
25881790 | for (int x = 0; x < w; x++) { |
| 924 | 23712480 | const pixel *p = top + x + idx; | |
| 925 | 23712480 | POS(x, y) = INTRA_LUMA_FILTER(p); | |
| 926 | } | ||
| 927 | } else { | ||
| 928 |
2/2✓ Branch 0 taken 2717112 times.
✓ Branch 1 taken 295138 times.
|
6024500 | for (int x = 0; x < w; x++) { |
| 929 | 5434224 | const pixel *p = top + x + idx; | |
| 930 | 5434224 | POS(x, y) = INTRA_CHROMA_FILTER(p); | |
| 931 | } | ||
| 932 | } | ||
| 933 | } | ||
| 934 |
2/2✓ Branch 0 taken 387548 times.
✓ Branch 1 taken 1214740 times.
|
3204576 | if (need_pdpc) { |
| 935 | 775096 | int inv_angle_sum = 256 + inv_angle; | |
| 936 |
2/2✓ Branch 0 taken 2099216 times.
✓ Branch 1 taken 387548 times.
|
4973528 | for (int x = 0; x < FFMIN(w, 3 << nscale); x++) { |
| 937 | 4198432 | const pixel l = left[y + (inv_angle_sum >> 9)]; | |
| 938 | 4198432 | const pixel val = POS(x, y); | |
| 939 | 4198432 | const int wl = 32 >> ((x << 1) >> nscale); | |
| 940 | 4198432 | const int pred = val + (((l - val) * wl + 32) >> 6); | |
| 941 | 4198432 | POS(x, y) = CLIP(pred); | |
| 942 | 4198432 | inv_angle_sum += inv_angle; | |
| 943 | } | ||
| 944 | } | ||
| 945 | 3204576 | pos += dp; | |
| 946 | } | ||
| 947 | 421656 | } | |
| 948 | |||
| 949 | //8.4.5.2.13 Specification of INTRA_ANGULAR2..INTRA_ANGULAR66 intra prediction modes | ||
| 950 | 384110 | static void FUNC(pred_angular_h)(uint8_t *_src, const uint8_t *_top, const uint8_t *_left, | |
| 951 | const int w, const int h, const ptrdiff_t stride, const int c_idx, const int mode, | ||
| 952 | const int ref_idx, const int filter_flag, const int need_pdpc) | ||
| 953 | { | ||
| 954 | 384110 | pixel *src = (pixel *)_src; | |
| 955 | 384110 | const pixel *left = (const pixel *)_left - (1 + ref_idx); | |
| 956 | 384110 | const pixel *top = (const pixel *)_top; | |
| 957 | 384110 | const int is_luma = !c_idx; | |
| 958 | 384110 | const int intra_pred_angle = ff_vvc_intra_pred_angle_derive(mode); | |
| 959 | 384110 | const int dp = intra_pred_angle; | |
| 960 | 384110 | int nscale = 0, inv_angle, inv_angle_sum; | |
| 961 | |||
| 962 |
2/2✓ Branch 0 taken 37566 times.
✓ Branch 1 taken 154489 times.
|
384110 | if (need_pdpc) { |
| 963 | 75132 | inv_angle = ff_vvc_intra_inv_angle_derive(intra_pred_angle); | |
| 964 | 75132 | inv_angle_sum = 256 + inv_angle; | |
| 965 | 75132 | nscale = ff_vvc_nscale_derive(w, h, mode); | |
| 966 | } | ||
| 967 | |||
| 968 |
2/2✓ Branch 0 taken 1542264 times.
✓ Branch 1 taken 192055 times.
|
3468638 | for (int y = 0; y < h; y++) { |
| 969 | 3084528 | int pos = (1 + ref_idx) * intra_pred_angle; | |
| 970 | int wt; | ||
| 971 |
2/2✓ Branch 0 taken 421848 times.
✓ Branch 1 taken 1120416 times.
|
3084528 | if (need_pdpc) |
| 972 | 843696 | wt = (32 >> FFMIN(31, (y * 2) >> nscale)); | |
| 973 | |||
| 974 |
2/2✓ Branch 0 taken 22143504 times.
✓ Branch 1 taken 1542264 times.
|
47371536 | for (int x = 0; x < w; x++) { |
| 975 | 44287008 | const int idx = (pos >> 5) + ref_idx; | |
| 976 | 44287008 | const int fact = pos & 31; | |
| 977 | 44287008 | const pixel *p = left + y + idx; | |
| 978 | int pred; | ||
| 979 |
6/6✓ Branch 0 taken 2077860 times.
✓ Branch 1 taken 20065644 times.
✓ Branch 2 taken 1671164 times.
✓ Branch 3 taken 406696 times.
✓ Branch 4 taken 988748 times.
✓ Branch 5 taken 682416 times.
|
44287008 | if (!fact && (!is_luma || !filter_flag)) { |
| 980 | 2790888 | pred = p[1]; | |
| 981 | } else { | ||
| 982 |
2/2✓ Branch 0 taken 15913668 times.
✓ Branch 1 taken 4834392 times.
|
41496120 | if (!c_idx) { |
| 983 | 31827336 | const int8_t *f = ff_vvc_intra_luma_filter[filter_flag][fact]; | |
| 984 | 31827336 | pred = INTRA_LUMA_FILTER(p); | |
| 985 | } else { | ||
| 986 | 9668784 | pred = INTRA_CHROMA_FILTER(p); | |
| 987 | } | ||
| 988 | } | ||
| 989 |
2/2✓ Branch 0 taken 5125312 times.
✓ Branch 1 taken 17018192 times.
|
44287008 | if (need_pdpc) { |
| 990 |
2/2✓ Branch 0 taken 1982544 times.
✓ Branch 1 taken 3142768 times.
|
10250624 | if (y < (3 << nscale)) { |
| 991 | 3965088 | const pixel t = top[x + (inv_angle_sum >> 9)]; | |
| 992 | 3965088 | pred = CLIP(pred + (((t - pred) * wt + 32) >> 6)); | |
| 993 | } | ||
| 994 | } | ||
| 995 | 44287008 | POS(x, y) = pred; | |
| 996 | 44287008 | pos += dp; | |
| 997 | } | ||
| 998 |
2/2✓ Branch 0 taken 421848 times.
✓ Branch 1 taken 1120416 times.
|
3084528 | if (need_pdpc) |
| 999 | 843696 | inv_angle_sum += inv_angle; | |
| 1000 | } | ||
| 1001 | 384110 | } | |
| 1002 | |||
| 1003 | 3088 | static void FUNC(ff_vvc_intra_dsp_init)(VVCIntraDSPContext *const intra) | |
| 1004 | { | ||
| 1005 | 3088 | intra->lmcs_scale_chroma = FUNC(lmcs_scale_chroma); | |
| 1006 | 3088 | intra->intra_cclm_pred = FUNC(intra_cclm_pred); | |
| 1007 | 3088 | intra->intra_pred = FUNC(intra_pred); | |
| 1008 | 3088 | intra->pred_planar = FUNC(pred_planar); | |
| 1009 | 3088 | intra->pred_mip = FUNC(pred_mip); | |
| 1010 | 3088 | intra->pred_dc = FUNC(pred_dc); | |
| 1011 | 3088 | intra->pred_v = FUNC(pred_v); | |
| 1012 | 3088 | intra->pred_h = FUNC(pred_h); | |
| 1013 | 3088 | intra->pred_angular_v = FUNC(pred_angular_v); | |
| 1014 | 3088 | intra->pred_angular_h = FUNC(pred_angular_h); | |
| 1015 | 3088 | } | |
| 1016 |