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 |