cbs: Refcount all the things!
[libav.git] / libavcodec / cbs.c
1 /*
2 * This file is part of Libav.
3 *
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.
8 *
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.
13 *
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
17 */
18
19 #include <string.h>
20
21 #include "config.h"
22
23 #include "libavutil/avassert.h"
24 #include "libavutil/buffer.h"
25 #include "libavutil/common.h"
26
27 #include "cbs.h"
28 #include "cbs_internal.h"
29
30
31 static const CodedBitstreamType *cbs_type_table[] = {
32 #if CONFIG_CBS_H264
33 &ff_cbs_type_h264,
34 #endif
35 #if CONFIG_CBS_H265
36 &ff_cbs_type_h265,
37 #endif
38 #if CONFIG_CBS_MPEG2
39 &ff_cbs_type_mpeg2,
40 #endif
41 };
42
43 int ff_cbs_init(CodedBitstreamContext **ctx_ptr,
44 enum AVCodecID codec_id, void *log_ctx)
45 {
46 CodedBitstreamContext *ctx;
47 const CodedBitstreamType *type;
48 int i;
49
50 type = NULL;
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];
54 break;
55 }
56 }
57 if (!type)
58 return AVERROR(EINVAL);
59
60 ctx = av_mallocz(sizeof(*ctx));
61 if (!ctx)
62 return AVERROR(ENOMEM);
63
64 ctx->log_ctx = log_ctx;
65 ctx->codec = type;
66
67 ctx->priv_data = av_mallocz(ctx->codec->priv_data_size);
68 if (!ctx->priv_data) {
69 av_freep(&ctx);
70 return AVERROR(ENOMEM);
71 }
72
73 ctx->decompose_unit_types = NULL;
74
75 ctx->trace_enable = 0;
76 ctx->trace_level = AV_LOG_TRACE;
77
78 *ctx_ptr = ctx;
79 return 0;
80 }
81
82 void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
83 {
84 CodedBitstreamContext *ctx = *ctx_ptr;
85
86 if (!ctx)
87 return;
88
89 if (ctx->codec && ctx->codec->close)
90 ctx->codec->close(ctx);
91
92 av_freep(&ctx->priv_data);
93 av_freep(ctx_ptr);
94 }
95
96 static void cbs_unit_uninit(CodedBitstreamContext *ctx,
97 CodedBitstreamUnit *unit)
98 {
99 av_buffer_unref(&unit->content_ref);
100 unit->content = NULL;
101
102 av_buffer_unref(&unit->data_ref);
103 unit->data = NULL;
104 unit->data_size = 0;
105 unit->data_bit_padding = 0;
106 }
107
108 void ff_cbs_fragment_uninit(CodedBitstreamContext *ctx,
109 CodedBitstreamFragment *frag)
110 {
111 int i;
112
113 for (i = 0; i < frag->nb_units; i++)
114 cbs_unit_uninit(ctx, &frag->units[i]);
115 av_freep(&frag->units);
116 frag->nb_units = 0;
117
118 av_buffer_unref(&frag->data_ref);
119 frag->data = NULL;
120 frag->data_size = 0;
121 frag->data_bit_padding = 0;
122 }
123
124 static int cbs_read_fragment_content(CodedBitstreamContext *ctx,
125 CodedBitstreamFragment *frag)
126 {
127 int err, i, j;
128
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)
133 break;
134 }
135 if (j >= ctx->nb_decompose_unit_types)
136 continue;
137 }
138
139 av_buffer_unref(&frag->units[i].content_ref);
140 frag->units[i].content = NULL;
141
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);
150 return err;
151 }
152 }
153
154 return 0;
155 }
156
157 int ff_cbs_read_extradata(CodedBitstreamContext *ctx,
158 CodedBitstreamFragment *frag,
159 const AVCodecParameters *par)
160 {
161 int err;
162
163 memset(frag, 0, sizeof(*frag));
164
165 frag->data = par->extradata;
166 frag->data_size = par->extradata_size;
167
168 err = ctx->codec->split_fragment(ctx, frag, 1);
169 if (err < 0)
170 return err;
171
172 frag->data = NULL;
173 frag->data_size = 0;
174
175 return cbs_read_fragment_content(ctx, frag);
176 }
177
178 static int cbs_fill_fragment_data(CodedBitstreamContext *ctx,
179 CodedBitstreamFragment *frag,
180 const uint8_t *data, size_t size)
181 {
182 av_assert0(!frag->data && !frag->data_ref);
183
184 frag->data_ref =
185 av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
186 if (!frag->data_ref)
187 return AVERROR(ENOMEM);
188
189 frag->data = frag->data_ref->data;
190 frag->data_size = size;
191
192 memcpy(frag->data, data, size);
193 memset(frag->data + size, 0,
194 AV_INPUT_BUFFER_PADDING_SIZE);
195
196 return 0;
197 }
198
199 int ff_cbs_read_packet(CodedBitstreamContext *ctx,
200 CodedBitstreamFragment *frag,
201 const AVPacket *pkt)
202 {
203 int err;
204
205 memset(frag, 0, sizeof(*frag));
206
207 if (pkt->buf) {
208 frag->data_ref = av_buffer_ref(pkt->buf);
209 if (!frag->data_ref)
210 return AVERROR(ENOMEM);
211
212 frag->data = pkt->data;
213 frag->data_size = pkt->size;
214
215 } else {
216 err = cbs_fill_fragment_data(ctx, frag, pkt->data, pkt->size);
217 if (err < 0)
218 return err;
219 }
220
221 err = ctx->codec->split_fragment(ctx, frag, 0);
222 if (err < 0)
223 return err;
224
225 return cbs_read_fragment_content(ctx, frag);
226 }
227
228 int ff_cbs_read(CodedBitstreamContext *ctx,
229 CodedBitstreamFragment *frag,
230 const uint8_t *data, size_t size)
231 {
232 int err;
233
234 memset(frag, 0, sizeof(*frag));
235
236 err = cbs_fill_fragment_data(ctx, frag, data, size);
237 if (err < 0)
238 return err;
239
240 err = ctx->codec->split_fragment(ctx, frag, 0);
241 if (err < 0)
242 return err;
243
244 return cbs_read_fragment_content(ctx, frag);
245 }
246
247
248 int ff_cbs_write_fragment_data(CodedBitstreamContext *ctx,
249 CodedBitstreamFragment *frag)
250 {
251 int err, i;
252
253 for (i = 0; i < frag->nb_units; i++) {
254 CodedBitstreamUnit *unit = &frag->units[i];
255
256 if (!unit->content)
257 continue;
258
259 av_buffer_unref(&unit->data_ref);
260 unit->data = NULL;
261
262 err = ctx->codec->write_unit(ctx, unit);
263 if (err < 0) {
264 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to write unit %d "
265 "(type %"PRIu32").\n", i, unit->type);
266 return err;
267 }
268 }
269
270 av_buffer_unref(&frag->data_ref);
271 frag->data = NULL;
272
273 err = ctx->codec->assemble_fragment(ctx, frag);
274 if (err < 0) {
275 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to assemble fragment.\n");
276 return err;
277 }
278
279 return 0;
280 }
281
282 int ff_cbs_write_extradata(CodedBitstreamContext *ctx,
283 AVCodecParameters *par,
284 CodedBitstreamFragment *frag)
285 {
286 int err;
287
288 err = ff_cbs_write_fragment_data(ctx, frag);
289 if (err < 0)
290 return err;
291
292 av_freep(&par->extradata);
293
294 par->extradata = av_malloc(frag->data_size +
295 AV_INPUT_BUFFER_PADDING_SIZE);
296 if (!par->extradata)
297 return AVERROR(ENOMEM);
298
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;
303
304 return 0;
305 }
306
307 int ff_cbs_write_packet(CodedBitstreamContext *ctx,
308 AVPacket *pkt,
309 CodedBitstreamFragment *frag)
310 {
311 int err;
312
313 err = ff_cbs_write_fragment_data(ctx, frag);
314 if (err < 0)
315 return err;
316
317 err = av_new_packet(pkt, frag->data_size);
318 if (err < 0)
319 return err;
320
321 memcpy(pkt->data, frag->data, frag->data_size);
322 pkt->size = frag->data_size;
323
324 return 0;
325 }
326
327
328 void ff_cbs_trace_header(CodedBitstreamContext *ctx,
329 const char *name)
330 {
331 if (!ctx->trace_enable)
332 return;
333
334 av_log(ctx->log_ctx, ctx->trace_level, "%s\n", name);
335 }
336
337 void ff_cbs_trace_syntax_element(CodedBitstreamContext *ctx, int position,
338 const char *name, const char *bits,
339 int64_t value)
340 {
341 size_t name_len, bits_len;
342 int pad;
343
344 if (!ctx->trace_enable)
345 return;
346
347 av_assert0(value >= INT_MIN && value <= UINT32_MAX);
348
349 name_len = strlen(name);
350 bits_len = strlen(bits);
351
352 if (name_len + bits_len > 60)
353 pad = bits_len + 2;
354 else
355 pad = 61 - name_len;
356
357 av_log(ctx->log_ctx, ctx->trace_level, "%-10d %s%*s = %"PRId64"\n",
358 position, name, pad, bits, value);
359 }
360
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)
364 {
365 uint32_t value;
366 int position;
367
368 av_assert0(width <= 32);
369
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;
374 }
375
376 if (ctx->trace_enable)
377 position = bitstream_tell(bc);
378
379 value = bitstream_read(bc, width);
380
381 if (ctx->trace_enable) {
382 char bits[33];
383 int i;
384 for (i = 0; i < width; i++)
385 bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
386 bits[i] = 0;
387
388 ff_cbs_trace_syntax_element(ctx, position, name, bits, value);
389 }
390
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;
396 }
397
398 *write_to = value;
399 return 0;
400 }
401
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)
405 {
406 av_assert0(width <= 32);
407
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;
413 }
414
415 if (put_bits_left(pbc) < width)
416 return AVERROR(ENOSPC);
417
418 if (ctx->trace_enable) {
419 char bits[33];
420 int i;
421 for (i = 0; i < width; i++)
422 bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
423 bits[i] = 0;
424
425 ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), name, bits, value);
426 }
427
428 if (width < 32)
429 put_bits(pbc, width, value);
430 else
431 put_bits32(pbc, value);
432
433 return 0;
434 }
435
436
437 int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx,
438 CodedBitstreamUnit *unit,
439 size_t size,
440 void (*free)(void *opaque, uint8_t *data))
441 {
442 av_assert0(!unit->content && !unit->content_ref);
443
444 unit->content = av_mallocz(size);
445 if (!unit->content)
446 return AVERROR(ENOMEM);
447
448 unit->content_ref = av_buffer_create(unit->content, size,
449 free, ctx, 0);
450 if (!unit->content_ref) {
451 av_freep(&unit->content);
452 return AVERROR(ENOMEM);
453 }
454
455 return 0;
456 }
457
458 int ff_cbs_alloc_unit_data(CodedBitstreamContext *ctx,
459 CodedBitstreamUnit *unit,
460 size_t size)
461 {
462 av_assert0(!unit->data && !unit->data_ref);
463
464 unit->data_ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
465 if (!unit->data_ref)
466 return AVERROR(ENOMEM);
467
468 unit->data = unit->data_ref->data;
469 unit->data_size = size;
470
471 memset(unit->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
472
473 return 0;
474 }
475
476 static int cbs_insert_unit(CodedBitstreamContext *ctx,
477 CodedBitstreamFragment *frag,
478 int position)
479 {
480 CodedBitstreamUnit *units;
481
482 units = av_malloc_array(frag->nb_units + 1, sizeof(*units));
483 if (!units)
484 return AVERROR(ENOMEM);
485
486 if (position > 0)
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));
491
492 memset(units + position, 0, sizeof(*units));
493
494 av_freep(&frag->units);
495 frag->units = units;
496 ++frag->nb_units;
497
498 return 0;
499 }
500
501 int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx,
502 CodedBitstreamFragment *frag,
503 int position,
504 CodedBitstreamUnitType type,
505 void *content,
506 AVBufferRef *content_buf)
507 {
508 CodedBitstreamUnit *unit;
509 AVBufferRef *content_ref;
510 int err;
511
512 if (position == -1)
513 position = frag->nb_units;
514 av_assert0(position >= 0 && position <= frag->nb_units);
515
516 if (content_buf) {
517 content_ref = av_buffer_ref(content_buf);
518 if (!content_ref)
519 return AVERROR(ENOMEM);
520 } else {
521 content_ref = NULL;
522 }
523
524 err = cbs_insert_unit(ctx, frag, position);
525 if (err < 0) {
526 av_buffer_unref(&content_ref);
527 return err;
528 }
529
530 unit = &frag->units[position];
531 unit->type = type;
532 unit->content = content;
533 unit->content_ref = content_ref;
534
535 return 0;
536 }
537
538 int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx,
539 CodedBitstreamFragment *frag,
540 int position,
541 CodedBitstreamUnitType type,
542 uint8_t *data, size_t data_size,
543 AVBufferRef *data_buf)
544 {
545 CodedBitstreamUnit *unit;
546 AVBufferRef *data_ref;
547 int err;
548
549 if (position == -1)
550 position = frag->nb_units;
551 av_assert0(position >= 0 && position <= frag->nb_units);
552
553 if (data_buf)
554 data_ref = av_buffer_ref(data_buf);
555 else
556 data_ref = av_buffer_create(data, data_size, NULL, NULL, 0);
557 if (!data_ref)
558 return AVERROR(ENOMEM);
559
560 err = cbs_insert_unit(ctx, frag, position);
561 if (err < 0) {
562 av_buffer_unref(&data_ref);
563 return err;
564 }
565
566 unit = &frag->units[position];
567 unit->type = type;
568 unit->data = data;
569 unit->data_size = data_size;
570 unit->data_ref = data_ref;
571
572 return 0;
573 }
574
575 int ff_cbs_delete_unit(CodedBitstreamContext *ctx,
576 CodedBitstreamFragment *frag,
577 int position)
578 {
579 if (position < 0 || position >= frag->nb_units)
580 return AVERROR(EINVAL);
581
582 cbs_unit_uninit(ctx, &frag->units[position]);
583
584 --frag->nb_units;
585
586 if (frag->nb_units == 0) {
587 av_freep(&frag->units);
588
589 } else {
590 memmove(frag->units + position,
591 frag->units + position + 1,
592 (frag->nb_units - position) * sizeof(*frag->units));
593
594 // Don't bother reallocating the unit array.
595 }
596
597 return 0;
598 }