FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/cbs.c
Date: 2023-06-04 16:45:34
Exec Total Coverage
Lines: 337 483 69.8%
Functions: 35 37 94.6%
Branches: 157 329 47.7%

Line Branch Exec Source
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/buffer.h"
25 #include "libavutil/common.h"
26 #include "libavutil/opt.h"
27
28 #include "avcodec.h"
29 #include "cbs.h"
30 #include "cbs_internal.h"
31
32
33 static const CodedBitstreamType *const cbs_type_table[] = {
34 #if CONFIG_CBS_AV1
35 &ff_cbs_type_av1,
36 #endif
37 #if CONFIG_CBS_H264
38 &ff_cbs_type_h264,
39 #endif
40 #if CONFIG_CBS_H265
41 &ff_cbs_type_h265,
42 #endif
43 #if CONFIG_CBS_JPEG
44 &ff_cbs_type_jpeg,
45 #endif
46 #if CONFIG_CBS_MPEG2
47 &ff_cbs_type_mpeg2,
48 #endif
49 #if CONFIG_CBS_VP9
50 &ff_cbs_type_vp9,
51 #endif
52 };
53
54 const enum AVCodecID ff_cbs_all_codec_ids[] = {
55 #if CONFIG_CBS_AV1
56 AV_CODEC_ID_AV1,
57 #endif
58 #if CONFIG_CBS_H264
59 AV_CODEC_ID_H264,
60 #endif
61 #if CONFIG_CBS_H265
62 AV_CODEC_ID_H265,
63 #endif
64 #if CONFIG_CBS_JPEG
65 AV_CODEC_ID_MJPEG,
66 #endif
67 #if CONFIG_CBS_MPEG2
68 AV_CODEC_ID_MPEG2VIDEO,
69 #endif
70 #if CONFIG_CBS_VP9
71 AV_CODEC_ID_VP9,
72 #endif
73 AV_CODEC_ID_NONE
74 };
75
76 193 av_cold int ff_cbs_init(CodedBitstreamContext **ctx_ptr,
77 enum AVCodecID codec_id, void *log_ctx)
78 {
79 CodedBitstreamContext *ctx;
80 const CodedBitstreamType *type;
81 int i;
82
83 193 type = NULL;
84
1/2
✓ Branch 0 taken 477 times.
✗ Branch 1 not taken.
477 for (i = 0; i < FF_ARRAY_ELEMS(cbs_type_table); i++) {
85
2/2
✓ Branch 0 taken 193 times.
✓ Branch 1 taken 284 times.
477 if (cbs_type_table[i]->codec_id == codec_id) {
86 193 type = cbs_type_table[i];
87 193 break;
88 }
89 }
90
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (!type)
91 return AVERROR(EINVAL);
92
93 193 ctx = av_mallocz(sizeof(*ctx));
94
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (!ctx)
95 return AVERROR(ENOMEM);
96
97 193 ctx->log_ctx = log_ctx;
98 193 ctx->codec = type; /* Must be before any error */
99
100
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 if (type->priv_data_size) {
101 193 ctx->priv_data = av_mallocz(ctx->codec->priv_data_size);
102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (!ctx->priv_data) {
103 av_freep(&ctx);
104 return AVERROR(ENOMEM);
105 }
106
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 114 times.
193 if (type->priv_class) {
107 79 *(const AVClass **)ctx->priv_data = type->priv_class;
108 79 av_opt_set_defaults(ctx->priv_data);
109 }
110 }
111
112 193 ctx->decompose_unit_types = NULL;
113
114 193 ctx->trace_enable = 0;
115 193 ctx->trace_level = AV_LOG_TRACE;
116
117 193 *ctx_ptr = ctx;
118 193 return 0;
119 }
120
121 av_cold void ff_cbs_flush(CodedBitstreamContext *ctx)
122 {
123 if (ctx->codec->flush)
124 ctx->codec->flush(ctx);
125 }
126
127 193 av_cold void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
128 {
129 193 CodedBitstreamContext *ctx = *ctx_ptr;
130
131
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
193 if (!ctx)
132 return;
133
134
2/2
✓ Branch 0 taken 159 times.
✓ Branch 1 taken 34 times.
193 if (ctx->codec->close)
135 159 ctx->codec->close(ctx);
136
137 193 av_freep(&ctx->write_buffer);
138
139
3/4
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 114 times.
✓ Branch 2 taken 79 times.
✗ Branch 3 not taken.
193 if (ctx->codec->priv_class && ctx->priv_data)
140 79 av_opt_free(ctx->priv_data);
141
142 193 av_freep(&ctx->priv_data);
143 193 av_freep(ctx_ptr);
144 }
145
146 27675 static void cbs_unit_uninit(CodedBitstreamUnit *unit)
147 {
148 27675 av_buffer_unref(&unit->content_ref);
149 27675 unit->content = NULL;
150
151 27675 av_buffer_unref(&unit->data_ref);
152 27675 unit->data = NULL;
153 27675 unit->data_size = 0;
154 27675 unit->data_bit_padding = 0;
155 27675 }
156
157 6455 void ff_cbs_fragment_reset(CodedBitstreamFragment *frag)
158 {
159 int i;
160
161
2/2
✓ Branch 0 taken 27603 times.
✓ Branch 1 taken 6455 times.
34058 for (i = 0; i < frag->nb_units; i++)
162 27603 cbs_unit_uninit(&frag->units[i]);
163 6455 frag->nb_units = 0;
164
165 6455 av_buffer_unref(&frag->data_ref);
166 6455 frag->data = NULL;
167 6455 frag->data_size = 0;
168 6455 frag->data_bit_padding = 0;
169 6455 }
170
171 120 av_cold void ff_cbs_fragment_free(CodedBitstreamFragment *frag)
172 {
173 120 ff_cbs_fragment_reset(frag);
174
175 120 av_freep(&frag->units);
176 120 frag->nb_units_allocated = 0;
177 120 }
178
179 6320 static int cbs_read_fragment_content(CodedBitstreamContext *ctx,
180 CodedBitstreamFragment *frag)
181 {
182 int err, i, j;
183
184
2/2
✓ Branch 0 taken 27662 times.
✓ Branch 1 taken 6319 times.
33981 for (i = 0; i < frag->nb_units; i++) {
185 27662 CodedBitstreamUnit *unit = &frag->units[i];
186
187
2/2
✓ Branch 0 taken 2111 times.
✓ Branch 1 taken 25551 times.
27662 if (ctx->decompose_unit_types) {
188
2/2
✓ Branch 0 taken 7230 times.
✓ Branch 1 taken 12 times.
7242 for (j = 0; j < ctx->nb_decompose_unit_types; j++) {
189
2/2
✓ Branch 0 taken 2099 times.
✓ Branch 1 taken 5131 times.
7230 if (ctx->decompose_unit_types[j] == unit->type)
190 2099 break;
191 }
192
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2099 times.
2111 if (j >= ctx->nb_decompose_unit_types)
193 12 continue;
194 }
195
196 27650 av_buffer_unref(&unit->content_ref);
197 27650 unit->content = NULL;
198
199
2/4
✓ Branch 0 taken 27650 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27650 times.
27650 av_assert0(unit->data && unit->data_ref);
200
201 27650 err = ctx->codec->read_unit(ctx, unit);
202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27650 times.
27650 if (err == AVERROR(ENOSYS)) {
203 av_log(ctx->log_ctx, AV_LOG_VERBOSE,
204 "Decomposition unimplemented for unit %d "
205 "(type %"PRIu32").\n", i, unit->type);
206
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27650 times.
27650 } else if (err == AVERROR(EAGAIN)) {
207 av_log(ctx->log_ctx, AV_LOG_VERBOSE,
208 "Skipping decomposition of unit %d "
209 "(type %"PRIu32").\n", i, unit->type);
210 av_buffer_unref(&unit->content_ref);
211 unit->content = NULL;
212
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 27649 times.
27650 } else if (err < 0) {
213 1 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to read unit %d "
214 "(type %"PRIu32").\n", i, unit->type);
215 1 return err;
216 }
217 }
218
219 6319 return 0;
220 }
221
222 511 static int cbs_fill_fragment_data(CodedBitstreamFragment *frag,
223 const uint8_t *data, size_t size)
224 {
225
2/4
✓ Branch 0 taken 511 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 511 times.
511 av_assert0(!frag->data && !frag->data_ref);
226
227 511 frag->data_ref =
228 511 av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 511 times.
511 if (!frag->data_ref)
230 return AVERROR(ENOMEM);
231
232 511 frag->data = frag->data_ref->data;
233 511 frag->data_size = size;
234
235 511 memcpy(frag->data, data, size);
236 511 memset(frag->data + size, 0,
237 AV_INPUT_BUFFER_PADDING_SIZE);
238
239 511 return 0;
240 }
241
242 6320 static int cbs_read_data(CodedBitstreamContext *ctx,
243 CodedBitstreamFragment *frag,
244 AVBufferRef *buf,
245 const uint8_t *data, size_t size,
246 int header)
247 {
248 int err;
249
250
2/2
✓ Branch 0 taken 5809 times.
✓ Branch 1 taken 511 times.
6320 if (buf) {
251 5809 frag->data_ref = av_buffer_ref(buf);
252
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5809 times.
5809 if (!frag->data_ref)
253 return AVERROR(ENOMEM);
254
255 5809 frag->data = (uint8_t *)data;
256 5809 frag->data_size = size;
257
258 } else {
259 511 err = cbs_fill_fragment_data(frag, data, size);
260
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 511 times.
511 if (err < 0)
261 return err;
262 }
263
264 6320 err = ctx->codec->split_fragment(ctx, frag, header);
265
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6320 times.
6320 if (err < 0)
266 return err;
267
268 6320 return cbs_read_fragment_content(ctx, frag);
269 }
270
271 59 int ff_cbs_read_extradata(CodedBitstreamContext *ctx,
272 CodedBitstreamFragment *frag,
273 const AVCodecParameters *par)
274 {
275 118 return cbs_read_data(ctx, frag, NULL,
276 59 par->extradata,
277 59 par->extradata_size, 1);
278 }
279
280 25 int ff_cbs_read_extradata_from_codec(CodedBitstreamContext *ctx,
281 CodedBitstreamFragment *frag,
282 const AVCodecContext *avctx)
283 {
284 50 return cbs_read_data(ctx, frag, NULL,
285 25 avctx->extradata,
286 25 avctx->extradata_size, 1);
287 }
288
289 5809 int ff_cbs_read_packet(CodedBitstreamContext *ctx,
290 CodedBitstreamFragment *frag,
291 const AVPacket *pkt)
292 {
293 11618 return cbs_read_data(ctx, frag, pkt->buf,
294 5809 pkt->data, pkt->size, 0);
295 }
296
297 2 int ff_cbs_read_packet_side_data(CodedBitstreamContext *ctx,
298 CodedBitstreamFragment *frag,
299 const AVPacket *pkt)
300 {
301 size_t side_data_size;
302 const uint8_t *side_data =
303 2 av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
304 &side_data_size);
305
306 2 return cbs_read_data(ctx, frag, NULL,
307 side_data, side_data_size, 1);
308 }
309
310 425 int ff_cbs_read(CodedBitstreamContext *ctx,
311 CodedBitstreamFragment *frag,
312 const uint8_t *data, size_t size)
313 {
314 425 return cbs_read_data(ctx, frag, NULL,
315 data, size, 0);
316 }
317
318 /**
319 * Allocate a new internal data buffer of the given size in the unit.
320 *
321 * The data buffer will have input padding.
322 */
323 25475 static int cbs_alloc_unit_data(CodedBitstreamUnit *unit,
324 size_t size)
325 {
326
2/4
✓ Branch 0 taken 25475 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 25475 times.
25475 av_assert0(!unit->data && !unit->data_ref);
327
328 25475 unit->data_ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
329
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25475 times.
25475 if (!unit->data_ref)
330 return AVERROR(ENOMEM);
331
332 25475 unit->data = unit->data_ref->data;
333 25475 unit->data_size = size;
334
335 25475 memset(unit->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
336
337 25475 return 0;
338 }
339
340 25475 static int cbs_write_unit_data(CodedBitstreamContext *ctx,
341 CodedBitstreamUnit *unit)
342 {
343 PutBitContext pbc;
344 int ret;
345
346
2/2
✓ Branch 0 taken 74 times.
✓ Branch 1 taken 25401 times.
25475 if (!ctx->write_buffer) {
347 // Initial write buffer size is 1MB.
348 74 ctx->write_buffer_size = 1024 * 1024;
349
350 74 reallocate_and_try_again:
351 74 ret = av_reallocp(&ctx->write_buffer, ctx->write_buffer_size);
352
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 74 times.
74 if (ret < 0) {
353 av_log(ctx->log_ctx, AV_LOG_ERROR, "Unable to allocate a "
354 "sufficiently large write buffer (last attempt "
355 "%"SIZE_SPECIFIER" bytes).\n", ctx->write_buffer_size);
356 return ret;
357 }
358 }
359
360 25475 init_put_bits(&pbc, ctx->write_buffer, ctx->write_buffer_size);
361
362 25475 ret = ctx->codec->write_unit(ctx, unit, &pbc);
363
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25475 times.
25475 if (ret < 0) {
364 if (ret == AVERROR(ENOSPC)) {
365 // Overflow.
366 if (ctx->write_buffer_size == INT_MAX / 8)
367 return AVERROR(ENOMEM);
368 ctx->write_buffer_size = FFMIN(2 * ctx->write_buffer_size, INT_MAX / 8);
369 goto reallocate_and_try_again;
370 }
371 // Write failed for some other reason.
372 return ret;
373 }
374
375 // Overflow but we didn't notice.
376
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 25475 times.
25475 av_assert0(put_bits_count(&pbc) <= 8 * ctx->write_buffer_size);
377
378
2/2
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 25423 times.
25475 if (put_bits_count(&pbc) % 8)
379 52 unit->data_bit_padding = 8 - put_bits_count(&pbc) % 8;
380 else
381 25423 unit->data_bit_padding = 0;
382
383 25475 flush_put_bits(&pbc);
384
385 25475 ret = cbs_alloc_unit_data(unit, put_bytes_output(&pbc));
386
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25475 times.
25475 if (ret < 0)
387 return ret;
388
389 25475 memcpy(unit->data, ctx->write_buffer, unit->data_size);
390
391 25475 return 0;
392 }
393
394 5527 int ff_cbs_write_fragment_data(CodedBitstreamContext *ctx,
395 CodedBitstreamFragment *frag)
396 {
397 int err, i;
398
399
2/2
✓ Branch 0 taken 25475 times.
✓ Branch 1 taken 5527 times.
31002 for (i = 0; i < frag->nb_units; i++) {
400 25475 CodedBitstreamUnit *unit = &frag->units[i];
401
402
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25475 times.
25475 if (!unit->content)
403 continue;
404
405 25475 av_buffer_unref(&unit->data_ref);
406 25475 unit->data = NULL;
407
408 25475 err = cbs_write_unit_data(ctx, unit);
409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25475 times.
25475 if (err < 0) {
410 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to write unit %d "
411 "(type %"PRIu32").\n", i, unit->type);
412 return err;
413 }
414
2/4
✓ Branch 0 taken 25475 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 25475 times.
25475 av_assert0(unit->data && unit->data_ref);
415 }
416
417 5527 av_buffer_unref(&frag->data_ref);
418 5527 frag->data = NULL;
419
420 5527 err = ctx->codec->assemble_fragment(ctx, frag);
421
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5527 times.
5527 if (err < 0) {
422 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to assemble fragment.\n");
423 return err;
424 }
425
2/4
✓ Branch 0 taken 5527 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5527 times.
5527 av_assert0(frag->data && frag->data_ref);
426
427 5527 return 0;
428 }
429
430 59 int ff_cbs_write_extradata(CodedBitstreamContext *ctx,
431 AVCodecParameters *par,
432 CodedBitstreamFragment *frag)
433 {
434 int err;
435
436 59 err = ff_cbs_write_fragment_data(ctx, frag);
437
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 if (err < 0)
438 return err;
439
440 59 av_freep(&par->extradata);
441 59 par->extradata_size = 0;
442
443
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 58 times.
59 if (!frag->data_size)
444 1 return 0;
445
446 58 par->extradata = av_malloc(frag->data_size +
447 AV_INPUT_BUFFER_PADDING_SIZE);
448
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
58 if (!par->extradata)
449 return AVERROR(ENOMEM);
450
451 58 memcpy(par->extradata, frag->data, frag->data_size);
452 58 memset(par->extradata + frag->data_size, 0,
453 AV_INPUT_BUFFER_PADDING_SIZE);
454 58 par->extradata_size = frag->data_size;
455
456 58 return 0;
457 }
458
459 5466 int ff_cbs_write_packet(CodedBitstreamContext *ctx,
460 AVPacket *pkt,
461 CodedBitstreamFragment *frag)
462 {
463 AVBufferRef *buf;
464 int err;
465
466 5466 err = ff_cbs_write_fragment_data(ctx, frag);
467
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5466 times.
5466 if (err < 0)
468 return err;
469
470 5466 buf = av_buffer_ref(frag->data_ref);
471
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5466 times.
5466 if (!buf)
472 return AVERROR(ENOMEM);
473
474 5466 av_buffer_unref(&pkt->buf);
475
476 5466 pkt->buf = buf;
477 5466 pkt->data = frag->data;
478 5466 pkt->size = frag->data_size;
479
480 5466 return 0;
481 }
482
483
484 67646 void ff_cbs_trace_header(CodedBitstreamContext *ctx,
485 const char *name)
486 {
487
1/2
✓ Branch 0 taken 67646 times.
✗ Branch 1 not taken.
67646 if (!ctx->trace_enable)
488 67646 return;
489
490 av_log(ctx->log_ctx, ctx->trace_level, "%s\n", name);
491 }
492
493 void ff_cbs_trace_syntax_element(CodedBitstreamContext *ctx, int position,
494 const char *str, const int *subscripts,
495 const char *bits, int64_t value)
496 {
497 char name[256];
498 size_t name_len, bits_len;
499 int pad, subs, i, j, k, n;
500
501 if (!ctx->trace_enable)
502 return;
503
504 av_assert0(value >= INT_MIN && value <= UINT32_MAX);
505
506 subs = subscripts ? subscripts[0] : 0;
507 n = 0;
508 for (i = j = 0; str[i];) {
509 if (str[i] == '[') {
510 if (n < subs) {
511 ++n;
512 k = snprintf(name + j, sizeof(name) - j, "[%d", subscripts[n]);
513 av_assert0(k > 0 && j + k < sizeof(name));
514 j += k;
515 for (++i; str[i] && str[i] != ']'; i++);
516 av_assert0(str[i] == ']');
517 } else {
518 while (str[i] && str[i] != ']')
519 name[j++] = str[i++];
520 av_assert0(str[i] == ']');
521 }
522 } else {
523 av_assert0(j + 1 < sizeof(name));
524 name[j++] = str[i++];
525 }
526 }
527 av_assert0(j + 1 < sizeof(name));
528 name[j] = 0;
529 av_assert0(n == subs);
530
531 name_len = strlen(name);
532 bits_len = strlen(bits);
533
534 if (name_len + bits_len > 60)
535 pad = bits_len + 2;
536 else
537 pad = 61 - name_len;
538
539 av_log(ctx->log_ctx, ctx->trace_level, "%-10d %s%*s = %"PRId64"\n",
540 position, name, pad, bits, value);
541 }
542
543 1461285 int ff_cbs_read_unsigned(CodedBitstreamContext *ctx, GetBitContext *gbc,
544 int width, const char *name,
545 const int *subscripts, uint32_t *write_to,
546 uint32_t range_min, uint32_t range_max)
547 {
548 uint32_t value;
549 int position;
550
551
2/4
✓ Branch 0 taken 1461285 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1461285 times.
1461285 av_assert0(width > 0 && width <= 32);
552
553
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1461284 times.
1461285 if (get_bits_left(gbc) < width) {
554 1 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at "
555 "%s: bitstream ended.\n", name);
556 1 return AVERROR_INVALIDDATA;
557 }
558
559
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1461284 times.
1461284 if (ctx->trace_enable)
560 position = get_bits_count(gbc);
561
562 1461284 value = get_bits_long(gbc, width);
563
564
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1461284 times.
1461284 if (ctx->trace_enable) {
565 char bits[33];
566 int i;
567 for (i = 0; i < width; i++)
568 bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
569 bits[i] = 0;
570
571 ff_cbs_trace_syntax_element(ctx, position, name, subscripts,
572 bits, value);
573 }
574
575
2/4
✓ Branch 0 taken 1461284 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1461284 times.
1461284 if (value < range_min || value > range_max) {
576 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
577 "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
578 name, value, range_min, range_max);
579 return AVERROR_INVALIDDATA;
580 }
581
582 1461284 *write_to = value;
583 1461284 return 0;
584 }
585
586 494731 int ff_cbs_write_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc,
587 int width, const char *name,
588 const int *subscripts, uint32_t value,
589 uint32_t range_min, uint32_t range_max)
590 {
591
2/4
✓ Branch 0 taken 494731 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 494731 times.
494731 av_assert0(width > 0 && width <= 32);
592
593
2/4
✓ Branch 0 taken 494731 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 494731 times.
494731 if (value < range_min || value > range_max) {
594 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
595 "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
596 name, value, range_min, range_max);
597 return AVERROR_INVALIDDATA;
598 }
599
600
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 494731 times.
494731 if (put_bits_left(pbc) < width)
601 return AVERROR(ENOSPC);
602
603
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 494731 times.
494731 if (ctx->trace_enable) {
604 char bits[33];
605 int i;
606 for (i = 0; i < width; i++)
607 bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
608 bits[i] = 0;
609
610 ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc),
611 name, subscripts, bits, value);
612 }
613
614
2/2
✓ Branch 0 taken 493765 times.
✓ Branch 1 taken 966 times.
494731 if (width < 32)
615 493765 put_bits(pbc, width, value);
616 else
617 966 put_bits32(pbc, value);
618
619 494731 return 0;
620 }
621
622 50 int ff_cbs_read_signed(CodedBitstreamContext *ctx, GetBitContext *gbc,
623 int width, const char *name,
624 const int *subscripts, int32_t *write_to,
625 int32_t range_min, int32_t range_max)
626 {
627 int32_t value;
628 int position;
629
630
2/4
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 50 times.
50 av_assert0(width > 0 && width <= 32);
631
632
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 50 times.
50 if (get_bits_left(gbc) < width) {
633 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at "
634 "%s: bitstream ended.\n", name);
635 return AVERROR_INVALIDDATA;
636 }
637
638
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
50 if (ctx->trace_enable)
639 position = get_bits_count(gbc);
640
641 50 value = get_sbits_long(gbc, width);
642
643
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
50 if (ctx->trace_enable) {
644 char bits[33];
645 int i;
646 for (i = 0; i < width; i++)
647 bits[i] = value & (1U << (width - i - 1)) ? '1' : '0';
648 bits[i] = 0;
649
650 ff_cbs_trace_syntax_element(ctx, position, name, subscripts,
651 bits, value);
652 }
653
654
2/4
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 50 times.
50 if (value < range_min || value > range_max) {
655 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
656 "%"PRId32", but must be in [%"PRId32",%"PRId32"].\n",
657 name, value, range_min, range_max);
658 return AVERROR_INVALIDDATA;
659 }
660
661 50 *write_to = value;
662 50 return 0;
663 }
664
665 50 int ff_cbs_write_signed(CodedBitstreamContext *ctx, PutBitContext *pbc,
666 int width, const char *name,
667 const int *subscripts, int32_t value,
668 int32_t range_min, int32_t range_max)
669 {
670
2/4
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 50 times.
50 av_assert0(width > 0 && width <= 32);
671
672
2/4
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 50 times.
50 if (value < range_min || value > range_max) {
673 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
674 "%"PRId32", but must be in [%"PRId32",%"PRId32"].\n",
675 name, value, range_min, range_max);
676 return AVERROR_INVALIDDATA;
677 }
678
679
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 50 times.
50 if (put_bits_left(pbc) < width)
680 return AVERROR(ENOSPC);
681
682
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
50 if (ctx->trace_enable) {
683 char bits[33];
684 int i;
685 for (i = 0; i < width; i++)
686 bits[i] = value & (1U << (width - i - 1)) ? '1' : '0';
687 bits[i] = 0;
688
689 ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc),
690 name, subscripts, bits, value);
691 }
692
693
1/2
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
50 if (width < 32)
694 50 put_sbits(pbc, width, value);
695 else
696 put_bits32(pbc, value);
697
698 50 return 0;
699 }
700
701
702 27675 static int cbs_insert_unit(CodedBitstreamFragment *frag,
703 int position)
704 {
705 CodedBitstreamUnit *units;
706
707
2/2
✓ Branch 0 taken 27328 times.
✓ Branch 1 taken 347 times.
27675 if (frag->nb_units < frag->nb_units_allocated) {
708 27328 units = frag->units;
709
710
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27328 times.
27328 if (position < frag->nb_units)
711 memmove(units + position + 1, units + position,
712 (frag->nb_units - position) * sizeof(*units));
713 } else {
714 347 units = av_malloc_array(frag->nb_units*2 + 1, sizeof(*units));
715
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 347 times.
347 if (!units)
716 return AVERROR(ENOMEM);
717
718 347 frag->nb_units_allocated = 2*frag->nb_units_allocated + 1;
719
720
2/2
✓ Branch 0 taken 227 times.
✓ Branch 1 taken 120 times.
347 if (position > 0)
721 227 memcpy(units, frag->units, position * sizeof(*units));
722
723
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 347 times.
347 if (position < frag->nb_units)
724 memcpy(units + position + 1, frag->units + position,
725 (frag->nb_units - position) * sizeof(*units));
726 }
727
728 27675 memset(units + position, 0, sizeof(*units));
729
730
2/2
✓ Branch 0 taken 347 times.
✓ Branch 1 taken 27328 times.
27675 if (units != frag->units) {
731 347 av_free(frag->units);
732 347 frag->units = units;
733 }
734
735 27675 ++frag->nb_units;
736
737 27675 return 0;
738 }
739
740 13 int ff_cbs_insert_unit_content(CodedBitstreamFragment *frag,
741 int position,
742 CodedBitstreamUnitType type,
743 void *content,
744 AVBufferRef *content_buf)
745 {
746 CodedBitstreamUnit *unit;
747 AVBufferRef *content_ref;
748 int err;
749
750
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (position == -1)
751 13 position = frag->nb_units;
752
2/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
13 av_assert0(position >= 0 && position <= frag->nb_units);
753
754
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (content_buf) {
755 13 content_ref = av_buffer_ref(content_buf);
756
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (!content_ref)
757 return AVERROR(ENOMEM);
758 } else {
759 content_ref = NULL;
760 }
761
762 13 err = cbs_insert_unit(frag, position);
763
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (err < 0) {
764 av_buffer_unref(&content_ref);
765 return err;
766 }
767
768 13 unit = &frag->units[position];
769 13 unit->type = type;
770 13 unit->content = content;
771 13 unit->content_ref = content_ref;
772
773 13 return 0;
774 }
775
776 27662 static int cbs_insert_unit_data(CodedBitstreamFragment *frag,
777 CodedBitstreamUnitType type,
778 uint8_t *data, size_t data_size,
779 AVBufferRef *data_buf,
780 int position)
781 {
782 CodedBitstreamUnit *unit;
783 AVBufferRef *data_ref;
784 int err;
785
786
2/4
✓ Branch 0 taken 27662 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27662 times.
27662 av_assert0(position >= 0 && position <= frag->nb_units);
787
788
1/2
✓ Branch 0 taken 27662 times.
✗ Branch 1 not taken.
27662 if (data_buf)
789 27662 data_ref = av_buffer_ref(data_buf);
790 else
791 data_ref = av_buffer_create(data, data_size, NULL, NULL, 0);
792
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27662 times.
27662 if (!data_ref) {
793 if (!data_buf)
794 av_free(data);
795 return AVERROR(ENOMEM);
796 }
797
798 27662 err = cbs_insert_unit(frag, position);
799
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27662 times.
27662 if (err < 0) {
800 av_buffer_unref(&data_ref);
801 return err;
802 }
803
804 27662 unit = &frag->units[position];
805 27662 unit->type = type;
806 27662 unit->data = data;
807 27662 unit->data_size = data_size;
808 27662 unit->data_ref = data_ref;
809
810 27662 return 0;
811 }
812
813 27662 int ff_cbs_append_unit_data(CodedBitstreamFragment *frag,
814 CodedBitstreamUnitType type,
815 uint8_t *data, size_t data_size,
816 AVBufferRef *data_buf)
817 {
818 27662 return cbs_insert_unit_data(frag, type,
819 data, data_size, data_buf,
820 frag->nb_units);
821 }
822
823 72 void ff_cbs_delete_unit(CodedBitstreamFragment *frag,
824 int position)
825 {
826
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 72 times.
72 av_assert0(0 <= position && position < frag->nb_units
827 && "Unit to be deleted not in fragment.");
828
829 72 cbs_unit_uninit(&frag->units[position]);
830
831 72 --frag->nb_units;
832
833
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if (frag->nb_units > 0)
834 72 memmove(frag->units + position,
835 72 frag->units + position + 1,
836 72 (frag->nb_units - position) * sizeof(*frag->units));
837 72 }
838
839 26041 static void cbs_default_free_unit_content(void *opaque, uint8_t *data)
840 {
841 26041 const CodedBitstreamUnitTypeDescriptor *desc = opaque;
842
843
2/2
✓ Branch 0 taken 32601 times.
✓ Branch 1 taken 26041 times.
58642 for (int i = 0; i < desc->type.ref.nb_offsets; i++) {
844 32601 void **ptr = (void**)(data + desc->type.ref.offsets[i]);
845 32601 av_buffer_unref((AVBufferRef**)(ptr + 1));
846 }
847 26041 av_free(data);
848 26041 }
849
850 static const CodedBitstreamUnitTypeDescriptor
851 27957 *cbs_find_unit_type_desc(CodedBitstreamContext *ctx,
852 CodedBitstreamUnit *unit)
853 {
854 const CodedBitstreamUnitTypeDescriptor *desc;
855 int i, j;
856
857
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27957 times.
27957 if (!ctx->codec->unit_types)
858 return NULL;
859
860 102901 for (i = 0;; i++) {
861 102901 desc = &ctx->codec->unit_types[i];
862
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 102901 times.
102901 if (desc->nb_unit_types == 0)
863 break;
864
2/2
✓ Branch 0 taken 17887 times.
✓ Branch 1 taken 85014 times.
102901 if (desc->nb_unit_types == CBS_UNIT_TYPE_RANGE) {
865
1/2
✓ Branch 0 taken 17887 times.
✗ Branch 1 not taken.
17887 if (unit->type >= desc->unit_type.range.start &&
866
2/2
✓ Branch 0 taken 14610 times.
✓ Branch 1 taken 3277 times.
17887 unit->type <= desc->unit_type.range.end)
867 14610 return desc;
868 } else {
869
2/2
✓ Branch 0 taken 93036 times.
✓ Branch 1 taken 71667 times.
164703 for (j = 0; j < desc->nb_unit_types; j++) {
870
2/2
✓ Branch 0 taken 13347 times.
✓ Branch 1 taken 79689 times.
93036 if (desc->unit_type.list[j] == unit->type)
871 13347 return desc;
872 }
873 }
874 }
875 return NULL;
876 }
877
878 27650 int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx,
879 CodedBitstreamUnit *unit)
880 {
881 const CodedBitstreamUnitTypeDescriptor *desc;
882
883
2/4
✓ Branch 0 taken 27650 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27650 times.
27650 av_assert0(!unit->content && !unit->content_ref);
884
885 27650 desc = cbs_find_unit_type_desc(ctx, unit);
886
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27650 times.
27650 if (!desc)
887 return AVERROR(ENOSYS);
888
889 27650 unit->content = av_mallocz(desc->content_size);
890
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27650 times.
27650 if (!unit->content)
891 return AVERROR(ENOMEM);
892
893 27650 unit->content_ref =
894 27650 av_buffer_create(unit->content, desc->content_size,
895
2/2
✓ Branch 0 taken 1916 times.
✓ Branch 1 taken 25734 times.
27650 desc->content_type == CBS_CONTENT_TYPE_COMPLEX
896 ? desc->type.complex.content_free
897 : cbs_default_free_unit_content,
898 (void*)desc, 0);
899
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27650 times.
27650 if (!unit->content_ref) {
900 av_freep(&unit->content);
901 return AVERROR(ENOMEM);
902 }
903
904 27650 return 0;
905 }
906
907 307 static int cbs_clone_internal_refs_unit_content(AVBufferRef **clone_ref,
908 const CodedBitstreamUnit *unit,
909 const CodedBitstreamUnitTypeDescriptor *desc)
910 {
911 const uint8_t *src;
912 uint8_t *copy;
913 int err, i;
914
915
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 307 times.
307 av_assert0(unit->content);
916 307 src = unit->content;
917
918 307 copy = av_memdup(src, desc->content_size);
919
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 307 times.
307 if (!copy)
920 return AVERROR(ENOMEM);
921
922
2/2
✓ Branch 0 taken 307 times.
✓ Branch 1 taken 307 times.
614 for (i = 0; i < desc->type.ref.nb_offsets; i++) {
923 307 const uint8_t *const *src_ptr = (const uint8_t* const*)(src + desc->type.ref.offsets[i]);
924 307 const AVBufferRef *src_buf = *(AVBufferRef**)(src_ptr + 1);
925 307 uint8_t **copy_ptr = (uint8_t**)(copy + desc->type.ref.offsets[i]);
926 307 AVBufferRef **copy_buf = (AVBufferRef**)(copy_ptr + 1);
927
928
1/2
✓ Branch 0 taken 307 times.
✗ Branch 1 not taken.
307 if (!*src_ptr) {
929
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 307 times.
307 av_assert0(!src_buf);
930 307 continue;
931 }
932 if (!src_buf) {
933 // We can't handle a non-refcounted pointer here - we don't
934 // have enough information to handle whatever structure lies
935 // at the other end of it.
936 err = AVERROR(EINVAL);
937 goto fail;
938 }
939
940 *copy_buf = av_buffer_ref(src_buf);
941 if (!*copy_buf) {
942 err = AVERROR(ENOMEM);
943 goto fail;
944 }
945 }
946
947 307 *clone_ref = av_buffer_create(copy, desc->content_size,
948 cbs_default_free_unit_content,
949 (void*)desc, 0);
950
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 307 times.
307 if (!*clone_ref) {
951 err = AVERROR(ENOMEM);
952 goto fail;
953 }
954
955 307 return 0;
956
957 fail:
958 for (--i; i >= 0; i--)
959 av_buffer_unref((AVBufferRef**)(copy + desc->type.ref.offsets[i]));
960 av_freep(&copy);
961 *clone_ref = NULL;
962 return err;
963 }
964
965 /*
966 * On success, unit->content and unit->content_ref are updated with
967 * the new content; unit is untouched on failure.
968 * Any old content_ref is simply overwritten and not freed.
969 */
970 307 static int cbs_clone_unit_content(CodedBitstreamContext *ctx,
971 CodedBitstreamUnit *unit)
972 {
973 const CodedBitstreamUnitTypeDescriptor *desc;
974 AVBufferRef *ref;
975 int err;
976
977 307 desc = cbs_find_unit_type_desc(ctx, unit);
978
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 307 times.
307 if (!desc)
979 return AVERROR(ENOSYS);
980
981
1/3
✓ Branch 0 taken 307 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
307 switch (desc->content_type) {
982 307 case CBS_CONTENT_TYPE_INTERNAL_REFS:
983 307 err = cbs_clone_internal_refs_unit_content(&ref, unit, desc);
984 307 break;
985
986 case CBS_CONTENT_TYPE_COMPLEX:
987 if (!desc->type.complex.content_clone)
988 return AVERROR_PATCHWELCOME;
989 err = desc->type.complex.content_clone(&ref, unit);
990 break;
991
992 default:
993 av_assert0(0 && "Invalid content type.");
994 }
995
996
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 307 times.
307 if (err < 0)
997 return err;
998
999 307 unit->content_ref = ref;
1000 307 unit->content = ref->data;
1001 307 return 0;
1002 }
1003
1004 4009 int ff_cbs_make_unit_refcounted(CodedBitstreamContext *ctx,
1005 CodedBitstreamUnit *unit)
1006 {
1007
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4009 times.
4009 av_assert0(unit->content);
1008
1/2
✓ Branch 0 taken 4009 times.
✗ Branch 1 not taken.
4009 if (unit->content_ref)
1009 4009 return 0;
1010 return cbs_clone_unit_content(ctx, unit);
1011 }
1012
1013 307 int ff_cbs_make_unit_writable(CodedBitstreamContext *ctx,
1014 CodedBitstreamUnit *unit)
1015 {
1016 307 AVBufferRef *ref = unit->content_ref;
1017 int err;
1018
1019
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 307 times.
307 av_assert0(unit->content);
1020
2/4
✓ Branch 0 taken 307 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 307 times.
307 if (ref && av_buffer_is_writable(ref))
1021 return 0;
1022
1023 307 err = cbs_clone_unit_content(ctx, unit);
1024
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 307 times.
307 if (err < 0)
1025 return err;
1026 307 av_buffer_unref(&ref);
1027 307 return 0;
1028 }
1029