avformat/mpeg: demux ivtv captions
[ffmpeg.git] / libavcodec / cbs.c
blob01dd916d81071d7a62887e6bf3e8da89c3395d22
1 /*
2 * This file is part of FFmpeg.
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.
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.
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
19 #include <string.h>
21 #include "config.h"
23 #include "libavutil/avassert.h"
24 #include "libavutil/buffer.h"
25 #include "libavutil/common.h"
26 #include "libavutil/mem.h"
27 #include "libavutil/opt.h"
29 #include "avcodec.h"
30 #include "cbs.h"
31 #include "cbs_internal.h"
32 #include "libavutil/refstruct.h"
35 static const CodedBitstreamType *const cbs_type_table[] = {
36 #if CONFIG_CBS_AV1
37 &ff_cbs_type_av1,
38 #endif
39 #if CONFIG_CBS_H264
40 &ff_cbs_type_h264,
41 #endif
42 #if CONFIG_CBS_H265
43 &ff_cbs_type_h265,
44 #endif
45 #if CONFIG_CBS_H266
46 &ff_cbs_type_h266,
47 #endif
48 #if CONFIG_CBS_JPEG
49 &ff_cbs_type_jpeg,
50 #endif
51 #if CONFIG_CBS_MPEG2
52 &ff_cbs_type_mpeg2,
53 #endif
54 #if CONFIG_CBS_VP8
55 &ff_cbs_type_vp8,
56 #endif
57 #if CONFIG_CBS_VP9
58 &ff_cbs_type_vp9,
59 #endif
62 const enum AVCodecID ff_cbs_all_codec_ids[] = {
63 #if CONFIG_CBS_AV1
64 AV_CODEC_ID_AV1,
65 #endif
66 #if CONFIG_CBS_H264
67 AV_CODEC_ID_H264,
68 #endif
69 #if CONFIG_CBS_H265
70 AV_CODEC_ID_H265,
71 #endif
72 #if CONFIG_CBS_H266
73 AV_CODEC_ID_H266,
74 #endif
75 #if CONFIG_CBS_JPEG
76 AV_CODEC_ID_MJPEG,
77 #endif
78 #if CONFIG_CBS_MPEG2
79 AV_CODEC_ID_MPEG2VIDEO,
80 #endif
81 #if CONFIG_CBS_VP8
82 AV_CODEC_ID_VP8,
83 #endif
84 #if CONFIG_CBS_VP9
85 AV_CODEC_ID_VP9,
86 #endif
87 AV_CODEC_ID_NONE
90 av_cold int ff_cbs_init(CodedBitstreamContext **ctx_ptr,
91 enum AVCodecID codec_id, void *log_ctx)
93 CodedBitstreamContext *ctx;
94 const CodedBitstreamType *type;
95 int i;
97 type = NULL;
98 for (i = 0; i < FF_ARRAY_ELEMS(cbs_type_table); i++) {
99 if (cbs_type_table[i]->codec_id == codec_id) {
100 type = cbs_type_table[i];
101 break;
104 if (!type)
105 return AVERROR(EINVAL);
107 ctx = av_mallocz(sizeof(*ctx));
108 if (!ctx)
109 return AVERROR(ENOMEM);
111 ctx->log_ctx = log_ctx;
112 ctx->codec = type; /* Must be before any error */
114 if (type->priv_data_size) {
115 ctx->priv_data = av_mallocz(ctx->codec->priv_data_size);
116 if (!ctx->priv_data) {
117 av_freep(&ctx);
118 return AVERROR(ENOMEM);
120 if (type->priv_class) {
121 *(const AVClass **)ctx->priv_data = type->priv_class;
122 av_opt_set_defaults(ctx->priv_data);
126 ctx->decompose_unit_types = NULL;
128 ctx->trace_enable = 0;
129 ctx->trace_level = AV_LOG_TRACE;
130 ctx->trace_context = ctx;
132 *ctx_ptr = ctx;
133 return 0;
136 av_cold void ff_cbs_flush(CodedBitstreamContext *ctx)
138 if (ctx->codec->flush)
139 ctx->codec->flush(ctx);
142 av_cold void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
144 CodedBitstreamContext *ctx = *ctx_ptr;
146 if (!ctx)
147 return;
149 if (ctx->codec->close)
150 ctx->codec->close(ctx);
152 av_freep(&ctx->write_buffer);
154 if (ctx->codec->priv_class && ctx->priv_data)
155 av_opt_free(ctx->priv_data);
157 av_freep(&ctx->priv_data);
158 av_freep(ctx_ptr);
161 static void cbs_unit_uninit(CodedBitstreamUnit *unit)
163 av_refstruct_unref(&unit->content_ref);
164 unit->content = NULL;
166 av_buffer_unref(&unit->data_ref);
167 unit->data = NULL;
168 unit->data_size = 0;
169 unit->data_bit_padding = 0;
172 void ff_cbs_fragment_reset(CodedBitstreamFragment *frag)
174 int i;
176 for (i = 0; i < frag->nb_units; i++)
177 cbs_unit_uninit(&frag->units[i]);
178 frag->nb_units = 0;
180 av_buffer_unref(&frag->data_ref);
181 frag->data = NULL;
182 frag->data_size = 0;
183 frag->data_bit_padding = 0;
186 av_cold void ff_cbs_fragment_free(CodedBitstreamFragment *frag)
188 ff_cbs_fragment_reset(frag);
190 av_freep(&frag->units);
191 frag->nb_units_allocated = 0;
194 static int cbs_read_fragment_content(CodedBitstreamContext *ctx,
195 CodedBitstreamFragment *frag)
197 int err, i, j;
199 for (i = 0; i < frag->nb_units; i++) {
200 CodedBitstreamUnit *unit = &frag->units[i];
202 if (ctx->decompose_unit_types) {
203 for (j = 0; j < ctx->nb_decompose_unit_types; j++) {
204 if (ctx->decompose_unit_types[j] == unit->type)
205 break;
207 if (j >= ctx->nb_decompose_unit_types)
208 continue;
211 av_refstruct_unref(&unit->content_ref);
212 unit->content = NULL;
214 av_assert0(unit->data && unit->data_ref);
216 err = ctx->codec->read_unit(ctx, unit);
217 if (err == AVERROR(ENOSYS)) {
218 av_log(ctx->log_ctx, AV_LOG_VERBOSE,
219 "Decomposition unimplemented for unit %d "
220 "(type %"PRIu32").\n", i, unit->type);
221 } else if (err == AVERROR(EAGAIN)) {
222 av_log(ctx->log_ctx, AV_LOG_VERBOSE,
223 "Skipping decomposition of unit %d "
224 "(type %"PRIu32").\n", i, unit->type);
225 av_refstruct_unref(&unit->content_ref);
226 unit->content = NULL;
227 } else if (err < 0) {
228 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to read unit %d "
229 "(type %"PRIu32").\n", i, unit->type);
230 return err;
234 return 0;
237 static int cbs_fill_fragment_data(CodedBitstreamFragment *frag,
238 const uint8_t *data, size_t size)
240 av_assert0(!frag->data && !frag->data_ref);
242 frag->data_ref =
243 av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
244 if (!frag->data_ref)
245 return AVERROR(ENOMEM);
247 frag->data = frag->data_ref->data;
248 frag->data_size = size;
250 memcpy(frag->data, data, size);
251 memset(frag->data + size, 0,
252 AV_INPUT_BUFFER_PADDING_SIZE);
254 return 0;
257 static int cbs_read_data(CodedBitstreamContext *ctx,
258 CodedBitstreamFragment *frag,
259 AVBufferRef *buf,
260 const uint8_t *data, size_t size,
261 int header)
263 int err;
265 if (buf) {
266 frag->data_ref = av_buffer_ref(buf);
267 if (!frag->data_ref)
268 return AVERROR(ENOMEM);
270 frag->data = (uint8_t *)data;
271 frag->data_size = size;
273 } else {
274 err = cbs_fill_fragment_data(frag, data, size);
275 if (err < 0)
276 return err;
279 err = ctx->codec->split_fragment(ctx, frag, header);
280 if (err < 0)
281 return err;
283 return cbs_read_fragment_content(ctx, frag);
286 int ff_cbs_read_extradata(CodedBitstreamContext *ctx,
287 CodedBitstreamFragment *frag,
288 const AVCodecParameters *par)
290 return cbs_read_data(ctx, frag, NULL,
291 par->extradata,
292 par->extradata_size, 1);
295 int ff_cbs_read_extradata_from_codec(CodedBitstreamContext *ctx,
296 CodedBitstreamFragment *frag,
297 const AVCodecContext *avctx)
299 return cbs_read_data(ctx, frag, NULL,
300 avctx->extradata,
301 avctx->extradata_size, 1);
304 int ff_cbs_read_packet(CodedBitstreamContext *ctx,
305 CodedBitstreamFragment *frag,
306 const AVPacket *pkt)
308 return cbs_read_data(ctx, frag, pkt->buf,
309 pkt->data, pkt->size, 0);
312 int ff_cbs_read_packet_side_data(CodedBitstreamContext *ctx,
313 CodedBitstreamFragment *frag,
314 const AVPacket *pkt)
316 size_t side_data_size;
317 const uint8_t *side_data =
318 av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
319 &side_data_size);
321 return cbs_read_data(ctx, frag, NULL,
322 side_data, side_data_size, 1);
325 int ff_cbs_read(CodedBitstreamContext *ctx,
326 CodedBitstreamFragment *frag,
327 const uint8_t *data, size_t size)
329 return cbs_read_data(ctx, frag, NULL,
330 data, size, 0);
334 * Allocate a new internal data buffer of the given size in the unit.
336 * The data buffer will have input padding.
338 static int cbs_alloc_unit_data(CodedBitstreamUnit *unit,
339 size_t size)
341 av_assert0(!unit->data && !unit->data_ref);
343 unit->data_ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
344 if (!unit->data_ref)
345 return AVERROR(ENOMEM);
347 unit->data = unit->data_ref->data;
348 unit->data_size = size;
350 memset(unit->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
352 return 0;
355 static int cbs_write_unit_data(CodedBitstreamContext *ctx,
356 CodedBitstreamUnit *unit)
358 PutBitContext pbc;
359 int ret;
361 if (!ctx->write_buffer) {
362 // Initial write buffer size is 1MB.
363 ctx->write_buffer_size = 1024 * 1024;
365 reallocate_and_try_again:
366 ret = av_reallocp(&ctx->write_buffer, ctx->write_buffer_size);
367 if (ret < 0) {
368 av_log(ctx->log_ctx, AV_LOG_ERROR, "Unable to allocate a "
369 "sufficiently large write buffer (last attempt "
370 "%"SIZE_SPECIFIER" bytes).\n", ctx->write_buffer_size);
371 return ret;
375 init_put_bits(&pbc, ctx->write_buffer, ctx->write_buffer_size);
377 ret = ctx->codec->write_unit(ctx, unit, &pbc);
378 if (ret < 0) {
379 if (ret == AVERROR(ENOSPC)) {
380 // Overflow.
381 if (ctx->write_buffer_size == INT_MAX / 8)
382 return AVERROR(ENOMEM);
383 ctx->write_buffer_size = FFMIN(2 * ctx->write_buffer_size, INT_MAX / 8);
384 goto reallocate_and_try_again;
386 // Write failed for some other reason.
387 return ret;
390 // Overflow but we didn't notice.
391 av_assert0(put_bits_count(&pbc) <= 8 * ctx->write_buffer_size);
393 if (put_bits_count(&pbc) % 8)
394 unit->data_bit_padding = 8 - put_bits_count(&pbc) % 8;
395 else
396 unit->data_bit_padding = 0;
398 flush_put_bits(&pbc);
400 ret = cbs_alloc_unit_data(unit, put_bytes_output(&pbc));
401 if (ret < 0)
402 return ret;
404 memcpy(unit->data, ctx->write_buffer, unit->data_size);
406 return 0;
409 int ff_cbs_write_fragment_data(CodedBitstreamContext *ctx,
410 CodedBitstreamFragment *frag)
412 int err, i;
414 for (i = 0; i < frag->nb_units; i++) {
415 CodedBitstreamUnit *unit = &frag->units[i];
417 if (!unit->content)
418 continue;
420 av_buffer_unref(&unit->data_ref);
421 unit->data = NULL;
423 err = cbs_write_unit_data(ctx, unit);
424 if (err < 0) {
425 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to write unit %d "
426 "(type %"PRIu32").\n", i, unit->type);
427 return err;
429 av_assert0(unit->data && unit->data_ref);
432 av_buffer_unref(&frag->data_ref);
433 frag->data = NULL;
435 err = ctx->codec->assemble_fragment(ctx, frag);
436 if (err < 0) {
437 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to assemble fragment.\n");
438 return err;
440 av_assert0(frag->data && frag->data_ref);
442 return 0;
445 int ff_cbs_write_extradata(CodedBitstreamContext *ctx,
446 AVCodecParameters *par,
447 CodedBitstreamFragment *frag)
449 int err;
451 err = ff_cbs_write_fragment_data(ctx, frag);
452 if (err < 0)
453 return err;
455 av_freep(&par->extradata);
456 par->extradata_size = 0;
458 if (!frag->data_size)
459 return 0;
461 par->extradata = av_malloc(frag->data_size +
462 AV_INPUT_BUFFER_PADDING_SIZE);
463 if (!par->extradata)
464 return AVERROR(ENOMEM);
466 memcpy(par->extradata, frag->data, frag->data_size);
467 memset(par->extradata + frag->data_size, 0,
468 AV_INPUT_BUFFER_PADDING_SIZE);
469 par->extradata_size = frag->data_size;
471 return 0;
474 int ff_cbs_write_packet(CodedBitstreamContext *ctx,
475 AVPacket *pkt,
476 CodedBitstreamFragment *frag)
478 AVBufferRef *buf;
479 int err;
481 err = ff_cbs_write_fragment_data(ctx, frag);
482 if (err < 0)
483 return err;
485 buf = av_buffer_ref(frag->data_ref);
486 if (!buf)
487 return AVERROR(ENOMEM);
489 av_buffer_unref(&pkt->buf);
491 pkt->buf = buf;
492 pkt->data = frag->data;
493 pkt->size = frag->data_size;
495 return 0;
499 void ff_cbs_trace_header(CodedBitstreamContext *ctx,
500 const char *name)
502 if (!ctx->trace_enable)
503 return;
505 av_log(ctx->log_ctx, ctx->trace_level, "%s\n", name);
508 void ff_cbs_trace_read_log(void *trace_context,
509 GetBitContext *gbc, int length,
510 const char *str, const int *subscripts,
511 int64_t value)
513 CodedBitstreamContext *ctx = trace_context;
514 char name[256];
515 char bits[256];
516 size_t name_len, bits_len;
517 int pad, subs, i, j, k, n;
518 int position;
520 av_assert0(value >= INT_MIN && value <= UINT32_MAX);
522 position = get_bits_count(gbc);
524 av_assert0(length < 256);
525 for (i = 0; i < length; i++)
526 bits[i] = get_bits1(gbc) ? '1' : '0';
527 bits[length] = 0;
529 subs = subscripts ? subscripts[0] : 0;
530 n = 0;
531 for (i = j = 0; str[i];) {
532 if (str[i] == '[') {
533 if (n < subs) {
534 ++n;
535 k = snprintf(name + j, sizeof(name) - j, "[%d", subscripts[n]);
536 av_assert0(k > 0 && j + k < sizeof(name));
537 j += k;
538 for (++i; str[i] && str[i] != ']'; i++);
539 av_assert0(str[i] == ']');
540 } else {
541 while (str[i] && str[i] != ']')
542 name[j++] = str[i++];
543 av_assert0(str[i] == ']');
545 } else {
546 av_assert0(j + 1 < sizeof(name));
547 name[j++] = str[i++];
550 av_assert0(j + 1 < sizeof(name));
551 name[j] = 0;
552 av_assert0(n == subs);
554 name_len = strlen(name);
555 bits_len = length;
557 if (name_len + bits_len > 60)
558 pad = bits_len + 2;
559 else
560 pad = 61 - name_len;
562 av_log(ctx->log_ctx, ctx->trace_level, "%-10d %s%*s = %"PRId64"\n",
563 position, name, pad, bits, value);
566 void ff_cbs_trace_write_log(void *trace_context,
567 PutBitContext *pbc, int length,
568 const char *str, const int *subscripts,
569 int64_t value)
571 CodedBitstreamContext *ctx = trace_context;
573 // Ensure that the syntax element is written to the output buffer,
574 // make a GetBitContext pointed at the start position, then call the
575 // read log function which can read the bits back to log them.
577 GetBitContext gbc;
578 int position;
580 if (length > 0) {
581 PutBitContext flush;
582 flush = *pbc;
583 flush_put_bits(&flush);
586 position = put_bits_count(pbc);
587 av_assert0(position >= length);
589 init_get_bits(&gbc, pbc->buf, position);
591 skip_bits_long(&gbc, position - length);
593 ff_cbs_trace_read_log(ctx, &gbc, length, str, subscripts, value);
596 static av_always_inline int cbs_read_unsigned(CodedBitstreamContext *ctx,
597 GetBitContext *gbc,
598 int width, const char *name,
599 const int *subscripts,
600 uint32_t *write_to,
601 uint32_t range_min,
602 uint32_t range_max)
604 uint32_t value;
606 CBS_TRACE_READ_START();
608 av_assert0(width > 0 && width <= 32);
610 if (get_bits_left(gbc) < width) {
611 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at "
612 "%s: bitstream ended.\n", name);
613 return AVERROR_INVALIDDATA;
616 value = get_bits_long(gbc, width);
618 CBS_TRACE_READ_END();
620 if (value < range_min || value > range_max) {
621 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
622 "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
623 name, value, range_min, range_max);
624 return AVERROR_INVALIDDATA;
627 *write_to = value;
628 return 0;
631 int ff_cbs_read_unsigned(CodedBitstreamContext *ctx, GetBitContext *gbc,
632 int width, const char *name,
633 const int *subscripts, uint32_t *write_to,
634 uint32_t range_min, uint32_t range_max)
636 return cbs_read_unsigned(ctx, gbc, width, name, subscripts,
637 write_to, range_min, range_max);
640 int ff_cbs_read_simple_unsigned(CodedBitstreamContext *ctx, GetBitContext *gbc,
641 int width, const char *name, uint32_t *write_to)
643 return cbs_read_unsigned(ctx, gbc, width, name, NULL,
644 write_to, 0, UINT32_MAX);
647 int ff_cbs_write_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc,
648 int width, const char *name,
649 const int *subscripts, uint32_t value,
650 uint32_t range_min, uint32_t range_max)
652 CBS_TRACE_WRITE_START();
654 av_assert0(width > 0 && width <= 32);
656 if (value < range_min || value > range_max) {
657 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
658 "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
659 name, value, range_min, range_max);
660 return AVERROR_INVALIDDATA;
663 if (put_bits_left(pbc) < width)
664 return AVERROR(ENOSPC);
666 if (width < 32)
667 put_bits(pbc, width, value);
668 else
669 put_bits32(pbc, value);
671 CBS_TRACE_WRITE_END();
673 return 0;
676 int ff_cbs_write_simple_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc,
677 int width, const char *name, uint32_t value)
679 return ff_cbs_write_unsigned(ctx, pbc, width, name, NULL,
680 value, 0, MAX_UINT_BITS(width));
683 int ff_cbs_read_signed(CodedBitstreamContext *ctx, GetBitContext *gbc,
684 int width, const char *name,
685 const int *subscripts, int32_t *write_to,
686 int32_t range_min, int32_t range_max)
688 int32_t value;
690 CBS_TRACE_READ_START();
692 av_assert0(width > 0 && width <= 32);
694 if (get_bits_left(gbc) < width) {
695 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at "
696 "%s: bitstream ended.\n", name);
697 return AVERROR_INVALIDDATA;
700 value = get_sbits_long(gbc, width);
702 CBS_TRACE_READ_END();
704 if (value < range_min || value > range_max) {
705 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
706 "%"PRId32", but must be in [%"PRId32",%"PRId32"].\n",
707 name, value, range_min, range_max);
708 return AVERROR_INVALIDDATA;
711 *write_to = value;
712 return 0;
715 int ff_cbs_write_signed(CodedBitstreamContext *ctx, PutBitContext *pbc,
716 int width, const char *name,
717 const int *subscripts, int32_t value,
718 int32_t range_min, int32_t range_max)
720 CBS_TRACE_WRITE_START();
722 av_assert0(width > 0 && width <= 32);
724 if (value < range_min || value > range_max) {
725 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
726 "%"PRId32", but must be in [%"PRId32",%"PRId32"].\n",
727 name, value, range_min, range_max);
728 return AVERROR_INVALIDDATA;
731 if (put_bits_left(pbc) < width)
732 return AVERROR(ENOSPC);
734 if (width < 32)
735 put_sbits(pbc, width, value);
736 else
737 put_bits32(pbc, value);
739 CBS_TRACE_WRITE_END();
741 return 0;
745 static int cbs_insert_unit(CodedBitstreamFragment *frag,
746 int position)
748 CodedBitstreamUnit *units;
750 if (frag->nb_units < frag->nb_units_allocated) {
751 units = frag->units;
753 if (position < frag->nb_units)
754 memmove(units + position + 1, units + position,
755 (frag->nb_units - position) * sizeof(*units));
756 } else {
757 units = av_malloc_array(frag->nb_units*2 + 1, sizeof(*units));
758 if (!units)
759 return AVERROR(ENOMEM);
761 frag->nb_units_allocated = 2*frag->nb_units_allocated + 1;
763 if (position > 0)
764 memcpy(units, frag->units, position * sizeof(*units));
766 if (position < frag->nb_units)
767 memcpy(units + position + 1, frag->units + position,
768 (frag->nb_units - position) * sizeof(*units));
771 memset(units + position, 0, sizeof(*units));
773 if (units != frag->units) {
774 av_free(frag->units);
775 frag->units = units;
778 ++frag->nb_units;
780 return 0;
783 int ff_cbs_insert_unit_content(CodedBitstreamFragment *frag,
784 int position,
785 CodedBitstreamUnitType type,
786 void *content,
787 void *content_ref)
789 CodedBitstreamUnit *unit;
790 int err;
792 if (position == -1)
793 position = frag->nb_units;
794 av_assert0(position >= 0 && position <= frag->nb_units);
796 err = cbs_insert_unit(frag, position);
797 if (err < 0)
798 return err;
800 if (content_ref) {
801 // Create our own reference out of the user-supplied one.
802 content_ref = av_refstruct_ref(content_ref);
805 unit = &frag->units[position];
806 unit->type = type;
807 unit->content = content;
808 unit->content_ref = content_ref;
810 return 0;
813 static int cbs_insert_unit_data(CodedBitstreamFragment *frag,
814 CodedBitstreamUnitType type,
815 uint8_t *data, size_t data_size,
816 AVBufferRef *data_buf,
817 int position)
819 CodedBitstreamUnit *unit;
820 AVBufferRef *data_ref;
821 int err;
823 av_assert0(position >= 0 && position <= frag->nb_units);
825 if (data_buf)
826 data_ref = av_buffer_ref(data_buf);
827 else
828 data_ref = av_buffer_create(data, data_size, NULL, NULL, 0);
829 if (!data_ref) {
830 if (!data_buf)
831 av_free(data);
832 return AVERROR(ENOMEM);
835 err = cbs_insert_unit(frag, position);
836 if (err < 0) {
837 av_buffer_unref(&data_ref);
838 return err;
841 unit = &frag->units[position];
842 unit->type = type;
843 unit->data = data;
844 unit->data_size = data_size;
845 unit->data_ref = data_ref;
847 return 0;
850 int ff_cbs_append_unit_data(CodedBitstreamFragment *frag,
851 CodedBitstreamUnitType type,
852 uint8_t *data, size_t data_size,
853 AVBufferRef *data_buf)
855 return cbs_insert_unit_data(frag, type,
856 data, data_size, data_buf,
857 frag->nb_units);
860 void ff_cbs_delete_unit(CodedBitstreamFragment *frag,
861 int position)
863 av_assert0(0 <= position && position < frag->nb_units
864 && "Unit to be deleted not in fragment.");
866 cbs_unit_uninit(&frag->units[position]);
868 --frag->nb_units;
870 if (frag->nb_units > 0)
871 memmove(frag->units + position,
872 frag->units + position + 1,
873 (frag->nb_units - position) * sizeof(*frag->units));
876 static void cbs_default_free_unit_content(AVRefStructOpaque opaque, void *content)
878 const CodedBitstreamUnitTypeDescriptor *desc = opaque.c;
880 for (int i = 0; i < desc->type.ref.nb_offsets; i++) {
881 void **ptr = (void**)((char*)content + desc->type.ref.offsets[i]);
882 av_buffer_unref((AVBufferRef**)(ptr + 1));
886 static const CodedBitstreamUnitTypeDescriptor
887 *cbs_find_unit_type_desc(CodedBitstreamContext *ctx,
888 CodedBitstreamUnit *unit)
890 const CodedBitstreamUnitTypeDescriptor *desc;
891 int i, j;
893 if (!ctx->codec->unit_types)
894 return NULL;
896 for (i = 0;; i++) {
897 desc = &ctx->codec->unit_types[i];
898 if (desc->nb_unit_types == 0)
899 break;
900 if (desc->nb_unit_types == CBS_UNIT_TYPE_RANGE) {
901 if (unit->type >= desc->unit_type.range.start &&
902 unit->type <= desc->unit_type.range.end)
903 return desc;
904 } else {
905 for (j = 0; j < desc->nb_unit_types; j++) {
906 if (desc->unit_type.list[j] == unit->type)
907 return desc;
911 return NULL;
914 static void *cbs_alloc_content(const CodedBitstreamUnitTypeDescriptor *desc)
916 return av_refstruct_alloc_ext_c(desc->content_size, 0,
917 (AVRefStructOpaque){ .c = desc },
918 desc->content_type == CBS_CONTENT_TYPE_COMPLEX
919 ? desc->type.complex.content_free
920 : cbs_default_free_unit_content);
923 int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx,
924 CodedBitstreamUnit *unit)
926 const CodedBitstreamUnitTypeDescriptor *desc;
928 av_assert0(!unit->content && !unit->content_ref);
930 desc = cbs_find_unit_type_desc(ctx, unit);
931 if (!desc)
932 return AVERROR(ENOSYS);
934 unit->content_ref = cbs_alloc_content(desc);
935 if (!unit->content_ref)
936 return AVERROR(ENOMEM);
937 unit->content = unit->content_ref;
939 return 0;
942 static int cbs_clone_noncomplex_unit_content(void **clonep,
943 const CodedBitstreamUnit *unit,
944 const CodedBitstreamUnitTypeDescriptor *desc)
946 const uint8_t *src;
947 uint8_t *copy;
948 int err, i;
950 av_assert0(unit->content);
951 src = unit->content;
953 copy = cbs_alloc_content(desc);
954 if (!copy)
955 return AVERROR(ENOMEM);
956 memcpy(copy, src, desc->content_size);
957 for (int i = 0; i < desc->type.ref.nb_offsets; i++) {
958 void **ptr = (void**)(copy + desc->type.ref.offsets[i]);
959 /* Zero all the AVBufferRefs as they are owned by src. */
960 *(ptr + 1) = NULL;
963 for (i = 0; i < desc->type.ref.nb_offsets; i++) {
964 const uint8_t *const *src_ptr = (const uint8_t* const*)(src + desc->type.ref.offsets[i]);
965 const AVBufferRef *src_buf = *(AVBufferRef**)(src_ptr + 1);
966 uint8_t **copy_ptr = (uint8_t**)(copy + desc->type.ref.offsets[i]);
967 AVBufferRef **copy_buf = (AVBufferRef**)(copy_ptr + 1);
969 if (!*src_ptr) {
970 av_assert0(!src_buf);
971 continue;
973 if (!src_buf) {
974 // We can't handle a non-refcounted pointer here - we don't
975 // have enough information to handle whatever structure lies
976 // at the other end of it.
977 err = AVERROR(EINVAL);
978 goto fail;
981 *copy_buf = av_buffer_ref(src_buf);
982 if (!*copy_buf) {
983 err = AVERROR(ENOMEM);
984 goto fail;
987 *clonep = copy;
989 return 0;
991 fail:
992 av_refstruct_unref(&copy);
993 return err;
997 * On success, unit->content and unit->content_ref are updated with
998 * the new content; unit is untouched on failure.
999 * Any old content_ref is simply overwritten and not freed.
1001 static int cbs_clone_unit_content(CodedBitstreamContext *ctx,
1002 CodedBitstreamUnit *unit)
1004 const CodedBitstreamUnitTypeDescriptor *desc;
1005 void *new_content;
1006 int err;
1008 desc = cbs_find_unit_type_desc(ctx, unit);
1009 if (!desc)
1010 return AVERROR(ENOSYS);
1012 switch (desc->content_type) {
1013 case CBS_CONTENT_TYPE_INTERNAL_REFS:
1014 err = cbs_clone_noncomplex_unit_content(&new_content, unit, desc);
1015 break;
1017 case CBS_CONTENT_TYPE_COMPLEX:
1018 if (!desc->type.complex.content_clone)
1019 return AVERROR_PATCHWELCOME;
1020 err = desc->type.complex.content_clone(&new_content, unit);
1021 break;
1023 default:
1024 av_assert0(0 && "Invalid content type.");
1027 if (err < 0)
1028 return err;
1030 unit->content_ref = new_content;
1031 unit->content = new_content;
1032 return 0;
1035 int ff_cbs_make_unit_refcounted(CodedBitstreamContext *ctx,
1036 CodedBitstreamUnit *unit)
1038 av_assert0(unit->content);
1039 if (unit->content_ref)
1040 return 0;
1041 return cbs_clone_unit_content(ctx, unit);
1044 int ff_cbs_make_unit_writable(CodedBitstreamContext *ctx,
1045 CodedBitstreamUnit *unit)
1047 void *ref = unit->content_ref;
1048 int err;
1050 av_assert0(unit->content);
1051 if (ref && av_refstruct_exclusive(ref))
1052 return 0;
1054 err = cbs_clone_unit_content(ctx, unit);
1055 if (err < 0)
1056 return err;
1057 av_refstruct_unref(&ref);
1058 return 0;
1061 void ff_cbs_discard_units(CodedBitstreamContext *ctx,
1062 CodedBitstreamFragment *frag,
1063 enum AVDiscard skip,
1064 int flags)
1066 if (!ctx->codec->discarded_unit)
1067 return;
1069 for (int i = frag->nb_units - 1; i >= 0; i--) {
1070 if (ctx->codec->discarded_unit(ctx, &frag->units[i], skip)) {
1071 // discard all units
1072 if (!(flags & DISCARD_FLAG_KEEP_NON_VCL)) {
1073 ff_cbs_fragment_free(frag);
1074 return;
1077 ff_cbs_delete_unit(frag, i);