2 * This file is part of Libav.
4 * Libav 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 * Libav 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 Libav; 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[] = {
43 int ff_cbs_init(CodedBitstreamContext **ctx_ptr,
44 enum AVCodecID codec_id, void *log_ctx)
46 CodedBitstreamContext *ctx;
47 const CodedBitstreamType *type;
51 for (i = 0; i < FF_ARRAY_ELEMS(cbs_type_table); i++) {
52 if (cbs_type_table[i]->codec_id == codec_id) {
53 type = cbs_type_table[i];
58 return AVERROR(EINVAL);
60 ctx = av_mallocz(sizeof(*ctx));
62 return AVERROR(ENOMEM);
64 ctx->log_ctx = log_ctx;
67 ctx->priv_data = av_mallocz(ctx->codec->priv_data_size);
68 if (!ctx->priv_data) {
70 return AVERROR(ENOMEM);
73 ctx->decompose_unit_types = NULL;
75 ctx->trace_enable = 0;
76 ctx->trace_level = AV_LOG_TRACE;
82 void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
84 CodedBitstreamContext *ctx = *ctx_ptr;
89 if (ctx->codec && ctx->codec->close)
90 ctx->codec->close(ctx);
92 av_freep(&ctx->priv_data);
96 static void cbs_unit_uninit(CodedBitstreamContext *ctx,
97 CodedBitstreamUnit *unit)
99 av_buffer_unref(&unit->content_ref);
100 unit->content = NULL;
102 av_buffer_unref(&unit->data_ref);
105 unit->data_bit_padding = 0;
108 void ff_cbs_fragment_uninit(CodedBitstreamContext *ctx,
109 CodedBitstreamFragment *frag)
113 for (i = 0; i < frag->nb_units; i++)
114 cbs_unit_uninit(ctx, &frag->units[i]);
115 av_freep(&frag->units);
118 av_buffer_unref(&frag->data_ref);
121 frag->data_bit_padding = 0;
124 static int cbs_read_fragment_content(CodedBitstreamContext *ctx,
125 CodedBitstreamFragment *frag)
129 for (i = 0; i < frag->nb_units; i++) {
130 if (ctx->decompose_unit_types) {
131 for (j = 0; j < ctx->nb_decompose_unit_types; j++) {
132 if (ctx->decompose_unit_types[j] == frag->units[i].type)
135 if (j >= ctx->nb_decompose_unit_types)
139 av_buffer_unref(&frag->units[i].content_ref);
140 frag->units[i].content = NULL;
142 err = ctx->codec->read_unit(ctx, &frag->units[i]);
143 if (err == AVERROR(ENOSYS)) {
144 av_log(ctx->log_ctx, AV_LOG_VERBOSE,
145 "Decomposition unimplemented for unit %d "
146 "(type %"PRIu32").\n", i, frag->units[i].type);
147 } else if (err < 0) {
148 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to read unit %d "
149 "(type %"PRIu32").\n", i, frag->units[i].type);
157 int ff_cbs_read_extradata(CodedBitstreamContext *ctx,
158 CodedBitstreamFragment *frag,
159 const AVCodecParameters *par)
163 memset(frag, 0, sizeof(*frag));
165 frag->data = par->extradata;
166 frag->data_size = par->extradata_size;
168 err = ctx->codec->split_fragment(ctx, frag, 1);
175 return cbs_read_fragment_content(ctx, frag);
178 static int cbs_fill_fragment_data(CodedBitstreamContext *ctx,
179 CodedBitstreamFragment *frag,
180 const uint8_t *data, size_t size)
182 av_assert0(!frag->data && !frag->data_ref);
185 av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
187 return AVERROR(ENOMEM);
189 frag->data = frag->data_ref->data;
190 frag->data_size = size;
192 memcpy(frag->data, data, size);
193 memset(frag->data + size, 0,
194 AV_INPUT_BUFFER_PADDING_SIZE);
199 int ff_cbs_read_packet(CodedBitstreamContext *ctx,
200 CodedBitstreamFragment *frag,
205 memset(frag, 0, sizeof(*frag));
208 frag->data_ref = av_buffer_ref(pkt->buf);
210 return AVERROR(ENOMEM);
212 frag->data = pkt->data;
213 frag->data_size = pkt->size;
216 err = cbs_fill_fragment_data(ctx, frag, pkt->data, pkt->size);
221 err = ctx->codec->split_fragment(ctx, frag, 0);
225 return cbs_read_fragment_content(ctx, frag);
228 int ff_cbs_read(CodedBitstreamContext *ctx,
229 CodedBitstreamFragment *frag,
230 const uint8_t *data, size_t size)
234 memset(frag, 0, sizeof(*frag));
236 err = cbs_fill_fragment_data(ctx, frag, data, size);
240 err = ctx->codec->split_fragment(ctx, frag, 0);
244 return cbs_read_fragment_content(ctx, frag);
248 int ff_cbs_write_fragment_data(CodedBitstreamContext *ctx,
249 CodedBitstreamFragment *frag)
253 for (i = 0; i < frag->nb_units; i++) {
254 CodedBitstreamUnit *unit = &frag->units[i];
259 av_buffer_unref(&unit->data_ref);
262 err = ctx->codec->write_unit(ctx, unit);
264 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to write unit %d "
265 "(type %"PRIu32").\n", i, unit->type);
270 av_buffer_unref(&frag->data_ref);
273 err = ctx->codec->assemble_fragment(ctx, frag);
275 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to assemble fragment.\n");
282 int ff_cbs_write_extradata(CodedBitstreamContext *ctx,
283 AVCodecParameters *par,
284 CodedBitstreamFragment *frag)
288 err = ff_cbs_write_fragment_data(ctx, frag);
292 av_freep(&par->extradata);
294 par->extradata = av_malloc(frag->data_size +
295 AV_INPUT_BUFFER_PADDING_SIZE);
297 return AVERROR(ENOMEM);
299 memcpy(par->extradata, frag->data, frag->data_size);
300 memset(par->extradata + frag->data_size, 0,
301 AV_INPUT_BUFFER_PADDING_SIZE);
302 par->extradata_size = frag->data_size;
307 int ff_cbs_write_packet(CodedBitstreamContext *ctx,
309 CodedBitstreamFragment *frag)
313 err = ff_cbs_write_fragment_data(ctx, frag);
317 err = av_new_packet(pkt, frag->data_size);
321 memcpy(pkt->data, frag->data, frag->data_size);
322 pkt->size = frag->data_size;
328 void ff_cbs_trace_header(CodedBitstreamContext *ctx,
331 if (!ctx->trace_enable)
334 av_log(ctx->log_ctx, ctx->trace_level, "%s\n", name);
337 void ff_cbs_trace_syntax_element(CodedBitstreamContext *ctx, int position,
338 const char *name, const char *bits,
341 size_t name_len, bits_len;
344 if (!ctx->trace_enable)
347 av_assert0(value >= INT_MIN && value <= UINT32_MAX);
349 name_len = strlen(name);
350 bits_len = strlen(bits);
352 if (name_len + bits_len > 60)
357 av_log(ctx->log_ctx, ctx->trace_level, "%-10d %s%*s = %"PRId64"\n",
358 position, name, pad, bits, value);
361 int ff_cbs_read_unsigned(CodedBitstreamContext *ctx, BitstreamContext *bc,
362 int width, const char *name, uint32_t *write_to,
363 uint32_t range_min, uint32_t range_max)
368 av_assert0(width <= 32);
370 if (bitstream_bits_left(bc) < width) {
371 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at "
372 "%s: bitstream ended.\n", name);
373 return AVERROR_INVALIDDATA;
376 if (ctx->trace_enable)
377 position = bitstream_tell(bc);
379 value = bitstream_read(bc, width);
381 if (ctx->trace_enable) {
384 for (i = 0; i < width; i++)
385 bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
388 ff_cbs_trace_syntax_element(ctx, position, name, bits, value);
391 if (value < range_min || value > range_max) {
392 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
393 "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
394 name, value, range_min, range_max);
395 return AVERROR_INVALIDDATA;
402 int ff_cbs_write_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc,
403 int width, const char *name, uint32_t value,
404 uint32_t range_min, uint32_t range_max)
406 av_assert0(width <= 32);
408 if (value < range_min || value > range_max) {
409 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
410 "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
411 name, value, range_min, range_max);
412 return AVERROR_INVALIDDATA;
415 if (put_bits_left(pbc) < width)
416 return AVERROR(ENOSPC);
418 if (ctx->trace_enable) {
421 for (i = 0; i < width; i++)
422 bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
425 ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), name, bits, value);
429 put_bits(pbc, width, value);
431 put_bits32(pbc, value);
437 int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx,
438 CodedBitstreamUnit *unit,
440 void (*free)(void *opaque, uint8_t *data))
442 av_assert0(!unit->content && !unit->content_ref);
444 unit->content = av_mallocz(size);
446 return AVERROR(ENOMEM);
448 unit->content_ref = av_buffer_create(unit->content, size,
450 if (!unit->content_ref) {
451 av_freep(&unit->content);
452 return AVERROR(ENOMEM);
458 int ff_cbs_alloc_unit_data(CodedBitstreamContext *ctx,
459 CodedBitstreamUnit *unit,
462 av_assert0(!unit->data && !unit->data_ref);
464 unit->data_ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
466 return AVERROR(ENOMEM);
468 unit->data = unit->data_ref->data;
469 unit->data_size = size;
471 memset(unit->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
476 static int cbs_insert_unit(CodedBitstreamContext *ctx,
477 CodedBitstreamFragment *frag,
480 CodedBitstreamUnit *units;
482 units = av_malloc_array(frag->nb_units + 1, sizeof(*units));
484 return AVERROR(ENOMEM);
487 memcpy(units, frag->units, position * sizeof(*units));
488 if (position < frag->nb_units)
489 memcpy(units + position + 1, frag->units + position,
490 (frag->nb_units - position) * sizeof(*units));
492 memset(units + position, 0, sizeof(*units));
494 av_freep(&frag->units);
501 int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx,
502 CodedBitstreamFragment *frag,
504 CodedBitstreamUnitType type,
506 AVBufferRef *content_buf)
508 CodedBitstreamUnit *unit;
509 AVBufferRef *content_ref;
513 position = frag->nb_units;
514 av_assert0(position >= 0 && position <= frag->nb_units);
517 content_ref = av_buffer_ref(content_buf);
519 return AVERROR(ENOMEM);
524 err = cbs_insert_unit(ctx, frag, position);
526 av_buffer_unref(&content_ref);
530 unit = &frag->units[position];
532 unit->content = content;
533 unit->content_ref = content_ref;
538 int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx,
539 CodedBitstreamFragment *frag,
541 CodedBitstreamUnitType type,
542 uint8_t *data, size_t data_size,
543 AVBufferRef *data_buf)
545 CodedBitstreamUnit *unit;
546 AVBufferRef *data_ref;
550 position = frag->nb_units;
551 av_assert0(position >= 0 && position <= frag->nb_units);
554 data_ref = av_buffer_ref(data_buf);
556 data_ref = av_buffer_create(data, data_size, NULL, NULL, 0);
558 return AVERROR(ENOMEM);
560 err = cbs_insert_unit(ctx, frag, position);
562 av_buffer_unref(&data_ref);
566 unit = &frag->units[position];
569 unit->data_size = data_size;
570 unit->data_ref = data_ref;
575 int ff_cbs_delete_unit(CodedBitstreamContext *ctx,
576 CodedBitstreamFragment *frag,
579 if (position < 0 || position >= frag->nb_units)
580 return AVERROR(EINVAL);
582 cbs_unit_uninit(ctx, &frag->units[position]);
586 if (frag->nb_units == 0) {
587 av_freep(&frag->units);
590 memmove(frag->units + position,
591 frag->units + position + 1,
592 (frag->nb_units - position) * sizeof(*frag->units));
594 // Don't bother reallocating the unit array.