FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/vvc/intra.c
Date: 2026-04-24 19:58: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 435660 static int is_cclm(enum IntraPredMode mode)
35 {
36
6/6
✓ Branch 0 taken 369283 times.
✓ Branch 1 taken 66377 times.
✓ Branch 2 taken 344581 times.
✓ Branch 3 taken 24702 times.
✓ Branch 4 taken 27697 times.
✓ Branch 5 taken 316884 times.
435660 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 968171 static void derive_transform_type(const VVCFrameContext *fc, const VVCLocalContext *lc, const TransformBlock *tb, enum VVCTxType *trh, enum VVCTxType *trv)
136 {
137 968171 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 968171 const VVCSPS *sps = fc->ps.sps;
141 968171 int implicit_mts_enabled = 0;
142
6/6
✓ Branch 0 taken 696513 times.
✓ Branch 1 taken 271658 times.
✓ Branch 2 taken 143243 times.
✓ Branch 3 taken 553270 times.
✓ Branch 4 taken 32899 times.
✓ Branch 5 taken 110344 times.
968171 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 5622 times.
663614 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 504245 times.
663614 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 504245 *trh = mts_to_trh[cu->mts_idx];
168 504245 *trv = mts_to_trv[cu->mts_idx];
169 }
170
171 2191665 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 2191665 const VVCSPS *sps = lc->fc->ps.sps;
174 2191665 const int hs = sps->hshift[ch_type];
175 2191665 const int vs = sps->vshift[ch_type];
176 ReconstructedArea *a;
177
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2191665 times.
2191665 if (lc->num_ras[ch_type] >= FF_ARRAY_ELEMS(lc->ras[ch_type]))
179 return AVERROR_INVALIDDATA;
180
181 2191665 a = &lc->ras[ch_type][lc->num_ras[ch_type]];
182 2191665 a->x = x0 >> hs;
183 2191665 a->y = y0 >> vs;
184 2191665 a->w = w >> hs;
185 2191665 a->h = h >> vs;
186 2191665 lc->num_ras[ch_type]++;
187
188 2191665 return 0;
189 }
190
191 1045685 static void add_tu_area(const TransformUnit *tu, int *x0, int *y0, int *w, int *h)
192 {
193 1045685 *x0 = tu->x0;
194 1045685 *y0 = tu->y0;
195 1045685 *w = tu->width;
196 1045685 *h = tu->height;
197 1045685 }
198
199 #define MIN_ISP_PRED_WIDTH 4
200 786377 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 786377 int has_luma = 1;
203 786377 add_tu_area(tu, x0, y0, w, h);
204
4/4
✓ Branch 0 taken 77382 times.
✓ Branch 1 taken 708995 times.
✓ Branch 2 taken 28178 times.
✓ Branch 3 taken 49204 times.
786377 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 786377 return has_luma;
209 }
210
211 282626 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 259308 times.
✓ Branch 1 taken 23318 times.
282626 if (cu->isp_split_type == ISP_NO_SPLIT) {
214 259308 add_tu_area(tu, x0, y0, w, h);
215 259308 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 1533177 static int predict_intra(VVCLocalContext *lc, const TransformUnit *tu, const int idx, const int target_ch_type)
229 {
230 1533177 const VVCFrameContext *fc = lc->fc;
231 1533177 const CodingUnit *cu = lc->cu;
232 1533177 const VVCTreeType tree_type = cu->tree_type;
233 int x0, y0, w, h, ret;
234
2/2
✓ Branch 0 taken 464174 times.
✓ Branch 1 taken 1069003 times.
1533177 if (cu->pred_mode != MODE_INTRA) {
235 464174 ret = add_reconstructed_area(lc, target_ch_type, tu->x0, tu->y0, tu->width, tu->height);
236 464174 return ret;
237 }
238
3/4
✓ Branch 0 taken 786377 times.
✓ Branch 1 taken 282626 times.
✓ Branch 2 taken 786377 times.
✗ Branch 3 not taken.
1069003 if (!target_ch_type && tree_type != DUAL_TREE_CHROMA) {
239
2/2
✓ Branch 1 taken 771146 times.
✓ Branch 2 taken 15231 times.
786377 if (get_luma_predict_unit(cu, tu, idx, &x0, &y0, &w, &h)) {
240 771146 ff_vvc_set_neighbour_available(lc, x0, y0, w, h);
241 771146 fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 0);
242 771146 ret = add_reconstructed_area(lc, 0, x0, y0, w, h);
243
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 771146 times.
771146 if (ret < 0)
244 return ret;
245 }
246 }
247
3/4
✓ Branch 0 taken 282626 times.
✓ Branch 1 taken 786377 times.
✓ Branch 2 taken 282626 times.
✗ Branch 3 not taken.
1069003 if (target_ch_type && tree_type != DUAL_TREE_LUMA) {
248
2/2
✓ Branch 1 taken 265225 times.
✓ Branch 2 taken 17401 times.
282626 if (get_chroma_predict_unit(cu, tu, idx, &x0, &y0, &w, &h)){
249 265225 ff_vvc_set_neighbour_available(lc, x0, y0, w, h);
250
2/2
✓ Branch 1 taken 102227 times.
✓ Branch 2 taken 162998 times.
265225 if (is_cclm(cu->intra_pred_mode_c)) {
251 102227 fc->vvcdsp.intra.intra_cclm_pred(lc, x0, y0, w, h);
252 } else {
253 162998 fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 1);
254 162998 fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 2);
255 }
256 265225 ret = add_reconstructed_area(lc, 1, x0, y0, w, h);
257
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 265225 times.
265225 if (ret < 0)
258 return ret;
259 }
260 }
261 1069003 return 0;
262 }
263
264 904215 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 904215 const int add = 1 << (shift - 1);
268
2/2
✓ Branch 0 taken 9327314 times.
✓ Branch 1 taken 904215 times.
10231529 for (int y = 0; y < h; y++) {
269 9327314 int *p = coeff + y * w;
270
2/2
✓ Branch 0 taken 50257482 times.
✓ Branch 1 taken 9327314 times.
59584796 for (int x = 0; x < nzw; x++) {
271 50257482 *p = av_clip_intp2((*p + add) >> shift, log2_transform_range);
272 50257482 p++;
273 }
274 9327314 memset(p, 0, sizeof(*p) * (w - nzw));
275 }
276 904215 }
277
278 917662 static void scale(int *out, const int *in, const int w, const int h, const int shift)
279 {
280 917662 const int add = 1 << (shift - 1);
281
2/2
✓ Branch 0 taken 9384502 times.
✓ Branch 1 taken 917662 times.
10302164 for (int y = 0; y < h; y++) {
282
2/2
✓ Branch 0 taken 155033156 times.
✓ Branch 1 taken 9384502 times.
164417658 for (int x = 0; x < w; x++) {
283 155033156 int *o = out + y * w + x;
284 155033156 const int *i = in + y * w + x;
285 155033156 *o = (*i + add) >> shift;
286 }
287 }
288 917662 }
289
290 // part of 8.7.3 Scaling process for transform coefficients
291 1277426 static void derive_qp(const VVCLocalContext *lc, const TransformUnit *tu, TransformBlock *tb)
292 {
293 1277426 const VVCSPS *sps = lc->fc->ps.sps;
294 1277426 const H266RawSliceHeader *rsh = lc->sc->sh.r;
295 1277426 const CodingUnit *cu = lc->cu;
296
8/8
✓ Branch 0 taken 443505 times.
✓ Branch 1 taken 833921 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.
1277426 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 1245774 times.
1277426 const int idx = is_jcbcr ? JCBCR : tb->c_idx;
298
2/2
✓ Branch 0 taken 833921 times.
✓ Branch 1 taken 443505 times.
1277426 const int qp = cu->qp[idx] + (idx ? 0 : sps->qp_bd_offset);
299 1277426 const int act_offset[] = { -5, 1, 3, 1 };
300
2/2
✓ Branch 0 taken 21078 times.
✓ Branch 1 taken 1256348 times.
1277426 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 1220859 times.
1277426 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 1220859 const int log_sum = tb->log2_tb_width + tb->log2_tb_height;
310 1220859 const int rect_non_ts_flag = log_sum & 1;
311
312 1220859 tb->qp = av_clip(qp + qp_act_offset, 0, 63 + sps->qp_bd_offset);
313 1220859 tb->rect_non_ts_flag = rect_non_ts_flag;
314 1220859 tb->bd_shift = sps->bit_depth + rect_non_ts_flag + (log_sum / 2)
315 1220859 + 10 - sps->log2_transform_range + rsh->sh_dep_quant_used_flag;
316 }
317 1277426 tb->bd_offset = (1 << tb->bd_shift) >> 1;
318 1277426 }
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 1024738 static av_always_inline int derive_scale(const TransformBlock *tb, const int sh_dep_quant_used_flag)
343 {
344
4/4
✓ Branch 0 taken 953927 times.
✓ Branch 1 taken 70811 times.
✓ Branch 2 taken 897360 times.
✓ Branch 3 taken 56567 times.
1024738 const int addin = sh_dep_quant_used_flag && !tb->ts;
345 1024738 const int qp = tb->qp + addin;
346
347 1024738 return level_scale[tb->rect_non_ts_flag][rem6[qp]] << div6[qp];
348 }
349
350 //8.7.3 Scaling process for transform coefficients
351 1024738 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 1024738 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 1024738 const VVCFrameParamSets *ps = &lc->fc->ps;
367 1024738 const VVCSPS *sps = ps->sps;
368 1024738 const H266RawSliceHeader *rsh = lc->sc->sh.r;
369 1024738 const CodingUnit *cu = lc->cu;
370 1024738 const VVCScalingList *sl = ps->sl;
371 1024738 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 1021887 times.
✓ Branch 1 taken 2851 times.
✓ Branch 2 taken 178496 times.
✓ Branch 3 taken 843391 times.
1024738 const int log2_matrix_size = (id < 2) ? 1 : (id < 8) ? 2 : 3;
373 1024738 uint8_t *p = scale_m;
374
375
4/4
✓ Branch 0 taken 99612 times.
✓ Branch 1 taken 925126 times.
✓ Branch 2 taken 97122 times.
✓ Branch 3 taken 2490 times.
1024738 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 959012 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 12001601 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 12001601 coeff = ((int64_t) coeff * scale * scale_m + tb->bd_offset) >> tb->bd_shift;
404 12001601 coeff = av_clip_intp2(coeff, log2_transform_range);
405 12001601 return coeff;
406 }
407
408 1024738 static void dequant(const VVCLocalContext *lc, const TransformUnit *tu, TransformBlock *tb)
409 {
410 uint8_t tmp[MAX_TB_SIZE * MAX_TB_SIZE];
411 1024738 const H266RawSliceHeader *rsh = lc->sc->sh.r;
412 1024738 const VVCSPS *sps = lc->fc->ps.sps;
413 1024738 const uint8_t *scale_m = derive_scale_m(lc, tb, tmp);
414 int scale;
415
416 1024738 derive_qp(lc, tu, tb);
417 1024738 scale = derive_scale(tb, rsh->sh_dep_quant_used_flag);
418
419
2/2
✓ Branch 0 taken 3958530 times.
✓ Branch 1 taken 1024738 times.
4983268 for (int y = tb->min_scan_y; y <= tb->max_scan_y; y++) {
420
2/2
✓ Branch 0 taken 23823410 times.
✓ Branch 1 taken 3958530 times.
27781940 for (int x = tb->min_scan_x; x <= tb->max_scan_x; x++) {
421 23823410 int *coeff = tb->coeffs + y * tb->tb_width + x;
422
423
2/2
✓ Branch 0 taken 12001601 times.
✓ Branch 1 taken 11821809 times.
23823410 if (*coeff)
424 12001601 *coeff = scale_coeff(tb, *coeff, scale, *scale_m, sps->log2_transform_range);
425 23823410 scale_m++;
426 }
427 }
428 1024738 }
429
430 //transmatrix[0][0]
431 #define DCT_A 64
432 951577 static void itx_2d(const VVCFrameContext *fc, TransformBlock *tb, const enum VVCTxType trh, const enum VVCTxType trv)
433 {
434 951577 const VVCSPS *sps = fc->ps.sps;
435 951577 const int w = tb->tb_width;
436 951577 const int h = tb->tb_height;
437 951577 const size_t nzw = tb->max_scan_x + 1;
438 951577 const size_t nzh = tb->max_scan_y + 1;
439 951577 const int shift[] = { 7, 5 + sps->log2_transform_range - sps->bit_depth };
440
441
9/10
✓ Branch 0 taken 354920 times.
✓ Branch 1 taken 596657 times.
✓ Branch 2 taken 77917 times.
✓ Branch 3 taken 277003 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.
951577 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 4301206 times.
✓ Branch 1 taken 904215 times.
5205421 for (int x = 0; x < nzw; x++)
453 4301206 fc->vvcdsp.itx.itx[trv][tb->log2_tb_height - 1](tb->coeffs + x, w, nzh);
454 904215 scale_clip(tb->coeffs, nzw, w, h, shift[0], sps->log2_transform_range);
455
456
2/2
✓ Branch 0 taken 9327314 times.
✓ Branch 1 taken 904215 times.
10231529 for (int y = 0; y < h; y++)
457 9327314 fc->vvcdsp.itx.itx[trh][tb->log2_tb_width - 1](tb->coeffs + y * w, 1, nzw);
458 904215 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 1024738 static void lmcs_scale_chroma(VVCLocalContext *lc, TransformUnit *tu, TransformBlock *tb, const int target_ch_type)
501 {
502 1024738 const VVCFrameContext *fc = lc->fc;
503 1024738 const VVCSH *sh = &lc->sc->sh;
504 1024738 const CodingUnit *cu = lc->cu;
505 1024738 const int c_idx = tb->c_idx;
506 1024738 const int ch_type = c_idx > 0;
507 1024738 const int w = tb->tb_width;
508 1024738 const int h = tb->tb_height;
509
7/8
✓ Branch 0 taken 277281 times.
✓ Branch 1 taken 747457 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.
1024738 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 955846 times.
✓ Branch 2 taken 54921 times.
✓ Branch 3 taken 13971 times.
1024738 const int has_jcbcr = tu->joint_cbcr_residual_flag && c_idx;
511
512
2/2
✓ Branch 0 taken 1079659 times.
✓ Branch 1 taken 1024738 times.
2104397 for (int j = 0; j < 1 + has_jcbcr; j++) {
513 1079659 const bool is_jcbcr = j > 0;
514 1079659 const int jcbcr_idx = CB + tu->coded_flag[CB];
515 1079659 TransformBlock *jcbcr = &tu->tbs[jcbcr_idx - tu->tbs[0].c_idx];
516
2/2
✓ Branch 0 taken 54921 times.
✓ Branch 1 taken 1024738 times.
1079659 int *coeffs = is_jcbcr ? jcbcr->coeffs : tb->coeffs;
517
518
4/4
✓ Branch 0 taken 1024738 times.
✓ Branch 1 taken 54921 times.
✓ Branch 2 taken 54921 times.
✓ Branch 3 taken 969817 times.
1079659 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 921893 times.
1079659 if (chroma_scale)
524 157766 fc->vvcdsp.intra.lmcs_scale_chroma(lc, coeffs, w, h, cu->x0, cu->y0);
525 }
526 1024738 }
527
528 1533177 static void add_residual(const VVCLocalContext *lc, TransformUnit *tu, const int target_ch_type)
529 {
530 1533177 const VVCFrameContext *fc = lc->fc;
531 1533177 const CodingUnit *cu = lc->cu;
532
533
2/2
✓ Branch 0 taken 2907535 times.
✓ Branch 1 taken 1533177 times.
4440712 for (int i = 0; i < tu->nb_tbs; i++) {
534 2907535 TransformBlock *tb = tu->tbs + i;
535 2907535 const int c_idx = tb->c_idx;
536 2907535 const int ch_type = c_idx > 0;
537 2907535 const ptrdiff_t stride = fc->frame->linesize[c_idx];
538
6/6
✓ Branch 0 taken 1584055 times.
✓ Branch 1 taken 1323480 times.
✓ Branch 2 taken 1535287 times.
✓ Branch 3 taken 48768 times.
✓ Branch 4 taken 1146396 times.
✓ Branch 5 taken 388891 times.
4053931 const bool has_residual = tb->has_coeffs || cu->act_enabled_flag ||
539
2/2
✓ Branch 0 taken 77501 times.
✓ Branch 1 taken 1068895 times.
1146396 (c_idx && tu->joint_cbcr_residual_flag);
540 2907535 uint8_t *dst = POS(c_idx, tb->x0, tb->y0);
541
542
4/4
✓ Branch 0 taken 2004549 times.
✓ Branch 1 taken 902986 times.
✓ Branch 2 taken 1103586 times.
✓ Branch 3 taken 900963 times.
2907535 if (ch_type == target_ch_type && has_residual)
543 1103586 fc->vvcdsp.itx.add_residual(dst, tb->coeffs, tb->tb_width, tb->tb_height, stride);
544 }
545 1533177 }
546
547 1533177 static void itransform(VVCLocalContext *lc, TransformUnit *tu, const int target_ch_type)
548 {
549 1533177 const VVCFrameContext *fc = lc->fc;
550 1533177 const CodingUnit *cu = lc->cu;
551 1533177 TransformBlock *tbs = tu->tbs;
552
4/4
✓ Branch 0 taken 30308 times.
✓ Branch 1 taken 1502869 times.
✓ Branch 2 taken 15154 times.
✓ Branch 3 taken 15154 times.
1533177 const bool is_act_luma = cu->act_enabled_flag && target_ch_type == LUMA;
553
554
2/2
✓ Branch 0 taken 2907535 times.
✓ Branch 1 taken 1533177 times.
4440712 for (int i = 0; i < tu->nb_tbs; i++) {
555 2907535 TransformBlock *tb = tbs + i;
556 2907535 const int c_idx = tb->c_idx;
557 2907535 const int ch_type = c_idx > 0;
558
6/6
✓ Branch 0 taken 2862073 times.
✓ Branch 1 taken 45462 times.
✓ Branch 2 taken 2816611 times.
✓ Branch 3 taken 45462 times.
✓ Branch 4 taken 1959087 times.
✓ Branch 5 taken 857524 times.
2907535 const bool do_itx = is_act_luma || !cu->act_enabled_flag && ch_type == target_ch_type;
559
560
4/4
✓ Branch 0 taken 1323480 times.
✓ Branch 1 taken 1584055 times.
✓ Branch 2 taken 1024738 times.
✓ Branch 3 taken 298742 times.
2907535 if (tb->has_coeffs && do_itx) {
561
2/2
✓ Branch 0 taken 3683 times.
✓ Branch 1 taken 1021055 times.
1024738 if (cu->bdpcm_flag[tb->c_idx])
562 3683 transform_bdpcm(tb, lc, cu);
563 1024738 dequant(lc, tu, tb);
564
2/2
✓ Branch 0 taken 968171 times.
✓ Branch 1 taken 56567 times.
1024738 if (!tb->ts) {
565 enum VVCTxType trh, trv;
566
567
2/2
✓ Branch 0 taken 175544 times.
✓ Branch 1 taken 792627 times.
968171 if (cu->apply_lfnst_flag[c_idx])
568 175544 ilfnst_transform(lc, tb);
569 968171 derive_transform_type(fc, lc, tb, &trh, &trv);
570
4/4
✓ Branch 0 taken 965251 times.
✓ Branch 1 taken 2920 times.
✓ Branch 2 taken 951577 times.
✓ Branch 3 taken 13674 times.
968171 if (tb->tb_width > 1 && tb->tb_height > 1)
571 951577 itx_2d(fc, tb, trh, trv);
572 else
573 16594 itx_1d(fc, tb, trh, trv);
574 }
575 1024738 lmcs_scale_chroma(lc, tu, tb, target_ch_type);
576 }
577 }
578
579
2/2
✓ Branch 0 taken 15154 times.
✓ Branch 1 taken 1518023 times.
1533177 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 1533177 add_residual(lc, tu, target_ch_type);
586 1533177 }
587
588 1014971 static int reconstruct(VVCLocalContext *lc)
589 {
590 1014971 VVCFrameContext *fc = lc->fc;
591 1014971 CodingUnit *cu = lc->cu;
592 1014971 const int start = cu->tree_type == DUAL_TREE_CHROMA;
593
4/4
✓ Branch 0 taken 995843 times.
✓ Branch 1 taken 19128 times.
✓ Branch 2 taken 432386 times.
✓ Branch 3 taken 563457 times.
1014971 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 1254635 times.
✓ Branch 1 taken 1014971 times.
2269606 for (int ch_type = start; ch_type <= end; ch_type++) {
597 1254635 TransformUnit *tu = cu->tus.head;
598
2/2
✓ Branch 0 taken 1533177 times.
✓ Branch 1 taken 1254635 times.
2787812 for (int i = 0; tu; i++) {
599 1533177 ret = predict_intra(lc, tu, i, ch_type);
600
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1533177 times.
1533177 if (ret < 0)
601 return ret;
602 1533177 itransform(lc, tu, ch_type);
603 1533177 tu = tu->next;
604 }
605 }
606 1014971 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 55785 int ff_vvc_reconstruct(VVCLocalContext *lc, const int rs, const int rx, const int ry)
713 {
714 55785 const VVCFrameContext *fc = lc->fc;
715 55785 const VVCSPS *sps = fc->ps.sps;
716 55785 const int x_ctb = rx << sps->ctb_log2_size_y;
717 55785 const int y_ctb = ry << sps->ctb_log2_size_y;
718 55785 CodingUnit *cu = fc->tab.cus[rs];
719 55785 int ret = 0;
720
721 55785 lc->num_ras[0] = lc->num_ras[1] = 0;
722 55785 lc->lmcs.x_vpdu = -1;
723 55785 lc->lmcs.y_vpdu = -1;
724 55785 ff_vvc_decode_neighbour(lc, x_ctb, y_ctb, rx, ry, rs);
725
2/2
✓ Branch 0 taken 1386881 times.
✓ Branch 1 taken 55785 times.
1442666 while (cu) {
726 1386881 lc->cu = cu;
727
728
2/2
✓ Branch 0 taken 16327 times.
✓ Branch 1 taken 1370554 times.
1386881 if (cu->ciip_flag)
729 16327 ff_vvc_predict_ciip(lc);
730
2/2
✓ Branch 0 taken 87174 times.
✓ Branch 1 taken 1283380 times.
1370554 else if (cu->pred_mode == MODE_IBC)
731 87174 vvc_predict_ibc(lc);
732
2/2
✓ Branch 0 taken 6977 times.
✓ Branch 1 taken 1276403 times.
1283380 else if (cu->pred_mode == MODE_PLT)
733 6977 vvc_predict_palette(lc);
734
2/2
✓ Branch 0 taken 1014971 times.
✓ Branch 1 taken 371910 times.
1386881 if (cu->coded_flag) {
735 1014971 ret = reconstruct(lc);
736 } else {
737
1/2
✓ Branch 0 taken 371910 times.
✗ Branch 1 not taken.
371910 if (cu->tree_type != DUAL_TREE_CHROMA) {
738 371910 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 371910 times.
371910 if (ret < 0)
740 return ret;
741 }
742
4/4
✓ Branch 0 taken 355399 times.
✓ Branch 1 taken 16511 times.
✓ Branch 2 taken 319210 times.
✓ Branch 3 taken 36189 times.
371910 if (sps->r->sps_chroma_format_idc && cu->tree_type != DUAL_TREE_LUMA) {
743 319210 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 319210 times.
319210 if (ret < 0)
745 return ret;
746 }
747 }
748
2/2
✓ Branch 0 taken 258152 times.
✓ Branch 1 taken 1128729 times.
1386881 if (sps->r->sps_ibc_enabled_flag)
749 258152 ibc_fill_vir_buf(lc, cu);
750 1386881 cu = cu->next;
751 }
752 55785 ff_vvc_ctu_free_cus(fc->tab.cus + rs);
753 55785 return ret;
754 }
755