FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/vvc/ps.c
Date: 2025-10-10 03:51:19
Exec Total Coverage
Lines: 812 916 88.6%
Functions: 75 76 98.7%
Branches: 412 534 77.2%

Line Branch Exec Source
1 /*
2 * VVC parameter set parser
3 *
4 * Copyright (C) 2023 Nuo Mi
5 * Copyright (C) 2022 Xu Mu
6 *
7 * This file is part of FFmpeg.
8 *
9 * FFmpeg is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * FFmpeg is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with FFmpeg; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23 #include <stdbool.h>
24
25 #include "libavcodec/cbs_h266.h"
26 #include "libavcodec/decode.h"
27 #include "libavcodec/h2645data.h"
28 #include "libavutil/mem.h"
29 #include "libavutil/pixdesc.h"
30 #include "libavutil/refstruct.h"
31 #include "data.h"
32 #include "ps.h"
33 #include "dec.h"
34
35 100 static int sps_map_pixel_format(VVCSPS *sps, void *log_ctx)
36 {
37 100 const H266RawSPS *r = sps->r;
38 const AVPixFmtDescriptor *desc;
39
40
2/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 93 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
100 switch (sps->bit_depth) {
41 7 case 8:
42
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (r->sps_chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY8;
43
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if (r->sps_chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P;
44
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (r->sps_chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P;
45
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (r->sps_chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P;
46 7 break;
47 93 case 10:
48
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 90 times.
93 if (r->sps_chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY10;
49
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 10 times.
93 if (r->sps_chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P10;
50
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 91 times.
93 if (r->sps_chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P10;
51
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 88 times.
93 if (r->sps_chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P10;
52 93 break;
53 case 12:
54 if (r->sps_chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY12;
55 if (r->sps_chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P12;
56 if (r->sps_chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P12;
57 if (r->sps_chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P12;
58 break;
59 default:
60 av_log(log_ctx, AV_LOG_ERROR,
61 "The following bit-depths are currently specified: 8, 10, 12 bits, "
62 "chroma_format_idc is %d, depth is %d\n",
63 r->sps_chroma_format_idc, sps->bit_depth);
64 return AVERROR_INVALIDDATA;
65 }
66
67 100 desc = av_pix_fmt_desc_get(sps->pix_fmt);
68
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 if (!desc)
69 return AVERROR(EINVAL);
70
71 100 sps->hshift[0] = sps->vshift[0] = 0;
72 100 sps->hshift[2] = sps->hshift[1] = desc->log2_chroma_w;
73 100 sps->vshift[2] = sps->vshift[1] = desc->log2_chroma_h;
74
75 100 sps->pixel_shift = sps->bit_depth > 8;
76
77 100 return 0;
78 }
79
80 100 static int sps_bit_depth(VVCSPS *sps, void *log_ctx)
81 {
82 100 const H266RawSPS *r = sps->r;
83
84 100 sps->bit_depth = r->sps_bitdepth_minus8 + 8;
85 100 sps->qp_bd_offset = 6 * (sps->bit_depth - 8);
86 100 sps->log2_transform_range =
87
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
100 r->sps_extended_precision_flag ? FFMAX(15, FFMIN(20, sps->bit_depth + 6)) : 15;
88 100 return sps_map_pixel_format(sps, log_ctx);
89 }
90
91 97 static int sps_chroma_qp_table(VVCSPS *sps)
92 {
93 97 const H266RawSPS *r = sps->r;
94 194 const int num_qp_tables = r->sps_same_qp_table_for_chroma_flag ?
95
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
97 1 : (r->sps_joint_cbcr_enabled_flag ? 3 : 2);
96
97
2/2
✓ Branch 0 taken 103 times.
✓ Branch 1 taken 97 times.
200 for (int i = 0; i < num_qp_tables; i++) {
98 int num_points_in_qp_table;
99 int8_t qp_in[VVC_MAX_POINTS_IN_QP_TABLE], qp_out[VVC_MAX_POINTS_IN_QP_TABLE];
100 unsigned int delta_qp_in[VVC_MAX_POINTS_IN_QP_TABLE];
101 103 int off = sps->qp_bd_offset;
102
103 103 num_points_in_qp_table = r->sps_num_points_in_qp_table_minus1[i] + 1;
104
105 103 qp_out[0] = qp_in[0] = r->sps_qp_table_start_minus26[i] + 26;
106
2/2
✓ Branch 0 taken 317 times.
✓ Branch 1 taken 103 times.
420 for (int j = 0; j < num_points_in_qp_table; j++ ) {
107 317 const uint8_t delta_qp_out = (r->sps_delta_qp_in_val_minus1[i][j] ^ r->sps_delta_qp_diff_val[i][j]);
108 317 delta_qp_in[j] = r->sps_delta_qp_in_val_minus1[i][j] + 1;
109 // Note: we cannot check qp_{in,out}[j+1] here as qp_*[j] + delta_qp_*
110 // may not fit in an 8-bit signed integer.
111
2/4
✓ Branch 0 taken 317 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 317 times.
317 if (qp_in[j] + delta_qp_in[j] > 63 || qp_out[j] + delta_qp_out > 63)
112 return AVERROR(EINVAL);
113 317 qp_in[j+1] = qp_in[j] + delta_qp_in[j];
114 317 qp_out[j+1] = qp_out[j] + delta_qp_out;
115 }
116 103 sps->chroma_qp_table[i][qp_in[0] + off] = qp_out[0];
117
2/2
✓ Branch 0 taken 3008 times.
✓ Branch 1 taken 103 times.
3111 for (int k = qp_in[0] - 1 + off; k >= 0; k--)
118 3008 sps->chroma_qp_table[i][k] = av_clip(sps->chroma_qp_table[i][k+1]-1, -off, 63);
119
120
2/2
✓ Branch 0 taken 317 times.
✓ Branch 1 taken 103 times.
420 for (int j = 0; j < num_points_in_qp_table; j++) {
121 317 int sh = delta_qp_in[j] >> 1;
122
2/2
✓ Branch 0 taken 2532 times.
✓ Branch 1 taken 317 times.
2849 for (int k = qp_in[j] + 1 + off, m = 1; k <= qp_in[j+1] + off; k++, m++) {
123 2532 sps->chroma_qp_table[i][k] = sps->chroma_qp_table[i][qp_in[j] + off] +
124 2532 ((qp_out[j+1] - qp_out[j]) * m + sh) / delta_qp_in[j];
125 }
126 }
127
2/2
✓ Branch 0 taken 2101 times.
✓ Branch 1 taken 103 times.
2204 for (int k = qp_in[num_points_in_qp_table] + 1 + off; k <= 63 + off; k++)
128 2101 sps->chroma_qp_table[i][k] = av_clip(sps->chroma_qp_table[i][k-1] + 1, -sps->qp_bd_offset, 63);
129 }
130
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 3 times.
97 if (r->sps_same_qp_table_for_chroma_flag) {
131 94 memcpy(&sps->chroma_qp_table[1], &sps->chroma_qp_table[0], sizeof(sps->chroma_qp_table[0]));
132 94 memcpy(&sps->chroma_qp_table[2], &sps->chroma_qp_table[0], sizeof(sps->chroma_qp_table[0]));
133 }
134
135 97 return 0;
136 }
137
138 100 static void sps_poc(VVCSPS *sps)
139 {
140 100 sps->max_pic_order_cnt_lsb = 1 << (sps->r->sps_log2_max_pic_order_cnt_lsb_minus4 + 4);
141 100 }
142
143 100 static void sps_inter(VVCSPS *sps)
144 {
145 100 const H266RawSPS *r = sps->r;
146
147 100 sps->max_num_merge_cand = 6 - r->sps_six_minus_max_num_merge_cand;
148 100 sps->max_num_ibc_merge_cand = 6 - r->sps_six_minus_max_num_ibc_merge_cand;
149
150
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 16 times.
100 if (sps->r->sps_gpm_enabled_flag) {
151 84 sps->max_num_gpm_merge_cand = 2;
152
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 if (sps->max_num_merge_cand >= 3)
153 84 sps->max_num_gpm_merge_cand = sps->max_num_merge_cand - r->sps_max_num_merge_cand_minus_max_num_gpm_cand;
154 }
155
156 100 sps->log2_parallel_merge_level = r->sps_log2_parallel_merge_level_minus2 + 2;
157 100 }
158
159 100 static void sps_partition_constraints(VVCSPS* sps)
160 {
161 100 const H266RawSPS *r = sps->r;
162
163 100 sps->ctb_log2_size_y = r->sps_log2_ctu_size_minus5 + 5;
164 100 sps->ctb_size_y = 1 << sps->ctb_log2_size_y;
165 100 sps->min_cb_log2_size_y = r->sps_log2_min_luma_coding_block_size_minus2 + 2;
166 100 sps->min_cb_size_y = 1 << sps->min_cb_log2_size_y;
167
2/2
✓ Branch 0 taken 93 times.
✓ Branch 1 taken 7 times.
100 sps->max_tb_size_y = 1 << (r->sps_max_luma_transform_size_64_flag ? 6 : 5);
168 100 sps->max_ts_size = 1 << (r->sps_log2_transform_skip_max_size_minus2 + 2);
169 100 }
170
171 100 static void sps_ladf(VVCSPS* sps)
172 {
173 100 const H266RawSPS *r = sps->r;
174
175
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 98 times.
100 if (r->sps_ladf_enabled_flag) {
176 2 sps->num_ladf_intervals = r->sps_num_ladf_intervals_minus2 + 2;
177 2 sps->ladf_interval_lower_bound[0] = 0;
178
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 for (int i = 0; i < sps->num_ladf_intervals - 1; i++) {
179 4 sps->ladf_interval_lower_bound[i + 1] =
180 4 sps->ladf_interval_lower_bound[i] + r->sps_ladf_delta_threshold_minus1[i] + 1;
181 }
182 }
183 100 }
184
185 #define EXTENDED_SAR 255
186 9 static void sps_vui(AVCodecContext *c, const H266RawVUI *vui)
187 {
188 9 AVRational sar = (AVRational){ 0, 1 };
189
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7 times.
9 if (vui->vui_aspect_ratio_info_present_flag) {
190
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (vui->vui_aspect_ratio_idc < FF_ARRAY_ELEMS(ff_h2645_pixel_aspect))
191 2 sar = ff_h2645_pixel_aspect[vui->vui_aspect_ratio_idc];
192 else if (vui->vui_aspect_ratio_idc == EXTENDED_SAR) {
193 sar = (AVRational){ vui->vui_sar_width, vui->vui_sar_height };
194 } else {
195 av_log(c, AV_LOG_WARNING, "Unknown SAR index: %u.\n", vui->vui_aspect_ratio_idc);
196 }
197 }
198 9 ff_set_sar(c, sar);
199
200
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7 times.
9 if (vui->vui_colour_description_present_flag) {
201 2 c->color_primaries = vui->vui_colour_primaries;
202 2 c->color_trc = vui->vui_transfer_characteristics;
203 2 c->colorspace = vui->vui_matrix_coeffs;
204
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 c->color_range = vui->vui_full_range_flag ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
205
206 // Set invalid values to "unspecified"
207
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (!av_color_primaries_name(c->color_primaries))
208 c->color_primaries = AVCOL_PRI_UNSPECIFIED;
209
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (!av_color_transfer_name(c->color_trc))
210 c->color_trc = AVCOL_TRC_UNSPECIFIED;
211
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (!av_color_space_name(c->colorspace))
212 c->colorspace = AVCOL_SPC_UNSPECIFIED;
213 } else {
214 7 c->color_primaries = AVCOL_PRI_UNSPECIFIED;
215 7 c->color_trc = AVCOL_TRC_UNSPECIFIED;
216 7 c->colorspace = AVCOL_SPC_UNSPECIFIED;
217 7 c->color_range = AVCOL_RANGE_MPEG;
218 }
219 9 }
220
221
222 100 static void sps_export_stream_params(AVCodecContext *c, const VVCSPS *sps)
223 {
224 100 const H266RawSPS *r = sps->r;
225
226 100 c->has_b_frames = !!r->sps_dpb_params.dpb_max_num_reorder_pics[r->sps_max_sublayers_minus1];
227
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 91 times.
100 if (r->sps_vui_parameters_present_flag)
228 9 sps_vui(c, &r->vui);
229 100 }
230
231 100 static int sps_derive(VVCSPS *sps, AVCodecContext *c)
232 {
233 int ret;
234 100 const H266RawSPS *r = sps->r;
235
236 100 ret = sps_bit_depth(sps, c);
237
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 if (ret < 0)
238 return ret;
239 100 sps_poc(sps);
240 100 sps_inter(sps);
241 100 sps_partition_constraints(sps);
242 100 sps_ladf(sps);
243
2/2
✓ Branch 0 taken 97 times.
✓ Branch 1 taken 3 times.
100 if (r->sps_chroma_format_idc != 0) {
244 97 ret = sps_chroma_qp_table(sps);
245
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 97 times.
97 if (ret < 0)
246 return ret;
247 }
248 100 sps_export_stream_params(c, sps);
249
250 100 return 0;
251 }
252
253 100 static void sps_free(AVRefStructOpaque opaque, void *obj)
254 {
255 100 VVCSPS *sps = obj;
256 100 av_refstruct_unref(&sps->r);
257 100 }
258
259 100 static const VVCSPS *sps_alloc(const H266RawSPS *rsps, AVCodecContext *c)
260 {
261 int ret;
262 100 VVCSPS *sps = av_refstruct_alloc_ext(sizeof(*sps), 0, NULL, sps_free);
263
264
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 if (!sps)
265 return NULL;
266
267 100 av_refstruct_replace(&sps->r, rsps);
268
269 100 ret = sps_derive(sps, c);
270
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 if (ret < 0)
271 goto fail;
272
273 100 return sps;
274
275 fail:
276 av_refstruct_unref(&sps);
277 return NULL;
278 }
279
280 1066 static int decode_sps(VVCParamSets *ps, AVCodecContext *c, const H266RawSPS *rsps, int is_clvss)
281 {
282 1066 const int sps_id = rsps->sps_seq_parameter_set_id;
283 1066 const VVCSPS *old_sps = ps->sps_list[sps_id];
284 const VVCSPS *sps;
285
286
2/2
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 957 times.
1066 if (is_clvss) {
287 109 ps->sps_id_used = 0;
288 }
289
290
2/2
✓ Branch 0 taken 971 times.
✓ Branch 1 taken 95 times.
1066 if (old_sps) {
291
4/4
✓ Branch 0 taken 302 times.
✓ Branch 1 taken 669 times.
✓ Branch 2 taken 297 times.
✓ Branch 3 taken 5 times.
971 if (old_sps->r == rsps || !memcmp(old_sps->r, rsps, sizeof(*old_sps->r))) {
292 966 ps->sps_id_used |= (1 << sps_id);
293 966 return 0;
294
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 } else if (ps->sps_id_used & (1 << sps_id))
295 return AVERROR_INVALIDDATA;
296 }
297
298 100 sps = sps_alloc(rsps, c);
299
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 if (!sps)
300 return AVERROR(ENOMEM);
301
302 100 av_refstruct_unref(&ps->sps_list[sps_id]);
303 100 ps->sps_list[sps_id] = sps;
304 100 ps->sps_id_used |= (1 << sps_id);
305
306 100 return 0;
307 }
308
309 199 static void pps_chroma_qp_offset(VVCPPS *pps)
310 {
311 199 pps->chroma_qp_offset[CB - 1] = pps->r->pps_cb_qp_offset;
312 199 pps->chroma_qp_offset[CR - 1] = pps->r->pps_cr_qp_offset;
313 199 pps->chroma_qp_offset[JCBCR - 1]= pps->r->pps_joint_cbcr_qp_offset_value;
314
2/2
✓ Branch 0 taken 1194 times.
✓ Branch 1 taken 199 times.
1393 for (int i = 0; i < 6; i++) {
315 1194 pps->chroma_qp_offset_list[i][CB - 1] = pps->r->pps_cb_qp_offset_list[i];
316 1194 pps->chroma_qp_offset_list[i][CR - 1] = pps->r->pps_cr_qp_offset_list[i];
317 1194 pps->chroma_qp_offset_list[i][JCBCR - 1]= pps->r->pps_joint_cbcr_qp_offset_list[i];
318 }
319 199 }
320
321 199 static void pps_width_height(VVCPPS *pps, const VVCSPS *sps)
322 {
323 199 const H266RawPPS *r = pps->r;
324
325 199 pps->width = r->pps_pic_width_in_luma_samples;
326 199 pps->height = r->pps_pic_height_in_luma_samples;
327
328 199 pps->ctb_width = AV_CEIL_RSHIFT(pps->width, sps->ctb_log2_size_y);
329 199 pps->ctb_height = AV_CEIL_RSHIFT(pps->height, sps->ctb_log2_size_y);
330 199 pps->ctb_count = pps->ctb_width * pps->ctb_height;
331
332 199 pps->min_cb_width = pps->width >> sps->min_cb_log2_size_y;
333 199 pps->min_cb_height = pps->height >> sps->min_cb_log2_size_y;
334
335 199 pps->min_pu_width = pps->width >> MIN_PU_LOG2;
336 199 pps->min_pu_height = pps->height >> MIN_PU_LOG2;
337 199 pps->min_tu_width = pps->width >> MIN_TU_LOG2;
338 199 pps->min_tu_height = pps->height >> MIN_TU_LOG2;
339
340 199 pps->width32 = AV_CEIL_RSHIFT(pps->width, 5);
341 199 pps->height32 = AV_CEIL_RSHIFT(pps->height, 5);
342 199 pps->width64 = AV_CEIL_RSHIFT(pps->width, 6);
343 199 pps->height64 = AV_CEIL_RSHIFT(pps->height, 6);
344 199 }
345
346 199 static int pps_bd(VVCPPS *pps)
347 {
348 199 const H266RawPPS *r = pps->r;
349
350 199 pps->col_bd = av_calloc(r->num_tile_columns + 1, sizeof(*pps->col_bd));
351 199 pps->row_bd = av_calloc(r->num_tile_rows + 1, sizeof(*pps->row_bd));
352 199 pps->ctb_to_col_bd = av_calloc(pps->ctb_width + 1, sizeof(*pps->ctb_to_col_bd));
353 199 pps->ctb_to_row_bd = av_calloc(pps->ctb_height + 1, sizeof(*pps->ctb_to_col_bd));
354
4/8
✓ Branch 0 taken 199 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 199 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 199 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 199 times.
199 if (!pps->col_bd || !pps->row_bd || !pps->ctb_to_col_bd || !pps->ctb_to_row_bd)
355 return AVERROR(ENOMEM);
356
357
2/2
✓ Branch 0 taken 312 times.
✓ Branch 1 taken 199 times.
511 for (int i = 0, j = 0; i < r->num_tile_columns; i++) {
358 312 pps->col_bd[i] = j;
359 312 j += r->col_width_val[i];
360
2/2
✓ Branch 0 taken 1359 times.
✓ Branch 1 taken 312 times.
1671 for (int k = pps->col_bd[i]; k < j; k++)
361 1359 pps->ctb_to_col_bd[k] = pps->col_bd[i];
362 }
363 199 pps->col_bd[r->num_tile_columns] = pps->ctb_to_col_bd[pps->ctb_width] = pps->ctb_width;
364
365
2/2
✓ Branch 0 taken 302 times.
✓ Branch 1 taken 199 times.
501 for (int i = 0, j = 0; i < r->num_tile_rows; i++) {
366 302 pps->row_bd[i] = j;
367 302 j += r->row_height_val[i];
368
2/2
✓ Branch 0 taken 825 times.
✓ Branch 1 taken 302 times.
1127 for (int k = pps->row_bd[i]; k < j; k++)
369 825 pps->ctb_to_row_bd[k] = pps->row_bd[i];
370 }
371 199 pps->row_bd[r->num_tile_rows] = pps->ctb_to_row_bd[pps->ctb_height] = pps->ctb_height;
372
373 199 return 0;
374 }
375
376
377 158 static int next_tile_idx(int tile_idx, const int i, const H266RawPPS *r)
378 {
379
2/2
✓ Branch 0 taken 61 times.
✓ Branch 1 taken 97 times.
158 if (r->pps_tile_idx_delta_present_flag) {
380 61 tile_idx += r->pps_tile_idx_delta_val[i];
381 } else {
382 97 tile_idx += r->pps_slice_width_in_tiles_minus1[i] + 1;
383
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 45 times.
97 if (tile_idx % r->num_tile_columns == 0)
384 52 tile_idx += (r->pps_slice_height_in_tiles_minus1[i]) * r->num_tile_columns;
385 }
386 158 return tile_idx;
387 }
388
389 158 static void tile_xy(int *tile_x, int *tile_y, const int tile_idx, const VVCPPS *pps)
390 {
391 158 *tile_x = tile_idx % pps->r->num_tile_columns;
392 158 *tile_y = tile_idx / pps->r->num_tile_columns;
393 158 }
394
395 720 static void ctu_xy(int *rx, int *ry, const int tile_x, const int tile_y, const VVCPPS *pps)
396 {
397 720 *rx = pps->col_bd[tile_x];
398 720 *ry = pps->row_bd[tile_y];
399 720 }
400
401 7893 static int ctu_rs(const int rx, const int ry, const VVCPPS *pps)
402 {
403 7893 return pps->ctb_width * ry + rx;
404 }
405
406 776 static int pps_add_ctus(VVCPPS *pps, int *off, const int rx, const int ry,
407 const int w, const int h)
408 {
409 776 int start = *off;
410
2/2
✓ Branch 0 taken 1660 times.
✓ Branch 1 taken 776 times.
2436 for (int y = 0; y < h; y++) {
411
2/2
✓ Branch 0 taken 7893 times.
✓ Branch 1 taken 1660 times.
9553 for (int x = 0; x < w; x++) {
412
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7893 times.
7893 if (*off >= pps->ctb_count)
413 return AVERROR_INVALIDDATA;
414 7893 pps->ctb_addr_in_slice[*off] = ctu_rs(rx + x, ry + y, pps);
415 7893 (*off)++;
416 }
417 }
418 776 return *off - start;
419 }
420
421 2 static int pps_single_slice_picture(VVCPPS *pps, int *off)
422 {
423 2 pps->num_ctus_in_slice[0] = 0;
424
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 for (int j = 0; j < pps->r->num_tile_rows; j++) {
425
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 for (int i = 0; i < pps->r->num_tile_columns; i++) {
426 8 const int ret = pps_add_ctus(pps, off,
427 8 pps->col_bd[i], pps->row_bd[j],
428 8 pps->r->col_width_val[i], pps->r->row_height_val[j]);
429
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (ret < 0)
430 return ret;
431 8 pps->num_ctus_in_slice[0] += ret;
432 }
433 }
434
435 2 return 0;
436 }
437
438 16 static void subpic_tiles(int *tile_x, int *tile_y, int *tile_x_end, int *tile_y_end,
439 const VVCSPS *sps, const VVCPPS *pps, const int i)
440 {
441 16 const int rx = sps->r->sps_subpic_ctu_top_left_x[i];
442 16 const int ry = sps->r->sps_subpic_ctu_top_left_y[i];
443
444 16 *tile_x = *tile_y = 0;
445
446
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 16 times.
40 while (pps->col_bd[*tile_x] < rx)
447 24 (*tile_x)++;
448
449
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 16 times.
24 while (pps->row_bd[*tile_y] < ry)
450 8 (*tile_y)++;
451
452 16 *tile_x_end = (*tile_x);
453 16 *tile_y_end = (*tile_y);
454
455
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 while (pps->col_bd[*tile_x_end] < rx + sps->r->sps_subpic_width_minus1[i] + 1)
456 16 (*tile_x_end)++;
457
458
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 while (pps->row_bd[*tile_y_end] < ry + sps->r->sps_subpic_height_minus1[i] + 1)
459 16 (*tile_y_end)++;
460 16 }
461
462 static int pps_subpic_less_than_one_tile_slice(VVCPPS *pps, const VVCSPS *sps, const int i, const int tx, const int ty, int *off)
463 {
464 const int ret = pps_add_ctus(pps, off,
465 sps->r->sps_subpic_ctu_top_left_x[i], sps->r->sps_subpic_ctu_top_left_y[i],
466 sps->r->sps_subpic_width_minus1[i] + 1, sps->r->sps_subpic_height_minus1[i] + 1);
467 if (ret < 0)
468 return ret;
469
470 pps->num_ctus_in_slice[i] = ret;
471 return 0;
472 }
473
474 16 static int pps_subpic_one_or_more_tiles_slice(VVCPPS *pps, const int tile_x, const int tile_y, const int x_end, const int y_end,
475 const int i, int *off)
476 {
477
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 for (int ty = tile_y; ty < y_end; ty++) {
478
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 for (int tx = tile_x; tx < x_end; tx++) {
479 16 const int ret = pps_add_ctus(pps, off,
480 16 pps->col_bd[tx], pps->row_bd[ty],
481 16 pps->r->col_width_val[tx], pps->r->row_height_val[ty]);
482
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (ret < 0)
483 return ret;
484
485 16 pps->num_ctus_in_slice[i] += ret;
486 }
487 }
488 16 return 0;
489 }
490
491 16 static int pps_subpic_slice(VVCPPS *pps, const VVCSPS *sps, const int i, int *off)
492 {
493 int tx, ty, x_end, y_end;
494
495 16 pps->slice_start_offset[i] = *off;
496 16 pps->num_ctus_in_slice[i] = 0;
497
498 16 subpic_tiles(&tx, &ty, &x_end, &y_end, sps, pps, i);
499
2/4
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
16 if (ty + 1 == y_end && sps->r->sps_subpic_height_minus1[i] + 1 < pps->r->row_height_val[ty])
500 return pps_subpic_less_than_one_tile_slice(pps, sps, i, tx, ty, off);
501 else
502 16 return pps_subpic_one_or_more_tiles_slice(pps, tx, ty, x_end, y_end, i, off);
503 }
504
505 4 static int pps_single_slice_per_subpic(VVCPPS *pps, const VVCSPS *sps, int *off)
506 {
507 int ret;
508
509
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (!sps->r->sps_subpic_info_present_flag) {
510 2 ret = pps_single_slice_picture(pps, off);
511
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (ret < 0)
512 return ret;
513 } else {
514
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 2 times.
18 for (int i = 0; i < pps->r->pps_num_slices_in_pic_minus1 + 1; i++) {
515 16 const int ret = pps_subpic_slice(pps, sps, i, off);
516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (ret < 0)
517 return ret;
518 }
519 }
520 4 return 0;
521 }
522
523 95 static int pps_one_tile_slices(VVCPPS *pps, const int tile_idx, int i, int *off)
524 {
525 95 const H266RawPPS *r = pps->r;
526 int rx, ry, ctu_y_end, tile_x, tile_y;
527
528 95 tile_xy(&tile_x, &tile_y, tile_idx, pps);
529 95 ctu_xy(&rx, &ry, tile_x, tile_y, pps);
530 95 ctu_y_end = ry + r->row_height_val[tile_y];
531
2/2
✓ Branch 0 taken 127 times.
✓ Branch 1 taken 95 times.
222 while (ry < ctu_y_end) {
532 int ret;
533 127 pps->slice_start_offset[i] = *off;
534 127 ret = pps_add_ctus(pps, off, rx, ry,
535 127 r->col_width_val[tile_x], r->slice_height_in_ctus[i]);
536
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 127 times.
127 if (ret < 0)
537 return ret;
538 127 pps->num_ctus_in_slice[i] = ret;
539 127 ry += r->slice_height_in_ctus[i++];
540 }
541 95 i--;
542 95 return i;
543 }
544
545 63 static int pps_multi_tiles_slice(VVCPPS *pps, const int tile_idx, const int i, int *off, bool *tile_in_slice)
546 {
547 63 const H266RawPPS *r = pps->r;
548 int rx, ry, tile_x, tile_y;
549
550 63 tile_xy(&tile_x, &tile_y, tile_idx, pps);
551 63 pps->slice_start_offset[i] = *off;
552 63 pps->num_ctus_in_slice[i] = 0;
553
2/2
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 63 times.
186 for (int ty = tile_y; ty <= tile_y + r->pps_slice_height_in_tiles_minus1[i]; ty++) {
554
2/2
✓ Branch 0 taken 414 times.
✓ Branch 1 taken 123 times.
537 for (int tx = tile_x; tx <= tile_x + r->pps_slice_width_in_tiles_minus1[i]; tx++) {
555 int ret;
556 414 const int idx = ty * r->num_tile_columns + tx;
557
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 414 times.
414 if (tile_in_slice[idx])
558 return AVERROR_INVALIDDATA;
559 414 tile_in_slice[idx] = true;
560 414 ctu_xy(&rx, &ry, tx, ty, pps);
561 414 ret = pps_add_ctus(pps, off, rx, ry,
562 414 r->col_width_val[tx], r->row_height_val[ty]);
563
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 414 times.
414 if (ret < 0)
564 return ret;
565 414 pps->num_ctus_in_slice[i] += ret;
566 }
567 }
568
569 63 return 0;
570 }
571
572 36 static int pps_rect_slice(VVCPPS *pps, const VVCSPS *sps)
573 {
574 36 const H266RawPPS *r = pps->r;
575 36 bool tile_in_slice[VVC_MAX_TILES_PER_AU] = {false};
576 36 int tile_idx = 0, off = 0, ret;
577
578
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 32 times.
36 if (r->pps_single_slice_per_subpic_flag) {
579 4 return pps_single_slice_per_subpic(pps, sps, &off);
580 }
581
582
2/2
✓ Branch 0 taken 158 times.
✓ Branch 1 taken 32 times.
190 for (int i = 0; i < r->pps_num_slices_in_pic_minus1 + 1; i++) {
583
2/2
✓ Branch 0 taken 101 times.
✓ Branch 1 taken 57 times.
158 if (!r->pps_slice_width_in_tiles_minus1[i] &&
584
2/2
✓ Branch 0 taken 95 times.
✓ Branch 1 taken 6 times.
101 !r->pps_slice_height_in_tiles_minus1[i]) {
585
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 95 times.
95 if (tile_in_slice[tile_idx])
586 return AVERROR_INVALIDDATA;
587 95 tile_in_slice[tile_idx] = true;
588 95 ret = pps_one_tile_slices(pps, tile_idx, i, &off);
589
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 95 times.
95 if (ret < 0)
590 return ret;
591 95 i = ret;
592 } else {
593 63 ret = pps_multi_tiles_slice(pps, tile_idx, i, &off, tile_in_slice);
594
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
63 if (ret < 0)
595 return ret;
596 }
597 158 tile_idx = next_tile_idx(tile_idx, i, r);
598 }
599
600
2/2
✓ Branch 0 taken 509 times.
✓ Branch 1 taken 32 times.
541 for (int i = 0; i < r->num_tiles_in_pic; i++) {
601
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 509 times.
509 if (!tile_in_slice[i])
602 return AVERROR_INVALIDDATA;
603 }
604
605 32 return 0;
606 }
607
608 163 static int pps_no_rect_slice(VVCPPS* pps)
609 {
610 163 const H266RawPPS* r = pps->r;
611 163 int rx, ry, off = 0;
612
613
2/2
✓ Branch 0 taken 171 times.
✓ Branch 1 taken 163 times.
334 for (int tile_y = 0; tile_y < r->num_tile_rows; tile_y++) {
614
2/2
✓ Branch 0 taken 211 times.
✓ Branch 1 taken 171 times.
382 for (int tile_x = 0; tile_x < r->num_tile_columns; tile_x++) {
615 int ret;
616 211 ctu_xy(&rx, &ry, tile_x, tile_y, pps);
617 211 ret = pps_add_ctus(pps, &off, rx, ry, r->col_width_val[tile_x], r->row_height_val[tile_y]);
618
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 211 times.
211 if (ret < 0)
619 return ret;
620 }
621 }
622
623 163 return 0;
624 }
625
626 199 static int pps_slice_map(VVCPPS *pps, const VVCSPS *sps)
627 {
628 int ret;
629
630 199 pps->ctb_addr_in_slice = av_calloc(pps->ctb_count, sizeof(*pps->ctb_addr_in_slice));
631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 199 times.
199 if (!pps->ctb_addr_in_slice)
632 return AVERROR(ENOMEM);
633
634
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 163 times.
199 if (pps->r->pps_rect_slice_flag)
635 36 return pps_rect_slice(pps, sps);
636
637 163 ret = pps_no_rect_slice(pps);
638
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 163 times.
163 if (ret < 0)
639 return ret;
640
641 163 return 0;
642 }
643
644 199 static void pps_ref_wraparound_offset(VVCPPS *pps, const VVCSPS *sps)
645 {
646 199 const H266RawPPS *r = pps->r;
647
648
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 196 times.
199 if (r->pps_ref_wraparound_enabled_flag)
649 3 pps->ref_wraparound_offset = (pps->width / sps->min_cb_size_y) - r->pps_pic_width_minus_wraparound_offset;
650 199 }
651
652 199 static void pps_subpic(VVCPPS *pps, const VVCSPS *sps)
653 {
654 199 const H266RawSPS *rsps = sps->r;
655
2/2
✓ Branch 0 taken 279 times.
✓ Branch 1 taken 199 times.
478 for (int i = 0; i < rsps->sps_num_subpics_minus1 + 1; i++) {
656
2/2
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 170 times.
279 if (rsps->sps_subpic_treated_as_pic_flag[i]) {
657 109 pps->subpic_x[i] = rsps->sps_subpic_ctu_top_left_x[i] << sps->ctb_log2_size_y;
658 109 pps->subpic_y[i] = rsps->sps_subpic_ctu_top_left_y[i] << sps->ctb_log2_size_y;
659 109 pps->subpic_width[i] = FFMIN(pps->width - pps->subpic_x[i], (rsps->sps_subpic_width_minus1[i] + 1) << sps->ctb_log2_size_y);
660 109 pps->subpic_height[i] = FFMIN(pps->height - pps->subpic_y[i], (rsps->sps_subpic_height_minus1[i] + 1) << sps->ctb_log2_size_y);
661 } else {
662 170 pps->subpic_x[i] = 0;
663 170 pps->subpic_y[i] = 0;
664 170 pps->subpic_width[i] = pps->width;
665 170 pps->subpic_height[i] = pps->height;
666 }
667 }
668 199 }
669
670 199 static int pps_derive(VVCPPS *pps, const VVCSPS *sps)
671 {
672 int ret;
673
674 199 pps_chroma_qp_offset(pps);
675 199 pps_width_height(pps, sps);
676
677 199 ret = pps_bd(pps);
678
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 199 times.
199 if (ret < 0)
679 return ret;
680
681 199 ret = pps_slice_map(pps, sps);
682
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 199 times.
199 if (ret < 0)
683 return ret;
684
685 199 pps_ref_wraparound_offset(pps, sps);
686 199 pps_subpic(pps, sps);
687
688 199 return 0;
689 }
690
691 199 static void pps_free(AVRefStructOpaque opaque, void *obj)
692 {
693 199 VVCPPS *pps = obj;
694
695 199 av_refstruct_unref(&pps->r);
696
697 199 av_freep(&pps->col_bd);
698 199 av_freep(&pps->row_bd);
699 199 av_freep(&pps->ctb_to_col_bd);
700 199 av_freep(&pps->ctb_to_row_bd);
701 199 av_freep(&pps->ctb_addr_in_slice);
702 199 }
703
704 199 static const VVCPPS *pps_alloc(const H266RawPPS *rpps, const VVCSPS *sps)
705 {
706 int ret;
707 199 VVCPPS *pps = av_refstruct_alloc_ext(sizeof(*pps), 0, NULL, pps_free);
708
709
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 199 times.
199 if (!pps)
710 return NULL;
711
712 199 av_refstruct_replace(&pps->r, rpps);
713
714 199 ret = pps_derive(pps, sps);
715
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 199 times.
199 if (ret < 0)
716 goto fail;
717
718 199 return pps;
719
720 fail:
721 av_refstruct_unref(&pps);
722 return NULL;
723 }
724
725 1066 static int decode_pps(VVCParamSets *ps, const H266RawPPS *rpps)
726 {
727 1066 int ret = 0;
728 1066 const int pps_id = rpps->pps_pic_parameter_set_id;
729 1066 const int sps_id = rpps->pps_seq_parameter_set_id;
730 1066 const VVCPPS *old_pps = ps->pps_list[pps_id];
731 const VVCPPS *pps;
732
733
4/4
✓ Branch 0 taken 949 times.
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 867 times.
✓ Branch 3 taken 82 times.
1066 if (old_pps && old_pps->r == rpps)
734 867 return 0;
735
736 199 pps = pps_alloc(rpps, ps->sps_list[sps_id]);
737
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 199 times.
199 if (!pps)
738 return AVERROR(ENOMEM);
739
740 199 av_refstruct_unref(&ps->pps_list[pps_id]);
741 199 ps->pps_list[pps_id] = pps;
742
743 199 return ret;
744 }
745
746 1066 static int decode_ps(VVCParamSets *ps, AVCodecContext *c, const CodedBitstreamH266Context *h266, int is_clvss)
747 {
748 1066 const H266RawPictureHeader *ph = h266->ph;
749 const H266RawPPS *rpps;
750 const H266RawSPS *rsps;
751 int ret;
752
753
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
1066 if (!ph)
754 return AVERROR_INVALIDDATA;
755
756 1066 rpps = h266->pps[ph->ph_pic_parameter_set_id];
757
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
1066 if (!rpps)
758 return AVERROR_INVALIDDATA;
759
760 1066 rsps = h266->sps[rpps->pps_seq_parameter_set_id];
761
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
1066 if (!rsps)
762 return AVERROR_INVALIDDATA;
763
764 1066 ret = decode_sps(ps, c, rsps, is_clvss);
765
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
1066 if (ret < 0)
766 return ret;
767
768
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
1066 if (rsps->sps_log2_ctu_size_minus5 > 2) {
769 // CTU > 128 are reserved in vvc spec v3
770 av_log(c, AV_LOG_ERROR, "CTU size > 128. \n");
771 return AVERROR_PATCHWELCOME;
772 }
773
774 1066 ret = decode_pps(ps, rpps);
775
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
1066 if (ret < 0)
776 return ret;
777
778 1066 return 0;
779 }
780
781 #define WEIGHT_TABLE(x) \
782 w->nb_weights[L##x] = r->num_weights_l##x; \
783 for (int i = 0; i < w->nb_weights[L##x]; i++) { \
784 w->weight_flag[L##x][LUMA][i] = r->luma_weight_l##x##_flag[i]; \
785 w->weight_flag[L##x][CHROMA][i] = r->chroma_weight_l##x##_flag[i]; \
786 w->weight[L##x][LUMA][i] = denom[LUMA] + r->delta_luma_weight_l##x[i]; \
787 w->offset[L##x][LUMA][i] = r->luma_offset_l##x[i]; \
788 for (int j = CB; j <= CR; j++) { \
789 w->weight[L##x][j][i] = denom[CHROMA] + r->delta_chroma_weight_l##x[i][j - 1]; \
790 w->offset[L##x][j][i] = 128 + r->delta_chroma_offset_l##x[i][j - 1]; \
791 w->offset[L##x][j][i] -= (128 * w->weight[L##x][j][i]) >> w->log2_denom[CHROMA]; \
792 w->offset[L##x][j][i] = av_clip_intp2(w->offset[L##x][j][i], 7); \
793 } \
794 } \
795
796 73 static void pred_weight_table(PredWeightTable *w, const H266RawPredWeightTable *r)
797 {
798 int denom[2];
799
800 73 w->log2_denom[LUMA] = r->luma_log2_weight_denom;
801 73 w->log2_denom[CHROMA] = w->log2_denom[LUMA] + r->delta_chroma_log2_weight_denom;
802 73 denom[LUMA] = 1 << w->log2_denom[LUMA];
803 73 denom[CHROMA] = 1 << w->log2_denom[CHROMA];
804
4/4
✓ Branch 0 taken 830 times.
✓ Branch 1 taken 415 times.
✓ Branch 2 taken 415 times.
✓ Branch 3 taken 73 times.
1318 WEIGHT_TABLE(0)
805
4/4
✓ Branch 0 taken 710 times.
✓ Branch 1 taken 355 times.
✓ Branch 2 taken 355 times.
✓ Branch 3 taken 73 times.
1138 WEIGHT_TABLE(1)
806 73 }
807
808 // 8.3.1 Decoding process for picture order count
809 1066 static int ph_compute_poc(const H266RawPictureHeader *ph, const H266RawSPS *sps, const int poc_tid0, const int is_clvss)
810 {
811 1066 const int max_poc_lsb = 1 << (sps->sps_log2_max_pic_order_cnt_lsb_minus4 + 4);
812 1066 const int prev_poc_lsb = poc_tid0 % max_poc_lsb;
813 1066 const int prev_poc_msb = poc_tid0 - prev_poc_lsb;
814 1066 const int poc_lsb = ph->ph_pic_order_cnt_lsb;
815 int poc_msb;
816
817
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
1066 if (ph->ph_poc_msb_cycle_present_flag) {
818 poc_msb = ph->ph_poc_msb_cycle_val * max_poc_lsb;
819
2/2
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 957 times.
1066 } else if (is_clvss) {
820 109 poc_msb = 0;
821 } else {
822
3/4
✓ Branch 0 taken 598 times.
✓ Branch 1 taken 359 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 598 times.
957 if (poc_lsb < prev_poc_lsb && prev_poc_lsb - poc_lsb >= max_poc_lsb / 2)
823 poc_msb = prev_poc_msb + max_poc_lsb;
824
3/4
✓ Branch 0 taken 359 times.
✓ Branch 1 taken 598 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 359 times.
957 else if (poc_lsb > prev_poc_lsb && poc_lsb - prev_poc_lsb > max_poc_lsb / 2)
825 poc_msb = prev_poc_msb - max_poc_lsb;
826 else
827 957 poc_msb = prev_poc_msb;
828 }
829
830 1066 return poc_msb + poc_lsb;
831 }
832
833 774144 static av_always_inline uint16_t lmcs_derive_lut_sample(uint16_t sample,
834 uint16_t *pivot1, uint16_t *pivot2, uint16_t *scale_coeff, const int idx, const int max)
835 {
836 774144 const int lut_sample =
837 774144 pivot1[idx] + ((scale_coeff[idx] * (sample - pivot2[idx]) + (1<< 10)) >> 11);
838 774144 return av_clip(lut_sample, 0, max - 1);
839 }
840
841 //8.8.2.2 Inverse mapping process for a luma sample
842 378 static int lmcs_derive_lut(VVCLMCS *lmcs, const H266RawAPS *rlmcs, const H266RawSPS *sps)
843 {
844 378 const int bit_depth = (sps->sps_bitdepth_minus8 + 8);
845 378 const int max = (1 << bit_depth);
846 378 const int org_cw = max / LMCS_MAX_BIN_SIZE;
847 378 const int shift = av_log2(org_cw);
848 378 const int off = 1 << (shift - 1);
849 int cw[LMCS_MAX_BIN_SIZE];
850 uint16_t input_pivot[LMCS_MAX_BIN_SIZE];
851 uint16_t scale_coeff[LMCS_MAX_BIN_SIZE];
852 uint16_t inv_scale_coeff[LMCS_MAX_BIN_SIZE];
853 378 int i, delta_crs, sum_cw = 0;
854
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 378 times.
378 if (bit_depth > LMCS_MAX_BIT_DEPTH)
855 return AVERROR_PATCHWELCOME;
856
857
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 378 times.
378 if (!rlmcs)
858 return AVERROR_INVALIDDATA;
859
860 378 lmcs->min_bin_idx = rlmcs->lmcs_min_bin_idx;
861 378 lmcs->max_bin_idx = LMCS_MAX_BIN_SIZE - 1 - rlmcs->lmcs_delta_max_bin_idx;
862
863 378 memset(cw, 0, sizeof(cw));
864
2/2
✓ Branch 0 taken 5037 times.
✓ Branch 1 taken 378 times.
5415 for (int i = lmcs->min_bin_idx; i <= lmcs->max_bin_idx; i++) {
865 5037 cw[i] = org_cw + (1 - 2 * rlmcs->lmcs_delta_sign_cw_flag[i]) * rlmcs->lmcs_delta_abs_cw[i];
866 5037 sum_cw += cw[i];
867 }
868
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 378 times.
378 if (sum_cw > (1 << bit_depth) - 1)
869 return AVERROR_INVALIDDATA;
870
871 378 delta_crs = (1 - 2 * rlmcs->lmcs_delta_sign_crs_flag) * rlmcs->lmcs_delta_abs_crs;
872
873 378 lmcs->pivot[0] = 0;
874
2/2
✓ Branch 0 taken 6048 times.
✓ Branch 1 taken 378 times.
6426 for (i = 0; i < LMCS_MAX_BIN_SIZE; i++) {
875 6048 input_pivot[i] = i * org_cw;
876 6048 lmcs->pivot[i + 1] = lmcs->pivot[i] + cw[i];
877
4/4
✓ Branch 0 taken 5644 times.
✓ Branch 1 taken 404 times.
✓ Branch 2 taken 5037 times.
✓ Branch 3 taken 607 times.
6048 if (i >= lmcs->min_bin_idx && i <= lmcs->max_bin_idx &&
878
2/2
✓ Branch 0 taken 4456 times.
✓ Branch 1 taken 581 times.
5037 lmcs->pivot[i] % (1 << (bit_depth - 5)) != 0 &&
879
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4456 times.
4456 lmcs->pivot[i] >> (bit_depth - 5) == lmcs->pivot[i + 1] >> (bit_depth - 5))
880 return AVERROR_INVALIDDATA;
881 6048 scale_coeff[i] = (cw[i] * (1 << 11) + off) >> shift;
882
2/2
✓ Branch 0 taken 1011 times.
✓ Branch 1 taken 5037 times.
6048 if (cw[i] == 0) {
883 1011 inv_scale_coeff[i] = 0;
884 1011 lmcs->chroma_scale_coeff[i] = (1 << 11);
885 } else {
886 5037 const int cw_plus_d = cw[i] + delta_crs;
887
2/4
✓ Branch 0 taken 5037 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5037 times.
5037 if (cw_plus_d < (org_cw >> 3) || cw_plus_d > ((org_cw << 3) - 1))
888 return AVERROR_INVALIDDATA;
889 5037 inv_scale_coeff[i] = org_cw * (1 << 11) / cw[i];
890 5037 lmcs->chroma_scale_coeff[i] = org_cw * (1 << 11) / cw_plus_d;
891 }
892 }
893
894 //derive lmcs_fwd_lut
895
2/2
✓ Branch 0 taken 387072 times.
✓ Branch 1 taken 378 times.
387450 for (uint16_t sample = 0; sample < max; sample++) {
896 387072 const int idx_y = sample >> shift;
897 387072 const uint16_t fwd_sample = lmcs_derive_lut_sample(sample, lmcs->pivot,
898 input_pivot, scale_coeff, idx_y, max);
899
1/2
✓ Branch 0 taken 387072 times.
✗ Branch 1 not taken.
387072 if (bit_depth > 8)
900 387072 lmcs->fwd_lut.u16[sample] = fwd_sample;
901 else
902 lmcs->fwd_lut.u8 [sample] = fwd_sample;
903
904 }
905
906 //derive lmcs_inv_lut
907 378 i = lmcs->min_bin_idx;
908
2/2
✓ Branch 0 taken 387072 times.
✓ Branch 1 taken 378 times.
387450 for (uint16_t sample = 0; sample < max; sample++) {
909 uint16_t inv_sample;
910
4/4
✓ Branch 0 taken 375898 times.
✓ Branch 1 taken 16211 times.
✓ Branch 2 taken 5037 times.
✓ Branch 3 taken 370861 times.
392109 while (i <= lmcs->max_bin_idx && sample >= lmcs->pivot[i + 1])
911 5037 i++;
912 387072 i = FFMIN(i, LMCS_MAX_BIN_SIZE - 1);
913
914 387072 inv_sample = lmcs_derive_lut_sample(sample, input_pivot, lmcs->pivot,
915 inv_scale_coeff, i, max);
916
917
1/2
✓ Branch 0 taken 387072 times.
✗ Branch 1 not taken.
387072 if (bit_depth > 8)
918 387072 lmcs->inv_lut.u16[sample] = inv_sample;
919 else
920 lmcs->inv_lut.u8 [sample] = inv_sample;
921 }
922
923 378 return 0;
924 }
925
926 1066 static int ph_max_num_subblock_merge_cand(const H266RawSPS *sps, const H266RawPictureHeader *ph)
927 {
928
2/2
✓ Branch 0 taken 1061 times.
✓ Branch 1 taken 5 times.
1066 if (sps->sps_affine_enabled_flag)
929 1061 return 5 - sps->sps_five_minus_max_num_subblock_merge_cand;
930
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5 return sps->sps_sbtmvp_enabled_flag && ph->ph_temporal_mvp_enabled_flag;
931 }
932
933 42 static int ph_vb_pos(uint16_t *vbs, uint8_t *num_vbs, const uint16_t *pos_minus_1, const uint8_t num_pos, uint16_t max, const int ctb_size_y)
934 {
935 42 max = FF_CEIL_RSHIFT(max, 3) - 2;
936
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 for (int i = 0; i < num_pos; i++) {
937 if (pos_minus_1[i] > max)
938 return AVERROR_INVALIDDATA;
939
940 vbs[i] = (pos_minus_1[i] + 1) << 3;
941
942 // The distance between any two vertical virtual boundaries shall be greater than or equal to CtbSizeY luma samples
943 if (i && vbs[i] < vbs[i - 1] + ctb_size_y)
944 return AVERROR_INVALIDDATA;
945 }
946 42 *num_vbs = num_pos;
947
948 42 return 0;
949 }
950
951 #define VBF(f) (sps->sps_virtual_boundaries_present_flag ? sps->sps_##f : ph->r->ph_##f)
952 #define VBFS(c, d) VBF(virtual_boundary_pos_##c##_minus1), VBF(num_##d##_virtual_boundaries)
953
954 1066 static int ph_vb(VVCPH *ph, const H266RawSPS *sps, const H266RawPPS *pps)
955 {
956 1066 const int ctb_size_y = 1 << (sps->sps_log2_ctu_size_minus5 + 5);
957 int ret;
958
959
2/2
✓ Branch 0 taken 1045 times.
✓ Branch 1 taken 21 times.
1066 if (!sps->sps_virtual_boundaries_enabled_flag)
960 1045 return 0;
961
962
2/4
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
21 ret = ph_vb_pos(ph->vb_pos_x, &ph->num_ver_vbs, VBFS(x, ver), pps->pps_pic_width_in_luma_samples, ctb_size_y);
963
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (ret < 0)
964 return ret;
965
966
2/4
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
21 ret = ph_vb_pos(ph->vb_pos_y, &ph->num_hor_vbs, VBFS(y, hor), pps->pps_pic_height_in_luma_samples, ctb_size_y);
967
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (ret < 0)
968 return ret;
969
970 21 return 0;
971 }
972
973 1066 static int ph_derive(VVCPH *ph, const H266RawSPS *sps, const H266RawPPS *pps, const int poc_tid0, const int is_clvss)
974 {
975 int ret;
976 1066 ph->max_num_subblock_merge_cand = ph_max_num_subblock_merge_cand(sps, ph->r);
977
978 1066 ph->poc = ph_compute_poc(ph->r, sps, poc_tid0, is_clvss);
979
980
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
1066 if (pps->pps_wp_info_in_ph_flag)
981 pred_weight_table(&ph->pwt, &ph->r->ph_pred_weight_table);
982
983 1066 ret = ph_vb(ph, sps, pps);
984
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
1066 if (ret < 0)
985 return ret;
986
987 1066 return 0;
988 }
989
990 1066 static int decode_ph(VVCFrameParamSets *fps, const H266RawPictureHeader *rph, void *rph_ref,
991 const int poc_tid0, const int is_clvss)
992 {
993 int ret;
994 1066 VVCPH *ph = &fps->ph;
995 1066 const H266RawSPS *sps = fps->sps->r;
996 1066 const H266RawPPS *pps = fps->pps->r;
997
998 1066 ph->r = rph;
999 1066 av_refstruct_replace(&ph->rref, rph_ref);
1000 1066 ret = ph_derive(ph, sps, pps, poc_tid0, is_clvss);
1001
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
1066 if (ret < 0)
1002 return ret;
1003
1004 1066 return 0;
1005 }
1006
1007 1066 static int decode_frame_ps(VVCFrameParamSets *fps, const VVCParamSets *ps,
1008 const CodedBitstreamH266Context *h266, const int poc_tid0, const int is_clvss)
1009 {
1010 1066 const H266RawPictureHeader *ph = h266->ph;
1011 const H266RawPPS *rpps;
1012 int ret;
1013
1014
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
1066 if (!ph)
1015 return AVERROR_INVALIDDATA;
1016
1017 1066 rpps = h266->pps[ph->ph_pic_parameter_set_id];
1018
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
1066 if (!rpps)
1019 return AVERROR_INVALIDDATA;
1020
1021 1066 av_refstruct_replace(&fps->sps, ps->sps_list[rpps->pps_seq_parameter_set_id]);
1022 1066 av_refstruct_replace(&fps->pps, ps->pps_list[rpps->pps_pic_parameter_set_id]);
1023
1024 1066 ret = decode_ph(fps, ph, h266->ph_ref, poc_tid0, is_clvss);
1025
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
1066 if (ret < 0)
1026 return ret;
1027
1028
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 929 times.
1066 if (ph->ph_explicit_scaling_list_enabled_flag)
1029 137 av_refstruct_replace(&fps->sl, ps->scaling_list[ph->ph_scaling_list_aps_id]);
1030
1031
2/2
✓ Branch 0 taken 378 times.
✓ Branch 1 taken 688 times.
1066 if (ph->ph_lmcs_enabled_flag) {
1032 378 ret = lmcs_derive_lut(&fps->lmcs, ps->lmcs_list[ph->ph_lmcs_aps_id], fps->sps->r);
1033
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 378 times.
378 if (ret < 0)
1034 return ret;
1035 }
1036
1037
2/2
✓ Branch 0 taken 8528 times.
✓ Branch 1 taken 1066 times.
9594 for (int i = 0; i < FF_ARRAY_ELEMS(fps->alf_list); i++)
1038 8528 av_refstruct_replace(&fps->alf_list[i], ps->alf_list[i]);
1039
1040 1066 return 0;
1041 }
1042
1043 1066 static void decode_recovery_flag(VVCContext *s)
1044 {
1045
4/4
✓ Branch 0 taken 1059 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 96 times.
✓ Branch 3 taken 963 times.
1066 if (IS_IDR(s))
1046 103 s->no_output_before_recovery_flag = 1;
1047
4/4
✓ Branch 0 taken 951 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 948 times.
963 else if (IS_CRA(s) || IS_GDR(s))
1048 15 s->no_output_before_recovery_flag = s->last_eos;
1049 1066 }
1050
1051 1066 static void decode_recovery_poc(VVCContext *s, const VVCPH *ph)
1052 {
1053
2/2
✓ Branch 0 taken 865 times.
✓ Branch 1 taken 201 times.
1066 if (s->no_output_before_recovery_flag) {
1054
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 862 times.
865 if (IS_GDR(s))
1055 3 s->gdr_recovery_point_poc = ph->poc + ph->r->ph_recovery_poc_cnt;
1056
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 862 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
865 if (!GDR_IS_RECOVERED(s) && s->gdr_recovery_point_poc <= ph->poc)
1057 3 GDR_SET_RECOVERED(s);
1058 }
1059 1066 }
1060
1061 1066 int ff_vvc_decode_frame_ps(VVCFrameParamSets *fps, struct VVCContext *s)
1062 {
1063 1066 int ret = 0;
1064 1066 VVCParamSets *ps = &s->ps;
1065 1066 const CodedBitstreamH266Context *h266 = s->cbc->priv_data;
1066 int is_clvss;
1067
1068 1066 decode_recovery_flag(s);
1069
10/10
✓ Branch 0 taken 1059 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 963 times.
✓ Branch 3 taken 96 times.
✓ Branch 4 taken 951 times.
✓ Branch 5 taken 12 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 948 times.
✓ Branch 8 taken 109 times.
✓ Branch 9 taken 9 times.
1066 is_clvss = IS_CLVSS(s);
1070
1071 1066 ret = decode_ps(ps, s->avctx, h266, is_clvss);
1072
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
1066 if (ret < 0)
1073 return ret;
1074
1075 1066 ret = decode_frame_ps(fps, ps, h266, s->poc_tid0, is_clvss);
1076 1066 decode_recovery_poc(s, &fps->ph);
1077 1066 return ret;
1078 }
1079
1080 752 void ff_vvc_frame_ps_free(VVCFrameParamSets *fps)
1081 {
1082 752 av_refstruct_unref(&fps->sps);
1083 752 av_refstruct_unref(&fps->pps);
1084 752 av_refstruct_unref(&fps->ph.rref);
1085 752 av_refstruct_unref(&fps->sl);
1086
2/2
✓ Branch 0 taken 6016 times.
✓ Branch 1 taken 752 times.
6768 for (int i = 0; i < FF_ARRAY_ELEMS(fps->alf_list); i++)
1087 6016 av_refstruct_unref(&fps->alf_list[i]);
1088 752 }
1089
1090 94 void ff_vvc_ps_uninit(VVCParamSets *ps)
1091 {
1092
2/2
✓ Branch 0 taken 752 times.
✓ Branch 1 taken 94 times.
846 for (int i = 0; i < FF_ARRAY_ELEMS(ps->scaling_list); i++)
1093 752 av_refstruct_unref(&ps->scaling_list[i]);
1094
2/2
✓ Branch 0 taken 376 times.
✓ Branch 1 taken 94 times.
470 for (int i = 0; i < FF_ARRAY_ELEMS(ps->lmcs_list); i++)
1095 376 av_refstruct_unref(&ps->lmcs_list[i]);
1096
2/2
✓ Branch 0 taken 752 times.
✓ Branch 1 taken 94 times.
846 for (int i = 0; i < FF_ARRAY_ELEMS(ps->alf_list); i++)
1097 752 av_refstruct_unref(&ps->alf_list[i]);
1098
2/2
✓ Branch 0 taken 1504 times.
✓ Branch 1 taken 94 times.
1598 for (int i = 0; i < FF_ARRAY_ELEMS(ps->sps_list); i++)
1099 1504 av_refstruct_unref(&ps->sps_list[i]);
1100
2/2
✓ Branch 0 taken 6016 times.
✓ Branch 1 taken 94 times.
6110 for (int i = 0; i < FF_ARRAY_ELEMS(ps->pps_list); i++)
1101 6016 av_refstruct_unref(&ps->pps_list[i]);
1102 94 }
1103
1104 7603 static void alf_coeff(int16_t *coeff,
1105 const uint8_t *abs, const uint8_t *sign, const int size)
1106 {
1107
2/2
✓ Branch 0 taken 86868 times.
✓ Branch 1 taken 7603 times.
94471 for (int i = 0; i < size; i++)
1108 86868 coeff[i] = (1 - 2 * sign[i]) * abs[i];
1109 7603 }
1110
1111 830 static void alf_coeff_cc(int16_t *coeff,
1112 const uint8_t *mapped_abs, const uint8_t *sign)
1113 {
1114
2/2
✓ Branch 0 taken 5810 times.
✓ Branch 1 taken 830 times.
6640 for (int i = 0; i < ALF_NUM_COEFF_CC; i++) {
1115 5810 int c = mapped_abs[i];
1116
2/2
✓ Branch 0 taken 4996 times.
✓ Branch 1 taken 814 times.
5810 if (c)
1117 4996 c = (1 - 2 * sign[i]) * (1 << (c - 1));
1118 5810 coeff[i] = c;
1119 }
1120 830 }
1121
1122 326 static void alf_luma(VVCALF *alf, const H266RawAPS *aps)
1123 {
1124
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 275 times.
326 if (!aps->alf_luma_filter_signal_flag)
1125 51 return;
1126
1127
2/2
✓ Branch 0 taken 6875 times.
✓ Branch 1 taken 275 times.
7150 for (int i = 0; i < ALF_NUM_FILTERS_LUMA; i++) {
1128 6875 const int ref = aps->alf_luma_coeff_delta_idx[i];
1129 6875 const uint8_t *abs = aps->alf_luma_coeff_abs[ref];
1130 6875 const uint8_t *sign = aps->alf_luma_coeff_sign[ref];
1131
1132 6875 alf_coeff(alf->luma_coeff[i], abs, sign, ALF_NUM_COEFF_LUMA);
1133 6875 memcpy(alf->luma_clip_idx[i], aps->alf_luma_clip_idx[ref],
1134 sizeof(alf->luma_clip_idx[i]));
1135 }
1136 }
1137
1138 326 static void alf_chroma(VVCALF *alf, const H266RawAPS *aps)
1139 {
1140
2/2
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 236 times.
326 if (!aps->alf_chroma_filter_signal_flag)
1141 90 return;
1142
1143 236 alf->num_chroma_filters = aps->alf_chroma_num_alt_filters_minus1 + 1;
1144
2/2
✓ Branch 0 taken 728 times.
✓ Branch 1 taken 236 times.
964 for (int i = 0; i < alf->num_chroma_filters; i++) {
1145 728 const uint8_t *abs = aps->alf_chroma_coeff_abs[i];
1146 728 const uint8_t *sign = aps->alf_chroma_coeff_sign[i];
1147
1148 728 alf_coeff(alf->chroma_coeff[i], abs, sign, ALF_NUM_COEFF_CHROMA);
1149 728 memcpy(alf->chroma_clip_idx[i], aps->alf_chroma_clip_idx[i],
1150 sizeof(alf->chroma_clip_idx[i]));
1151 }
1152 }
1153
1154 326 static void alf_cc(VVCALF *alf, const H266RawAPS *aps)
1155 {
1156 326 const uint8_t (*abs[])[ALF_NUM_COEFF_CC] =
1157 326 { aps->alf_cc_cb_mapped_coeff_abs, aps->alf_cc_cr_mapped_coeff_abs };
1158 326 const uint8_t (*sign[])[ALF_NUM_COEFF_CC] =
1159 326 {aps->alf_cc_cb_coeff_sign, aps->alf_cc_cr_coeff_sign };
1160 326 const int signaled[] = { aps->alf_cc_cb_filter_signal_flag, aps->alf_cc_cr_filter_signal_flag};
1161
1162 326 alf->num_cc_filters[0] = aps->alf_cc_cb_filters_signalled_minus1 + 1;
1163 326 alf->num_cc_filters[1] = aps->alf_cc_cr_filters_signalled_minus1 + 1;
1164
1165
2/2
✓ Branch 0 taken 652 times.
✓ Branch 1 taken 326 times.
978 for (int idx = 0; idx < 2; idx++) {
1166
2/2
✓ Branch 0 taken 276 times.
✓ Branch 1 taken 376 times.
652 if (signaled[idx]) {
1167
2/2
✓ Branch 0 taken 830 times.
✓ Branch 1 taken 276 times.
1106 for (int i = 0; i < alf->num_cc_filters[idx]; i++)
1168 830 alf_coeff_cc(alf->cc_coeff[idx][i], abs[idx][i], sign[idx][i]);
1169 }
1170 }
1171 326 }
1172
1173 326 static void alf_derive(VVCALF *alf, const H266RawAPS *aps)
1174 {
1175 326 alf_luma(alf, aps);
1176 326 alf_chroma(alf, aps);
1177 326 alf_cc(alf, aps);
1178 326 }
1179
1180 326 static void alf_free(AVRefStructOpaque unused, void *obj)
1181 {
1182 326 VVCALF *alf = obj;
1183
1184 326 av_refstruct_unref(&alf->r);
1185 326 }
1186
1187 326 static int aps_decode_alf(const VVCALF **alf, const H266RawAPS *aps)
1188 {
1189 326 VVCALF *a = av_refstruct_alloc_ext(sizeof(*a), 0, NULL, alf_free);
1190
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 326 times.
326 if (!a)
1191 return AVERROR(ENOMEM);
1192
1193 326 alf_derive(a, aps);
1194 326 av_refstruct_replace(&a->r, aps);
1195 326 av_refstruct_replace(alf, a);
1196 326 av_refstruct_unref(&a);
1197
1198 326 return 0;
1199 }
1200
1201 280 static int is_luma_list(const int id)
1202 {
1203
4/4
✓ Branch 0 taken 190 times.
✓ Branch 1 taken 90 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 180 times.
280 return id % VVC_MAX_SAMPLE_ARRAYS == SL_START_4x4 || id == SL_START_64x64 + 1;
1204 }
1205
1206 448 static int derive_matrix_size(const int id)
1207 {
1208
4/4
✓ Branch 0 taken 416 times.
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 96 times.
✓ Branch 3 taken 320 times.
448 return id < SL_START_4x4 ? 2 : (id < SL_START_8x8 ? 4 : 8);
1209 }
1210
1211 // 7.4.3.20 Scaling list data semantics
1212 16 static void scaling_derive(VVCScalingList *sl, const H266RawAPS *aps)
1213 {
1214
2/2
✓ Branch 0 taken 448 times.
✓ Branch 1 taken 16 times.
464 for (int id = 0; id < SL_MAX_ID; id++) {
1215 448 const int matrix_size = derive_matrix_size(id);
1216 448 const int log2_size = av_log2(matrix_size);
1217 448 const int list_size = matrix_size * matrix_size;
1218 int coeff[SL_MAX_MATRIX_SIZE * SL_MAX_MATRIX_SIZE];
1219 const uint8_t *pred;
1220 const int *scaling_list;
1221 448 int dc = 0;
1222
1223
4/4
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 168 times.
✓ Branch 3 taken 100 times.
✓ Branch 4 taken 180 times.
448 if (aps->aps_chroma_present_flag || is_luma_list(id)) {
1224
2/2
✓ Branch 0 taken 122 times.
✓ Branch 1 taken 146 times.
268 if (!aps->scaling_list_copy_mode_flag[id]) {
1225 122 int next_coef = 0;
1226
1227
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 86 times.
122 if (id >= SL_START_16x16)
1228 36 dc = next_coef = aps->scaling_list_dc_coef[id - SL_START_16x16];
1229
1230
2/2
✓ Branch 0 taken 5504 times.
✓ Branch 1 taken 122 times.
5626 for (int i = 0; i < list_size; i++) {
1231 5504 const int x = ff_vvc_diag_scan_x[3][3][i];
1232 5504 const int y = ff_vvc_diag_scan_y[3][3][i];
1233
1234
6/6
✓ Branch 0 taken 384 times.
✓ Branch 1 taken 5120 times.
✓ Branch 2 taken 192 times.
✓ Branch 3 taken 192 times.
✓ Branch 4 taken 96 times.
✓ Branch 5 taken 96 times.
5504 if (!(id >= SL_START_64x64 && x >= 4 && y >= 4))
1235 5408 next_coef += aps->scaling_list_delta_coef[id][i];
1236 5504 coeff[i] = next_coef;
1237 }
1238 }
1239 }
1240
1241 //dc
1242
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 224 times.
448 if (id >= SL_START_16x16) {
1243
4/4
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 188 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 32 times.
224 if (!aps->scaling_list_copy_mode_flag[id] && !aps->scaling_list_pred_mode_flag[id]) {
1244 4 dc += 8;
1245
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 140 times.
220 } else if (!aps->scaling_list_pred_id_delta[id]) {
1246 80 dc += 16;
1247 } else {
1248 140 const int ref_id = id - aps->scaling_list_pred_id_delta[id];
1249
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 46 times.
140 if (ref_id >= SL_START_16x16)
1250 94 dc += sl->scaling_matrix_dc_rec[ref_id - SL_START_16x16];
1251 else
1252 46 dc += sl->scaling_matrix_rec[ref_id][0];
1253 }
1254 224 sl->scaling_matrix_dc_rec[id - SL_START_16x16] = dc & 255;
1255 }
1256
1257 //ac
1258
2/2
✓ Branch 0 taken 122 times.
✓ Branch 1 taken 326 times.
448 scaling_list = aps->scaling_list_copy_mode_flag[id] ? ff_vvc_scaling_list0 : coeff;
1259
4/4
✓ Branch 0 taken 122 times.
✓ Branch 1 taken 326 times.
✓ Branch 2 taken 46 times.
✓ Branch 3 taken 76 times.
448 if (!aps->scaling_list_copy_mode_flag[id] && !aps->scaling_list_pred_mode_flag[id])
1260 46 pred = ff_vvc_scaling_pred_8;
1261
2/2
✓ Branch 0 taken 194 times.
✓ Branch 1 taken 208 times.
402 else if (!aps->scaling_list_pred_id_delta[id])
1262 194 pred = ff_vvc_scaling_pred_16;
1263 else
1264 208 pred = sl->scaling_matrix_rec[id - aps->scaling_list_pred_id_delta[id]];
1265
2/2
✓ Branch 0 taken 22144 times.
✓ Branch 1 taken 448 times.
22592 for (int i = 0; i < list_size; i++) {
1266 22144 const int x = ff_vvc_diag_scan_x[log2_size][log2_size][i];
1267 22144 const int y = ff_vvc_diag_scan_y[log2_size][log2_size][i];
1268 22144 const int off = y * matrix_size + x;
1269 22144 sl->scaling_matrix_rec[id][off] = (pred[off] + scaling_list[i]) & 255;
1270 }
1271 }
1272 16 }
1273
1274 16 static int aps_decode_scaling(const VVCScalingList **scaling, const H266RawAPS *aps)
1275 {
1276 16 VVCScalingList *sl = av_refstruct_allocz(sizeof(*sl));
1277
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (!sl)
1278 return AVERROR(ENOMEM);
1279
1280 16 scaling_derive(sl, aps);
1281 16 av_refstruct_replace(scaling, sl);
1282 16 av_refstruct_unref(&sl);
1283
1284 16 return 0;
1285 }
1286
1287 427 int ff_vvc_decode_aps(VVCParamSets *ps, const CodedBitstreamUnit *unit)
1288 {
1289 427 const H266RawAPS *aps = unit->content_ref;
1290 427 int ret = 0;
1291
1292
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 427 times.
427 if (!aps)
1293 return AVERROR_INVALIDDATA;
1294
1295
3/4
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 85 times.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
427 switch (aps->aps_params_type) {
1296 326 case VVC_ASP_TYPE_ALF:
1297 326 ret = aps_decode_alf(&ps->alf_list[aps->aps_adaptation_parameter_set_id], aps);
1298 326 break;
1299 85 case VVC_ASP_TYPE_LMCS:
1300 85 av_refstruct_replace(&ps->lmcs_list[aps->aps_adaptation_parameter_set_id], aps);
1301 85 break;
1302 16 case VVC_ASP_TYPE_SCALING:
1303 16 ret = aps_decode_scaling(&ps->scaling_list[aps->aps_adaptation_parameter_set_id], aps);
1304 16 break;
1305 }
1306
1307 427 return ret;
1308 }
1309
1310 1831 static int sh_alf_aps(const VVCSH *sh, const VVCFrameParamSets *fps)
1311 {
1312
2/2
✓ Branch 0 taken 422 times.
✓ Branch 1 taken 1409 times.
1831 if (!sh->r->sh_alf_enabled_flag)
1313 422 return 0;
1314
1315
2/2
✓ Branch 0 taken 1735 times.
✓ Branch 1 taken 1409 times.
3144 for (int i = 0; i < sh->r->sh_num_alf_aps_ids_luma; i++) {
1316 1735 const VVCALF *alf_aps_luma = fps->alf_list[sh->r->sh_alf_aps_id_luma[i]];
1317
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1735 times.
1735 if (!alf_aps_luma)
1318 return AVERROR_INVALIDDATA;
1319 }
1320
1321
4/4
✓ Branch 0 taken 753 times.
✓ Branch 1 taken 656 times.
✓ Branch 2 taken 152 times.
✓ Branch 3 taken 601 times.
1409 if (sh->r->sh_alf_cb_enabled_flag || sh->r->sh_alf_cr_enabled_flag) {
1322 808 const VVCALF *alf_aps_chroma = fps->alf_list[sh->r->sh_alf_aps_id_chroma];
1323
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 808 times.
808 if (!alf_aps_chroma)
1324 return AVERROR_INVALIDDATA;
1325 }
1326
1327
2/2
✓ Branch 0 taken 1350 times.
✓ Branch 1 taken 59 times.
1409 if (fps->sps->r->sps_ccalf_enabled_flag) {
1328
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 1134 times.
1350 if (sh->r->sh_alf_cc_cb_enabled_flag) {
1329 216 const VVCALF *alf_aps_cc_cr = fps->alf_list[sh->r->sh_alf_cc_cb_aps_id];
1330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if (!alf_aps_cc_cr)
1331 return AVERROR_INVALIDDATA;
1332 }
1333
2/2
✓ Branch 0 taken 188 times.
✓ Branch 1 taken 1162 times.
1350 if (sh->r->sh_alf_cc_cr_enabled_flag) {
1334 188 const VVCALF *alf_aps_cc_cr = fps->alf_list[sh->r->sh_alf_cc_cr_aps_id];
1335
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 188 times.
188 if (!alf_aps_cc_cr)
1336 return AVERROR_INVALIDDATA;
1337 }
1338 }
1339
1340 1409 return 0;
1341 }
1342
1343 1831 static int sh_slice_address(VVCSH *sh, const H266RawSPS *sps, const VVCPPS *pps)
1344 {
1345 1831 const int slice_address = sh->r->sh_slice_address;
1346
1347
2/2
✓ Branch 0 taken 684 times.
✓ Branch 1 taken 1147 times.
1831 if (pps->r->pps_rect_slice_flag) {
1348 684 int pic_level_slice_idx = slice_address;
1349
2/2
✓ Branch 0 taken 1047 times.
✓ Branch 1 taken 684 times.
1731 for (int j = 0; j < sh->r->curr_subpic_idx; j++)
1350 1047 pic_level_slice_idx += pps->r->num_slices_in_subpic[j];
1351 684 sh->ctb_addr_in_curr_slice = pps->ctb_addr_in_slice + pps->slice_start_offset[pic_level_slice_idx];
1352 684 sh->num_ctus_in_curr_slice = pps->num_ctus_in_slice[pic_level_slice_idx];
1353 } else {
1354 1147 int tile_x = slice_address % pps->r->num_tile_columns;
1355 1147 int tile_y = slice_address / pps->r->num_tile_columns;
1356 1147 const int slice_start_ctb = pps->row_bd[tile_y] * pps->ctb_width + pps->col_bd[tile_x] * pps->r->row_height_val[tile_y];
1357
1358 1147 sh->ctb_addr_in_curr_slice = pps->ctb_addr_in_slice + slice_start_ctb;
1359
1360 1147 sh->num_ctus_in_curr_slice = 0;
1361
2/2
✓ Branch 0 taken 1227 times.
✓ Branch 1 taken 1147 times.
2374 for (int tile_idx = slice_address; tile_idx <= slice_address + sh->r->sh_num_tiles_in_slice_minus1; tile_idx++) {
1362 1227 tile_x = tile_idx % pps->r->num_tile_columns;
1363 1227 tile_y = tile_idx / pps->r->num_tile_columns;
1364 1227 sh->num_ctus_in_curr_slice += pps->r->row_height_val[tile_y] * pps->r->col_width_val[tile_x];
1365 }
1366 }
1367
1368
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1831 times.
1831 if (!sh->num_ctus_in_curr_slice)
1369 return AVERROR_INVALIDDATA;
1370
1371 1831 return 0;
1372 }
1373
1374 1831 static void sh_qp_y(VVCSH *sh, const H266RawPPS *pps, const H266RawPictureHeader *ph)
1375 {
1376 1831 const int init_qp = pps->pps_init_qp_minus26 + 26;
1377
1378
2/2
✓ Branch 0 taken 1561 times.
✓ Branch 1 taken 270 times.
1831 if (!pps->pps_qp_delta_info_in_ph_flag)
1379 1561 sh->slice_qp_y = init_qp + sh->r->sh_qp_delta;
1380 else
1381 270 sh->slice_qp_y = init_qp + ph->ph_qp_delta;
1382 1831 }
1383
1384 1831 static void sh_inter(VVCSH *sh, const H266RawSPS *sps, const H266RawPPS *pps)
1385 {
1386 1831 const H266RawSliceHeader *rsh = sh->r;
1387
1388
1/2
✓ Branch 0 taken 1831 times.
✗ Branch 1 not taken.
1831 if (!pps->pps_wp_info_in_ph_flag &&
1389
4/4
✓ Branch 0 taken 82 times.
✓ Branch 1 taken 1749 times.
✓ Branch 2 taken 70 times.
✓ Branch 3 taken 12 times.
1831 ((pps->pps_weighted_pred_flag && IS_P(rsh)) ||
1390
4/4
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 1749 times.
✓ Branch 2 taken 61 times.
✓ Branch 3 taken 9 times.
1819 (pps->pps_weighted_bipred_flag && IS_B(rsh))))
1391 73 pred_weight_table(&sh->pwt, &rsh->sh_pred_weight_table);
1392 1831 }
1393
1394 1831 static void sh_deblock_offsets(VVCSH *sh)
1395 {
1396 1831 const H266RawSliceHeader *r = sh->r;
1397
1398
2/2
✓ Branch 0 taken 1830 times.
✓ Branch 1 taken 1 times.
1831 if (!r->sh_deblocking_filter_disabled_flag) {
1399 1830 sh->deblock.beta_offset[LUMA] = r->sh_luma_beta_offset_div2 * 2;
1400 1830 sh->deblock.tc_offset[LUMA] = r->sh_luma_tc_offset_div2 * 2;
1401 1830 sh->deblock.beta_offset[CB] = r->sh_cb_beta_offset_div2 * 2;
1402 1830 sh->deblock.tc_offset[CB] = r->sh_cb_tc_offset_div2 * 2;
1403 1830 sh->deblock.beta_offset[CR] = r->sh_cr_beta_offset_div2 * 2;
1404 1830 sh->deblock.tc_offset[CR] = r->sh_cr_tc_offset_div2 * 2;
1405 }
1406 1831 }
1407
1408 1831 static void sh_partition_constraints(VVCSH *sh, const H266RawSPS *sps, const H266RawPictureHeader *ph)
1409 {
1410 1831 const int min_cb_log2_size_y = sps->sps_log2_min_luma_coding_block_size_minus2 + 2;
1411 int min_qt_log2_size_y[2];
1412
1413
2/2
✓ Branch 0 taken 284 times.
✓ Branch 1 taken 1547 times.
1831 if (IS_I(sh->r)) {
1414 284 min_qt_log2_size_y[LUMA] = (min_cb_log2_size_y + ph->ph_log2_diff_min_qt_min_cb_intra_slice_luma);
1415 284 min_qt_log2_size_y[CHROMA] = (min_cb_log2_size_y + ph->ph_log2_diff_min_qt_min_cb_intra_slice_chroma);
1416
1417 284 sh->max_bt_size[LUMA] = 1 << (min_qt_log2_size_y[LUMA] + ph->ph_log2_diff_max_bt_min_qt_intra_slice_luma);
1418 284 sh->max_bt_size[CHROMA] = 1 << (min_qt_log2_size_y[CHROMA]+ ph->ph_log2_diff_max_bt_min_qt_intra_slice_chroma);
1419
1420 284 sh->max_tt_size[LUMA] = 1 << (min_qt_log2_size_y[LUMA] + ph->ph_log2_diff_max_tt_min_qt_intra_slice_luma);
1421 284 sh->max_tt_size[CHROMA] = 1 << (min_qt_log2_size_y[CHROMA]+ ph->ph_log2_diff_max_tt_min_qt_intra_slice_chroma);
1422
1423 284 sh->max_mtt_depth[LUMA] = ph->ph_max_mtt_hierarchy_depth_intra_slice_luma;
1424 284 sh->max_mtt_depth[CHROMA] = ph->ph_max_mtt_hierarchy_depth_intra_slice_chroma;
1425
1426 284 sh->cu_qp_delta_subdiv = ph->ph_cu_qp_delta_subdiv_intra_slice;
1427 284 sh->cu_chroma_qp_offset_subdiv = ph->ph_cu_chroma_qp_offset_subdiv_intra_slice;
1428 } else {
1429
2/2
✓ Branch 0 taken 3094 times.
✓ Branch 1 taken 1547 times.
4641 for (int i = LUMA; i <= CHROMA; i++) {
1430 3094 min_qt_log2_size_y[i] = (min_cb_log2_size_y + ph->ph_log2_diff_min_qt_min_cb_inter_slice);
1431 3094 sh->max_bt_size[i] = 1 << (min_qt_log2_size_y[i] + ph->ph_log2_diff_max_bt_min_qt_inter_slice);
1432 3094 sh->max_tt_size[i] = 1 << (min_qt_log2_size_y[i] + ph->ph_log2_diff_max_tt_min_qt_inter_slice);
1433 3094 sh->max_mtt_depth[i] = ph->ph_max_mtt_hierarchy_depth_inter_slice;
1434 }
1435
1436 1547 sh->cu_qp_delta_subdiv = ph->ph_cu_qp_delta_subdiv_inter_slice;
1437 1547 sh->cu_chroma_qp_offset_subdiv = ph->ph_cu_chroma_qp_offset_subdiv_inter_slice;
1438 }
1439
1440 1831 sh->min_qt_size[LUMA] = 1 << min_qt_log2_size_y[LUMA];
1441 1831 sh->min_qt_size[CHROMA] = 1 << min_qt_log2_size_y[CHROMA];
1442 1831 }
1443
1444 1831 static void sh_entry_points(VVCSH *sh, const H266RawSPS *sps, const VVCPPS *pps)
1445 {
1446
2/2
✓ Branch 0 taken 1737 times.
✓ Branch 1 taken 94 times.
1831 if (sps->sps_entry_point_offsets_present_flag) {
1447
2/2
✓ Branch 0 taken 49469 times.
✓ Branch 1 taken 1737 times.
51206 for (int i = 1, j = 0; i < sh->num_ctus_in_curr_slice; i++) {
1448 49469 const int pre_ctb_addr_x = sh->ctb_addr_in_curr_slice[i - 1] % pps->ctb_width;
1449 49469 const int pre_ctb_addr_y = sh->ctb_addr_in_curr_slice[i - 1] / pps->ctb_width;
1450 49469 const int ctb_addr_x = sh->ctb_addr_in_curr_slice[i] % pps->ctb_width;
1451 49469 const int ctb_addr_y = sh->ctb_addr_in_curr_slice[i] / pps->ctb_width;
1452
2/2
✓ Branch 0 taken 49426 times.
✓ Branch 1 taken 43 times.
49469 if (pps->ctb_to_row_bd[ctb_addr_y] != pps->ctb_to_row_bd[pre_ctb_addr_y] ||
1453
4/4
✓ Branch 0 taken 49249 times.
✓ Branch 1 taken 177 times.
✓ Branch 2 taken 3763 times.
✓ Branch 3 taken 45486 times.
49426 pps->ctb_to_col_bd[ctb_addr_x] != pps->ctb_to_col_bd[pre_ctb_addr_x] ||
1454
2/2
✓ Branch 0 taken 153 times.
✓ Branch 1 taken 3610 times.
3763 (ctb_addr_y != pre_ctb_addr_y && sps->sps_entropy_coding_sync_enabled_flag)) {
1455 373 sh->entry_point_start_ctu[j++] = i;
1456 }
1457 }
1458 }
1459 1831 }
1460
1461 1831 static int sh_derive(VVCSH *sh, const VVCFrameParamSets *fps)
1462 {
1463 1831 const H266RawSPS *sps = fps->sps->r;
1464 1831 const H266RawPPS *pps = fps->pps->r;
1465 1831 const H266RawPictureHeader *ph = fps->ph.r;
1466 int ret;
1467
1468 1831 ret = sh_slice_address(sh, sps, fps->pps);
1469
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1831 times.
1831 if (ret < 0)
1470 return ret;
1471 1831 ret = sh_alf_aps(sh, fps);
1472
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1831 times.
1831 if (ret < 0)
1473 return ret;
1474 1831 sh_inter(sh, sps, pps);
1475 1831 sh_qp_y(sh, pps, ph);
1476 1831 sh_deblock_offsets(sh);
1477 1831 sh_partition_constraints(sh, sps, ph);
1478 1831 sh_entry_points(sh, sps, fps->pps);
1479
1480 1831 return 0;
1481 }
1482
1483 1831 int ff_vvc_decode_sh(VVCSH *sh, const VVCFrameParamSets *fps, const CodedBitstreamUnit *unit)
1484 {
1485 int ret;
1486
1487
2/4
✓ Branch 0 taken 1831 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1831 times.
1831 if (!fps->sps || !fps->pps)
1488 return AVERROR_INVALIDDATA;
1489
1490 1831 av_refstruct_replace(&sh->r, unit->content_ref);
1491
1492 1831 ret = sh_derive(sh, fps);
1493
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1831 times.
1831 if (ret < 0)
1494 return ret;
1495
1496 1831 return 0;
1497 }
1498