FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/vvc/intra.c
Date: 2026-10-11 02:49:39
Exec Total Coverage
Lines: 465 474 98.1%
Functions: 29 29 100.0%
Branches: 309 328 94.2%

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 435674 static int is_cclm(enum IntraPredMode mode)
35 {
36
6/6
✓ Branch 0 taken 369285 times.
✓ Branch 1 taken 66389 times.
✓ Branch 2 taken 344583 times.
✓ Branch 3 taken 24702 times.
✓ Branch 4 taken 27697 times.
✓ Branch 5 taken 316886 times.
435674 return mode == INTRA_LT_CCLM || mode == INTRA_L_CCLM || mode == INTRA_T_CCLM;
37 }
38
39 175544 static int derive_ilfnst_pred_mode_intra(const VVCLocalContext *lc, const TransformBlock *tb)
40 {
41 175544 const VVCFrameContext *fc = lc->fc;
42 175544 const VVCSPS *sps = fc->ps.sps;
43 175544 const CodingUnit *cu = lc->cu;
44 175544 const int x_tb = tb->x0 >> fc->ps.sps->min_cb_log2_size_y;
45 175544 const int y_tb = tb->y0 >> fc->ps.sps->min_cb_log2_size_y;
46 175544 const int x_c = (tb->x0 + (tb->tb_width << sps->hshift[1] >> 1) ) >> fc->ps.sps->min_cb_log2_size_y;
47 175544 const int y_c = (tb->y0 + (tb->tb_height << sps->vshift[1] >> 1)) >> fc->ps.sps->min_cb_log2_size_y;
48 175544 const int min_cb_width = fc->ps.pps->min_cb_width;
49 175544 const int intra_mip_flag = SAMPLE_CTB(fc->tab.imf, x_tb, y_tb);
50
2/2
✓ Branch 0 taken 123501 times.
✓ Branch 1 taken 52043 times.
175544 int pred_mode_intra = tb->c_idx == 0 ? cu->intra_pred_mode_y : cu->intra_pred_mode_c;
51
4/4
✓ Branch 0 taken 20026 times.
✓ Branch 1 taken 155518 times.
✓ Branch 2 taken 5109 times.
✓ Branch 3 taken 14917 times.
175544 if (intra_mip_flag && !tb->c_idx) {
52 5109 pred_mode_intra = INTRA_PLANAR;
53
2/2
✓ Branch 1 taken 16549 times.
✓ Branch 2 taken 153886 times.
170435 } else if (is_cclm(pred_mode_intra)) {
54 16549 int intra_mip_flag_c = SAMPLE_CTB(fc->tab.imf, x_c, y_c);
55 16549 int cu_pred_mode = SAMPLE_CTB(fc->tab.cpm[0], x_c, y_c);
56
2/2
✓ Branch 0 taken 4523 times.
✓ Branch 1 taken 12026 times.
16549 if (intra_mip_flag_c) {
57 4523 pred_mode_intra = INTRA_PLANAR;
58
4/4
✓ Branch 0 taken 10642 times.
✓ Branch 1 taken 1384 times.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 10598 times.
12026 } else if (cu_pred_mode == MODE_IBC || cu_pred_mode == MODE_PLT) {
59 1428 pred_mode_intra = INTRA_DC;
60 } else {
61 10598 pred_mode_intra = SAMPLE_CTB(fc->tab.ipm, x_c, y_c);
62 }
63 }
64 175544 pred_mode_intra = ff_vvc_wide_angle_mode_mapping(cu, tb->tb_width, tb->tb_height, tb->c_idx, pred_mode_intra);
65
66 175544 return pred_mode_intra;
67 }
68
69 //8.7.4 Transformation process for scaled transform coefficients
70 175544 static void ilfnst_transform(const VVCLocalContext *lc, TransformBlock *tb)
71 {
72 175544 const VVCSPS *sps = lc->fc->ps.sps;
73 175544 const CodingUnit *cu = lc->cu;
74 175544 const int w = tb->tb_width;
75 175544 const int h = tb->tb_height;
76
4/4
✓ Branch 0 taken 101394 times.
✓ Branch 1 taken 74150 times.
✓ Branch 2 taken 69150 times.
✓ Branch 3 taken 32244 times.
175544 const int n_lfnst_out_size = (w >= 8 && h >= 8) ? 48 : 16; ///< nLfnstOutSize
77
4/4
✓ Branch 0 taken 101394 times.
✓ Branch 1 taken 74150 times.
✓ Branch 2 taken 69150 times.
✓ Branch 3 taken 32244 times.
175544 const int log2_lfnst_size = (w >= 8 && h >= 8) ? 3 : 2; ///< log2LfnstSize
78 175544 const int n_lfnst_size = 1 << log2_lfnst_size; ///< nLfnstSize
79
8/8
✓ Branch 0 taken 40673 times.
✓ Branch 1 taken 134871 times.
✓ Branch 2 taken 27977 times.
✓ Branch 3 taken 12696 times.
✓ Branch 4 taken 74150 times.
✓ Branch 5 taken 88698 times.
✓ Branch 6 taken 50407 times.
✓ Branch 7 taken 23743 times.
175544 const int non_zero_size = ((w == 8 && h == 8) || (w == 4 && h == 4)) ? 8 : 16; ///< nonZeroSize
80 175544 const int pred_mode_intra = derive_ilfnst_pred_mode_intra(lc, tb);
81 175544 const int transpose = pred_mode_intra > 34;
82 int u[16], v[48];
83
84
2/2
✓ Branch 0 taken 2303880 times.
✓ Branch 1 taken 175544 times.
2479424 for (int x = 0; x < non_zero_size; x++) {
85 2303880 int xc = ff_vvc_diag_scan_x[2][2][x];
86 2303880 int yc = ff_vvc_diag_scan_y[2][2][x];
87 2303880 u[x] = tb->coeffs[w * yc + xc];
88 }
89 175544 ff_vvc_inv_lfnst_1d(v, u, non_zero_size, n_lfnst_out_size, pred_mode_intra,
90 175544 cu->lfnst_idx, sps->log2_transform_range);
91
2/2
✓ Branch 0 taken 50894 times.
✓ Branch 1 taken 124650 times.
175544 if (transpose) {
92 50894 int *dst = tb->coeffs;
93 50894 const int *src = v;
94
2/2
✓ Branch 0 taken 35550 times.
✓ Branch 1 taken 15344 times.
50894 if (n_lfnst_size == 4) {
95
2/2
✓ Branch 0 taken 142200 times.
✓ Branch 1 taken 35550 times.
177750 for (int y = 0; y < 4; y++) {
96 142200 dst[0] = src[0];
97 142200 dst[1] = src[4];
98 142200 dst[2] = src[8];
99 142200 dst[3] = src[12];
100 142200 src++;
101 142200 dst += w;
102 }
103 } else {
104
2/2
✓ Branch 0 taken 122752 times.
✓ Branch 1 taken 15344 times.
138096 for (int y = 0; y < 8; y++) {
105 122752 dst[0] = src[0];
106 122752 dst[1] = src[8];
107 122752 dst[2] = src[16];
108 122752 dst[3] = src[24];
109
2/2
✓ Branch 0 taken 61376 times.
✓ Branch 1 taken 61376 times.
122752 if (y < 4) {
110 61376 dst[4] = src[32];
111 61376 dst[5] = src[36];
112 61376 dst[6] = src[40];
113 61376 dst[7] = src[44];
114 }
115 122752 src++;
116 122752 dst += w;
117 }
118 }
119
120 } else {
121 124650 int *dst = tb->coeffs;
122 124650 const int *src = v;
123
2/2
✓ Branch 0 taken 713824 times.
✓ Branch 1 taken 124650 times.
838474 for (int y = 0; y < n_lfnst_size; y++) {
124
2/2
✓ Branch 0 taken 498600 times.
✓ Branch 1 taken 215224 times.
713824 int size = (y < 4) ? n_lfnst_size : 4;
125 713824 memcpy(dst, src, size * sizeof(int));
126 713824 src += size;
127 713824 dst += w;
128 }
129 }
130 175544 tb->max_scan_x = n_lfnst_size - 1;
131 175544 tb->max_scan_y = n_lfnst_size - 1;
132 175544 }
133
134 //part of 8.7.4 Transformation process for scaled transform coefficients
135 968188 static void derive_transform_type(const VVCFrameContext *fc, const VVCLocalContext *lc, const TransformBlock *tb, enum VVCTxType *trh, enum VVCTxType *trv)
136 {
137 968188 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 968188 const VVCSPS *sps = fc->ps.sps;
141 968188 int implicit_mts_enabled = 0;
142
6/6
✓ Branch 0 taken 696530 times.
✓ Branch 1 taken 271658 times.
✓ Branch 2 taken 143243 times.
✓ Branch 3 taken 553287 times.
✓ Branch 4 taken 32899 times.
✓ Branch 5 taken 110344 times.
968188 if (tb->c_idx || (cu->isp_split_type != ISP_NO_SPLIT && cu->lfnst_idx)) {
143 304557 *trh = *trv = VVC_DCT2;
144 304557 return;
145 }
146
147
2/2
✓ Branch 0 taken 657992 times.
✓ Branch 1 taken 5639 times.
663631 if (sps->r->sps_mts_enabled_flag) {
148
2/2
✓ Branch 0 taken 547648 times.
✓ Branch 1 taken 110344 times.
657992 if (cu->isp_split_type != ISP_NO_SPLIT ||
149
4/4
✓ Branch 0 taken 34956 times.
✓ Branch 1 taken 512692 times.
✓ Branch 2 taken 523 times.
✓ Branch 3 taken 34433 times.
547648 (cu->sbt_flag && FFMAX(tb->tb_width, tb->tb_height) <= 32) ||
150
4/4
✓ Branch 0 taken 45019 times.
✓ Branch 1 taken 468196 times.
✓ Branch 2 taken 28412 times.
✓ Branch 3 taken 16607 times.
513215 (!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 159369 implicit_mts_enabled = 1;
153 }
154 }
155
2/2
✓ Branch 0 taken 159369 times.
✓ Branch 1 taken 504262 times.
663631 if (implicit_mts_enabled) {
156 159369 const int w = tb->tb_width;
157 159369 const int h = tb->tb_height;
158
2/2
✓ Branch 0 taken 34433 times.
✓ Branch 1 taken 124936 times.
159369 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 105634 times.
✓ Branch 1 taken 19302 times.
✓ Branch 2 taken 85366 times.
✓ Branch 3 taken 20268 times.
124936 *trh = (w >= 4 && w <= 16) ? VVC_DST7 : VVC_DCT2;
163
4/4
✓ Branch 0 taken 79098 times.
✓ Branch 1 taken 45838 times.
✓ Branch 2 taken 76026 times.
✓ Branch 3 taken 3072 times.
124936 *trv = (h >= 4 && h <= 16) ? VVC_DST7 : VVC_DCT2;
164 }
165 159369 return;
166 }
167 504262 *trh = mts_to_trh[cu->mts_idx];
168 504262 *trv = mts_to_trv[cu->mts_idx];
169 }
170
171 2191763 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 2191763 const VVCSPS *sps = lc->fc->ps.sps;
174 2191763 const int hs = sps->hshift[ch_type];
175 2191763 const int vs = sps->vshift[ch_type];
176 ReconstructedArea *a;
177
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2191763 times.
2191763 if (lc->num_ras[ch_type] >= FF_ARRAY_ELEMS(lc->ras[ch_type]))
179 ✗ return AVERROR_INVALIDDATA;
180
181 2191763 a = &lc->ras[ch_type][lc->num_ras[ch_type]];
182 2191763 a->x = x0 >> hs;
183 2191763 a->y = y0 >> vs;
184 2191763 a->w = w >> hs;
185 2191763 a->h = h >> vs;
186 2191763 lc->num_ras[ch_type]++;
187
188 2191763 return 0;
189 }
190
191 1045713 static void add_tu_area(const TransformUnit *tu, int *x0, int *y0, int *w, int *h)
192 {
193 1045713 *x0 = tu->x0;
194 1045713 *y0 = tu->y0;
195 1045713 *w = tu->width;
196 1045713 *h = tu->height;
197 1045713 }
198
199 #define MIN_ISP_PRED_WIDTH 4
200 786391 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 786391 int has_luma = 1;
203 786391 add_tu_area(tu, x0, y0, w, h);
204
4/4
✓ Branch 0 taken 77382 times.
✓ Branch 1 taken 709009 times.
✓ Branch 2 taken 28178 times.
✓ Branch 3 taken 49204 times.
786391 if (cu->isp_split_type == ISP_VER_SPLIT && tu->width < MIN_ISP_PRED_WIDTH) {
205 28178 *w = MIN_ISP_PRED_WIDTH;
206 28178 has_luma = !(idx % (MIN_ISP_PRED_WIDTH / tu->width));
207 }
208 786391 return has_luma;
209 }
210
211 282640 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 259322 times.
✓ Branch 1 taken 23318 times.
282640 if (cu->isp_split_type == ISP_NO_SPLIT) {
214 259322 add_tu_area(tu, x0, y0, w, h);
215 259322 return 1;
216 }
217
2/2
✓ Branch 0 taken 5917 times.
✓ Branch 1 taken 17401 times.
23318 if (idx == cu->num_intra_subpartitions - 1) {
218 5917 *x0 = cu->x0;
219 5917 *y0 = cu->y0;
220 5917 *w = cu->cb_width;
221 5917 *h = cu->cb_height;
222 5917 return 1;
223 }
224 17401 return 0;
225 }
226
227 //8.4.5.1 General decoding process for intra blocks
228 1533215 static int predict_intra(VVCLocalContext *lc, const TransformUnit *tu, const int idx, const int target_ch_type)
229 {
230 1533215 const VVCFrameContext *fc = lc->fc;
231 1533215 const CodingUnit *cu = lc->cu;
232 1533215 const VVCTreeType tree_type = cu->tree_type;
233 int x0, y0, w, h, ret;
234
2/2
✓ Branch 0 taken 464184 times.
✓ Branch 1 taken 1069031 times.
1533215 if (cu->pred_mode != MODE_INTRA) {
235 464184 ret = add_reconstructed_area(lc, target_ch_type, tu->x0, tu->y0, tu->width, tu->height);
236 464184 return ret;
237 }
238
3/4
✓ Branch 0 taken 786391 times.
✓ Branch 1 taken 282640 times.
✓ Branch 2 taken 786391 times.
✗ Branch 3 not taken.
1069031 if (!target_ch_type && tree_type != DUAL_TREE_CHROMA) {
239
2/2
✓ Branch 1 taken 771160 times.
✓ Branch 2 taken 15231 times.
786391 if (get_luma_predict_unit(cu, tu, idx, &x0, &y0, &w, &h)) {
240 771160 ff_vvc_set_neighbour_available(lc, x0, y0, w, h);
241 771160 fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 0);
242 771160 ret = add_reconstructed_area(lc, 0, x0, y0, w, h);
243
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 771160 times.
771160 if (ret < 0)
244 ✗ return ret;
245 }
246 }
247
3/4
✓ Branch 0 taken 282640 times.
✓ Branch 1 taken 786391 times.
✓ Branch 2 taken 282640 times.
✗ Branch 3 not taken.
1069031 if (target_ch_type && tree_type != DUAL_TREE_LUMA) {
248
2/2
✓ Branch 1 taken 265239 times.
✓ Branch 2 taken 17401 times.
282640 if (get_chroma_predict_unit(cu, tu, idx, &x0, &y0, &w, &h)){
249 265239 ff_vvc_set_neighbour_available(lc, x0, y0, w, h);
250
2/2
✓ Branch 1 taken 102239 times.
✓ Branch 2 taken 163000 times.
265239 if (is_cclm(cu->intra_pred_mode_c)) {
251 102239 fc->vvcdsp.intra.intra_cclm_pred(lc, x0, y0, w, h);
252 } else {
253 163000 fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 1);
254 163000 fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 2);
255 }
256 265239 ret = add_reconstructed_area(lc, 1, x0, y0, w, h);
257
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 265239 times.
265239 if (ret < 0)
258 ✗ return ret;
259 }
260 }
261 1069031 return 0;
262 }
263
264 904232 static void scale_clip(int *coeff, const int nzw, const int w, const int h,
265 const int shift, const int log2_transform_range)
266 {
267 904232 const int add = 1 << (shift - 1);
268
2/2
✓ Branch 0 taken 9327858 times.
✓ Branch 1 taken 904232 times.
10232090 for (int y = 0; y < h; y++) {
269 9327858 int *p = coeff + y * w;
270
2/2
✓ Branch 0 taken 50258890 times.
✓ Branch 1 taken 9327858 times.
59586748 for (int x = 0; x < nzw; x++) {
271 50258890 *p = av_clip_intp2((*p + add) >> shift, log2_transform_range);
272 50258890 p++;
273 }
274 9327858 memset(p, 0, sizeof(*p) * (w - nzw));
275 }
276 904232 }
277
278 917679 static void scale(int *out, const int *in, const int w, const int h, const int shift)
279 {
280 917679 const int add = 1 << (shift - 1);
281
2/2
✓ Branch 0 taken 9385046 times.
✓ Branch 1 taken 917679 times.
10302725 for (int y = 0; y < h; y++) {
282
2/2
✓ Branch 0 taken 155050564 times.
✓ Branch 1 taken 9385046 times.
164435610 for (int x = 0; x < w; x++) {
283 155050564 int *o = out + y * w + x;
284 155050564 const int *i = in + y * w + x;
285 155050564 *o = (*i + add) >> shift;
286 }
287 }
288 917679 }
289
290 // part of 8.7.3 Scaling process for transform coefficients
291 1277443 static void derive_qp(const VVCLocalContext *lc, const TransformUnit *tu, TransformBlock *tb)
292 {
293 1277443 const VVCSPS *sps = lc->fc->ps.sps;
294 1277443 const H266RawSliceHeader *rsh = lc->sc->sh.r;
295 1277443 const CodingUnit *cu = lc->cu;
296
8/8
✓ Branch 0 taken 443505 times.
✓ Branch 1 taken 833938 times.
✓ Branch 2 taken 54921 times.
✓ Branch 3 taken 388584 times.
✓ Branch 4 taken 46741 times.
✓ Branch 5 taken 8180 times.
✓ Branch 6 taken 31652 times.
✓ Branch 7 taken 15089 times.
1277443 const bool is_jcbcr = tb->c_idx && tu->joint_cbcr_residual_flag && tu->coded_flag[CB] && tu->coded_flag[CR];
297
2/2
✓ Branch 0 taken 31652 times.
✓ Branch 1 taken 1245791 times.
1277443 const int idx = is_jcbcr ? JCBCR : tb->c_idx;
298
2/2
✓ Branch 0 taken 833938 times.
✓ Branch 1 taken 443505 times.
1277443 const int qp = cu->qp[idx] + (idx ? 0 : sps->qp_bd_offset);
299 1277443 const int act_offset[] = { -5, 1, 3, 1 };
300
2/2
✓ Branch 0 taken 21078 times.
✓ Branch 1 taken 1256365 times.
1277443 const int qp_act_offset = cu->act_enabled_flag ? act_offset[idx] : 0;
301
302
2/2
✓ Branch 0 taken 56567 times.
✓ Branch 1 taken 1220876 times.
1277443 if (tb->ts) {
303 56567 const int qp_prime_ts_min = 4 + 6 * sps->r->sps_min_qp_prime_ts;
304
305 56567 tb->qp = av_clip(qp + qp_act_offset, qp_prime_ts_min, 63 + sps->qp_bd_offset);
306 56567 tb->rect_non_ts_flag = 0;
307 56567 tb->bd_shift = 10;
308 } else {
309 1220876 const int log_sum = tb->log2_tb_width + tb->log2_tb_height;
310 1220876 const int rect_non_ts_flag = log_sum & 1;
311
312 1220876 tb->qp = av_clip(qp + qp_act_offset, 0, 63 + sps->qp_bd_offset);
313 1220876 tb->rect_non_ts_flag = rect_non_ts_flag;
314 1220876 tb->bd_shift = sps->bit_depth + rect_non_ts_flag + (log_sum / 2)
315 1220876 + 10 - sps->log2_transform_range + rsh->sh_dep_quant_used_flag;
316 }
317 1277443 tb->bd_offset = (1 << tb->bd_shift) >> 1;
318 1277443 }
319
320 static const uint8_t rem6[63 + 8 * 6 + 1] = {
321 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5,
322 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5,
323 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5,
324 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5,
325 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3,
326 };
327
328 static const uint8_t div6[63 + 8 * 6 + 1] = {
329 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3,
330 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7,
331 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11,
332 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15,
333 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18,
334 };
335
336 const static int level_scale[2][6] = {
337 { 40, 45, 51, 57, 64, 72 },
338 { 57, 64, 72, 80, 90, 102 }
339 };
340
341 //8.7.3 Scaling process for transform coefficients
342 1024755 static av_always_inline int derive_scale(const TransformBlock *tb, const int sh_dep_quant_used_flag)
343 {
344
4/4
✓ Branch 0 taken 953944 times.
✓ Branch 1 taken 70811 times.
✓ Branch 2 taken 897377 times.
✓ Branch 3 taken 56567 times.
1024755 const int addin = sh_dep_quant_used_flag && !tb->ts;
345 1024755 const int qp = tb->qp + addin;
346
347 1024755 return level_scale[tb->rect_non_ts_flag][rem6[qp]] << div6[qp];
348 }
349
350 //8.7.3 Scaling process for transform coefficients
351 1024755 static const uint8_t* derive_scale_m(const VVCLocalContext *lc, const TransformBlock *tb, uint8_t *scale_m)
352 {
353 //Table 38 – Specification of the scaling matrix identifier variable id according to predMode, cIdx, nTbW, and nTbH
354 1024755 const int ids[2][3][6] = {
355 {
356 { 0, 2, 8, 14, 20, 26 },
357 { 0, 3, 9, 15, 21, 21 },
358 { 0, 4, 10, 16, 22, 22 }
359 },
360 {
361 { 0, 5, 11, 17, 23, 27 },
362 { 0, 6, 12, 18, 24, 24 },
363 { 1, 7, 13, 19, 25, 25 },
364 }
365 };
366 1024755 const VVCFrameParamSets *ps = &lc->fc->ps;
367 1024755 const VVCSPS *sps = ps->sps;
368 1024755 const H266RawSliceHeader *rsh = lc->sc->sh.r;
369 1024755 const CodingUnit *cu = lc->cu;
370 1024755 const VVCScalingList *sl = ps->sl;
371 1024755 const int id = ids[cu->pred_mode != MODE_INTRA][tb->c_idx][FFMAX(tb->log2_tb_height, tb->log2_tb_width) - 1];
372
4/4
✓ Branch 0 taken 1021904 times.
✓ Branch 1 taken 2851 times.
✓ Branch 2 taken 178496 times.
✓ Branch 3 taken 843408 times.
1024755 const int log2_matrix_size = (id < 2) ? 1 : (id < 8) ? 2 : 3;
373 1024755 uint8_t *p = scale_m;
374
375
4/4
✓ Branch 0 taken 99612 times.
✓ Branch 1 taken 925143 times.
✓ Branch 2 taken 97122 times.
✓ Branch 3 taken 2490 times.
1024755 if (!rsh->sh_explicit_scaling_list_used_flag || tb->ts ||
376
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]) ||
377
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65726 times.
65726 (sps->r->sps_scaling_matrix_for_alternative_colour_space_disabled_flag &&
378 ✗ sps->r->sps_scaling_matrix_designated_colour_space_flag == cu->act_enabled_flag))
379 959029 return ff_vvc_default_scale_m;
380
381
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65726 times.
65726 if (!sl) {
382 ✗ av_log(lc->fc->log_ctx, AV_LOG_WARNING, "bug: no scaling list aps, id = %d", ps->ph.r->ph_scaling_list_aps_id);
383 ✗ return ff_vvc_default_scale_m;
384 }
385
386
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++) {
387 326806 const int off = y << log2_matrix_size >> tb->log2_tb_height << log2_matrix_size;
388 326806 const uint8_t *m = &sl->scaling_matrix_rec[id][off];
389
390
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++)
391 1859082 *p++ = m[x << log2_matrix_size >> tb->log2_tb_width];
392 }
393
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)
394 27312 *scale_m = sl->scaling_matrix_dc_rec[id - SL_START_16x16];
395
396 65726 return scale_m;
397 }
398
399 //8.7.3 Scaling process for transform coefficients
400 12001726 static av_always_inline int scale_coeff(const TransformBlock *tb, int coeff,
401 const int scale, const int scale_m, const int log2_transform_range)
402 {
403 12001726 coeff = ((int64_t) coeff * scale * scale_m + tb->bd_offset) >> tb->bd_shift;
404 12001726 coeff = av_clip_intp2(coeff, log2_transform_range);
405 12001726 return coeff;
406 }
407
408 1024755 static void dequant(const VVCLocalContext *lc, const TransformUnit *tu, TransformBlock *tb)
409 {
410 uint8_t tmp[MAX_TB_SIZE * MAX_TB_SIZE];
411 1024755 const H266RawSliceHeader *rsh = lc->sc->sh.r;
412 1024755 const VVCSPS *sps = lc->fc->ps.sps;
413 1024755 const uint8_t *scale_m = derive_scale_m(lc, tb, tmp);
414 int scale;
415
416 1024755 derive_qp(lc, tu, tb);
417 1024755 scale = derive_scale(tb, rsh->sh_dep_quant_used_flag);
418
419
2/2
✓ Branch 0 taken 3958592 times.
✓ Branch 1 taken 1024755 times.
4983347 for (int y = tb->min_scan_y; y <= tb->max_scan_y; y++) {
420
2/2
✓ Branch 0 taken 23823573 times.
✓ Branch 1 taken 3958592 times.
27782165 for (int x = tb->min_scan_x; x <= tb->max_scan_x; x++) {
421 23823573 int *coeff = tb->coeffs + y * tb->tb_width + x;
422
423
2/2
✓ Branch 0 taken 12001726 times.
✓ Branch 1 taken 11821847 times.
23823573 if (*coeff)
424 12001726 *coeff = scale_coeff(tb, *coeff, scale, *scale_m, sps->log2_transform_range);
425 23823573 scale_m++;
426 }
427 }
428 1024755 }
429
430 //transmatrix[0][0]
431 #define DCT_A 64
432 951594 static void itx_2d(const VVCFrameContext *fc, TransformBlock *tb, const enum VVCTxType trh, const enum VVCTxType trv)
433 {
434 951594 const VVCSPS *sps = fc->ps.sps;
435 951594 const int w = tb->tb_width;
436 951594 const int h = tb->tb_height;
437 951594 const size_t nzw = tb->max_scan_x + 1;
438 951594 const size_t nzh = tb->max_scan_y + 1;
439 951594 const int shift[] = { 7, 5 + sps->log2_transform_range - sps->bit_depth };
440
441
9/10
✓ Branch 0 taken 354937 times.
✓ Branch 1 taken 596657 times.
✓ Branch 2 taken 77917 times.
✓ Branch 3 taken 277020 times.
✓ Branch 4 taken 53977 times.
✓ Branch 5 taken 23940 times.
✓ Branch 6 taken 47362 times.
✓ Branch 7 taken 6615 times.
✓ Branch 8 taken 47362 times.
✗ Branch 9 not taken.
951594 if (w == h && nzw == 1 && nzh == 1 && trh == VVC_DCT2 && trv == VVC_DCT2) {
442 47362 const int add[] = { 1 << (shift[0] - 1), 1 << (shift[1] - 1) };
443 47362 const int t = (tb->coeffs[0] * DCT_A + add[0]) >> shift[0];
444 47362 const int dc = (t * DCT_A + add[1]) >> shift[1];
445
446
2/2
✓ Branch 0 taken 17231008 times.
✓ Branch 1 taken 47362 times.
17278370 for (int i = 0; i < w * h; i++)
447 17231008 tb->coeffs[i] = dc;
448
449 47362 return;
450 }
451
452
2/2
✓ Branch 0 taken 4301250 times.
✓ Branch 1 taken 904232 times.
5205482 for (int x = 0; x < nzw; x++)
453 4301250 fc->vvcdsp.itx.itx[trv][tb->log2_tb_height - 1](tb->coeffs + x, w, nzh);
454 904232 scale_clip(tb->coeffs, nzw, w, h, shift[0], sps->log2_transform_range);
455
456
2/2
✓ Branch 0 taken 9327858 times.
✓ Branch 1 taken 904232 times.
10232090 for (int y = 0; y < h; y++)
457 9327858 fc->vvcdsp.itx.itx[trh][tb->log2_tb_width - 1](tb->coeffs + y * w, 1, nzw);
458 904232 scale(tb->coeffs, tb->coeffs, w, h, shift[1]);
459 }
460
461 16594 static void itx_1d(const VVCFrameContext *fc, TransformBlock *tb, const enum VVCTxType trh, const enum VVCTxType trv)
462 {
463 16594 const VVCSPS *sps = fc->ps.sps;
464 16594 const int w = tb->tb_width;
465 16594 const int h = tb->tb_height;
466 16594 const size_t nzw = tb->max_scan_x + 1;
467 16594 const size_t nzh = tb->max_scan_y + 1;
468
469
12/12
✓ Branch 0 taken 13674 times.
✓ Branch 1 taken 2920 times.
✓ Branch 2 taken 5047 times.
✓ Branch 3 taken 8627 times.
✓ Branch 4 taken 2097 times.
✓ Branch 5 taken 2950 times.
✓ Branch 6 taken 2920 times.
✓ Branch 7 taken 10724 times.
✓ Branch 8 taken 822 times.
✓ Branch 9 taken 2098 times.
✓ Branch 10 taken 197 times.
✓ Branch 11 taken 625 times.
16594 if ((w > 1 && nzw == 1 && trh == VVC_DCT2) || (h > 1 && nzh == 1 && trv == VVC_DCT2)) {
470 3147 const int shift = 6 + sps->log2_transform_range - sps->bit_depth;
471 3147 const int add = 1 << (shift - 1);
472 3147 const int dc = (tb->coeffs[0] * DCT_A + add) >> shift;
473
474
2/2
✓ Branch 0 taken 101056 times.
✓ Branch 1 taken 3147 times.
104203 for (int i = 0; i < w * h; i++)
475 101056 tb->coeffs[i] = dc;
476
477 3147 return;
478 }
479
480
2/2
✓ Branch 0 taken 10724 times.
✓ Branch 1 taken 2723 times.
13447 if (w > 1)
481 10724 fc->vvcdsp.itx.itx[trh][tb->log2_tb_width - 1](tb->coeffs, 1, nzw);
482 else
483 2723 fc->vvcdsp.itx.itx[trv][tb->log2_tb_height - 1](tb->coeffs, 1, nzh);
484 13447 scale(tb->coeffs, tb->coeffs, w, h, 6 + sps->log2_transform_range - sps->bit_depth);
485 }
486
487 3683 static void transform_bdpcm(TransformBlock *tb, const VVCLocalContext *lc, const CodingUnit *cu)
488 {
489 3683 const VVCSPS *sps = lc->fc->ps.sps;
490
2/2
✓ Branch 0 taken 174 times.
✓ Branch 1 taken 3509 times.
3683 const IntraPredMode mode = tb->c_idx ? cu->intra_pred_mode_c : cu->intra_pred_mode_y;
491 3683 const int vertical = mode == INTRA_VERT;
492 3683 lc->fc->vvcdsp.itx.transform_bdpcm(tb->coeffs, tb->tb_width, tb->tb_height,
493 3683 vertical, sps->log2_transform_range);
494
2/2
✓ Branch 0 taken 2422 times.
✓ Branch 1 taken 1261 times.
3683 if (vertical)
495 2422 tb->max_scan_y = tb->tb_height - 1;
496 else
497 1261 tb->max_scan_x = tb->tb_width - 1;
498 3683 }
499
500 1024755 static void lmcs_scale_chroma(VVCLocalContext *lc, TransformUnit *tu, TransformBlock *tb, const int target_ch_type)
501 {
502 1024755 const VVCFrameContext *fc = lc->fc;
503 1024755 const VVCSH *sh = &lc->sc->sh;
504 1024755 const CodingUnit *cu = lc->cu;
505 1024755 const int c_idx = tb->c_idx;
506 1024755 const int ch_type = c_idx > 0;
507 1024755 const int w = tb->tb_width;
508 1024755 const int h = tb->tb_height;
509
7/8
✓ Branch 0 taken 277281 times.
✓ Branch 1 taken 747474 times.
✓ Branch 2 taken 132690 times.
✓ Branch 3 taken 144591 times.
✓ Branch 4 taken 132690 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 130617 times.
✓ Branch 7 taken 2073 times.
1024755 const int chroma_scale = ch_type && sh->r->sh_lmcs_used_flag && fc->ps.ph.r->ph_chroma_residual_scale_flag && (w * h > 4);
510
4/4
✓ Branch 0 taken 68892 times.
✓ Branch 1 taken 955863 times.
✓ Branch 2 taken 54921 times.
✓ Branch 3 taken 13971 times.
1024755 const int has_jcbcr = tu->joint_cbcr_residual_flag && c_idx;
511
512
2/2
✓ Branch 0 taken 1079676 times.
✓ Branch 1 taken 1024755 times.
2104431 for (int j = 0; j < 1 + has_jcbcr; j++) {
513 1079676 const bool is_jcbcr = j > 0;
514 1079676 const int jcbcr_idx = CB + tu->coded_flag[CB];
515 1079676 TransformBlock *jcbcr = &tu->tbs[jcbcr_idx - tu->tbs[0].c_idx];
516
2/2
✓ Branch 0 taken 54921 times.
✓ Branch 1 taken 1024755 times.
1079676 int *coeffs = is_jcbcr ? jcbcr->coeffs : tb->coeffs;
517
518
4/4
✓ Branch 0 taken 1024755 times.
✓ Branch 1 taken 54921 times.
✓ Branch 2 taken 54921 times.
✓ Branch 3 taken 969834 times.
1079676 if (!j && has_jcbcr) {
519 54921 const int c_sign = 1 - 2 * fc->ps.ph.r->ph_joint_cbcr_sign_flag;
520 54921 const int shift = tu->coded_flag[CB] ^ tu->coded_flag[CR];
521 54921 fc->vvcdsp.itx.pred_residual_joint(jcbcr->coeffs, tb->coeffs, w, h, c_sign, shift);
522 }
523
2/2
✓ Branch 0 taken 157766 times.
✓ Branch 1 taken 921910 times.
1079676 if (chroma_scale)
524 157766 fc->vvcdsp.intra.lmcs_scale_chroma(lc, coeffs, w, h, cu->x0, cu->y0);
525 }
526 1024755 }
527
528 1533215 static void add_residual(const VVCLocalContext *lc, TransformUnit *tu, const int target_ch_type)
529 {
530 1533215 const VVCFrameContext *fc = lc->fc;
531 1533215 const CodingUnit *cu = lc->cu;
532
533
2/2
✓ Branch 0 taken 2907649 times.
✓ Branch 1 taken 1533215 times.
4440864 for (int i = 0; i < tu->nb_tbs; i++) {
534 2907649 TransformBlock *tb = tu->tbs + i;
535 2907649 const int c_idx = tb->c_idx;
536 2907649 const int ch_type = c_idx > 0;
537 2907649 const ptrdiff_t stride = fc->frame->linesize[c_idx];
538
6/6
✓ Branch 0 taken 1584135 times.
✓ Branch 1 taken 1323514 times.
✓ Branch 2 taken 1535367 times.
✓ Branch 3 taken 48768 times.
✓ Branch 4 taken 1146472 times.
✓ Branch 5 taken 388895 times.
4054121 const bool has_residual = tb->has_coeffs || cu->act_enabled_flag ||
539
2/2
✓ Branch 0 taken 77501 times.
✓ Branch 1 taken 1068971 times.
1146472 (c_idx && tu->joint_cbcr_residual_flag);
540 2907649 uint8_t *dst = POS(c_idx, tb->x0, tb->y0);
541
542
4/4
✓ Branch 0 taken 2004606 times.
✓ Branch 1 taken 903043 times.
✓ Branch 2 taken 1103603 times.
✓ Branch 3 taken 901003 times.
2907649 if (ch_type == target_ch_type && has_residual)
543 1103603 fc->vvcdsp.itx.add_residual(dst, tb->coeffs, tb->tb_width, tb->tb_height, stride);
544 }
545 1533215 }
546
547 1533215 static void itransform(VVCLocalContext *lc, TransformUnit *tu, const int target_ch_type)
548 {
549 1533215 const VVCFrameContext *fc = lc->fc;
550 1533215 const CodingUnit *cu = lc->cu;
551 1533215 TransformBlock *tbs = tu->tbs;
552
4/4
✓ Branch 0 taken 30308 times.
✓ Branch 1 taken 1502907 times.
✓ Branch 2 taken 15154 times.
✓ Branch 3 taken 15154 times.
1533215 const bool is_act_luma = cu->act_enabled_flag && target_ch_type == LUMA;
553
554
2/2
✓ Branch 0 taken 2907649 times.
✓ Branch 1 taken 1533215 times.
4440864 for (int i = 0; i < tu->nb_tbs; i++) {
555 2907649 TransformBlock *tb = tbs + i;
556 2907649 const int c_idx = tb->c_idx;
557 2907649 const int ch_type = c_idx > 0;
558
6/6
✓ Branch 0 taken 2862187 times.
✓ Branch 1 taken 45462 times.
✓ Branch 2 taken 2816725 times.
✓ Branch 3 taken 45462 times.
✓ Branch 4 taken 1959144 times.
✓ Branch 5 taken 857581 times.
2907649 const bool do_itx = is_act_luma || !cu->act_enabled_flag && ch_type == target_ch_type;
559
560
4/4
✓ Branch 0 taken 1323514 times.
✓ Branch 1 taken 1584135 times.
✓ Branch 2 taken 1024755 times.
✓ Branch 3 taken 298759 times.
2907649 if (tb->has_coeffs && do_itx) {
561
2/2
✓ Branch 0 taken 3683 times.
✓ Branch 1 taken 1021072 times.
1024755 if (cu->bdpcm_flag[tb->c_idx])
562 3683 transform_bdpcm(tb, lc, cu);
563 1024755 dequant(lc, tu, tb);
564
2/2
✓ Branch 0 taken 968188 times.
✓ Branch 1 taken 56567 times.
1024755 if (!tb->ts) {
565 enum VVCTxType trh, trv;
566
567
2/2
✓ Branch 0 taken 175544 times.
✓ Branch 1 taken 792644 times.
968188 if (cu->apply_lfnst_flag[c_idx])
568 175544 ilfnst_transform(lc, tb);
569 968188 derive_transform_type(fc, lc, tb, &trh, &trv);
570
4/4
✓ Branch 0 taken 965268 times.
✓ Branch 1 taken 2920 times.
✓ Branch 2 taken 951594 times.
✓ Branch 3 taken 13674 times.
968188 if (tb->tb_width > 1 && tb->tb_height > 1)
571 951594 itx_2d(fc, tb, trh, trv);
572 else
573 16594 itx_1d(fc, tb, trh, trv);
574 }
575 1024755 lmcs_scale_chroma(lc, tu, tb, target_ch_type);
576 }
577 }
578
579
2/2
✓ Branch 0 taken 15154 times.
✓ Branch 1 taken 1518061 times.
1533215 if (is_act_luma) {
580 15154 fc->vvcdsp.itx.adaptive_color_transform(
581 15154 tbs[LUMA].coeffs, tbs[CB].coeffs, tbs[CR].coeffs,
582 tbs[LUMA].tb_width, tbs[LUMA].tb_height);
583 }
584
585 1533215 add_residual(lc, tu, target_ch_type);
586 1533215 }
587
588 1014990 static int reconstruct(VVCLocalContext *lc)
589 {
590 1014990 VVCFrameContext *fc = lc->fc;
591 1014990 CodingUnit *cu = lc->cu;
592 1014990 const int start = cu->tree_type == DUAL_TREE_CHROMA;
593
4/4
✓ Branch 0 taken 995862 times.
✓ Branch 1 taken 19128 times.
✓ Branch 2 taken 432405 times.
✓ Branch 3 taken 563457 times.
1014990 const int end = fc->ps.sps->r->sps_chroma_format_idc && (cu->tree_type != DUAL_TREE_LUMA);
594 int ret;
595
596
2/2
✓ Branch 0 taken 1254673 times.
✓ Branch 1 taken 1014990 times.
2269663 for (int ch_type = start; ch_type <= end; ch_type++) {
597 1254673 TransformUnit *tu = cu->tus.head;
598
2/2
✓ Branch 0 taken 1533215 times.
✓ Branch 1 taken 1254673 times.
2787888 for (int i = 0; tu; i++) {
599 1533215 ret = predict_intra(lc, tu, i, ch_type);
600
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1533215 times.
1533215 if (ret < 0)
601 ✗ return ret;
602 1533215 itransform(lc, tu, ch_type);
603 1533215 tu = tu->next;
604 }
605 }
606 1014990 return 0;
607 }
608
609 #define IBC_POS(c_idx, x, y) \
610 (fc->tab.ibc_vir_buf[c_idx] + \
611 (x << ps) + (y + ((cu->y0 & ~(sps->ctb_size_y - 1)) >> vs)) * ibc_stride)
612 #define IBC_X(x) ((x) & ((fc->tab.sz.ibc_buffer_width >> hs) - 1))
613 #define IBC_Y(y) ((y) & ((1 << sps->ctb_log2_size_y >> vs) - 1))
614
615 167524 static void intra_block_copy(const VVCLocalContext *lc, const int c_idx)
616 {
617 167524 const CodingUnit *cu = lc->cu;
618 167524 const PredictionUnit *pu = &cu->pu;
619 167524 const VVCFrameContext *fc = lc->fc;
620 167524 const VVCSPS *sps = fc->ps.sps;
621 167524 const Mv *bv = &pu->mi.mv[L0][0];
622 167524 const int hs = sps->hshift[c_idx];
623 167524 const int vs = sps->vshift[c_idx];
624 167524 const int ps = sps->pixel_shift;
625 167524 const int ref_x = IBC_X((cu->x0 >> hs) + (bv->x >> (4 + hs)));
626 167524 const int ref_y = IBC_Y((cu->y0 >> vs) + (bv->y >> (4 + vs)));
627 167524 const int w = cu->cb_width >> hs;
628 167524 const int h = cu->cb_height >> vs;
629 167524 const int ibc_buf_width = fc->tab.sz.ibc_buffer_width >> hs; ///< IbcBufWidthY and IbcBufWidthC
630 167524 const int rw = FFMIN(w, ibc_buf_width - ref_x);
631 167524 const int ibc_stride = ibc_buf_width << ps;
632 167524 const int dst_stride = fc->frame->linesize[c_idx];
633 167524 const uint8_t *ibc_buf = IBC_POS(c_idx, ref_x, ref_y);
634 167524 uint8_t *dst = POS(c_idx, cu->x0, cu->y0);
635
636 167524 av_image_copy_plane(dst, dst_stride, ibc_buf, ibc_stride, rw << ps, h);
637
638
2/2
✓ Branch 0 taken 2354 times.
✓ Branch 1 taken 165170 times.
167524 if (w > rw) {
639 //wrap around, left part
640 2354 ibc_buf = IBC_POS(c_idx, 0, ref_y);
641 2354 dst += rw << ps;
642 2354 av_image_copy_plane(dst, dst_stride, ibc_buf, ibc_stride, (w - rw) << ps, h);
643 }
644 167524 }
645
646 87174 static void vvc_predict_ibc(const VVCLocalContext *lc)
647 {
648 87174 const H266RawSPS *rsps = lc->fc->ps.sps->r;
649
650 87174 intra_block_copy(lc, LUMA);
651
3/4
✓ Branch 0 taken 40175 times.
✓ Branch 1 taken 46999 times.
✓ Branch 2 taken 40175 times.
✗ Branch 3 not taken.
87174 if (lc->cu->tree_type == SINGLE_TREE && rsps->sps_chroma_format_idc) {
652 40175 intra_block_copy(lc, CB);
653 40175 intra_block_copy(lc, CR);
654 }
655 87174 }
656
657 258152 static void ibc_fill_vir_buf(const VVCLocalContext *lc, const CodingUnit *cu)
658 {
659 258152 const VVCFrameContext *fc = lc->fc;
660 258152 const VVCSPS *sps = fc->ps.sps;
661 int start, end;
662
663 258152 ff_vvc_channel_range(&start, &end, cu->tree_type, sps->r->sps_chroma_format_idc);
664
665
2/2
✓ Branch 0 taken 531705 times.
✓ Branch 1 taken 258152 times.
789857 for (int c_idx = start; c_idx < end; c_idx++) {
666 531705 const int hs = sps->hshift[c_idx];
667 531705 const int vs = sps->vshift[c_idx];
668 531705 const int ps = sps->pixel_shift;
669 531705 const int x = IBC_X(cu->x0 >> hs);
670 531705 const int y = IBC_Y(cu->y0 >> vs);
671 531705 const int src_stride = fc->frame->linesize[c_idx];
672 531705 const int ibc_stride = fc->tab.sz.ibc_buffer_width >> hs << ps;
673 531705 const uint8_t *src = POS(c_idx, cu->x0, cu->y0);
674 531705 uint8_t *ibc_buf = IBC_POS(c_idx, x, y);
675
676 531705 av_image_copy_plane(ibc_buf, ibc_stride, src, src_stride, cu->cb_width >> hs << ps , cu->cb_height >> vs);
677 }
678 258152 }
679
680 252688 int ff_vvc_palette_derive_scale(VVCLocalContext *lc, const TransformUnit *tu, TransformBlock *tb)
681 {
682 252688 const VVCSPS *sps = lc->fc->ps.sps;
683 252688 const int qp_prime_ts_min = 4 + 6 * sps->r->sps_min_qp_prime_ts;
684 int qp;
685
686 252688 derive_qp(lc, tu, tb);
687 252688 qp = FFMAX(qp_prime_ts_min, tb->qp);
688 252688 return level_scale[0][rem6[qp]] << div6[qp];
689 }
690
691 // 8.4.5.3 Decoding process for palette mode
692 6977 static void vvc_predict_palette(VVCLocalContext *lc)
693 {
694 6977 const VVCFrameContext *fc = lc->fc;
695 6977 const CodingUnit *cu = lc->cu;
696 6977 TransformUnit *tu = cu->tus.head;
697 6977 const VVCSPS *sps = fc->ps.sps;
698 6977 const int ps = sps->pixel_shift;
699
700
2/2
✓ Branch 0 taken 19123 times.
✓ Branch 1 taken 6977 times.
26100 for (int i = 0; i < tu->nb_tbs; i++) {
701 19123 TransformBlock *tb = &tu->tbs[i];
702 19123 const int c_idx = tb->c_idx;
703 19123 const int w = tb->tb_width;
704 19123 const int h = tb->tb_height;
705 19123 const ptrdiff_t stride = fc->frame->linesize[c_idx];
706 19123 uint8_t *dst = POS(c_idx, cu->x0, cu->y0);
707
708 19123 av_image_copy_plane(dst, stride, (uint8_t*)tb->coeffs, w << ps, w << ps, h);
709 }
710 6977 }
711
712 55834 int ff_vvc_reconstruct(VVCLocalContext *lc, const int rs, const int rx, const int ry)
713 {
714 55834 const VVCFrameContext *fc = lc->fc;
715 55834 const VVCSPS *sps = fc->ps.sps;
716 55834 const int x_ctb = rx << sps->ctb_log2_size_y;
717 55834 const int y_ctb = ry << sps->ctb_log2_size_y;
718 55834 CodingUnit *cu = fc->tab.cus[rs];
719 55834 int ret = 0;
720
721 55834 lc->num_ras[0] = lc->num_ras[1] = 0;
722 55834 lc->lmcs.x_vpdu = -1;
723 55834 lc->lmcs.y_vpdu = -1;
724 55834 ff_vvc_decode_neighbour(lc, x_ctb, y_ctb, rx, ry, rs);
725
2/2
✓ Branch 0 taken 1386930 times.
✓ Branch 1 taken 55834 times.
1442764 while (cu) {
726 1386930 lc->cu = cu;
727
728
2/2
✓ Branch 0 taken 16327 times.
✓ Branch 1 taken 1370603 times.
1386930 if (cu->ciip_flag)
729 16327 ff_vvc_predict_ciip(lc);
730
2/2
✓ Branch 0 taken 87174 times.
✓ Branch 1 taken 1283429 times.
1370603 else if (cu->pred_mode == MODE_IBC)
731 87174 vvc_predict_ibc(lc);
732
2/2
✓ Branch 0 taken 6977 times.
✓ Branch 1 taken 1276452 times.
1283429 else if (cu->pred_mode == MODE_PLT)
733 6977 vvc_predict_palette(lc);
734
2/2
✓ Branch 0 taken 1014990 times.
✓ Branch 1 taken 371940 times.
1386930 if (cu->coded_flag) {
735 1014990 ret = reconstruct(lc);
736 } else {
737
1/2
✓ Branch 0 taken 371940 times.
✗ Branch 1 not taken.
371940 if (cu->tree_type != DUAL_TREE_CHROMA) {
738 371940 ret = add_reconstructed_area(lc, LUMA, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
739
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 371940 times.
371940 if (ret < 0)
740 ✗ return ret;
741 }
742
4/4
✓ Branch 0 taken 355429 times.
✓ Branch 1 taken 16511 times.
✓ Branch 2 taken 319240 times.
✓ Branch 3 taken 36189 times.
371940 if (sps->r->sps_chroma_format_idc && cu->tree_type != DUAL_TREE_LUMA) {
743 319240 ret = add_reconstructed_area(lc, CHROMA, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
744
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 319240 times.
319240 if (ret < 0)
745 ✗ return ret;
746 }
747 }
748
2/2
✓ Branch 0 taken 258152 times.
✓ Branch 1 taken 1128778 times.
1386930 if (sps->r->sps_ibc_enabled_flag)
749 258152 ibc_fill_vir_buf(lc, cu);
750 1386930 cu = cu->next;
751 }
752 55834 ff_vvc_ctu_free_cus(fc->tab.cus + rs);
753 55834 return ret;
754 }
755