Coverage Report

Created: 2026-04-01 07:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavcodec/cbs_h266.c
Line
Count
Source
1
/*
2
 * This file is part of FFmpeg.
3
 *
4
 * FFmpeg is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2.1 of the License, or (at your option) any later version.
8
 *
9
 * FFmpeg is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
15
 * License along with FFmpeg; if not, write to the Free Software
16
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
 */
18
19
#include "libavutil/intmath.h"
20
#include "libavutil/mem.h"
21
#include "libavutil/refstruct.h"
22
#include "bytestream.h"
23
#include "cbs.h"
24
#include "cbs_internal.h"
25
#include "cbs_h2645.h"
26
#include "cbs_h266.h"
27
#include "cbs_sei.h"
28
#include "get_bits.h"
29
30
9.72M
#define HEADER(name) do { \
31
9.72M
        ff_cbs_trace_header(ctx, name); \
32
9.72M
    } while (0)
33
34
888M
#define CHECK(call) do { \
35
1.39G
        err = (call); \
36
887M
        if (err < 0) \
37
887M
            return err; \
38
887M
    } while (0)
39
40
#define FUNC_NAME2(rw, codec, name) cbs_ ## codec ## _ ## rw ## _ ## name
41
#define FUNC_NAME1(rw, codec, name) FUNC_NAME2(rw, codec, name)
42
#define FUNC_H266(name) FUNC_NAME1(READWRITE, h266, name)
43
#define FUNC_NAME2_EXPORT(rw, codec, name) ff_cbs_ ## codec ## _ ## rw ## _ ## name
44
#define FUNC_NAME1_EXPORT(rw, codec, name) FUNC_NAME2_EXPORT(rw, codec, name)
45
#define FUNC_SEI(name)  FUNC_NAME1_EXPORT(READWRITE, sei,  name)
46
47
#define SEI_FUNC(name, args) \
48
static int FUNC_H266(name) args;  \
49
static int FUNC_H266(name ## _internal)(CodedBitstreamContext *ctx, \
50
                                   RWContext *rw, void *cur,   \
51
                                   SEIMessageState *state)     \
52
{ \
53
    return FUNC_H266(name)(ctx, rw, cur, state); \
54
} \
55
static int FUNC_H266(name) args
56
57
#define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : NULL)
58
59
#define u(width, name, range_min, range_max) \
60
26.6M
        xu(width, name, current->name, range_min, range_max, 0, )
61
129M
#define flag(name) ub(1, name)
62
#define ue(name, range_min, range_max) \
63
48.2M
        xue(name, current->name, range_min, range_max, 0, )
64
#define i(width, name, range_min, range_max) \
65
        xi(width, name, current->name, range_min, range_max, 0, )
66
#define ib(width, name) \
67
        xi(width, name, current->name, MIN_INT_BITS(width), MAX_INT_BITS(width), 0, )
68
#define se(name, range_min, range_max) \
69
16.1M
        xse(name, current->name, range_min, range_max, 0, )
70
71
#define us(width, name, range_min, range_max, subs, ...) \
72
5.50M
        xu(width, name, current->name, range_min, range_max, subs, __VA_ARGS__)
73
#define ubs(width, name, subs, ...) \
74
9.72M
        xu(width, name, current->name, 0, MAX_UINT_BITS(width), subs, __VA_ARGS__)
75
#define flags(name, subs, ...) \
76
60.5M
        xu(1, name, current->name, 0, 1, subs, __VA_ARGS__)
77
#define ues(name, range_min, range_max, subs, ...) \
78
20.2M
        xue(name, current->name, range_min, range_max, subs, __VA_ARGS__)
79
#define is(width, name, range_min, range_max, subs, ...) \
80
        xi(width, name, current->name, range_min, range_max, subs, __VA_ARGS__)
81
#define ibs(width, name, subs, ...) \
82
        xi(width, name, current->name, MIN_INT_BITS(width), MAX_INT_BITS(width), subs, __VA_ARGS__)
83
#define ses(name, range_min, range_max, subs, ...) \
84
6.10M
        xse(name, current->name, range_min, range_max, subs, __VA_ARGS__)
85
86
26.6M
#define fixed(width, name, value) do { \
87
19.8M
        av_unused uint32_t fixed_value = value; \
88
19.8M
        xu(width, name, fixed_value, value, value, 0, ); \
89
19.8M
    } while (0)
90
91
92
#define READ
93
#define READWRITE read
94
#define RWContext GetBitContext
95
96
148M
#define ub(width, name) do { \
97
148M
        uint32_t value; \
98
148M
        CHECK(ff_cbs_read_simple_unsigned(ctx, rw, width, #name, \
99
148M
                                          &value)); \
100
148M
        current->name = value; \
101
148M
    } while (0)
102
464M
#define xu(width, name, var, range_min, range_max, subs, ...) do { \
103
455M
        uint32_t value; \
104
455M
        CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \
105
455M
                                   SUBSCRIPTS(subs, __VA_ARGS__), \
106
455M
                                   &value, range_min, range_max)); \
107
455M
        var = value; \
108
453M
    } while (0)
109
67.2M
#define xue(name, var, range_min, range_max, subs, ...) do { \
110
66.7M
        uint32_t value; \
111
66.7M
        CHECK(ff_cbs_read_ue_golomb(ctx, rw, #name, \
112
66.7M
                                 SUBSCRIPTS(subs, __VA_ARGS__), \
113
66.7M
                                 &value, range_min, range_max)); \
114
66.7M
        var = value; \
115
65.6M
    } while (0)
116
#define xi(width, name, var, range_min, range_max, subs, ...) do { \
117
        int32_t value; \
118
        CHECK(ff_cbs_read_signed(ctx, rw, width, #name, \
119
                                 SUBSCRIPTS(subs, __VA_ARGS__), \
120
                                 &value, range_min, range_max)); \
121
        var = value; \
122
    } while (0)
123
21.9M
#define xse(name, var, range_min, range_max, subs, ...) do { \
124
21.9M
        int32_t value; \
125
21.9M
        CHECK(ff_cbs_read_se_golomb(ctx, rw, #name, \
126
21.9M
                                 SUBSCRIPTS(subs, __VA_ARGS__), \
127
21.9M
                                 &value, range_min, range_max)); \
128
21.9M
        var = value; \
129
21.6M
    } while (0)
130
131
132
311M
#define infer(name, value) do { \
133
311M
        current->name = value; \
134
311M
    } while (0)
135
136
#define more_rbsp_data(var) ((var) = ff_cbs_h2645_read_more_rbsp_data(rw))
137
138
119k
#define bit_position(rw)   (get_bits_count(rw))
139
10.3M
#define byte_alignment(rw) (get_bits_count(rw) % 8)
140
141
512k
#define allocate(name, size) do { \
142
512k
        name ## _ref = av_buffer_allocz(size + \
143
512k
                                        AV_INPUT_BUFFER_PADDING_SIZE); \
144
512k
        if (!name ## _ref) \
145
512k
            return AVERROR(ENOMEM); \
146
512k
        name = name ## _ref->data; \
147
512k
    } while (0)
148
149
#define FUNC(name) FUNC_H266(name)
150
#include "cbs_h266_syntax_template.c"
151
#undef FUNC
152
153
154
#undef READ
155
#undef READWRITE
156
#undef RWContext
157
#undef ub
158
#undef xu
159
#undef xi
160
#undef xue
161
#undef xse
162
#undef infer
163
#undef more_rbsp_data
164
#undef bit_position
165
#undef byte_alignment
166
#undef allocate
167
#undef allocate_struct
168
169
170
#define WRITE
171
#define READWRITE write
172
#define RWContext PutBitContext
173
174
2.43M
#define ub(width, name) do { \
175
2.41M
        uint32_t value = current->name; \
176
2.41M
        CHECK(ff_cbs_write_simple_unsigned(ctx, rw, width, #name, \
177
2.41M
                                           value)); \
178
2.41M
    } while (0)
179
146M
#define xu(width, name, var, range_min, range_max, subs, ...) do { \
180
146M
        uint32_t value = var; \
181
146M
        CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \
182
146M
                                    SUBSCRIPTS(subs, __VA_ARGS__), \
183
146M
                                    value, range_min, range_max)); \
184
146M
    } while (0)
185
1.67M
#define xue(name, var, range_min, range_max, subs, ...) do { \
186
1.66M
        uint32_t value = var; \
187
1.66M
        CHECK(ff_cbs_write_ue_golomb(ctx, rw, #name, \
188
1.66M
                                  SUBSCRIPTS(subs, __VA_ARGS__), \
189
1.66M
                                  value, range_min, range_max)); \
190
1.66M
    } while (0)
191
#define xi(width, name, var, range_min, range_max, subs, ...) do { \
192
        int32_t value = var; \
193
        CHECK(ff_cbs_write_signed(ctx, rw, width, #name, \
194
                                  SUBSCRIPTS(subs, __VA_ARGS__), \
195
                                  value, range_min, range_max)); \
196
    } while (0)
197
323k
#define xse(name, var, range_min, range_max, subs, ...) do { \
198
323k
        int32_t value = var; \
199
323k
        CHECK(ff_cbs_write_se_golomb(ctx, rw, #name, \
200
323k
                                  SUBSCRIPTS(subs, __VA_ARGS__), \
201
323k
                                  value, range_min, range_max)); \
202
323k
    } while (0)
203
204
3.22M
#define infer(name, value) do { \
205
3.21M
        if (current->name != (value)) { \
206
26.6k
            av_log(ctx->log_ctx, AV_LOG_ERROR, \
207
26.6k
                   "%s does not match inferred value: " \
208
26.6k
                   "%"PRId64", but should be %"PRId64".\n", \
209
26.6k
                   #name, (int64_t)current->name, (int64_t)(value)); \
210
26.6k
            return AVERROR_INVALIDDATA; \
211
26.6k
        } \
212
3.21M
    } while (0)
213
214
#define more_rbsp_data(var) (var)
215
216
6.83k
#define bit_position(rw)   (put_bits_count(rw))
217
391k
#define byte_alignment(rw) (put_bits_count(rw) % 8)
218
219
#define allocate(name, size) do { \
220
        if (!name) { \
221
            av_log(ctx->log_ctx, AV_LOG_ERROR, "%s must be set " \
222
                   "for writing.\n", #name); \
223
            return AVERROR_INVALIDDATA; \
224
        } \
225
    } while (0)
226
227
#define FUNC(name) FUNC_H266(name)
228
#include "cbs_h266_syntax_template.c"
229
#undef FUNC
230
231
#undef WRITE
232
#undef READWRITE
233
#undef RWContext
234
#undef ub
235
#undef xu
236
#undef xi
237
#undef xue
238
#undef xse
239
#undef u
240
#undef i
241
#undef flag
242
#undef ue
243
#undef se
244
#undef infer
245
#undef more_rbsp_data
246
#undef bit_position
247
#undef byte_alignment
248
#undef allocate
249
250
251
252
static int cbs_h266_split_fragment(CodedBitstreamContext *ctx,
253
                                   CodedBitstreamFragment *frag,
254
                                   int header)
255
12.0M
{
256
12.0M
    enum AVCodecID codec_id = ctx->codec->codec_id;
257
12.0M
    CodedBitstreamH266Context *priv = ctx->priv_data;
258
12.0M
    CodedBitstreamH2645Context *h2645 = &priv->common;
259
12.0M
    GetByteContext gbc;
260
12.0M
    int err;
261
262
12.0M
    av_assert0(frag->data && frag->nb_units == 0);
263
12.0M
    if (frag->data_size == 0)
264
34.5k
        return 0;
265
266
12.0M
    if(header && frag->data[0]) {
267
        // VVCC header.
268
671
        int ptl_present_flag, num_arrays;
269
671
        int b, i, j;
270
271
671
        h2645->mp4 = 1;
272
273
671
        bytestream2_init(&gbc, frag->data, frag->data_size);
274
275
671
        b = bytestream2_get_byte(&gbc);
276
671
        h2645->nal_length_size = ((b >> 1) & 3) + 1;
277
671
        ptl_present_flag = b & 1;
278
279
671
        if(ptl_present_flag) {
280
477
            int num_sublayers, num_bytes_constraint_info, num_sub_profiles;
281
477
            num_sublayers = (bytestream2_get_be16u(&gbc) >> 4) & 7;
282
477
            bytestream2_skip(&gbc, 1);
283
284
            // begin VvcPTLRecord(num_sublayers);
285
477
            num_bytes_constraint_info = bytestream2_get_byte(&gbc) & 0x3f;
286
477
            bytestream2_skip(&gbc, 2 + num_bytes_constraint_info);
287
477
            if(num_sublayers > 1) {
288
258
                int count_present_flags = 0;
289
258
                b = bytestream2_get_byte(&gbc);
290
1.39k
                for(i = num_sublayers - 2; i >= 0; i--) {
291
1.13k
                    if((b >> (7 - (num_sublayers - 2 - i))) & 0x01)
292
398
                        count_present_flags++;
293
1.13k
                }
294
258
                bytestream2_skip(&gbc, count_present_flags);
295
258
            }
296
477
            num_sub_profiles = bytestream2_get_byte(&gbc);
297
477
            bytestream2_skip(&gbc, num_sub_profiles * 4);
298
            // end VvcPTLRecord(num_sublayers);
299
300
477
            bytestream2_skip(&gbc, 3 * 2);
301
477
        }
302
303
671
        num_arrays = bytestream2_get_byte(&gbc);
304
5.08k
        for(j = 0; j < num_arrays; j++) {
305
4.62k
            size_t start, end, size;
306
4.62k
            int nal_unit_type = bytestream2_get_byte(&gbc) & 0x1f;
307
4.62k
            unsigned int num_nalus = 1;
308
4.62k
            if(nal_unit_type != VVC_DCI_NUT && nal_unit_type != VVC_OPI_NUT)
309
4.04k
                num_nalus = bytestream2_get_be16(&gbc);
310
311
4.62k
            start = bytestream2_tell(&gbc);
312
14.7k
            for(i = 0; i < num_nalus; i++) {
313
10.3k
                if (bytestream2_get_bytes_left(&gbc) < 2)
314
13
                    return AVERROR_INVALIDDATA;
315
10.2k
                size = bytestream2_get_be16(&gbc);
316
10.2k
                if (bytestream2_get_bytes_left(&gbc) < size)
317
186
                    return AVERROR_INVALIDDATA;
318
10.1k
                bytestream2_skip(&gbc, size);
319
10.1k
            }
320
4.42k
            end = bytestream2_tell(&gbc);
321
322
4.42k
            err = ff_h2645_packet_split(&h2645->read_packet,
323
4.42k
                                        frag->data + start, end - start,
324
4.42k
                                        ctx->log_ctx, 2, AV_CODEC_ID_VVC,
325
4.42k
                                        H2645_FLAG_IS_NALFF | H2645_FLAG_SMALL_PADDING | H2645_FLAG_USE_REF);
326
4.42k
            if (err < 0) {
327
12
                av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to split "
328
12
                       "VVCC array %d (%d NAL units of type %d).\n",
329
12
                       i, num_nalus, nal_unit_type);
330
12
                return err;
331
12
            }
332
4.41k
            err = ff_cbs_h2645_fragment_add_nals(ctx, frag, &h2645->read_packet);
333
4.41k
            if (err < 0)
334
0
                return err;
335
4.41k
        }
336
12.0M
    } else {
337
12.0M
        int flags = (H2645_FLAG_IS_NALFF * !!h2645->mp4) | H2645_FLAG_SMALL_PADDING | H2645_FLAG_USE_REF;
338
        // Annex B, or later MP4 with already-known parameters.
339
340
12.0M
        err = ff_h2645_packet_split(&h2645->read_packet,
341
12.0M
                                    frag->data, frag->data_size,
342
12.0M
                                    ctx->log_ctx,
343
12.0M
                                    h2645->nal_length_size,
344
12.0M
                                    codec_id, flags);
345
12.0M
        if (err < 0)
346
1.92M
            return err;
347
348
10.1M
        err = ff_cbs_h2645_fragment_add_nals(ctx, frag, &h2645->read_packet);
349
10.1M
        if (err < 0)
350
0
            return err;
351
10.1M
    }
352
353
10.1M
    return 0;
354
12.0M
}
355
356
#define cbs_h266_replace_ps(ps_name, ps_var, id_element) \
357
static int cbs_h266_replace_ ## ps_var(CodedBitstreamContext *ctx, \
358
329k
                                       CodedBitstreamUnit *unit)  \
359
329k
{ \
360
329k
    CodedBitstreamH266Context *priv = ctx->priv_data; \
361
329k
    H266Raw ## ps_name *ps_var = unit->content; \
362
329k
    unsigned int id = ps_var->id_element; \
363
329k
    int err = ff_cbs_make_unit_refcounted(ctx, unit); \
364
329k
    if (err < 0) \
365
329k
        return err; \
366
329k
    av_assert0(unit->content_ref); \
367
329k
    av_refstruct_replace(&priv->ps_var[id], unit->content_ref); \
368
329k
    return 0; \
369
329k
}
370
371
34.8k
cbs_h266_replace_ps(VPS, vps, vps_video_parameter_set_id)
372
294k
cbs_h266_replace_ps(PPS, pps, pps_pic_parameter_set_id)
373
374
static int cbs_h266_replace_sps(CodedBitstreamContext *ctx,
375
                                CodedBitstreamUnit *unit)
376
186k
{
377
186k
    CodedBitstreamH266Context *priv = ctx->priv_data;
378
186k
    H266RawSPS *sps = unit->content;
379
186k
    unsigned int id = sps->sps_seq_parameter_set_id;
380
186k
    int err = ff_cbs_make_unit_refcounted(ctx, unit);
381
186k
    if (err < 0)
382
0
        return err;
383
186k
    av_assert0(unit->content_ref);
384
186k
    if (priv->sps[id] && memcmp(priv->sps[id], unit->content_ref, sizeof(*priv->sps[id]))) {
385
8.72M
        for (unsigned int i = 0; i < VVC_MAX_PPS_COUNT; i++) {
386
8.59M
            if (priv->pps[i] && priv->pps[i]->pps_seq_parameter_set_id == id)
387
86.5k
                av_refstruct_unref(&priv->pps[i]);
388
8.59M
        }
389
134k
    }
390
186k
    av_refstruct_replace(&priv->sps[id], unit->content_ref);
391
186k
    return 0;
392
186k
}
393
394
static int cbs_h266_replace_ph(CodedBitstreamContext *ctx,
395
                               CodedBitstreamUnit *unit,
396
                               H266RawPictureHeader *ph)
397
4.87M
{
398
4.87M
    CodedBitstreamH266Context *h266 = ctx->priv_data;
399
4.87M
    int err;
400
401
4.87M
    err = ff_cbs_make_unit_refcounted(ctx, unit);
402
4.87M
    if (err < 0)
403
0
        return err;
404
4.87M
    av_assert0(unit->content_ref);
405
4.87M
    av_refstruct_replace(&h266->ph_ref, unit->content_ref);
406
4.87M
    h266->ph = ph;
407
4.87M
    return 0;
408
4.87M
}
409
410
static int cbs_h266_read_nal_unit(CodedBitstreamContext *ctx,
411
                                  CodedBitstreamUnit *unit)
412
10.2M
{
413
10.2M
    GetBitContext gbc;
414
10.2M
    int err;
415
10.2M
    CodedBitstreamH266Context *h266 = ctx->priv_data;
416
417
10.2M
    err = init_get_bits8(&gbc, unit->data, unit->data_size);
418
10.2M
    if (err < 0)
419
0
        return err;
420
421
10.2M
    err = ff_cbs_alloc_unit_content(ctx, unit);
422
10.2M
    if (err < 0)
423
628k
        return err;
424
425
9.61M
    switch (unit->type) {
426
21.1k
    case VVC_DCI_NUT:
427
21.1k
        {
428
21.1k
            err = cbs_h266_read_dci(ctx, &gbc, unit->content);
429
430
21.1k
            if (err < 0)
431
19.0k
                return err;
432
21.1k
        }
433
2.08k
        break;
434
92.7k
    case VVC_OPI_NUT:
435
92.7k
        {
436
92.7k
            err = cbs_h266_read_opi(ctx, &gbc, unit->content);
437
438
92.7k
            if (err < 0)
439
36.8k
                return err;
440
92.7k
        }
441
55.8k
        break;
442
174k
    case VVC_VPS_NUT:
443
174k
        {
444
174k
            H266RawVPS *vps = unit->content;
445
446
174k
            err = cbs_h266_read_vps(ctx, &gbc, vps);
447
174k
            if (err < 0)
448
145k
                return err;
449
450
28.8k
            err = cbs_h266_replace_vps(ctx, unit);
451
28.8k
            if (err < 0)
452
0
                return err;
453
28.8k
        }
454
28.8k
        break;
455
760k
    case VVC_SPS_NUT:
456
760k
        {
457
760k
            H266RawSPS *sps = unit->content;
458
459
760k
            err = cbs_h266_read_sps(ctx, &gbc, sps);
460
760k
            if (err < 0)
461
588k
                return err;
462
463
172k
            err = cbs_h266_replace_sps(ctx, unit);
464
172k
            if (err < 0)
465
0
                return err;
466
172k
        }
467
172k
        break;
468
469
399k
    case VVC_PPS_NUT:
470
399k
        {
471
399k
            H266RawPPS *pps = unit->content;
472
473
399k
            err = cbs_h266_read_pps(ctx, &gbc, pps);
474
399k
            if (err < 0)
475
114k
                return err;
476
477
285k
            err = cbs_h266_replace_pps(ctx, unit);
478
285k
            if (err < 0)
479
0
                return err;
480
285k
        }
481
285k
        break;
482
483
285k
    case VVC_PREFIX_APS_NUT:
484
285k
    case VVC_SUFFIX_APS_NUT:
485
285k
        {
486
285k
            err = cbs_h266_read_aps(ctx, &gbc, unit->content,
487
285k
                                    unit->type == VVC_PREFIX_APS_NUT);
488
489
285k
            if (err < 0)
490
192k
                return err;
491
285k
        }
492
92.4k
        break;
493
97.2k
    case VVC_PH_NUT:
494
97.2k
        {
495
97.2k
            H266RawPH *ph = unit->content;
496
97.2k
            err = cbs_h266_read_ph(ctx, &gbc, ph);
497
97.2k
            if (err < 0)
498
80.3k
                return err;
499
16.8k
            err = cbs_h266_replace_ph(ctx, unit, &ph->ph_picture_header);
500
16.8k
            if (err < 0)
501
0
                return err;
502
16.8k
        }
503
16.8k
        break;
504
505
6.82M
    case VVC_TRAIL_NUT:
506
7.03M
    case VVC_STSA_NUT:
507
7.09M
    case VVC_RADL_NUT:
508
7.16M
    case VVC_RASL_NUT:
509
7.31M
    case VVC_IDR_W_RADL:
510
7.38M
    case VVC_IDR_N_LP:
511
7.66M
    case VVC_CRA_NUT:
512
7.69M
    case VVC_GDR_NUT:
513
7.69M
        {
514
7.69M
            H266RawSlice *slice = unit->content;
515
7.69M
            int pos, len;
516
517
7.69M
            err = cbs_h266_read_slice_header(ctx, &gbc, &slice->header);
518
7.69M
            if (err < 0)
519
2.75M
                return err;
520
521
4.94M
            if (!ff_cbs_h2645_read_more_rbsp_data(&gbc))
522
15.1k
                return AVERROR_INVALIDDATA;
523
524
4.92M
            pos = get_bits_count(&gbc);
525
4.92M
            len = unit->data_size;
526
527
4.92M
            if (slice->header.sh_picture_header_in_slice_header_flag) {
528
4.84M
                err = cbs_h266_replace_ph(ctx, unit, &slice->header.sh_picture_header);
529
4.84M
                if (err < 0)
530
0
                    return err;
531
4.84M
                slice->ph_ref = NULL;
532
4.84M
            } else {
533
82.2k
                slice->ph_ref = av_refstruct_ref(h266->ph_ref);
534
82.2k
            }
535
4.92M
            slice->ph     = h266->ph;
536
4.92M
            slice->pps    = av_refstruct_ref(h266->pps[slice->ph->ph_pic_parameter_set_id]);
537
4.92M
            slice->sps    = av_refstruct_ref(h266->sps[slice->pps->pps_seq_parameter_set_id]);
538
539
4.92M
            slice->header_size = pos / 8;
540
4.92M
            slice->data_size = len - pos / 8;
541
4.92M
            slice->data_ref  = av_buffer_ref(unit->data_ref);
542
4.92M
            if (!slice->data_ref)
543
0
                return AVERROR(ENOMEM);
544
4.92M
            slice->data = unit->data + pos / 8;
545
4.92M
            slice->data_bit_start = pos % 8;
546
4.92M
        }
547
0
        break;
548
549
21.6k
    case VVC_AUD_NUT:
550
21.6k
        {
551
21.6k
            err = cbs_h266_read_aud(ctx, &gbc, unit->content);
552
21.6k
            if (err < 0)
553
7.15k
                return err;
554
21.6k
        }
555
14.5k
        break;
556
557
31.1k
    case VVC_PREFIX_SEI_NUT:
558
65.5k
    case VVC_SUFFIX_SEI_NUT:
559
65.5k
        {
560
65.5k
            err = cbs_h266_read_sei(ctx, &gbc, unit->content,
561
65.5k
                                    unit->type == VVC_PREFIX_SEI_NUT);
562
563
65.5k
            if (err < 0)
564
52.7k
                return err;
565
65.5k
        }
566
12.7k
        break;
567
568
12.7k
    default:
569
0
        return AVERROR(ENOSYS);
570
9.61M
    }
571
5.60M
    return 0;
572
9.61M
}
573
574
static int cbs_h266_write_nal_unit(CodedBitstreamContext *ctx,
575
                                   CodedBitstreamUnit *unit,
576
                                   PutBitContext *pbc)
577
116k
{
578
116k
    int err;
579
580
116k
    switch (unit->type) {
581
1.02k
    case VVC_DCI_NUT:
582
1.02k
        {
583
1.02k
            H266RawDCI *dci = unit->content;
584
585
1.02k
            err = cbs_h266_write_dci(ctx, pbc, dci);
586
1.02k
            if (err < 0)
587
0
                return err;
588
1.02k
        }
589
1.02k
        break;
590
6.18k
    case VVC_OPI_NUT:
591
6.18k
        {
592
6.18k
            H266RawOPI *opi = unit->content;
593
594
6.18k
            err = cbs_h266_write_opi(ctx, pbc, opi);
595
6.18k
            if (err < 0)
596
0
                return err;
597
6.18k
        }
598
6.18k
        break;
599
6.18k
    case VVC_VPS_NUT:
600
5.99k
        {
601
5.99k
            H266RawVPS *vps = unit->content;
602
603
5.99k
            err = cbs_h266_write_vps(ctx, pbc, vps);
604
5.99k
            if (err < 0)
605
0
                return err;
606
607
5.99k
            err = cbs_h266_replace_vps(ctx, unit);
608
5.99k
            if (err < 0)
609
0
                return err;
610
5.99k
        }
611
5.99k
        break;
612
14.3k
    case VVC_SPS_NUT:
613
14.3k
        {
614
14.3k
            H266RawSPS *sps = unit->content;
615
616
14.3k
            err = cbs_h266_write_sps(ctx, pbc, sps);
617
14.3k
            if (err < 0)
618
216
                return err;
619
620
14.0k
            err = cbs_h266_replace_sps(ctx, unit);
621
14.0k
            if (err < 0)
622
0
                return err;
623
14.0k
        }
624
14.0k
        break;
625
626
14.4k
    case VVC_PPS_NUT:
627
14.4k
        {
628
14.4k
            H266RawPPS *pps = unit->content;
629
630
14.4k
            err = cbs_h266_write_pps(ctx, pbc, pps);
631
14.4k
            if (err < 0)
632
4.68k
                return err;
633
634
9.75k
            err = cbs_h266_replace_pps(ctx, unit);
635
9.75k
            if (err < 0)
636
0
                return err;
637
9.75k
        }
638
9.75k
        break;
639
640
12.2k
    case VVC_PREFIX_APS_NUT:
641
12.6k
    case VVC_SUFFIX_APS_NUT:
642
12.6k
        {
643
12.6k
            err = cbs_h266_write_aps(ctx, pbc, unit->content,
644
12.6k
                                     unit->type == VVC_PREFIX_APS_NUT);
645
12.6k
            if (err < 0)
646
0
                return err;
647
12.6k
        }
648
12.6k
        break;
649
12.6k
    case VVC_PH_NUT:
650
9.12k
        {
651
9.12k
            H266RawPH *ph = unit->content;
652
9.12k
            err = cbs_h266_write_ph(ctx, pbc, ph);
653
9.12k
            if (err < 0)
654
6.24k
                return err;
655
656
2.88k
            err = cbs_h266_replace_ph(ctx, unit, &ph->ph_picture_header);
657
2.88k
            if (err < 0)
658
0
                return err;
659
2.88k
        }
660
2.88k
        break;
661
662
7.89k
    case VVC_TRAIL_NUT:
663
24.9k
    case VVC_STSA_NUT:
664
31.8k
    case VVC_RADL_NUT:
665
39.0k
    case VVC_RASL_NUT:
666
39.2k
    case VVC_IDR_W_RADL:
667
44.5k
    case VVC_IDR_N_LP:
668
44.9k
    case VVC_CRA_NUT:
669
46.8k
    case VVC_GDR_NUT:
670
46.8k
        {
671
46.8k
            H266RawSlice *slice = unit->content;
672
673
46.8k
            err = cbs_h266_write_slice_header(ctx, pbc, &slice->header);
674
46.8k
            if (err < 0)
675
27.6k
                return err;
676
677
19.2k
            if (slice->header.sh_picture_header_in_slice_header_flag) {
678
11.1k
                err = cbs_h266_replace_ph(ctx, unit, &slice->header.sh_picture_header);
679
11.1k
                if (err < 0)
680
0
                    return err;
681
11.1k
            }
682
683
19.2k
            if (slice->data) {
684
19.2k
                err = ff_cbs_h2645_write_slice_data(ctx, pbc, slice->data,
685
19.2k
                                                 slice->data_size,
686
19.2k
                                                 slice->data_bit_start);
687
19.2k
                if (err < 0)
688
0
                    return err;
689
19.2k
            } else {
690
                // No slice data - that was just the header.
691
0
            }
692
19.2k
        }
693
19.2k
        break;
694
695
19.2k
    case VVC_AUD_NUT:
696
2.60k
        {
697
2.60k
            err = cbs_h266_write_aud(ctx, pbc, unit->content);
698
2.60k
            if (err < 0)
699
0
                return err;
700
2.60k
        }
701
2.60k
        break;
702
703
2.60k
    case VVC_PREFIX_SEI_NUT:
704
3.70k
    case VVC_SUFFIX_SEI_NUT:
705
3.70k
        {
706
3.70k
            err = cbs_h266_write_sei(ctx, pbc, unit->content,
707
3.70k
                                     unit->type == VVC_PREFIX_SEI_NUT);
708
709
3.70k
            if (err < 0)
710
0
                return err;
711
3.70k
        }
712
3.70k
        break;
713
714
3.70k
    default:
715
0
        av_log(ctx->log_ctx, AV_LOG_ERROR, "Write unimplemented for "
716
0
               "NAL unit type %"PRIu32".\n", unit->type);
717
0
        return AVERROR_PATCHWELCOME;
718
116k
    }
719
720
78.0k
    return 0;
721
116k
}
722
723
static av_cold void cbs_h266_flush(CodedBitstreamContext *ctx)
724
46.1k
{
725
46.1k
    CodedBitstreamH266Context *h266 = ctx->priv_data;
726
727
783k
    for (int i = 0; i < FF_ARRAY_ELEMS(h266->vps); i++)
728
737k
        av_refstruct_unref(&h266->vps[i]);
729
783k
    for (int i = 0; i < FF_ARRAY_ELEMS(h266->sps); i++)
730
737k
        av_refstruct_unref(&h266->sps[i]);
731
2.99M
    for (int i = 0; i < FF_ARRAY_ELEMS(h266->pps); i++)
732
2.95M
        av_refstruct_unref(&h266->pps[i]);
733
46.1k
    av_refstruct_unref(&h266->ph_ref);
734
46.1k
}
735
736
static av_cold void cbs_h266_close(CodedBitstreamContext *ctx)
737
46.1k
{
738
46.1k
    CodedBitstreamH266Context *h266 = ctx->priv_data;
739
740
46.1k
    cbs_h266_flush(ctx);
741
46.1k
    ff_h2645_packet_uninit(&h266->common.read_packet);
742
46.1k
}
743
744
static void cbs_h266_free_slice(AVRefStructOpaque unused, void *content)
745
7.69M
{
746
7.69M
    H266RawSlice *slice = content;
747
7.69M
    av_buffer_unref(&slice->data_ref);
748
7.69M
    av_refstruct_unref(&slice->sps);
749
7.69M
    av_refstruct_unref(&slice->pps);
750
7.69M
    av_refstruct_unref(&slice->ph_ref);
751
7.69M
}
752
753
754
static void cbs_h266_free_sei(AVRefStructOpaque unused, void *content)
755
65.5k
{
756
65.5k
    H266RawSEI *sei = content;
757
65.5k
    ff_cbs_sei_free_message_list(&sei->message_list);
758
65.5k
}
759
760
static CodedBitstreamUnitTypeDescriptor cbs_h266_unit_types[] = {
761
    CBS_UNIT_TYPE_INTERNAL_REF(VVC_DCI_NUT, H266RawDCI, extension_data.data),
762
    CBS_UNIT_TYPE_INTERNAL_REF(VVC_OPI_NUT, H266RawOPI, extension_data.data),
763
    CBS_UNIT_TYPE_INTERNAL_REF(VVC_VPS_NUT, H266RawVPS, extension_data.data),
764
    {
765
        .nb_unit_types     = 1,
766
        .unit_type.list[0] = VVC_SPS_NUT,
767
        .content_type      = CBS_CONTENT_TYPE_INTERNAL_REFS,
768
        .content_size      = sizeof(H266RawSPS),
769
        .type.ref          = {
770
            .nb_offsets = 2,
771
            .offsets    = { offsetof(H266RawSPS, extension_data.data),
772
                            offsetof(H266RawSPS, vui.extension_data.data) }
773
        },
774
    },
775
    CBS_UNIT_TYPE_INTERNAL_REF(VVC_PPS_NUT, H266RawPPS, extension_data.data),
776
    CBS_UNIT_TYPE_INTERNAL_REF(VVC_PREFIX_APS_NUT, H266RawAPS, extension_data.data),
777
    CBS_UNIT_TYPE_INTERNAL_REF(VVC_SUFFIX_APS_NUT, H266RawAPS, extension_data.data),
778
779
    CBS_UNIT_TYPE_POD(VVC_PH_NUT , H266RawPH),
780
    CBS_UNIT_TYPE_POD(VVC_AUD_NUT, H266RawAUD),
781
782
    CBS_UNIT_TYPES_COMPLEX((VVC_TRAIL_NUT, VVC_STSA_NUT, VVC_RADL_NUT),
783
                           H266RawSlice, cbs_h266_free_slice),
784
    CBS_UNIT_TYPES_COMPLEX((VVC_RASL_NUT, VVC_IDR_W_RADL, VVC_IDR_N_LP),
785
                           H266RawSlice, cbs_h266_free_slice),
786
    CBS_UNIT_TYPES_COMPLEX((VVC_CRA_NUT, VVC_GDR_NUT),
787
                           H266RawSlice, cbs_h266_free_slice),
788
789
    CBS_UNIT_TYPES_COMPLEX((VVC_PREFIX_SEI_NUT, VVC_SUFFIX_SEI_NUT),
790
                           H266RawSEI, cbs_h266_free_sei),
791
792
    CBS_UNIT_TYPE_END_OF_LIST
793
};
794
795
const CodedBitstreamType ff_cbs_type_h266 = {
796
    .codec_id          = AV_CODEC_ID_VVC,
797
798
    .priv_data_size    = sizeof(CodedBitstreamH266Context),
799
800
    .unit_types        = cbs_h266_unit_types,
801
802
    .split_fragment    = &cbs_h266_split_fragment,
803
    .read_unit         = &cbs_h266_read_nal_unit,
804
    .write_unit        = &cbs_h266_write_nal_unit,
805
    .assemble_fragment = &ff_cbs_h2645_assemble_fragment,
806
807
    .flush             = &cbs_h266_flush,
808
    .close             = &cbs_h266_close,
809
};