FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/vvc/intra_template.c
Date: 2025-04-25 22:50:00
Exec Total Coverage
Lines: 623 629 99.0%
Functions: 53 90 58.9%
Branches: 395 404 97.8%

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 184082 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 184082 const VVCSPS *sps = fc->ps.sps;
33
2/2
✓ Branch 0 taken 184082 times.
✓ Branch 1 taken 92041 times.
552246 for (int i = 0; i < VVC_MAX_SAMPLE_ARRAYS - 1; i++) {
34 368164 const int c_idx = i + 1;
35 368164 const int x = x0 >> sps->hshift[c_idx];
36 368164 const int y = y0 >> sps->vshift[c_idx];
37 368164 const ptrdiff_t stride = fc->frame->linesize[c_idx] / sizeof(pixel);
38 368164 pixel *src = (pixel*)fc->frame->data[c_idx] + x + y * stride;
39
2/2
✓ Branch 0 taken 1756160 times.
✓ Branch 1 taken 184082 times.
3880484 for (int y = 0; y < h; y++) {
40
2/2
✓ Branch 0 taken 27361984 times.
✓ Branch 1 taken 1756160 times.
58236288 for (int x = 0; x < w; x++) {
41 54723968 const int dsy = pdsy[y * w + x];
42 54723968 const int pred = ((dsy * a[i]) >> k[i]) + b[i];
43 54723968 POS(x, y) = CLIP(pred);
44 }
45 }
46 }
47 184082 }
48
49 #define MAX_PICK_POS 4
50 #define TOP 0
51 #define LEFT 1
52
53 1612 static av_always_inline void FUNC(cclm_get_params_default)(int *a, int *b, int *k)
54 {
55
2/2
✓ Branch 0 taken 1612 times.
✓ Branch 1 taken 806 times.
4836 for (int i = 0; i < 2; i++) {
56 3224 a[i] = k[i] = 0;
57 3224 b[i] = 1 << (BIT_DEPTH - 1);
58 }
59 1612 }
60
61 184082 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 184082 const enum IntraPredMode mode = lc->cu->intra_pred_mode_c;
66
6/6
✓ Branch 0 taken 88714 times.
✓ Branch 1 taken 3327 times.
✓ Branch 2 taken 86093 times.
✓ Branch 3 taken 2621 times.
✓ Branch 4 taken 38814 times.
✓ Branch 5 taken 47279 times.
184082 const int num_is4 = !avail_t || !avail_l || mode != INTRA_LT_CCLM;
67 int num_samp[2];
68
69
2/2
✓ Branch 0 taken 51323 times.
✓ Branch 1 taken 40718 times.
184082 if (mode == INTRA_LT_CCLM) {
70
2/2
✓ Branch 0 taken 48865 times.
✓ Branch 1 taken 2458 times.
102646 num_samp[TOP] = avail_t ? w : 0;
71
2/2
✓ Branch 0 taken 49737 times.
✓ Branch 1 taken 1586 times.
102646 num_samp[LEFT] = avail_l ? h : 0;
72 } else {
73
4/4
✓ Branch 0 taken 39849 times.
✓ Branch 1 taken 869 times.
✓ Branch 2 taken 20808 times.
✓ Branch 3 taken 19041 times.
81436 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 39683 times.
✓ Branch 1 taken 1035 times.
✓ Branch 2 taken 19104 times.
✓ Branch 3 taken 20579 times.
81436 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 22368 times.
✓ Branch 1 taken 69673 times.
✓ Branch 2 taken 806 times.
✓ Branch 3 taken 21562 times.
184082 if (!num_samp[TOP] && !num_samp[LEFT]) {
77 1612 return 0;
78 }
79
2/2
✓ Branch 0 taken 182470 times.
✓ Branch 1 taken 91235 times.
547410 for (int i = TOP; i <= LEFT; i++) {
80 364940 const int start = num_samp[i] >> (2 + num_is4);
81 364940 const int step = FFMAX(1, num_samp[i] >> (1 + num_is4)) ;
82 364940 cnt[i] = FFMIN(num_samp[i], (1 + num_is4) << 1);
83
2/2
✓ Branch 0 taken 363568 times.
✓ Branch 1 taken 182470 times.
1092076 for (int c = 0; c < cnt[i]; c++)
84 727136 pos[i][c] = start + c * step;
85 }
86 182470 return 1;
87 }
88
89 51764 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 51764 times.
✓ Branch 1 taken 25882 times.
155292 for (int i = 0; i < cnt; i++)
93 103528 sel_luma[i] = src[pos[i] * step];
94 51764 }
95
96 182470 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 182470 const VVCSPS *sps = fc->ps.sps;
101
102 182470 const int b_ctu_boundary = !av_zero_extend(y0, sps->ctb_log2_size_y);
103 182470 const int hs = sps->hshift[1];
104 182470 const int vs = sps->vshift[1];
105 182470 const ptrdiff_t stride = fc->frame->linesize[0] / sizeof(pixel);
106
107
3/4
✓ Branch 0 taken 12941 times.
✓ Branch 1 taken 78294 times.
✓ Branch 2 taken 12941 times.
✗ Branch 3 not taken.
208352 if (!hs && !vs) {
108 25882 const pixel* src = (pixel*)fc->frame->data[0] + x0 + y0 * stride;
109 25882 FUNC(cclm_select_luma_444)(src - avail_t * stride, 1, cnt[TOP], pos[TOP], sel_luma);
110 25882 FUNC(cclm_select_luma_444)(src - avail_l, stride, cnt[LEFT], pos[LEFT], sel_luma + cnt[TOP]);
111 } else {
112 // top
113
3/4
✓ Branch 0 taken 78294 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 66790 times.
✓ Branch 3 taken 11504 times.
290168 if (vs && !b_ctu_boundary) {
114 133580 const pixel *source = (pixel *)fc->frame->data[0] + x0 + (y0 - 2) * stride;
115
2/2
✓ Branch 0 taken 139678 times.
✓ Branch 1 taken 66790 times.
412936 for (int i = 0; i < cnt[TOP]; i++) {
116 279356 const int x = pos[TOP][i] << hs;
117 279356 const pixel *src = source + x;
118
4/4
✓ Branch 0 taken 2675 times.
✓ Branch 1 taken 137003 times.
✓ Branch 2 taken 2436 times.
✓ Branch 3 taken 239 times.
279356 const int has_left = x || avail_l;
119
2/2
✓ Branch 0 taken 139439 times.
✓ Branch 1 taken 239 times.
279356 const pixel l = has_left ? POS(-1, 0) : POS(0, 0);
120
2/2
✓ Branch 0 taken 4240 times.
✓ Branch 1 taken 135438 times.
279356 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 135199 times.
✓ Branch 1 taken 239 times.
270876 const pixel l1 = has_left ? POS(-1, 1) : POS(0, 1);
124 270876 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 23008 const pixel *source = (pixel*)fc->frame->data[0] + x0 + (y0 - 1) * stride;
129
2/2
✓ Branch 0 taken 17888 times.
✓ Branch 1 taken 11504 times.
58784 for (int i = 0; i < cnt[TOP]; i++) {
130 35776 const int x = pos[TOP][i] << hs;
131 35776 const pixel *src = source + x;
132
4/4
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 17854 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 27 times.
35776 const int has_left = x || avail_l;
133
2/2
✓ Branch 0 taken 17861 times.
✓ Branch 1 taken 27 times.
35776 const pixel l = has_left ? POS(-1, 0) : POS(0, 0);
134 35776 sel_luma[i] = (l + 2 * POS(0, 0) + POS(1, 0) + 2) >> 2;
135 }
136 }
137
138 // left
139 {
140 const pixel *left;
141 156588 const pixel *source = (pixel *)fc->frame->data[0] + x0 + y0 * stride - (1 + hs) * avail_l;
142 156588 left = source - avail_l;
143
144
2/2
✓ Branch 0 taken 154238 times.
✓ Branch 1 taken 78294 times.
465064 for (int i = 0; i < cnt[LEFT]; i++) {
145 308476 const int y = pos[LEFT][i] << vs;
146 308476 const int offset = y * stride;
147 308476 const pixel *l = left + offset;
148 308476 const pixel *src = source + offset;
149 pixel pred;
150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 154238 times.
308476 if (!vs) {
151 pred = (*l + 2 * POS(0, 0) + POS(1, 0) + 2) >> 2;
152 } else {
153
2/2
✓ Branch 0 taken 6058 times.
✓ Branch 1 taken 148180 times.
308476 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 296360 pred = (*l + *(l + stride) + 2 * POS(0, 0) + 2 * POS(0, 1) + POS(1, 0) + POS(1, 1) + 4) >> 3;
159 }
160 }
161 308476 sel_luma[i + cnt[TOP]] = pred;
162 }
163 }
164 }
165 182470 }
166
167 182470 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 182470 times.
✓ Branch 1 taken 91235 times.
547410 for (int c_idx = 1; c_idx < VVC_MAX_SAMPLE_ARRAYS; c_idx++) {
172 364940 const ptrdiff_t stride = fc->frame->linesize[c_idx] / sizeof(pixel);
173
174 //top
175 364940 const pixel *src = (pixel*)fc->frame->data[c_idx] + x + (y - 1)* stride;
176
2/2
✓ Branch 0 taken 368268 times.
✓ Branch 1 taken 182470 times.
1101476 for (int i = 0; i < cnt[TOP]; i++) {
177 736536 sel[c_idx][i] = src[pos[TOP][i]];
178 }
179
180 //left
181 364940 src = (pixel*)fc->frame->data[c_idx] + x - 1 + y * stride;
182
2/2
✓ Branch 0 taken 358868 times.
✓ Branch 1 taken 182470 times.
1082676 for (int i = 0; i < cnt[LEFT]; i++) {
183 717736 sel[c_idx][i + cnt[TOP]] = src[pos[LEFT][i] * stride];
184 }
185 }
186 182470 }
187
188 184082 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 184082 const VVCFrameContext *fc = lc->fc;
193 184082 const VVCSPS *sps = fc->ps.sps;
194 184082 const int x = x0 >> sps->hshift[1];
195 184082 const int y = y0 >> sps->vshift[1];
196 int cnt[2], pos[2][MAX_PICK_POS];
197
198
2/2
✓ Branch 1 taken 806 times.
✓ Branch 2 taken 91235 times.
184082 if (!FUNC(cclm_get_select_pos)(lc, x, y, w, h, avail_t, avail_l, cnt, pos))
199 1612 return 0;
200
201 182470 FUNC(cclm_select_luma)(fc, x0, y0, avail_t, avail_l, cnt, pos, sel[LUMA]);
202 182470 FUNC(cclm_select_chroma)(fc, x, y, cnt, pos, sel);
203
204
2/2
✓ Branch 0 taken 686 times.
✓ Branch 1 taken 90549 times.
182470 if (cnt[TOP] + cnt[LEFT] == 2) {
205
2/2
✓ Branch 0 taken 2058 times.
✓ Branch 1 taken 686 times.
5488 for (int c_idx = 0; c_idx < VVC_MAX_SAMPLE_ARRAYS; c_idx++) {
206 4116 sel[c_idx][3] = sel[c_idx][0];
207 4116 sel[c_idx][2] = sel[c_idx][1];
208 4116 sel[c_idx][0] = sel[c_idx][1];
209 4116 sel[c_idx][1] = sel[c_idx][3];
210 }
211 }
212 182470 return 1;
213 }
214
215 182470 static av_always_inline void FUNC(cclm_get_min_max)(
216 const pixel sel[][MAX_PICK_POS * 2], int *min, int *max)
217 {
218 182470 int min_grp_idx[] = { 0, 2 };
219 182470 int max_grp_idx[] = { 1, 3 };
220
221
2/2
✓ Branch 0 taken 43016 times.
✓ Branch 1 taken 48219 times.
182470 if (sel[LUMA][min_grp_idx[0]] > sel[LUMA][min_grp_idx[1]])
222 86032 FFSWAP(int, min_grp_idx[0], min_grp_idx[1]);
223
2/2
✓ Branch 0 taken 43816 times.
✓ Branch 1 taken 47419 times.
182470 if (sel[LUMA][max_grp_idx[0]] > sel[LUMA][max_grp_idx[1]])
224 87632 FFSWAP(int, max_grp_idx[0], max_grp_idx[1]);
225
2/2
✓ Branch 0 taken 8980 times.
✓ Branch 1 taken 82255 times.
182470 if (sel[LUMA][min_grp_idx[0]] > sel[LUMA][max_grp_idx[1]]) {
226 17960 FFSWAP(int, min_grp_idx[0], max_grp_idx[0]);
227 17960 FFSWAP(int, min_grp_idx[1], max_grp_idx[1]);
228 }
229
2/2
✓ Branch 0 taken 68244 times.
✓ Branch 1 taken 22991 times.
182470 if (sel[LUMA][min_grp_idx[1]] > sel[LUMA][max_grp_idx[0]])
230 136488 FFSWAP(int, min_grp_idx[1], max_grp_idx[0]);
231
2/2
✓ Branch 0 taken 273705 times.
✓ Branch 1 taken 91235 times.
729880 for (int c_idx = 0; c_idx < VVC_MAX_SAMPLE_ARRAYS; c_idx++) {
232 547410 max[c_idx] = (sel[c_idx][max_grp_idx[0]] + sel[c_idx][max_grp_idx[1]] + 1) >> 1;
233 547410 min[c_idx] = (sel[c_idx][min_grp_idx[0]] + sel[c_idx][min_grp_idx[1]] + 1) >> 1;
234 }
235 182470 }
236
237 184082 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 806 times.
✓ Branch 2 taken 91235 times.
184082 if (!FUNC(cclm_select_samples)(lc, x0, y0, w, h, avail_t, avail_l, sel)) {
246 1612 FUNC(cclm_get_params_default)(a, b, k);
247 10002 return;
248 }
249
250 182470 FUNC(cclm_get_min_max)(sel, min, max);
251
252 182470 diff = max[LUMA] - min[LUMA];
253
2/2
✓ Branch 0 taken 4195 times.
✓ Branch 1 taken 87040 times.
182470 if (diff == 0) {
254
2/2
✓ Branch 0 taken 8390 times.
✓ Branch 1 taken 4195 times.
25170 for (int i = 0; i < 2; i++) {
255 16780 a[i] = k[i] = 0;
256 16780 b[i] = min[i + 1];
257 }
258 8390 return;
259 }
260
2/2
✓ Branch 0 taken 174080 times.
✓ Branch 1 taken 87040 times.
522240 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 348160 const int diffc = max[i + 1] - min[i + 1];
263 348160 int x = av_log2(diff);
264 int y, v, sign, add;
265 348160 const int norm_diff = ((diff << 4) >> x) & 15;
266 348160 x += (norm_diff) ? 1 : 0;
267
2/2
✓ Branch 0 taken 155293 times.
✓ Branch 1 taken 18787 times.
348160 y = abs(diffc) > 0 ? av_log2(abs(diffc)) + 1 : 0;
268 348160 v = div_sig_table[norm_diff] | 8;
269 348160 add = (1 << y >> 1);
270 348160 a[i] = (diffc * v + add) >> y;
271 348160 k[i] = FFMAX(1, 3 + x -y);
272
2/2
✓ Branch 0 taken 77125 times.
✓ Branch 1 taken 96955 times.
348160 sign = a[i] < 0 ? -1 : (a[i] > 0);
273
2/2
✓ Branch 0 taken 1715 times.
✓ Branch 1 taken 172365 times.
348160 a[i] = ((3 + x - y) < 1) ? sign * 15 : a[i];
274 348160 b[i] = min[i + 1] - ((a[i] * min[0]) >> k[i]);
275 }
276
277 }
278
279 #undef TOP
280 #undef LEFT
281
282 184082 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 184082 const int hs = fc->ps.sps->hshift[1];
287 184082 const int vs = fc->ps.sps->vshift[1];
288 184082 const ptrdiff_t stride = fc->frame->linesize[0] / sizeof(pixel);
289 184082 const pixel *source = (pixel*)fc->frame->data[0] + x0 + y0 * stride;
290 184082 const pixel *left = source - avail_l;
291 184082 const pixel *top = source - avail_t * stride;
292
293 184082 const VVCSPS *sps = fc->ps.sps;
294
3/4
✓ Branch 0 taken 12944 times.
✓ Branch 1 taken 79097 times.
✓ Branch 2 taken 12944 times.
✗ Branch 3 not taken.
184082 if (!hs && !vs) {
295
2/2
✓ Branch 0 taken 178996 times.
✓ Branch 1 taken 12944 times.
383880 for (int i = 0; i < h; i++)
296 357992 memcpy(pdsy + i * w, source + i * stride, w * sizeof(pixel));
297 25888 return;
298 }
299
2/2
✓ Branch 0 taken 699084 times.
✓ Branch 1 taken 79097 times.
1556362 for (int i = 0; i < h; i++) {
300 1398168 const pixel *src = source;
301 1398168 const pixel *l = left;
302 1398168 const pixel *t = top;
303
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 699084 times.
1398168 if (!vs) {
304 for (int j = 0; j < w; j++) {
305 pixel pred = (*l + 2 * POS(0, 0) + POS(1, 0) + 2) >> 2;
306 pdsy[i * w + j] = pred;
307 src += 2;
308 l = src - 1;
309 }
310
311 } else {
312
2/2
✓ Branch 0 taken 54676 times.
✓ Branch 1 taken 644408 times.
1398168 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 8849904 times.
✓ Branch 1 taken 644408 times.
18988624 for (int j = 0; j < w; j++) {
322 17699808 pixel pred = (*l + *(l + stride) + 2 * POS(0, 0) + 2 * POS(0, 1) + POS(1, 0) + POS(1, 1) + 4) >> 3;
323
324 17699808 pdsy[i * w + j] = pred;
325 17699808 src += 2;
326 17699808 l = src - 1;
327 }
328 }
329 }
330 1398168 source += (stride << vs);
331 1398168 left += (stride << vs);
332 1398168 top = source - stride;
333 }
334 }
335
336 578 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 578 times.
✓ Branch 1 taken 289 times.
1734 for (int c_idx = 1; c_idx < VVC_MAX_SAMPLE_ARRAYS; c_idx++) {
340 1156 const ptrdiff_t stride = fc->frame->linesize[c_idx] / sizeof(pixel);
341 1156 pixel *dst = (pixel*)fc->frame->data[c_idx] + x + y * stride;
342
2/2
✓ Branch 0 taken 10416 times.
✓ Branch 1 taken 578 times.
21988 for (int i = 0; i < h; i++) {
343
2/2
✓ Branch 0 taken 268032 times.
✓ Branch 1 taken 10416 times.
556896 for (int j = 0; j < w; j++) {
344 536064 dst[j] = 1 << (BIT_DEPTH - 1);
345 }
346 20832 dst += stride;
347 }
348 }
349 578 }
350
351 //8.4.5.2.14 Specification of INTRA_LT_CCLM, INTRA_L_CCLM and INTRA_T_CCLM intra prediction mode
352 184660 static void FUNC(intra_cclm_pred)(const VVCLocalContext *lc, const int x0, const int y0,
353 const int width, const int height)
354 {
355 184660 VVCFrameContext *fc = lc->fc;
356 184660 const VVCSPS *sps = fc->ps.sps;
357 184660 const int avail_t = ff_vvc_get_top_available(lc, x0, y0, 1, 0);
358 184660 const int avail_l = ff_vvc_get_left_available(lc, x0, y0, 1, 0);
359 184660 const int hs = sps->hshift[1];
360 184660 const int vs = sps->vshift[1];
361 184660 const int x = x0 >> hs;
362 184660 const int y = y0 >> vs;
363 184660 const int w = width >> hs;
364 184660 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 3616 times.
✓ Branch 1 taken 88714 times.
✓ Branch 2 taken 289 times.
✓ Branch 3 taken 3327 times.
184660 if (!avail_t && !avail_l) {
369 578 FUNC(cclm_pred_default)(fc, x, y, w, h, avail_t, avail_l);
370 578 return;
371 }
372 184082 FUNC(cclm_get_luma_rec_pixels)(fc, x0, y0, w, h, avail_t, avail_l, dsy);
373 184082 FUNC(cclm_get_params) (lc, x0, y0, w, h, avail_t, avail_l, a, b, k);
374 184082 FUNC(cclm_linear_pred)(fc, x0, y0, w, h, dsy, a, b, k);
375 }
376
377 37836 static int FUNC(lmcs_sum_samples)(const pixel *start, ptrdiff_t stride, const int avail, const int target_size)
378 {
379 37836 const int size = FFMIN(avail, target_size);
380 37836 int sum = 0;
381
2/2
✓ Branch 0 taken 1188040 times.
✓ Branch 1 taken 18918 times.
2413916 for (int i = 0; i < size; i++) {
382 2376080 sum += *start;
383 2376080 start += stride;
384 }
385 37836 sum += *(start - stride) * (target_size - size);
386 37836 return sum;
387 }
388
389 // 8.7.5.3 Picture reconstruction with luma dependent chroma residual scaling process for chroma samples
390 286724 static int FUNC(lmcs_derive_chroma_scale)(VVCLocalContext *lc, const int x0, const int y0)
391 {
392 286724 VVCFrameContext *fc = lc->fc;
393 286724 const VVCLMCS *lmcs = &fc->ps.lmcs;
394 286724 const int size_y = FFMIN(fc->ps.sps->ctb_size_y, 64);
395
396 286724 const int x = x0 & ~(size_y - 1);
397 286724 const int y = y0 & ~(size_y - 1);
398
4/4
✓ Branch 0 taken 133273 times.
✓ Branch 1 taken 10089 times.
✓ Branch 2 taken 879 times.
✓ Branch 3 taken 132394 times.
286724 if (lc->lmcs.x_vpdu != x || lc->lmcs.y_vpdu != y) {
399 21936 int cnt = 0, luma = 0, i;
400 21936 const pixel *src = (const pixel *)(fc->frame->data[LUMA] + y * fc->frame->linesize[LUMA] + (x << fc->ps.sps->pixel_shift));
401 21936 const ptrdiff_t stride = fc->frame->linesize[LUMA] / sizeof(pixel);
402 21936 const int avail_t = ff_vvc_get_top_available (lc, x, y, 1, 0);
403 21936 const int avail_l = ff_vvc_get_left_available(lc, x, y, 1, 0);
404
2/2
✓ Branch 0 taken 9682 times.
✓ Branch 1 taken 1286 times.
21936 if (avail_l) {
405 19364 luma += FUNC(lmcs_sum_samples)(src - 1, stride, fc->ps.pps->height - y, size_y);
406 19364 cnt = size_y;
407 }
408
2/2
✓ Branch 0 taken 9236 times.
✓ Branch 1 taken 1732 times.
21936 if (avail_t) {
409 18472 luma += FUNC(lmcs_sum_samples)(src - stride, 1, fc->ps.pps->width - x, size_y);
410 18472 cnt += size_y;
411 }
412
2/2
✓ Branch 0 taken 10634 times.
✓ Branch 1 taken 334 times.
21936 if (cnt)
413 21268 luma = (luma + (cnt >> 1)) >> av_log2(cnt);
414 else
415 668 luma = 1 << (BIT_DEPTH - 1);
416
417
2/2
✓ Branch 0 taken 65112 times.
✓ Branch 1 taken 466 times.
131156 for (i = lmcs->min_bin_idx; i <= lmcs->max_bin_idx; i++) {
418
2/2
✓ Branch 0 taken 10502 times.
✓ Branch 1 taken 54610 times.
130224 if (luma < lmcs->pivot[i + 1])
419 21004 break;
420 }
421 21936 i = FFMIN(i, LMCS_MAX_BIN_SIZE - 1);
422
423 21936 lc->lmcs.chroma_scale = lmcs->chroma_scale_coeff[i];
424 21936 lc->lmcs.x_vpdu = x;
425 21936 lc->lmcs.y_vpdu = y;
426 }
427 286724 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 286724 static void FUNC(lmcs_scale_chroma)(VVCLocalContext *lc, int *dst, const int *coeff,
432 const int width, const int height, const int x0_cu, const int y0_cu)
433 {
434 286724 const int chroma_scale = FUNC(lmcs_derive_chroma_scale)(lc, x0_cu, y0_cu);
435
436
2/2
✓ Branch 0 taken 1507990 times.
✓ Branch 1 taken 143362 times.
3302704 for (int y = 0; y < height; y++) {
437
2/2
✓ Branch 0 taken 24352368 times.
✓ Branch 1 taken 1507990 times.
51720716 for (int x = 0; x < width; x++) {
438 48704736 const int c = av_clip_intp2(*coeff, BIT_DEPTH);
439
440
2/2
✓ Branch 0 taken 10888622 times.
✓ Branch 1 taken 13463746 times.
48704736 if (c > 0)
441 21777244 *dst = (c * chroma_scale + (1 << 10)) >> 11;
442 else
443 26927492 *dst = -((-c * chroma_scale + (1 << 10)) >> 11);
444 48704736 coeff++;
445 48704736 dst++;
446 }
447 }
448 286724 }
449
450 236782 static av_always_inline void FUNC(ref_filter)(const pixel *left, const pixel *top,
451 pixel *filtered_left, pixel *filtered_top, const int left_size, const int top_size,
452 const int unfilter_last_one)
453 {
454 236782 filtered_left[-1] = filtered_top[-1] = (left[0] + 2 * left[-1] + top[0] + 2 ) >> 2;
455
2/2
✓ Branch 0 taken 1976978 times.
✓ Branch 1 taken 118391 times.
4190738 for (int i = 0; i < left_size - unfilter_last_one; i++) {
456 3953956 filtered_left[i] = (left[i- 1] + 2 * left[i] + left[i + 1] + 2) >> 2;
457 }
458
2/2
✓ Branch 0 taken 2288394 times.
✓ Branch 1 taken 118391 times.
4813570 for (int i = 0; i < top_size - unfilter_last_one; i++) {
459 4576788 filtered_top[i] = (top[i-1] + 2 * top[i] + top[i + 1] + 2) >> 2;
460 }
461
2/2
✓ Branch 0 taken 5384 times.
✓ Branch 1 taken 113007 times.
236782 if (unfilter_last_one) {
462 10768 filtered_top[top_size - 1] = top[top_size - 1];
463 10768 filtered_left[left_size - 1] = left[left_size - 1];
464 }
465 236782 }
466
467 2082926 static av_always_inline void FUNC(prepare_intra_edge_params)(const VVCLocalContext *lc,
468 IntraEdgeParams* edge, const pixel *src, const ptrdiff_t stride,
469 const int x, int y, int w, int h, int c_idx, const int is_intra_mip,
470 const int mode, const int ref_idx, const int need_pdpc)
471 {
472 #define EXTEND(ptr, val, len) \
473 do { \
474 for (i = 0; i < (len); i++) \
475 *(ptr + i) = val; \
476 } while (0)
477 2082926 const CodingUnit *cu = lc->cu;
478
2/2
✓ Branch 0 taken 932478 times.
✓ Branch 1 taken 108985 times.
2082926 const int ref_filter_flag = is_intra_mip ? 0 : ff_vvc_ref_filter_flag_derive(mode);
479
4/4
✓ Branch 0 taken 514091 times.
✓ Branch 1 taken 483767 times.
✓ Branch 2 taken 365553 times.
✓ Branch 3 taken 148538 times.
1995716 const int filter_flag = !ref_idx && w * h > 32 && !c_idx &&
480
6/6
✓ Branch 0 taken 997858 times.
✓ Branch 1 taken 43605 times.
✓ Branch 2 taken 309659 times.
✓ Branch 3 taken 55894 times.
✓ Branch 4 taken 118391 times.
✓ Branch 5 taken 191268 times.
4078642 cu->isp_split_type == ISP_NO_SPLIT && ref_filter_flag;
481 2082926 int cand_up_left = lc->na.cand_up_left;
482 2082926 pixel *left = (pixel*)edge->left_array + MAX_TB_SIZE + 3;
483 2082926 pixel *top = (pixel*)edge->top_array + MAX_TB_SIZE + 3;
484 2082926 pixel *filtered_left = (pixel*)edge->filtered_left_array + MAX_TB_SIZE + 3;
485 2082926 pixel *filtered_top = (pixel*)edge->filtered_top_array + MAX_TB_SIZE + 3;
486 2082926 const int ref_line = ref_idx == 3 ? -4 : (-1 - ref_idx);
487 int left_size, top_size, unfilter_left_size, unfilter_top_size;
488 int left_available, top_available;
489 int refw, refh;
490 int intra_pred_angle, inv_angle;
491 int i;
492
493
4/4
✓ Branch 0 taken 932478 times.
✓ Branch 1 taken 108985 times.
✓ Branch 2 taken 362647 times.
✓ Branch 3 taken 569831 times.
2082926 if (is_intra_mip || mode == INTRA_PLANAR) {
494 943264 left_size = h + 1;
495 943264 top_size = w + 1;
496 943264 unfilter_left_size = left_size + filter_flag;
497 943264 unfilter_top_size = top_size + filter_flag;
498
2/2
✓ Branch 0 taken 69715 times.
✓ Branch 1 taken 500116 times.
1139662 } else if (mode == INTRA_DC) {
499 139430 unfilter_left_size = left_size = h;
500 139430 unfilter_top_size = top_size = w;
501
2/2
✓ Branch 0 taken 55439 times.
✓ Branch 1 taken 444677 times.
1000232 } else if (mode == INTRA_VERT) {
502 //we may need 1 pixel to predict the top left.
503
2/2
✓ Branch 0 taken 46511 times.
✓ Branch 1 taken 8928 times.
110878 unfilter_left_size = left_size = need_pdpc ? h : 1;
504 110878 unfilter_top_size = top_size = w;
505
2/2
✓ Branch 0 taken 55162 times.
✓ Branch 1 taken 389515 times.
889354 } else if (mode == INTRA_HORZ) {
506 110324 unfilter_left_size = left_size = h;
507 //even need_pdpc == 0, we may need 1 pixel to predict the top left.
508
2/2
✓ Branch 0 taken 42398 times.
✓ Branch 1 taken 12764 times.
110324 unfilter_top_size = top_size = need_pdpc ? w : 1;
509 } else {
510
4/4
✓ Branch 0 taken 89825 times.
✓ Branch 1 taken 299690 times.
✓ Branch 2 taken 2870 times.
✓ Branch 3 taken 86955 times.
779030 if (cu->isp_split_type == ISP_NO_SPLIT || c_idx) {
511 605120 refw = w * 2;
512 605120 refh = h * 2;
513 } else {
514 173910 refw = cu->cb_width + w;
515 173910 refh = cu->cb_height + h;
516 }
517 779030 intra_pred_angle = ff_vvc_intra_pred_angle_derive(mode);
518 779030 inv_angle = ff_vvc_intra_inv_angle_derive(intra_pred_angle);
519 779030 unfilter_top_size = top_size = refw;
520 779030 unfilter_left_size = left_size = refh;
521 }
522
523 2082926 left_available = ff_vvc_get_left_available(lc, x, y, unfilter_left_size, c_idx);
524
2/2
✓ Branch 0 taken 10811317 times.
✓ Branch 1 taken 1041463 times.
23705560 for (i = 0; i < left_available; i++)
525 21622634 left[i] = POS(ref_line, i);
526
527 2082926 top_available = ff_vvc_get_top_available(lc, x, y, unfilter_top_size, c_idx);
528 2082926 memcpy(top, src + ref_line * stride, top_available * sizeof(pixel));
529
530
2/2
✓ Branch 0 taken 1110627 times.
✓ Branch 1 taken 1041463 times.
4304180 for (int i = -1; i >= ref_line; i--) {
531
2/2
✓ Branch 0 taken 1061333 times.
✓ Branch 1 taken 49294 times.
2221254 if (cand_up_left) {
532 2122666 left[i] = POS(ref_line, i);
533 2122666 top[i] = POS(i, ref_line);
534
2/2
✓ Branch 0 taken 22154 times.
✓ Branch 1 taken 27140 times.
98588 } else if (left_available) {
535 44308 left[i] = top[i] = left[0];
536
2/2
✓ Branch 0 taken 26111 times.
✓ Branch 1 taken 1029 times.
54280 } else if (top_available) {
537 52222 left[i] = top[i] = top[0];
538 } else {
539 2058 left[i] = top[i] = 1 << (BIT_DEPTH - 1);
540 }
541 }
542
543
2/2
✓ Branch 0 taken 3541163 times.
✓ Branch 1 taken 1041463 times.
9165252 EXTEND(top + top_available, top[top_available-1], unfilter_top_size - top_available);
544
2/2
✓ Branch 0 taken 2725942 times.
✓ Branch 1 taken 1041463 times.
7534810 EXTEND(left + left_available, left[left_available-1], unfilter_left_size - left_available);
545
546
2/2
✓ Branch 0 taken 389348 times.
✓ Branch 1 taken 652115 times.
2082926 if (ref_filter_flag) {
547
8/8
✓ Branch 0 taken 388410 times.
✓ Branch 1 taken 938 times.
✓ Branch 2 taken 218149 times.
✓ Branch 3 taken 170261 times.
✓ Branch 4 taken 145247 times.
✓ Branch 5 taken 72902 times.
✓ Branch 6 taken 118391 times.
✓ Branch 7 taken 26856 times.
778696 if (!ref_idx && w * h > 32 && !c_idx && cu->isp_split_type == ISP_NO_SPLIT ) {
548 236782 const int unfilter_last_one = left_size == unfilter_left_size;
549 236782 FUNC(ref_filter)(left, top, filtered_left, filtered_top, unfilter_left_size, unfilter_top_size, unfilter_last_one);
550 236782 left = filtered_left;
551 236782 top = filtered_top;
552 }
553 }
554
6/6
✓ Branch 0 taken 932478 times.
✓ Branch 1 taken 108985 times.
✓ Branch 2 taken 569831 times.
✓ Branch 3 taken 362647 times.
✓ Branch 4 taken 500116 times.
✓ Branch 5 taken 69715 times.
2082926 if (!is_intra_mip && mode != INTRA_PLANAR && mode != INTRA_DC) {
555
6/6
✓ Branch 0 taken 473415 times.
✓ Branch 1 taken 26701 times.
✓ Branch 2 taken 436648 times.
✓ Branch 3 taken 36767 times.
✓ Branch 4 taken 107038 times.
✓ Branch 5 taken 329610 times.
1000232 if (ref_filter_flag || ref_idx || cu->isp_split_type != ISP_NO_SPLIT) {
556 341012 edge->filter_flag = 0;
557 } else {
558 659220 const int min_dist_ver_hor = FFMIN(abs(mode - 50), abs(mode - 18));
559 659220 const int intra_hor_ver_dist_thres[] = {24, 14, 2, 0, 0};
560 659220 const int ntbs = (av_log2(w) + av_log2(h)) >> 1;
561 659220 edge->filter_flag = min_dist_ver_hor > intra_hor_ver_dist_thres[ntbs - 2];
562 }
563
564
4/4
✓ Branch 0 taken 444677 times.
✓ Branch 1 taken 55439 times.
✓ Branch 2 taken 389515 times.
✓ Branch 3 taken 55162 times.
1000232 if (mode != INTRA_VERT && mode != INTRA_HORZ) {
565
2/2
✓ Branch 0 taken 204025 times.
✓ Branch 1 taken 185490 times.
779030 if (mode >= INTRA_DIAG) {
566
2/2
✓ Branch 0 taken 103833 times.
✓ Branch 1 taken 100192 times.
408050 if (intra_pred_angle < 0) {
567 207666 pixel *p = top - (ref_idx + 1);
568
2/2
✓ Branch 0 taken 850372 times.
✓ Branch 1 taken 103833 times.
1908410 for (int x = -h; x < 0; x++) {
569 1700744 const int idx = -1 - ref_idx + FFMIN((x*inv_angle + 256) >> 9, h);
570 1700744 p[x] = left[idx];
571 }
572 } else {
573
2/2
✓ Branch 0 taken 218771 times.
✓ Branch 1 taken 100192 times.
637926 for (int i = refw; i <= refw + FFMAX(1, w/h) * ref_idx + 1; i++)
574 437542 top[i] = top[refw - 1];
575 }
576 } else {
577
2/2
✓ Branch 0 taken 96680 times.
✓ Branch 1 taken 88810 times.
370980 if (intra_pred_angle < 0) {
578 193360 pixel *p = left - (ref_idx + 1);
579
2/2
✓ Branch 0 taken 1436832 times.
✓ Branch 1 taken 96680 times.
3067024 for (int x = -w; x < 0; x++) {
580 2873664 const int idx = -1 - ref_idx + FFMIN((x*inv_angle + 256) >> 9, w);
581 2873664 p[x] = top[idx];
582 }
583 } else {
584
2/2
✓ Branch 0 taken 194068 times.
✓ Branch 1 taken 88810 times.
565756 for (int i = refh; i <= refh + FFMAX(1, h/w) * ref_idx + 1; i++)
585 388136 left[i] = left[refh - 1];
586 }
587 }
588 }
589 }
590 2082926 edge->left = (uint8_t*)left;
591 2082926 edge->top = (uint8_t*)top;
592 2082926 }
593
594 //8.4.1 General decoding process for coding units coded in intra prediction mode
595 2082926 static void FUNC(intra_pred)(const VVCLocalContext *lc, int x0, int y0,
596 const int width, const int height, int c_idx)
597 {
598 2082926 VVCFrameContext *fc = lc->fc;
599 2082926 const VVCSPS *sps = fc->ps.sps;
600 2082926 const VVCPPS *pps = fc->ps.pps;
601 2082926 const CodingUnit *cu = lc->cu;
602 2082926 const int log2_min_cb_size = sps->min_cb_log2_size_y;
603 2082926 const int min_cb_width = pps->min_cb_width;
604 2082926 const int x_cb = x0 >> log2_min_cb_size;
605 2082926 const int y_cb = y0 >> log2_min_cb_size;
606
607 2082926 const int hshift = fc->ps.sps->hshift[c_idx];
608 2082926 const int vshift = fc->ps.sps->vshift[c_idx];
609 2082926 const int x = x0 >> hshift;
610 2082926 const int y = y0 >> vshift;
611 2082926 const int w = width >> hshift;
612 2082926 const int h = height >> vshift;
613 2082926 const ptrdiff_t stride = fc->frame->linesize[c_idx] / sizeof(pixel);
614
615
2/2
✓ Branch 0 taken 299954 times.
✓ Branch 1 taken 741509 times.
2082926 const int pred_mode = c_idx ? cu->intra_pred_mode_c : cu->intra_pred_mode_y;
616 2082926 const int mode = ff_vvc_wide_angle_mode_mapping(cu, w, h, c_idx, pred_mode);
617
618 2082926 const int intra_mip_flag = SAMPLE_CTB(fc->tab.imf, x_cb, y_cb);
619
6/6
✓ Branch 0 taken 162933 times.
✓ Branch 1 taken 878530 times.
✓ Branch 2 taken 54236 times.
✓ Branch 3 taken 108697 times.
✓ Branch 4 taken 288 times.
✓ Branch 5 taken 53948 times.
2082926 const int is_intra_mip = intra_mip_flag && (!c_idx || cu->mip_chroma_direct_flag);
620
2/2
✓ Branch 0 taken 741509 times.
✓ Branch 1 taken 299954 times.
2082926 const int ref_idx = c_idx ? 0 : cu->intra_luma_ref_idx;
621 2082926 const int need_pdpc = ff_vvc_need_pdpc(w, h, cu->bdpcm_flag[c_idx], mode, ref_idx);
622
623
624 2082926 pixel *src = (pixel*)fc->frame->data[c_idx] + x + y * stride;
625 IntraEdgeParams edge;
626
627 2082926 FUNC(prepare_intra_edge_params)(lc, &edge, src, stride, x, y, w, h, c_idx, is_intra_mip, mode, ref_idx, need_pdpc);
628
629
2/2
✓ Branch 0 taken 108985 times.
✓ Branch 1 taken 932478 times.
2082926 if (is_intra_mip) {
630 int intra_mip_transposed_flag;
631 int intra_mip_mode;
632 217970 unpack_mip_info(&intra_mip_transposed_flag, &intra_mip_mode, intra_mip_flag);
633
634 217970 fc->vvcdsp.intra.pred_mip((uint8_t *)src, edge.top, edge.left,
635 w, h, stride, intra_mip_mode, intra_mip_transposed_flag);
636
2/2
✓ Branch 0 taken 362647 times.
✓ Branch 1 taken 569831 times.
1864956 } else if (mode == INTRA_PLANAR) {
637 725294 fc->vvcdsp.intra.pred_planar((uint8_t *)src, edge.top, edge.left, w, h, stride);
638
2/2
✓ Branch 0 taken 69715 times.
✓ Branch 1 taken 500116 times.
1139662 } else if (mode == INTRA_DC) {
639 139430 fc->vvcdsp.intra.pred_dc((uint8_t *)src, edge.top, edge.left, w, h, stride);
640
2/2
✓ Branch 0 taken 55439 times.
✓ Branch 1 taken 444677 times.
1000232 } else if (mode == INTRA_VERT) {
641 110878 fc->vvcdsp.intra.pred_v((uint8_t *)src, edge.top, w, h, stride);
642
2/2
✓ Branch 0 taken 55162 times.
✓ Branch 1 taken 389515 times.
889354 } else if (mode == INTRA_HORZ) {
643 110324 fc->vvcdsp.intra.pred_h((uint8_t *)src, edge.left, w, h, stride);
644 } else {
645
2/2
✓ Branch 0 taken 204025 times.
✓ Branch 1 taken 185490 times.
779030 if (mode >= INTRA_DIAG) {
646 408050 fc->vvcdsp.intra.pred_angular_v((uint8_t *)src, edge.top, edge.left,
647 w, h, stride, c_idx, mode, ref_idx,
648 edge.filter_flag, need_pdpc);
649 } else {
650 370980 fc->vvcdsp.intra.pred_angular_h((uint8_t *)src, edge.top, edge.left,
651 w, h, stride, c_idx, mode, ref_idx,
652 edge.filter_flag, need_pdpc);
653 }
654 }
655
2/2
✓ Branch 0 taken 646602 times.
✓ Branch 1 taken 394861 times.
2082926 if (need_pdpc) {
656 //8.4.5.2.15 Position-dependent intra prediction sample filtering process
657
8/8
✓ Branch 0 taken 554930 times.
✓ Branch 1 taken 91672 times.
✓ Branch 2 taken 227105 times.
✓ Branch 3 taken 327825 times.
✓ Branch 4 taken 169112 times.
✓ Branch 5 taken 57993 times.
✓ Branch 6 taken 122601 times.
✓ Branch 7 taken 46511 times.
1293204 if (!is_intra_mip && (mode == INTRA_PLANAR || mode == INTRA_DC ||
658
2/2
✓ Branch 0 taken 42398 times.
✓ Branch 1 taken 80203 times.
245202 mode == INTRA_VERT || mode == INTRA_HORZ)) {
659 949454 const int scale = (av_log2(w) + av_log2(h) - 2) >> 2;
660 949454 const pixel *left = (pixel*)edge.left;
661 949454 const pixel *top = (pixel*)edge.top;
662
2/2
✓ Branch 0 taken 5017460 times.
✓ Branch 1 taken 474727 times.
10984374 for (int y = 0; y < h; y++) {
663
2/2
✓ Branch 0 taken 84144432 times.
✓ Branch 1 taken 5017460 times.
178323784 for (int x = 0; x < w; x++) {
664 int l, t, wl, wt, pred;
665 pixel val;
666
4/4
✓ Branch 0 taken 24647568 times.
✓ Branch 1 taken 59496864 times.
✓ Branch 2 taken 9860336 times.
✓ Branch 3 taken 14787232 times.
168288864 if (mode == INTRA_PLANAR || mode == INTRA_DC) {
667 138714400 l = left[y];
668 138714400 t = top[x];
669 138714400 wl = 32 >> FFMIN((x << 1) >> scale, 31);
670 138714400 wt = 32 >> FFMIN((y << 1) >> scale, 31);
671 } else {
672 29574464 l = left[y] - left[-1] + POS(x,y);
673 29574464 t = top[x] - top[-1] + POS(x,y);
674
2/2
✓ Branch 0 taken 6890528 times.
✓ Branch 1 taken 7896704 times.
29574464 wl = (mode == INTRA_VERT) ? (32 >> FFMIN((x << 1) >> scale, 31)) : 0;
675
2/2
✓ Branch 0 taken 7896704 times.
✓ Branch 1 taken 6890528 times.
29574464 wt = (mode == INTRA_HORZ) ? (32 >> FFMIN((y << 1) >> scale, 31)) : 0;
676 }
677 168288864 val = POS(x, y);
678 168288864 pred = val + ((wl * (l - val) + wt * (t - val) + 32) >> 6);
679 168288864 POS(x, y) = CLIP(pred);
680 }
681 }
682 }
683 }
684 2082926 }
685
686 //8.4.5.2.11 Specification of INTRA_PLANAR intra prediction mode
687 725294 static av_always_inline void FUNC(pred_planar)(uint8_t *_src, const uint8_t *_top,
688 const uint8_t *_left, const int w, const int h, const ptrdiff_t stride)
689 {
690 int x, y;
691 725294 pixel *src = (pixel *)_src;
692 725294 const pixel *top = (const pixel *)_top;
693 725294 const pixel *left = (const pixel *)_left;
694 725294 const int logw = av_log2(w);
695 725294 const int logh = av_log2(h);
696 725294 const int size = w * h;
697 725294 const int shift = (logw + logh + 1);
698
2/2
✓ Branch 0 taken 3590260 times.
✓ Branch 1 taken 362647 times.
7905814 for (y = 0; y < h; y++) {
699
2/2
✓ Branch 0 taken 60384928 times.
✓ Branch 1 taken 3590260 times.
127950376 for (x = 0; x < w; x++) {
700 120769856 const int pred_v = ((h - 1 - y) * top[x] + (y + 1) * left[h]) << logw;
701 120769856 const int pred_h = ((w - 1 - x) * left[y] + (x + 1) * top[w]) << logh;
702 120769856 const int pred = (pred_v + pred_h + size) >> shift;
703 120769856 POS(x, y) = pred;
704 }
705 }
706 725294 }
707
708 //8.4.5.2.3 MIP boundary sample downsampling process
709 435940 static av_always_inline void FUNC(mip_downsampling)(int *reduced, const int boundary_size,
710 const pixel *ref, const int n_tb_s)
711 {
712 435940 const int b_dwn = n_tb_s / boundary_size;
713 435940 const int log2 = av_log2(b_dwn);
714
715
2/2
✓ Branch 0 taken 38796 times.
✓ Branch 1 taken 179174 times.
435940 if (boundary_size == n_tb_s) {
716
2/2
✓ Branch 0 taken 155184 times.
✓ Branch 1 taken 38796 times.
387960 for (int i = 0; i < n_tb_s; i++)
717 310368 reduced[i] = ref[i];
718 77592 return;
719 }
720
2/2
✓ Branch 0 taken 655380 times.
✓ Branch 1 taken 179174 times.
1669108 for (int i = 0; i < boundary_size; i++) {
721 int r;
722 1310760 r = *ref++;
723
2/2
✓ Branch 0 taken 1847092 times.
✓ Branch 1 taken 655380 times.
5004944 for (int j = 1; j < b_dwn; j++)
724 3694184 r += *ref++;
725 1310760 reduced[i] = (r + (1 << (log2 - 1))) >> log2;
726 }
727 }
728
729 217970 static av_always_inline void FUNC(mip_reduced_pred)(pixel *src, const ptrdiff_t stride,
730 const int up_hor, const int up_ver, const int pred_size, const int *reduced, const int reduced_size,
731 const int ow, const int temp0, const uint8_t *matrix, int is_transposed)
732 {
733 217970 src = &POS(up_hor - 1, up_ver - 1);
734
2/2
✓ Branch 0 taken 612920 times.
✓ Branch 1 taken 108985 times.
1443810 for (int y = 0; y < pred_size; y++) {
735
2/2
✓ Branch 0 taken 3867520 times.
✓ Branch 1 taken 612920 times.
8960880 for (int x = 0; x < pred_size; x++) {
736 7735040 int pred = 0;
737
2/2
✓ Branch 0 taken 27127424 times.
✓ Branch 1 taken 3867520 times.
61989888 for (int i = 0; i < reduced_size; i++)
738 54254848 pred += reduced[i] * matrix[i];
739 7735040 matrix += reduced_size;
740 7735040 pred = ((pred + ow) >> 6) + temp0;
741 7735040 pred = av_clip(pred, 0, (1<<BIT_DEPTH) - 1);
742
2/2
✓ Branch 0 taken 1945696 times.
✓ Branch 1 taken 1921824 times.
7735040 if (is_transposed)
743 3891392 POS(y * up_hor, x * up_ver) = pred;
744 else
745 3843648 POS(x * up_hor, y * up_ver) = pred;
746 }
747 }
748 217970 }
749
750 250318 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,
751 const pixel *boundary, const int boundary_step, const int pred_size)
752 {
753
754
2/2
✓ Branch 0 taken 1197932 times.
✓ Branch 1 taken 125159 times.
2646182 for (int i = 0; i < dst_height; i++) {
755 2395864 const pixel *before = boundary;
756 2395864 const pixel *after = dst - dst_step;
757 2395864 pixel *d = dst;
758
2/2
✓ Branch 0 taken 8453200 times.
✓ Branch 1 taken 1197932 times.
19302264 for (int j = 0; j < pred_size; j++) {
759 16906400 after += dst_step * factor;
760
2/2
✓ Branch 0 taken 17948016 times.
✓ Branch 1 taken 8453200 times.
52802432 for (int k = 1; k < factor; k++) {
761 35896032 int mid = (factor - k) * (*before) + k * (*after);
762 35896032 *d = (mid + factor / 2) / factor;
763 35896032 d += dst_step;
764 }
765 16906400 before = after;
766 16906400 d += dst_step;
767 }
768 2395864 boundary += boundary_step;
769 2395864 dst += dst_stride;
770 }
771 250318 }
772
773 //8.4.5.2.2 Matrix-based intra sample prediction
774 217970 static av_always_inline void FUNC(pred_mip)(uint8_t *_src, const uint8_t *_top,
775 const uint8_t *_left, const int w, const int h, const ptrdiff_t stride,
776 int mode_id, int is_transposed)
777 {
778 217970 pixel *src = (pixel *)_src;
779 217970 const pixel *top = (const pixel *)_top;
780 217970 const pixel *left = (const pixel *)_left;
781
782 217970 const int size_id = ff_vvc_get_mip_size_id(w, h);
783 static const int boundary_sizes[] = {2, 4, 4};
784 static const int pred_sizes[] = {4, 4, 8};
785 217970 const int boundary_size = boundary_sizes[size_id];
786 217970 const int pred_size = pred_sizes[size_id];
787 217970 const int in_size = 2 * boundary_size - ((size_id == 2) ? 1 : 0);
788 217970 const uint8_t *matrix = ff_vvc_get_mip_matrix(size_id, mode_id);
789 217970 const int up_hor = w / pred_size;
790 217970 const int up_ver = h / pred_size;
791
792 int reduced[16];
793 217970 int *red_t = reduced;
794 217970 int *red_l = reduced + boundary_size;
795 217970 int off = 1, ow = 0;
796 int temp0;
797
798
2/2
✓ Branch 0 taken 55633 times.
✓ Branch 1 taken 53352 times.
217970 if (is_transposed) {
799 111266 FFSWAP(int*, red_t, red_l);
800 }
801 217970 FUNC(mip_downsampling)(red_t, boundary_size, top, w);
802 217970 FUNC(mip_downsampling)(red_l, boundary_size, left, h);
803
804 217970 temp0 = reduced[0];
805
2/2
✓ Branch 0 taken 64740 times.
✓ Branch 1 taken 44245 times.
217970 if (size_id != 2) {
806 129480 off = 0;
807 129480 ow = (1 << (BIT_DEPTH - 1)) - temp0;
808 } else {
809 88490 ow = reduced[1] - temp0;
810 }
811 217970 reduced[0] = ow;
812
2/2
✓ Branch 0 taken 657334 times.
✓ Branch 1 taken 108985 times.
1532638 for (int i = 1; i < in_size; i++) {
813 1314668 reduced[i] = reduced[i + off] - temp0;
814 1314668 ow += reduced[i];
815 }
816 217970 ow = 32 - 32 * ow;
817
818 217970 FUNC(mip_reduced_pred)(src, stride, up_hor, up_ver, pred_size, reduced, in_size, ow, temp0, matrix, is_transposed);
819
4/4
✓ Branch 0 taken 38556 times.
✓ Branch 1 taken 70429 times.
✓ Branch 2 taken 23227 times.
✓ Branch 3 taken 15329 times.
217970 if (up_hor > 1 || up_ver > 1) {
820
2/2
✓ Branch 0 taken 70429 times.
✓ Branch 1 taken 23227 times.
187312 if (up_hor > 1)
821 140858 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);
822
2/2
✓ Branch 0 taken 54730 times.
✓ Branch 1 taken 38926 times.
187312 if (up_ver > 1)
823 109460 FUNC(mip_upsampling_1d)(src, stride, 1, w, up_ver, top, 1, pred_size);
824 }
825 217970 }
826
827 139430 static av_always_inline pixel FUNC(pred_dc_val)(const pixel *top, const pixel *left,
828 const int w, const int h)
829 {
830 pixel dc_val;
831 139430 int sum = 0;
832
2/2
✓ Branch 0 taken 24235 times.
✓ Branch 1 taken 45480 times.
139430 unsigned int offset = (w == h) ? (w << 1) : FFMAX(w, h);
833 139430 const int shift = av_log2(offset);
834 139430 offset >>= 1;
835
2/2
✓ Branch 0 taken 54591 times.
✓ Branch 1 taken 15124 times.
139430 if (w >= h) {
836
2/2
✓ Branch 0 taken 778792 times.
✓ Branch 1 taken 54591 times.
1666766 for (int i = 0; i < w; i++)
837 1557584 sum += top[i];
838 }
839
2/2
✓ Branch 0 taken 39359 times.
✓ Branch 1 taken 30356 times.
139430 if (w <= h) {
840
2/2
✓ Branch 0 taken 478968 times.
✓ Branch 1 taken 39359 times.
1036654 for (int i = 0; i < h; i++)
841 957936 sum += left[i];
842 }
843 139430 dc_val = (sum + offset) >> shift;
844 139430 return dc_val;
845 }
846
847 //8.4.5.2.12 Specification of INTRA_DC intra prediction mode
848 139430 static av_always_inline void FUNC(pred_dc)(uint8_t *_src, const uint8_t *_top,
849 const uint8_t *_left, const int w, const int h, const ptrdiff_t stride)
850 {
851 int x, y;
852 139430 pixel *src = (pixel *)_src;
853 139430 const pixel *top = (const pixel *)_top;
854 139430 const pixel *left = (const pixel *)_left;
855 139430 const pixel dc = FUNC(pred_dc_val)(top, left, w, h);
856 139430 const pixel4 a = PIXEL_SPLAT_X4(dc);
857
2/2
✓ Branch 0 taken 646320 times.
✓ Branch 1 taken 69715 times.
1432070 for (y = 0; y < h; y++) {
858 1292640 pixel *s = src;
859
2/2
✓ Branch 0 taken 2690848 times.
✓ Branch 1 taken 646320 times.
6674336 for (x = 0; x < w; x += 4) {
860 5381696 AV_WN4P(s, a);
861 5381696 s += 4;
862 }
863 1292640 src += stride;
864 }
865 139430 }
866
867 110878 static av_always_inline void FUNC(pred_v)(uint8_t *_src, const uint8_t *_top,
868 const int w, const int h, const ptrdiff_t stride)
869 {
870 110878 pixel *src = (pixel *)_src;
871 110878 const pixel *top = (const pixel *)_top;
872
2/2
✓ Branch 0 taken 519416 times.
✓ Branch 1 taken 55439 times.
1149710 for (int y = 0; y < h; y++) {
873 1038832 memcpy(src, top, sizeof(pixel) * w);
874 1038832 src += stride;
875 }
876 110878 }
877
878 110324 static void FUNC(pred_h)(uint8_t *_src, const uint8_t *_left, const int w, const int h,
879 const ptrdiff_t stride)
880 {
881 110324 pixel *src = (pixel *)_src;
882 110324 const pixel *left = (const pixel *)_left;
883
2/2
✓ Branch 0 taken 474116 times.
✓ Branch 1 taken 55162 times.
1058556 for (int y = 0; y < h; y++) {
884 948232 const pixel4 a = PIXEL_SPLAT_X4(left[y]);
885
2/2
✓ Branch 0 taken 2147004 times.
✓ Branch 1 taken 474116 times.
5242240 for (int x = 0; x < w; x += 4) {
886 4294008 AV_WN4P(&POS(x, y), a);
887 }
888 }
889 110324 }
890
891 #define INTRA_LUMA_FILTER(p) CLIP((p[0] * f[0] + p[1] * f[1] + p[2] * f[2] + p[3] * f[3] + 32) >> 6)
892 #define INTRA_CHROMA_FILTER(p) (((32 - fact) * p[1] + fact * p[2] + 16) >> 5)
893
894 //8.4.5.2.13 Specification of INTRA_ANGULAR2..INTRA_ANGULAR66 intra prediction modes
895 408050 static void FUNC(pred_angular_v)(uint8_t *_src, const uint8_t *_top, const uint8_t *_left,
896 const int w, const int h, const ptrdiff_t stride, const int c_idx, const int mode,
897 const int ref_idx, const int filter_flag, const int need_pdpc)
898 {
899 408050 pixel *src = (pixel *)_src;
900 408050 const pixel *left = (const pixel *)_left;
901 408050 const pixel *top = (const pixel *)_top - (1 + ref_idx);
902 408050 const int intra_pred_angle = ff_vvc_intra_pred_angle_derive(mode);
903 408050 int pos = (1 + ref_idx) * intra_pred_angle;
904 408050 const int dp = intra_pred_angle;
905 408050 const int is_luma = !c_idx;
906 int nscale, inv_angle;
907
908
2/2
✓ Branch 0 taken 43538 times.
✓ Branch 1 taken 160487 times.
408050 if (need_pdpc) {
909 87076 inv_angle = ff_vvc_intra_inv_angle_derive(intra_pred_angle);
910 87076 nscale = ff_vvc_nscale_derive(w, h, mode);
911 }
912
913
2/2
✓ Branch 0 taken 1556796 times.
✓ Branch 1 taken 204025 times.
3521642 for (int y = 0; y < h; y++) {
914 3113592 const int idx = (pos >> 5) + ref_idx;
915 3113592 const int fact = pos & 31;
916
6/6
✓ Branch 0 taken 240683 times.
✓ Branch 1 taken 1316113 times.
✓ Branch 2 taken 149725 times.
✓ Branch 3 taken 90958 times.
✓ Branch 4 taken 125184 times.
✓ Branch 5 taken 24541 times.
3113592 if (!fact && (!is_luma || !filter_flag)) {
917
2/2
✓ Branch 0 taken 2285804 times.
✓ Branch 1 taken 216142 times.
5003892 for (int x = 0; x < w; x++) {
918 4571608 const pixel *p = top + x + idx + 1;
919 4571608 POS(x, y) = *p;
920 }
921 } else {
922
2/2
✓ Branch 0 taken 1064828 times.
✓ Branch 1 taken 275826 times.
2681308 if (!c_idx) {
923 2129656 const int8_t *f = ff_vvc_intra_luma_filter[filter_flag][fact];
924
2/2
✓ Branch 0 taken 11704004 times.
✓ Branch 1 taken 1064828 times.
25537664 for (int x = 0; x < w; x++) {
925 23408008 const pixel *p = top + x + idx;
926 23408008 POS(x, y) = INTRA_LUMA_FILTER(p);
927 }
928 } else {
929
2/2
✓ Branch 0 taken 2565680 times.
✓ Branch 1 taken 275826 times.
5683012 for (int x = 0; x < w; x++) {
930 5131360 const pixel *p = top + x + idx;
931 5131360 POS(x, y) = INTRA_CHROMA_FILTER(p);
932 }
933 }
934 }
935
2/2
✓ Branch 0 taken 380896 times.
✓ Branch 1 taken 1175900 times.
3113592 if (need_pdpc) {
936 761792 int inv_angle_sum = 256 + inv_angle;
937
2/2
✓ Branch 0 taken 2068204 times.
✓ Branch 1 taken 380896 times.
4898200 for (int x = 0; x < FFMIN(w, 3 << nscale); x++) {
938 4136408 const pixel l = left[y + (inv_angle_sum >> 9)];
939 4136408 const pixel val = POS(x, y);
940 4136408 const int wl = 32 >> ((x << 1) >> nscale);
941 4136408 const int pred = val + (((l - val) * wl + 32) >> 6);
942 4136408 POS(x, y) = CLIP(pred);
943 4136408 inv_angle_sum += inv_angle;
944 }
945 }
946 3113592 pos += dp;
947 }
948 408050 }
949
950 //8.4.5.2.13 Specification of INTRA_ANGULAR2..INTRA_ANGULAR66 intra prediction modes
951 370980 static void FUNC(pred_angular_h)(uint8_t *_src, const uint8_t *_top, const uint8_t *_left,
952 const int w, const int h, const ptrdiff_t stride, const int c_idx, const int mode,
953 const int ref_idx, const int filter_flag, const int need_pdpc)
954 {
955 370980 pixel *src = (pixel *)_src;
956 370980 const pixel *left = (const pixel *)_left - (1 + ref_idx);
957 370980 const pixel *top = (const pixel *)_top;
958 370980 const int is_luma = !c_idx;
959 370980 const int intra_pred_angle = ff_vvc_intra_pred_angle_derive(mode);
960 370980 const int dp = intra_pred_angle;
961 370980 int nscale = 0, inv_angle, inv_angle_sum;
962
963
2/2
✓ Branch 0 taken 36665 times.
✓ Branch 1 taken 148825 times.
370980 if (need_pdpc) {
964 73330 inv_angle = ff_vvc_intra_inv_angle_derive(intra_pred_angle);
965 73330 inv_angle_sum = 256 + inv_angle;
966 73330 nscale = ff_vvc_nscale_derive(w, h, mode);
967 }
968
969
2/2
✓ Branch 0 taken 1498960 times.
✓ Branch 1 taken 185490 times.
3368900 for (int y = 0; y < h; y++) {
970 2997920 int pos = (1 + ref_idx) * intra_pred_angle;
971 int wt;
972
2/2
✓ Branch 0 taken 411788 times.
✓ Branch 1 taken 1087172 times.
2997920 if (need_pdpc)
973 823576 wt = (32 >> FFMIN(31, (y * 2) >> nscale));
974
975
2/2
✓ Branch 0 taken 21692016 times.
✓ Branch 1 taken 1498960 times.
46381952 for (int x = 0; x < w; x++) {
976 43384032 const int idx = (pos >> 5) + ref_idx;
977 43384032 const int fact = pos & 31;
978 43384032 const pixel *p = left + y + idx;
979 int pred;
980
6/6
✓ Branch 0 taken 2039404 times.
✓ Branch 1 taken 19652612 times.
✓ Branch 2 taken 1653020 times.
✓ Branch 3 taken 386384 times.
✓ Branch 4 taken 977428 times.
✓ Branch 5 taken 675592 times.
43384032 if (!fact && (!is_luma || !filter_flag)) {
981 2727624 pred = p[1];
982 } else {
983
2/2
✓ Branch 0 taken 15693148 times.
✓ Branch 1 taken 4635056 times.
40656408 if (!c_idx) {
984 31386296 const int8_t *f = ff_vvc_intra_luma_filter[filter_flag][fact];
985 31386296 pred = INTRA_LUMA_FILTER(p);
986 } else {
987 9270112 pred = INTRA_CHROMA_FILTER(p);
988 }
989 }
990
2/2
✓ Branch 0 taken 4965552 times.
✓ Branch 1 taken 16726464 times.
43384032 if (need_pdpc) {
991
2/2
✓ Branch 0 taken 1935056 times.
✓ Branch 1 taken 3030496 times.
9931104 if (y < (3 << nscale)) {
992 3870112 const pixel t = top[x + (inv_angle_sum >> 9)];
993 3870112 pred = CLIP(pred + (((t - pred) * wt + 32) >> 6));
994 }
995 }
996 43384032 POS(x, y) = pred;
997 43384032 pos += dp;
998 }
999
2/2
✓ Branch 0 taken 411788 times.
✓ Branch 1 taken 1087172 times.
2997920 if (need_pdpc)
1000 823576 inv_angle_sum += inv_angle;
1001 }
1002 370980 }
1003
1004 2650 static void FUNC(ff_vvc_intra_dsp_init)(VVCIntraDSPContext *const intra)
1005 {
1006 2650 intra->lmcs_scale_chroma = FUNC(lmcs_scale_chroma);
1007 2650 intra->intra_cclm_pred = FUNC(intra_cclm_pred);
1008 2650 intra->intra_pred = FUNC(intra_pred);
1009 2650 intra->pred_planar = FUNC(pred_planar);
1010 2650 intra->pred_mip = FUNC(pred_mip);
1011 2650 intra->pred_dc = FUNC(pred_dc);
1012 2650 intra->pred_v = FUNC(pred_v);
1013 2650 intra->pred_h = FUNC(pred_h);
1014 2650 intra->pred_angular_v = FUNC(pred_angular_v);
1015 2650 intra->pred_angular_h = FUNC(pred_angular_h);
1016 2650 }
1017