FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/vvc/intra.c
Date: 2025-06-01 09:29:47
Exec Total Coverage
Lines: 435 462 94.2%
Functions: 27 29 93.1%
Branches: 292 316 92.4%

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 395164 static int is_cclm(enum IntraPredMode mode)
35 {
36
6/6
✓ Branch 0 taken 334981 times.
✓ Branch 1 taken 60183 times.
✓ Branch 2 taken 312026 times.
✓ Branch 3 taken 22955 times.
✓ Branch 4 taken 25032 times.
✓ Branch 5 taken 286994 times.
395164 return mode == INTRA_LT_CCLM || mode == INTRA_L_CCLM || mode == INTRA_T_CCLM;
37 }
38
39 171081 static int derive_ilfnst_pred_mode_intra(const VVCLocalContext *lc, const TransformBlock *tb)
40 {
41 171081 const VVCFrameContext *fc = lc->fc;
42 171081 const VVCSPS *sps = fc->ps.sps;
43 171081 const CodingUnit *cu = lc->cu;
44 171081 const int x_tb = tb->x0 >> fc->ps.sps->min_cb_log2_size_y;
45 171081 const int y_tb = tb->y0 >> fc->ps.sps->min_cb_log2_size_y;
46 171081 const int x_c = (tb->x0 + (tb->tb_width << sps->hshift[1] >> 1) ) >> fc->ps.sps->min_cb_log2_size_y;
47 171081 const int y_c = (tb->y0 + (tb->tb_height << sps->vshift[1] >> 1)) >> fc->ps.sps->min_cb_log2_size_y;
48 171081 const int min_cb_width = fc->ps.pps->min_cb_width;
49 171081 const int intra_mip_flag = SAMPLE_CTB(fc->tab.imf, x_tb, y_tb);
50
2/2
✓ Branch 0 taken 120399 times.
✓ Branch 1 taken 50682 times.
171081 int pred_mode_intra = tb->c_idx == 0 ? cu->intra_pred_mode_y : cu->intra_pred_mode_c;
51
4/4
✓ Branch 0 taken 19883 times.
✓ Branch 1 taken 151198 times.
✓ Branch 2 taken 5088 times.
✓ Branch 3 taken 14795 times.
171081 if (intra_mip_flag && !tb->c_idx) {
52 5088 pred_mode_intra = INTRA_PLANAR;
53
2/2
✓ Branch 1 taken 15840 times.
✓ Branch 2 taken 150153 times.
165993 } else if (is_cclm(pred_mode_intra)) {
54 15840 int intra_mip_flag_c = SAMPLE_CTB(fc->tab.imf, x_c, y_c);
55 15840 int cu_pred_mode = SAMPLE_CTB(fc->tab.cpm[0], x_c, y_c);
56
2/2
✓ Branch 0 taken 4442 times.
✓ Branch 1 taken 11398 times.
15840 if (intra_mip_flag_c) {
57 4442 pred_mode_intra = INTRA_PLANAR;
58
3/4
✓ Branch 0 taken 10426 times.
✓ Branch 1 taken 972 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10426 times.
11398 } else if (cu_pred_mode == MODE_IBC || cu_pred_mode == MODE_PLT) {
59 972 pred_mode_intra = INTRA_DC;
60 } else {
61 10426 pred_mode_intra = SAMPLE_CTB(fc->tab.ipm, x_c, y_c);
62 }
63 }
64 171081 pred_mode_intra = ff_vvc_wide_angle_mode_mapping(cu, tb->tb_width, tb->tb_height, tb->c_idx, pred_mode_intra);
65
66 171081 return pred_mode_intra;
67 }
68
69 //8.7.4 Transformation process for scaled transform coefficients
70 171081 static void ilfnst_transform(const VVCLocalContext *lc, TransformBlock *tb)
71 {
72 171081 const VVCSPS *sps = lc->fc->ps.sps;
73 171081 const CodingUnit *cu = lc->cu;
74 171081 const int w = tb->tb_width;
75 171081 const int h = tb->tb_height;
76
4/4
✓ Branch 0 taken 99497 times.
✓ Branch 1 taken 71584 times.
✓ Branch 2 taken 68322 times.
✓ Branch 3 taken 31175 times.
171081 const int n_lfnst_out_size = (w >= 8 && h >= 8) ? 48 : 16; ///< nLfnstOutSize
77
4/4
✓ Branch 0 taken 99497 times.
✓ Branch 1 taken 71584 times.
✓ Branch 2 taken 68322 times.
✓ Branch 3 taken 31175 times.
171081 const int log2_lfnst_size = (w >= 8 && h >= 8) ? 3 : 2; ///< log2LfnstSize
78 171081 const int n_lfnst_size = 1 << log2_lfnst_size; ///< nLfnstSize
79
8/8
✓ Branch 0 taken 39632 times.
✓ Branch 1 taken 131449 times.
✓ Branch 2 taken 27202 times.
✓ Branch 3 taken 12430 times.
✓ Branch 4 taken 71584 times.
✓ Branch 5 taken 87067 times.
✓ Branch 6 taken 49283 times.
✓ Branch 7 taken 22301 times.
171081 const int non_zero_size = ((w == 8 && h == 8) || (w == 4 && h == 4)) ? 8 : 16; ///< nonZeroSize
80 171081 const int pred_mode_intra = derive_ilfnst_pred_mode_intra(lc, tb);
81 171081 const int transpose = pred_mode_intra > 34;
82 int u[16], v[48];
83
84
2/2
✓ Branch 0 taken 2243592 times.
✓ Branch 1 taken 171081 times.
2414673 for (int x = 0; x < non_zero_size; x++) {
85 2243592 int xc = ff_vvc_diag_scan_x[2][2][x];
86 2243592 int yc = ff_vvc_diag_scan_y[2][2][x];
87 2243592 u[x] = tb->coeffs[w * yc + xc];
88 }
89 171081 ff_vvc_inv_lfnst_1d(v, u, non_zero_size, n_lfnst_out_size, pred_mode_intra,
90 171081 cu->lfnst_idx, sps->log2_transform_range);
91
2/2
✓ Branch 0 taken 49682 times.
✓ Branch 1 taken 121399 times.
171081 if (transpose) {
92 49682 int *dst = tb->coeffs;
93 49682 const int *src = v;
94
2/2
✓ Branch 0 taken 34560 times.
✓ Branch 1 taken 15122 times.
49682 if (n_lfnst_size == 4) {
95
2/2
✓ Branch 0 taken 138240 times.
✓ Branch 1 taken 34560 times.
172800 for (int y = 0; y < 4; y++) {
96 138240 dst[0] = src[0];
97 138240 dst[1] = src[4];
98 138240 dst[2] = src[8];
99 138240 dst[3] = src[12];
100 138240 src++;
101 138240 dst += w;
102 }
103 } else {
104
2/2
✓ Branch 0 taken 120976 times.
✓ Branch 1 taken 15122 times.
136098 for (int y = 0; y < 8; y++) {
105 120976 dst[0] = src[0];
106 120976 dst[1] = src[8];
107 120976 dst[2] = src[16];
108 120976 dst[3] = src[24];
109
2/2
✓ Branch 0 taken 60488 times.
✓ Branch 1 taken 60488 times.
120976 if (y < 4) {
110 60488 dst[4] = src[32];
111 60488 dst[5] = src[36];
112 60488 dst[6] = src[40];
113 60488 dst[7] = src[44];
114 }
115 120976 src++;
116 120976 dst += w;
117 }
118 }
119
120 } else {
121 121399 int *dst = tb->coeffs;
122 121399 const int *src = v;
123
2/2
✓ Branch 0 taken 698396 times.
✓ Branch 1 taken 121399 times.
819795 for (int y = 0; y < n_lfnst_size; y++) {
124
2/2
✓ Branch 0 taken 485596 times.
✓ Branch 1 taken 212800 times.
698396 int size = (y < 4) ? n_lfnst_size : 4;
125 698396 memcpy(dst, src, size * sizeof(int));
126 698396 src += size;
127 698396 dst += w;
128 }
129 }
130 171081 tb->max_scan_x = n_lfnst_size - 1;
131 171081 tb->max_scan_y = n_lfnst_size - 1;
132 171081 }
133
134 //part of 8.7.4 Transformation process for scaled transform coefficients
135 923289 static void derive_transform_type(const VVCFrameContext *fc, const VVCLocalContext *lc, const TransformBlock *tb, enum VVCTxType *trh, enum VVCTxType *trv)
136 {
137 923289 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 923289 const VVCSPS *sps = fc->ps.sps;
141 923289 int implicit_mts_enabled = 0;
142
6/6
✓ Branch 0 taken 671986 times.
✓ Branch 1 taken 251303 times.
✓ Branch 2 taken 137942 times.
✓ Branch 3 taken 534044 times.
✓ Branch 4 taken 32201 times.
✓ Branch 5 taken 105741 times.
923289 if (tb->c_idx || (cu->isp_split_type != ISP_NO_SPLIT && cu->lfnst_idx)) {
143 283504 *trh = *trv = VVC_DCT2;
144 283504 return;
145 }
146
147
2/2
✓ Branch 0 taken 635891 times.
✓ Branch 1 taken 3894 times.
639785 if (sps->r->sps_mts_enabled_flag) {
148
2/2
✓ Branch 0 taken 530150 times.
✓ Branch 1 taken 105741 times.
635891 if (cu->isp_split_type != ISP_NO_SPLIT ||
149
4/4
✓ Branch 0 taken 34142 times.
✓ Branch 1 taken 496008 times.
✓ Branch 2 taken 465 times.
✓ Branch 3 taken 33677 times.
530150 (cu->sbt_flag && FFMAX(tb->tb_width, tb->tb_height) <= 32) ||
150
4/4
✓ Branch 0 taken 45019 times.
✓ Branch 1 taken 451454 times.
✓ Branch 2 taken 28412 times.
✓ Branch 3 taken 16607 times.
496473 (!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 154010 implicit_mts_enabled = 1;
153 }
154 }
155
2/2
✓ Branch 0 taken 154010 times.
✓ Branch 1 taken 485775 times.
639785 if (implicit_mts_enabled) {
156 154010 const int w = tb->tb_width;
157 154010 const int h = tb->tb_height;
158
2/2
✓ Branch 0 taken 33677 times.
✓ Branch 1 taken 120333 times.
154010 if (cu->sbt_flag) {
159
4/4
✓ Branch 0 taken 17823 times.
✓ Branch 1 taken 15854 times.
✓ Branch 2 taken 8393 times.
✓ Branch 3 taken 9430 times.
33677 *trh = (cu->sbt_horizontal_flag || cu->sbt_pos_flag) ? VVC_DST7 : VVC_DCT8;
160
4/4
✓ Branch 0 taken 15854 times.
✓ Branch 1 taken 17823 times.
✓ Branch 2 taken 7657 times.
✓ Branch 3 taken 8197 times.
33677 *trv = (!cu->sbt_horizontal_flag || cu->sbt_pos_flag) ? VVC_DST7 : VVC_DCT8;
161 } else {
162
4/4
✓ Branch 0 taken 101947 times.
✓ Branch 1 taken 18386 times.
✓ Branch 2 taken 81961 times.
✓ Branch 3 taken 19986 times.
120333 *trh = (w >= 4 && w <= 16) ? VVC_DST7 : VVC_DCT2;
163
4/4
✓ Branch 0 taken 77159 times.
✓ Branch 1 taken 43174 times.
✓ Branch 2 taken 74254 times.
✓ Branch 3 taken 2905 times.
120333 *trv = (h >= 4 && h <= 16) ? VVC_DST7 : VVC_DCT2;
164 }
165 154010 return;
166 }
167 485775 *trh = mts_to_trh[cu->mts_idx];
168 485775 *trv = mts_to_trv[cu->mts_idx];
169 }
170
171 1918572 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 1918572 const VVCSPS *sps = lc->fc->ps.sps;
174 1918572 const int hs = sps->hshift[ch_type];
175 1918572 const int vs = sps->vshift[ch_type];
176 ReconstructedArea *a;
177
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1918572 times.
1918572 if (lc->num_ras[ch_type] >= FF_ARRAY_ELEMS(lc->ras[ch_type]))
179 return AVERROR_INVALIDDATA;
180
181 1918572 a = &lc->ras[ch_type][lc->num_ras[ch_type]];
182 1918572 a->x = x0 >> hs;
183 1918572 a->y = y0 >> vs;
184 1918572 a->w = w >> hs;
185 1918572 a->h = h >> vs;
186 1918572 lc->num_ras[ch_type]++;
187
188 1918572 return 0;
189 }
190
191 963998 static void add_tu_area(const TransformUnit *tu, int *x0, int *y0, int *w, int *h)
192 {
193 963998 *x0 = tu->x0;
194 963998 *y0 = tu->y0;
195 963998 *w = tu->width;
196 963998 *h = tu->height;
197 963998 }
198
199 #define MIN_ISP_PRED_WIDTH 4
200 740018 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 740018 int has_luma = 1;
203 740018 add_tu_area(tu, x0, y0, w, h);
204
4/4
✓ Branch 0 taken 74180 times.
✓ Branch 1 taken 665838 times.
✓ Branch 2 taken 26318 times.
✓ Branch 3 taken 47862 times.
740018 if (cu->isp_split_type == ISP_VER_SPLIT && tu->width < MIN_ISP_PRED_WIDTH) {
205 26318 *w = MIN_ISP_PRED_WIDTH;
206 26318 has_luma = !(idx % (MIN_ISP_PRED_WIDTH / tu->width));
207 }
208 740018 return has_luma;
209 }
210
211 244690 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 223980 times.
✓ Branch 1 taken 20710 times.
244690 if (cu->isp_split_type == ISP_NO_SPLIT) {
214 223980 add_tu_area(tu, x0, y0, w, h);
215 223980 return 1;
216 }
217
2/2
✓ Branch 0 taken 5191 times.
✓ Branch 1 taken 15519 times.
20710 if (idx == cu->num_intra_subpartitions - 1) {
218 5191 *x0 = cu->x0;
219 5191 *y0 = cu->y0;
220 5191 *w = cu->cb_width;
221 5191 *h = cu->cb_height;
222 5191 return 1;
223 }
224 15519 return 0;
225 }
226
227 //8.4.5.1 General decoding process for intra blocks
228 1400823 static void predict_intra(VVCLocalContext *lc, const TransformUnit *tu, const int idx, const int target_ch_type)
229 {
230 1400823 const VVCFrameContext *fc = lc->fc;
231 1400823 const CodingUnit *cu = lc->cu;
232 1400823 const VVCTreeType tree_type = cu->tree_type;
233 int x0, y0, w, h;
234
2/2
✓ Branch 0 taken 416115 times.
✓ Branch 1 taken 984708 times.
1400823 if (cu->pred_mode != MODE_INTRA) {
235 416115 add_reconstructed_area(lc, target_ch_type, tu->x0, tu->y0, tu->width, tu->height);
236 416115 return;
237 }
238
3/4
✓ Branch 0 taken 740018 times.
✓ Branch 1 taken 244690 times.
✓ Branch 2 taken 740018 times.
✗ Branch 3 not taken.
984708 if (!target_ch_type && tree_type != DUAL_TREE_CHROMA) {
239
2/2
✓ Branch 1 taken 725823 times.
✓ Branch 2 taken 14195 times.
740018 if (get_luma_predict_unit(cu, tu, idx, &x0, &y0, &w, &h)) {
240 725823 ff_vvc_set_neighbour_available(lc, x0, y0, w, h);
241 725823 fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 0);
242 725823 add_reconstructed_area(lc, 0, x0, y0, w, h);
243 }
244 }
245
3/4
✓ Branch 0 taken 244690 times.
✓ Branch 1 taken 740018 times.
✓ Branch 2 taken 244690 times.
✗ Branch 3 not taken.
984708 if (target_ch_type && tree_type != DUAL_TREE_LUMA) {
246
2/2
✓ Branch 1 taken 229171 times.
✓ Branch 2 taken 15519 times.
244690 if (get_chroma_predict_unit(cu, tu, idx, &x0, &y0, &w, &h)){
247 229171 ff_vvc_set_neighbour_available(lc, x0, y0, w, h);
248
2/2
✓ Branch 1 taken 92330 times.
✓ Branch 2 taken 136841 times.
229171 if (is_cclm(cu->intra_pred_mode_c)) {
249 92330 fc->vvcdsp.intra.intra_cclm_pred(lc, x0, y0, w, h);
250 } else {
251 136841 fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 1);
252 136841 fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 2);
253 }
254 229171 add_reconstructed_area(lc, 1, x0, y0, w, h);
255 }
256 }
257 }
258
259 863387 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 863387 const int add = 1 << (shift - 1);
263
2/2
✓ Branch 0 taken 8934880 times.
✓ Branch 1 taken 863387 times.
9798267 for (int y = 0; y < h; y++) {
264 8934880 int *p = coeff + y * w;
265
2/2
✓ Branch 0 taken 48301112 times.
✓ Branch 1 taken 8934880 times.
57235992 for (int x = 0; x < nzw; x++) {
266 48301112 *p = av_clip_intp2((*p + add) >> shift, log2_transform_range);
267 48301112 p++;
268 }
269 8934880 memset(p, 0, sizeof(*p) * (w - nzw));
270 }
271 863387 }
272
273 876208 static void scale(int *out, const int *in, const int w, const int h, const int shift)
274 {
275 876208 const int add = 1 << (shift - 1);
276
2/2
✓ Branch 0 taken 8989514 times.
✓ Branch 1 taken 876208 times.
9865722 for (int y = 0; y < h; y++) {
277
2/2
✓ Branch 0 taken 150691500 times.
✓ Branch 1 taken 8989514 times.
159681014 for (int x = 0; x < w; x++) {
278 150691500 int *o = out + y * w + x;
279 150691500 const int *i = in + y * w + x;
280 150691500 *o = (*i + add) >> shift;
281 }
282 }
283 876208 }
284
285 // part of 8.7.3 Scaling process for transform coefficients
286 952114 static void derive_qp(const VVCLocalContext *lc, const TransformUnit *tu, TransformBlock *tb)
287 {
288 952114 const VVCSPS *sps = lc->fc->ps.sps;
289 952114 const H266RawSliceHeader *rsh = lc->sc->sh.r;
290 952114 const CodingUnit *cu = lc->cu;
291
8/8
✓ Branch 0 taken 254695 times.
✓ Branch 1 taken 697419 times.
✓ Branch 2 taken 52268 times.
✓ Branch 3 taken 202427 times.
✓ Branch 4 taken 44548 times.
✓ Branch 5 taken 7720 times.
✓ Branch 6 taken 29773 times.
✓ Branch 7 taken 14775 times.
952114 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 29773 times.
✓ Branch 1 taken 922341 times.
952114 const int idx = is_jcbcr ? JCBCR : tb->c_idx;
293
2/2
✓ Branch 0 taken 697419 times.
✓ Branch 1 taken 254695 times.
952114 const int qp = cu->qp[idx] + (idx ? 0 : sps->qp_bd_offset);
294 952114 const int act_offset[] = { -5, 1, 3, 1 };
295
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 952114 times.
952114 const int qp_act_offset = cu->act_enabled_flag ? act_offset[idx] : 0;
296
297
2/2
✓ Branch 0 taken 28825 times.
✓ Branch 1 taken 923289 times.
952114 if (tb->ts) {
298 28825 const int qp_prime_ts_min = 4 + 6 * sps->r->sps_min_qp_prime_ts;
299
300 28825 tb->qp = av_clip(qp + qp_act_offset, qp_prime_ts_min, 63 + sps->qp_bd_offset);
301 28825 tb->rect_non_ts_flag = 0;
302 28825 tb->bd_shift = 10;
303 } else {
304 923289 const int log_sum = tb->log2_tb_width + tb->log2_tb_height;
305 923289 const int rect_non_ts_flag = log_sum & 1;
306
307 923289 tb->qp = av_clip(qp + qp_act_offset, 0, 63 + sps->qp_bd_offset);
308 923289 tb->rect_non_ts_flag = rect_non_ts_flag;
309 923289 tb->bd_shift = sps->bit_depth + rect_non_ts_flag + (log_sum / 2)
310 923289 + 10 - sps->log2_transform_range + rsh->sh_dep_quant_used_flag;
311 }
312 952114 tb->bd_offset = (1 << tb->bd_shift) >> 1;
313 952114 }
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 952114 static av_always_inline int derive_scale(const TransformBlock *tb, const int sh_dep_quant_used_flag)
338 {
339
4/4
✓ Branch 0 taken 884800 times.
✓ Branch 1 taken 67314 times.
✓ Branch 2 taken 855975 times.
✓ Branch 3 taken 28825 times.
952114 const int addin = sh_dep_quant_used_flag && !tb->ts;
340 952114 const int qp = tb->qp + addin;
341
342 952114 return level_scale[tb->rect_non_ts_flag][rem6[qp]] << div6[qp];
343 }
344
345 //8.7.3 Scaling process for transform coefficients
346 952114 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 952114 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 952114 const VVCFrameParamSets *ps = &lc->fc->ps;
362 952114 const VVCSPS *sps = ps->sps;
363 952114 const H266RawSliceHeader *rsh = lc->sc->sh.r;
364 952114 const CodingUnit *cu = lc->cu;
365 952114 const VVCScalingList *sl = ps->sl;
366 952114 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 949263 times.
✓ Branch 1 taken 2851 times.
✓ Branch 2 taken 166682 times.
✓ Branch 3 taken 782581 times.
952114 const int log2_matrix_size = (id < 2) ? 1 : (id < 8) ? 2 : 3;
368 952114 uint8_t *p = scale_m;
369
370
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 952114 times.
952114 av_assert0(!sps->r->sps_scaling_matrix_for_alternative_colour_space_disabled_flag);
371
372
4/4
✓ Branch 0 taken 99612 times.
✓ Branch 1 taken 852502 times.
✓ Branch 2 taken 97122 times.
✓ Branch 3 taken 2490 times.
952114 if (!rsh->sh_explicit_scaling_list_used_flag || tb->ts ||
373
3/4
✓ Branch 0 taken 97122 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 31396 times.
✓ Branch 3 taken 65726 times.
97122 sps->r->sps_scaling_matrix_for_lfnst_disabled_flag && cu->apply_lfnst_flag[tb->c_idx])
374 886388 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 11473467 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 11473467 coeff = ((int64_t) coeff * scale * scale_m + tb->bd_offset) >> tb->bd_shift;
399 11473467 coeff = av_clip_intp2(coeff, log2_transform_range);
400 11473467 return coeff;
401 }
402
403 952114 static void dequant(const VVCLocalContext *lc, const TransformUnit *tu, TransformBlock *tb)
404 {
405 uint8_t tmp[MAX_TB_SIZE * MAX_TB_SIZE];
406 952114 const H266RawSliceHeader *rsh = lc->sc->sh.r;
407 952114 const VVCSPS *sps = lc->fc->ps.sps;
408 952114 const uint8_t *scale_m = derive_scale_m(lc, tb, tmp);
409 int scale;
410
411 952114 derive_qp(lc, tu, tb);
412 952114 scale = derive_scale(tb, rsh->sh_dep_quant_used_flag);
413
414
2/2
✓ Branch 0 taken 3738175 times.
✓ Branch 1 taken 952114 times.
4690289 for (int y = tb->min_scan_y; y <= tb->max_scan_y; y++) {
415
2/2
✓ Branch 0 taken 22650915 times.
✓ Branch 1 taken 3738175 times.
26389090 for (int x = tb->min_scan_x; x <= tb->max_scan_x; x++) {
416 22650915 int *coeff = tb->coeffs + y * tb->tb_width + x;
417
418
2/2
✓ Branch 0 taken 11473467 times.
✓ Branch 1 taken 11177448 times.
22650915 if (*coeff)
419 11473467 *coeff = scale_coeff(tb, *coeff, scale, *scale_m, sps->log2_transform_range);
420 22650915 scale_m++;
421 }
422 }
423 952114 }
424
425 //transmatrix[0][0]
426 #define DCT_A 64
427 907442 static void itx_2d(const VVCFrameContext *fc, TransformBlock *tb, const enum VVCTxType trh, const enum VVCTxType trv)
428 {
429 907442 const VVCSPS *sps = fc->ps.sps;
430 907442 const int w = tb->tb_width;
431 907442 const int h = tb->tb_height;
432 907442 const size_t nzw = tb->max_scan_x + 1;
433 907442 const size_t nzh = tb->max_scan_y + 1;
434 907442 const int shift[] = { 7, 5 + sps->log2_transform_range - sps->bit_depth };
435
436
9/10
✓ Branch 0 taken 338493 times.
✓ Branch 1 taken 568949 times.
✓ Branch 2 taken 73143 times.
✓ Branch 3 taken 265350 times.
✓ Branch 4 taken 50513 times.
✓ Branch 5 taken 22630 times.
✓ Branch 6 taken 44055 times.
✓ Branch 7 taken 6458 times.
✓ Branch 8 taken 44055 times.
✗ Branch 9 not taken.
907442 if (w == h && nzw == 1 && nzh == 1 && trh == VVC_DCT2 && trv == VVC_DCT2) {
437 44055 const int add[] = { 1 << (shift[0] - 1), 1 << (shift[1] - 1) };
438 44055 const int t = (tb->coeffs[0] * DCT_A + add[0]) >> shift[0];
439 44055 const int dc = (t * DCT_A + add[1]) >> shift[1];
440
441
2/2
✓ Branch 0 taken 15444624 times.
✓ Branch 1 taken 44055 times.
15488679 for (int i = 0; i < w * h; i++)
442 15444624 tb->coeffs[i] = dc;
443
444 44055 return;
445 }
446
447
2/2
✓ Branch 0 taken 4133006 times.
✓ Branch 1 taken 863387 times.
4996393 for (int x = 0; x < nzw; x++)
448 4133006 fc->vvcdsp.itx.itx[trv][tb->log2_tb_height - 1](tb->coeffs + x, w, nzh);
449 863387 scale_clip(tb->coeffs, nzw, w, h, shift[0], sps->log2_transform_range);
450
451
2/2
✓ Branch 0 taken 8934880 times.
✓ Branch 1 taken 863387 times.
9798267 for (int y = 0; y < h; y++)
452 8934880 fc->vvcdsp.itx.itx[trh][tb->log2_tb_width - 1](tb->coeffs + y * w, 1, nzw);
453 863387 scale(tb->coeffs, tb->coeffs, w, h, shift[1]);
454 }
455
456 15847 static void itx_1d(const VVCFrameContext *fc, TransformBlock *tb, const enum VVCTxType trh, const enum VVCTxType trv)
457 {
458 15847 const VVCSPS *sps = fc->ps.sps;
459 15847 const int w = tb->tb_width;
460 15847 const int h = tb->tb_height;
461 15847 const size_t nzw = tb->max_scan_x + 1;
462 15847 const size_t nzh = tb->max_scan_y + 1;
463
464
12/12
✓ Branch 0 taken 13087 times.
✓ Branch 1 taken 2760 times.
✓ Branch 2 taken 4804 times.
✓ Branch 3 taken 8283 times.
✓ Branch 4 taken 1935 times.
✓ Branch 5 taken 2869 times.
✓ Branch 6 taken 2760 times.
✓ Branch 7 taken 10218 times.
✓ Branch 8 taken 738 times.
✓ Branch 9 taken 2022 times.
✓ Branch 10 taken 157 times.
✓ Branch 11 taken 581 times.
15847 if ((w > 1 && nzw == 1 && trh == VVC_DCT2) || (h > 1 && nzh == 1 && trv == VVC_DCT2)) {
465 3026 const int shift = 6 + sps->log2_transform_range - sps->bit_depth;
466 3026 const int add = 1 << (shift - 1);
467 3026 const int dc = (tb->coeffs[0] * DCT_A + add) >> shift;
468
469
2/2
✓ Branch 0 taken 97184 times.
✓ Branch 1 taken 3026 times.
100210 for (int i = 0; i < w * h; i++)
470 97184 tb->coeffs[i] = dc;
471
472 3026 return;
473 }
474
475
2/2
✓ Branch 0 taken 10218 times.
✓ Branch 1 taken 2603 times.
12821 if (w > 1)
476 10218 fc->vvcdsp.itx.itx[trh][tb->log2_tb_width - 1](tb->coeffs, 1, nzw);
477 else
478 2603 fc->vvcdsp.itx.itx[trv][tb->log2_tb_height - 1](tb->coeffs, 1, nzh);
479 12821 scale(tb->coeffs, tb->coeffs, w, h, 6 + sps->log2_transform_range - sps->bit_depth);
480 }
481
482 10 static void transform_bdpcm(TransformBlock *tb, const VVCLocalContext *lc, const CodingUnit *cu)
483 {
484 10 const VVCSPS *sps = lc->fc->ps.sps;
485
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6 times.
10 const IntraPredMode mode = tb->c_idx ? cu->intra_pred_mode_c : cu->intra_pred_mode_y;
486 10 const int vertical = mode == INTRA_VERT;
487 10 lc->fc->vvcdsp.itx.transform_bdpcm(tb->coeffs, tb->tb_width, tb->tb_height,
488 10 vertical, sps->log2_transform_range);
489
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6 times.
10 if (vertical)
490 4 tb->max_scan_y = tb->tb_height - 1;
491 else
492 6 tb->max_scan_x = tb->tb_width - 1;
493 10 }
494
495 952114 static void lmcs_scale_chroma(VVCLocalContext *lc, TransformUnit *tu, TransformBlock *tb, const int target_ch_type)
496 {
497 952114 const VVCFrameContext *fc = lc->fc;
498 952114 const VVCSH *sh = &lc->sc->sh;
499 952114 const CodingUnit *cu = lc->cu;
500 952114 const int c_idx = tb->c_idx;
501 952114 const int ch_type = c_idx > 0;
502 952114 const int w = tb->tb_width;
503 952114 const int h = tb->tb_height;
504
7/8
✓ Branch 0 taken 254695 times.
✓ Branch 1 taken 697419 times.
✓ Branch 2 taken 120118 times.
✓ Branch 3 taken 134577 times.
✓ Branch 4 taken 120118 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 118045 times.
✓ Branch 7 taken 2073 times.
952114 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 64933 times.
✓ Branch 1 taken 887181 times.
✓ Branch 2 taken 52268 times.
✓ Branch 3 taken 12665 times.
952114 const int has_jcbcr = tu->joint_cbcr_residual_flag && c_idx;
506
507
2/2
✓ Branch 0 taken 1004382 times.
✓ Branch 1 taken 952114 times.
1956496 for (int j = 0; j < 1 + has_jcbcr; j++) {
508 1004382 const bool is_jcbcr = j > 0;
509 1004382 const int jcbcr_idx = CB + tu->coded_flag[CB];
510 1004382 TransformBlock *jcbcr = &tu->tbs[jcbcr_idx - tu->tbs[0].c_idx];
511
2/2
✓ Branch 0 taken 52268 times.
✓ Branch 1 taken 952114 times.
1004382 int *coeffs = is_jcbcr ? jcbcr->coeffs : tb->coeffs;
512
513
4/4
✓ Branch 0 taken 952114 times.
✓ Branch 1 taken 52268 times.
✓ Branch 2 taken 52268 times.
✓ Branch 3 taken 899846 times.
1004382 if (!j && has_jcbcr) {
514 52268 const int c_sign = 1 - 2 * fc->ps.ph.r->ph_joint_cbcr_sign_flag;
515 52268 const int shift = tu->coded_flag[CB] ^ tu->coded_flag[CR];
516 52268 fc->vvcdsp.itx.pred_residual_joint(jcbcr->coeffs, tb->coeffs, w, h, c_sign, shift);
517 }
518
2/2
✓ Branch 0 taken 143362 times.
✓ Branch 1 taken 861020 times.
1004382 if (chroma_scale)
519 143362 fc->vvcdsp.intra.lmcs_scale_chroma(lc, coeffs, w, h, cu->x0, cu->y0);
520 }
521 952114 }
522
523 1400823 static void add_residual(const VVCLocalContext *lc, TransformUnit *tu, const int target_ch_type)
524 {
525 1400823 const VVCFrameContext *fc = lc->fc;
526 1400823 const CodingUnit *cu = lc->cu;
527
528
2/2
✓ Branch 0 taken 2582084 times.
✓ Branch 1 taken 1400823 times.
3982907 for (int i = 0; i < tu->nb_tbs; i++) {
529 2582084 TransformBlock *tb = tu->tbs + i;
530 2582084 const int c_idx = tb->c_idx;
531 2582084 const int ch_type = c_idx > 0;
532 2582084 const ptrdiff_t stride = fc->frame->linesize[c_idx];
533
5/6
✓ Branch 0 taken 1374946 times.
✓ Branch 1 taken 1207138 times.
✓ Branch 2 taken 1374946 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1023858 times.
✓ Branch 5 taken 351088 times.
3605942 const bool has_residual = tb->has_coeffs || cu->act_enabled_flag ||
534
2/2
✓ Branch 0 taken 73689 times.
✓ Branch 1 taken 950169 times.
1023858 (c_idx && tu->joint_cbcr_residual_flag);
535 2582084 uint8_t *dst = POS(c_idx, tb->x0, tb->y0);
536
537
4/4
✓ Branch 0 taken 1817129 times.
✓ Branch 1 taken 764955 times.
✓ Branch 2 taken 1004382 times.
✓ Branch 3 taken 812747 times.
2582084 if (ch_type == target_ch_type && has_residual)
538 1004382 fc->vvcdsp.itx.add_residual(dst, tb->coeffs, tb->tb_width, tb->tb_height, stride);
539 }
540 1400823 }
541
542 1400823 static void itransform(VVCLocalContext *lc, TransformUnit *tu, const int target_ch_type)
543 {
544 1400823 const VVCFrameContext *fc = lc->fc;
545 1400823 const CodingUnit *cu = lc->cu;
546 1400823 TransformBlock *tbs = tu->tbs;
547
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1400823 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1400823 const bool is_act_luma = cu->act_enabled_flag && target_ch_type == LUMA;
548
549
2/2
✓ Branch 0 taken 2582084 times.
✓ Branch 1 taken 1400823 times.
3982907 for (int i = 0; i < tu->nb_tbs; i++) {
550 2582084 TransformBlock *tb = tbs + i;
551 2582084 const int c_idx = tb->c_idx;
552 2582084 const int ch_type = c_idx > 0;
553
4/6
✓ Branch 0 taken 2582084 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2582084 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1817129 times.
✓ Branch 5 taken 764955 times.
2582084 const bool do_itx = is_act_luma || !cu->act_enabled_flag && ch_type == target_ch_type;
554
555
4/4
✓ Branch 0 taken 1207138 times.
✓ Branch 1 taken 1374946 times.
✓ Branch 2 taken 952114 times.
✓ Branch 3 taken 255024 times.
2582084 if (tb->has_coeffs && do_itx) {
556
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 952104 times.
952114 if (cu->bdpcm_flag[tb->c_idx])
557 10 transform_bdpcm(tb, lc, cu);
558 952114 dequant(lc, tu, tb);
559
2/2
✓ Branch 0 taken 923289 times.
✓ Branch 1 taken 28825 times.
952114 if (!tb->ts) {
560 enum VVCTxType trh, trv;
561
562
2/2
✓ Branch 0 taken 171081 times.
✓ Branch 1 taken 752208 times.
923289 if (cu->apply_lfnst_flag[c_idx])
563 171081 ilfnst_transform(lc, tb);
564 923289 derive_transform_type(fc, lc, tb, &trh, &trv);
565
4/4
✓ Branch 0 taken 920529 times.
✓ Branch 1 taken 2760 times.
✓ Branch 2 taken 907442 times.
✓ Branch 3 taken 13087 times.
923289 if (tb->tb_width > 1 && tb->tb_height > 1)
566 907442 itx_2d(fc, tb, trh, trv);
567 else
568 15847 itx_1d(fc, tb, trh, trv);
569 }
570 952114 lmcs_scale_chroma(lc, tu, tb, target_ch_type);
571 }
572 }
573
574
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1400823 times.
1400823 if (is_act_luma) {
575 fc->vvcdsp.itx.adaptive_color_transform(
576 tbs[LUMA].coeffs, tbs[CB].coeffs, tbs[CR].coeffs,
577 tbs[LUMA].tb_width, tbs[LUMA].tb_height);
578 }
579
580 1400823 add_residual(lc, tu, target_ch_type);
581 1400823 }
582
583 938287 static int reconstruct(VVCLocalContext *lc)
584 {
585 938287 VVCFrameContext *fc = lc->fc;
586 938287 CodingUnit *cu = lc->cu;
587 938287 const int start = cu->tree_type == DUAL_TREE_CHROMA;
588
4/4
✓ Branch 0 taken 919159 times.
✓ Branch 1 taken 19128 times.
✓ Branch 2 taken 378348 times.
✓ Branch 3 taken 540811 times.
938287 const int end = fc->ps.sps->r->sps_chroma_format_idc && (cu->tree_type != DUAL_TREE_LUMA);
589
590
2/2
✓ Branch 0 taken 1135478 times.
✓ Branch 1 taken 938287 times.
2073765 for (int ch_type = start; ch_type <= end; ch_type++) {
591 1135478 TransformUnit *tu = cu->tus.head;
592
2/2
✓ Branch 0 taken 1400823 times.
✓ Branch 1 taken 1135478 times.
2536301 for (int i = 0; tu; i++) {
593 1400823 predict_intra(lc, tu, i, ch_type);
594 1400823 itransform(lc, tu, ch_type);
595 1400823 tu = tu->next;
596 }
597 }
598 938287 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 31272 static void intra_block_copy(const VVCLocalContext *lc, const int c_idx)
608 {
609 31272 const CodingUnit *cu = lc->cu;
610 31272 const PredictionUnit *pu = &cu->pu;
611 31272 const VVCFrameContext *fc = lc->fc;
612 31272 const VVCSPS *sps = fc->ps.sps;
613 31272 const Mv *bv = &pu->mi.mv[L0][0];
614 31272 const int hs = sps->hshift[c_idx];
615 31272 const int vs = sps->vshift[c_idx];
616 31272 const int ps = sps->pixel_shift;
617 31272 const int ref_x = IBC_X((cu->x0 >> hs) + (bv->x >> (4 + hs)));
618 31272 const int ref_y = IBC_Y((cu->y0 >> vs) + (bv->y >> (4 + vs)));
619 31272 const int w = cu->cb_width >> hs;
620 31272 const int h = cu->cb_height >> vs;
621 31272 const int ibc_buf_width = fc->tab.sz.ibc_buffer_width >> hs; ///< IbcBufWidthY and IbcBufWidthC
622 31272 const int rw = FFMIN(w, ibc_buf_width - ref_x);
623 31272 const int ibc_stride = ibc_buf_width << ps;
624 31272 const int dst_stride = fc->frame->linesize[c_idx];
625 31272 const uint8_t *ibc_buf = IBC_POS(c_idx, ref_x, ref_y);
626 31272 uint8_t *dst = POS(c_idx, cu->x0, cu->y0);
627
628 31272 av_image_copy_plane(dst, dst_stride, ibc_buf, ibc_stride, rw << ps, h);
629
630
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 31241 times.
31272 if (w > rw) {
631 //wrap around, left part
632 31 ibc_buf = IBC_POS(c_idx, 0, ref_y);
633 31 dst += rw << ps;
634 31 av_image_copy_plane(dst, dst_stride, ibc_buf, ibc_stride, (w - rw) << ps, h);
635 }
636 31272 }
637
638 31182 static void vvc_predict_ibc(const VVCLocalContext *lc)
639 {
640 31182 const H266RawSPS *rsps = lc->fc->ps.sps->r;
641
642 31182 intra_block_copy(lc, LUMA);
643
3/4
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 31137 times.
✓ Branch 2 taken 45 times.
✗ Branch 3 not taken.
31182 if (lc->cu->tree_type == SINGLE_TREE && rsps->sps_chroma_format_idc) {
644 45 intra_block_copy(lc, CB);
645 45 intra_block_copy(lc, CR);
646 }
647 31182 }
648
649 127411 static void ibc_fill_vir_buf(const VVCLocalContext *lc, const CodingUnit *cu)
650 {
651 127411 const VVCFrameContext *fc = lc->fc;
652 127411 const VVCSPS *sps = fc->ps.sps;
653 int start, end;
654
655 127411 ff_vvc_channel_range(&start, &end, cu->tree_type, sps->r->sps_chroma_format_idc);
656
657
2/2
✓ Branch 0 taken 195820 times.
✓ Branch 1 taken 127411 times.
323231 for (int c_idx = start; c_idx < end; c_idx++) {
658 195820 const int hs = sps->hshift[c_idx];
659 195820 const int vs = sps->vshift[c_idx];
660 195820 const int ps = sps->pixel_shift;
661 195820 const int x = IBC_X(cu->x0 >> hs);
662 195820 const int y = IBC_Y(cu->y0 >> vs);
663 195820 const int src_stride = fc->frame->linesize[c_idx];
664 195820 const int ibc_stride = fc->tab.sz.ibc_buffer_width >> hs << ps;
665 195820 const uint8_t *src = POS(c_idx, cu->x0, cu->y0);
666 195820 uint8_t *ibc_buf = IBC_POS(c_idx, x, y);
667
668 195820 av_image_copy_plane(ibc_buf, ibc_stride, src, src_stride, cu->cb_width >> hs << ps , cu->cb_height >> vs);
669 }
670 127411 }
671
672 int ff_vvc_palette_derive_scale(VVCLocalContext *lc, const TransformUnit *tu, TransformBlock *tb)
673 {
674 const VVCSPS *sps = lc->fc->ps.sps;
675 const int qp_prime_ts_min = 4 + 6 * sps->r->sps_min_qp_prime_ts;
676 int qp;
677
678 derive_qp(lc, tu, tb);
679 qp = FFMAX(qp_prime_ts_min, tb->qp);
680 return level_scale[0][rem6[qp]] << div6[qp];
681 }
682
683 // 8.4.5.3 Decoding process for palette mode
684 static void vvc_predict_palette(VVCLocalContext *lc)
685 {
686 const VVCFrameContext *fc = lc->fc;
687 const CodingUnit *cu = lc->cu;
688 TransformUnit *tu = cu->tus.head;
689 const VVCSPS *sps = fc->ps.sps;
690 const int ps = sps->pixel_shift;
691
692 for (int i = 0; i < tu->nb_tbs; i++) {
693 TransformBlock *tb = &tu->tbs[i];
694 const int c_idx = tb->c_idx;
695 const int w = tb->tb_width;
696 const int h = tb->tb_height;
697 const ptrdiff_t stride = fc->frame->linesize[c_idx];
698 uint8_t *dst = POS(c_idx, cu->x0, cu->y0);
699
700 av_image_copy_plane(dst, stride, (uint8_t*)tb->coeffs, w << ps, w << ps, h);
701 }
702 }
703
704 46713 int ff_vvc_reconstruct(VVCLocalContext *lc, const int rs, const int rx, const int ry)
705 {
706 46713 const VVCFrameContext *fc = lc->fc;
707 46713 const VVCSPS *sps = fc->ps.sps;
708 46713 const int x_ctb = rx << sps->ctb_log2_size_y;
709 46713 const int y_ctb = ry << sps->ctb_log2_size_y;
710 46713 CodingUnit *cu = fc->tab.cus[rs];
711 46713 int ret = 0;
712
713 46713 lc->num_ras[0] = lc->num_ras[1] = 0;
714 46713 lc->lmcs.x_vpdu = -1;
715 46713 lc->lmcs.y_vpdu = -1;
716 46713 ff_vvc_decode_neighbour(lc, x_ctb, y_ctb, rx, ry, rs);
717
2/2
✓ Branch 0 taken 1233121 times.
✓ Branch 1 taken 46713 times.
1279834 while (cu) {
718 1233121 lc->cu = cu;
719
720
2/2
✓ Branch 0 taken 15686 times.
✓ Branch 1 taken 1217435 times.
1233121 if (cu->ciip_flag)
721 15686 ff_vvc_predict_ciip(lc);
722
2/2
✓ Branch 0 taken 31182 times.
✓ Branch 1 taken 1186253 times.
1217435 else if (cu->pred_mode == MODE_IBC)
723 31182 vvc_predict_ibc(lc);
724
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1186253 times.
1186253 else if (cu->pred_mode == MODE_PLT)
725 vvc_predict_palette(lc);
726
2/2
✓ Branch 0 taken 938287 times.
✓ Branch 1 taken 294834 times.
1233121 if (cu->coded_flag) {
727 938287 ret = reconstruct(lc);
728 } else {
729
1/2
✓ Branch 0 taken 294834 times.
✗ Branch 1 not taken.
294834 if (cu->tree_type != DUAL_TREE_CHROMA)
730 294834 add_reconstructed_area(lc, LUMA, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
731
4/4
✓ Branch 0 taken 278323 times.
✓ Branch 1 taken 16511 times.
✓ Branch 2 taken 252629 times.
✓ Branch 3 taken 25694 times.
294834 if (sps->r->sps_chroma_format_idc && cu->tree_type != DUAL_TREE_LUMA)
732 252629 add_reconstructed_area(lc, CHROMA, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
733 }
734
2/2
✓ Branch 0 taken 127411 times.
✓ Branch 1 taken 1105710 times.
1233121 if (sps->r->sps_ibc_enabled_flag)
735 127411 ibc_fill_vir_buf(lc, cu);
736 1233121 cu = cu->next;
737 }
738 46713 ff_vvc_ctu_free_cus(fc->tab.cus + rs);
739 46713 return ret;
740 }
741
742