]> git.sesse.net Git - ffmpeg/blob - libavcodec/cbs.c
libopenh264dec: Export the decoded profile and level in AVCodecContext
[ffmpeg] / 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 }