FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/vvc/ps.c
Date: 2024-11-20 23:03:26
Exec Total Coverage
Lines: 725 823 88.1%
Functions: 71 74 95.9%
Branches: 353 464 76.1%

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