FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/cbs.c
Date: 2026-04-22 18:56:46
Exec Total Coverage
Lines: 405 490 82.7%
Functions: 53 66 80.3%
Branches: 199 329 60.5%

Line Branch Exec 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 <string.h>
20
21 #include "libavutil/avassert.h"
22 #include "libavutil/buffer.h"
23 #include "libavutil/common.h"
24 #include "libavutil/mem.h"
25 #include "libavutil/opt.h"
26
27 #include "avcodec.h"
28 #include "cbs.h"
29 #include "cbs_internal.h"
30 #include "libavutil/refstruct.h"
31
32
33 static const CodedBitstreamType *const cbs_type_table[] = {
34 #if CBS_APV
35 &CBS_FUNC(type_apv),
36 #endif
37 #if CBS_AV1
38 &CBS_FUNC(type_av1),
39 #endif
40 #if CBS_H264
41 &CBS_FUNC(type_h264),
42 #endif
43 #if CBS_H265
44 &CBS_FUNC(type_h265),
45 #endif
46 #if CBS_H266
47 &CBS_FUNC(type_h266),
48 #endif
49 #if CBS_LCEVC
50 &CBS_FUNC(type_lcevc),
51 #endif
52 #if CBS_JPEG
53 &CBS_FUNC(type_jpeg),
54 #endif
55 #if CBS_MPEG2
56 &CBS_FUNC(type_mpeg2),
57 #endif
58 #if CBS_VP8
59 &CBS_FUNC(type_vp8),
60 #endif
61 #if CBS_VP9
62 &CBS_FUNC(type_vp9),
63 #endif
64 };
65
66 const enum AVCodecID CBS_FUNC(all_codec_ids)[] = {
67 #if CBS_APV
68 AV_CODEC_ID_APV,
69 #endif
70 #if CBS_AV1
71 AV_CODEC_ID_AV1,
72 #endif
73 #if CBS_H264
74 AV_CODEC_ID_H264,
75 #endif
76 #if CBS_H265
77 AV_CODEC_ID_H265,
78 #endif
79 #if CBS_H266
80 AV_CODEC_ID_H266,
81 #endif
82 #if CBS_LCEVC
83 AV_CODEC_ID_LCEVC,
84 #endif
85 #if CBS_JPEG
86 AV_CODEC_ID_MJPEG,
87 #endif
88 #if CBS_MPEG2
89 AV_CODEC_ID_MPEG2VIDEO,
90 #endif
91 #if CBS_VP8
92 AV_CODEC_ID_VP8,
93 #endif
94 #if CBS_VP9
95 AV_CODEC_ID_VP9,
96 #endif
97 AV_CODEC_ID_NONE
98 };
99
100 940 av_cold int CBS_FUNC(init)(CodedBitstreamContext **ctx_ptr,
101 enum AVCodecID codec_id, void *log_ctx)
102 {
103 CodedBitstreamContext *ctx;
104 const CodedBitstreamType *type;
105 int i;
106
107 940 type = NULL;
108
1/2
✓ Branch 0 taken 6778 times.
✗ Branch 1 not taken.
6778 for (i = 0; i < FF_ARRAY_ELEMS(cbs_type_table); i++) {
109
2/2
✓ Branch 0 taken 940 times.
✓ Branch 1 taken 5838 times.
6778 if (cbs_type_table[i]->codec_id == codec_id) {
110 940 type = cbs_type_table[i];
111 940 break;
112 }
113 }
114
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 940 times.
940 if (!type)
115 return AVERROR(EINVAL);
116
117 940 ctx = av_mallocz(sizeof(*ctx));
118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 940 times.
940 if (!ctx)
119 return AVERROR(ENOMEM);
120
121 940 ctx->log_ctx = log_ctx;
122 940 ctx->codec = type; /* Must be before any error */
123
124
1/2
✓ Branch 0 taken 940 times.
✗ Branch 1 not taken.
940 if (type->priv_data_size) {
125 940 ctx->priv_data = av_mallocz(ctx->codec->priv_data_size);
126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 940 times.
940 if (!ctx->priv_data) {
127 av_freep(&ctx);
128 return AVERROR(ENOMEM);
129 }
130
2/2
✓ Branch 0 taken 93 times.
✓ Branch 1 taken 847 times.
940 if (type->priv_class) {
131 93 *(const AVClass **)ctx->priv_data = type->priv_class;
132 93 av_opt_set_defaults(ctx->priv_data);
133 }
134 }
135
136 940 ctx->decompose_unit_types = NULL;
137
138 940 ctx->trace_enable = 0;
139 940 ctx->trace_level = AV_LOG_TRACE;
140 940 ctx->trace_context = ctx;
141
142 940 *ctx_ptr = ctx;
143 940 return 0;
144 }
145
146 4 av_cold void CBS_FUNC(flush)(CodedBitstreamContext *ctx)
147 {
148
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (ctx->codec->flush)
149 4 ctx->codec->flush(ctx);
150 4 }
151
152 1230 av_cold void CBS_FUNC(close)(CodedBitstreamContext **ctx_ptr)
153 {
154 1230 CodedBitstreamContext *ctx = *ctx_ptr;
155
156
2/2
✓ Branch 0 taken 290 times.
✓ Branch 1 taken 940 times.
1230 if (!ctx)
157 290 return;
158
159
2/2
✓ Branch 0 taken 403 times.
✓ Branch 1 taken 537 times.
940 if (ctx->codec->close)
160 403 ctx->codec->close(ctx);
161
162 940 av_freep(&ctx->write_buffer);
163
164
3/4
✓ Branch 0 taken 93 times.
✓ Branch 1 taken 847 times.
✓ Branch 2 taken 93 times.
✗ Branch 3 not taken.
940 if (ctx->codec->priv_class && ctx->priv_data)
165 93 av_opt_free(ctx->priv_data);
166
167 940 av_freep(&ctx->priv_data);
168 940 av_freep(ctx_ptr);
169 }
170
171 53097 static void cbs_unit_uninit(CodedBitstreamUnit *unit)
172 {
173 53097 av_refstruct_unref(&unit->content_ref);
174 53097 unit->content = NULL;
175
176 53097 av_buffer_unref(&unit->data_ref);
177 53097 unit->data = NULL;
178 53097 unit->data_size = 0;
179 53097 unit->data_bit_padding = 0;
180 53097 }
181
182 17897 void CBS_FUNC(fragment_reset)(CodedBitstreamFragment *frag)
183 {
184 int i;
185
186
2/2
✓ Branch 0 taken 53025 times.
✓ Branch 1 taken 17897 times.
70922 for (i = 0; i < frag->nb_units; i++)
187 53025 cbs_unit_uninit(&frag->units[i]);
188 17897 frag->nb_units = 0;
189
190 17897 av_buffer_unref(&frag->data_ref);
191 17897 frag->data = NULL;
192 17897 frag->data_size = 0;
193 17897 frag->data_bit_padding = 0;
194 17897 }
195
196 1688 av_cold void CBS_FUNC(fragment_free)(CodedBitstreamFragment *frag)
197 {
198 1688 CBS_FUNC(fragment_reset)(frag);
199
200 1688 av_freep(&frag->units);
201 1688 frag->nb_units_allocated = 0;
202 1688 }
203
204 #if CBS_READ
205 16223 static int cbs_read_fragment_content(CodedBitstreamContext *ctx,
206 CodedBitstreamFragment *frag)
207 {
208 int err, i, j;
209
210
2/2
✓ Branch 0 taken 53084 times.
✓ Branch 1 taken 16222 times.
69306 for (i = 0; i < frag->nb_units; i++) {
211 53084 CodedBitstreamUnit *unit = &frag->units[i];
212
213
2/2
✓ Branch 0 taken 11653 times.
✓ Branch 1 taken 41431 times.
53084 if (ctx->decompose_unit_types) {
214
2/2
✓ Branch 0 taken 81054 times.
✓ Branch 1 taken 3932 times.
84986 for (j = 0; j < ctx->nb_decompose_unit_types; j++) {
215
2/2
✓ Branch 0 taken 7721 times.
✓ Branch 1 taken 73333 times.
81054 if (ctx->decompose_unit_types[j] == unit->type)
216 7721 break;
217 }
218
2/2
✓ Branch 0 taken 3932 times.
✓ Branch 1 taken 7721 times.
11653 if (j >= ctx->nb_decompose_unit_types)
219 3932 continue;
220 }
221
222 49152 av_refstruct_unref(&unit->content_ref);
223 49152 unit->content = NULL;
224
225
2/4
✓ Branch 0 taken 49152 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 49152 times.
49152 av_assert0(unit->data && unit->data_ref);
226
227 49152 err = ctx->codec->read_unit(ctx, unit);
228
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49152 times.
49152 if (err == AVERROR(ENOSYS)) {
229 av_log(ctx->log_ctx, AV_LOG_VERBOSE,
230 "Decomposition unimplemented for unit %d "
231 "(type %"PRIu32").\n", i, unit->type);
232
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49152 times.
49152 } else if (err == AVERROR(EAGAIN)) {
233 av_log(ctx->log_ctx, AV_LOG_VERBOSE,
234 "Skipping decomposition of unit %d "
235 "(type %"PRIu32").\n", i, unit->type);
236 av_refstruct_unref(&unit->content_ref);
237 unit->content = NULL;
238
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 49151 times.
49152 } else if (err < 0) {
239 1 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to read unit %d "
240 "(type %"PRIu32"): %s.\n",
241 1 i, unit->type, av_err2str(err));
242 1 return err;
243 }
244 }
245
246 16222 return 0;
247 }
248
249 4113 static int cbs_fill_fragment_data(CodedBitstreamFragment *frag,
250 const uint8_t *data, size_t size)
251 {
252
2/4
✓ Branch 0 taken 4113 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4113 times.
4113 av_assert0(!frag->data && !frag->data_ref);
253
254 4113 frag->data_ref =
255 4113 av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
256
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4113 times.
4113 if (!frag->data_ref)
257 return AVERROR(ENOMEM);
258
259 4113 frag->data = frag->data_ref->data;
260 4113 frag->data_size = size;
261
262 4113 memcpy(frag->data, data, size);
263 4113 memset(frag->data + size, 0,
264 AV_INPUT_BUFFER_PADDING_SIZE);
265
266 4113 return 0;
267 }
268
269 16223 static int cbs_read_data(CodedBitstreamContext *ctx,
270 CodedBitstreamFragment *frag,
271 const AVBufferRef *buf,
272 const uint8_t *data, size_t size,
273 int header)
274 {
275 int err;
276
277
2/2
✓ Branch 0 taken 12110 times.
✓ Branch 1 taken 4113 times.
16223 if (buf) {
278 12110 frag->data_ref = av_buffer_ref(buf);
279
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
12110 if (!frag->data_ref)
280 return AVERROR(ENOMEM);
281
282 12110 frag->data = (uint8_t *)data;
283 12110 frag->data_size = size;
284
285 } else {
286 4113 err = cbs_fill_fragment_data(frag, data, size);
287
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4113 times.
4113 if (err < 0)
288 return err;
289 }
290
291 16223 err = ctx->codec->split_fragment(ctx, frag, header);
292
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16223 times.
16223 if (err < 0)
293 return err;
294
295 16223 return cbs_read_fragment_content(ctx, frag);
296 }
297
298 100 int CBS_FUNC(read_extradata)(CodedBitstreamContext *ctx,
299 CodedBitstreamFragment *frag,
300 const AVCodecParameters *par)
301 {
302 200 return cbs_read_data(ctx, frag, NULL,
303 100 par->extradata,
304 100 par->extradata_size, 1);
305 }
306
307 133 int CBS_FUNC(read_extradata_from_codec)(CodedBitstreamContext *ctx,
308 CodedBitstreamFragment *frag,
309 const AVCodecContext *avctx)
310 {
311 266 return cbs_read_data(ctx, frag, NULL,
312 133 avctx->extradata,
313 133 avctx->extradata_size, 1);
314 }
315
316 12089 int CBS_FUNC(read_packet)(CodedBitstreamContext *ctx,
317 CodedBitstreamFragment *frag,
318 const AVPacket *pkt)
319 {
320 24178 return cbs_read_data(ctx, frag, pkt->buf,
321 12089 pkt->data, pkt->size, 0);
322 }
323
324 1 int CBS_FUNC(read_packet_side_data)(CodedBitstreamContext *ctx,
325 CodedBitstreamFragment *frag,
326 const AVPacket *pkt)
327 {
328 size_t side_data_size;
329 const uint8_t *side_data =
330 1 av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
331 &side_data_size);
332
333 1 return cbs_read_data(ctx, frag, NULL,
334 side_data, side_data_size, 1);
335 }
336
337 3900 int CBS_FUNC(read)(CodedBitstreamContext *ctx,
338 CodedBitstreamFragment *frag,
339 const AVBufferRef *buf,
340 const uint8_t *data, size_t size)
341 {
342 3900 return cbs_read_data(ctx, frag, buf,
343 data, size, 0);
344 }
345 #endif
346
347 #if CBS_WRITE
348 /**
349 * Allocate a new internal data buffer of the given size in the unit.
350 *
351 * The data buffer will have input padding.
352 */
353 31946 static int cbs_alloc_unit_data(CodedBitstreamUnit *unit,
354 size_t size)
355 {
356
2/4
✓ Branch 0 taken 31946 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 31946 times.
31946 av_assert0(!unit->data && !unit->data_ref);
357
358 31946 unit->data_ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
359
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31946 times.
31946 if (!unit->data_ref)
360 return AVERROR(ENOMEM);
361
362 31946 unit->data = unit->data_ref->data;
363 31946 unit->data_size = size;
364
365 31946 memset(unit->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
366
367 31946 return 0;
368 }
369
370 31946 static int cbs_write_unit_data(CodedBitstreamContext *ctx,
371 CodedBitstreamUnit *unit)
372 {
373 PutBitContext pbc;
374 int ret;
375
376
2/2
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 31833 times.
31946 if (!ctx->write_buffer) {
377 // Initial write buffer size is 1MB.
378 113 ctx->write_buffer_size = 1024 * 1024;
379
380 113 reallocate_and_try_again:
381 113 ret = av_reallocp(&ctx->write_buffer, ctx->write_buffer_size);
382
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 113 times.
113 if (ret < 0) {
383 av_log(ctx->log_ctx, AV_LOG_ERROR, "Unable to allocate a "
384 "sufficiently large write buffer (last attempt "
385 "%zu bytes).\n", ctx->write_buffer_size);
386 return ret;
387 }
388 }
389
390 31946 init_put_bits(&pbc, ctx->write_buffer, ctx->write_buffer_size);
391
392 31946 ret = ctx->codec->write_unit(ctx, unit, &pbc);
393
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31946 times.
31946 if (ret < 0) {
394 if (ret == AVERROR(ENOSPC)) {
395 // Overflow.
396 if (ctx->write_buffer_size == INT_MAX / 8)
397 return AVERROR(ENOMEM);
398 ctx->write_buffer_size = FFMIN(2 * ctx->write_buffer_size, INT_MAX / 8);
399 goto reallocate_and_try_again;
400 }
401 // Write failed for some other reason.
402 return ret;
403 }
404
405 // Overflow but we didn't notice.
406
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 31946 times.
31946 av_assert0(put_bits_count(&pbc) <= 8 * ctx->write_buffer_size);
407
408
2/2
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 31894 times.
31946 if (put_bits_count(&pbc) % 8)
409 52 unit->data_bit_padding = 8 - put_bits_count(&pbc) % 8;
410 else
411 31894 unit->data_bit_padding = 0;
412
413 31946 flush_put_bits(&pbc);
414
415 31946 ret = cbs_alloc_unit_data(unit, put_bytes_output(&pbc));
416
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31946 times.
31946 if (ret < 0)
417 return ret;
418
419 31946 memcpy(unit->data, ctx->write_buffer, unit->data_size);
420
421 31946 return 0;
422 }
423
424 7888 int CBS_FUNC(write_fragment_data)(CodedBitstreamContext *ctx,
425 CodedBitstreamFragment *frag)
426 {
427 int err, i;
428
429
2/2
✓ Branch 0 taken 31946 times.
✓ Branch 1 taken 7888 times.
39834 for (i = 0; i < frag->nb_units; i++) {
430 31946 CodedBitstreamUnit *unit = &frag->units[i];
431
432
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31946 times.
31946 if (!unit->content)
433 continue;
434
435 31946 av_buffer_unref(&unit->data_ref);
436 31946 unit->data = NULL;
437
438 31946 err = cbs_write_unit_data(ctx, unit);
439
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31946 times.
31946 if (err < 0) {
440 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to write unit %d "
441 "(type %"PRIu32").\n", i, unit->type);
442 return err;
443 }
444
2/4
✓ Branch 0 taken 31946 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 31946 times.
31946 av_assert0(unit->data && unit->data_ref);
445 }
446
447 7888 av_buffer_unref(&frag->data_ref);
448 7888 frag->data = NULL;
449
450 7888 err = ctx->codec->assemble_fragment(ctx, frag);
451
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7888 times.
7888 if (err < 0) {
452 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to assemble fragment.\n");
453 return err;
454 }
455
2/4
✓ Branch 0 taken 7888 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7888 times.
7888 av_assert0(frag->data && frag->data_ref);
456
457 7888 return 0;
458 }
459
460 96 int CBS_FUNC(write_extradata)(CodedBitstreamContext *ctx,
461 AVCodecParameters *par,
462 CodedBitstreamFragment *frag)
463 {
464 int err;
465
466 96 err = CBS_FUNC(write_fragment_data)(ctx, frag);
467
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 if (err < 0)
468 return err;
469
470 96 av_freep(&par->extradata);
471 96 par->extradata_size = 0;
472
473
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 95 times.
96 if (!frag->data_size)
474 1 return 0;
475
476 95 par->extradata = av_malloc(frag->data_size +
477 AV_INPUT_BUFFER_PADDING_SIZE);
478
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 95 times.
95 if (!par->extradata)
479 return AVERROR(ENOMEM);
480
481 95 memcpy(par->extradata, frag->data, frag->data_size);
482 95 memset(par->extradata + frag->data_size, 0,
483 AV_INPUT_BUFFER_PADDING_SIZE);
484 95 par->extradata_size = frag->data_size;
485
486 95 return 0;
487 }
488
489 7791 int CBS_FUNC(write_packet)(CodedBitstreamContext *ctx,
490 AVPacket *pkt,
491 CodedBitstreamFragment *frag)
492 {
493 AVBufferRef *buf;
494 int err;
495
496 7791 err = CBS_FUNC(write_fragment_data)(ctx, frag);
497
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7791 times.
7791 if (err < 0)
498 return err;
499
500 7791 buf = av_buffer_ref(frag->data_ref);
501
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7791 times.
7791 if (!buf)
502 return AVERROR(ENOMEM);
503
504 7791 av_buffer_unref(&pkt->buf);
505
506 7791 pkt->buf = buf;
507 7791 pkt->data = frag->data;
508 7791 pkt->size = frag->data_size;
509
510 7791 return 0;
511 }
512 #endif
513
514
515 103887 void CBS_FUNC(trace_header)(CodedBitstreamContext *ctx,
516 const char *name)
517 {
518 #if CBS_TRACE
519
2/2
✓ Branch 0 taken 67103 times.
✓ Branch 1 taken 36781 times.
103884 if (!ctx->trace_enable)
520 67103 return;
521
522 36781 av_log(ctx->log_ctx, ctx->trace_level, "%s\n", name);
523 #endif
524 3 }
525
526 973411 void CBS_FUNC(trace_read_log)(void *trace_context,
527 GetBitContext *gbc, int length,
528 const char *str, const int *subscripts,
529 int64_t value)
530 {
531 #if CBS_TRACE
532 973411 CodedBitstreamContext *ctx = trace_context;
533 char name[256];
534 char bits[256];
535 size_t name_len, bits_len;
536 int pad, subs, i, j, k, n;
537 int position;
538
539
2/4
✓ Branch 0 taken 973411 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 973411 times.
973411 av_assert0(value >= INT_MIN && value <= UINT32_MAX);
540
541 973411 position = get_bits_count(gbc);
542
543
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 973411 times.
973411 av_assert0(length < 256);
544
2/2
✓ Branch 0 taken 3711164 times.
✓ Branch 1 taken 973411 times.
4684575 for (i = 0; i < length; i++)
545
2/2
✓ Branch 1 taken 1437909 times.
✓ Branch 2 taken 2273255 times.
3711164 bits[i] = get_bits1(gbc) ? '1' : '0';
546 973411 bits[length] = 0;
547
548
2/2
✓ Branch 0 taken 392788 times.
✓ Branch 1 taken 580623 times.
973411 subs = subscripts ? subscripts[0] : 0;
549 973411 n = 0;
550
2/2
✓ Branch 0 taken 21479487 times.
✓ Branch 1 taken 973411 times.
22452898 for (i = j = 0; str[i];) {
551
2/2
✓ Branch 0 taken 692863 times.
✓ Branch 1 taken 20786624 times.
21479487 if (str[i] == '[') {
552
2/2
✓ Branch 0 taken 691206 times.
✓ Branch 1 taken 1657 times.
692863 if (n < subs) {
553 691206 ++n;
554 691206 k = snprintf(name + j, sizeof(name) - j, "[%d", subscripts[n]);
555
2/4
✓ Branch 0 taken 691206 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 691206 times.
691206 av_assert0(k > 0 && j + k < sizeof(name));
556 691206 j += k;
557
3/4
✓ Branch 0 taken 2584381 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1893175 times.
✓ Branch 3 taken 691206 times.
2584381 for (++i; str[i] && str[i] != ']'; i++);
558
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 691206 times.
691206 av_assert0(str[i] == ']');
559 } else {
560
3/4
✓ Branch 0 taken 4971 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3314 times.
✓ Branch 3 taken 1657 times.
4971 while (str[i] && str[i] != ']')
561 3314 name[j++] = str[i++];
562
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1657 times.
1657 av_assert0(str[i] == ']');
563 }
564 } else {
565
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20786624 times.
20786624 av_assert0(j + 1 < sizeof(name));
566 20786624 name[j++] = str[i++];
567 }
568 }
569
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 973411 times.
973411 av_assert0(j + 1 < sizeof(name));
570 973411 name[j] = 0;
571
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 973411 times.
973411 av_assert0(n == subs);
572
573 973411 name_len = strlen(name);
574 973411 bits_len = length;
575
576
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 973397 times.
973411 if (name_len + bits_len > 60)
577 14 pad = bits_len + 2;
578 else
579 973397 pad = 61 - name_len;
580
581 973411 av_log(ctx->log_ctx, ctx->trace_level, "%-10d %s%*s = %"PRId64"\n",
582 position, name, pad, bits, value);
583 #endif
584 973411 }
585
586 973411 void CBS_FUNC(trace_write_log)(void *trace_context,
587 PutBitContext *pbc, int length,
588 const char *str, const int *subscripts,
589 int64_t value)
590 {
591 #if CBS_TRACE
592 973411 CodedBitstreamContext *ctx = trace_context;
593
594 // Ensure that the syntax element is written to the output buffer,
595 // make a GetBitContext pointed at the start position, then call the
596 // read log function which can read the bits back to log them.
597
598 GetBitContext gbc;
599 int position;
600
601
2/2
✓ Branch 0 taken 973172 times.
✓ Branch 1 taken 239 times.
973411 if (length > 0) {
602 PutBitContext flush;
603 973172 flush = *pbc;
604 973172 flush_put_bits(&flush);
605 }
606
607 973411 position = put_bits_count(pbc);
608
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 973411 times.
973411 av_assert0(position >= length);
609
610 973411 init_get_bits(&gbc, pbc->buf, position);
611
612 973411 skip_bits_long(&gbc, position - length);
613
614 973411 CBS_FUNC(trace_read_log)(ctx, &gbc, length, str, subscripts, value);
615 #endif
616 973411 }
617
618 #if CBS_READ
619 2448214 static av_always_inline int cbs_read_unsigned(CodedBitstreamContext *ctx,
620 GetBitContext *gbc,
621 int width, const char *name,
622 const int *subscripts,
623 uint32_t *write_to,
624 uint32_t range_min,
625 uint32_t range_max)
626 {
627 uint32_t value;
628
629
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2448052 times.
2448052 CBS_TRACE_READ_START();
630
631
2/4
✓ Branch 0 taken 2448214 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2448214 times.
2448214 av_assert0(width > 0 && width <= 32);
632
633
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2448213 times.
2448214 if (get_bits_left(gbc) < width) {
634 1 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at "
635 "%s: bitstream ended.\n", name);
636 1 return AVERROR_INVALIDDATA;
637 }
638
639 2448213 value = get_bits_long(gbc, width);
640
641
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2448051 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2448051 CBS_TRACE_READ_END();
642
643
2/4
✓ Branch 0 taken 2448213 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2448213 times.
2448213 if (value < range_min || value > range_max) {
644 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
645 "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
646 name, value, range_min, range_max);
647 return AVERROR_INVALIDDATA;
648 }
649
650 2448213 *write_to = value;
651 2448213 return 0;
652 }
653
654 1856521 int CBS_FUNC(read_unsigned)(CodedBitstreamContext *ctx, GetBitContext *gbc,
655 int width, const char *name,
656 const int *subscripts, uint32_t *write_to,
657 uint32_t range_min, uint32_t range_max)
658 {
659 1856521 return cbs_read_unsigned(ctx, gbc, width, name, subscripts,
660 write_to, range_min, range_max);
661 }
662
663 591693 int CBS_FUNC(read_simple_unsigned)(CodedBitstreamContext *ctx, GetBitContext *gbc,
664 int width, const char *name, uint32_t *write_to)
665 {
666 591693 return cbs_read_unsigned(ctx, gbc, width, name, NULL,
667 write_to, 0, UINT32_MAX);
668 }
669 #endif
670
671 #if CBS_WRITE
672 943391 int CBS_FUNC(write_unsigned)(CodedBitstreamContext *ctx, PutBitContext *pbc,
673 int width, const char *name,
674 const int *subscripts, uint32_t value,
675 uint32_t range_min, uint32_t range_max)
676 {
677
2/2
✓ Branch 0 taken 734550 times.
✓ Branch 1 taken 208841 times.
943391 CBS_TRACE_WRITE_START();
678
679
2/4
✓ Branch 0 taken 943391 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 943391 times.
943391 av_assert0(width > 0 && width <= 32);
680
681
2/4
✓ Branch 0 taken 943391 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 943391 times.
943391 if (value < range_min || value > range_max) {
682 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
683 "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
684 name, value, range_min, range_max);
685 return AVERROR_INVALIDDATA;
686 }
687
688
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 943391 times.
943391 if (put_bits_left(pbc) < width)
689 return AVERROR(ENOSPC);
690
691 943391 put_bits63(pbc, width, value);
692
693
3/4
✓ Branch 0 taken 734550 times.
✓ Branch 1 taken 208841 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 734550 times.
943391 CBS_TRACE_WRITE_END();
694
695 943391 return 0;
696 }
697
698 267642 int CBS_FUNC(write_simple_unsigned)(CodedBitstreamContext *ctx, PutBitContext *pbc,
699 int width, const char *name, uint32_t value)
700 {
701 535284 return CBS_FUNC(write_unsigned)(ctx, pbc, width, name, NULL,
702 267642 value, 0, MAX_UINT_BITS(width));
703 }
704 #endif
705
706 #if CBS_READ
707 50 int CBS_FUNC(read_signed)(CodedBitstreamContext *ctx, GetBitContext *gbc,
708 int width, const char *name,
709 const int *subscripts, int32_t *write_to,
710 int32_t range_min, int32_t range_max)
711 {
712 int32_t value;
713
714
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
50 CBS_TRACE_READ_START();
715
716
2/4
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 50 times.
50 av_assert0(width > 0 && width <= 32);
717
718
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 50 times.
50 if (get_bits_left(gbc) < width) {
719 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at "
720 "%s: bitstream ended.\n", name);
721 return AVERROR_INVALIDDATA;
722 }
723
724 50 value = get_sbits_long(gbc, width);
725
726
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
50 CBS_TRACE_READ_END();
727
728
2/4
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 50 times.
50 if (value < range_min || value > range_max) {
729 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
730 "%"PRId32", but must be in [%"PRId32",%"PRId32"].\n",
731 name, value, range_min, range_max);
732 return AVERROR_INVALIDDATA;
733 }
734
735 50 *write_to = value;
736 50 return 0;
737 }
738 #endif
739
740 #if CBS_WRITE
741 50 int CBS_FUNC(write_signed)(CodedBitstreamContext *ctx, PutBitContext *pbc,
742 int width, const char *name,
743 const int *subscripts, int32_t value,
744 int32_t range_min, int32_t range_max)
745 {
746
1/2
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
50 CBS_TRACE_WRITE_START();
747
748
2/4
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 50 times.
50 av_assert0(width > 0 && width <= 32);
749
750
2/4
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 50 times.
50 if (value < range_min || value > range_max) {
751 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
752 "%"PRId32", but must be in [%"PRId32",%"PRId32"].\n",
753 name, value, range_min, range_max);
754 return AVERROR_INVALIDDATA;
755 }
756
757
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 50 times.
50 if (put_bits_left(pbc) < width)
758 return AVERROR(ENOSPC);
759
760 50 put_bits63(pbc, width, zero_extend(value, width));
761
762
2/4
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
50 CBS_TRACE_WRITE_END();
763
764 50 return 0;
765 }
766 #endif
767
768
769 53097 static int cbs_insert_unit(CodedBitstreamFragment *frag,
770 int position)
771 {
772 CodedBitstreamUnit *units;
773
774
2/2
✓ Branch 0 taken 50210 times.
✓ Branch 1 taken 2887 times.
53097 if (frag->nb_units < frag->nb_units_allocated) {
775 50210 units = frag->units;
776
777
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50210 times.
50210 if (position < frag->nb_units)
778 memmove(units + position + 1, units + position,
779 (frag->nb_units - position) * sizeof(*units));
780 } else {
781 2887 units = av_malloc_array(frag->nb_units*2 + 1, sizeof(*units));
782
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2887 times.
2887 if (!units)
783 return AVERROR(ENOMEM);
784
785 2887 frag->nb_units_allocated = 2*frag->nb_units_allocated + 1;
786
787
2/2
✓ Branch 0 taken 1503 times.
✓ Branch 1 taken 1384 times.
2887 if (position > 0)
788 1503 memcpy(units, frag->units, position * sizeof(*units));
789
790
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2887 times.
2887 if (position < frag->nb_units)
791 memcpy(units + position + 1, frag->units + position,
792 (frag->nb_units - position) * sizeof(*units));
793
794 2887 av_free(frag->units);
795 2887 frag->units = units;
796 }
797
798 53097 memset(units + position, 0, sizeof(*units));
799
800 53097 ++frag->nb_units;
801
802 53097 return 0;
803 }
804
805 13 int CBS_FUNC(insert_unit_content)(CodedBitstreamFragment *frag,
806 int position,
807 CodedBitstreamUnitType type,
808 void *content,
809 void *content_ref)
810 {
811 CodedBitstreamUnit *unit;
812 int err;
813
814
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (position == -1)
815 13 position = frag->nb_units;
816
2/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
13 av_assert0(position >= 0 && position <= frag->nb_units);
817
818 13 err = cbs_insert_unit(frag, position);
819
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (err < 0)
820 return err;
821
822
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (content_ref) {
823 // Create our own reference out of the user-supplied one.
824 13 content_ref = av_refstruct_ref(content_ref);
825 }
826
827 13 unit = &frag->units[position];
828 13 unit->type = type;
829 13 unit->content = content;
830 13 unit->content_ref = content_ref;
831
832 13 return 0;
833 }
834
835 53084 static int cbs_insert_unit_data(CodedBitstreamFragment *frag,
836 CodedBitstreamUnitType type,
837 uint8_t *data, size_t data_size,
838 AVBufferRef *data_buf,
839 int position)
840 {
841 CodedBitstreamUnit *unit;
842 AVBufferRef *data_ref;
843 int err;
844
845
2/4
✓ Branch 0 taken 53084 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53084 times.
53084 av_assert0(position >= 0 && position <= frag->nb_units);
846
847
1/2
✓ Branch 0 taken 53084 times.
✗ Branch 1 not taken.
53084 if (data_buf)
848 53084 data_ref = av_buffer_ref(data_buf);
849 else
850 data_ref = av_buffer_create(data, data_size, NULL, NULL, 0);
851
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53084 times.
53084 if (!data_ref) {
852 if (!data_buf)
853 av_free(data);
854 return AVERROR(ENOMEM);
855 }
856
857 53084 err = cbs_insert_unit(frag, position);
858
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53084 times.
53084 if (err < 0) {
859 av_buffer_unref(&data_ref);
860 return err;
861 }
862
863 53084 unit = &frag->units[position];
864 53084 unit->type = type;
865 53084 unit->data = data;
866 53084 unit->data_size = data_size;
867 53084 unit->data_ref = data_ref;
868
869 53084 return 0;
870 }
871
872 53084 int CBS_FUNC(append_unit_data)(CodedBitstreamFragment *frag,
873 CodedBitstreamUnitType type,
874 uint8_t *data, size_t data_size,
875 AVBufferRef *data_buf)
876 {
877 53084 return cbs_insert_unit_data(frag, type,
878 data, data_size, data_buf,
879 frag->nb_units);
880 }
881
882 72 void CBS_FUNC(delete_unit)(CodedBitstreamFragment *frag,
883 int position)
884 {
885
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 72 times.
72 av_assert0(0 <= position && position < frag->nb_units
886 && "Unit to be deleted not in fragment.");
887
888 72 cbs_unit_uninit(&frag->units[position]);
889
890 72 --frag->nb_units;
891
892
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if (frag->nb_units > 0)
893 72 memmove(frag->units + position,
894 72 frag->units + position + 1,
895 72 (frag->nb_units - position) * sizeof(*frag->units));
896 72 }
897
898 34539 static void cbs_default_free_unit_content(AVRefStructOpaque opaque, void *content)
899 {
900 34539 CodedBitstreamUnitTypeDescriptor *desc = opaque.c;
901
902
2/2
✓ Branch 0 taken 42515 times.
✓ Branch 1 taken 34539 times.
77054 for (int i = 0; i < desc->type.ref.nb_offsets; i++) {
903 42515 void **ptr = (void**)((char*)content + desc->type.ref.offsets[i]);
904 42515 av_buffer_unref((AVBufferRef**)(ptr + 1));
905 }
906 34539 }
907
908 static CodedBitstreamUnitTypeDescriptor
909 49458 *cbs_find_unit_type_desc(CodedBitstreamContext *ctx,
910 CodedBitstreamUnit *unit)
911 {
912 CodedBitstreamUnitTypeDescriptor *desc;
913 int i, j;
914
915
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49458 times.
49458 if (!ctx->codec->unit_types)
916 return NULL;
917
918 284772 for (i = 0;; i++) {
919 284772 desc = &ctx->codec->unit_types[i];
920
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 284772 times.
284772 if (desc->nb_unit_types == 0)
921 break;
922
2/2
✓ Branch 0 taken 20226 times.
✓ Branch 1 taken 264546 times.
284772 if (desc->nb_unit_types == CBS_UNIT_TYPE_RANGE) {
923
1/2
✓ Branch 0 taken 20226 times.
✗ Branch 1 not taken.
20226 if (unit->type >= desc->unit_type.range.start &&
924
2/2
✓ Branch 0 taken 16271 times.
✓ Branch 1 taken 3955 times.
20226 unit->type <= desc->unit_type.range.end)
925 16271 return desc;
926 } else {
927
2/2
✓ Branch 0 taken 305775 times.
✓ Branch 1 taken 231359 times.
537134 for (j = 0; j < desc->nb_unit_types; j++) {
928
2/2
✓ Branch 0 taken 33187 times.
✓ Branch 1 taken 272588 times.
305775 if (desc->unit_type.list[j] == unit->type)
929 33187 return desc;
930 }
931 }
932 }
933 return NULL;
934 }
935
936 49458 static void *cbs_alloc_content(CodedBitstreamUnitTypeDescriptor *desc)
937 {
938 49458 return av_refstruct_alloc_ext_c(desc->content_size, 0,
939 49458 (AVRefStructOpaque){ .c = desc },
940
2/2
✓ Branch 0 taken 14919 times.
✓ Branch 1 taken 34539 times.
49458 desc->content_type == CBS_CONTENT_TYPE_COMPLEX
941 ? desc->type.complex.content_free
942 : cbs_default_free_unit_content);
943 }
944
945 49152 int CBS_FUNC(alloc_unit_content)(CodedBitstreamContext *ctx,
946 CodedBitstreamUnit *unit)
947 {
948 CodedBitstreamUnitTypeDescriptor *desc;
949
950
2/4
✓ Branch 0 taken 49152 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 49152 times.
49152 av_assert0(!unit->content && !unit->content_ref);
951
952 49152 desc = cbs_find_unit_type_desc(ctx, unit);
953
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49152 times.
49152 if (!desc)
954 return AVERROR(ENOSYS);
955
956 49152 unit->content_ref = cbs_alloc_content(desc);
957
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49152 times.
49152 if (!unit->content_ref)
958 return AVERROR(ENOMEM);
959 49152 unit->content = unit->content_ref;
960
961 49152 return 0;
962 }
963
964 306 static int cbs_clone_noncomplex_unit_content(void **clonep,
965 const CodedBitstreamUnit *unit,
966 CodedBitstreamUnitTypeDescriptor *desc)
967 {
968 const uint8_t *src;
969 uint8_t *copy;
970 int err;
971
972
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 306 times.
306 av_assert0(unit->content);
973 306 src = unit->content;
974
975 306 copy = cbs_alloc_content(desc);
976
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 306 times.
306 if (!copy)
977 return AVERROR(ENOMEM);
978 306 memcpy(copy, src, desc->content_size);
979
2/2
✓ Branch 0 taken 306 times.
✓ Branch 1 taken 306 times.
612 for (int i = 0; i < desc->type.ref.nb_offsets; i++) {
980 306 void **ptr = (void**)(copy + desc->type.ref.offsets[i]);
981 /* Zero all the AVBufferRefs as they are owned by src. */
982 306 *(ptr + 1) = NULL;
983 }
984
985
2/2
✓ Branch 0 taken 306 times.
✓ Branch 1 taken 306 times.
612 for (int i = 0; i < desc->type.ref.nb_offsets; i++) {
986 306 const uint8_t *const *src_ptr = (const uint8_t* const*)(src + desc->type.ref.offsets[i]);
987 306 const AVBufferRef *src_buf = *(AVBufferRef**)(src_ptr + 1);
988 306 uint8_t **copy_ptr = (uint8_t**)(copy + desc->type.ref.offsets[i]);
989 306 AVBufferRef **copy_buf = (AVBufferRef**)(copy_ptr + 1);
990
991
1/2
✓ Branch 0 taken 306 times.
✗ Branch 1 not taken.
306 if (!*src_ptr) {
992
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 306 times.
306 av_assert0(!src_buf);
993 306 continue;
994 }
995 if (!src_buf) {
996 // We can't handle a non-refcounted pointer here - we don't
997 // have enough information to handle whatever structure lies
998 // at the other end of it.
999 err = AVERROR(EINVAL);
1000 goto fail;
1001 }
1002
1003 *copy_buf = av_buffer_ref(src_buf);
1004 if (!*copy_buf) {
1005 err = AVERROR(ENOMEM);
1006 goto fail;
1007 }
1008 }
1009 306 *clonep = copy;
1010
1011 306 return 0;
1012
1013 fail:
1014 av_refstruct_unref(&copy);
1015 return err;
1016 }
1017
1018 /*
1019 * On success, unit->content and unit->content_ref are updated with
1020 * the new content; unit is untouched on failure.
1021 * Any old content_ref is simply overwritten and not freed.
1022 */
1023 306 static int cbs_clone_unit_content(CodedBitstreamContext *ctx,
1024 CodedBitstreamUnit *unit)
1025 {
1026 CodedBitstreamUnitTypeDescriptor *desc;
1027 void *new_content;
1028 int err;
1029
1030 306 desc = cbs_find_unit_type_desc(ctx, unit);
1031
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 306 times.
306 if (!desc)
1032 return AVERROR(ENOSYS);
1033
1034
1/3
✓ Branch 0 taken 306 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
306 switch (desc->content_type) {
1035 306 case CBS_CONTENT_TYPE_INTERNAL_REFS:
1036 306 err = cbs_clone_noncomplex_unit_content(&new_content, unit, desc);
1037 306 break;
1038
1039 case CBS_CONTENT_TYPE_COMPLEX:
1040 if (!desc->type.complex.content_clone)
1041 return AVERROR_PATCHWELCOME;
1042 err = desc->type.complex.content_clone(&new_content, unit);
1043 break;
1044
1045 default:
1046 av_assert0(0 && "Invalid content type.");
1047 }
1048
1049
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 306 times.
306 if (err < 0)
1050 return err;
1051
1052 306 unit->content_ref = new_content;
1053 306 unit->content = new_content;
1054 306 return 0;
1055 }
1056
1057 16012 int CBS_FUNC(make_unit_refcounted)(CodedBitstreamContext *ctx,
1058 CodedBitstreamUnit *unit)
1059 {
1060
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16012 times.
16012 av_assert0(unit->content);
1061
1/2
✓ Branch 0 taken 16012 times.
✗ Branch 1 not taken.
16012 if (unit->content_ref)
1062 16012 return 0;
1063 return cbs_clone_unit_content(ctx, unit);
1064 }
1065
1066 306 int CBS_FUNC(make_unit_writable)(CodedBitstreamContext *ctx,
1067 CodedBitstreamUnit *unit)
1068 {
1069 306 void *ref = unit->content_ref;
1070 int err;
1071
1072
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 306 times.
306 av_assert0(unit->content);
1073
2/4
✓ Branch 0 taken 306 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 306 times.
306 if (ref && av_refstruct_exclusive(ref))
1074 return 0;
1075
1076 306 err = cbs_clone_unit_content(ctx, unit);
1077
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 306 times.
306 if (err < 0)
1078 return err;
1079 306 av_refstruct_unref(&ref);
1080 306 return 0;
1081 }
1082
1083 696 void CBS_FUNC(discard_units)(CodedBitstreamContext *ctx,
1084 CodedBitstreamFragment *frag,
1085 enum AVDiscard skip,
1086 int flags)
1087 {
1088
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 696 times.
696 if (!ctx->codec->discarded_unit)
1089 return;
1090
1091
2/2
✓ Branch 0 taken 1292 times.
✓ Branch 1 taken 134 times.
1426 for (int i = frag->nb_units - 1; i >= 0; i--) {
1092
2/2
✓ Branch 1 taken 562 times.
✓ Branch 2 taken 730 times.
1292 if (ctx->codec->discarded_unit(ctx, &frag->units[i], skip)) {
1093 // discard all units
1094
1/2
✓ Branch 0 taken 562 times.
✗ Branch 1 not taken.
562 if (!(flags & DISCARD_FLAG_KEEP_NON_VCL)) {
1095 562 CBS_FUNC(fragment_free)(frag);
1096 562 return;
1097 }
1098
1099 CBS_FUNC(delete_unit)(frag, i);
1100 }
1101 }
1102 }
1103