FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/cbs.c
Date: 2025-04-25 22:50:00
Exec Total Coverage
Lines: 404 490 82.4%
Functions: 46 66 69.7%
Branches: 201 331 60.7%

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