FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/vvc/intra.c
Date: 2025-08-19 23:55:23
Exec Total Coverage
Lines: 459 463 99.1%
Functions: 29 29 100.0%
Branches: 304 318 95.6%

Line Branch Exec Source
1 /*
2 * VVC intra prediction
3 *
4 * Copyright (C) 2021 Nuo Mi
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 #include "libavutil/frame.h"
23 #include "libavutil/imgutils.h"
24
25 #include "data.h"
26 #include "inter.h"
27 #include "intra.h"
28 #include "itx_1d.h"
29
30 #define POS(c_idx, x, y) \
31 &fc->frame->data[c_idx][((y) >> fc->ps.sps->vshift[c_idx]) * fc->frame->linesize[c_idx] + \
32 (((x) >> fc->ps.sps->hshift[c_idx]) << fc->ps.sps->pixel_shift)]
33
34 421955 static int is_cclm(enum IntraPredMode mode)
35 {
36
6/6
✓ Branch 0 taken 358278 times.
✓ Branch 1 taken 63677 times.
✓ Branch 2 taken 334430 times.
✓ Branch 3 taken 23848 times.
✓ Branch 4 taken 26387 times.
✓ Branch 5 taken 308043 times.
421955 return mode == INTRA_LT_CCLM || mode == INTRA_L_CCLM || mode == INTRA_T_CCLM;
37 }
38
39 174834 static int derive_ilfnst_pred_mode_intra(const VVCLocalContext *lc, const TransformBlock *tb)
40 {
41 174834 const VVCFrameContext *fc = lc->fc;
42 174834 const VVCSPS *sps = fc->ps.sps;
43 174834 const CodingUnit *cu = lc->cu;
44 174834 const int x_tb = tb->x0 >> fc->ps.sps->min_cb_log2_size_y;
45 174834 const int y_tb = tb->y0 >> fc->ps.sps->min_cb_log2_size_y;
46 174834 const int x_c = (tb->x0 + (tb->tb_width << sps->hshift[1] >> 1) ) >> fc->ps.sps->min_cb_log2_size_y;
47 174834 const int y_c = (tb->y0 + (tb->tb_height << sps->vshift[1] >> 1)) >> fc->ps.sps->min_cb_log2_size_y;
48 174834 const int min_cb_width = fc->ps.pps->min_cb_width;
49 174834 const int intra_mip_flag = SAMPLE_CTB(fc->tab.imf, x_tb, y_tb);
50
2/2
✓ Branch 0 taken 123297 times.
✓ Branch 1 taken 51537 times.
174834 int pred_mode_intra = tb->c_idx == 0 ? cu->intra_pred_mode_y : cu->intra_pred_mode_c;
51
4/4
✓ Branch 0 taken 20014 times.
✓ Branch 1 taken 154820 times.
✓ Branch 2 taken 5109 times.
✓ Branch 3 taken 14905 times.
174834 if (intra_mip_flag && !tb->c_idx) {
52 5109 pred_mode_intra = INTRA_PLANAR;
53
2/2
✓ Branch 1 taken 16275 times.
✓ Branch 2 taken 153450 times.
169725 } else if (is_cclm(pred_mode_intra)) {
54 16275 int intra_mip_flag_c = SAMPLE_CTB(fc->tab.imf, x_c, y_c);
55 16275 int cu_pred_mode = SAMPLE_CTB(fc->tab.cpm[0], x_c, y_c);
56
2/2
✓ Branch 0 taken 4509 times.
✓ Branch 1 taken 11766 times.
16275 if (intra_mip_flag_c) {
57 4509 pred_mode_intra = INTRA_PLANAR;
58
4/4
✓ Branch 0 taken 10588 times.
✓ Branch 1 taken 1178 times.
✓ Branch 2 taken 22 times.
✓ Branch 3 taken 10566 times.
11766 } else if (cu_pred_mode == MODE_IBC || cu_pred_mode == MODE_PLT) {
59 1200 pred_mode_intra = INTRA_DC;
60 } else {
61 10566 pred_mode_intra = SAMPLE_CTB(fc->tab.ipm, x_c, y_c);
62 }
63 }
64 174834 pred_mode_intra = ff_vvc_wide_angle_mode_mapping(cu, tb->tb_width, tb->tb_height, tb->c_idx, pred_mode_intra);
65
66 174834 return pred_mode_intra;
67 }
68
69 //8.7.4 Transformation process for scaled transform coefficients
70 174834 static void ilfnst_transform(const VVCLocalContext *lc, TransformBlock *tb)
71 {
72 174834 const VVCSPS *sps = lc->fc->ps.sps;
73 174834 const CodingUnit *cu = lc->cu;
74 174834 const int w = tb->tb_width;
75 174834 const int h = tb->tb_height;
76
4/4
✓ Branch 0 taken 101276 times.
✓ Branch 1 taken 73558 times.
✓ Branch 2 taken 69098 times.
✓ Branch 3 taken 32178 times.
174834 const int n_lfnst_out_size = (w >= 8 && h >= 8) ? 48 : 16; ///< nLfnstOutSize
77
4/4
✓ Branch 0 taken 101276 times.
✓ Branch 1 taken 73558 times.
✓ Branch 2 taken 69098 times.
✓ Branch 3 taken 32178 times.
174834 const int log2_lfnst_size = (w >= 8 && h >= 8) ? 3 : 2; ///< log2LfnstSize
78 174834 const int n_lfnst_size = 1 << log2_lfnst_size; ///< nLfnstSize
79
8/8
✓ Branch 0 taken 40607 times.
✓ Branch 1 taken 134227 times.
✓ Branch 2 taken 27925 times.
✓ Branch 3 taken 12682 times.
✓ Branch 4 taken 73558 times.
✓ Branch 5 taken 88594 times.
✓ Branch 6 taken 50345 times.
✓ Branch 7 taken 23213 times.
174834 const int non_zero_size = ((w == 8 && h == 8) || (w == 4 && h == 4)) ? 8 : 16; ///< nonZeroSize
80 174834 const int pred_mode_intra = derive_ilfnst_pred_mode_intra(lc, tb);
81 174834 const int transpose = pred_mode_intra > 34;
82 int u[16], v[48];
83
84
2/2
✓ Branch 0 taken 2293128 times.
✓ Branch 1 taken 174834 times.
2467962 for (int x = 0; x < non_zero_size; x++) {
85 2293128 int xc = ff_vvc_diag_scan_x[2][2][x];
86 2293128 int yc = ff_vvc_diag_scan_y[2][2][x];
87 2293128 u[x] = tb->coeffs[w * yc + xc];
88 }
89 174834 ff_vvc_inv_lfnst_1d(v, u, non_zero_size, n_lfnst_out_size, pred_mode_intra,
90 174834 cu->lfnst_idx, sps->log2_transform_range);
91
2/2
✓ Branch 0 taken 50702 times.
✓ Branch 1 taken 124132 times.
174834 if (transpose) {
92 50702 int *dst = tb->coeffs;
93 50702 const int *src = v;
94
2/2
✓ Branch 0 taken 35390 times.
✓ Branch 1 taken 15312 times.
50702 if (n_lfnst_size == 4) {
95
2/2
✓ Branch 0 taken 141560 times.
✓ Branch 1 taken 35390 times.
176950 for (int y = 0; y < 4; y++) {
96 141560 dst[0] = src[0];
97 141560 dst[1] = src[4];
98 141560 dst[2] = src[8];
99 141560 dst[3] = src[12];
100 141560 src++;
101 141560 dst += w;
102 }
103 } else {
104
2/2
✓ Branch 0 taken 122496 times.
✓ Branch 1 taken 15312 times.
137808 for (int y = 0; y < 8; y++) {
105 122496 dst[0] = src[0];
106 122496 dst[1] = src[8];
107 122496 dst[2] = src[16];
108 122496 dst[3] = src[24];
109
2/2
✓ Branch 0 taken 61248 times.
✓ Branch 1 taken 61248 times.
122496 if (y < 4) {
110 61248 dst[4] = src[32];
111 61248 dst[5] = src[36];
112 61248 dst[6] = src[40];
113 61248 dst[7] = src[44];
114 }
115 122496 src++;
116 122496 dst += w;
117 }
118 }
119
120 } else {
121 124132 int *dst = tb->coeffs;
122 124132 const int *src = v;
123
2/2
✓ Branch 0 taken 711672 times.
✓ Branch 1 taken 124132 times.
835804 for (int y = 0; y < n_lfnst_size; y++) {
124
2/2
✓ Branch 0 taken 496528 times.
✓ Branch 1 taken 215144 times.
711672 int size = (y < 4) ? n_lfnst_size : 4;
125 711672 memcpy(dst, src, size * sizeof(int));
126 711672 src += size;
127 711672 dst += w;
128 }
129 }
130 174834 tb->max_scan_x = n_lfnst_size - 1;
131 174834 tb->max_scan_y = n_lfnst_size - 1;
132 174834 }
133
134 //part of 8.7.4 Transformation process for scaled transform coefficients
135 957397 static void derive_transform_type(const VVCFrameContext *fc, const VVCLocalContext *lc, const TransformBlock *tb, enum VVCTxType *trh, enum VVCTxType *trv)
136 {
137 957397 const CodingUnit *cu = lc->cu;
138 static const enum VVCTxType mts_to_trh[] = { VVC_DCT2, VVC_DST7, VVC_DCT8, VVC_DST7, VVC_DCT8 };
139 static const enum VVCTxType mts_to_trv[] = { VVC_DCT2, VVC_DST7, VVC_DST7, VVC_DCT8, VVC_DCT8 };
140 957397 const VVCSPS *sps = fc->ps.sps;
141 957397 int implicit_mts_enabled = 0;
142
6/6
✓ Branch 0 taken 692885 times.
✓ Branch 1 taken 264512 times.
✓ Branch 2 taken 142447 times.
✓ Branch 3 taken 550438 times.
✓ Branch 4 taken 32815 times.
✓ Branch 5 taken 109632 times.
957397 if (tb->c_idx || (cu->isp_split_type != ISP_NO_SPLIT && cu->lfnst_idx)) {
143 297327 *trh = *trv = VVC_DCT2;
144 297327 return;
145 }
146
147
2/2
✓ Branch 0 taken 656176 times.
✓ Branch 1 taken 3894 times.
660070 if (sps->r->sps_mts_enabled_flag) {
148
2/2
✓ Branch 0 taken 546544 times.
✓ Branch 1 taken 109632 times.
656176 if (cu->isp_split_type != ISP_NO_SPLIT ||
149
4/4
✓ Branch 0 taken 34954 times.
✓ Branch 1 taken 511590 times.
✓ Branch 2 taken 523 times.
✓ Branch 3 taken 34431 times.
546544 (cu->sbt_flag && FFMAX(tb->tb_width, tb->tb_height) <= 32) ||
150
4/4
✓ Branch 0 taken 45019 times.
✓ Branch 1 taken 467094 times.
✓ Branch 2 taken 28412 times.
✓ Branch 3 taken 16607 times.
512113 (!sps->r->sps_explicit_mts_intra_enabled_flag && cu->pred_mode == MODE_INTRA &&
151
4/4
✓ Branch 0 taken 18449 times.
✓ Branch 1 taken 9963 times.
✓ Branch 2 taken 14592 times.
✓ Branch 3 taken 3857 times.
28412 !cu->lfnst_idx && !cu->intra_mip_flag)) {
152 158655 implicit_mts_enabled = 1;
153 }
154 }
155
2/2
✓ Branch 0 taken 158655 times.
✓ Branch 1 taken 501415 times.
660070 if (implicit_mts_enabled) {
156 158655 const int w = tb->tb_width;
157 158655 const int h = tb->tb_height;
158
2/2
✓ Branch 0 taken 34431 times.
✓ Branch 1 taken 124224 times.
158655 if (cu->sbt_flag) {
159
4/4
✓ Branch 0 taken 18254 times.
✓ Branch 1 taken 16177 times.
✓ Branch 2 taken 8586 times.
✓ Branch 3 taken 9668 times.
34431 *trh = (cu->sbt_horizontal_flag || cu->sbt_pos_flag) ? VVC_DST7 : VVC_DCT8;
160
4/4
✓ Branch 0 taken 16177 times.
✓ Branch 1 taken 18254 times.
✓ Branch 2 taken 7799 times.
✓ Branch 3 taken 8378 times.
34431 *trv = (!cu->sbt_horizontal_flag || cu->sbt_pos_flag) ? VVC_DST7 : VVC_DCT8;
161 } else {
162
4/4
✓ Branch 0 taken 105232 times.
✓ Branch 1 taken 18992 times.
✓ Branch 2 taken 85050 times.
✓ Branch 3 taken 20182 times.
124224 *trh = (w >= 4 && w <= 16) ? VVC_DST7 : VVC_DCT2;
163
4/4
✓ Branch 0 taken 78618 times.
✓ Branch 1 taken 45606 times.
✓ Branch 2 taken 75624 times.
✓ Branch 3 taken 2994 times.
124224 *trv = (h >= 4 && h <= 16) ? VVC_DST7 : VVC_DCT2;
164 }
165 158655 return;
166 }
167 501415 *trh = mts_to_trh[cu->mts_idx];
168 501415 *trv = mts_to_trv[cu->mts_idx];
169 }
170
171 2123762 static int add_reconstructed_area(VVCLocalContext *lc, const int ch_type, const int x0, const int y0, const int w, const int h)
172 {
173 2123762 const VVCSPS *sps = lc->fc->ps.sps;
174 2123762 const int hs = sps->hshift[ch_type];
175 2123762 const int vs = sps->vshift[ch_type];
176 ReconstructedArea *a;
177
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2123762 times.
2123762 if (lc->num_ras[ch_type] >= FF_ARRAY_ELEMS(lc->ras[ch_type]))
179 return AVERROR_INVALIDDATA;
180
181 2123762 a = &lc->ras[ch_type][lc->num_ras[ch_type]];
182 2123762 a->x = x0 >> hs;
183 2123762 a->y = y0 >> vs;
184 2123762 a->w = w >> hs;
185 2123762 a->h = h >> vs;
186 2123762 lc->num_ras[ch_type]++;
187
188 2123762 return 0;
189 }
190
191 1019732 static void add_tu_area(const TransformUnit *tu, int *x0, int *y0, int *w, int *h)
192 {
193 1019732 *x0 = tu->x0;
194 1019732 *y0 = tu->y0;
195 1019732 *w = tu->width;
196 1019732 *h = tu->height;
197 1019732 }
198
199 #define MIN_ISP_PRED_WIDTH 4
200 773129 static int get_luma_predict_unit(const CodingUnit *cu, const TransformUnit *tu, const int idx, int *x0, int *y0, int *w, int *h)
201 {
202 773129 int has_luma = 1;
203 773129 add_tu_area(tu, x0, y0, w, h);
204
4/4
✓ Branch 0 taken 76438 times.
✓ Branch 1 taken 696691 times.
✓ Branch 2 taken 27478 times.
✓ Branch 3 taken 48960 times.
773129 if (cu->isp_split_type == ISP_VER_SPLIT && tu->width < MIN_ISP_PRED_WIDTH) {
205 27478 *w = MIN_ISP_PRED_WIDTH;
206 27478 has_luma = !(idx % (MIN_ISP_PRED_WIDTH / tu->width));
207 }
208 773129 return has_luma;
209 }
210
211 268909 static int get_chroma_predict_unit(const CodingUnit *cu, const TransformUnit *tu, const int idx, int *x0, int *y0, int *w, int *h)
212 {
213
2/2
✓ Branch 0 taken 246603 times.
✓ Branch 1 taken 22306 times.
268909 if (cu->isp_split_type == ISP_NO_SPLIT) {
214 246603 add_tu_area(tu, x0, y0, w, h);
215 246603 return 1;
216 }
217
2/2
✓ Branch 0 taken 5627 times.
✓ Branch 1 taken 16679 times.
22306 if (idx == cu->num_intra_subpartitions - 1) {
218 5627 *x0 = cu->x0;
219 5627 *y0 = cu->y0;
220 5627 *w = cu->cb_width;
221 5627 *h = cu->cb_height;
222 5627 return 1;
223 }
224 16679 return 0;
225 }
226
227 //8.4.5.1 General decoding process for intra blocks
228 1494996 static void predict_intra(VVCLocalContext *lc, const TransformUnit *tu, const int idx, const int target_ch_type)
229 {
230 1494996 const VVCFrameContext *fc = lc->fc;
231 1494996 const CodingUnit *cu = lc->cu;
232 1494996 const VVCTreeType tree_type = cu->tree_type;
233 int x0, y0, w, h;
234
2/2
✓ Branch 0 taken 452958 times.
✓ Branch 1 taken 1042038 times.
1494996 if (cu->pred_mode != MODE_INTRA) {
235 452958 add_reconstructed_area(lc, target_ch_type, tu->x0, tu->y0, tu->width, tu->height);
236 452958 return;
237 }
238
3/4
✓ Branch 0 taken 773129 times.
✓ Branch 1 taken 268909 times.
✓ Branch 2 taken 773129 times.
✗ Branch 3 not taken.
1042038 if (!target_ch_type && tree_type != DUAL_TREE_CHROMA) {
239
2/2
✓ Branch 1 taken 758292 times.
✓ Branch 2 taken 14837 times.
773129 if (get_luma_predict_unit(cu, tu, idx, &x0, &y0, &w, &h)) {
240 758292 ff_vvc_set_neighbour_available(lc, x0, y0, w, h);
241 758292 fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 0);
242 758292 add_reconstructed_area(lc, 0, x0, y0, w, h);
243 }
244 }
245
3/4
✓ Branch 0 taken 268909 times.
✓ Branch 1 taken 773129 times.
✓ Branch 2 taken 268909 times.
✗ Branch 3 not taken.
1042038 if (target_ch_type && tree_type != DUAL_TREE_LUMA) {
246
2/2
✓ Branch 1 taken 252230 times.
✓ Branch 2 taken 16679 times.
268909 if (get_chroma_predict_unit(cu, tu, idx, &x0, &y0, &w, &h)){
247 252230 ff_vvc_set_neighbour_available(lc, x0, y0, w, h);
248
2/2
✓ Branch 1 taken 97637 times.
✓ Branch 2 taken 154593 times.
252230 if (is_cclm(cu->intra_pred_mode_c)) {
249 97637 fc->vvcdsp.intra.intra_cclm_pred(lc, x0, y0, w, h);
250 } else {
251 154593 fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 1);
252 154593 fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 2);
253 }
254 252230 add_reconstructed_area(lc, 1, x0, y0, w, h);
255 }
256 }
257 }
258
259 893985 static void scale_clip(int *coeff, const int nzw, const int w, const int h,
260 const int shift, const int log2_transform_range)
261 {
262 893985 const int add = 1 << (shift - 1);
263
2/2
✓ Branch 0 taken 9214426 times.
✓ Branch 1 taken 893985 times.
10108411 for (int y = 0; y < h; y++) {
264 9214426 int *p = coeff + y * w;
265
2/2
✓ Branch 0 taken 49465154 times.
✓ Branch 1 taken 9214426 times.
58679580 for (int x = 0; x < nzw; x++) {
266 49465154 *p = av_clip_intp2((*p + add) >> shift, log2_transform_range);
267 49465154 p++;
268 }
269 9214426 memset(p, 0, sizeof(*p) * (w - nzw));
270 }
271 893985 }
272
273 907358 static void scale(int *out, const int *in, const int w, const int h, const int shift)
274 {
275 907358 const int add = 1 << (shift - 1);
276
2/2
✓ Branch 0 taken 9270876 times.
✓ Branch 1 taken 907358 times.
10178234 for (int y = 0; y < h; y++) {
277
2/2
✓ Branch 0 taken 153973668 times.
✓ Branch 1 taken 9270876 times.
163244544 for (int x = 0; x < w; x++) {
278 153973668 int *o = out + y * w + x;
279 153973668 const int *i = in + y * w + x;
280 153973668 *o = (*i + add) >> shift;
281 }
282 }
283 907358 }
284
285 // part of 8.7.3 Scaling process for transform coefficients
286 1182274 static void derive_qp(const VVCLocalContext *lc, const TransformUnit *tu, TransformBlock *tb)
287 {
288 1182274 const VVCSPS *sps = lc->fc->ps.sps;
289 1182274 const H266RawSliceHeader *rsh = lc->sc->sh.r;
290 1182274 const CodingUnit *cu = lc->cu;
291
8/8
✓ Branch 0 taken 386771 times.
✓ Branch 1 taken 795503 times.
✓ Branch 2 taken 54225 times.
✓ Branch 3 taken 332546 times.
✓ Branch 4 taken 46099 times.
✓ Branch 5 taken 8126 times.
✓ Branch 6 taken 31034 times.
✓ Branch 7 taken 15065 times.
1182274 const bool is_jcbcr = tb->c_idx && tu->joint_cbcr_residual_flag && tu->coded_flag[CB] && tu->coded_flag[CR];
292
2/2
✓ Branch 0 taken 31034 times.
✓ Branch 1 taken 1151240 times.
1182274 const int idx = is_jcbcr ? JCBCR : tb->c_idx;
293
2/2
✓ Branch 0 taken 795503 times.
✓ Branch 1 taken 386771 times.
1182274 const int qp = cu->qp[idx] + (idx ? 0 : sps->qp_bd_offset);
294 1182274 const int act_offset[] = { -5, 1, 3, 1 };
295
2/2
✓ Branch 0 taken 21078 times.
✓ Branch 1 taken 1161196 times.
1182274 const int qp_act_offset = cu->act_enabled_flag ? act_offset[idx] : 0;
296
297
2/2
✓ Branch 0 taken 47521 times.
✓ Branch 1 taken 1134753 times.
1182274 if (tb->ts) {
298 47521 const int qp_prime_ts_min = 4 + 6 * sps->r->sps_min_qp_prime_ts;
299
300 47521 tb->qp = av_clip(qp + qp_act_offset, qp_prime_ts_min, 63 + sps->qp_bd_offset);
301 47521 tb->rect_non_ts_flag = 0;
302 47521 tb->bd_shift = 10;
303 } else {
304 1134753 const int log_sum = tb->log2_tb_width + tb->log2_tb_height;
305 1134753 const int rect_non_ts_flag = log_sum & 1;
306
307 1134753 tb->qp = av_clip(qp + qp_act_offset, 0, 63 + sps->qp_bd_offset);
308 1134753 tb->rect_non_ts_flag = rect_non_ts_flag;
309 1134753 tb->bd_shift = sps->bit_depth + rect_non_ts_flag + (log_sum / 2)
310 1134753 + 10 - sps->log2_transform_range + rsh->sh_dep_quant_used_flag;
311 }
312 1182274 tb->bd_offset = (1 << tb->bd_shift) >> 1;
313 1182274 }
314
315 static const uint8_t rem6[63 + 8 * 6 + 1] = {
316 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5,
317 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5,
318 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5,
319 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5,
320 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3,
321 };
322
323 static const uint8_t div6[63 + 8 * 6 + 1] = {
324 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3,
325 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7,
326 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11,
327 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15,
328 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18,
329 };
330
331 const static int level_scale[2][6] = {
332 { 40, 45, 51, 57, 64, 72 },
333 { 57, 64, 72, 80, 90, 102 }
334 };
335
336 //8.7.3 Scaling process for transform coefficients
337 1004918 static av_always_inline int derive_scale(const TransformBlock *tb, const int sh_dep_quant_used_flag)
338 {
339
4/4
✓ Branch 0 taken 937604 times.
✓ Branch 1 taken 67314 times.
✓ Branch 2 taken 890083 times.
✓ Branch 3 taken 47521 times.
1004918 const int addin = sh_dep_quant_used_flag && !tb->ts;
340 1004918 const int qp = tb->qp + addin;
341
342 1004918 return level_scale[tb->rect_non_ts_flag][rem6[qp]] << div6[qp];
343 }
344
345 //8.7.3 Scaling process for transform coefficients
346 1004918 static const uint8_t* derive_scale_m(const VVCLocalContext *lc, const TransformBlock *tb, uint8_t *scale_m)
347 {
348 //Table 38 – Specification of the scaling matrix identifier variable id according to predMode, cIdx, nTbW, and nTbH
349 1004918 const int ids[2][3][6] = {
350 {
351 { 0, 2, 8, 14, 20, 26 },
352 { 0, 3, 9, 15, 21, 21 },
353 { 0, 4, 10, 16, 22, 22 }
354 },
355 {
356 { 0, 5, 11, 17, 23, 27 },
357 { 0, 6, 12, 18, 24, 24 },
358 { 1, 7, 13, 19, 25, 25 },
359 }
360 };
361 1004918 const VVCFrameParamSets *ps = &lc->fc->ps;
362 1004918 const VVCSPS *sps = ps->sps;
363 1004918 const H266RawSliceHeader *rsh = lc->sc->sh.r;
364 1004918 const CodingUnit *cu = lc->cu;
365 1004918 const VVCScalingList *sl = ps->sl;
366 1004918 const int id = ids[cu->pred_mode != MODE_INTRA][tb->c_idx][FFMAX(tb->log2_tb_height, tb->log2_tb_width) - 1];
367
4/4
✓ Branch 0 taken 1002067 times.
✓ Branch 1 taken 2851 times.
✓ Branch 2 taken 176144 times.
✓ Branch 3 taken 825923 times.
1004918 const int log2_matrix_size = (id < 2) ? 1 : (id < 8) ? 2 : 3;
368 1004918 uint8_t *p = scale_m;
369
370
4/4
✓ Branch 0 taken 99612 times.
✓ Branch 1 taken 905306 times.
✓ Branch 2 taken 97122 times.
✓ Branch 3 taken 2490 times.
1004918 if (!rsh->sh_explicit_scaling_list_used_flag || tb->ts ||
371
3/4
✓ Branch 0 taken 97122 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 65726 times.
✓ Branch 3 taken 31396 times.
97122 (sps->r->sps_scaling_matrix_for_lfnst_disabled_flag && cu->apply_lfnst_flag[tb->c_idx]) ||
372
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65726 times.
65726 (sps->r->sps_scaling_matrix_for_alternative_colour_space_disabled_flag &&
373 sps->r->sps_scaling_matrix_designated_colour_space_flag == cu->act_enabled_flag))
374 939192 return ff_vvc_default_scale_m;
375
376
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65726 times.
65726 if (!sl) {
377 av_log(lc->fc->log_ctx, AV_LOG_WARNING, "bug: no scaling list aps, id = %d", ps->ph.r->ph_scaling_list_aps_id);
378 return ff_vvc_default_scale_m;
379 }
380
381
2/2
✓ Branch 0 taken 326806 times.
✓ Branch 1 taken 65726 times.
392532 for (int y = tb->min_scan_y; y <= tb->max_scan_y; y++) {
382 326806 const int off = y << log2_matrix_size >> tb->log2_tb_height << log2_matrix_size;
383 326806 const uint8_t *m = &sl->scaling_matrix_rec[id][off];
384
385
2/2
✓ Branch 0 taken 1859082 times.
✓ Branch 1 taken 326806 times.
2185888 for (int x = tb->min_scan_x; x <= tb->max_scan_x; x++)
386 1859082 *p++ = m[x << log2_matrix_size >> tb->log2_tb_width];
387 }
388
4/6
✓ Branch 0 taken 27312 times.
✓ Branch 1 taken 38414 times.
✓ Branch 2 taken 27312 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27312 times.
✗ Branch 5 not taken.
65726 if (id >= SL_START_16x16 && !tb->min_scan_x && !tb->min_scan_y)
389 27312 *scale_m = sl->scaling_matrix_dc_rec[id - SL_START_16x16];
390
391 65726 return scale_m;
392 }
393
394 //8.7.3 Scaling process for transform coefficients
395 11761615 static av_always_inline int scale_coeff(const TransformBlock *tb, int coeff,
396 const int scale, const int scale_m, const int log2_transform_range)
397 {
398 11761615 coeff = ((int64_t) coeff * scale * scale_m + tb->bd_offset) >> tb->bd_shift;
399 11761615 coeff = av_clip_intp2(coeff, log2_transform_range);
400 11761615 return coeff;
401 }
402
403 1004918 static void dequant(const VVCLocalContext *lc, const TransformUnit *tu, TransformBlock *tb)
404 {
405 uint8_t tmp[MAX_TB_SIZE * MAX_TB_SIZE];
406 1004918 const H266RawSliceHeader *rsh = lc->sc->sh.r;
407 1004918 const VVCSPS *sps = lc->fc->ps.sps;
408 1004918 const uint8_t *scale_m = derive_scale_m(lc, tb, tmp);
409 int scale;
410
411 1004918 derive_qp(lc, tu, tb);
412 1004918 scale = derive_scale(tb, rsh->sh_dep_quant_used_flag);
413
414
2/2
✓ Branch 0 taken 3881159 times.
✓ Branch 1 taken 1004918 times.
4886077 for (int y = tb->min_scan_y; y <= tb->max_scan_y; y++) {
415
2/2
✓ Branch 0 taken 23205185 times.
✓ Branch 1 taken 3881159 times.
27086344 for (int x = tb->min_scan_x; x <= tb->max_scan_x; x++) {
416 23205185 int *coeff = tb->coeffs + y * tb->tb_width + x;
417
418
2/2
✓ Branch 0 taken 11761615 times.
✓ Branch 1 taken 11443570 times.
23205185 if (*coeff)
419 11761615 *coeff = scale_coeff(tb, *coeff, scale, *scale_m, sps->log2_transform_range);
420 23205185 scale_m++;
421 }
422 }
423 1004918 }
424
425 //transmatrix[0][0]
426 #define DCT_A 64
427 940923 static void itx_2d(const VVCFrameContext *fc, TransformBlock *tb, const enum VVCTxType trh, const enum VVCTxType trv)
428 {
429 940923 const VVCSPS *sps = fc->ps.sps;
430 940923 const int w = tb->tb_width;
431 940923 const int h = tb->tb_height;
432 940923 const size_t nzw = tb->max_scan_x + 1;
433 940923 const size_t nzh = tb->max_scan_y + 1;
434 940923 const int shift[] = { 7, 5 + sps->log2_transform_range - sps->bit_depth };
435
436
9/10
✓ Branch 0 taken 349451 times.
✓ Branch 1 taken 591472 times.
✓ Branch 2 taken 77116 times.
✓ Branch 3 taken 272335 times.
✓ Branch 4 taken 53541 times.
✓ Branch 5 taken 23575 times.
✓ Branch 6 taken 46938 times.
✓ Branch 7 taken 6603 times.
✓ Branch 8 taken 46938 times.
✗ Branch 9 not taken.
940923 if (w == h && nzw == 1 && nzh == 1 && trh == VVC_DCT2 && trv == VVC_DCT2) {
437 46938 const int add[] = { 1 << (shift[0] - 1), 1 << (shift[1] - 1) };
438 46938 const int t = (tb->coeffs[0] * DCT_A + add[0]) >> shift[0];
439 46938 const int dc = (t * DCT_A + add[1]) >> shift[1];
440
441
2/2
✓ Branch 0 taken 17189760 times.
✓ Branch 1 taken 46938 times.
17236698 for (int i = 0; i < w * h; i++)
442 17189760 tb->coeffs[i] = dc;
443
444 46938 return;
445 }
446
447
2/2
✓ Branch 0 taken 4241455 times.
✓ Branch 1 taken 893985 times.
5135440 for (int x = 0; x < nzw; x++)
448 4241455 fc->vvcdsp.itx.itx[trv][tb->log2_tb_height - 1](tb->coeffs + x, w, nzh);
449 893985 scale_clip(tb->coeffs, nzw, w, h, shift[0], sps->log2_transform_range);
450
451
2/2
✓ Branch 0 taken 9214426 times.
✓ Branch 1 taken 893985 times.
10108411 for (int y = 0; y < h; y++)
452 9214426 fc->vvcdsp.itx.itx[trh][tb->log2_tb_width - 1](tb->coeffs + y * w, 1, nzw);
453 893985 scale(tb->coeffs, tb->coeffs, w, h, shift[1]);
454 }
455
456 16474 static void itx_1d(const VVCFrameContext *fc, TransformBlock *tb, const enum VVCTxType trh, const enum VVCTxType trv)
457 {
458 16474 const VVCSPS *sps = fc->ps.sps;
459 16474 const int w = tb->tb_width;
460 16474 const int h = tb->tb_height;
461 16474 const size_t nzw = tb->max_scan_x + 1;
462 16474 const size_t nzh = tb->max_scan_y + 1;
463
464
12/12
✓ Branch 0 taken 13610 times.
✓ Branch 1 taken 2864 times.
✓ Branch 2 taken 5003 times.
✓ Branch 3 taken 8607 times.
✓ Branch 4 taken 2083 times.
✓ Branch 5 taken 2920 times.
✓ Branch 6 taken 2864 times.
✓ Branch 7 taken 10690 times.
✓ Branch 8 taken 786 times.
✓ Branch 9 taken 2078 times.
✓ Branch 10 taken 181 times.
✓ Branch 11 taken 605 times.
16474 if ((w > 1 && nzw == 1 && trh == VVC_DCT2) || (h > 1 && nzh == 1 && trv == VVC_DCT2)) {
465 3101 const int shift = 6 + sps->log2_transform_range - sps->bit_depth;
466 3101 const int add = 1 << (shift - 1);
467 3101 const int dc = (tb->coeffs[0] * DCT_A + add) >> shift;
468
469
2/2
✓ Branch 0 taken 99584 times.
✓ Branch 1 taken 3101 times.
102685 for (int i = 0; i < w * h; i++)
470 99584 tb->coeffs[i] = dc;
471
472 3101 return;
473 }
474
475
2/2
✓ Branch 0 taken 10690 times.
✓ Branch 1 taken 2683 times.
13373 if (w > 1)
476 10690 fc->vvcdsp.itx.itx[trh][tb->log2_tb_width - 1](tb->coeffs, 1, nzw);
477 else
478 2683 fc->vvcdsp.itx.itx[trv][tb->log2_tb_height - 1](tb->coeffs, 1, nzh);
479 13373 scale(tb->coeffs, tb->coeffs, w, h, 6 + sps->log2_transform_range - sps->bit_depth);
480 }
481
482 2205 static void transform_bdpcm(TransformBlock *tb, const VVCLocalContext *lc, const CodingUnit *cu)
483 {
484 2205 const VVCSPS *sps = lc->fc->ps.sps;
485
2/2
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 2115 times.
2205 const IntraPredMode mode = tb->c_idx ? cu->intra_pred_mode_c : cu->intra_pred_mode_y;
486 2205 const int vertical = mode == INTRA_VERT;
487 2205 lc->fc->vvcdsp.itx.transform_bdpcm(tb->coeffs, tb->tb_width, tb->tb_height,
488 2205 vertical, sps->log2_transform_range);
489
2/2
✓ Branch 0 taken 1418 times.
✓ Branch 1 taken 787 times.
2205 if (vertical)
490 1418 tb->max_scan_y = tb->tb_height - 1;
491 else
492 787 tb->max_scan_x = tb->tb_width - 1;
493 2205 }
494
495 1004918 static void lmcs_scale_chroma(VVCLocalContext *lc, TransformUnit *tu, TransformBlock *tb, const int target_ch_type)
496 {
497 1004918 const VVCFrameContext *fc = lc->fc;
498 1004918 const VVCSH *sh = &lc->sc->sh;
499 1004918 const CodingUnit *cu = lc->cu;
500 1004918 const int c_idx = tb->c_idx;
501 1004918 const int ch_type = c_idx > 0;
502 1004918 const int w = tb->tb_width;
503 1004918 const int h = tb->tb_height;
504
7/8
✓ Branch 0 taken 269651 times.
✓ Branch 1 taken 735267 times.
✓ Branch 2 taken 126829 times.
✓ Branch 3 taken 142822 times.
✓ Branch 4 taken 126829 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 124756 times.
✓ Branch 7 taken 2073 times.
1004918 const int chroma_scale = ch_type && sh->r->sh_lmcs_used_flag && fc->ps.ph.r->ph_chroma_residual_scale_flag && (w * h > 4);
505
4/4
✓ Branch 0 taken 67780 times.
✓ Branch 1 taken 937138 times.
✓ Branch 2 taken 54225 times.
✓ Branch 3 taken 13555 times.
1004918 const int has_jcbcr = tu->joint_cbcr_residual_flag && c_idx;
506
507
2/2
✓ Branch 0 taken 1059143 times.
✓ Branch 1 taken 1004918 times.
2064061 for (int j = 0; j < 1 + has_jcbcr; j++) {
508 1059143 const bool is_jcbcr = j > 0;
509 1059143 const int jcbcr_idx = CB + tu->coded_flag[CB];
510 1059143 TransformBlock *jcbcr = &tu->tbs[jcbcr_idx - tu->tbs[0].c_idx];
511
2/2
✓ Branch 0 taken 54225 times.
✓ Branch 1 taken 1004918 times.
1059143 int *coeffs = is_jcbcr ? jcbcr->coeffs : tb->coeffs;
512
513
4/4
✓ Branch 0 taken 1004918 times.
✓ Branch 1 taken 54225 times.
✓ Branch 2 taken 54225 times.
✓ Branch 3 taken 950693 times.
1059143 if (!j && has_jcbcr) {
514 54225 const int c_sign = 1 - 2 * fc->ps.ph.r->ph_joint_cbcr_sign_flag;
515 54225 const int shift = tu->coded_flag[CB] ^ tu->coded_flag[CR];
516 54225 fc->vvcdsp.itx.pred_residual_joint(jcbcr->coeffs, tb->coeffs, w, h, c_sign, shift);
517 }
518
2/2
✓ Branch 0 taken 151209 times.
✓ Branch 1 taken 907934 times.
1059143 if (chroma_scale)
519 151209 fc->vvcdsp.intra.lmcs_scale_chroma(lc, coeffs, w, h, cu->x0, cu->y0);
520 }
521 1004918 }
522
523 1494996 static void add_residual(const VVCLocalContext *lc, TransformUnit *tu, const int target_ch_type)
524 {
525 1494996 const VVCFrameContext *fc = lc->fc;
526 1494996 const CodingUnit *cu = lc->cu;
527
528
2/2
✓ Branch 0 taken 2817412 times.
✓ Branch 1 taken 1494996 times.
4312408 for (int i = 0; i < tu->nb_tbs; i++) {
529 2817412 TransformBlock *tb = tu->tbs + i;
530 2817412 const int c_idx = tb->c_idx;
531 2817412 const int ch_type = c_idx > 0;
532 2817412 const ptrdiff_t stride = fc->frame->linesize[c_idx];
533
6/6
✓ Branch 0 taken 1522831 times.
✓ Branch 1 taken 1294581 times.
✓ Branch 2 taken 1474063 times.
✓ Branch 3 taken 48768 times.
✓ Branch 4 taken 1099522 times.
✓ Branch 5 taken 374541 times.
3916934 const bool has_residual = tb->has_coeffs || cu->act_enabled_flag ||
534
2/2
✓ Branch 0 taken 76187 times.
✓ Branch 1 taken 1023335 times.
1099522 (c_idx && tu->joint_cbcr_residual_flag);
535 2817412 uint8_t *dst = POS(c_idx, tb->x0, tb->y0);
536
537
4/4
✓ Branch 0 taken 1950044 times.
✓ Branch 1 taken 867368 times.
✓ Branch 2 taken 1083070 times.
✓ Branch 3 taken 866974 times.
2817412 if (ch_type == target_ch_type && has_residual)
538 1083070 fc->vvcdsp.itx.add_residual(dst, tb->coeffs, tb->tb_width, tb->tb_height, stride);
539 }
540 1494996 }
541
542 1494996 static void itransform(VVCLocalContext *lc, TransformUnit *tu, const int target_ch_type)
543 {
544 1494996 const VVCFrameContext *fc = lc->fc;
545 1494996 const CodingUnit *cu = lc->cu;
546 1494996 TransformBlock *tbs = tu->tbs;
547
4/4
✓ Branch 0 taken 30308 times.
✓ Branch 1 taken 1464688 times.
✓ Branch 2 taken 15154 times.
✓ Branch 3 taken 15154 times.
1494996 const bool is_act_luma = cu->act_enabled_flag && target_ch_type == LUMA;
548
549
2/2
✓ Branch 0 taken 2817412 times.
✓ Branch 1 taken 1494996 times.
4312408 for (int i = 0; i < tu->nb_tbs; i++) {
550 2817412 TransformBlock *tb = tbs + i;
551 2817412 const int c_idx = tb->c_idx;
552 2817412 const int ch_type = c_idx > 0;
553
6/6
✓ Branch 0 taken 2771950 times.
✓ Branch 1 taken 45462 times.
✓ Branch 2 taken 2726488 times.
✓ Branch 3 taken 45462 times.
✓ Branch 4 taken 1904582 times.
✓ Branch 5 taken 821906 times.
2817412 const bool do_itx = is_act_luma || !cu->act_enabled_flag && ch_type == target_ch_type;
554
555
4/4
✓ Branch 0 taken 1294581 times.
✓ Branch 1 taken 1522831 times.
✓ Branch 2 taken 1004918 times.
✓ Branch 3 taken 289663 times.
2817412 if (tb->has_coeffs && do_itx) {
556
2/2
✓ Branch 0 taken 2205 times.
✓ Branch 1 taken 1002713 times.
1004918 if (cu->bdpcm_flag[tb->c_idx])
557 2205 transform_bdpcm(tb, lc, cu);
558 1004918 dequant(lc, tu, tb);
559
2/2
✓ Branch 0 taken 957397 times.
✓ Branch 1 taken 47521 times.
1004918 if (!tb->ts) {
560 enum VVCTxType trh, trv;
561
562
2/2
✓ Branch 0 taken 174834 times.
✓ Branch 1 taken 782563 times.
957397 if (cu->apply_lfnst_flag[c_idx])
563 174834 ilfnst_transform(lc, tb);
564 957397 derive_transform_type(fc, lc, tb, &trh, &trv);
565
4/4
✓ Branch 0 taken 954533 times.
✓ Branch 1 taken 2864 times.
✓ Branch 2 taken 940923 times.
✓ Branch 3 taken 13610 times.
957397 if (tb->tb_width > 1 && tb->tb_height > 1)
566 940923 itx_2d(fc, tb, trh, trv);
567 else
568 16474 itx_1d(fc, tb, trh, trv);
569 }
570 1004918 lmcs_scale_chroma(lc, tu, tb, target_ch_type);
571 }
572 }
573
574
2/2
✓ Branch 0 taken 15154 times.
✓ Branch 1 taken 1479842 times.
1494996 if (is_act_luma) {
575 15154 fc->vvcdsp.itx.adaptive_color_transform(
576 15154 tbs[LUMA].coeffs, tbs[CB].coeffs, tbs[CR].coeffs,
577 tbs[LUMA].tb_width, tbs[LUMA].tb_height);
578 }
579
580 1494996 add_residual(lc, tu, target_ch_type);
581 1494996 }
582
583 990255 static int reconstruct(VVCLocalContext *lc)
584 {
585 990255 VVCFrameContext *fc = lc->fc;
586 990255 CodingUnit *cu = lc->cu;
587 990255 const int start = cu->tree_type == DUAL_TREE_CHROMA;
588
4/4
✓ Branch 0 taken 971127 times.
✓ Branch 1 taken 19128 times.
✓ Branch 2 taken 415345 times.
✓ Branch 3 taken 555782 times.
990255 const int end = fc->ps.sps->r->sps_chroma_format_idc && (cu->tree_type != DUAL_TREE_LUMA);
589
590
2/2
✓ Branch 0 taken 1218292 times.
✓ Branch 1 taken 990255 times.
2208547 for (int ch_type = start; ch_type <= end; ch_type++) {
591 1218292 TransformUnit *tu = cu->tus.head;
592
2/2
✓ Branch 0 taken 1494996 times.
✓ Branch 1 taken 1218292 times.
2713288 for (int i = 0; tu; i++) {
593 1494996 predict_intra(lc, tu, i, ch_type);
594 1494996 itransform(lc, tu, ch_type);
595 1494996 tu = tu->next;
596 }
597 }
598 990255 return 0;
599 }
600
601 #define IBC_POS(c_idx, x, y) \
602 (fc->tab.ibc_vir_buf[c_idx] + \
603 (x << ps) + (y + ((cu->y0 & ~(sps->ctb_size_y - 1)) >> vs)) * ibc_stride)
604 #define IBC_X(x) ((x) & ((fc->tab.sz.ibc_buffer_width >> hs) - 1))
605 #define IBC_Y(y) ((y) & ((1 << sps->ctb_log2_size_y >> vs) - 1))
606
607 123438 static void intra_block_copy(const VVCLocalContext *lc, const int c_idx)
608 {
609 123438 const CodingUnit *cu = lc->cu;
610 123438 const PredictionUnit *pu = &cu->pu;
611 123438 const VVCFrameContext *fc = lc->fc;
612 123438 const VVCSPS *sps = fc->ps.sps;
613 123438 const Mv *bv = &pu->mi.mv[L0][0];
614 123438 const int hs = sps->hshift[c_idx];
615 123438 const int vs = sps->vshift[c_idx];
616 123438 const int ps = sps->pixel_shift;
617 123438 const int ref_x = IBC_X((cu->x0 >> hs) + (bv->x >> (4 + hs)));
618 123438 const int ref_y = IBC_Y((cu->y0 >> vs) + (bv->y >> (4 + vs)));
619 123438 const int w = cu->cb_width >> hs;
620 123438 const int h = cu->cb_height >> vs;
621 123438 const int ibc_buf_width = fc->tab.sz.ibc_buffer_width >> hs; ///< IbcBufWidthY and IbcBufWidthC
622 123438 const int rw = FFMIN(w, ibc_buf_width - ref_x);
623 123438 const int ibc_stride = ibc_buf_width << ps;
624 123438 const int dst_stride = fc->frame->linesize[c_idx];
625 123438 const uint8_t *ibc_buf = IBC_POS(c_idx, ref_x, ref_y);
626 123438 uint8_t *dst = POS(c_idx, cu->x0, cu->y0);
627
628 123438 av_image_copy_plane(dst, dst_stride, ibc_buf, ibc_stride, rw << ps, h);
629
630
2/2
✓ Branch 0 taken 1566 times.
✓ Branch 1 taken 121872 times.
123438 if (w > rw) {
631 //wrap around, left part
632 1566 ibc_buf = IBC_POS(c_idx, 0, ref_y);
633 1566 dst += rw << ps;
634 1566 av_image_copy_plane(dst, dst_stride, ibc_buf, ibc_stride, (w - rw) << ps, h);
635 }
636 123438 }
637
638 67240 static void vvc_predict_ibc(const VVCLocalContext *lc)
639 {
640 67240 const H266RawSPS *rsps = lc->fc->ps.sps->r;
641
642 67240 intra_block_copy(lc, LUMA);
643
3/4
✓ Branch 0 taken 28099 times.
✓ Branch 1 taken 39141 times.
✓ Branch 2 taken 28099 times.
✗ Branch 3 not taken.
67240 if (lc->cu->tree_type == SINGLE_TREE && rsps->sps_chroma_format_idc) {
644 28099 intra_block_copy(lc, CB);
645 28099 intra_block_copy(lc, CR);
646 }
647 67240 }
648
649 220290 static void ibc_fill_vir_buf(const VVCLocalContext *lc, const CodingUnit *cu)
650 {
651 220290 const VVCFrameContext *fc = lc->fc;
652 220290 const VVCSPS *sps = fc->ps.sps;
653 int start, end;
654
655 220290 ff_vvc_channel_range(&start, &end, cu->tree_type, sps->r->sps_chroma_format_idc);
656
657
2/2
✓ Branch 0 taken 446095 times.
✓ Branch 1 taken 220290 times.
666385 for (int c_idx = start; c_idx < end; c_idx++) {
658 446095 const int hs = sps->hshift[c_idx];
659 446095 const int vs = sps->vshift[c_idx];
660 446095 const int ps = sps->pixel_shift;
661 446095 const int x = IBC_X(cu->x0 >> hs);
662 446095 const int y = IBC_Y(cu->y0 >> vs);
663 446095 const int src_stride = fc->frame->linesize[c_idx];
664 446095 const int ibc_stride = fc->tab.sz.ibc_buffer_width >> hs << ps;
665 446095 const uint8_t *src = POS(c_idx, cu->x0, cu->y0);
666 446095 uint8_t *ibc_buf = IBC_POS(c_idx, x, y);
667
668 446095 av_image_copy_plane(ibc_buf, ibc_stride, src, src_stride, cu->cb_width >> hs << ps , cu->cb_height >> vs);
669 }
670 220290 }
671
672 177356 int ff_vvc_palette_derive_scale(VVCLocalContext *lc, const TransformUnit *tu, TransformBlock *tb)
673 {
674 177356 const VVCSPS *sps = lc->fc->ps.sps;
675 177356 const int qp_prime_ts_min = 4 + 6 * sps->r->sps_min_qp_prime_ts;
676 int qp;
677
678 177356 derive_qp(lc, tu, tb);
679 177356 qp = FFMAX(qp_prime_ts_min, tb->qp);
680 177356 return level_scale[0][rem6[qp]] << div6[qp];
681 }
682
683 // 8.4.5.3 Decoding process for palette mode
684 4497 static void vvc_predict_palette(VVCLocalContext *lc)
685 {
686 4497 const VVCFrameContext *fc = lc->fc;
687 4497 const CodingUnit *cu = lc->cu;
688 4497 TransformUnit *tu = cu->tus.head;
689 4497 const VVCSPS *sps = fc->ps.sps;
690 4497 const int ps = sps->pixel_shift;
691
692
2/2
✓ Branch 0 taken 12587 times.
✓ Branch 1 taken 4497 times.
17084 for (int i = 0; i < tu->nb_tbs; i++) {
693 12587 TransformBlock *tb = &tu->tbs[i];
694 12587 const int c_idx = tb->c_idx;
695 12587 const int w = tb->tb_width;
696 12587 const int h = tb->tb_height;
697 12587 const ptrdiff_t stride = fc->frame->linesize[c_idx];
698 12587 uint8_t *dst = POS(c_idx, cu->x0, cu->y0);
699
700 12587 av_image_copy_plane(dst, stride, (uint8_t*)tb->coeffs, w << ps, w << ps, h);
701 }
702 4497 }
703
704 53355 int ff_vvc_reconstruct(VVCLocalContext *lc, const int rs, const int rx, const int ry)
705 {
706 53355 const VVCFrameContext *fc = lc->fc;
707 53355 const VVCSPS *sps = fc->ps.sps;
708 53355 const int x_ctb = rx << sps->ctb_log2_size_y;
709 53355 const int y_ctb = ry << sps->ctb_log2_size_y;
710 53355 CodingUnit *cu = fc->tab.cus[rs];
711 53355 int ret = 0;
712
713 53355 lc->num_ras[0] = lc->num_ras[1] = 0;
714 53355 lc->lmcs.x_vpdu = -1;
715 53355 lc->lmcs.y_vpdu = -1;
716 53355 ff_vvc_decode_neighbour(lc, x_ctb, y_ctb, rx, ry, rs);
717
2/2
✓ Branch 0 taken 1344148 times.
✓ Branch 1 taken 53355 times.
1397503 while (cu) {
718 1344148 lc->cu = cu;
719
720
2/2
✓ Branch 0 taken 16327 times.
✓ Branch 1 taken 1327821 times.
1344148 if (cu->ciip_flag)
721 16327 ff_vvc_predict_ciip(lc);
722
2/2
✓ Branch 0 taken 67240 times.
✓ Branch 1 taken 1260581 times.
1327821 else if (cu->pred_mode == MODE_IBC)
723 67240 vvc_predict_ibc(lc);
724
2/2
✓ Branch 0 taken 4497 times.
✓ Branch 1 taken 1256084 times.
1260581 else if (cu->pred_mode == MODE_PLT)
725 4497 vvc_predict_palette(lc);
726
2/2
✓ Branch 0 taken 990255 times.
✓ Branch 1 taken 353893 times.
1344148 if (cu->coded_flag) {
727 990255 ret = reconstruct(lc);
728 } else {
729
1/2
✓ Branch 0 taken 353893 times.
✗ Branch 1 not taken.
353893 if (cu->tree_type != DUAL_TREE_CHROMA)
730 353893 add_reconstructed_area(lc, LUMA, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
731
4/4
✓ Branch 0 taken 337382 times.
✓ Branch 1 taken 16511 times.
✓ Branch 2 taken 306389 times.
✓ Branch 3 taken 30993 times.
353893 if (sps->r->sps_chroma_format_idc && cu->tree_type != DUAL_TREE_LUMA)
732 306389 add_reconstructed_area(lc, CHROMA, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
733 }
734
2/2
✓ Branch 0 taken 220290 times.
✓ Branch 1 taken 1123858 times.
1344148 if (sps->r->sps_ibc_enabled_flag)
735 220290 ibc_fill_vir_buf(lc, cu);
736 1344148 cu = cu->next;
737 }
738 53355 ff_vvc_ctu_free_cus(fc->tab.cus + rs);
739 53355 return ret;
740 }
741