lavc: Add coded bitstream read/write API
[ffmpeg.git] / libavcodec / cbs.c
1 /*
2  * This file is part of FFmpeg.
3  *
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.
8  *
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.
13  *
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
17  */
18
19 #include <string.h>
20
21 #include "config.h"
22
23 #include "libavutil/avassert.h"
24 #include "libavutil/common.h"
25
26 #include "cbs.h"
27 #include "cbs_internal.h"
28
29
30 static const CodedBitstreamType *cbs_type_table[] = {
31 };
32
33 int ff_cbs_init(CodedBitstreamContext **ctx_ptr,
34                 enum AVCodecID codec_id, void *log_ctx)
35 {
36     CodedBitstreamContext *ctx;
37     const CodedBitstreamType *type;
38     int i;
39
40     type = NULL;
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];
44             break;
45         }
46     }
47     if (!type)
48         return AVERROR(EINVAL);
49
50     ctx = av_mallocz(sizeof(*ctx));
51     if (!ctx)
52         return AVERROR(ENOMEM);
53
54     ctx->log_ctx = log_ctx;
55     ctx->codec   = type;
56
57     ctx->priv_data = av_mallocz(ctx->codec->priv_data_size);
58     if (!ctx->priv_data) {
59         av_freep(&ctx);
60         return AVERROR(ENOMEM);
61     }
62
63     ctx->decompose_unit_types = NULL;
64
65     ctx->trace_enable = 0;
66     ctx->trace_level  = AV_LOG_TRACE;
67
68     *ctx_ptr = ctx;
69     return 0;
70 }
71
72 void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
73 {
74     CodedBitstreamContext *ctx = *ctx_ptr;
75
76     if (!ctx)
77         return;
78
79     if (ctx->codec && ctx->codec->close)
80         ctx->codec->close(ctx);
81
82     av_freep(&ctx->priv_data);
83     av_freep(ctx_ptr);
84 }
85
86 static void cbs_unit_uninit(CodedBitstreamContext *ctx,
87                             CodedBitstreamUnit *unit)
88 {
89     if (ctx->codec->free_unit && unit->content && !unit->content_external)
90         ctx->codec->free_unit(unit);
91
92     av_freep(&unit->data);
93     unit->data_size = 0;
94     unit->data_bit_padding = 0;
95 }
96
97 void ff_cbs_fragment_uninit(CodedBitstreamContext *ctx,
98                             CodedBitstreamFragment *frag)
99 {
100     int i;
101
102     for (i = 0; i < frag->nb_units; i++)
103         cbs_unit_uninit(ctx, &frag->units[i]);
104     av_freep(&frag->units);
105     frag->nb_units = 0;
106
107     av_freep(&frag->data);
108     frag->data_size        = 0;
109     frag->data_bit_padding = 0;
110 }
111
112 static int cbs_read_fragment_content(CodedBitstreamContext *ctx,
113                                      CodedBitstreamFragment *frag)
114 {
115     int err, i, j;
116
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)
121                     break;
122             }
123             if (j >= ctx->nb_decompose_unit_types)
124                 continue;
125         }
126
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);
135             return err;
136         }
137     }
138
139     return 0;
140 }
141
142 int ff_cbs_read_extradata(CodedBitstreamContext *ctx,
143                           CodedBitstreamFragment *frag,
144                           const AVCodecParameters *par)
145 {
146     int err;
147
148     memset(frag, 0, sizeof(*frag));
149
150     frag->data      = par->extradata;
151     frag->data_size = par->extradata_size;
152
153     err = ctx->codec->split_fragment(ctx, frag, 1);
154     if (err < 0)
155         return err;
156
157     frag->data      = NULL;
158     frag->data_size = 0;
159
160     return cbs_read_fragment_content(ctx, frag);
161 }
162
163 int ff_cbs_read_packet(CodedBitstreamContext *ctx,
164                        CodedBitstreamFragment *frag,
165                        const AVPacket *pkt)
166 {
167     int err;
168
169     memset(frag, 0, sizeof(*frag));
170
171     frag->data      = pkt->data;
172     frag->data_size = pkt->size;
173
174     err = ctx->codec->split_fragment(ctx, frag, 0);
175     if (err < 0)
176         return err;
177
178     frag->data      = NULL;
179     frag->data_size = 0;
180
181     return cbs_read_fragment_content(ctx, frag);
182 }
183
184 int ff_cbs_read(CodedBitstreamContext *ctx,
185                 CodedBitstreamFragment *frag,
186                 const uint8_t *data, size_t size)
187 {
188     int err;
189
190     memset(frag, 0, sizeof(*frag));
191
192     // (We won't write to this during split.)
193     frag->data      = (uint8_t*)data;
194     frag->data_size = size;
195
196     err = ctx->codec->split_fragment(ctx, frag, 0);
197     if (err < 0)
198         return err;
199
200     frag->data      = NULL;
201     frag->data_size = 0;
202
203     return cbs_read_fragment_content(ctx, frag);
204 }
205
206
207 int ff_cbs_write_fragment_data(CodedBitstreamContext *ctx,
208                                CodedBitstreamFragment *frag)
209 {
210     int err, i;
211
212     for (i = 0; i < frag->nb_units; i++) {
213         if (!frag->units[i].content)
214             continue;
215
216         err = ctx->codec->write_unit(ctx, &frag->units[i]);
217         if (err < 0) {
218             av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to write unit %d "
219                    "(type %"PRIu32").\n", i, frag->units[i].type);
220             return err;
221         }
222     }
223
224     err = ctx->codec->assemble_fragment(ctx, frag);
225     if (err < 0) {
226         av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to assemble fragment.\n");
227         return err;
228     }
229
230     return 0;
231 }
232
233 int ff_cbs_write_extradata(CodedBitstreamContext *ctx,
234                            AVCodecParameters *par,
235                            CodedBitstreamFragment *frag)
236 {
237     int err;
238
239     err = ff_cbs_write_fragment_data(ctx, frag);
240     if (err < 0)
241         return err;
242
243     av_freep(&par->extradata);
244
245     par->extradata = av_malloc(frag->data_size +
246                                AV_INPUT_BUFFER_PADDING_SIZE);
247     if (!par->extradata)
248         return AVERROR(ENOMEM);
249
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;
254
255     return 0;
256 }
257
258 int ff_cbs_write_packet(CodedBitstreamContext *ctx,
259                         AVPacket *pkt,
260                         CodedBitstreamFragment *frag)
261 {
262     int err;
263
264     err = ff_cbs_write_fragment_data(ctx, frag);
265     if (err < 0)
266         return err;
267
268     err = av_new_packet(pkt, frag->data_size);
269     if (err < 0)
270         return err;
271
272     memcpy(pkt->data, frag->data, frag->data_size);
273     pkt->size = frag->data_size;
274
275     return 0;
276 }
277
278
279 void ff_cbs_trace_header(CodedBitstreamContext *ctx,
280                          const char *name)
281 {
282     if (!ctx->trace_enable)
283         return;
284
285     av_log(ctx->log_ctx, ctx->trace_level, "%s\n", name);
286 }
287
288 void ff_cbs_trace_syntax_element(CodedBitstreamContext *ctx, int position,
289                                  const char *name, const char *bits,
290                                  int64_t value)
291 {
292     size_t name_len, bits_len;
293     int pad;
294
295     if (!ctx->trace_enable)
296         return;
297
298     av_assert0(value >= INT_MIN && value <= UINT32_MAX);
299
300     name_len = strlen(name);
301     bits_len = strlen(bits);
302
303     if (name_len + bits_len > 60)
304         pad = bits_len + 2;
305     else
306         pad = 61 - name_len;
307
308     av_log(ctx->log_ctx, ctx->trace_level, "%-10d  %s%*s = %"PRId64"\n",
309            position, name, pad, bits, value);
310 }
311
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)
315 {
316     uint32_t value;
317     int position;
318
319     av_assert0(width > 0 && width <= 32);
320
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;
325     }
326
327     if (ctx->trace_enable)
328         position = get_bits_count(gbc);
329
330     value = get_bits_long(gbc, width);
331
332     if (ctx->trace_enable) {
333         char bits[33];
334         int i;
335         for (i = 0; i < width; i++)
336             bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
337         bits[i] = 0;
338
339         ff_cbs_trace_syntax_element(ctx, position, name, bits, value);
340     }
341
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;
347     }
348
349     *write_to = value;
350     return 0;
351 }
352
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)
356 {
357     av_assert0(width > 0 && width <= 32);
358
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;
364     }
365
366     if (put_bits_left(pbc) < width)
367         return AVERROR(ENOSPC);
368
369     if (ctx->trace_enable) {
370         char bits[33];
371         int i;
372         for (i = 0; i < width; i++)
373             bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
374         bits[i] = 0;
375
376         ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), name, bits, value);
377     }
378
379     if (width < 32)
380         put_bits(pbc, width, value);
381     else
382         put_bits32(pbc, value);
383
384     return 0;
385 }
386
387
388 static int cbs_insert_unit(CodedBitstreamContext *ctx,
389                            CodedBitstreamFragment *frag,
390                            int position)
391 {
392     CodedBitstreamUnit *units;
393
394     units = av_malloc_array(frag->nb_units + 1, sizeof(*units));
395     if (!units)
396         return AVERROR(ENOMEM);
397
398     if (position > 0)
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));
403
404     memset(units + position, 0, sizeof(*units));
405
406     av_freep(&frag->units);
407     frag->units = units;
408     ++frag->nb_units;
409
410     return 0;
411 }
412
413 int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx,
414                                CodedBitstreamFragment *frag,
415                                int position,
416                                CodedBitstreamUnitType type,
417                                void *content)
418 {
419     int err;
420
421     if (position == -1)
422         position = frag->nb_units;
423     av_assert0(position >= 0 && position <= frag->nb_units);
424
425     err = cbs_insert_unit(ctx, frag, position);
426     if (err < 0)
427         return err;
428
429     frag->units[position].type             = type;
430     frag->units[position].content          = content;
431     frag->units[position].content_external = 1;
432
433     return 0;
434 }
435
436 int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx,
437                             CodedBitstreamFragment *frag,
438                             int position,
439                             CodedBitstreamUnitType type,
440                             uint8_t *data, size_t data_size)
441 {
442     int err;
443
444     if (position == -1)
445         position = frag->nb_units;
446     av_assert0(position >= 0 && position <= frag->nb_units);
447
448     err = cbs_insert_unit(ctx, frag, position);
449     if (err < 0)
450         return err;
451
452     frag->units[position].type      = type;
453     frag->units[position].data      = data;
454     frag->units[position].data_size = data_size;
455
456     return 0;
457 }
458
459 int ff_cbs_delete_unit(CodedBitstreamContext *ctx,
460                        CodedBitstreamFragment *frag,
461                        int position)
462 {
463     if (position < 0 || position >= frag->nb_units)
464         return AVERROR(EINVAL);
465
466     cbs_unit_uninit(ctx, &frag->units[position]);
467
468     --frag->nb_units;
469
470     if (frag->nb_units == 0) {
471         av_freep(&frag->units);
472
473     } else {
474         memmove(frag->units + position,
475                 frag->units + position + 1,
476                 (frag->nb_units - position) * sizeof(*frag->units));
477
478         // Don't bother reallocating the unit array.
479     }
480
481     return 0;
482 }