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/common.h"
27 #include "cbs_internal.h"
30 static const CodedBitstreamType *cbs_type_table[] = {
42 int ff_cbs_init(CodedBitstreamContext *ctx,
43 enum AVCodecID codec_id, void *log_ctx)
45 const CodedBitstreamType *type;
49 for (i = 0; i < FF_ARRAY_ELEMS(cbs_type_table); i++) {
50 if (cbs_type_table[i]->codec_id == codec_id) {
51 type = cbs_type_table[i];
56 return AVERROR(EINVAL);
58 ctx->log_ctx = log_ctx;
61 ctx->priv_data = av_mallocz(ctx->codec->priv_data_size);
63 return AVERROR(ENOMEM);
65 ctx->decompose_unit_types = NULL;
67 ctx->trace_enable = 0;
68 ctx->trace_level = AV_LOG_TRACE;
73 void ff_cbs_close(CodedBitstreamContext *ctx)
75 if (ctx->codec && ctx->codec->close)
76 ctx->codec->close(ctx);
78 av_freep(&ctx->priv_data);
81 static void cbs_unit_uninit(CodedBitstreamContext *ctx,
82 CodedBitstreamUnit *unit)
84 if (ctx->codec->free_unit && unit->content && !unit->content_external)
85 ctx->codec->free_unit(unit);
87 av_freep(&unit->data);
89 unit->data_bit_padding = 0;
92 void ff_cbs_fragment_uninit(CodedBitstreamContext *ctx,
93 CodedBitstreamFragment *frag)
97 for (i = 0; i < frag->nb_units; i++)
98 cbs_unit_uninit(ctx, &frag->units[i]);
99 av_freep(&frag->units);
102 av_freep(&frag->data);
104 frag->data_bit_padding = 0;
107 static int cbs_read_fragment_content(CodedBitstreamContext *ctx,
108 CodedBitstreamFragment *frag)
112 for (i = 0; i < frag->nb_units; i++) {
113 if (ctx->decompose_unit_types) {
114 for (j = 0; j < ctx->nb_decompose_unit_types; j++) {
115 if (ctx->decompose_unit_types[j] == frag->units[i].type)
118 if (j >= ctx->nb_decompose_unit_types)
122 err = ctx->codec->read_unit(ctx, &frag->units[i]);
123 if (err == AVERROR(ENOSYS)) {
124 av_log(ctx->log_ctx, AV_LOG_WARNING,
125 "Decomposition unimplemented for unit %d "
126 "(type %d).\n", i, frag->units[i].type);
127 } else if (err < 0) {
128 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to read unit %d "
129 "(type %d).\n", i, frag->units[i].type);
137 int ff_cbs_read_extradata(CodedBitstreamContext *ctx,
138 CodedBitstreamFragment *frag,
139 const AVCodecParameters *par)
143 memset(frag, 0, sizeof(*frag));
145 frag->data = par->extradata;
146 frag->data_size = par->extradata_size;
148 err = ctx->codec->split_fragment(ctx, frag, 1);
155 return cbs_read_fragment_content(ctx, frag);
158 int ff_cbs_read_packet(CodedBitstreamContext *ctx,
159 CodedBitstreamFragment *frag,
164 memset(frag, 0, sizeof(*frag));
166 frag->data = pkt->data;
167 frag->data_size = pkt->size;
169 err = ctx->codec->split_fragment(ctx, frag, 0);
176 return cbs_read_fragment_content(ctx, frag);
179 int ff_cbs_read(CodedBitstreamContext *ctx,
180 CodedBitstreamFragment *frag,
181 const uint8_t *data, size_t size)
185 memset(frag, 0, sizeof(*frag));
187 // (We won't write to this during split.)
188 frag->data = (uint8_t*)data;
189 frag->data_size = size;
191 err = ctx->codec->split_fragment(ctx, frag, 0);
198 return cbs_read_fragment_content(ctx, frag);
202 int ff_cbs_write_fragment_data(CodedBitstreamContext *ctx,
203 CodedBitstreamFragment *frag)
207 for (i = 0; i < frag->nb_units; i++) {
208 if (!frag->units[i].content)
211 err = ctx->codec->write_unit(ctx, &frag->units[i]);
213 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to write unit %d "
214 "(type %d).\n", i, frag->units[i].type);
219 err = ctx->codec->assemble_fragment(ctx, frag);
221 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to assemble fragment.\n");
228 int ff_cbs_write_extradata(CodedBitstreamContext *ctx,
229 AVCodecParameters *par,
230 CodedBitstreamFragment *frag)
234 err = ff_cbs_write_fragment_data(ctx, frag);
238 av_freep(&par->extradata);
240 par->extradata = av_malloc(frag->data_size +
241 AV_INPUT_BUFFER_PADDING_SIZE);
243 return AVERROR(ENOMEM);
245 memcpy(par->extradata, frag->data, frag->data_size);
246 memset(par->extradata + frag->data_size, 0,
247 AV_INPUT_BUFFER_PADDING_SIZE);
248 par->extradata_size = frag->data_size;
253 int ff_cbs_write_packet(CodedBitstreamContext *ctx,
255 CodedBitstreamFragment *frag)
259 err = ff_cbs_write_fragment_data(ctx, frag);
263 err = av_new_packet(pkt, frag->data_size);
267 memcpy(pkt->data, frag->data, frag->data_size);
268 pkt->size = frag->data_size;
274 void ff_cbs_trace_header(CodedBitstreamContext *ctx,
277 if (!ctx->trace_enable)
280 av_log(ctx->log_ctx, ctx->trace_level, "%s\n", name);
283 void ff_cbs_trace_syntax_element(CodedBitstreamContext *ctx, int position,
284 const char *name, const char *bits,
287 size_t name_len, bits_len;
290 if (!ctx->trace_enable)
293 av_assert0(value >= INT_MIN && value <= UINT32_MAX);
295 name_len = strlen(name);
296 bits_len = strlen(bits);
298 if (name_len + bits_len > 60)
303 av_log(ctx->log_ctx, ctx->trace_level, "%-10d %s%*s = %"PRId64"\n",
304 position, name, pad, bits, value);
307 int ff_cbs_read_unsigned(CodedBitstreamContext *ctx, BitstreamContext *bc,
308 int width, const char *name, uint32_t *write_to,
309 uint32_t range_min, uint32_t range_max)
314 av_assert0(width <= 32);
316 if (bitstream_bits_left(bc) < width) {
317 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at "
318 "%s: bitstream ended.\n", name);
319 return AVERROR_INVALIDDATA;
322 if (ctx->trace_enable)
323 position = bitstream_tell(bc);
325 value = bitstream_read(bc, width);
327 if (ctx->trace_enable) {
330 for (i = 0; i < width; i++)
331 bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
334 ff_cbs_trace_syntax_element(ctx, position, name, bits, value);
337 if (value < range_min || value > range_max) {
338 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
339 "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
340 name, value, range_min, range_max);
341 return AVERROR_INVALIDDATA;
348 int ff_cbs_write_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc,
349 int width, const char *name, uint32_t value,
350 uint32_t range_min, uint32_t range_max)
352 av_assert0(width <= 32);
354 if (value < range_min || value > range_max) {
355 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
356 "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
357 name, value, range_min, range_max);
358 return AVERROR_INVALIDDATA;
361 if (put_bits_left(pbc) < width)
362 return AVERROR(ENOSPC);
364 if (ctx->trace_enable) {
367 for (i = 0; i < width; i++)
368 bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
371 ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), name, bits, value);
375 put_bits(pbc, width, value);
377 put_bits32(pbc, value);
383 static int cbs_insert_unit(CodedBitstreamContext *ctx,
384 CodedBitstreamFragment *frag,
387 CodedBitstreamUnit *units;
389 units = av_malloc_array(frag->nb_units + 1, sizeof(*units));
391 return AVERROR(ENOMEM);
394 memcpy(units, frag->units, position * sizeof(*units));
395 if (position < frag->nb_units)
396 memcpy(units + position + 1, frag->units + position,
397 (frag->nb_units - position) * sizeof(*units));
399 memset(units + position, 0, sizeof(*units));
401 av_freep(&frag->units);
408 int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx,
409 CodedBitstreamFragment *frag,
410 int position, uint32_t type,
416 position = frag->nb_units;
417 av_assert0(position >= 0 && position <= frag->nb_units);
419 err = cbs_insert_unit(ctx, frag, position);
423 frag->units[position].type = type;
424 frag->units[position].content = content;
425 frag->units[position].content_external = 1;
430 int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx,
431 CodedBitstreamFragment *frag,
432 int position, uint32_t type,
433 uint8_t *data, size_t data_size)
438 position = frag->nb_units;
439 av_assert0(position >= 0 && position <= frag->nb_units);
441 err = cbs_insert_unit(ctx, frag, position);
445 frag->units[position].type = type;
446 frag->units[position].data = data;
447 frag->units[position].data_size = data_size;
452 int ff_cbs_delete_unit(CodedBitstreamContext *ctx,
453 CodedBitstreamFragment *frag,
456 if (position < 0 || position >= frag->nb_units)
457 return AVERROR(EINVAL);
459 cbs_unit_uninit(ctx, &frag->units[position]);
463 if (frag->nb_units == 0) {
464 av_freep(&frag->units);
467 memmove(frag->units + position,
468 frag->units + position + 1,
469 (frag->nb_units - position) * sizeof(*frag->units));
471 // Don't bother reallocating the unit array.