FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/cbs_av1.c
Date: 2026-09-15 15:24:09
Exec Total Coverage
Lines: 362 549 65.9%
Functions: 17 21 81.0%
Branches: 191 365 52.3%

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 "libavutil/attributes.h"
20 #include "libavutil/avassert.h"
21 #include "libavutil/opt.h"
22 #include "libavutil/pixfmt.h"
23
24 #include "cbs.h"
25 #include "cbs_internal.h"
26 #include "cbs_av1.h"
27 #include "defs.h"
28 #include "libavutil/refstruct.h"
29
30
31 #if CBS_READ
32 static int cbs_av1_read_uvlc(CodedBitstreamContext *ctx, GetBitContext *gbc,
33 const char *name, uint32_t *write_to,
34 uint32_t range_min, uint32_t range_max)
35 {
36 uint32_t zeroes, bits_value, value;
37
38 CBS_TRACE_READ_START();
39
40 zeroes = 0;
41 while (zeroes < 32) {
42 if (get_bits_left(gbc) < 1) {
43 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid uvlc code at "
44 "%s: bitstream ended.\n", name);
45 return AVERROR_INVALIDDATA;
46 }
47
48 if (get_bits1(gbc))
49 break;
50 ++zeroes;
51 }
52
53 if (zeroes >= 32) {
54 // The spec allows at least thirty-two zero bits followed by a
55 // one to mean 2^32-1, with no constraint on the number of
56 // zeroes. The libaom reference decoder does not match this,
57 // instead reading thirty-two zeroes but not the following one
58 // to mean 2^32-1. These two interpretations are incompatible
59 // and other implementations may follow one or the other.
60 // Therefore we reject thirty-two zeroes because the intended
61 // behaviour is not clear.
62 av_log(ctx->log_ctx, AV_LOG_ERROR, "Thirty-two zero bits in "
63 "%s uvlc code: considered invalid due to conflicting "
64 "standard and reference decoder behaviour.\n", name);
65 return AVERROR_INVALIDDATA;
66 } else {
67 if (get_bits_left(gbc) < zeroes) {
68 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid uvlc code at "
69 "%s: bitstream ended.\n", name);
70 return AVERROR_INVALIDDATA;
71 }
72
73 bits_value = get_bits_long(gbc, zeroes);
74 value = bits_value + (UINT32_C(1) << zeroes) - 1;
75 }
76
77 CBS_TRACE_READ_END_NO_SUBSCRIPTS();
78
79 if (value < range_min || value > range_max) {
80 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
81 "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
82 name, value, range_min, range_max);
83 return AVERROR_INVALIDDATA;
84 }
85
86 *write_to = value;
87 return 0;
88 }
89 #endif
90
91 #if CBS_WRITE
92 static int cbs_av1_write_uvlc(CodedBitstreamContext *ctx, PutBitContext *pbc,
93 const char *name, uint32_t value,
94 uint32_t range_min, uint32_t range_max)
95 {
96 uint32_t v;
97 int zeroes;
98
99 CBS_TRACE_WRITE_START();
100
101 if (value < range_min || value > range_max) {
102 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
103 "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
104 name, value, range_min, range_max);
105 return AVERROR_INVALIDDATA;
106 }
107
108 zeroes = av_log2(value + 1);
109 v = value - (1U << zeroes) + 1;
110
111 if (put_bits_left(pbc) < 2 * zeroes + 1)
112 return AVERROR(ENOSPC);
113
114 put_bits(pbc, zeroes, 0);
115 put_bits(pbc, 1, 1);
116 put_bits(pbc, zeroes, v);
117
118 CBS_TRACE_WRITE_END_NO_SUBSCRIPTS();
119
120 return 0;
121 }
122 #endif
123
124 #if CBS_READ
125 6432 static int cbs_av1_read_leb128(CodedBitstreamContext *ctx, GetBitContext *gbc,
126 const char *name, uint64_t *write_to)
127 {
128 uint64_t value;
129 uint32_t byte;
130 int i;
131
132
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6330 times.
6330 CBS_TRACE_READ_START();
133
134 6432 value = 0;
135
1/2
✓ Branch 0 taken 8876 times.
✗ Branch 1 not taken.
8876 for (i = 0; i < 8; i++) {
136
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8876 times.
8876 if (get_bits_left(gbc) < 8) {
137 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid leb128 at "
138 "%s: bitstream ended.\n", name);
139 return AVERROR_INVALIDDATA;
140 }
141 8876 byte = get_bits(gbc, 8);
142 8876 value |= (uint64_t)(byte & 0x7f) << (i * 7);
143
2/2
✓ Branch 0 taken 6432 times.
✓ Branch 1 taken 2444 times.
8876 if (!(byte & 0x80))
144 6432 break;
145 }
146
147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6432 times.
6432 if (value > UINT32_MAX)
148 return AVERROR_INVALIDDATA;
149
150
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6330 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
6330 CBS_TRACE_READ_END_NO_SUBSCRIPTS();
151
152 6432 *write_to = value;
153 6432 return 0;
154 }
155 #endif
156
157 #if CBS_WRITE
158 1029 static int cbs_av1_write_leb128(CodedBitstreamContext *ctx, PutBitContext *pbc,
159 const char *name, uint64_t value, int fixed_length)
160 {
161 int len, i;
162 uint8_t byte;
163
164
2/2
✓ Branch 0 taken 1007 times.
✓ Branch 1 taken 22 times.
1029 CBS_TRACE_WRITE_START();
165
166 1029 len = (av_log2(value) + 7) / 7;
167
168
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1029 times.
1029 if (fixed_length) {
169 if (fixed_length < len) {
170 av_log(ctx->log_ctx, AV_LOG_ERROR, "OBU is too large for "
171 "fixed length size field (%d > %d).\n",
172 len, fixed_length);
173 return AVERROR(EINVAL);
174 }
175 len = fixed_length;
176 }
177
178
2/2
✓ Branch 0 taken 1448 times.
✓ Branch 1 taken 1029 times.
2477 for (i = 0; i < len; i++) {
179
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1448 times.
1448 if (put_bits_left(pbc) < 8)
180 return AVERROR(ENOSPC);
181
182 1448 byte = value >> (7 * i) & 0x7f;
183
2/2
✓ Branch 0 taken 419 times.
✓ Branch 1 taken 1029 times.
1448 if (i < len - 1)
184 419 byte |= 0x80;
185
186 1448 put_bits(pbc, 8, byte);
187 }
188
189
3/4
✓ Branch 0 taken 1007 times.
✓ Branch 1 taken 22 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1007 times.
1029 CBS_TRACE_WRITE_END_NO_SUBSCRIPTS();
190
191 1029 return 0;
192 }
193 #endif
194
195 #if CBS_READ
196 660 static int cbs_av1_read_ns(CodedBitstreamContext *ctx, GetBitContext *gbc,
197 uint32_t n, const char *name,
198 const int *subscripts, uint32_t *write_to)
199 {
200 uint32_t m, v, extra_bit, value;
201 int w;
202
203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 530 times.
530 CBS_TRACE_READ_START();
204
205
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 660 times.
660 av_assert0(n > 0);
206
207 660 w = av_log2(n) + 1;
208 660 m = (1 << w) - n;
209
210
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 660 times.
660 if (get_bits_left(gbc) < w) {
211 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid non-symmetric value at "
212 "%s: bitstream ended.\n", name);
213 return AVERROR_INVALIDDATA;
214 }
215
216
1/2
✓ Branch 0 taken 660 times.
✗ Branch 1 not taken.
660 if (w - 1 > 0)
217 660 v = get_bits(gbc, w - 1);
218 else
219 v = 0;
220
221
2/2
✓ Branch 0 taken 528 times.
✓ Branch 1 taken 132 times.
660 if (v < m) {
222 528 value = v;
223 } else {
224 132 extra_bit = get_bits1(gbc);
225 132 value = (v << 1) - m + extra_bit;
226 }
227
228
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 530 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
530 CBS_TRACE_READ_END();
229
230 660 *write_to = value;
231 660 return 0;
232 }
233 #endif
234
235 #if CBS_WRITE
236 130 static int cbs_av1_write_ns(CodedBitstreamContext *ctx, PutBitContext *pbc,
237 uint32_t n, const char *name,
238 const int *subscripts, uint32_t value)
239 {
240 uint32_t w, m, v, extra_bit;
241
242
1/2
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
130 CBS_TRACE_WRITE_START();
243
244
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 130 times.
130 if (value > n) {
245 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
246 "%"PRIu32", but must be in [0,%"PRIu32"].\n",
247 name, value, n);
248 return AVERROR_INVALIDDATA;
249 }
250
251 130 w = av_log2(n) + 1;
252 130 m = (1 << w) - n;
253
254
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 130 times.
130 if (put_bits_left(pbc) < w)
255 return AVERROR(ENOSPC);
256
257
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 26 times.
130 if (value < m) {
258 104 v = value;
259 104 put_bits(pbc, w - 1, v);
260 } else {
261 26 v = m + ((value - m) >> 1);
262 26 extra_bit = (value - m) & 1;
263 26 put_bits(pbc, w - 1, v);
264 26 put_bits(pbc, 1, extra_bit);
265 }
266
267
2/4
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 130 times.
130 CBS_TRACE_WRITE_END();
268
269 130 return 0;
270 }
271 #endif
272
273 #if CBS_READ
274 4295 static int cbs_av1_read_increment(CodedBitstreamContext *ctx, GetBitContext *gbc,
275 uint32_t range_min, uint32_t range_max,
276 const char *name, uint32_t *write_to)
277 {
278 uint32_t value;
279
280
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4259 times.
4259 CBS_TRACE_READ_START();
281
282
2/4
✓ Branch 0 taken 4295 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4295 times.
4295 av_assert0(range_min <= range_max && range_max - range_min < 32);
283
284
2/2
✓ Branch 0 taken 5920 times.
✓ Branch 1 taken 591 times.
6511 for (value = range_min; value < range_max;) {
285
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5920 times.
5920 if (get_bits_left(gbc) < 1) {
286 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid increment value at "
287 "%s: bitstream ended.\n", name);
288 return AVERROR_INVALIDDATA;
289 }
290
2/2
✓ Branch 1 taken 2216 times.
✓ Branch 2 taken 3704 times.
5920 if (get_bits1(gbc))
291 2216 ++value;
292 else
293 3704 break;
294 }
295
296
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4259 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4259 CBS_TRACE_READ_END_NO_SUBSCRIPTS();
297
298 4295 *write_to = value;
299 4295 return 0;
300 }
301 #endif
302
303 #if CBS_WRITE
304 1317 static int cbs_av1_write_increment(CodedBitstreamContext *ctx, PutBitContext *pbc,
305 uint32_t range_min, uint32_t range_max,
306 const char *name, uint32_t value)
307 {
308 int len;
309
310
2/2
✓ Branch 0 taken 1282 times.
✓ Branch 1 taken 35 times.
1317 CBS_TRACE_WRITE_START();
311
312
2/4
✓ Branch 0 taken 1317 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1317 times.
1317 av_assert0(range_min <= range_max && range_max - range_min < 32);
313
2/4
✓ Branch 0 taken 1317 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1317 times.
1317 if (value < range_min || value > range_max) {
314 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
315 "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
316 name, value, range_min, range_max);
317 return AVERROR_INVALIDDATA;
318 }
319
320
2/2
✓ Branch 0 taken 203 times.
✓ Branch 1 taken 1114 times.
1317 if (value == range_max)
321 203 len = range_max - range_min;
322 else
323 1114 len = value - range_min + 1;
324
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1317 times.
1317 if (put_bits_left(pbc) < len)
325 return AVERROR(ENOSPC);
326
327
1/2
✓ Branch 0 taken 1317 times.
✗ Branch 1 not taken.
1317 if (len > 0)
328 1317 put_bits(pbc, len, (1U << len) - 1 - (value != range_max));
329
330
3/4
✓ Branch 0 taken 1282 times.
✓ Branch 1 taken 35 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1282 times.
1317 CBS_TRACE_WRITE_END_NO_SUBSCRIPTS();
331
332 1317 return 0;
333 }
334 #endif
335
336 #if CBS_READ
337 184 static int cbs_av1_read_subexp(CodedBitstreamContext *ctx, GetBitContext *gbc,
338 uint32_t range_max, const char *name,
339 const int *subscripts, uint32_t *write_to)
340 {
341 uint32_t value, max_len, len, range_offset, range_bits;
342 int err;
343
344
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 184 times.
184 CBS_TRACE_READ_START();
345
346
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 184 times.
184 av_assert0(range_max > 0);
347 184 max_len = av_log2(range_max - 1) - 3;
348
349 184 err = cbs_av1_read_increment(ctx, gbc, 0, max_len,
350 "subexp_more_bits", &len);
351
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 184 times.
184 if (err < 0)
352 return err;
353
354
2/2
✓ Branch 0 taken 174 times.
✓ Branch 1 taken 10 times.
184 if (len) {
355 174 range_bits = 2 + len;
356 174 range_offset = 1 << range_bits;
357 } else {
358 10 range_bits = 3;
359 10 range_offset = 0;
360 }
361
362
1/2
✓ Branch 0 taken 184 times.
✗ Branch 1 not taken.
184 if (len < max_len) {
363 184 err = CBS_FUNC(read_simple_unsigned)(ctx, gbc, range_bits,
364 "subexp_bits", &value);
365
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 184 times.
184 if (err < 0)
366 return err;
367
368 } else {
369 err = cbs_av1_read_ns(ctx, gbc, range_max - range_offset,
370 "subexp_final_bits", NULL, &value);
371 if (err < 0)
372 return err;
373 }
374 184 value += range_offset;
375
376
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 184 times.
184 CBS_TRACE_READ_END_VALUE_ONLY();
377
378 184 *write_to = value;
379 184 return err;
380 }
381 #endif
382
383 #if CBS_WRITE
384 60 static int cbs_av1_write_subexp(CodedBitstreamContext *ctx, PutBitContext *pbc,
385 uint32_t range_max, const char *name,
386 const int *subscripts, uint32_t value)
387 {
388 int err;
389 uint32_t max_len, len, range_offset, range_bits;
390
391
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 CBS_TRACE_WRITE_START();
392
393
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60 times.
60 if (value > range_max) {
394 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
395 "%"PRIu32", but must be in [0,%"PRIu32"].\n",
396 name, value, range_max);
397 return AVERROR_INVALIDDATA;
398 }
399
400
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60 times.
60 av_assert0(range_max > 0);
401 60 max_len = av_log2(range_max - 1) - 3;
402
403
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 55 times.
60 if (value < 8) {
404 5 range_bits = 3;
405 5 range_offset = 0;
406 5 len = 0;
407 } else {
408 55 range_bits = av_log2(value);
409 55 len = range_bits - 2;
410
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
55 if (len > max_len) {
411 // The top bin is combined with the one below it.
412 av_assert0(len == max_len + 1);
413 --range_bits;
414 len = max_len;
415 }
416 55 range_offset = 1 << range_bits;
417 }
418
419 60 err = cbs_av1_write_increment(ctx, pbc, 0, max_len,
420 "subexp_more_bits", len);
421
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60 times.
60 if (err < 0)
422 return err;
423
424
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 if (len < max_len) {
425 60 err = CBS_FUNC(write_simple_unsigned)(ctx, pbc, range_bits,
426 "subexp_bits",
427 value - range_offset);
428
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60 times.
60 if (err < 0)
429 return err;
430
431 } else {
432 err = cbs_av1_write_ns(ctx, pbc, range_max - range_offset,
433 "subexp_final_bits", NULL,
434 value - range_offset);
435 if (err < 0)
436 return err;
437 }
438
439
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 CBS_TRACE_WRITE_END_VALUE_ONLY();
440
441 60 return err;
442 }
443 #endif
444
445
446 9201 static int cbs_av1_tile_log2(int blksize, int target)
447 {
448 int k;
449
2/2
✓ Branch 0 taken 10017 times.
✓ Branch 1 taken 9201 times.
19218 for (k = 0; (blksize << k) < target; k++);
450 9201 return k;
451 }
452
453 25205 static int cbs_av1_get_relative_dist(const AV1RawSequenceHeader *seq,
454 unsigned int a, unsigned int b)
455 {
456 unsigned int diff, m;
457
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25205 times.
25205 if (!seq->enable_order_hint)
458 return 0;
459 25205 diff = a - b;
460 25205 m = 1 << seq->order_hint_bits_minus_1;
461 25205 diff = (diff & (m - 1)) - (diff & m);
462 25205 return diff;
463 }
464
465 av_unused static size_t cbs_av1_get_payload_bytes_left(GetBitContext *gbc)
466 {
467 GetBitContext tmp = *gbc;
468 size_t size = 0;
469 for (int i = 0; get_bits_left(&tmp) >= 8; i++) {
470 if (get_bits(&tmp, 8))
471 size = i;
472 }
473 return size;
474 }
475
476
477 #define HEADER(name) do { \
478 CBS_FUNC(trace_header)(ctx, name); \
479 } while (0)
480
481 #define CHECK(call) do { \
482 err = (call); \
483 if (err < 0) \
484 return err; \
485 } while (0)
486
487 #define FUNC_NAME(rw, codec, name) cbs_ ## codec ## _ ## rw ## _ ## name
488 #define FUNC_AV1(rw, name) FUNC_NAME(rw, av1, name)
489 #define FUNC(name) FUNC_AV1(READWRITE, name)
490
491 #define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : NULL)
492
493 #if CBS_READ
494 #define fc(width, name, range_min, range_max) \
495 xf(width, name, current->name, range_min, range_max, 0, )
496 #define flag(name) fb(1, name)
497 #define su(width, name) \
498 xsu(width, name, current->name, 0, )
499
500 #define fbs(width, name, subs, ...) \
501 xf(width, name, current->name, 0, MAX_UINT_BITS(width), subs, __VA_ARGS__)
502 #define fcs(width, name, range_min, range_max, subs, ...) \
503 xf(width, name, current->name, range_min, range_max, subs, __VA_ARGS__)
504 #define flags(name, subs, ...) \
505 xf(1, name, current->name, 0, 1, subs, __VA_ARGS__)
506 #define sus(width, name, subs, ...) \
507 xsu(width, name, current->name, subs, __VA_ARGS__)
508
509 #define fixed(width, name, value) do { \
510 av_unused uint32_t fixed_value = value; \
511 xf(width, name, fixed_value, value, value, 0, ); \
512 } while (0)
513
514
515 #define READ
516 #define READWRITE read
517 #define RWContext GetBitContext
518
519 #define fb(width, name) do { \
520 uint32_t value; \
521 CHECK(CBS_FUNC(read_simple_unsigned)(ctx, rw, width, \
522 #name, &value)); \
523 current->name = value; \
524 } while (0)
525
526 #define xf(width, name, var, range_min, range_max, subs, ...) do { \
527 uint32_t value; \
528 CHECK(CBS_FUNC(read_unsigned)(ctx, rw, width, #name, \
529 SUBSCRIPTS(subs, __VA_ARGS__), \
530 &value, range_min, range_max)); \
531 var = value; \
532 } while (0)
533
534 #define xsu(width, name, var, subs, ...) do { \
535 int32_t value; \
536 CHECK(CBS_FUNC(read_signed)(ctx, rw, width, #name, \
537 SUBSCRIPTS(subs, __VA_ARGS__), &value, \
538 MIN_INT_BITS(width), \
539 MAX_INT_BITS(width))); \
540 var = value; \
541 } while (0)
542
543 #define uvlc(name, range_min, range_max) do { \
544 uint32_t value; \
545 CHECK(cbs_av1_read_uvlc(ctx, rw, #name, \
546 &value, range_min, range_max)); \
547 current->name = value; \
548 } while (0)
549
550 #define ns(max_value, name, subs, ...) do { \
551 uint32_t value; \
552 CHECK(cbs_av1_read_ns(ctx, rw, max_value, #name, \
553 SUBSCRIPTS(subs, __VA_ARGS__), &value)); \
554 current->name = value; \
555 } while (0)
556
557 #define increment(name, min, max) do { \
558 uint32_t value; \
559 CHECK(cbs_av1_read_increment(ctx, rw, min, max, #name, &value)); \
560 current->name = value; \
561 } while (0)
562
563 #define subexp(name, max, subs, ...) do { \
564 uint32_t value; \
565 CHECK(cbs_av1_read_subexp(ctx, rw, max, #name, \
566 SUBSCRIPTS(subs, __VA_ARGS__), &value)); \
567 current->name = value; \
568 } while (0)
569
570 #define delta_q(name) do { \
571 uint8_t delta_coded; \
572 int8_t delta_q; \
573 xf(1, name.delta_coded, delta_coded, 0, 1, 0, ); \
574 if (delta_coded) \
575 xsu(1 + 6, name.delta_q, delta_q, 0, ); \
576 else \
577 delta_q = 0; \
578 current->name = delta_q; \
579 } while (0)
580
581 #define leb128(name) do { \
582 uint64_t value; \
583 CHECK(cbs_av1_read_leb128(ctx, rw, #name, &value)); \
584 current->name = value; \
585 } while (0)
586
587 #define infer(name, value) do { \
588 current->name = value; \
589 } while (0)
590
591 #define byte_alignment(rw) (get_bits_count(rw) % 8)
592
593 #include "cbs_av1_syntax_template.c"
594
595 #undef READ
596 #undef READWRITE
597 #undef RWContext
598 #undef fb
599 #undef xf
600 #undef xsu
601 #undef uvlc
602 #undef ns
603 #undef increment
604 #undef subexp
605 #undef delta_q
606 #undef leb128
607 #undef infer
608 #undef byte_alignment
609 #endif // CBS_READ
610
611
612 #if CBS_WRITE
613 #define WRITE
614 #define READWRITE write
615 #define RWContext PutBitContext
616
617 #define fb(width, name) do { \
618 CHECK(CBS_FUNC(write_simple_unsigned)(ctx, rw, width, #name, \
619 current->name)); \
620 } while (0)
621
622 #define xf(width, name, var, range_min, range_max, subs, ...) do { \
623 CHECK(CBS_FUNC(write_unsigned)(ctx, rw, width, #name, \
624 SUBSCRIPTS(subs, __VA_ARGS__), \
625 var, range_min, range_max)); \
626 } while (0)
627
628 #define xsu(width, name, var, subs, ...) do { \
629 CHECK(CBS_FUNC(write_signed)(ctx, rw, width, #name, \
630 SUBSCRIPTS(subs, __VA_ARGS__), var, \
631 MIN_INT_BITS(width), \
632 MAX_INT_BITS(width))); \
633 } while (0)
634
635 #define uvlc(name, range_min, range_max) do { \
636 CHECK(cbs_av1_write_uvlc(ctx, rw, #name, current->name, \
637 range_min, range_max)); \
638 } while (0)
639
640 #define ns(max_value, name, subs, ...) do { \
641 CHECK(cbs_av1_write_ns(ctx, rw, max_value, #name, \
642 SUBSCRIPTS(subs, __VA_ARGS__), \
643 current->name)); \
644 } while (0)
645
646 #define increment(name, min, max) do { \
647 CHECK(cbs_av1_write_increment(ctx, rw, min, max, #name, \
648 current->name)); \
649 } while (0)
650
651 #define subexp(name, max, subs, ...) do { \
652 CHECK(cbs_av1_write_subexp(ctx, rw, max, #name, \
653 SUBSCRIPTS(subs, __VA_ARGS__), \
654 current->name)); \
655 } while (0)
656
657 #define delta_q(name) do { \
658 xf(1, name.delta_coded, current->name != 0, 0, 1, 0, ); \
659 if (current->name) \
660 xsu(1 + 6, name.delta_q, current->name, 0, ); \
661 } while (0)
662
663 #define leb128(name) do { \
664 CHECK(cbs_av1_write_leb128(ctx, rw, #name, current->name, 0)); \
665 } while (0)
666
667 #define infer(name, value) do { \
668 if (current->name != (value)) { \
669 av_log(ctx->log_ctx, AV_LOG_ERROR, \
670 "%s does not match inferred value: " \
671 "%"PRId64", but should be %"PRId64".\n", \
672 #name, (int64_t)current->name, (int64_t)(value)); \
673 return AVERROR_INVALIDDATA; \
674 } \
675 } while (0)
676
677 #define byte_alignment(rw) (put_bits_count(rw) % 8)
678
679 #include "cbs_av1_syntax_template.c"
680
681 #undef WRITE
682 #undef READWRITE
683 #undef RWContext
684 #undef fb
685 #undef xf
686 #undef xsu
687 #undef uvlc
688 #undef ns
689 #undef increment
690 #undef subexp
691 #undef delta_q
692 #undef leb128
693 #undef infer
694 #undef byte_alignment
695 #endif // CBS_WRITE
696
697 1276 static int cbs_av1_split_fragment(CodedBitstreamContext *ctx,
698 CodedBitstreamFragment *frag,
699 int header)
700 {
701 #if CBS_READ
702 GetBitContext gbc;
703 uint8_t *data;
704 size_t size;
705 uint64_t obu_length;
706 int pos, err, trace;
707
708 // Don't include this parsing in trace output.
709 1276 trace = ctx->trace_enable;
710 1276 ctx->trace_enable = 0;
711
712 1276 data = frag->data;
713 1276 size = frag->data_size;
714
715
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1276 times.
1276 if (INT_MAX / 8 < size) {
716 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid fragment: "
717 "too large (%zu bytes).\n", size);
718 err = AVERROR_INVALIDDATA;
719 goto fail;
720 }
721
722
5/6
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 1209 times.
✓ Branch 2 taken 67 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 30 times.
✓ Branch 5 taken 37 times.
1276 if (header && size && data[0] & 0x80) {
723 // first bit is nonzero, the extradata does not consist purely of
724 // OBUs. Expect MP4/Matroska AV1CodecConfigurationRecord
725 30 int config_record_version = data[0] & 0x7f;
726
727
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (config_record_version != 1) {
728 av_log(ctx->log_ctx, AV_LOG_ERROR,
729 "Unknown version %d of AV1CodecConfigurationRecord "
730 "found!\n",
731 config_record_version);
732 err = AVERROR_INVALIDDATA;
733 goto fail;
734 }
735
736
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 22 times.
30 if (size <= 4) {
737
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (size < 4) {
738 av_log(ctx->log_ctx, AV_LOG_WARNING,
739 "Undersized AV1CodecConfigurationRecord v%d found!\n",
740 config_record_version);
741 err = AVERROR_INVALIDDATA;
742 goto fail;
743 }
744
745 8 goto success;
746 }
747
748 // In AV1CodecConfigurationRecord v1, actual OBUs start after
749 // four bytes. Thus set the offset as required for properly
750 // parsing them.
751 22 data += 4;
752 22 size -= 4;
753 }
754
755
2/2
✓ Branch 0 taken 3236 times.
✓ Branch 1 taken 1268 times.
4504 while (size > 0) {
756 AV1RawOBUHeader obu_header;
757 uint64_t obu_size;
758
759 3236 init_get_bits(&gbc, data, 8 * size);
760
761 3236 err = cbs_av1_read_obu_header(ctx, &gbc, &obu_header);
762
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3236 times.
3236 if (err < 0)
763 goto fail;
764
765
2/2
✓ Branch 0 taken 3214 times.
✓ Branch 1 taken 22 times.
3236 if (obu_header.obu_has_size_field) {
766
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3214 times.
3214 if (get_bits_left(&gbc) < 8) {
767 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid OBU: fragment "
768 "too short (%zu bytes).\n", size);
769 err = AVERROR_INVALIDDATA;
770 goto fail;
771 }
772 3214 err = cbs_av1_read_leb128(ctx, &gbc, "obu_size", &obu_size);
773
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3214 times.
3214 if (err < 0)
774 goto fail;
775 } else
776 22 obu_size = size - 1 - obu_header.obu_extension_flag;
777
778 3236 pos = get_bits_count(&gbc);
779
2/4
✓ Branch 0 taken 3236 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3236 times.
3236 av_assert0(pos % 8 == 0 && pos / 8 <= size);
780
781 3236 obu_length = pos / 8 + obu_size;
782
783
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3236 times.
3236 if (size < obu_length) {
784 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid OBU length: "
785 "%"PRIu64", but only %zu bytes remaining in fragment.\n",
786 obu_length, size);
787 err = AVERROR_INVALIDDATA;
788 goto fail;
789 }
790
791 3236 err = CBS_FUNC(append_unit_data)(frag, obu_header.obu_type,
792 data, obu_length, frag->data_ref);
793
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3236 times.
3236 if (err < 0)
794 goto fail;
795
796 3236 data += obu_length;
797 3236 size -= obu_length;
798 }
799
800 1268 success:
801 1276 err = 0;
802 1276 fail:
803 1276 ctx->trace_enable = trace;
804 1276 return err;
805 #else
806 return AVERROR(ENOSYS);
807 #endif
808 }
809
810 #if CBS_READ
811 2818 static int cbs_av1_ref_tile_data(CodedBitstreamContext *ctx,
812 CodedBitstreamUnit *unit,
813 GetBitContext *gbc,
814 AVBufferRef **data_ref,
815 uint8_t **data, size_t *data_size)
816 {
817 int pos;
818
819 2818 pos = get_bits_count(gbc);
820
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2818 times.
2818 if (pos >= 8 * unit->data_size) {
821 av_log(ctx->log_ctx, AV_LOG_ERROR, "Bitstream ended before "
822 "any data in tile group (%d bits read).\n", pos);
823 return AVERROR_INVALIDDATA;
824 }
825 // Must be byte-aligned at this point.
826
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2818 times.
2818 av_assert0(pos % 8 == 0);
827
828 2818 *data_ref = av_buffer_ref(unit->data_ref);
829
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2818 times.
2818 if (!*data_ref)
830 return AVERROR(ENOMEM);
831
832 2818 *data = unit->data + pos / 8;
833 2818 *data_size = unit->data_size - pos / 8;
834
835 2818 return 0;
836 }
837 #endif
838
839 3224 static int cbs_av1_read_unit(CodedBitstreamContext *ctx,
840 CodedBitstreamUnit *unit)
841 {
842 #if CBS_READ
843 3224 CodedBitstreamAV1Context *priv = ctx->priv_data;
844 AV1RawOBU *obu;
845 GetBitContext gbc;
846 int err, start_pos, end_pos;
847
848 3224 err = CBS_FUNC(alloc_unit_content)(ctx, unit);
849
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3224 times.
3224 if (err < 0)
850 return err;
851 3224 obu = unit->content;
852
853 3224 err = init_get_bits(&gbc, unit->data, 8 * unit->data_size);
854
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3224 times.
3224 if (err < 0)
855 return err;
856
857 3224 err = cbs_av1_read_obu_header(ctx, &gbc, &obu->header);
858
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3224 times.
3224 if (err < 0)
859 return err;
860
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3224 times.
3224 av_assert0(obu->header.obu_type == unit->type);
861
862
2/2
✓ Branch 0 taken 3202 times.
✓ Branch 1 taken 22 times.
3224 if (obu->header.obu_has_size_field) {
863 uint64_t obu_size;
864 3202 err = cbs_av1_read_leb128(ctx, &gbc, "obu_size", &obu_size);
865
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3202 times.
3202 if (err < 0)
866 return err;
867 3202 obu->obu_size = obu_size;
868 } else {
869
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
22 if (unit->data_size < 1 + obu->header.obu_extension_flag) {
870 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid OBU length: "
871 "unit too short (%zu).\n", unit->data_size);
872 return AVERROR_INVALIDDATA;
873 }
874 22 obu->obu_size = unit->data_size - 1 - obu->header.obu_extension_flag;
875 }
876
877 3224 start_pos = get_bits_count(&gbc);
878
879
2/2
✓ Branch 0 taken 166 times.
✓ Branch 1 taken 3058 times.
3224 if (obu->header.obu_extension_flag) {
880
1/2
✓ Branch 0 taken 166 times.
✗ Branch 1 not taken.
166 if (obu->header.obu_type != AV1_OBU_SEQUENCE_HEADER &&
881
1/2
✓ Branch 0 taken 166 times.
✗ Branch 1 not taken.
166 obu->header.obu_type != AV1_OBU_TEMPORAL_DELIMITER &&
882
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 160 times.
166 priv->operating_point_idc) {
883 6 int in_temporal_layer =
884 6 (priv->operating_point_idc >> priv->temporal_id ) & 1;
885 6 int in_spatial_layer =
886 6 (priv->operating_point_idc >> (priv->spatial_id + 8)) & 1;
887
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 if (!in_temporal_layer || !in_spatial_layer) {
888 return AVERROR(EAGAIN); // drop_obu()
889 }
890 }
891 }
892
893
6/9
✓ Branch 0 taken 498 times.
✓ Branch 1 taken 1011 times.
✓ Branch 2 taken 290 times.
✓ Branch 3 taken 1188 times.
✓ Branch 4 taken 221 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 16 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
3224 switch (obu->header.obu_type) {
894 498 case AV1_OBU_SEQUENCE_HEADER:
895 {
896 498 err = cbs_av1_read_sequence_header_obu(ctx, &gbc,
897 &obu->obu.sequence_header);
898
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 498 times.
498 if (err < 0)
899 return err;
900
901
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 460 times.
498 if (priv->operating_point >= 0) {
902 38 AV1RawSequenceHeader *sequence_header = &obu->obu.sequence_header;
903
904
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (priv->operating_point > sequence_header->operating_points_cnt_minus_1) {
905 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid Operating Point %d requested. "
906 "Must not be higher than %u.\n",
907 priv->operating_point, sequence_header->operating_points_cnt_minus_1);
908 return AVERROR(EINVAL);
909 }
910 38 priv->operating_point_idc = sequence_header->operating_point_idc[priv->operating_point];
911 }
912
913 498 av_refstruct_replace(&priv->sequence_header_ref, unit->content_ref);
914 498 priv->sequence_header = &obu->obu.sequence_header;
915 }
916 498 break;
917 1011 case AV1_OBU_TEMPORAL_DELIMITER:
918 {
919 1011 err = cbs_av1_read_temporal_delimiter_obu(ctx, &gbc);
920
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1011 times.
1011 if (err < 0)
921 return err;
922 }
923 1011 break;
924 290 case AV1_OBU_FRAME_HEADER:
925 case AV1_OBU_REDUNDANT_FRAME_HEADER:
926 {
927 290 err = cbs_av1_read_frame_header_obu(ctx, &gbc,
928 &obu->obu.frame_header,
929 290 obu->header.obu_type ==
930 AV1_OBU_REDUNDANT_FRAME_HEADER,
931 unit->data_ref);
932
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 290 times.
290 if (err < 0)
933 return err;
934 }
935 290 break;
936 1188 case AV1_OBU_FRAME:
937 1188 err = cbs_av1_read_frame_obu(ctx, &gbc, &obu->obu.frame,
938 unit->data_ref);
939
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1188 times.
1188 if (err < 0)
940 return err;
941 av_fallthrough;
942 case AV1_OBU_TILE_GROUP:
943 {
944 2818 AV1RawTileGroup *tile_group = obu->header.obu_type == AV1_OBU_FRAME ? &obu->obu.frame.tile_group
945
2/2
✓ Branch 0 taken 1188 times.
✓ Branch 1 taken 221 times.
1409 : &obu->obu.tile_group;
946
947
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1409 times.
1409 if (!priv->seen_frame_header)
948 return AVERROR_INVALIDDATA;
949
950 1409 err = cbs_av1_ref_tile_data(ctx, unit, &gbc,
951 &tile_group->data_ref,
952 &tile_group->data,
953 &tile_group->data_size);
954
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1409 times.
1409 if (err < 0)
955 return err;
956
957 1409 err = cbs_av1_read_tile_group_obu(ctx, &gbc, tile_group);
958
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1409 times.
1409 if (err < 0)
959 return err;
960
961 1409 err = cbs_av1_ref_tile_data(ctx, unit, &gbc,
962 &tile_group->tile_data.data_ref,
963 &tile_group->tile_data.data,
964 &tile_group->tile_data.data_size);
965
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1409 times.
1409 if (err < 0)
966 return err;
967 }
968 1409 break;
969 #if CBS_AV1_OBU_TILE_LIST
970 case AV1_OBU_TILE_LIST:
971 {
972 err = cbs_av1_read_tile_list_obu(ctx, &gbc,
973 &obu->obu.tile_list);
974 if (err < 0)
975 return err;
976
977 err = cbs_av1_ref_tile_data(ctx, unit, &gbc,
978 &obu->obu.tile_list.tile_data.data_ref,
979 &obu->obu.tile_list.tile_data.data,
980 &obu->obu.tile_list.tile_data.data_size);
981 if (err < 0)
982 return err;
983 }
984 break;
985 #endif
986 #if CBS_AV1_OBU_METADATA
987 16 case AV1_OBU_METADATA:
988 {
989 16 err = cbs_av1_read_metadata_obu(ctx, &gbc, &obu->obu.metadata);
990
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (err < 0)
991 return err;
992 }
993 16 break;
994 #endif
995 #if CBS_AV1_OBU_PADDING
996 case AV1_OBU_PADDING:
997 {
998 err = cbs_av1_read_padding_obu(ctx, &gbc, &obu->obu.padding);
999 if (err < 0)
1000 return err;
1001 }
1002 break;
1003 #endif
1004 default:
1005 return AVERROR(ENOSYS);
1006 }
1007
1008 3224 end_pos = get_bits_count(&gbc);
1009
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3224 times.
3224 av_assert0(end_pos <= unit->data_size * 8);
1010
1011
2/2
✓ Branch 0 taken 2213 times.
✓ Branch 1 taken 1011 times.
3224 if (obu->obu_size > 0 &&
1012
2/2
✓ Branch 0 taken 1992 times.
✓ Branch 1 taken 221 times.
2213 obu->header.obu_type != AV1_OBU_TILE_GROUP &&
1013
1/2
✓ Branch 0 taken 1992 times.
✗ Branch 1 not taken.
1992 obu->header.obu_type != AV1_OBU_TILE_LIST &&
1014
2/2
✓ Branch 0 taken 804 times.
✓ Branch 1 taken 1188 times.
1992 obu->header.obu_type != AV1_OBU_FRAME) {
1015 804 int nb_bits = obu->obu_size * 8 + start_pos - end_pos;
1016
1017
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 804 times.
804 if (nb_bits <= 0)
1018 return AVERROR_INVALIDDATA;
1019
1020 804 err = cbs_av1_read_trailing_bits(ctx, &gbc, nb_bits);
1021
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 804 times.
804 if (err < 0)
1022 return err;
1023 }
1024
1025 3224 return 0;
1026 #else
1027 return AVERROR(ENOSYS);
1028 #endif
1029 }
1030
1031 1017 static int cbs_av1_write_obu(CodedBitstreamContext *ctx,
1032 CodedBitstreamUnit *unit,
1033 PutBitContext *pbc)
1034 {
1035 #if CBS_WRITE
1036 1017 CodedBitstreamAV1Context *priv = ctx->priv_data;
1037 1017 AV1RawOBU *obu = unit->content;
1038 PutBitContext pbc_tmp;
1039 AV1RawTileData *td;
1040 size_t header_size;
1041 int err, start_pos, end_pos, data_pos;
1042 CodedBitstreamAV1Context av1ctx;
1043
1044 // OBUs in the normal bitstream format must contain a size field
1045 // in every OBU (in annex B it is optional, but we don't support
1046 // writing that).
1047 1017 obu->header.obu_has_size_field = 1;
1048 1017 av1ctx = *priv;
1049
1050
2/2
✓ Branch 0 taken 999 times.
✓ Branch 1 taken 18 times.
1017 if (priv->sequence_header_ref) {
1051 999 av1ctx.sequence_header_ref = av_refstruct_ref(priv->sequence_header_ref);
1052 }
1053
1054
2/2
✓ Branch 0 taken 942 times.
✓ Branch 1 taken 75 times.
1017 if (priv->frame_header_ref) {
1055 942 av1ctx.frame_header_ref = av_buffer_ref(priv->frame_header_ref);
1056
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 942 times.
942 if (!av1ctx.frame_header_ref) {
1057 err = AVERROR(ENOMEM);
1058 goto error;
1059 }
1060 }
1061
1062 1017 err = cbs_av1_write_obu_header(ctx, pbc, &obu->header);
1063
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1017 times.
1017 if (err < 0)
1064 goto error;
1065
1066
1/2
✓ Branch 0 taken 1017 times.
✗ Branch 1 not taken.
1017 if (obu->header.obu_has_size_field) {
1067 1017 pbc_tmp = *pbc;
1068
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1017 times.
1017 if (priv->fixed_obu_size_length) {
1069 for (int i = 0; i < priv->fixed_obu_size_length; i++)
1070 put_bits(pbc, 8, 0);
1071 } else {
1072 // Add space for the size field to fill later.
1073 1017 put_bits32(pbc, 0);
1074 1017 put_bits32(pbc, 0);
1075 }
1076 }
1077
1078 1017 td = NULL;
1079 1017 start_pos = put_bits_count(pbc);
1080
1081
6/9
✓ Branch 0 taken 143 times.
✓ Branch 1 taken 337 times.
✓ Branch 2 taken 87 times.
✓ Branch 3 taken 334 times.
✓ Branch 4 taken 104 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
1017 switch (obu->header.obu_type) {
1082 143 case AV1_OBU_SEQUENCE_HEADER:
1083 {
1084 143 err = cbs_av1_write_sequence_header_obu(ctx, pbc,
1085 &obu->obu.sequence_header);
1086
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (err < 0)
1087 goto error;
1088
1089 143 av_refstruct_unref(&priv->sequence_header_ref);
1090 143 priv->sequence_header = NULL;
1091
1092 143 err = CBS_FUNC(make_unit_refcounted)(ctx, unit);
1093
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (err < 0)
1094 goto error;
1095
1096 143 priv->sequence_header_ref = av_refstruct_ref(unit->content_ref);
1097 143 priv->sequence_header = &obu->obu.sequence_header;
1098 }
1099 143 break;
1100 337 case AV1_OBU_TEMPORAL_DELIMITER:
1101 {
1102 337 err = cbs_av1_write_temporal_delimiter_obu(ctx, pbc);
1103
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 337 times.
337 if (err < 0)
1104 goto error;
1105 }
1106 337 break;
1107 87 case AV1_OBU_FRAME_HEADER:
1108 case AV1_OBU_REDUNDANT_FRAME_HEADER:
1109 {
1110 87 err = cbs_av1_write_frame_header_obu(ctx, pbc,
1111 &obu->obu.frame_header,
1112 87 obu->header.obu_type ==
1113 AV1_OBU_REDUNDANT_FRAME_HEADER,
1114 NULL);
1115
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 87 times.
87 if (err < 0)
1116 goto error;
1117 }
1118 87 break;
1119 334 case AV1_OBU_FRAME:
1120 334 err = cbs_av1_write_frame_obu(ctx, pbc, &obu->obu.frame, NULL);
1121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 334 times.
334 if (err < 0)
1122 goto error;
1123 av_fallthrough;
1124 case AV1_OBU_TILE_GROUP:
1125 {
1126 876 AV1RawTileGroup *tile_group = obu->header.obu_type == AV1_OBU_FRAME ? &obu->obu.frame.tile_group
1127
2/2
✓ Branch 0 taken 334 times.
✓ Branch 1 taken 104 times.
438 : &obu->obu.tile_group;
1128 438 err = cbs_av1_write_tile_group_obu(ctx, pbc, tile_group);
1129
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 438 times.
438 if (err < 0)
1130 goto error;
1131
1132 438 td = &tile_group->tile_data;
1133 }
1134 438 break;
1135 #if CBS_AV1_OBU_TILE_LIST
1136 case AV1_OBU_TILE_LIST:
1137 {
1138 err = cbs_av1_write_tile_list_obu(ctx, pbc, &obu->obu.tile_list);
1139 if (err < 0)
1140 goto error;
1141
1142 td = &obu->obu.tile_list.tile_data;
1143 }
1144 break;
1145 #endif
1146 #if CBS_AV1_OBU_METADATA
1147 12 case AV1_OBU_METADATA:
1148 {
1149 12 err = cbs_av1_write_metadata_obu(ctx, pbc, &obu->obu.metadata);
1150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (err < 0)
1151 goto error;
1152 }
1153 12 break;
1154 #endif
1155 #if CBS_AV1_OBU_PADDING
1156 case AV1_OBU_PADDING:
1157 {
1158 err = cbs_av1_write_padding_obu(ctx, pbc, &obu->obu.padding);
1159 if (err < 0)
1160 goto error;
1161 }
1162 break;
1163 #endif
1164 default:
1165 err = AVERROR(ENOSYS);
1166 goto error;
1167 }
1168
1169 1017 end_pos = put_bits_count(pbc);
1170 1017 header_size = (end_pos - start_pos + 7) / 8;
1171
2/2
✓ Branch 0 taken 438 times.
✓ Branch 1 taken 579 times.
1017 if (td) {
1172 438 obu->obu_size = header_size + td->data_size;
1173
2/2
✓ Branch 0 taken 242 times.
✓ Branch 1 taken 337 times.
579 } else if (header_size > 0) {
1174 // Add trailing bits and recalculate.
1175 242 err = cbs_av1_write_trailing_bits(ctx, pbc, 8 - end_pos % 8);
1176
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 242 times.
242 if (err < 0)
1177 goto error;
1178 242 end_pos = put_bits_count(pbc);
1179 242 obu->obu_size = header_size = (end_pos - start_pos + 7) / 8;
1180 } else {
1181 // Empty OBU.
1182 337 obu->obu_size = 0;
1183 }
1184
1185 1017 end_pos = put_bits_count(pbc);
1186 // Must now be byte-aligned.
1187
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1017 times.
1017 av_assert0(end_pos % 8 == 0);
1188 1017 flush_put_bits(pbc);
1189 1017 start_pos /= 8;
1190 1017 end_pos /= 8;
1191
1192 1017 *pbc = pbc_tmp;
1193 1017 err = cbs_av1_write_leb128(ctx, pbc, "obu_size", obu->obu_size,
1194 priv->fixed_obu_size_length);
1195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1017 times.
1017 if (err < 0)
1196 goto error;
1197
1198 1017 data_pos = put_bits_count(pbc) / 8;
1199 1017 flush_put_bits(pbc);
1200
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1017 times.
1017 av_assert0(data_pos <= start_pos);
1201
1202
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1017 times.
1017 if (8 * obu->obu_size > put_bits_left(pbc)) {
1203 av_refstruct_unref(&priv->sequence_header_ref);
1204 av_buffer_unref(&priv->frame_header_ref);
1205 *priv = av1ctx;
1206
1207 return AVERROR(ENOSPC);
1208 }
1209
1210
2/2
✓ Branch 0 taken 680 times.
✓ Branch 1 taken 337 times.
1017 if (obu->obu_size > 0) {
1211
1/2
✓ Branch 0 taken 680 times.
✗ Branch 1 not taken.
680 if (!priv->fixed_obu_size_length) {
1212 680 memmove(pbc->buf + data_pos,
1213 680 pbc->buf + start_pos, header_size);
1214 } else {
1215 // The size was fixed so the following data was
1216 // already written in the correct place.
1217 }
1218 680 skip_put_bytes(pbc, header_size);
1219
1220
2/2
✓ Branch 0 taken 438 times.
✓ Branch 1 taken 242 times.
680 if (td) {
1221 438 memcpy(pbc->buf + data_pos + header_size,
1222 438 td->data, td->data_size);
1223 438 skip_put_bytes(pbc, td->data_size);
1224 }
1225 }
1226
1227 // OBU data must be byte-aligned.
1228
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1017 times.
1017 av_assert0(put_bits_count(pbc) % 8 == 0);
1229 1017 err = 0;
1230
1231 1017 error:
1232 1017 av_refstruct_unref(&av1ctx.sequence_header_ref);
1233 1017 av_buffer_unref(&av1ctx.frame_header_ref);
1234
1235 1017 return err;
1236 #else
1237 return AVERROR(ENOSYS);
1238 #endif
1239 }
1240
1241 353 static int cbs_av1_assemble_fragment(CodedBitstreamContext *ctx,
1242 CodedBitstreamFragment *frag)
1243 {
1244 #if CBS_WRITE
1245 size_t size, pos;
1246 int i;
1247
1248 353 size = 0;
1249
2/2
✓ Branch 0 taken 1017 times.
✓ Branch 1 taken 353 times.
1370 for (i = 0; i < frag->nb_units; i++)
1250 1017 size += frag->units[i].data_size;
1251
1252 353 frag->data_ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
1253
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 353 times.
353 if (!frag->data_ref)
1254 return AVERROR(ENOMEM);
1255 353 frag->data = frag->data_ref->data;
1256 353 memset(frag->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1257
1258 353 pos = 0;
1259
2/2
✓ Branch 0 taken 1017 times.
✓ Branch 1 taken 353 times.
1370 for (i = 0; i < frag->nb_units; i++) {
1260 1017 memcpy(frag->data + pos, frag->units[i].data,
1261 1017 frag->units[i].data_size);
1262 1017 pos += frag->units[i].data_size;
1263 }
1264
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 353 times.
353 av_assert0(pos == size);
1265 353 frag->data_size = size;
1266
1267 353 return 0;
1268 #else
1269 return AVERROR(ENOSYS);
1270 #endif
1271 }
1272
1273 static av_cold void cbs_av1_flush(CodedBitstreamContext *ctx)
1274 {
1275 CodedBitstreamAV1Context *priv = ctx->priv_data;
1276
1277 av_buffer_unref(&priv->frame_header_ref);
1278 priv->sequence_header = NULL;
1279 priv->frame_header = NULL;
1280
1281 memset(priv->ref, 0, sizeof(priv->ref));
1282 priv->operating_point_idc = 0;
1283 priv->seen_frame_header = 0;
1284 priv->tile_num = 0;
1285 }
1286
1287 110 static av_cold void cbs_av1_close(CodedBitstreamContext *ctx)
1288 {
1289 110 CodedBitstreamAV1Context *priv = ctx->priv_data;
1290
1291 110 av_refstruct_unref(&priv->sequence_header_ref);
1292 110 av_buffer_unref(&priv->frame_header_ref);
1293 110 }
1294
1295 #if CBS_AV1_OBU_METADATA
1296 16 static void cbs_av1_free_metadata(AVRefStructOpaque unused, void *content)
1297 {
1298 16 AV1RawOBU *obu = content;
1299 AV1RawMetadata *md;
1300
1301
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 av_assert0(obu->header.obu_type == AV1_OBU_METADATA);
1302 16 md = &obu->obu.metadata;
1303
1304
1/3
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
16 switch (md->metadata_type) {
1305 16 case AV1_METADATA_TYPE_HDR_CLL:
1306 case AV1_METADATA_TYPE_HDR_MDCV:
1307 case AV1_METADATA_TYPE_SCALABILITY:
1308 case AV1_METADATA_TYPE_TIMECODE:
1309 16 break;
1310 case AV1_METADATA_TYPE_ITUT_T35:
1311 av_buffer_unref(&md->metadata.itut_t35.payload_ref);
1312 break;
1313 default:
1314 av_buffer_unref(&md->metadata.unknown.payload_ref);
1315 }
1316 16 }
1317 #endif
1318
1319 static CodedBitstreamUnitTypeDescriptor cbs_av1_unit_types[] = {
1320 CBS_UNIT_TYPE_POD(AV1_OBU_SEQUENCE_HEADER, AV1RawOBU),
1321 CBS_UNIT_TYPE_POD(AV1_OBU_TEMPORAL_DELIMITER, AV1RawOBU),
1322 CBS_UNIT_TYPE_POD(AV1_OBU_FRAME_HEADER, AV1RawOBU),
1323 CBS_UNIT_TYPE_POD(AV1_OBU_REDUNDANT_FRAME_HEADER, AV1RawOBU),
1324 {
1325 .nb_unit_types = 1,
1326 .unit_type.list[0] = AV1_OBU_TILE_GROUP,
1327 .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS,
1328 .content_size = sizeof(AV1RawOBU),
1329 .type.ref = {
1330 .nb_offsets = 2,
1331 .offsets = { offsetof(AV1RawOBU, obu.tile_group.data),
1332 offsetof(AV1RawOBU, obu.tile_group.tile_data.data) }
1333 },
1334 },
1335
1336 {
1337 .nb_unit_types = 1,
1338 .unit_type.list[0] = AV1_OBU_FRAME,
1339 .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS,
1340 .content_size = sizeof(AV1RawOBU),
1341 .type.ref = {
1342 .nb_offsets = 2,
1343 .offsets = { offsetof(AV1RawOBU, obu.frame.tile_group.data),
1344 offsetof(AV1RawOBU, obu.frame.tile_group.tile_data.data) }
1345 },
1346 },
1347 #if CBS_AV1_OBU_TILE_LIST
1348 CBS_UNIT_TYPE_INTERNAL_REF(AV1_OBU_TILE_LIST, AV1RawOBU,
1349 obu.tile_list.tile_data.data),
1350 #endif
1351 #if CBS_AV1_OBU_PADDING
1352 CBS_UNIT_TYPE_INTERNAL_REF(AV1_OBU_PADDING, AV1RawOBU,
1353 obu.padding.payload),
1354 #endif
1355
1356 #if CBS_AV1_OBU_METADATA
1357 CBS_UNIT_TYPE_COMPLEX(AV1_OBU_METADATA, AV1RawOBU,
1358 &cbs_av1_free_metadata),
1359 #endif
1360
1361 CBS_UNIT_TYPE_END_OF_LIST
1362 };
1363
1364 #define OFFSET(x) offsetof(CodedBitstreamAV1Context, x)
1365 static const AVOption cbs_av1_options[] = {
1366 { "operating_point", "Set operating point to select layers to parse from a scalable bitstream",
1367 OFFSET(operating_point), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, AV1_MAX_OPERATING_POINTS - 1, 0 },
1368 { "fixed_obu_size_length", "Set fixed length of the obu_size field",
1369 OFFSET(fixed_obu_size_length), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8, 0 },
1370 { NULL }
1371 };
1372
1373 static const AVClass cbs_av1_class = {
1374 .class_name = "cbs_av1",
1375 .item_name = av_default_item_name,
1376 .option = cbs_av1_options,
1377 .version = LIBAVUTIL_VERSION_INT,
1378 };
1379
1380 const CodedBitstreamType CBS_FUNC(type_av1) = {
1381 .codec_id = AV_CODEC_ID_AV1,
1382
1383 .priv_class = &cbs_av1_class,
1384 .priv_data_size = sizeof(CodedBitstreamAV1Context),
1385
1386 .unit_types = cbs_av1_unit_types,
1387
1388 .split_fragment = &cbs_av1_split_fragment,
1389 .read_unit = &cbs_av1_read_unit,
1390 .write_unit = &cbs_av1_write_obu,
1391 .assemble_fragment = &cbs_av1_assemble_fragment,
1392
1393 .flush = &cbs_av1_flush,
1394 .close = &cbs_av1_close,
1395 };
1396