FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/vvc/ps.c
Date: 2025-01-20 09:27:23
Exec Total Coverage
Lines: 752 840 89.5%
Functions: 72 74 97.3%
Branches: 373 476 78.4%

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