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
23 #include "libavutil/avassert.h"
24 #include "libavutil/buffer.h"
25 #include "libavutil/common.h"
28 #include "cbs_internal.h"
31 static const CodedBitstreamType *cbs_type_table[] = {
52 const enum AVCodecID ff_cbs_all_codec_ids[] = {
66 AV_CODEC_ID_MPEG2VIDEO,
74 int ff_cbs_init(CodedBitstreamContext **ctx_ptr,
75 enum AVCodecID codec_id, void *log_ctx)
77 CodedBitstreamContext *ctx;
78 const CodedBitstreamType *type;
82 for (i = 0; i < FF_ARRAY_ELEMS(cbs_type_table); i++) {
83 if (cbs_type_table[i]->codec_id == codec_id) {
84 type = cbs_type_table[i];
89 return AVERROR(EINVAL);
91 ctx = av_mallocz(sizeof(*ctx));
93 return AVERROR(ENOMEM);
95 ctx->log_ctx = log_ctx;
98 ctx->priv_data = av_mallocz(ctx->codec->priv_data_size);
99 if (!ctx->priv_data) {
101 return AVERROR(ENOMEM);
104 ctx->decompose_unit_types = NULL;
106 ctx->trace_enable = 0;
107 ctx->trace_level = AV_LOG_TRACE;
113 void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
115 CodedBitstreamContext *ctx = *ctx_ptr;
120 if (ctx->codec && ctx->codec->close)
121 ctx->codec->close(ctx);
123 av_freep(&ctx->priv_data);
127 static void cbs_unit_uninit(CodedBitstreamContext *ctx,
128 CodedBitstreamUnit *unit)
130 av_buffer_unref(&unit->content_ref);
131 unit->content = NULL;
133 av_buffer_unref(&unit->data_ref);
136 unit->data_bit_padding = 0;
139 void ff_cbs_fragment_uninit(CodedBitstreamContext *ctx,
140 CodedBitstreamFragment *frag)
144 for (i = 0; i < frag->nb_units; i++)
145 cbs_unit_uninit(ctx, &frag->units[i]);
146 av_freep(&frag->units);
149 av_buffer_unref(&frag->data_ref);
152 frag->data_bit_padding = 0;
155 static int cbs_read_fragment_content(CodedBitstreamContext *ctx,
156 CodedBitstreamFragment *frag)
160 for (i = 0; i < frag->nb_units; i++) {
161 CodedBitstreamUnit *unit = &frag->units[i];
163 if (ctx->decompose_unit_types) {
164 for (j = 0; j < ctx->nb_decompose_unit_types; j++) {
165 if (ctx->decompose_unit_types[j] == unit->type)
168 if (j >= ctx->nb_decompose_unit_types)
172 av_buffer_unref(&unit->content_ref);
173 unit->content = NULL;
175 av_assert0(unit->data && unit->data_ref);
177 err = ctx->codec->read_unit(ctx, unit);
178 if (err == AVERROR(ENOSYS)) {
179 av_log(ctx->log_ctx, AV_LOG_VERBOSE,
180 "Decomposition unimplemented for unit %d "
181 "(type %"PRIu32").\n", i, unit->type);
182 } else if (err < 0) {
183 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to read unit %d "
184 "(type %"PRIu32").\n", i, unit->type);
192 static int cbs_fill_fragment_data(CodedBitstreamContext *ctx,
193 CodedBitstreamFragment *frag,
194 const uint8_t *data, size_t size)
196 av_assert0(!frag->data && !frag->data_ref);
199 av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
201 return AVERROR(ENOMEM);
203 frag->data = frag->data_ref->data;
204 frag->data_size = size;
206 memcpy(frag->data, data, size);
207 memset(frag->data + size, 0,
208 AV_INPUT_BUFFER_PADDING_SIZE);
213 int ff_cbs_read_extradata(CodedBitstreamContext *ctx,
214 CodedBitstreamFragment *frag,
215 const AVCodecParameters *par)
219 memset(frag, 0, sizeof(*frag));
221 err = cbs_fill_fragment_data(ctx, frag, par->extradata,
222 par->extradata_size);
226 err = ctx->codec->split_fragment(ctx, frag, 1);
230 return cbs_read_fragment_content(ctx, frag);
233 int ff_cbs_read_packet(CodedBitstreamContext *ctx,
234 CodedBitstreamFragment *frag,
239 memset(frag, 0, sizeof(*frag));
242 frag->data_ref = av_buffer_ref(pkt->buf);
244 return AVERROR(ENOMEM);
246 frag->data = pkt->data;
247 frag->data_size = pkt->size;
250 err = cbs_fill_fragment_data(ctx, frag, pkt->data, pkt->size);
255 err = ctx->codec->split_fragment(ctx, frag, 0);
259 return cbs_read_fragment_content(ctx, frag);
262 int ff_cbs_read(CodedBitstreamContext *ctx,
263 CodedBitstreamFragment *frag,
264 const uint8_t *data, size_t size)
268 memset(frag, 0, sizeof(*frag));
270 err = cbs_fill_fragment_data(ctx, frag, data, size);
274 err = ctx->codec->split_fragment(ctx, frag, 0);
278 return cbs_read_fragment_content(ctx, frag);
282 int ff_cbs_write_fragment_data(CodedBitstreamContext *ctx,
283 CodedBitstreamFragment *frag)
287 for (i = 0; i < frag->nb_units; i++) {
288 CodedBitstreamUnit *unit = &frag->units[i];
293 av_buffer_unref(&unit->data_ref);
296 err = ctx->codec->write_unit(ctx, unit);
298 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to write unit %d "
299 "(type %"PRIu32").\n", i, unit->type);
302 av_assert0(unit->data && unit->data_ref);
305 av_buffer_unref(&frag->data_ref);
308 err = ctx->codec->assemble_fragment(ctx, frag);
310 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to assemble fragment.\n");
313 av_assert0(frag->data && frag->data_ref);
318 int ff_cbs_write_extradata(CodedBitstreamContext *ctx,
319 AVCodecParameters *par,
320 CodedBitstreamFragment *frag)
324 err = ff_cbs_write_fragment_data(ctx, frag);
328 av_freep(&par->extradata);
330 par->extradata = av_malloc(frag->data_size +
331 AV_INPUT_BUFFER_PADDING_SIZE);
333 return AVERROR(ENOMEM);
335 memcpy(par->extradata, frag->data, frag->data_size);
336 memset(par->extradata + frag->data_size, 0,
337 AV_INPUT_BUFFER_PADDING_SIZE);
338 par->extradata_size = frag->data_size;
343 int ff_cbs_write_packet(CodedBitstreamContext *ctx,
345 CodedBitstreamFragment *frag)
350 err = ff_cbs_write_fragment_data(ctx, frag);
354 buf = av_buffer_ref(frag->data_ref);
356 return AVERROR(ENOMEM);
360 pkt->data = frag->data;
361 pkt->size = frag->data_size;
367 void ff_cbs_trace_header(CodedBitstreamContext *ctx,
370 if (!ctx->trace_enable)
373 av_log(ctx->log_ctx, ctx->trace_level, "%s\n", name);
376 void ff_cbs_trace_syntax_element(CodedBitstreamContext *ctx, int position,
377 const char *str, const int *subscripts,
378 const char *bits, int64_t value)
381 size_t name_len, bits_len;
382 int pad, subs, i, j, k, n;
384 if (!ctx->trace_enable)
387 av_assert0(value >= INT_MIN && value <= UINT32_MAX);
389 subs = subscripts ? subscripts[0] : 0;
391 for (i = j = 0; str[i];) {
395 k = snprintf(name + j, sizeof(name) - j, "[%d", subscripts[n]);
396 av_assert0(k > 0 && j + k < sizeof(name));
398 for (++i; str[i] && str[i] != ']'; i++);
399 av_assert0(str[i] == ']');
401 while (str[i] && str[i] != ']')
402 name[j++] = str[i++];
403 av_assert0(str[i] == ']');
406 av_assert0(j + 1 < sizeof(name));
407 name[j++] = str[i++];
410 av_assert0(j + 1 < sizeof(name));
412 av_assert0(n == subs);
414 name_len = strlen(name);
415 bits_len = strlen(bits);
417 if (name_len + bits_len > 60)
422 av_log(ctx->log_ctx, ctx->trace_level, "%-10d %s%*s = %"PRId64"\n",
423 position, name, pad, bits, value);
426 int ff_cbs_read_unsigned(CodedBitstreamContext *ctx, GetBitContext *gbc,
427 int width, const char *name,
428 const int *subscripts, uint32_t *write_to,
429 uint32_t range_min, uint32_t range_max)
434 av_assert0(width > 0 && width <= 32);
436 if (get_bits_left(gbc) < width) {
437 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at "
438 "%s: bitstream ended.\n", name);
439 return AVERROR_INVALIDDATA;
442 if (ctx->trace_enable)
443 position = get_bits_count(gbc);
445 value = get_bits_long(gbc, width);
447 if (ctx->trace_enable) {
450 for (i = 0; i < width; i++)
451 bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
454 ff_cbs_trace_syntax_element(ctx, position, name, subscripts,
458 if (value < range_min || value > range_max) {
459 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
460 "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
461 name, value, range_min, range_max);
462 return AVERROR_INVALIDDATA;
469 int ff_cbs_write_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc,
470 int width, const char *name,
471 const int *subscripts, uint32_t value,
472 uint32_t range_min, uint32_t range_max)
474 av_assert0(width > 0 && width <= 32);
476 if (value < range_min || value > range_max) {
477 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
478 "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
479 name, value, range_min, range_max);
480 return AVERROR_INVALIDDATA;
483 if (put_bits_left(pbc) < width)
484 return AVERROR(ENOSPC);
486 if (ctx->trace_enable) {
489 for (i = 0; i < width; i++)
490 bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
493 ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc),
494 name, subscripts, bits, value);
498 put_bits(pbc, width, value);
500 put_bits32(pbc, value);
506 int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx,
507 CodedBitstreamUnit *unit,
509 void (*free)(void *opaque, uint8_t *data))
511 av_assert0(!unit->content && !unit->content_ref);
513 unit->content = av_mallocz(size);
515 return AVERROR(ENOMEM);
517 unit->content_ref = av_buffer_create(unit->content, size,
519 if (!unit->content_ref) {
520 av_freep(&unit->content);
521 return AVERROR(ENOMEM);
527 int ff_cbs_alloc_unit_data(CodedBitstreamContext *ctx,
528 CodedBitstreamUnit *unit,
531 av_assert0(!unit->data && !unit->data_ref);
533 unit->data_ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
535 return AVERROR(ENOMEM);
537 unit->data = unit->data_ref->data;
538 unit->data_size = size;
540 memset(unit->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
545 static int cbs_insert_unit(CodedBitstreamContext *ctx,
546 CodedBitstreamFragment *frag,
549 CodedBitstreamUnit *units;
551 units = av_malloc_array(frag->nb_units + 1, sizeof(*units));
553 return AVERROR(ENOMEM);
556 memcpy(units, frag->units, position * sizeof(*units));
557 if (position < frag->nb_units)
558 memcpy(units + position + 1, frag->units + position,
559 (frag->nb_units - position) * sizeof(*units));
561 memset(units + position, 0, sizeof(*units));
563 av_freep(&frag->units);
570 int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx,
571 CodedBitstreamFragment *frag,
573 CodedBitstreamUnitType type,
575 AVBufferRef *content_buf)
577 CodedBitstreamUnit *unit;
578 AVBufferRef *content_ref;
582 position = frag->nb_units;
583 av_assert0(position >= 0 && position <= frag->nb_units);
586 content_ref = av_buffer_ref(content_buf);
588 return AVERROR(ENOMEM);
593 err = cbs_insert_unit(ctx, frag, position);
595 av_buffer_unref(&content_ref);
599 unit = &frag->units[position];
601 unit->content = content;
602 unit->content_ref = content_ref;
607 int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx,
608 CodedBitstreamFragment *frag,
610 CodedBitstreamUnitType type,
611 uint8_t *data, size_t data_size,
612 AVBufferRef *data_buf)
614 CodedBitstreamUnit *unit;
615 AVBufferRef *data_ref;
619 position = frag->nb_units;
620 av_assert0(position >= 0 && position <= frag->nb_units);
623 data_ref = av_buffer_ref(data_buf);
625 data_ref = av_buffer_create(data, data_size, NULL, NULL, 0);
627 return AVERROR(ENOMEM);
629 err = cbs_insert_unit(ctx, frag, position);
631 av_buffer_unref(&data_ref);
635 unit = &frag->units[position];
638 unit->data_size = data_size;
639 unit->data_ref = data_ref;
644 int ff_cbs_delete_unit(CodedBitstreamContext *ctx,
645 CodedBitstreamFragment *frag,
648 if (position < 0 || position >= frag->nb_units)
649 return AVERROR(EINVAL);
651 cbs_unit_uninit(ctx, &frag->units[position]);
655 if (frag->nb_units == 0) {
656 av_freep(&frag->units);
659 memmove(frag->units + position,
660 frag->units + position + 1,
661 (frag->nb_units - position) * sizeof(*frag->units));
663 // Don't bother reallocating the unit array.