FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/vvc/intra.c
Date: 2026-01-23 14:02:51
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 421959 static int is_cclm(enum IntraPredMode mode)
35 {
36
6/6
✓ Branch 0 taken 358282 times.
✓ Branch 1 taken 63677 times.
✓ Branch 2 taken 334434 times.
✓ Branch 3 taken 23848 times.
✓ Branch 4 taken 26387 times.
✓ Branch 5 taken 308047 times.
421959 return mode == INTRA_LT_CCLM || mode == INTRA_L_CCLM || mode == INTRA_T_CCLM;
37 }
38
39 174836 static int derive_ilfnst_pred_mode_intra(const VVCLocalContext *lc, const TransformBlock *tb)
40 {
41 174836 const VVCFrameContext *fc = lc->fc;
42 174836 const VVCSPS *sps = fc->ps.sps;
43 174836 const CodingUnit *cu = lc->cu;
44 174836 const int x_tb = tb->x0 >> fc->ps.sps->min_cb_log2_size_y;
45 174836 const int y_tb = tb->y0 >> fc->ps.sps->min_cb_log2_size_y;
46 174836 const int x_c = (tb->x0 + (tb->tb_width << sps->hshift[1] >> 1) ) >> fc->ps.sps->min_cb_log2_size_y;
47 174836 const int y_c = (tb->y0 + (tb->tb_height << sps->vshift[1] >> 1)) >> fc->ps.sps->min_cb_log2_size_y;
48 174836 const int min_cb_width = fc->ps.pps->min_cb_width;
49 174836 const int intra_mip_flag = SAMPLE_CTB(fc->tab.imf, x_tb, y_tb);
50
2/2
✓ Branch 0 taken 123299 times.
✓ Branch 1 taken 51537 times.
174836 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 154822 times.
✓ Branch 2 taken 5109 times.
✓ Branch 3 taken 14905 times.
174836 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 153452 times.
169727 } 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 174836 pred_mode_intra = ff_vvc_wide_angle_mode_mapping(cu, tb->tb_width, tb->tb_height, tb->c_idx, pred_mode_intra);
65
66 174836 return pred_mode_intra;
67 }
68
69 //8.7.4 Transformation process for scaled transform coefficients
70 174836 static void ilfnst_transform(const VVCLocalContext *lc, TransformBlock *tb)
71 {
72 174836 const VVCSPS *sps = lc->fc->ps.sps;
73 174836 const CodingUnit *cu = lc->cu;
74 174836 const int w = tb->tb_width;
75 174836 const int h = tb->tb_height;
76
4/4
✓ Branch 0 taken 101278 times.
✓ Branch 1 taken 73558 times.
✓ Branch 2 taken 69100 times.
✓ Branch 3 taken 32178 times.
174836 const int n_lfnst_out_size = (w >= 8 && h >= 8) ? 48 : 16; ///< nLfnstOutSize
77
4/4
✓ Branch 0 taken 101278 times.
✓ Branch 1 taken 73558 times.
✓ Branch 2 taken 69100 times.
✓ Branch 3 taken 32178 times.
174836 const int log2_lfnst_size = (w >= 8 && h >= 8) ? 3 : 2; ///< log2LfnstSize
78 174836 const int n_lfnst_size = 1 << log2_lfnst_size; ///< nLfnstSize
79
8/8
✓ Branch 0 taken 40607 times.
✓ Branch 1 taken 134229 times.
✓ Branch 2 taken 27925 times.
✓ Branch 3 taken 12682 times.
✓ Branch 4 taken 73558 times.
✓ Branch 5 taken 88596 times.
✓ Branch 6 taken 50345 times.
✓ Branch 7 taken 23213 times.
174836 const int non_zero_size = ((w == 8 && h == 8) || (w == 4 && h == 4)) ? 8 : 16; ///< nonZeroSize
80 174836 const int pred_mode_intra = derive_ilfnst_pred_mode_intra(lc, tb);
81 174836 const int transpose = pred_mode_intra > 34;
82 int u[16], v[48];
83
84
2/2
✓ Branch 0 taken 2293160 times.
✓ Branch 1 taken 174836 times.
2467996 for (int x = 0; x < non_zero_size; x++) {
85 2293160 int xc = ff_vvc_diag_scan_x[2][2][x];
86 2293160 int yc = ff_vvc_diag_scan_y[2][2][x];
87 2293160 u[x] = tb->coeffs[w * yc + xc];
88 }
89 174836 ff_vvc_inv_lfnst_1d(v, u, non_zero_size, n_lfnst_out_size, pred_mode_intra,
90 174836 cu->lfnst_idx, sps->log2_transform_range);
91
2/2
✓ Branch 0 taken 50702 times.
✓ Branch 1 taken 124134 times.
174836 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 124134 int *dst = tb->coeffs;
122 124134 const int *src = v;
123
2/2
✓ Branch 0 taken 711688 times.
✓ Branch 1 taken 124134 times.
835822 for (int y = 0; y < n_lfnst_size; y++) {
124
2/2
✓ Branch 0 taken 496536 times.
✓ Branch 1 taken 215152 times.
711688 int size = (y < 4) ? n_lfnst_size : 4;
125 711688 memcpy(dst, src, size * sizeof(int));
126 711688 src += size;
127 711688 dst += w;
128 }
129 }
130 174836 tb->max_scan_x = n_lfnst_size - 1;
131 174836 tb->max_scan_y = n_lfnst_size - 1;
132 174836 }
133
134 //part of 8.7.4 Transformation process for scaled transform coefficients
135 957406 static void derive_transform_type(const VVCFrameContext *fc, const VVCLocalContext *lc, const TransformBlock *tb, enum VVCTxType *trh, enum VVCTxType *trv)
136 {
137 957406 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 957406 const VVCSPS *sps = fc->ps.sps;
141 957406 int implicit_mts_enabled = 0;
142
6/6
✓ Branch 0 taken 692893 times.
✓ Branch 1 taken 264513 times.
✓ Branch 2 taken 142447 times.
✓ Branch 3 taken 550446 times.
✓ Branch 4 taken 32815 times.
✓ Branch 5 taken 109632 times.
957406 if (tb->c_idx || (cu->isp_split_type != ISP_NO_SPLIT && cu->lfnst_idx)) {
143 297328 *trh = *trv = VVC_DCT2;
144 297328 return;
145 }
146
147
2/2
✓ Branch 0 taken 656184 times.
✓ Branch 1 taken 3894 times.
660078 if (sps->r->sps_mts_enabled_flag) {
148
2/2
✓ Branch 0 taken 546552 times.
✓ Branch 1 taken 109632 times.
656184 if (cu->isp_split_type != ISP_NO_SPLIT ||
149
4/4
✓ Branch 0 taken 34956 times.
✓ Branch 1 taken 511596 times.
✓ Branch 2 taken 523 times.
✓ Branch 3 taken 34433 times.
546552 (cu->sbt_flag && FFMAX(tb->tb_width, tb->tb_height) <= 32) ||
150
4/4
✓ Branch 0 taken 45019 times.
✓ Branch 1 taken 467100 times.
✓ Branch 2 taken 28412 times.
✓ Branch 3 taken 16607 times.
512119 (!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 158657 implicit_mts_enabled = 1;
153 }
154 }
155
2/2
✓ Branch 0 taken 158657 times.
✓ Branch 1 taken 501421 times.
660078 if (implicit_mts_enabled) {
156 158657 const int w = tb->tb_width;
157 158657 const int h = tb->tb_height;
158
2/2
✓ Branch 0 taken 34433 times.
✓ Branch 1 taken 124224 times.
158657 if (cu->sbt_flag) {
159
4/4
✓ Branch 0 taken 18254 times.
✓ Branch 1 taken 16179 times.
✓ Branch 2 taken 8586 times.
✓ Branch 3 taken 9668 times.
34433 *trh = (cu->sbt_horizontal_flag || cu->sbt_pos_flag) ? VVC_DST7 : VVC_DCT8;
160
4/4
✓ Branch 0 taken 16179 times.
✓ Branch 1 taken 18254 times.
✓ Branch 2 taken 7800 times.
✓ Branch 3 taken 8379 times.
34433 *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 158657 return;
166 }
167 501421 *trh = mts_to_trh[cu->mts_idx];
168 501421 *trv = mts_to_trv[cu->mts_idx];
169 }
170
171 2124694 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 2124694 const VVCSPS *sps = lc->fc->ps.sps;
174 2124694 const int hs = sps->hshift[ch_type];
175 2124694 const int vs = sps->vshift[ch_type];
176 ReconstructedArea *a;
177
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2124694 times.
2124694 if (lc->num_ras[ch_type] >= FF_ARRAY_ELEMS(lc->ras[ch_type]))
179 return AVERROR_INVALIDDATA;
180
181 2124694 a = &lc->ras[ch_type][lc->num_ras[ch_type]];
182 2124694 a->x = x0 >> hs;
183 2124694 a->y = y0 >> vs;
184 2124694 a->w = w >> hs;
185 2124694 a->h = h >> vs;
186 2124694 lc->num_ras[ch_type]++;
187
188 2124694 return 0;
189 }
190
191 1019736 static void add_tu_area(const TransformUnit *tu, int *x0, int *y0, int *w, int *h)
192 {
193 1019736 *x0 = tu->x0;
194 1019736 *y0 = tu->y0;
195 1019736 *w = tu->width;
196 1019736 *h = tu->height;
197 1019736 }
198
199 #define MIN_ISP_PRED_WIDTH 4
200 773131 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 773131 int has_luma = 1;
203 773131 add_tu_area(tu, x0, y0, w, h);
204
4/4
✓ Branch 0 taken 76438 times.
✓ Branch 1 taken 696693 times.
✓ Branch 2 taken 27478 times.
✓ Branch 3 taken 48960 times.
773131 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 773131 return has_luma;
209 }
210
211 268911 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 246605 times.
✓ Branch 1 taken 22306 times.
268911 if (cu->isp_split_type == ISP_NO_SPLIT) {
214 246605 add_tu_area(tu, x0, y0, w, h);
215 246605 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 1495020 static void predict_intra(VVCLocalContext *lc, const TransformUnit *tu, const int idx, const int target_ch_type)
229 {
230 1495020 const VVCFrameContext *fc = lc->fc;
231 1495020 const CodingUnit *cu = lc->cu;
232 1495020 const VVCTreeType tree_type = cu->tree_type;
233 int x0, y0, w, h;
234
2/2
✓ Branch 0 taken 452978 times.
✓ Branch 1 taken 1042042 times.
1495020 if (cu->pred_mode != MODE_INTRA) {
235 452978 add_reconstructed_area(lc, target_ch_type, tu->x0, tu->y0, tu->width, tu->height);
236 452978 return;
237 }
238
3/4
✓ Branch 0 taken 773131 times.
✓ Branch 1 taken 268911 times.
✓ Branch 2 taken 773131 times.
✗ Branch 3 not taken.
1042042 if (!target_ch_type && tree_type != DUAL_TREE_CHROMA) {
239
2/2
✓ Branch 1 taken 758294 times.
✓ Branch 2 taken 14837 times.
773131 if (get_luma_predict_unit(cu, tu, idx, &x0, &y0, &w, &h)) {
240 758294 ff_vvc_set_neighbour_available(lc, x0, y0, w, h);
241 758294 fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 0);
242 758294 add_reconstructed_area(lc, 0, x0, y0, w, h);
243 }
244 }
245
3/4
✓ Branch 0 taken 268911 times.
✓ Branch 1 taken 773131 times.
✓ Branch 2 taken 268911 times.
✗ Branch 3 not taken.
1042042 if (target_ch_type && tree_type != DUAL_TREE_LUMA) {
246
2/2
✓ Branch 1 taken 252232 times.
✓ Branch 2 taken 16679 times.
268911 if (get_chroma_predict_unit(cu, tu, idx, &x0, &y0, &w, &h)){
247 252232 ff_vvc_set_neighbour_available(lc, x0, y0, w, h);
248
2/2
✓ Branch 1 taken 97637 times.
✓ Branch 2 taken 154595 times.
252232 if (is_cclm(cu->intra_pred_mode_c)) {
249 97637 fc->vvcdsp.intra.intra_cclm_pred(lc, x0, y0, w, h);
250 } else {
251 154595 fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 1);
252 154595 fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 2);
253 }
254 252232 add_reconstructed_area(lc, 1, x0, y0, w, h);
255 }
256 }
257 }
258
259 893992 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 893992 const int add = 1 << (shift - 1);
263
2/2
✓ Branch 0 taken 9214778 times.
✓ Branch 1 taken 893992 times.
10108770 for (int y = 0; y < h; y++) {
264 9214778 int *p = coeff + y * w;
265
2/2
✓ Branch 0 taken 49466978 times.
✓ Branch 1 taken 9214778 times.
58681756 for (int x = 0; x < nzw; x++) {
266 49466978 *p = av_clip_intp2((*p + add) >> shift, log2_transform_range);
267 49466978 p++;
268 }
269 9214778 memset(p, 0, sizeof(*p) * (w - nzw));
270 }
271 893992 }
272
273 907365 static void scale(int *out, const int *in, const int w, const int h, const int shift)
274 {
275 907365 const int add = 1 << (shift - 1);
276
2/2
✓ Branch 0 taken 9271228 times.
✓ Branch 1 taken 907365 times.
10178593 for (int y = 0; y < h; y++) {
277
2/2
✓ Branch 0 taken 153993124 times.
✓ Branch 1 taken 9271228 times.
163264352 for (int x = 0; x < w; x++) {
278 153993124 int *o = out + y * w + x;
279 153993124 const int *i = in + y * w + x;
280 153993124 *o = (*i + add) >> shift;
281 }
282 }
283 907365 }
284
285 // part of 8.7.3 Scaling process for transform coefficients
286 1182283 static void derive_qp(const VVCLocalContext *lc, const TransformUnit *tu, TransformBlock *tb)
287 {
288 1182283 const VVCSPS *sps = lc->fc->ps.sps;
289 1182283 const H266RawSliceHeader *rsh = lc->sc->sh.r;
290 1182283 const CodingUnit *cu = lc->cu;
291
8/8
✓ Branch 0 taken 386772 times.
✓ Branch 1 taken 795511 times.
✓ Branch 2 taken 54225 times.
✓ Branch 3 taken 332547 times.
✓ Branch 4 taken 46099 times.
✓ Branch 5 taken 8126 times.
✓ Branch 6 taken 31034 times.
✓ Branch 7 taken 15065 times.
1182283 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 1151249 times.
1182283 const int idx = is_jcbcr ? JCBCR : tb->c_idx;
293
2/2
✓ Branch 0 taken 795511 times.
✓ Branch 1 taken 386772 times.
1182283 const int qp = cu->qp[idx] + (idx ? 0 : sps->qp_bd_offset);
294 1182283 const int act_offset[] = { -5, 1, 3, 1 };
295
2/2
✓ Branch 0 taken 21078 times.
✓ Branch 1 taken 1161205 times.
1182283 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 1134762 times.
1182283 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 1134762 const int log_sum = tb->log2_tb_width + tb->log2_tb_height;
305 1134762 const int rect_non_ts_flag = log_sum & 1;
306
307 1134762 tb->qp = av_clip(qp + qp_act_offset, 0, 63 + sps->qp_bd_offset);
308 1134762 tb->rect_non_ts_flag = rect_non_ts_flag;
309 1134762 tb->bd_shift = sps->bit_depth + rect_non_ts_flag + (log_sum / 2)
310 1134762 + 10 - sps->log2_transform_range + rsh->sh_dep_quant_used_flag;
311 }
312 1182283 tb->bd_offset = (1 << tb->bd_shift) >> 1;
313 1182283 }
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 1004927 static av_always_inline int derive_scale(const TransformBlock *tb, const int sh_dep_quant_used_flag)
338 {
339
4/4
✓ Branch 0 taken 937613 times.
✓ Branch 1 taken 67314 times.
✓ Branch 2 taken 890092 times.
✓ Branch 3 taken 47521 times.
1004927 const int addin = sh_dep_quant_used_flag && !tb->ts;
340 1004927 const int qp = tb->qp + addin;
341
342 1004927 return level_scale[tb->rect_non_ts_flag][rem6[qp]] << div6[qp];
343 }
344
345 //8.7.3 Scaling process for transform coefficients
346 1004927 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 1004927 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 1004927 const VVCFrameParamSets *ps = &lc->fc->ps;
362 1004927 const VVCSPS *sps = ps->sps;
363 1004927 const H266RawSliceHeader *rsh = lc->sc->sh.r;
364 1004927 const CodingUnit *cu = lc->cu;
365 1004927 const VVCScalingList *sl = ps->sl;
366 1004927 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 1002076 times.
✓ Branch 1 taken 2851 times.
✓ Branch 2 taken 176144 times.
✓ Branch 3 taken 825932 times.
1004927 const int log2_matrix_size = (id < 2) ? 1 : (id < 8) ? 2 : 3;
368 1004927 uint8_t *p = scale_m;
369
370
4/4
✓ Branch 0 taken 99612 times.
✓ Branch 1 taken 905315 times.
✓ Branch 2 taken 97122 times.
✓ Branch 3 taken 2490 times.
1004927 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 939201 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 11761651 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 11761651 coeff = ((int64_t) coeff * scale * scale_m + tb->bd_offset) >> tb->bd_shift;
399 11761651 coeff = av_clip_intp2(coeff, log2_transform_range);
400 11761651 return coeff;
401 }
402
403 1004927 static void dequant(const VVCLocalContext *lc, const TransformUnit *tu, TransformBlock *tb)
404 {
405 uint8_t tmp[MAX_TB_SIZE * MAX_TB_SIZE];
406 1004927 const H266RawSliceHeader *rsh = lc->sc->sh.r;
407 1004927 const VVCSPS *sps = lc->fc->ps.sps;
408 1004927 const uint8_t *scale_m = derive_scale_m(lc, tb, tmp);
409 int scale;
410
411 1004927 derive_qp(lc, tu, tb);
412 1004927 scale = derive_scale(tb, rsh->sh_dep_quant_used_flag);
413
414
2/2
✓ Branch 0 taken 3881176 times.
✓ Branch 1 taken 1004927 times.
4886103 for (int y = tb->min_scan_y; y <= tb->max_scan_y; y++) {
415
2/2
✓ Branch 0 taken 23205235 times.
✓ Branch 1 taken 3881176 times.
27086411 for (int x = tb->min_scan_x; x <= tb->max_scan_x; x++) {
416 23205235 int *coeff = tb->coeffs + y * tb->tb_width + x;
417
418
2/2
✓ Branch 0 taken 11761651 times.
✓ Branch 1 taken 11443584 times.
23205235 if (*coeff)
419 11761651 *coeff = scale_coeff(tb, *coeff, scale, *scale_m, sps->log2_transform_range);
420 23205235 scale_m++;
421 }
422 }
423 1004927 }
424
425 //transmatrix[0][0]
426 #define DCT_A 64
427 940932 static void itx_2d(const VVCFrameContext *fc, TransformBlock *tb, const enum VVCTxType trh, const enum VVCTxType trv)
428 {
429 940932 const VVCSPS *sps = fc->ps.sps;
430 940932 const int w = tb->tb_width;
431 940932 const int h = tb->tb_height;
432 940932 const size_t nzw = tb->max_scan_x + 1;
433 940932 const size_t nzh = tb->max_scan_y + 1;
434 940932 const int shift[] = { 7, 5 + sps->log2_transform_range - sps->bit_depth };
435
436
9/10
✓ Branch 0 taken 349457 times.
✓ Branch 1 taken 591475 times.
✓ Branch 2 taken 77118 times.
✓ Branch 3 taken 272339 times.
✓ Branch 4 taken 53543 times.
✓ Branch 5 taken 23575 times.
✓ Branch 6 taken 46940 times.
✓ Branch 7 taken 6603 times.
✓ Branch 8 taken 46940 times.
✗ Branch 9 not taken.
940932 if (w == h && nzw == 1 && nzh == 1 && trh == VVC_DCT2 && trv == VVC_DCT2) {
437 46940 const int add[] = { 1 << (shift[0] - 1), 1 << (shift[1] - 1) };
438 46940 const int t = (tb->coeffs[0] * DCT_A + add[0]) >> shift[0];
439 46940 const int dc = (t * DCT_A + add[1]) >> shift[1];
440
441
2/2
✓ Branch 0 taken 17194880 times.
✓ Branch 1 taken 46940 times.
17241820 for (int i = 0; i < w * h; i++)
442 17194880 tb->coeffs[i] = dc;
443
444 46940 return;
445 }
446
447
2/2
✓ Branch 0 taken 4241488 times.
✓ Branch 1 taken 893992 times.
5135480 for (int x = 0; x < nzw; x++)
448 4241488 fc->vvcdsp.itx.itx[trv][tb->log2_tb_height - 1](tb->coeffs + x, w, nzh);
449 893992 scale_clip(tb->coeffs, nzw, w, h, shift[0], sps->log2_transform_range);
450
451
2/2
✓ Branch 0 taken 9214778 times.
✓ Branch 1 taken 893992 times.
10108770 for (int y = 0; y < h; y++)
452 9214778 fc->vvcdsp.itx.itx[trh][tb->log2_tb_width - 1](tb->coeffs + y * w, 1, nzw);
453 893992 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 1004927 static void lmcs_scale_chroma(VVCLocalContext *lc, TransformUnit *tu, TransformBlock *tb, const int target_ch_type)
496 {
497 1004927 const VVCFrameContext *fc = lc->fc;
498 1004927 const VVCSH *sh = &lc->sc->sh;
499 1004927 const CodingUnit *cu = lc->cu;
500 1004927 const int c_idx = tb->c_idx;
501 1004927 const int ch_type = c_idx > 0;
502 1004927 const int w = tb->tb_width;
503 1004927 const int h = tb->tb_height;
504
7/8
✓ Branch 0 taken 269652 times.
✓ Branch 1 taken 735275 times.
✓ Branch 2 taken 126830 times.
✓ Branch 3 taken 142822 times.
✓ Branch 4 taken 126830 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 124757 times.
✓ Branch 7 taken 2073 times.
1004927 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 937147 times.
✓ Branch 2 taken 54225 times.
✓ Branch 3 taken 13555 times.
1004927 const int has_jcbcr = tu->joint_cbcr_residual_flag && c_idx;
506
507
2/2
✓ Branch 0 taken 1059152 times.
✓ Branch 1 taken 1004927 times.
2064079 for (int j = 0; j < 1 + has_jcbcr; j++) {
508 1059152 const bool is_jcbcr = j > 0;
509 1059152 const int jcbcr_idx = CB + tu->coded_flag[CB];
510 1059152 TransformBlock *jcbcr = &tu->tbs[jcbcr_idx - tu->tbs[0].c_idx];
511
2/2
✓ Branch 0 taken 54225 times.
✓ Branch 1 taken 1004927 times.
1059152 int *coeffs = is_jcbcr ? jcbcr->coeffs : tb->coeffs;
512
513
4/4
✓ Branch 0 taken 1004927 times.
✓ Branch 1 taken 54225 times.
✓ Branch 2 taken 54225 times.
✓ Branch 3 taken 950702 times.
1059152 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 151210 times.
✓ Branch 1 taken 907942 times.
1059152 if (chroma_scale)
519 151210 fc->vvcdsp.intra.lmcs_scale_chroma(lc, coeffs, w, h, cu->x0, cu->y0);
520 }
521 1004927 }
522
523 1495020 static void add_residual(const VVCLocalContext *lc, TransformUnit *tu, const int target_ch_type)
524 {
525 1495020 const VVCFrameContext *fc = lc->fc;
526 1495020 const CodingUnit *cu = lc->cu;
527
528
2/2
✓ Branch 0 taken 2817484 times.
✓ Branch 1 taken 1495020 times.
4312504 for (int i = 0; i < tu->nb_tbs; i++) {
529 2817484 TransformBlock *tb = tu->tbs + i;
530 2817484 const int c_idx = tb->c_idx;
531 2817484 const int ch_type = c_idx > 0;
532 2817484 const ptrdiff_t stride = fc->frame->linesize[c_idx];
533
6/6
✓ Branch 0 taken 1522885 times.
✓ Branch 1 taken 1294599 times.
✓ Branch 2 taken 1474117 times.
✓ Branch 3 taken 48768 times.
✓ Branch 4 taken 1099568 times.
✓ Branch 5 taken 374549 times.
3917052 const bool has_residual = tb->has_coeffs || cu->act_enabled_flag ||
534
2/2
✓ Branch 0 taken 76187 times.
✓ Branch 1 taken 1023381 times.
1099568 (c_idx && tu->joint_cbcr_residual_flag);
535 2817484 uint8_t *dst = POS(c_idx, tb->x0, tb->y0);
536
537
4/4
✓ Branch 0 taken 1950080 times.
✓ Branch 1 taken 867404 times.
✓ Branch 2 taken 1083079 times.
✓ Branch 3 taken 867001 times.
2817484 if (ch_type == target_ch_type && has_residual)
538 1083079 fc->vvcdsp.itx.add_residual(dst, tb->coeffs, tb->tb_width, tb->tb_height, stride);
539 }
540 1495020 }
541
542 1495020 static void itransform(VVCLocalContext *lc, TransformUnit *tu, const int target_ch_type)
543 {
544 1495020 const VVCFrameContext *fc = lc->fc;
545 1495020 const CodingUnit *cu = lc->cu;
546 1495020 TransformBlock *tbs = tu->tbs;
547
4/4
✓ Branch 0 taken 30308 times.
✓ Branch 1 taken 1464712 times.
✓ Branch 2 taken 15154 times.
✓ Branch 3 taken 15154 times.
1495020 const bool is_act_luma = cu->act_enabled_flag && target_ch_type == LUMA;
548
549
2/2
✓ Branch 0 taken 2817484 times.
✓ Branch 1 taken 1495020 times.
4312504 for (int i = 0; i < tu->nb_tbs; i++) {
550 2817484 TransformBlock *tb = tbs + i;
551 2817484 const int c_idx = tb->c_idx;
552 2817484 const int ch_type = c_idx > 0;
553
6/6
✓ Branch 0 taken 2772022 times.
✓ Branch 1 taken 45462 times.
✓ Branch 2 taken 2726560 times.
✓ Branch 3 taken 45462 times.
✓ Branch 4 taken 1904618 times.
✓ Branch 5 taken 821942 times.
2817484 const bool do_itx = is_act_luma || !cu->act_enabled_flag && ch_type == target_ch_type;
554
555
4/4
✓ Branch 0 taken 1294599 times.
✓ Branch 1 taken 1522885 times.
✓ Branch 2 taken 1004927 times.
✓ Branch 3 taken 289672 times.
2817484 if (tb->has_coeffs && do_itx) {
556
2/2
✓ Branch 0 taken 2205 times.
✓ Branch 1 taken 1002722 times.
1004927 if (cu->bdpcm_flag[tb->c_idx])
557 2205 transform_bdpcm(tb, lc, cu);
558 1004927 dequant(lc, tu, tb);
559
2/2
✓ Branch 0 taken 957406 times.
✓ Branch 1 taken 47521 times.
1004927 if (!tb->ts) {
560 enum VVCTxType trh, trv;
561
562
2/2
✓ Branch 0 taken 174836 times.
✓ Branch 1 taken 782570 times.
957406 if (cu->apply_lfnst_flag[c_idx])
563 174836 ilfnst_transform(lc, tb);
564 957406 derive_transform_type(fc, lc, tb, &trh, &trv);
565
4/4
✓ Branch 0 taken 954542 times.
✓ Branch 1 taken 2864 times.
✓ Branch 2 taken 940932 times.
✓ Branch 3 taken 13610 times.
957406 if (tb->tb_width > 1 && tb->tb_height > 1)
566 940932 itx_2d(fc, tb, trh, trv);
567 else
568 16474 itx_1d(fc, tb, trh, trv);
569 }
570 1004927 lmcs_scale_chroma(lc, tu, tb, target_ch_type);
571 }
572 }
573
574
2/2
✓ Branch 0 taken 15154 times.
✓ Branch 1 taken 1479866 times.
1495020 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 1495020 add_residual(lc, tu, target_ch_type);
581 1495020 }
582
583 990262 static int reconstruct(VVCLocalContext *lc)
584 {
585 990262 VVCFrameContext *fc = lc->fc;
586 990262 CodingUnit *cu = lc->cu;
587 990262 const int start = cu->tree_type == DUAL_TREE_CHROMA;
588
4/4
✓ Branch 0 taken 971134 times.
✓ Branch 1 taken 19128 times.
✓ Branch 2 taken 415352 times.
✓ Branch 3 taken 555782 times.
990262 const int end = fc->ps.sps->r->sps_chroma_format_idc && (cu->tree_type != DUAL_TREE_LUMA);
589
590
2/2
✓ Branch 0 taken 1218306 times.
✓ Branch 1 taken 990262 times.
2208568 for (int ch_type = start; ch_type <= end; ch_type++) {
591 1218306 TransformUnit *tu = cu->tus.head;
592
2/2
✓ Branch 0 taken 1495020 times.
✓ Branch 1 taken 1218306 times.
2713326 for (int i = 0; tu; i++) {
593 1495020 predict_intra(lc, tu, i, ch_type);
594 1495020 itransform(lc, tu, ch_type);
595 1495020 tu = tu->next;
596 }
597 }
598 990262 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 53475 int ff_vvc_reconstruct(VVCLocalContext *lc, const int rs, const int rx, const int ry)
705 {
706 53475 const VVCFrameContext *fc = lc->fc;
707 53475 const VVCSPS *sps = fc->ps.sps;
708 53475 const int x_ctb = rx << sps->ctb_log2_size_y;
709 53475 const int y_ctb = ry << sps->ctb_log2_size_y;
710 53475 CodingUnit *cu = fc->tab.cus[rs];
711 53475 int ret = 0;
712
713 53475 lc->num_ras[0] = lc->num_ras[1] = 0;
714 53475 lc->lmcs.x_vpdu = -1;
715 53475 lc->lmcs.y_vpdu = -1;
716 53475 ff_vvc_decode_neighbour(lc, x_ctb, y_ctb, rx, ry, rs);
717
2/2
✓ Branch 0 taken 1344609 times.
✓ Branch 1 taken 53475 times.
1398084 while (cu) {
718 1344609 lc->cu = cu;
719
720
2/2
✓ Branch 0 taken 16327 times.
✓ Branch 1 taken 1328282 times.
1344609 if (cu->ciip_flag)
721 16327 ff_vvc_predict_ciip(lc);
722
2/2
✓ Branch 0 taken 67240 times.
✓ Branch 1 taken 1261042 times.
1328282 else if (cu->pred_mode == MODE_IBC)
723 67240 vvc_predict_ibc(lc);
724
2/2
✓ Branch 0 taken 4497 times.
✓ Branch 1 taken 1256545 times.
1261042 else if (cu->pred_mode == MODE_PLT)
725 4497 vvc_predict_palette(lc);
726
2/2
✓ Branch 0 taken 990262 times.
✓ Branch 1 taken 354347 times.
1344609 if (cu->coded_flag) {
727 990262 ret = reconstruct(lc);
728 } else {
729
1/2
✓ Branch 0 taken 354347 times.
✗ Branch 1 not taken.
354347 if (cu->tree_type != DUAL_TREE_CHROMA)
730 354347 add_reconstructed_area(lc, LUMA, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
731
4/4
✓ Branch 0 taken 337836 times.
✓ Branch 1 taken 16511 times.
✓ Branch 2 taken 306843 times.
✓ Branch 3 taken 30993 times.
354347 if (sps->r->sps_chroma_format_idc && cu->tree_type != DUAL_TREE_LUMA)
732 306843 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 1124319 times.
1344609 if (sps->r->sps_ibc_enabled_flag)
735 220290 ibc_fill_vir_buf(lc, cu);
736 1344609 cu = cu->next;
737 }
738 53475 ff_vvc_ctu_free_cus(fc->tab.cus + rs);
739 53475 return ret;
740 }
741