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/common.h"
27 #include "cbs_internal.h"
30 static const CodedBitstreamType *cbs_type_table[] = {
33 int ff_cbs_init(CodedBitstreamContext **ctx_ptr,
34 enum AVCodecID codec_id, void *log_ctx)
36 CodedBitstreamContext *ctx;
37 const CodedBitstreamType *type;
41 for (i = 0; i < FF_ARRAY_ELEMS(cbs_type_table); i++) {
42 if (cbs_type_table[i]->codec_id == codec_id) {
43 type = cbs_type_table[i];
48 return AVERROR(EINVAL);
50 ctx = av_mallocz(sizeof(*ctx));
52 return AVERROR(ENOMEM);
54 ctx->log_ctx = log_ctx;
57 ctx->priv_data = av_mallocz(ctx->codec->priv_data_size);
58 if (!ctx->priv_data) {
60 return AVERROR(ENOMEM);
63 ctx->decompose_unit_types = NULL;
65 ctx->trace_enable = 0;
66 ctx->trace_level = AV_LOG_TRACE;
72 void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
74 CodedBitstreamContext *ctx = *ctx_ptr;
79 if (ctx->codec && ctx->codec->close)
80 ctx->codec->close(ctx);
82 av_freep(&ctx->priv_data);
86 static void cbs_unit_uninit(CodedBitstreamContext *ctx,
87 CodedBitstreamUnit *unit)
89 if (ctx->codec->free_unit && unit->content && !unit->content_external)
90 ctx->codec->free_unit(unit);
92 av_freep(&unit->data);
94 unit->data_bit_padding = 0;
97 void ff_cbs_fragment_uninit(CodedBitstreamContext *ctx,
98 CodedBitstreamFragment *frag)
102 for (i = 0; i < frag->nb_units; i++)
103 cbs_unit_uninit(ctx, &frag->units[i]);
104 av_freep(&frag->units);
107 av_freep(&frag->data);
109 frag->data_bit_padding = 0;
112 static int cbs_read_fragment_content(CodedBitstreamContext *ctx,
113 CodedBitstreamFragment *frag)
117 for (i = 0; i < frag->nb_units; i++) {
118 if (ctx->decompose_unit_types) {
119 for (j = 0; j < ctx->nb_decompose_unit_types; j++) {
120 if (ctx->decompose_unit_types[j] == frag->units[i].type)
123 if (j >= ctx->nb_decompose_unit_types)
127 err = ctx->codec->read_unit(ctx, &frag->units[i]);
128 if (err == AVERROR(ENOSYS)) {
129 av_log(ctx->log_ctx, AV_LOG_WARNING,
130 "Decomposition unimplemented for unit %d "
131 "(type %"PRIu32").\n", i, frag->units[i].type);
132 } else if (err < 0) {
133 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to read unit %d "
134 "(type %"PRIu32").\n", i, frag->units[i].type);
142 int ff_cbs_read_extradata(CodedBitstreamContext *ctx,
143 CodedBitstreamFragment *frag,
144 const AVCodecParameters *par)
148 memset(frag, 0, sizeof(*frag));
150 frag->data = par->extradata;
151 frag->data_size = par->extradata_size;
153 err = ctx->codec->split_fragment(ctx, frag, 1);
160 return cbs_read_fragment_content(ctx, frag);
163 int ff_cbs_read_packet(CodedBitstreamContext *ctx,
164 CodedBitstreamFragment *frag,
169 memset(frag, 0, sizeof(*frag));
171 frag->data = pkt->data;
172 frag->data_size = pkt->size;
174 err = ctx->codec->split_fragment(ctx, frag, 0);
181 return cbs_read_fragment_content(ctx, frag);
184 int ff_cbs_read(CodedBitstreamContext *ctx,
185 CodedBitstreamFragment *frag,
186 const uint8_t *data, size_t size)
190 memset(frag, 0, sizeof(*frag));
192 // (We won't write to this during split.)
193 frag->data = (uint8_t*)data;
194 frag->data_size = size;
196 err = ctx->codec->split_fragment(ctx, frag, 0);
203 return cbs_read_fragment_content(ctx, frag);
207 int ff_cbs_write_fragment_data(CodedBitstreamContext *ctx,
208 CodedBitstreamFragment *frag)
212 for (i = 0; i < frag->nb_units; i++) {
213 if (!frag->units[i].content)
216 err = ctx->codec->write_unit(ctx, &frag->units[i]);
218 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to write unit %d "
219 "(type %"PRIu32").\n", i, frag->units[i].type);
224 err = ctx->codec->assemble_fragment(ctx, frag);
226 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to assemble fragment.\n");
233 int ff_cbs_write_extradata(CodedBitstreamContext *ctx,
234 AVCodecParameters *par,
235 CodedBitstreamFragment *frag)
239 err = ff_cbs_write_fragment_data(ctx, frag);
243 av_freep(&par->extradata);
245 par->extradata = av_malloc(frag->data_size +
246 AV_INPUT_BUFFER_PADDING_SIZE);
248 return AVERROR(ENOMEM);
250 memcpy(par->extradata, frag->data, frag->data_size);
251 memset(par->extradata + frag->data_size, 0,
252 AV_INPUT_BUFFER_PADDING_SIZE);
253 par->extradata_size = frag->data_size;
258 int ff_cbs_write_packet(CodedBitstreamContext *ctx,
260 CodedBitstreamFragment *frag)
264 err = ff_cbs_write_fragment_data(ctx, frag);
268 err = av_new_packet(pkt, frag->data_size);
272 memcpy(pkt->data, frag->data, frag->data_size);
273 pkt->size = frag->data_size;
279 void ff_cbs_trace_header(CodedBitstreamContext *ctx,
282 if (!ctx->trace_enable)
285 av_log(ctx->log_ctx, ctx->trace_level, "%s\n", name);
288 void ff_cbs_trace_syntax_element(CodedBitstreamContext *ctx, int position,
289 const char *name, const char *bits,
292 size_t name_len, bits_len;
295 if (!ctx->trace_enable)
298 av_assert0(value >= INT_MIN && value <= UINT32_MAX);
300 name_len = strlen(name);
301 bits_len = strlen(bits);
303 if (name_len + bits_len > 60)
308 av_log(ctx->log_ctx, ctx->trace_level, "%-10d %s%*s = %"PRId64"\n",
309 position, name, pad, bits, value);
312 int ff_cbs_read_unsigned(CodedBitstreamContext *ctx, GetBitContext *gbc,
313 int width, const char *name, uint32_t *write_to,
314 uint32_t range_min, uint32_t range_max)
319 av_assert0(width > 0 && width <= 32);
321 if (get_bits_left(gbc) < width) {
322 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at "
323 "%s: bitstream ended.\n", name);
324 return AVERROR_INVALIDDATA;
327 if (ctx->trace_enable)
328 position = get_bits_count(gbc);
330 value = get_bits_long(gbc, width);
332 if (ctx->trace_enable) {
335 for (i = 0; i < width; i++)
336 bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
339 ff_cbs_trace_syntax_element(ctx, position, name, bits, value);
342 if (value < range_min || value > range_max) {
343 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
344 "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
345 name, value, range_min, range_max);
346 return AVERROR_INVALIDDATA;
353 int ff_cbs_write_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc,
354 int width, const char *name, uint32_t value,
355 uint32_t range_min, uint32_t range_max)
357 av_assert0(width > 0 && width <= 32);
359 if (value < range_min || value > range_max) {
360 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
361 "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
362 name, value, range_min, range_max);
363 return AVERROR_INVALIDDATA;
366 if (put_bits_left(pbc) < width)
367 return AVERROR(ENOSPC);
369 if (ctx->trace_enable) {
372 for (i = 0; i < width; i++)
373 bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
376 ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), name, bits, value);
380 put_bits(pbc, width, value);
382 put_bits32(pbc, value);
388 static int cbs_insert_unit(CodedBitstreamContext *ctx,
389 CodedBitstreamFragment *frag,
392 CodedBitstreamUnit *units;
394 units = av_malloc_array(frag->nb_units + 1, sizeof(*units));
396 return AVERROR(ENOMEM);
399 memcpy(units, frag->units, position * sizeof(*units));
400 if (position < frag->nb_units)
401 memcpy(units + position + 1, frag->units + position,
402 (frag->nb_units - position) * sizeof(*units));
404 memset(units + position, 0, sizeof(*units));
406 av_freep(&frag->units);
413 int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx,
414 CodedBitstreamFragment *frag,
416 CodedBitstreamUnitType type,
422 position = frag->nb_units;
423 av_assert0(position >= 0 && position <= frag->nb_units);
425 err = cbs_insert_unit(ctx, frag, position);
429 frag->units[position].type = type;
430 frag->units[position].content = content;
431 frag->units[position].content_external = 1;
436 int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx,
437 CodedBitstreamFragment *frag,
439 CodedBitstreamUnitType type,
440 uint8_t *data, size_t data_size)
445 position = frag->nb_units;
446 av_assert0(position >= 0 && position <= frag->nb_units);
448 err = cbs_insert_unit(ctx, frag, position);
452 frag->units[position].type = type;
453 frag->units[position].data = data;
454 frag->units[position].data_size = data_size;
459 int ff_cbs_delete_unit(CodedBitstreamContext *ctx,
460 CodedBitstreamFragment *frag,
463 if (position < 0 || position >= frag->nb_units)
464 return AVERROR(EINVAL);
466 cbs_unit_uninit(ctx, &frag->units[position]);
470 if (frag->nb_units == 0) {
471 av_freep(&frag->units);
474 memmove(frag->units + position,
475 frag->units + position + 1,
476 (frag->nb_units - position) * sizeof(*frag->units));
478 // Don't bother reallocating the unit array.