FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/cbs.c
Date: 2023-12-07 21:54:23
Exec Total Coverage
Lines: 402 493 81.5%
Functions: 42 43 97.7%
Branches: 202 335 60.3%

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