FFmpeg
Loading...
Searching...
No Matches
cbs.c
Go to the documentation of this file.
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
33static const CodedBitstreamType *const cbs_type_table[] = {
34#if CBS_APV
35 &CBS_FUNC(type_apv),
36#endif
37#if CBS_AV1
38 &CBS_FUNC(type_av1),
39#endif
40#if CBS_H264
41 &CBS_FUNC(type_h264),
42#endif
43#if CBS_H265
44 &CBS_FUNC(type_h265),
45#endif
46#if CBS_H266
47 &CBS_FUNC(type_h266),
48#endif
49#if CBS_LCEVC
50 &CBS_FUNC(type_lcevc),
51#endif
52#if CBS_JPEG
53 &CBS_FUNC(type_jpeg),
54#endif
55#if CBS_MPEG2
56 &CBS_FUNC(type_mpeg2),
57#endif
58#if CBS_VP8
59 &CBS_FUNC(type_vp8),
60#endif
61#if CBS_VP9
62 &CBS_FUNC(type_vp9),
63#endif
64};
65
67 enum AVCodecID codec_id, void *log_ctx)
68{
71 int i;
72
73 type = NULL;
74 for (i = 0; i < FF_ARRAY_ELEMS(cbs_type_table); i++) {
77 break;
78 }
79 }
80 if (!type)
81 return AVERROR(EINVAL);
82
83 ctx = av_mallocz(sizeof(*ctx));
84 if (!ctx)
85 return AVERROR(ENOMEM);
86
87 ctx->log_ctx = log_ctx;
88 ctx->codec = type; /* Must be before any error */
89
90 if (type->priv_data_size) {
91 ctx->priv_data = av_mallocz(ctx->codec->priv_data_size);
92 if (!ctx->priv_data) {
93 av_freep(&ctx);
94 return AVERROR(ENOMEM);
95 }
96 if (type->priv_class) {
97 *(const AVClass **)ctx->priv_data = type->priv_class;
98 av_opt_set_defaults(ctx->priv_data);
99 }
100 }
101
102 ctx->decompose_unit_types = NULL;
103
104 ctx->trace_enable = 0;
105 ctx->trace_level = AV_LOG_TRACE;
106 ctx->trace_context = ctx;
107
108 *ctx_ptr = ctx;
109 return 0;
110}
111
113{
114 if (ctx->codec->flush)
115 ctx->codec->flush(ctx);
116}
117
119{
120 CodedBitstreamContext *ctx = *ctx_ptr;
121
122 if (!ctx)
123 return;
124
125 if (ctx->codec->close)
126 ctx->codec->close(ctx);
127
128 av_freep(&ctx->write_buffer);
129
130 if (ctx->codec->priv_class && ctx->priv_data)
131 av_opt_free(ctx->priv_data);
132
133 av_freep(&ctx->priv_data);
134 av_freep(ctx_ptr);
135}
136
138{
140 unit->content = NULL;
141
143 unit->data = NULL;
144 unit->data_size = 0;
145 unit->data_bit_padding = 0;
146}
147
149{
150 int i;
151
152 for (i = 0; i < frag->nb_units; i++)
153 cbs_unit_uninit(&frag->units[i]);
154 frag->nb_units = 0;
155
156 av_buffer_unref(&frag->data_ref);
157 frag->data = NULL;
158 frag->data_size = 0;
159 frag->data_bit_padding = 0;
160}
161
163{
165
166 av_freep(&frag->units);
167 frag->nb_units_allocated = 0;
168}
169
170#if CBS_READ
171static int cbs_read_fragment_content(CodedBitstreamContext *ctx,
173{
174 int err, i, j;
175
176 for (i = 0; i < frag->nb_units; i++) {
177 CodedBitstreamUnit *unit = &frag->units[i];
178
179 if (ctx->decompose_unit_types) {
180 for (j = 0; j < ctx->nb_decompose_unit_types; j++) {
181 if (ctx->decompose_unit_types[j] == unit->type)
182 break;
183 }
184 if (j >= ctx->nb_decompose_unit_types)
185 continue;
186 }
187
189 unit->content = NULL;
190
191 av_assert0(unit->data && unit->data_ref);
192
193 err = ctx->codec->read_unit(ctx, unit);
194 if (err == AVERROR(ENOSYS)) {
195 av_log(ctx->log_ctx, AV_LOG_VERBOSE,
196 "Decomposition unimplemented for unit %d "
197 "(type %"PRIu32").\n", i, unit->type);
198 } else if (err == AVERROR(EAGAIN)) {
199 av_log(ctx->log_ctx, AV_LOG_VERBOSE,
200 "Skipping decomposition of unit %d "
201 "(type %"PRIu32").\n", i, unit->type);
203 unit->content = NULL;
204 } else if (err < 0) {
205 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to read unit %d "
206 "(type %"PRIu32"): %s.\n",
207 i, unit->type, av_err2str(err));
208 return err;
209 }
210 }
211
212 return 0;
213}
214
215static int cbs_fill_fragment_data(CodedBitstreamFragment *frag,
216 const uint8_t *data, size_t size)
217{
218 av_assert0(!frag->data && !frag->data_ref);
219
220 frag->data_ref =
222 if (!frag->data_ref)
223 return AVERROR(ENOMEM);
224
225 frag->data = frag->data_ref->data;
226 frag->data_size = size;
227
228 memcpy(frag->data, data, size);
229 memset(frag->data + size, 0,
231
232 return 0;
233}
234
235static int cbs_read_data(CodedBitstreamContext *ctx,
237 const AVBufferRef *buf,
238 const uint8_t *data, size_t size,
239 int header)
240{
241 int err;
242
243 if (buf) {
244 frag->data_ref = av_buffer_ref(buf);
245 if (!frag->data_ref)
246 return AVERROR(ENOMEM);
247
248 frag->data = (uint8_t *)data;
249 frag->data_size = size;
250
251 } else {
252 err = cbs_fill_fragment_data(frag, data, size);
253 if (err < 0)
254 return err;
255 }
256
257 err = ctx->codec->split_fragment(ctx, frag, header);
258 if (err < 0)
259 return err;
260
261 return cbs_read_fragment_content(ctx, frag);
262}
263
266 const AVCodecParameters *par)
267{
268 return cbs_read_data(ctx, frag, NULL,
269 par->extradata,
270 par->extradata_size, 1);
271}
272
275 const AVCodecContext *avctx)
276{
277 return cbs_read_data(ctx, frag, NULL,
278 avctx->extradata,
279 avctx->extradata_size, 1);
280}
281
284 const AVPacket *pkt)
285{
286 return cbs_read_data(ctx, frag, pkt->buf,
287 pkt->data, pkt->size, 0);
288}
289
292 const AVPacket *pkt)
293{
294 size_t side_data_size;
295 const uint8_t *side_data =
297 &side_data_size);
298
299 return cbs_read_data(ctx, frag, NULL,
300 side_data, side_data_size, 1);
301}
302
305 const AVBufferRef *buf,
306 const uint8_t *data, size_t size)
307{
308 return cbs_read_data(ctx, frag, buf,
309 data, size, 0);
310}
311#endif
312
313#if CBS_WRITE
314/**
315 * Allocate a new internal data buffer of the given size in the unit.
316 *
317 * The data buffer will have input padding.
318 */
319static int cbs_alloc_unit_data(CodedBitstreamUnit *unit,
320 size_t size)
321{
322 av_assert0(!unit->data && !unit->data_ref);
323
325 if (!unit->data_ref)
326 return AVERROR(ENOMEM);
327
328 unit->data = unit->data_ref->data;
329 unit->data_size = size;
330
331 memset(unit->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
332
333 return 0;
334}
335
336static int cbs_write_unit_data(CodedBitstreamContext *ctx,
337 CodedBitstreamUnit *unit)
338{
339 PutBitContext pbc;
340 int ret;
341
342 if (!ctx->write_buffer) {
343 // Initial write buffer size is 1MB.
344 ctx->write_buffer_size = 1024 * 1024;
345
346 reallocate_and_try_again:
347 ret = av_reallocp(&ctx->write_buffer, ctx->write_buffer_size);
348 if (ret < 0) {
349 av_log(ctx->log_ctx, AV_LOG_ERROR, "Unable to allocate a "
350 "sufficiently large write buffer (last attempt "
351 "%zu bytes).\n", ctx->write_buffer_size);
352 return ret;
353 }
354 }
355
356 init_put_bits(&pbc, ctx->write_buffer, ctx->write_buffer_size);
357
358 ret = ctx->codec->write_unit(ctx, unit, &pbc);
359 if (ret < 0) {
360 if (ret == AVERROR(ENOSPC)) {
361 // Overflow.
362 if (ctx->write_buffer_size == INT_MAX / 8)
363 return AVERROR(ENOMEM);
364 ctx->write_buffer_size = FFMIN(2 * ctx->write_buffer_size, INT_MAX / 8);
365 goto reallocate_and_try_again;
366 }
367 // Write failed for some other reason.
368 return ret;
369 }
370
371 // Overflow but we didn't notice.
372 av_assert0(put_bits_count(&pbc) <= 8 * ctx->write_buffer_size);
373
374 if (put_bits_count(&pbc) % 8)
375 unit->data_bit_padding = 8 - put_bits_count(&pbc) % 8;
376 else
377 unit->data_bit_padding = 0;
378
379 flush_put_bits(&pbc);
380
381 ret = cbs_alloc_unit_data(unit, put_bytes_output(&pbc));
382 if (ret < 0)
383 return ret;
384
385 memcpy(unit->data, ctx->write_buffer, unit->data_size);
386
387 return 0;
388}
389
392{
393 int err, i;
394
395 for (i = 0; i < frag->nb_units; i++) {
396 CodedBitstreamUnit *unit = &frag->units[i];
397
398 if (!unit->content)
399 continue;
400
402 unit->data = NULL;
403
404 err = cbs_write_unit_data(ctx, unit);
405 if (err < 0) {
406 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to write unit %d "
407 "(type %"PRIu32").\n", i, unit->type);
408 return err;
409 }
410 av_assert0(unit->data && unit->data_ref);
411 }
412
413 av_buffer_unref(&frag->data_ref);
414 frag->data = NULL;
415
416 err = ctx->codec->assemble_fragment(ctx, frag);
417 if (err < 0) {
418 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to assemble fragment.\n");
419 return err;
420 }
421 av_assert0(frag->data && frag->data_ref);
422
423 return 0;
424}
425
429{
430 int err;
431
432 err = CBS_FUNC(write_fragment_data)(ctx, frag);
433 if (err < 0)
434 return err;
435
436 av_freep(&par->extradata);
437 par->extradata_size = 0;
438
439 if (!frag->data_size)
440 return 0;
441
442 par->extradata = av_malloc(frag->data_size +
444 if (!par->extradata)
445 return AVERROR(ENOMEM);
446
447 memcpy(par->extradata, frag->data, frag->data_size);
448 memset(par->extradata + frag->data_size, 0,
450 par->extradata_size = frag->data_size;
451
452 return 0;
453}
454
456 AVPacket *pkt,
458{
459 AVBufferRef *buf;
460 int err;
461
462 err = CBS_FUNC(write_fragment_data)(ctx, frag);
463 if (err < 0)
464 return err;
465
466 buf = av_buffer_ref(frag->data_ref);
467 if (!buf)
468 return AVERROR(ENOMEM);
469
470 av_buffer_unref(&pkt->buf);
471
472 pkt->buf = buf;
473 pkt->data = frag->data;
474 pkt->size = frag->data_size;
475
476 return 0;
477}
478#endif
479
480
482 const char *name)
483{
484#if CBS_TRACE
485 if (!ctx->trace_enable)
486 return;
487
488 av_log(ctx->log_ctx, ctx->trace_level, "%s\n", name);
489#endif
490}
491
492void CBS_FUNC(trace_read_log)(void *trace_context,
493 GetBitContext *gbc, int length,
494 const char *str, const int *subscripts,
496{
497#if CBS_TRACE
498 CodedBitstreamContext *ctx = trace_context;
499 char name[256];
500 char bits[256];
501 size_t name_len, bits_len;
502 int pad, subs, i, j, k, n;
503 int position;
504
505 av_assert0(value >= INT_MIN && value <= UINT32_MAX);
506
507 position = get_bits_count(gbc);
508
509 av_assert0(length < 256);
510 for (i = 0; i < length; i++)
511 bits[i] = get_bits1(gbc) ? '1' : '0';
512 bits[length] = 0;
513
514 subs = subscripts ? subscripts[0] : 0;
515 n = 0;
516 for (i = j = 0; str[i];) {
517 if (str[i] == '[') {
518 if (n < subs) {
519 ++n;
520 k = snprintf(name + j, sizeof(name) - j, "[%d", subscripts[n]);
521 av_assert0(k > 0 && j + k < sizeof(name));
522 j += k;
523 for (++i; str[i] && str[i] != ']'; i++);
524 av_assert0(str[i] == ']');
525 } else {
526 while (str[i] && str[i] != ']')
527 name[j++] = str[i++];
528 av_assert0(str[i] == ']');
529 }
530 } else {
531 av_assert0(j + 1 < sizeof(name));
532 name[j++] = str[i++];
533 }
534 }
535 av_assert0(j + 1 < sizeof(name));
536 name[j] = 0;
537 av_assert0(n == subs);
538
539 name_len = strlen(name);
540 bits_len = length;
541
542 if (name_len + bits_len > 60)
543 pad = bits_len + 2;
544 else
545 pad = 61 - name_len;
546
547 av_log(ctx->log_ctx, ctx->trace_level, "%-10d %s%*s = %"PRId64"\n",
548 position, name, pad, bits, value);
549#endif
550}
551
552void CBS_FUNC(trace_write_log)(void *trace_context,
553 PutBitContext *pbc, int length,
554 const char *str, const int *subscripts,
556{
557#if CBS_TRACE
558 CodedBitstreamContext *ctx = trace_context;
559
560 // Ensure that the syntax element is written to the output buffer,
561 // make a GetBitContext pointed at the start position, then call the
562 // read log function which can read the bits back to log them.
563
564 GetBitContext gbc;
565 int position;
566
567 if (length > 0) {
569 flush = *pbc;
571 }
572
573 position = put_bits_count(pbc);
574 av_assert0(position >= length);
575
576 init_get_bits(&gbc, pbc->buf, position);
577
578 skip_bits_long(&gbc, position - length);
579
580 CBS_FUNC(trace_read_log)(ctx, &gbc, length, str, subscripts, value);
581#endif
582}
583
584#if CBS_READ
585static av_always_inline int cbs_read_unsigned(CodedBitstreamContext *ctx,
586 GetBitContext *gbc,
587 int width, const char *name,
588 const int *subscripts,
589 uint32_t *write_to,
590 uint32_t range_min,
591 uint32_t range_max)
592{
593 uint32_t value;
594
596
597 av_assert0(width > 0 && width <= 32);
598
599 if (get_bits_left(gbc) < width) {
600 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at "
601 "%s: bitstream ended.\n", name);
602 return AVERROR_INVALIDDATA;
603 }
604
605 value = get_bits_long(gbc, width);
606
608
609 if (value < range_min || value > range_max) {
610 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
611 "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
612 name, value, range_min, range_max);
613 return AVERROR_INVALIDDATA;
614 }
615
616 *write_to = value;
617 return 0;
618}
619
621 int width, const char *name,
622 const int *subscripts, uint32_t *write_to,
623 uint32_t range_min, uint32_t range_max)
624{
625 return cbs_read_unsigned(ctx, gbc, width, name, subscripts,
626 write_to, range_min, range_max);
627}
628
630 int width, const char *name, uint32_t *write_to)
631{
632 return cbs_read_unsigned(ctx, gbc, width, name, NULL,
633 write_to, 0, UINT32_MAX);
634}
635#endif
636
637#if CBS_WRITE
639 int width, const char *name,
640 const int *subscripts, uint32_t value,
641 uint32_t range_min, uint32_t range_max)
642{
644
645 av_assert0(width > 0 && width <= 32);
646
647 if (value < range_min || value > range_max) {
648 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
649 "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
650 name, value, range_min, range_max);
651 return AVERROR_INVALIDDATA;
652 }
653
654 if (put_bits_left(pbc) < width)
655 return AVERROR(ENOSPC);
656
657 put_bits63(pbc, width, value);
658
660
661 return 0;
662}
663
665 int width, const char *name, uint32_t value)
666{
667 return CBS_FUNC(write_unsigned)(ctx, pbc, width, name, NULL,
669}
670#endif
671
672#if CBS_READ
674 int width, const char *name,
675 const int *subscripts, int32_t *write_to,
676 int32_t range_min, int32_t range_max)
677{
679
681
682 av_assert0(width > 0 && width <= 32);
683
684 if (get_bits_left(gbc) < width) {
685 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at "
686 "%s: bitstream ended.\n", name);
687 return AVERROR_INVALIDDATA;
688 }
689
690 value = get_sbits_long(gbc, width);
691
693
694 if (value < range_min || value > range_max) {
695 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
696 "%"PRId32", but must be in [%"PRId32",%"PRId32"].\n",
697 name, value, range_min, range_max);
698 return AVERROR_INVALIDDATA;
699 }
700
701 *write_to = value;
702 return 0;
703}
704#endif
705
706#if CBS_WRITE
708 int width, const char *name,
709 const int *subscripts, int32_t value,
710 int32_t range_min, int32_t range_max)
711{
713
714 av_assert0(width > 0 && width <= 32);
715
716 if (value < range_min || value > range_max) {
717 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
718 "%"PRId32", but must be in [%"PRId32",%"PRId32"].\n",
719 name, value, range_min, range_max);
720 return AVERROR_INVALIDDATA;
721 }
722
723 if (put_bits_left(pbc) < width)
724 return AVERROR(ENOSPC);
725
727
729
730 return 0;
731}
732#endif
733
734
736 int position)
737{
738 CodedBitstreamUnit *units;
739
740 if (frag->nb_units < frag->nb_units_allocated) {
741 units = frag->units;
742
743 if (position < frag->nb_units)
744 memmove(units + position + 1, units + position,
745 (frag->nb_units - position) * sizeof(*units));
746 } else {
747 units = av_malloc_array(frag->nb_units*2 + 1, sizeof(*units));
748 if (!units)
749 return AVERROR(ENOMEM);
750
751 frag->nb_units_allocated = 2*frag->nb_units_allocated + 1;
752
753 if (position > 0)
754 memcpy(units, frag->units, position * sizeof(*units));
755
756 if (position < frag->nb_units)
757 memcpy(units + position + 1, frag->units + position,
758 (frag->nb_units - position) * sizeof(*units));
759
760 av_free(frag->units);
761 frag->units = units;
762 }
763
764 memset(units + position, 0, sizeof(*units));
765
766 ++frag->nb_units;
767
768 return 0;
769}
770
772 int position,
774 void *content,
775 void *content_ref)
776{
777 CodedBitstreamUnit *unit;
778 int err;
779
780 if (position == -1)
781 position = frag->nb_units;
782 av_assert0(position >= 0 && position <= frag->nb_units);
783
784 err = cbs_insert_unit(frag, position);
785 if (err < 0)
786 return err;
787
788 if (content_ref) {
789 // Create our own reference out of the user-supplied one.
790 content_ref = av_refstruct_ref(content_ref);
791 }
792
793 unit = &frag->units[position];
794 unit->type = type;
795 unit->content = content;
796 unit->content_ref = content_ref;
797
798 return 0;
799}
800
803 uint8_t *data, size_t data_size,
804 AVBufferRef *data_buf,
805 int position)
806{
807 CodedBitstreamUnit *unit;
808 AVBufferRef *data_ref;
809 int err;
810
811 av_assert0(position >= 0 && position <= frag->nb_units);
812
813 if (data_buf)
814 data_ref = av_buffer_ref(data_buf);
815 else
816 data_ref = av_buffer_create(data, data_size, NULL, NULL, 0);
817 if (!data_ref) {
818 if (!data_buf)
819 av_free(data);
820 return AVERROR(ENOMEM);
821 }
822
823 err = cbs_insert_unit(frag, position);
824 if (err < 0) {
825 av_buffer_unref(&data_ref);
826 return err;
827 }
828
829 unit = &frag->units[position];
830 unit->type = type;
831 unit->data = data;
832 unit->data_size = data_size;
833 unit->data_ref = data_ref;
834
835 return 0;
836}
837
840 uint8_t *data, size_t data_size,
841 AVBufferRef *data_buf)
842{
843 return cbs_insert_unit_data(frag, type,
844 data, data_size, data_buf,
845 frag->nb_units);
846}
847
849 int position)
850{
851 av_assert0(0 <= position && position < frag->nb_units
852 && "Unit to be deleted not in fragment.");
853
854 cbs_unit_uninit(&frag->units[position]);
855
856 --frag->nb_units;
857
858 if (frag->nb_units > 0)
859 memmove(frag->units + position,
860 frag->units + position + 1,
861 (frag->nb_units - position) * sizeof(*frag->units));
862}
863
864static void cbs_default_free_unit_content(AVRefStructOpaque opaque, void *content)
865{
867
868 for (int i = 0; i < desc->type.ref.nb_offsets; i++) {
869 void **ptr = (void**)((char*)content + desc->type.ref.offsets[i]);
870 av_buffer_unref((AVBufferRef**)(ptr + 1));
871 }
872}
873
876 CodedBitstreamUnit *unit)
877{
879 int i, j;
880
881 if (!ctx->codec->unit_types)
882 return NULL;
883
884 for (i = 0;; i++) {
885 desc = &ctx->codec->unit_types[i];
886 if (desc->nb_unit_types == 0)
887 break;
888 if (desc->nb_unit_types == CBS_UNIT_TYPE_RANGE) {
889 if (unit->type >= desc->unit_type.range.start &&
890 unit->type <= desc->unit_type.range.end)
891 return desc;
892 } else {
893 for (j = 0; j < desc->nb_unit_types; j++) {
894 if (desc->unit_type.list[j] == unit->type)
895 return desc;
896 }
897 }
898 }
899 return NULL;
900}
901
903{
904 return av_refstruct_alloc_ext_c(desc->content_size, 0,
905 (AVRefStructOpaque){ .c = desc },
906 desc->content_type == CBS_CONTENT_TYPE_COMPLEX
907 ? desc->type.complex.content_free
909}
910
912 CodedBitstreamUnit *unit)
913{
915
916 av_assert0(!unit->content && !unit->content_ref);
917
919 if (!desc)
920 return AVERROR(ENOSYS);
921
923 if (!unit->content_ref)
924 return AVERROR(ENOMEM);
925 unit->content = unit->content_ref;
926
927 return 0;
928}
929
930static int cbs_clone_noncomplex_unit_content(void **clonep,
931 const CodedBitstreamUnit *unit,
933{
934 const uint8_t *src;
935 uint8_t *copy;
936 int err;
937
938 av_assert0(unit->content);
939 src = unit->content;
940
942 if (!copy)
943 return AVERROR(ENOMEM);
944 memcpy(copy, src, desc->content_size);
945 for (int i = 0; i < desc->type.ref.nb_offsets; i++) {
946 void **ptr = (void**)(copy + desc->type.ref.offsets[i]);
947 /* Zero all the AVBufferRefs as they are owned by src. */
948 *(ptr + 1) = NULL;
949 }
950
951 for (int i = 0; i < desc->type.ref.nb_offsets; i++) {
952 const uint8_t *const *src_ptr = (const uint8_t* const*)(src + desc->type.ref.offsets[i]);
953 const AVBufferRef *src_buf = *(AVBufferRef**)(src_ptr + 1);
954 uint8_t **copy_ptr = (uint8_t**)(copy + desc->type.ref.offsets[i]);
955 AVBufferRef **copy_buf = (AVBufferRef**)(copy_ptr + 1);
956
957 if (!*src_ptr) {
958 av_assert0(!src_buf);
959 continue;
960 }
961 if (!src_buf) {
962 // We can't handle a non-refcounted pointer here - we don't
963 // have enough information to handle whatever structure lies
964 // at the other end of it.
965 err = AVERROR(EINVAL);
966 goto fail;
967 }
968
969 *copy_buf = av_buffer_ref(src_buf);
970 if (!*copy_buf) {
971 err = AVERROR(ENOMEM);
972 goto fail;
973 }
974 }
975 *clonep = copy;
976
977 return 0;
978
979fail:
981 return err;
982}
983
984/*
985 * On success, unit->content and unit->content_ref are updated with
986 * the new content; unit is untouched on failure.
987 * Any old content_ref is simply overwritten and not freed.
988 */
990 CodedBitstreamUnit *unit)
991{
993 void *new_content;
994 int err;
995
997 if (!desc)
998 return AVERROR(ENOSYS);
999
1000 switch (desc->content_type) {
1002 err = cbs_clone_noncomplex_unit_content(&new_content, unit, desc);
1003 break;
1004
1006 if (!desc->type.complex.content_clone)
1007 return AVERROR_PATCHWELCOME;
1008 err = desc->type.complex.content_clone(&new_content, unit);
1009 break;
1010
1011 default:
1012 av_assert0(0 && "Invalid content type.");
1013 }
1014
1015 if (err < 0)
1016 return err;
1017
1018 unit->content_ref = new_content;
1019 unit->content = new_content;
1020 return 0;
1021}
1022
1024 CodedBitstreamUnit *unit)
1025{
1026 av_assert0(unit->content);
1027 if (unit->content_ref)
1028 return 0;
1029 return cbs_clone_unit_content(ctx, unit);
1030}
1031
1033 CodedBitstreamUnit *unit)
1034{
1035 void *ref = unit->content_ref;
1036 int err;
1037
1038 av_assert0(unit->content);
1040 return 0;
1041
1042 err = cbs_clone_unit_content(ctx, unit);
1043 if (err < 0)
1044 return err;
1046 return 0;
1047}
1048
1051 enum AVDiscard skip,
1052 int flags)
1053{
1054 if (!ctx->codec->discarded_unit)
1055 return;
1056
1057 for (int i = frag->nb_units - 1; i >= 0; i--) {
1058 if (ctx->codec->discarded_unit(ctx, &frag->units[i], skip)) {
1059 // discard all units
1061 CBS_FUNC(fragment_free)(frag);
1062 return;
1063 }
1064
1065 CBS_FUNC(delete_unit)(frag, i);
1066 }
1067 }
1068}
static av_cold void close(AVCodecParserContext *s)
Definition apv_parser.c:197
int32_t
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
Libavcodec external API header.
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
static void BS_FUNC skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
static uint32_t BS_FUNC read(BSCTX *bc, unsigned int n)
Return n bits from the buffer, n has to be in the 0-32 range.
static int32_t BS_FUNC read_signed(BSCTX *bc, unsigned int n)
Return n bits from the buffer as a signed integer.
refcounted data buffer API
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
int CBS_FUNC read_simple_unsigned(CodedBitstreamContext *ctx, GetBitContext *gbc, int width, const char *name, uint32_t *write_to)
@ CBS_UNIT_TYPE_RANGE
#define CBS_TRACE_READ_END()
int CBS_FUNC write_signed(CodedBitstreamContext *ctx, PutBitContext *pbc, int width, const char *name, const int *subscripts, int32_t value, int32_t range_min, int32_t range_max)
@ CBS_CONTENT_TYPE_INTERNAL_REFS
@ CBS_CONTENT_TYPE_COMPLEX
#define CBS_TRACE_READ_START()
#define MAX_UINT_BITS(length)
int CBS_FUNC write_simple_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc, int width, const char *name, uint32_t value)
#define CBS_TRACE_WRITE_END()
int CBS_FUNC read_unsigned(CodedBitstreamContext *ctx, GetBitContext *gbc, int width, const char *name, const int *subscripts, uint32_t *write_to, uint32_t range_min, uint32_t range_max)
int CBS_FUNC write_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc, int width, const char *name, const int *subscripts, uint32_t value, uint32_t range_min, uint32_t range_max)
#define CBS_TRACE_WRITE_START()
common internal and external API header
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static AVPacket * pkt
void(* flush)(AVBSFContext *ctx)
Definition dts2pts.c:610
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
double value
Definition eval.c:102
static const uint8_t bits[8]
Definition fastaudio.c:100
static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
Definition ffmpeg_mux.c:204
static int get_sbits_long(GetBitContext *s, int n)
Read 0-32 bits as a signed integer.
Definition get_bits.h:474
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition get_bits.h:424
static int get_bits_left(GetBitContext *gb)
Definition get_bits.h:688
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition get_bits.h:280
static unsigned int get_bits1(GetBitContext *s)
Definition get_bits.h:391
static int get_bits_count(const GetBitContext *s)
Definition get_bits.h:254
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition get_bits.h:517
#define fail
Definition test.h:479
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition codec_id.h:47
AVDiscard
Definition defs.h:223
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
@ AV_PKT_DATA_NEW_EXTRADATA
The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format that the extradata buffer was...
Definition packet.h:56
uint8_t * av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, size_t *size)
Get side information from packet.
Definition packet.c:252
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition buffer.c:139
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition buffer.c:103
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition buffer.c:77
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition buffer.c:55
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition log.h:236
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition mem.c:188
void av_opt_free(void *obj)
Free all allocated objects in obj.
Definition opt.c:2025
void av_opt_set_defaults(void *s)
Set the values of all AVOption fields to their default values.
Definition opt.c:1754
cl_device_type type
int CBS_FUNC insert_unit_content(CodedBitstreamFragment *frag, int position, CodedBitstreamUnitType type, void *content, void *content_ref)
Insert a new unit into a fragment with the given content.
Definition cbs.c:771
void CBS_FUNC trace_read_log(void *trace_context, GetBitContext *gbc, int length, const char *str, const int *subscripts, int64_t value)
Helper function for read tracing which formats the syntax element and logs the result.
Definition cbs.c:492
static void * cbs_alloc_content(CodedBitstreamUnitTypeDescriptor *desc)
Definition cbs.c:902
void CBS_FUNC trace_header(CodedBitstreamContext *ctx, const char *name)
Definition cbs.c:481
static int cbs_clone_unit_content(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit)
Definition cbs.c:989
void CBS_FUNC discard_units(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, enum AVDiscard skip, int flags)
Discard units according to 'skip'.
Definition cbs.c:1049
static void cbs_default_free_unit_content(AVRefStructOpaque opaque, void *content)
Definition cbs.c:864
av_cold void CBS_FUNC fragment_free(CodedBitstreamFragment *frag)
Free the units array of a fragment in addition to what ff_cbs_fragment_reset does.
Definition cbs.c:162
void CBS_FUNC delete_unit(CodedBitstreamFragment *frag, int position)
Delete a unit from a fragment and free all memory it uses.
Definition cbs.c:848
static CodedBitstreamUnitTypeDescriptor * cbs_find_unit_type_desc(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit)
Definition cbs.c:875
static int cbs_insert_unit(CodedBitstreamFragment *frag, int position)
Definition cbs.c:735
int CBS_FUNC alloc_unit_content(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit)
Allocate a new internal content buffer matching the type of the unit.
Definition cbs.c:911
int CBS_FUNC make_unit_writable(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit)
Make the content of a unit writable so that internal fields can be modified.
Definition cbs.c:1032
static int cbs_insert_unit_data(CodedBitstreamFragment *frag, CodedBitstreamUnitType type, uint8_t *data, size_t data_size, AVBufferRef *data_buf, int position)
Definition cbs.c:801
void CBS_FUNC trace_write_log(void *trace_context, PutBitContext *pbc, int length, const char *str, const int *subscripts, int64_t value)
Helper function for write tracing which formats the syntax element and logs the result.
Definition cbs.c:552
static void cbs_unit_uninit(CodedBitstreamUnit *unit)
Definition cbs.c:137
int CBS_FUNC append_unit_data(CodedBitstreamFragment *frag, CodedBitstreamUnitType type, uint8_t *data, size_t data_size, AVBufferRef *data_buf)
Add a new unit to a fragment with the given data bitstream.
Definition cbs.c:838
void CBS_FUNC fragment_reset(CodedBitstreamFragment *frag)
Free the units contained in a fragment as well as the fragment's own data buffer, but not the units a...
Definition cbs.c:148
static int cbs_clone_noncomplex_unit_content(void **clonep, const CodedBitstreamUnit *unit, CodedBitstreamUnitTypeDescriptor *desc)
Definition cbs.c:930
int CBS_FUNC make_unit_refcounted(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit)
Make the content of a unit refcounted.
Definition cbs.c:1023
static const CodedBitstreamType *const cbs_type_table[]
Definition cbs.c:33
int CBS_FUNC read_extradata_from_codec(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, const struct AVCodecContext *avctx)
Read the extradata bitstream found in a codec context into a fragment, then split into units and deco...
int CBS_FUNC write_fragment_data(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag)
Write the content of the fragment to its own internal buffer.
int CBS_FUNC read_packet_side_data(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, const AVPacket *pkt)
@ DISCARD_FLAG_KEEP_NON_VCL
keep non-vcl units even if the picture has been dropped.
Definition cbs.h:507
int CBS_FUNC write_extradata(CodedBitstreamContext *ctx, AVCodecParameters *par, CodedBitstreamFragment *frag)
Write the bitstream of a fragment to the extradata in codec parameters.
int CBS_FUNC read_extradata(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, const AVCodecParameters *par)
Read the extradata bitstream found in codec parameters into a fragment, then split into units and dec...
uint32_t CodedBitstreamUnitType
The codec-specific type of a bitstream unit.
Definition cbs.h:66
#define CBS_FUNC(name)
Definition cbs.h:38
#define av_always_inline
Definition attributes.h:72
#define av_cold
Definition attributes.h:117
const char * desc
Definition libsvtav1.c:83
#define FFMIN(a, b)
Definition macros.h:49
static av_const unsigned zero_extend(unsigned val, unsigned bits)
Definition mathops.h:153
Memory handling functions.
const char data[16]
Definition mxf.c:149
#define av_malloc(s)
Definition ops_static.c:52
AVOptions.
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition put_bits.h:62
static int put_bits_count(PutBitContext *s)
Definition put_bits.h:90
static int put_bits_left(PutBitContext *s)
Definition put_bits.h:135
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition put_bits.h:153
static void put_bits63(PutBitContext *s, int n, uint64_t value)
Write up to 63 bits into a bitstream.
Definition put_bits.h:344
static int put_bytes_output(const PutBitContext *s)
Definition put_bits.h:99
const char * name
Definition qsvenc.c:142
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition refstruct.c:120
void * av_refstruct_alloc_ext_c(size_t size, unsigned flags, AVRefStructOpaque opaque, void(*free_cb)(AVRefStructOpaque opaque, void *obj))
Allocate a refcounted object of usable size size managed via the RefStruct API.
Definition refstruct.c:102
int av_refstruct_exclusive(const void *obj)
Check whether the reference count of an object managed via this API is 1.
Definition refstruct.c:174
void * av_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
Definition refstruct.c:140
static const uint8_t header[24]
Definition sdr2.c:68
#define FF_ARRAY_ELEMS(a)
#define snprintf
Definition snprintf.h:34
A reference to a data buffer.
Definition buffer.h:82
uint8_t * data
The data buffer.
Definition buffer.h:90
Describe the class of an AVClass context structure.
Definition log.h:76
main external API structure.
Definition avcodec.h:443
This struct describes the properties of an encoded stream.
Definition codec_par.h:49
This structure stores compressed data.
Definition packet.h:580
Context structure for coded bitstream operations.
Definition cbs.h:226
Coded bitstream fragment structure, combining one or more units.
Definition cbs.h:129
CodedBitstreamUnit * units
Pointer to an array of units of length nb_units_allocated.
Definition cbs.h:175
int nb_units
Number of units in this fragment.
Definition cbs.h:160
int nb_units_allocated
Number of allocated units.
Definition cbs.h:167
size_t data_size
The number of bytes in the bitstream.
Definition cbs.h:142
uint8_t * data
Pointer to the bitstream form of this fragment.
Definition cbs.h:135
AVBufferRef * data_ref
A reference to the buffer containing data.
Definition cbs.h:152
Coded bitstream unit structure.
Definition cbs.h:77
void * content
Pointer to the decomposed form of this unit.
Definition cbs.h:114
void * content_ref
If content is reference counted, a RefStruct reference backing content.
Definition cbs.h:119
uint8_t * data
Pointer to the directly-parsable bitstream form of this unit.
Definition cbs.h:88
size_t data_bit_padding
The number of bits which should be ignored in the final byte.
Definition cbs.h:99
CodedBitstreamUnitType type
Codec-specific type of this unit.
Definition cbs.h:81
size_t data_size
The number of bytes in the bitstream (including any padding bits in the final byte).
Definition cbs.h:93
AVBufferRef * data_ref
A reference to the buffer containing data.
Definition cbs.h:105
#define av_free(p)
#define av_malloc_array(a, b)
#define av_mallocz(s)
#define av_freep(p)
#define av_log(a,...)
#define src
Definition vp8dsp.c:248
static int ref[MAX_W *MAX_W]
static AVFormatContext * ctx
Definition movenc.c:49
#define width
Definition dsp.h:89
int size
RefStruct is an API for creating reference-counted objects with minimal overhead.
Definition refstruct.h:58
const void * c
Definition refstruct.h:60
enum AVCodecID codec_id
static void copy(const float *p1, float *p2, const int length)