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