FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/vvc/intra_template.c
Date: 2026-04-29 17:33:30
Exec Total Coverage
Lines: 628 628 100.0%
Functions: 53 90 58.9%
Branches: 400 404 99.0%

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 203852 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 203852 const VVCSPS *sps = fc->ps.sps;
33
2/2
✓ Branch 0 taken 203852 times.
✓ Branch 1 taken 101926 times.
611556 for (int i = 0; i < VVC_MAX_SAMPLE_ARRAYS - 1; i++) {
34 407704 const int c_idx = i + 1;
35 407704 const int x = x0 >> sps->hshift[c_idx];
36 407704 const int y = y0 >> sps->vshift[c_idx];
37 407704 const ptrdiff_t stride = fc->frame->linesize[c_idx] / sizeof(pixel);
38 407704 pixel *src = (pixel*)fc->frame->data[c_idx] + x + y * stride;
39
2/2
✓ Branch 0 taken 1971192 times.
✓ Branch 1 taken 203852 times.
4350088 for (int y = 0; y < h; y++) {
40
2/2
✓ Branch 0 taken 28944224 times.
✓ Branch 1 taken 1971192 times.
61830832 for (int x = 0; x < w; x++) {
41 57888448 const int dsy = pdsy[y * w + x];
42 57888448 const int pred = ((dsy * a[i]) >> k[i]) + b[i];
43 57888448 POS(x, y) = CLIP(pred);
44 }
45 }
46 }
47 203852 }
48
49 #define MAX_PICK_POS 4
50 #define TOP 0
51 #define LEFT 1
52
53 1662 static av_always_inline void FUNC(cclm_get_params_default)(int *a, int *b, int *k)
54 {
55
2/2
✓ Branch 0 taken 1662 times.
✓ Branch 1 taken 831 times.
4986 for (int i = 0; i < 2; i++) {
56 3324 a[i] = k[i] = 0;
57 3324 b[i] = 1 << (BIT_DEPTH - 1);
58 }
59 1662 }
60
61 203852 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 203852 const enum IntraPredMode mode = lc->cu->intra_pred_mode_c;
66
6/6
✓ Branch 0 taken 98499 times.
✓ Branch 1 taken 3427 times.
✓ Branch 2 taken 95796 times.
✓ Branch 3 taken 2703 times.
✓ Branch 4 taken 42784 times.
✓ Branch 5 taken 53012 times.
203852 const int num_is4 = !avail_t || !avail_l || mode != INTRA_LT_CCLM;
67 int num_samp[2];
68
69
2/2
✓ Branch 0 taken 57176 times.
✓ Branch 1 taken 44750 times.
203852 if (mode == INTRA_LT_CCLM) {
70
2/2
✓ Branch 0 taken 54652 times.
✓ Branch 1 taken 2524 times.
114352 num_samp[TOP] = avail_t ? w : 0;
71
2/2
✓ Branch 0 taken 55536 times.
✓ Branch 1 taken 1640 times.
114352 num_samp[LEFT] = avail_l ? h : 0;
72 } else {
73
4/4
✓ Branch 0 taken 43847 times.
✓ Branch 1 taken 903 times.
✓ Branch 2 taken 23180 times.
✓ Branch 3 taken 20667 times.
89500 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 43687 times.
✓ Branch 1 taken 1063 times.
✓ Branch 2 taken 20739 times.
✓ Branch 3 taken 22948 times.
89500 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 24094 times.
✓ Branch 1 taken 77832 times.
✓ Branch 2 taken 831 times.
✓ Branch 3 taken 23263 times.
203852 if (!num_samp[TOP] && !num_samp[LEFT]) {
77 1662 return 0;
78 }
79
2/2
✓ Branch 0 taken 202190 times.
✓ Branch 1 taken 101095 times.
606570 for (int i = TOP; i <= LEFT; i++) {
80 404380 const int start = num_samp[i] >> (2 + num_is4);
81 404380 const int step = FFMAX(1, num_samp[i] >> (1 + num_is4)) ;
82 404380 cnt[i] = FFMIN(num_samp[i], (1 + num_is4) << 1);
83
2/2
✓ Branch 0 taken 402986 times.
✓ Branch 1 taken 202190 times.
1210352 for (int c = 0; c < cnt[i]; c++)
84 805972 pos[i][c] = start + c * step;
85 }
86 202190 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 202190 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 202190 const VVCSPS *sps = fc->ps.sps;
101
102 202190 const int b_ctu_boundary = !av_zero_extend(y0, sps->ctb_log2_size_y);
103 202190 const int hs = sps->hshift[1];
104 202190 const int vs = sps->vshift[1];
105 202190 const ptrdiff_t stride = fc->frame->linesize[0] / sizeof(pixel);
106
107
3/4
✓ Branch 0 taken 13010 times.
✓ Branch 1 taken 88085 times.
✓ Branch 2 taken 13010 times.
✗ Branch 3 not taken.
228210 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 80158 times.
✓ Branch 1 taken 7927 times.
✓ Branch 2 taken 68206 times.
✓ Branch 3 taken 11952 times.
312582 if (vs && !b_ctu_boundary) {
114 136412 const pixel *source = (pixel *)fc->frame->data[0] + x0 + (y0 - 2) * stride;
115
2/2
✓ Branch 0 taken 142434 times.
✓ Branch 1 taken 68206 times.
421280 for (int i = 0; i < cnt[TOP]; i++) {
116 284868 const int x = pos[TOP][i] << hs;
117 284868 const pixel *src = source + x;
118
4/4
✓ Branch 0 taken 2703 times.
✓ Branch 1 taken 139731 times.
✓ Branch 2 taken 2456 times.
✓ Branch 3 taken 247 times.
284868 const int has_left = x || avail_l;
119
2/2
✓ Branch 0 taken 142187 times.
✓ Branch 1 taken 247 times.
284868 const pixel l = has_left ? POS(-1, 0) : POS(0, 0);
120
2/2
✓ Branch 0 taken 4240 times.
✓ Branch 1 taken 138194 times.
284868 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 137947 times.
✓ Branch 1 taken 247 times.
276388 const pixel l1 = has_left ? POS(-1, 1) : POS(0, 1);
124 276388 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 39758 const pixel *source = (pixel*)fc->frame->data[0] + x0 + (y0 - 1) * stride;
129
2/2
✓ Branch 0 taken 36188 times.
✓ Branch 1 taken 19879 times.
112134 for (int i = 0; i < cnt[TOP]; i++) {
130 72376 const int x = pos[TOP][i] << hs;
131 72376 const pixel *src = source + x;
132
4/4
✓ Branch 0 taken 653 times.
✓ Branch 1 taken 35535 times.
✓ Branch 2 taken 608 times.
✓ Branch 3 taken 45 times.
72376 const int has_left = x || avail_l;
133
2/2
✓ Branch 0 taken 36143 times.
✓ Branch 1 taken 45 times.
72376 const pixel l = has_left ? POS(-1, 0) : POS(0, 0);
134 72376 sel_luma[i] = (l + 2 * POS(0, 0) + POS(1, 0) + 2) >> 2;
135 }
136 }
137
138 // left
139 {
140 const pixel *left;
141 176170 const pixel *source = (pixel *)fc->frame->data[0] + x0 + y0 * stride - (1 + hs) * avail_l;
142 176170 left = source - avail_l;
143
144
2/2
✓ Branch 0 taken 172324 times.
✓ Branch 1 taken 88085 times.
520818 for (int i = 0; i < cnt[LEFT]; i++) {
145 344648 const int y = pos[LEFT][i] << vs;
146 344648 const int offset = y * stride;
147 344648 const pixel *l = left + offset;
148 344648 const pixel *src = source + offset;
149 pixel pred;
150
2/2
✓ Branch 0 taken 14282 times.
✓ Branch 1 taken 158042 times.
344648 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 151984 times.
316084 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 303968 pred = (*l + *(l + stride) + 2 * POS(0, 0) + 2 * POS(0, 1) + POS(1, 0) + POS(1, 1) + 4) >> 3;
159 }
160 }
161 344648 sel_luma[i + cnt[TOP]] = pred;
162 }
163 }
164 }
165 202190 }
166
167 202190 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 202190 times.
✓ Branch 1 taken 101095 times.
606570 for (int c_idx = 1; c_idx < VVC_MAX_SAMPLE_ARRAYS; c_idx++) {
172 404380 const ptrdiff_t stride = fc->frame->linesize[c_idx] / sizeof(pixel);
173
174 //top
175 404380 const pixel *src = (pixel*)fc->frame->data[c_idx] + x + (y - 1)* stride;
176
2/2
✓ Branch 0 taken 410608 times.
✓ Branch 1 taken 202190 times.
1225596 for (int i = 0; i < cnt[TOP]; i++) {
177 821216 sel[c_idx][i] = src[pos[TOP][i]];
178 }
179
180 //left
181 404380 src = (pixel*)fc->frame->data[c_idx] + x - 1 + y * stride;
182
2/2
✓ Branch 0 taken 395364 times.
✓ Branch 1 taken 202190 times.
1195108 for (int i = 0; i < cnt[LEFT]; i++) {
183 790728 sel[c_idx][i + cnt[TOP]] = src[pos[LEFT][i] * stride];
184 }
185 }
186 202190 }
187
188 203852 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 203852 const VVCFrameContext *fc = lc->fc;
193 203852 const VVCSPS *sps = fc->ps.sps;
194 203852 const int x = x0 >> sps->hshift[1];
195 203852 const int y = y0 >> sps->vshift[1];
196 int cnt[2], pos[2][MAX_PICK_POS];
197
198
2/2
✓ Branch 1 taken 831 times.
✓ Branch 2 taken 101095 times.
203852 if (!FUNC(cclm_get_select_pos)(lc, x, y, w, h, avail_t, avail_l, cnt, pos))
199 1662 return 0;
200
201 202190 FUNC(cclm_select_luma)(fc, x0, y0, avail_t, avail_l, cnt, pos, sel[LUMA]);
202 202190 FUNC(cclm_select_chroma)(fc, x, y, cnt, pos, sel);
203
204
2/2
✓ Branch 0 taken 697 times.
✓ Branch 1 taken 100398 times.
202190 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 202190 return 1;
213 }
214
215 202190 static av_always_inline void FUNC(cclm_get_min_max)(
216 const pixel sel[][MAX_PICK_POS * 2], int *min, int *max)
217 {
218 202190 int min_grp_idx[] = { 0, 2 };
219 202190 int max_grp_idx[] = { 1, 3 };
220
221
2/2
✓ Branch 0 taken 46752 times.
✓ Branch 1 taken 54343 times.
202190 if (sel[LUMA][min_grp_idx[0]] > sel[LUMA][min_grp_idx[1]])
222 93504 FFSWAP(int, min_grp_idx[0], min_grp_idx[1]);
223
2/2
✓ Branch 0 taken 47276 times.
✓ Branch 1 taken 53819 times.
202190 if (sel[LUMA][max_grp_idx[0]] > sel[LUMA][max_grp_idx[1]])
224 94552 FFSWAP(int, max_grp_idx[0], max_grp_idx[1]);
225
2/2
✓ Branch 0 taken 9506 times.
✓ Branch 1 taken 91589 times.
202190 if (sel[LUMA][min_grp_idx[0]] > sel[LUMA][max_grp_idx[1]]) {
226 19012 FFSWAP(int, min_grp_idx[0], max_grp_idx[0]);
227 19012 FFSWAP(int, min_grp_idx[1], max_grp_idx[1]);
228 }
229
2/2
✓ Branch 0 taken 74269 times.
✓ Branch 1 taken 26826 times.
202190 if (sel[LUMA][min_grp_idx[1]] > sel[LUMA][max_grp_idx[0]])
230 148538 FFSWAP(int, min_grp_idx[1], max_grp_idx[0]);
231
2/2
✓ Branch 0 taken 303285 times.
✓ Branch 1 taken 101095 times.
808760 for (int c_idx = 0; c_idx < VVC_MAX_SAMPLE_ARRAYS; c_idx++) {
232 606570 max[c_idx] = (sel[c_idx][max_grp_idx[0]] + sel[c_idx][max_grp_idx[1]] + 1) >> 1;
233 606570 min[c_idx] = (sel[c_idx][min_grp_idx[0]] + sel[c_idx][min_grp_idx[1]] + 1) >> 1;
234 }
235 202190 }
236
237 203852 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 831 times.
✓ Branch 2 taken 101095 times.
203852 if (!FUNC(cclm_select_samples)(lc, x0, y0, w, h, avail_t, avail_l, sel)) {
246 1662 FUNC(cclm_get_params_default)(a, b, k);
247 13980 return;
248 }
249
250 202190 FUNC(cclm_get_min_max)(sel, min, max);
251
252 202190 diff = max[LUMA] - min[LUMA];
253
2/2
✓ Branch 0 taken 6159 times.
✓ Branch 1 taken 94936 times.
202190 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 189872 times.
✓ Branch 1 taken 94936 times.
569616 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 379744 const int diffc = max[i + 1] - min[i + 1];
263 379744 int x = av_log2(diff);
264 int y, v, sign, add;
265 379744 const int norm_diff = ((diff << 4) >> x) & 15;
266 379744 x += (norm_diff) ? 1 : 0;
267
2/2
✓ Branch 0 taken 169730 times.
✓ Branch 1 taken 20142 times.
379744 y = abs(diffc) > 0 ? av_log2(abs(diffc)) + 1 : 0;
268 379744 v = div_sig_table[norm_diff] | 8;
269 379744 add = (1 << y >> 1);
270 379744 a[i] = (diffc * v + add) >> y;
271 379744 k[i] = FFMAX(1, 3 + x -y);
272
2/2
✓ Branch 0 taken 84191 times.
✓ Branch 1 taken 105681 times.
379744 sign = a[i] < 0 ? -1 : (a[i] > 0);
273
2/2
✓ Branch 0 taken 1731 times.
✓ Branch 1 taken 188141 times.
379744 a[i] = ((3 + x - y) < 1) ? sign * 15 : a[i];
274 379744 b[i] = min[i + 1] - ((a[i] * min[0]) >> k[i]);
275 }
276
277 }
278
279 #undef TOP
280 #undef LEFT
281
282 203852 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 203852 const int hs = fc->ps.sps->hshift[1];
287 203852 const int vs = fc->ps.sps->vshift[1];
288 203852 const ptrdiff_t stride = fc->frame->linesize[0] / sizeof(pixel);
289 203852 const pixel *source = (pixel*)fc->frame->data[0] + x0 + y0 * stride;
290 203852 const pixel *left = source - avail_l;
291 203852 const pixel *top = source - avail_t * stride;
292
293 203852 const VVCSPS *sps = fc->ps.sps;
294
3/4
✓ Branch 0 taken 13013 times.
✓ Branch 1 taken 88913 times.
✓ Branch 2 taken 13013 times.
✗ Branch 3 not taken.
203852 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 805668 times.
✓ Branch 1 taken 88913 times.
1789162 for (int i = 0; i < h; i++) {
300 1611336 const pixel *src = source;
301 1611336 const pixel *l = left;
302 1611336 const pixel *t = top;
303
2/2
✓ Branch 0 taken 93912 times.
✓ Branch 1 taken 711756 times.
1611336 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 657080 times.
1423512 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 8963904 times.
✓ Branch 1 taken 657080 times.
19241968 for (int j = 0; j < w; j++) {
322 17927808 pixel pred = (*l + *(l + stride) + 2 * POS(0, 0) + 2 * POS(0, 1) + POS(1, 0) + POS(1, 1) + 4) >> 3;
323
324 17927808 pdsy[i * w + j] = pred;
325 17927808 src += 2;
326 17927808 l = src - 1;
327 }
328 }
329 }
330 1611336 source += (stride << vs);
331 1611336 left += (stride << vs);
332 1611336 top = source - stride;
333 }
334 }
335
336 602 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 602 times.
✓ Branch 1 taken 301 times.
1806 for (int c_idx = 1; c_idx < VVC_MAX_SAMPLE_ARRAYS; c_idx++) {
340 1204 const ptrdiff_t stride = fc->frame->linesize[c_idx] / sizeof(pixel);
341 1204 pixel *dst = (pixel*)fc->frame->data[c_idx] + x + y * stride;
342
2/2
✓ Branch 0 taken 10672 times.
✓ Branch 1 taken 602 times.
22548 for (int i = 0; i < h; i++) {
343
2/2
✓ Branch 0 taken 271296 times.
✓ Branch 1 taken 10672 times.
563936 for (int j = 0; j < w; j++) {
344 542592 dst[j] = 1 << (BIT_DEPTH - 1);
345 }
346 21344 dst += stride;
347 }
348 }
349 602 }
350
351 //8.4.5.2.14 Specification of INTRA_LT_CCLM, INTRA_L_CCLM and INTRA_T_CCLM intra prediction mode
352 204454 static void FUNC(intra_cclm_pred)(const VVCLocalContext *lc, const int x0, const int y0,
353 const int width, const int height)
354 {
355 204454 VVCFrameContext *fc = lc->fc;
356 204454 const VVCSPS *sps = fc->ps.sps;
357 204454 const int avail_t = ff_vvc_get_top_available(lc, x0, y0, 1, 0);
358 204454 const int avail_l = ff_vvc_get_left_available(lc, x0, y0, 1, 0);
359 204454 const int hs = sps->hshift[1];
360 204454 const int vs = sps->vshift[1];
361 204454 const int x = x0 >> hs;
362 204454 const int y = y0 >> vs;
363 204454 const int w = width >> hs;
364 204454 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 3728 times.
✓ Branch 1 taken 98499 times.
✓ Branch 2 taken 301 times.
✓ Branch 3 taken 3427 times.
204454 if (!avail_t && !avail_l) {
369 602 FUNC(cclm_pred_default)(fc, x, y, w, h, avail_t, avail_l);
370 602 return;
371 }
372 203852 FUNC(cclm_get_luma_rec_pixels)(fc, x0, y0, w, h, avail_t, avail_l, dsy);
373 203852 FUNC(cclm_get_params) (lc, x0, y0, w, h, avail_t, avail_l, a, b, k);
374 203852 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 240694 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 240694 filtered_left[-1] = filtered_top[-1] = (left[0] + 2 * left[-1] + top[0] + 2 ) >> 2;
454
2/2
✓ Branch 0 taken 2009523 times.
✓ Branch 1 taken 120347 times.
4259740 for (int i = 0; i < left_size - unfilter_last_one; i++) {
455 4019046 filtered_left[i] = (left[i- 1] + 2 * left[i] + left[i + 1] + 2) >> 2;
456 }
457
2/2
✓ Branch 0 taken 2330419 times.
✓ Branch 1 taken 120347 times.
4901532 for (int i = 0; i < top_size - unfilter_last_one; i++) {
458 4660838 filtered_top[i] = (top[i-1] + 2 * top[i] + top[i + 1] + 2) >> 2;
459 }
460
2/2
✓ Branch 0 taken 5529 times.
✓ Branch 1 taken 114818 times.
240694 if (unfilter_last_one) {
461 11058 filtered_top[top_size - 1] = top[top_size - 1];
462 11058 filtered_left[left_size - 1] = left[left_size - 1];
463 }
464 240694 }
465
466 2281950 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 2281950 const CodingUnit *cu = lc->cu;
477
2/2
✓ Branch 0 taken 1027324 times.
✓ Branch 1 taken 113651 times.
2281950 const int ref_filter_flag = is_intra_mip ? 0 : ff_vvc_ref_filter_flag_derive(mode);
478
4/4
✓ Branch 0 taken 568309 times.
✓ Branch 1 taken 527386 times.
✓ Branch 2 taken 389339 times.
✓ Branch 3 taken 178970 times.
2191390 const int filter_flag = !ref_idx && w * h > 32 && !c_idx &&
479
6/6
✓ Branch 0 taken 1095695 times.
✓ Branch 1 taken 45280 times.
✓ Branch 2 taken 332451 times.
✓ Branch 3 taken 56888 times.
✓ Branch 4 taken 120347 times.
✓ Branch 5 taken 212104 times.
4473340 cu->isp_split_type == ISP_NO_SPLIT && ref_filter_flag;
480 2281950 int cand_up_left = lc->na.cand_up_left;
481 2281950 pixel *left = (pixel*)edge->left_array + MAX_TB_SIZE + 3;
482 2281950 pixel *top = (pixel*)edge->top_array + MAX_TB_SIZE + 3;
483 2281950 pixel *filtered_left = (pixel*)edge->filtered_left_array + MAX_TB_SIZE + 3;
484 2281950 pixel *filtered_top = (pixel*)edge->filtered_top_array + MAX_TB_SIZE + 3;
485 2281950 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 1027324 times.
✓ Branch 1 taken 113651 times.
✓ Branch 2 taken 372160 times.
✓ Branch 3 taken 655164 times.
2281950 if (is_intra_mip || mode == INTRA_PLANAR) {
493 971622 left_size = h + 1;
494 971622 top_size = w + 1;
495 971622 unfilter_left_size = left_size + filter_flag;
496 971622 unfilter_top_size = top_size + filter_flag;
497
2/2
✓ Branch 0 taken 77198 times.
✓ Branch 1 taken 577966 times.
1310328 } else if (mode == INTRA_DC) {
498 154396 unfilter_left_size = left_size = h;
499 154396 unfilter_top_size = top_size = w;
500
2/2
✓ Branch 0 taken 86654 times.
✓ Branch 1 taken 491312 times.
1155932 } else if (mode == INTRA_VERT) {
501 //we may need 1 pixel to predict the top left.
502
2/2
✓ Branch 0 taken 66799 times.
✓ Branch 1 taken 19855 times.
173308 unfilter_left_size = left_size = need_pdpc ? h : 1;
503 173308 unfilter_top_size = top_size = w;
504
2/2
✓ Branch 0 taken 87902 times.
✓ Branch 1 taken 403410 times.
982624 } else if (mode == INTRA_HORZ) {
505 175804 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 64530 times.
✓ Branch 1 taken 23372 times.
175804 unfilter_top_size = top_size = need_pdpc ? w : 1;
508 } else {
509
4/4
✓ Branch 0 taken 92584 times.
✓ Branch 1 taken 310826 times.
✓ Branch 2 taken 3012 times.
✓ Branch 3 taken 89572 times.
806820 if (cu->isp_split_type == ISP_NO_SPLIT || c_idx) {
510 627676 refw = w * 2;
511 627676 refh = h * 2;
512 } else {
513 179144 refw = cu->cb_width + w;
514 179144 refh = cu->cb_height + h;
515 }
516 806820 intra_pred_angle = ff_vvc_intra_pred_angle_derive(mode);
517 806820 inv_angle = ff_vvc_intra_inv_angle_derive(intra_pred_angle);
518 806820 unfilter_top_size = top_size = refw;
519 806820 unfilter_left_size = left_size = refh;
520 }
521
522 2281950 left_available = ff_vvc_get_left_available(lc, x, y, unfilter_left_size, c_idx);
523
2/2
✓ Branch 0 taken 11752674 times.
✓ Branch 1 taken 1140975 times.
25787298 for (i = 0; i < left_available; i++)
524 23505348 left[i] = POS(ref_line, i);
525
526 2281950 top_available = ff_vvc_get_top_available(lc, x, y, unfilter_top_size, c_idx);
527 2281950 memcpy(top, src + ref_line * stride, top_available * sizeof(pixel));
528
529
2/2
✓ Branch 0 taken 1213045 times.
✓ Branch 1 taken 1140975 times.
4708040 for (int i = -1; i >= ref_line; i--) {
530
2/2
✓ Branch 0 taken 1160390 times.
✓ Branch 1 taken 52655 times.
2426090 if (cand_up_left) {
531 2320780 left[i] = POS(ref_line, i);
532 2320780 top[i] = POS(i, ref_line);
533
2/2
✓ Branch 0 taken 24226 times.
✓ Branch 1 taken 28429 times.
105310 } else if (left_available) {
534 48452 left[i] = top[i] = left[0];
535
2/2
✓ Branch 0 taken 27385 times.
✓ Branch 1 taken 1044 times.
56858 } else if (top_available) {
536 54770 left[i] = top[i] = top[0];
537 } else {
538 2088 left[i] = top[i] = 1 << (BIT_DEPTH - 1);
539 }
540 }
541
542
2/2
✓ Branch 0 taken 3653101 times.
✓ Branch 1 taken 1140975 times.
9588152 EXTEND(top + top_available, top[top_available-1], unfilter_top_size - top_available);
543
2/2
✓ Branch 0 taken 2818282 times.
✓ Branch 1 taken 1140975 times.
7918514 EXTEND(left + left_available, left[left_available-1], unfilter_left_size - left_available);
544
545
2/2
✓ Branch 0 taken 399870 times.
✓ Branch 1 taken 741105 times.
2281950 if (ref_filter_flag) {
546
8/8
✓ Branch 0 taken 398913 times.
✓ Branch 1 taken 957 times.
✓ Branch 2 taken 222455 times.
✓ Branch 3 taken 176458 times.
✓ Branch 4 taken 147367 times.
✓ Branch 5 taken 75088 times.
✓ Branch 6 taken 120347 times.
✓ Branch 7 taken 27020 times.
799740 if (!ref_idx && w * h > 32 && !c_idx && cu->isp_split_type == ISP_NO_SPLIT ) {
547 240694 const int unfilter_last_one = left_size == unfilter_left_size;
548 240694 FUNC(ref_filter)(left, top, filtered_left, filtered_top, unfilter_left_size, unfilter_top_size, unfilter_last_one);
549 240694 left = filtered_left;
550 240694 top = filtered_top;
551 }
552 }
553
6/6
✓ Branch 0 taken 1027324 times.
✓ Branch 1 taken 113651 times.
✓ Branch 2 taken 655164 times.
✓ Branch 3 taken 372160 times.
✓ Branch 4 taken 577966 times.
✓ Branch 5 taken 77198 times.
2281950 if (!is_intra_mip && mode != INTRA_PLANAR && mode != INTRA_DC) {
554
6/6
✓ Branch 0 taken 550256 times.
✓ Branch 1 taken 27710 times.
✓ Branch 2 taken 512024 times.
✓ Branch 3 taken 38232 times.
✓ Branch 4 taken 112443 times.
✓ Branch 5 taken 399581 times.
1155932 if (ref_filter_flag || ref_idx || cu->isp_split_type != ISP_NO_SPLIT) {
555 356770 edge->filter_flag = 0;
556 } else {
557 799162 const int min_dist_ver_hor = FFMIN(abs(mode - 50), abs(mode - 18));
558 799162 const int intra_hor_ver_dist_thres[] = {24, 14, 2, 0, 0};
559 799162 const int ntbs = (av_log2(w) + av_log2(h)) >> 1;
560 799162 edge->filter_flag = min_dist_ver_hor > intra_hor_ver_dist_thres[ntbs - 2];
561 }
562
563
4/4
✓ Branch 0 taken 491312 times.
✓ Branch 1 taken 86654 times.
✓ Branch 2 taken 403410 times.
✓ Branch 3 taken 87902 times.
1155932 if (mode != INTRA_VERT && mode != INTRA_HORZ) {
564
2/2
✓ Branch 0 taken 211002 times.
✓ Branch 1 taken 192408 times.
806820 if (mode >= INTRA_DIAG) {
565
2/2
✓ Branch 0 taken 107553 times.
✓ Branch 1 taken 103449 times.
422004 if (intra_pred_angle < 0) {
566 215106 pixel *p = top - (ref_idx + 1);
567
2/2
✓ Branch 0 taken 876744 times.
✓ Branch 1 taken 107553 times.
1968594 for (int x = -h; x < 0; x++) {
568 1753488 const int idx = -1 - ref_idx + FFMIN((x*inv_angle + 256) >> 9, h);
569 1753488 p[x] = left[idx];
570 }
571 } else {
572
2/2
✓ Branch 0 taken 225469 times.
✓ Branch 1 taken 103449 times.
657836 for (int i = refw; i <= refw + FFMAX(1, w/h) * ref_idx + 1; i++)
573 450938 top[i] = top[refw - 1];
574 }
575 } else {
576
2/2
✓ Branch 0 taken 99800 times.
✓ Branch 1 taken 92608 times.
384816 if (intra_pred_angle < 0) {
577 199600 pixel *p = left - (ref_idx + 1);
578
2/2
✓ Branch 0 taken 1462452 times.
✓ Branch 1 taken 99800 times.
3124504 for (int x = -w; x < 0; x++) {
579 2924904 const int idx = -1 - ref_idx + FFMIN((x*inv_angle + 256) >> 9, w);
580 2924904 p[x] = top[idx];
581 }
582 } else {
583
2/2
✓ Branch 0 taken 201956 times.
✓ Branch 1 taken 92608 times.
589128 for (int i = refh; i <= refh + FFMAX(1, h/w) * ref_idx + 1; i++)
584 403912 left[i] = left[refh - 1];
585 }
586 }
587 }
588 }
589 2281950 edge->left = (uint8_t*)left;
590 2281950 edge->top = (uint8_t*)top;
591 2281950 }
592
593 //8.4.1 General decoding process for coding units coded in intra prediction mode
594 2281950 static void FUNC(intra_pred)(const VVCLocalContext *lc, int x0, int y0,
595 const int width, const int height, int c_idx)
596 {
597 2281950 VVCFrameContext *fc = lc->fc;
598 2281950 const VVCSPS *sps = fc->ps.sps;
599 2281950 const VVCPPS *pps = fc->ps.pps;
600 2281950 const CodingUnit *cu = lc->cu;
601 2281950 const int log2_min_cb_size = sps->min_cb_log2_size_y;
602 2281950 const int min_cb_width = pps->min_cb_width;
603 2281950 const int x_cb = x0 >> log2_min_cb_size;
604 2281950 const int y_cb = y0 >> log2_min_cb_size;
605
606 2281950 const int hshift = fc->ps.sps->hshift[c_idx];
607 2281950 const int vshift = fc->ps.sps->vshift[c_idx];
608 2281950 const int x = x0 >> hshift;
609 2281950 const int y = y0 >> vshift;
610 2281950 const int w = width >> hshift;
611 2281950 const int h = height >> vshift;
612 2281950 const ptrdiff_t stride = fc->frame->linesize[c_idx] / sizeof(pixel);
613
614
2/2
✓ Branch 0 taken 353502 times.
✓ Branch 1 taken 787473 times.
2281950 const int pred_mode = c_idx ? cu->intra_pred_mode_c : cu->intra_pred_mode_y;
615 2281950 const int mode = ff_vvc_wide_angle_mode_mapping(cu, w, h, c_idx, pred_mode);
616
617 2281950 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 972670 times.
✓ Branch 2 taken 56290 times.
✓ Branch 3 taken 112015 times.
✓ Branch 4 taken 1636 times.
✓ Branch 5 taken 54654 times.
2281950 const int is_intra_mip = intra_mip_flag && (!c_idx || cu->mip_chroma_direct_flag);
619
2/2
✓ Branch 0 taken 787473 times.
✓ Branch 1 taken 353502 times.
2281950 const int ref_idx = c_idx ? 0 : cu->intra_luma_ref_idx;
620 2281950 const int need_pdpc = ff_vvc_need_pdpc(w, h, cu->bdpcm_flag[c_idx], mode, ref_idx);
621
622
623 2281950 pixel *src = (pixel*)fc->frame->data[c_idx] + x + y * stride;
624 IntraEdgeParams edge;
625
626 2281950 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 1027324 times.
2281950 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 372160 times.
✓ Branch 1 taken 655164 times.
2054648 } else if (mode == INTRA_PLANAR) {
636 744320 fc->vvcdsp.intra.pred_planar((uint8_t *)src, edge.top, edge.left, w, h, stride);
637
2/2
✓ Branch 0 taken 77198 times.
✓ Branch 1 taken 577966 times.
1310328 } else if (mode == INTRA_DC) {
638 154396 fc->vvcdsp.intra.pred_dc((uint8_t *)src, edge.top, edge.left, w, h, stride);
639
2/2
✓ Branch 0 taken 86654 times.
✓ Branch 1 taken 491312 times.
1155932 } else if (mode == INTRA_VERT) {
640 173308 fc->vvcdsp.intra.pred_v((uint8_t *)src, edge.top, w, h, stride);
641
2/2
✓ Branch 0 taken 87902 times.
✓ Branch 1 taken 403410 times.
982624 } else if (mode == INTRA_HORZ) {
642 175804 fc->vvcdsp.intra.pred_h((uint8_t *)src, edge.left, w, h, stride);
643 } else {
644
2/2
✓ Branch 0 taken 211002 times.
✓ Branch 1 taken 192408 times.
806820 if (mode >= INTRA_DIAG) {
645 422004 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 384816 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 709560 times.
✓ Branch 1 taken 431415 times.
2281950 if (need_pdpc) {
655 //8.4.5.2.15 Position-dependent intra prediction sample filtering process
656
8/8
✓ Branch 0 taken 614338 times.
✓ Branch 1 taken 95222 times.
✓ Branch 2 taken 278756 times.
✓ Branch 3 taken 335582 times.
✓ Branch 4 taken 213647 times.
✓ Branch 5 taken 65109 times.
✓ Branch 6 taken 146848 times.
✓ Branch 7 taken 66799 times.
1419120 if (!is_intra_mip && (mode == INTRA_PLANAR || mode == INTRA_DC ||
657
2/2
✓ Branch 0 taken 64530 times.
✓ Branch 1 taken 82318 times.
293696 mode == INTRA_VERT || mode == INTRA_HORZ)) {
658 1064040 const int scale = (av_log2(w) + av_log2(h) - 2) >> 2;
659 1064040 const pixel *left = (pixel*)edge.left;
660 1064040 const pixel *top = (pixel*)edge.top;
661
2/2
✓ Branch 0 taken 5672532 times.
✓ Branch 1 taken 532020 times.
12409104 for (int y = 0; y < h; y++) {
662
2/2
✓ Branch 0 taken 91617296 times.
✓ Branch 1 taken 5672532 times.
194579656 for (int x = 0; x < w; x++) {
663 int l, t, wl, wt, pred;
664 pixel val;
665
4/4
✓ Branch 0 taken 30948480 times.
✓ Branch 1 taken 60668816 times.
✓ Branch 2 taken 10443616 times.
✓ Branch 3 taken 20504864 times.
183234592 if (mode == INTRA_PLANAR || mode == INTRA_DC) {
666 142224864 l = left[y];
667 142224864 t = top[x];
668 142224864 wl = 32 >> FFMIN((x << 1) >> scale, 31);
669 142224864 wt = 32 >> FFMIN((y << 1) >> scale, 31);
670 } else {
671 41009728 l = left[y] - left[-1] + POS(x,y);
672 41009728 t = top[x] - top[-1] + POS(x,y);
673
2/2
✓ Branch 0 taken 9120688 times.
✓ Branch 1 taken 11384176 times.
41009728 wl = (mode == INTRA_VERT) ? (32 >> FFMIN((x << 1) >> scale, 31)) : 0;
674
2/2
✓ Branch 0 taken 11384176 times.
✓ Branch 1 taken 9120688 times.
41009728 wt = (mode == INTRA_HORZ) ? (32 >> FFMIN((y << 1) >> scale, 31)) : 0;
675 }
676 183234592 val = POS(x, y);
677 183234592 pred = val + ((wl * (l - val) + wt * (t - val) + 32) >> 6);
678 183234592 POS(x, y) = CLIP(pred);
679 }
680 }
681 }
682 }
683 2281950 }
684
685 //8.4.5.2.11 Specification of INTRA_PLANAR intra prediction mode
686 744320 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 744320 pixel *src = (pixel *)_src;
691 744320 const pixel *top = (const pixel *)_top;
692 744320 const pixel *left = (const pixel *)_left;
693 744320 const int logw = av_log2(w);
694 744320 const int logh = av_log2(h);
695 744320 const int size = w * h;
696 744320 const int shift = (logw + logh + 1);
697
2/2
✓ Branch 0 taken 3671372 times.
✓ Branch 1 taken 372160 times.
8087064 for (y = 0; y < h; y++) {
698
2/2
✓ Branch 0 taken 61592016 times.
✓ Branch 1 taken 3671372 times.
130526776 for (x = 0; x < w; x++) {
699 123184032 const int pred_v = ((h - 1 - y) * top[x] + (y + 1) * left[h]) << logw;
700 123184032 const int pred_h = ((w - 1 - x) * left[y] + (x + 1) * top[w]) << logh;
701 123184032 const int pred = (pred_v + pred_h + size) >> shift;
702 123184032 POS(x, y) = pred;
703 }
704 }
705 744320 }
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 154396 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 154396 int sum = 0;
831
2/2
✓ Branch 0 taken 27038 times.
✓ Branch 1 taken 50160 times.
154396 unsigned int offset = (w == h) ? (w << 1) : FFMAX(w, h);
832 154396 const int shift = av_log2(offset);
833 154396 offset >>= 1;
834
2/2
✓ Branch 0 taken 58578 times.
✓ Branch 1 taken 18620 times.
154396 if (w >= h) {
835
2/2
✓ Branch 0 taken 814496 times.
✓ Branch 1 taken 58578 times.
1746148 for (int i = 0; i < w; i++)
836 1628992 sum += top[i];
837 }
838
2/2
✓ Branch 0 taken 45658 times.
✓ Branch 1 taken 31540 times.
154396 if (w <= h) {
839
2/2
✓ Branch 0 taken 545672 times.
✓ Branch 1 taken 45658 times.
1182660 for (int i = 0; i < h; i++)
840 1091344 sum += left[i];
841 }
842 154396 dc_val = (sum + offset) >> shift;
843 154396 return dc_val;
844 }
845
846 //8.4.5.2.12 Specification of INTRA_DC intra prediction mode
847 154396 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 154396 pixel *src = (pixel *)_src;
852 154396 const pixel *top = (const pixel *)_top;
853 154396 const pixel *left = (const pixel *)_left;
854 154396 const pixel dc = FUNC(pred_dc_val)(top, left, w, h);
855 154396 const pixel4 a = PIXEL_SPLAT_X4(dc);
856
2/2
✓ Branch 0 taken 718008 times.
✓ Branch 1 taken 77198 times.
1590412 for (y = 0; y < h; y++) {
857 1436016 pixel *s = src;
858
2/2
✓ Branch 0 taken 2840616 times.
✓ Branch 1 taken 718008 times.
7117248 for (x = 0; x < w; x += 4) {
859 5681232 AV_WN4P(s, a);
860 5681232 s += 4;
861 }
862 1436016 src += stride;
863 }
864 154396 }
865
866 173308 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 173308 pixel *src = (pixel *)_src;
870 173308 const pixel *top = (const pixel *)_top;
871
2/2
✓ Branch 0 taken 913192 times.
✓ Branch 1 taken 86654 times.
1999692 for (int y = 0; y < h; y++) {
872 1826384 memcpy(src, top, sizeof(pixel) * w);
873 1826384 src += stride;
874 }
875 173308 }
876
877 175804 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 175804 pixel *src = (pixel *)_src;
881 175804 const pixel *left = (const pixel *)_left;
882
2/2
✓ Branch 0 taken 831268 times.
✓ Branch 1 taken 87902 times.
1838340 for (int y = 0; y < h; y++) {
883 1662536 const pixel4 a = PIXEL_SPLAT_X4(left[y]);
884
2/2
✓ Branch 0 taken 3433420 times.
✓ Branch 1 taken 831268 times.
8529376 for (int x = 0; x < w; x += 4) {
885 6866840 AV_WN4P(&POS(x, y), a);
886 }
887 }
888 175804 }
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 422004 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 422004 pixel *src = (pixel *)_src;
899 422004 const pixel *left = (const pixel *)_left;
900 422004 const pixel *top = (const pixel *)_top - (1 + ref_idx);
901 422004 const int intra_pred_angle = ff_vvc_intra_pred_angle_derive(mode);
902 422004 int pos = (1 + ref_idx) * intra_pred_angle;
903 422004 const int dp = intra_pred_angle;
904 422004 const int is_luma = !c_idx;
905 int nscale, inv_angle;
906
907
2/2
✓ Branch 0 taken 44607 times.
✓ Branch 1 taken 166395 times.
422004 if (need_pdpc) {
908 89214 inv_angle = ff_vvc_intra_inv_angle_derive(intra_pred_angle);
909 89214 nscale = ff_vvc_nscale_derive(w, h, mode);
910 }
911
912
2/2
✓ Branch 0 taken 1604640 times.
✓ Branch 1 taken 211002 times.
3631284 for (int y = 0; y < h; y++) {
913 3209280 const int idx = (pos >> 5) + ref_idx;
914 3209280 const int fact = pos & 31;
915
6/6
✓ Branch 0 taken 248035 times.
✓ Branch 1 taken 1356605 times.
✓ Branch 2 taken 153637 times.
✓ Branch 3 taken 94398 times.
✓ Branch 4 taken 128869 times.
✓ Branch 5 taken 24768 times.
3209280 if (!fact && (!is_luma || !filter_flag)) {
916
2/2
✓ Branch 0 taken 2341512 times.
✓ Branch 1 taken 223267 times.
5129558 for (int x = 0; x < w; x++) {
917 4683024 const pixel *p = top + x + idx + 1;
918 4683024 POS(x, y) = *p;
919 }
920 } else {
921
2/2
✓ Branch 0 taken 1085935 times.
✓ Branch 1 taken 295438 times.
2762746 if (!c_idx) {
922 2171870 const int8_t *f = ff_vvc_intra_luma_filter[filter_flag][fact];
923
2/2
✓ Branch 0 taken 11876720 times.
✓ Branch 1 taken 1085935 times.
25925310 for (int x = 0; x < w; x++) {
924 23753440 const pixel *p = top + x + idx;
925 23753440 POS(x, y) = INTRA_LUMA_FILTER(p);
926 }
927 } else {
928
2/2
✓ Branch 0 taken 2719512 times.
✓ Branch 1 taken 295438 times.
6029900 for (int x = 0; x < w; x++) {
929 5439024 const pixel *p = top + x + idx;
930 5439024 POS(x, y) = INTRA_CHROMA_FILTER(p);
931 }
932 }
933 }
934
2/2
✓ Branch 0 taken 388540 times.
✓ Branch 1 taken 1216100 times.
3209280 if (need_pdpc) {
935 777080 int inv_angle_sum = 256 + inv_angle;
936
2/2
✓ Branch 0 taken 2107808 times.
✓ Branch 1 taken 388540 times.
4992696 for (int x = 0; x < FFMIN(w, 3 << nscale); x++) {
937 4215616 const pixel l = left[y + (inv_angle_sum >> 9)];
938 4215616 const pixel val = POS(x, y);
939 4215616 const int wl = 32 >> ((x << 1) >> nscale);
940 4215616 const int pred = val + (((l - val) * wl + 32) >> 6);
941 4215616 POS(x, y) = CLIP(pred);
942 4215616 inv_angle_sum += inv_angle;
943 }
944 }
945 3209280 pos += dp;
946 }
947 422004 }
948
949 //8.4.5.2.13 Specification of INTRA_ANGULAR2..INTRA_ANGULAR66 intra prediction modes
950 384816 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 384816 pixel *src = (pixel *)_src;
955 384816 const pixel *left = (const pixel *)_left - (1 + ref_idx);
956 384816 const pixel *top = (const pixel *)_top;
957 384816 const int is_luma = !c_idx;
958 384816 const int intra_pred_angle = ff_vvc_intra_pred_angle_derive(mode);
959 384816 const int dp = intra_pred_angle;
960 384816 int nscale = 0, inv_angle, inv_angle_sum;
961
962
2/2
✓ Branch 0 taken 37711 times.
✓ Branch 1 taken 154697 times.
384816 if (need_pdpc) {
963 75422 inv_angle = ff_vvc_intra_inv_angle_derive(intra_pred_angle);
964 75422 inv_angle_sum = 256 + inv_angle;
965 75422 nscale = ff_vvc_nscale_derive(w, h, mode);
966 }
967
968
2/2
✓ Branch 0 taken 1546952 times.
✓ Branch 1 taken 192408 times.
3478720 for (int y = 0; y < h; y++) {
969 3093904 int pos = (1 + ref_idx) * intra_pred_angle;
970 int wt;
971
2/2
✓ Branch 0 taken 423928 times.
✓ Branch 1 taken 1123024 times.
3093904 if (need_pdpc)
972 847856 wt = (32 >> FFMIN(31, (y * 2) >> nscale));
973
974
2/2
✓ Branch 0 taken 22210832 times.
✓ Branch 1 taken 1546952 times.
47515568 for (int x = 0; x < w; x++) {
975 44421664 const int idx = (pos >> 5) + ref_idx;
976 44421664 const int fact = pos & 31;
977 44421664 const pixel *p = left + y + idx;
978 int pred;
979
6/6
✓ Branch 0 taken 2093252 times.
✓ Branch 1 taken 20117580 times.
✓ Branch 2 taken 1684796 times.
✓ Branch 3 taken 408456 times.
✓ Branch 4 taken 999228 times.
✓ Branch 5 taken 685568 times.
44421664 if (!fact && (!is_luma || !filter_flag)) {
980 2815368 pred = p[1];
981 } else {
982
2/2
✓ Branch 0 taken 15962836 times.
✓ Branch 1 taken 4840312 times.
41606296 if (!c_idx) {
983 31925672 const int8_t *f = ff_vvc_intra_luma_filter[filter_flag][fact];
984 31925672 pred = INTRA_LUMA_FILTER(p);
985 } else {
986 9680624 pred = INTRA_CHROMA_FILTER(p);
987 }
988 }
989
2/2
✓ Branch 0 taken 5156672 times.
✓ Branch 1 taken 17054160 times.
44421664 if (need_pdpc) {
990
2/2
✓ Branch 0 taken 1997280 times.
✓ Branch 1 taken 3159392 times.
10313344 if (y < (3 << nscale)) {
991 3994560 const pixel t = top[x + (inv_angle_sum >> 9)];
992 3994560 pred = CLIP(pred + (((t - pred) * wt + 32) >> 6));
993 }
994 }
995 44421664 POS(x, y) = pred;
996 44421664 pos += dp;
997 }
998
2/2
✓ Branch 0 taken 423928 times.
✓ Branch 1 taken 1123024 times.
3093904 if (need_pdpc)
999 847856 inv_angle_sum += inv_angle;
1000 }
1001 384816 }
1002
1003 3156 static void FUNC(ff_vvc_intra_dsp_init)(VVCIntraDSPContext *const intra)
1004 {
1005 3156 intra->lmcs_scale_chroma = FUNC(lmcs_scale_chroma);
1006 3156 intra->intra_cclm_pred = FUNC(intra_cclm_pred);
1007 3156 intra->intra_pred = FUNC(intra_pred);
1008 3156 intra->pred_planar = FUNC(pred_planar);
1009 3156 intra->pred_mip = FUNC(pred_mip);
1010 3156 intra->pred_dc = FUNC(pred_dc);
1011 3156 intra->pred_v = FUNC(pred_v);
1012 3156 intra->pred_h = FUNC(pred_h);
1013 3156 intra->pred_angular_v = FUNC(pred_angular_v);
1014 3156 intra->pred_angular_h = FUNC(pred_angular_h);
1015 3156 }
1016