Coverage Report

Created: 2026-02-14 06:59

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