FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/cbs_av1.c
Date: 2025-10-10 03:51:19
Exec Total Coverage
Lines: 361 547 66.0%
Functions: 17 21 81.0%
Branches: 190 363 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 5842 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 5842 times.
5842 CBS_TRACE_READ_START();
133
134 5842 value = 0;
135
1/2
✓ Branch 0 taken 8044 times.
✗ Branch 1 not taken.
8044 for (i = 0; i < 8; i++) {
136
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8044 times.
8044 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 8044 byte = get_bits(gbc, 8);
142 8044 value |= (uint64_t)(byte & 0x7f) << (i * 7);
143
2/2
✓ Branch 0 taken 5842 times.
✓ Branch 1 taken 2202 times.
8044 if (!(byte & 0x80))
144 5842 break;
145 }
146
147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5842 times.
5842 if (value > UINT32_MAX)
148 return AVERROR_INVALIDDATA;
149
150
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5842 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
5842 CBS_TRACE_READ_END_NO_SUBSCRIPTS();
151
152 5842 *write_to = value;
153 5842 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 265 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 265 times.
265 CBS_TRACE_READ_START();
204
205
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 265 times.
265 av_assert0(n > 0);
206
207 265 w = av_log2(n) + 1;
208 265 m = (1 << w) - n;
209
210
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 265 times.
265 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 265 times.
✗ Branch 1 not taken.
265 if (w - 1 > 0)
217 265 v = get_bits(gbc, w - 1);
218 else
219 v = 0;
220
221
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 53 times.
265 if (v < m) {
222 212 value = v;
223 } else {
224 53 extra_bit = get_bits1(gbc);
225 53 value = (v << 1) - m + extra_bit;
226 }
227
228
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 265 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
265 CBS_TRACE_READ_END();
229
230 265 *write_to = value;
231 265 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 3826 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 3826 times.
3826 CBS_TRACE_READ_START();
281
282
2/4
✓ Branch 0 taken 3826 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3826 times.
3826 av_assert0(range_min <= range_max && range_max - range_min < 32);
283
284
2/2
✓ Branch 0 taken 5263 times.
✓ Branch 1 taken 474 times.
5737 for (value = range_min; value < range_max;) {
285
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5263 times.
5263 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 1911 times.
✓ Branch 2 taken 3352 times.
5263 if (get_bits1(gbc))
291 1911 ++value;
292 else
293 3352 break;
294 }
295
296
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3826 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3826 CBS_TRACE_READ_END_NO_SUBSCRIPTS();
297
298 3826 *write_to = value;
299 3826 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 8128 static int cbs_av1_tile_log2(int blksize, int target)
447 {
448 int k;
449
2/2
✓ Branch 0 taken 8784 times.
✓ Branch 1 taken 8128 times.
16912 for (k = 0; (blksize << k) < target; k++);
450 8128 return k;
451 }
452
453 22964 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 22964 times.
22964 if (!seq->enable_order_hint)
458 return 0;
459 22964 diff = a - b;
460 22964 m = 1 << seq->order_hint_bits_minus_1;
461 22964 diff = (diff & (m - 1)) - (diff & m);
462 22964 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 1088 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 1088 trace = ctx->trace_enable;
710 1088 ctx->trace_enable = 0;
711
712 1088 data = frag->data;
713 1088 size = frag->data_size;
714
715
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1088 times.
1088 if (INT_MAX / 8 < size) {
716 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid fragment: "
717 "too large (%"SIZE_SPECIFIER" bytes).\n", size);
718 err = AVERROR_INVALIDDATA;
719 goto fail;
720 }
721
722
5/6
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 1036 times.
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 36 times.
1088 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 16 int config_record_version = data[0] & 0x7f;
726
727
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 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 2 times.
✓ Branch 1 taken 14 times.
16 if (size <= 4) {
737
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 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 2 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 14 data += 4;
752 14 size -= 4;
753 }
754
755
2/2
✓ Branch 0 taken 2941 times.
✓ Branch 1 taken 1086 times.
4027 while (size > 0) {
756 AV1RawOBUHeader obu_header;
757 uint64_t obu_size;
758
759 2941 init_get_bits(&gbc, data, 8 * size);
760
761 2941 err = cbs_av1_read_obu_header(ctx, &gbc, &obu_header);
762
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2941 times.
2941 if (err < 0)
763 goto fail;
764
765
2/2
✓ Branch 0 taken 2919 times.
✓ Branch 1 taken 22 times.
2941 if (obu_header.obu_has_size_field) {
766
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2919 times.
2919 if (get_bits_left(&gbc) < 8) {
767 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid OBU: fragment "
768 "too short (%"SIZE_SPECIFIER" bytes).\n", size);
769 err = AVERROR_INVALIDDATA;
770 goto fail;
771 }
772 2919 err = cbs_av1_read_leb128(ctx, &gbc, "obu_size", &obu_size);
773
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2919 times.
2919 if (err < 0)
774 goto fail;
775 } else
776 22 obu_size = size - 1 - obu_header.obu_extension_flag;
777
778 2941 pos = get_bits_count(&gbc);
779
2/4
✓ Branch 0 taken 2941 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2941 times.
2941 av_assert0(pos % 8 == 0 && pos / 8 <= size);
780
781 2941 obu_length = pos / 8 + obu_size;
782
783
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2941 times.
2941 if (size < obu_length) {
784 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid OBU length: "
785 "%"PRIu64", but only %"SIZE_SPECIFIER" bytes remaining in fragment.\n",
786 obu_length, size);
787 err = AVERROR_INVALIDDATA;
788 goto fail;
789 }
790
791 2941 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 2941 times.
2941 if (err < 0)
794 goto fail;
795
796 2941 data += obu_length;
797 2941 size -= obu_length;
798 }
799
800 1086 success:
801 1088 err = 0;
802 1088 fail:
803 1088 ctx->trace_enable = trace;
804 1088 return err;
805 #else
806 return AVERROR(ENOSYS);
807 #endif
808 }
809
810 #if CBS_READ
811 2452 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 2452 pos = get_bits_count(gbc);
820
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2452 times.
2452 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 2452 times.
2452 av_assert0(pos % 8 == 0);
827
828 2452 *data_ref = av_buffer_ref(unit->data_ref);
829
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2452 times.
2452 if (!*data_ref)
830 return AVERROR(ENOMEM);
831
832 2452 *data = unit->data + pos / 8;
833 2452 *data_size = unit->data_size - pos / 8;
834
835 2452 return 0;
836 }
837 #endif
838
839 2929 static int cbs_av1_read_unit(CodedBitstreamContext *ctx,
840 CodedBitstreamUnit *unit)
841 {
842 #if CBS_READ
843 2929 CodedBitstreamAV1Context *priv = ctx->priv_data;
844 AV1RawOBU *obu;
845 GetBitContext gbc;
846 int err, start_pos, end_pos;
847
848 2929 err = CBS_FUNC(alloc_unit_content)(ctx, unit);
849
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2929 times.
2929 if (err < 0)
850 return err;
851 2929 obu = unit->content;
852
853 2929 err = init_get_bits(&gbc, unit->data, 8 * unit->data_size);
854
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2929 times.
2929 if (err < 0)
855 return err;
856
857 2929 err = cbs_av1_read_obu_header(ctx, &gbc, &obu->header);
858
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2929 times.
2929 if (err < 0)
859 return err;
860
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2929 times.
2929 av_assert0(obu->header.obu_type == unit->type);
861
862
2/2
✓ Branch 0 taken 2907 times.
✓ Branch 1 taken 22 times.
2929 if (obu->header.obu_has_size_field) {
863 uint64_t obu_size;
864 2907 err = cbs_av1_read_leb128(ctx, &gbc, "obu_size", &obu_size);
865
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2907 times.
2907 if (err < 0)
866 return err;
867 2907 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 (%"SIZE_SPECIFIER").\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 2929 start_pos = get_bits_count(&gbc);
878
879
2/2
✓ Branch 0 taken 166 times.
✓ Branch 1 taken 2763 times.
2929 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 477 times.
✓ Branch 1 taken 962 times.
✓ Branch 2 taken 248 times.
✓ Branch 3 taken 1005 times.
✓ Branch 4 taken 221 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 16 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
2929 switch (obu->header.obu_type) {
894 477 case AV1_OBU_SEQUENCE_HEADER:
895 {
896 477 err = cbs_av1_read_sequence_header_obu(ctx, &gbc,
897 &obu->obu.sequence_header);
898
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 477 times.
477 if (err < 0)
899 return err;
900
901
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 448 times.
477 if (priv->operating_point >= 0) {
902 29 AV1RawSequenceHeader *sequence_header = &obu->obu.sequence_header;
903
904
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
29 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 29 priv->operating_point_idc = sequence_header->operating_point_idc[priv->operating_point];
911 }
912
913 477 av_refstruct_replace(&priv->sequence_header_ref, unit->content_ref);
914 477 priv->sequence_header = &obu->obu.sequence_header;
915 }
916 477 break;
917 962 case AV1_OBU_TEMPORAL_DELIMITER:
918 {
919 962 err = cbs_av1_read_temporal_delimiter_obu(ctx, &gbc);
920
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 962 times.
962 if (err < 0)
921 return err;
922 }
923 962 break;
924 248 case AV1_OBU_FRAME_HEADER:
925 case AV1_OBU_REDUNDANT_FRAME_HEADER:
926 {
927 248 err = cbs_av1_read_frame_header_obu(ctx, &gbc,
928 &obu->obu.frame_header,
929 248 obu->header.obu_type ==
930 AV1_OBU_REDUNDANT_FRAME_HEADER,
931 unit->data_ref);
932
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 248 times.
248 if (err < 0)
933 return err;
934 }
935 248 break;
936 1005 case AV1_OBU_FRAME:
937 1005 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 1005 times.
1005 if (err < 0)
940 return err;
941 // fall-through
942 case AV1_OBU_TILE_GROUP:
943 {
944 2452 AV1RawTileGroup *tile_group = obu->header.obu_type == AV1_OBU_FRAME ? &obu->obu.frame.tile_group
945
2/2
✓ Branch 0 taken 1005 times.
✓ Branch 1 taken 221 times.
1226 : &obu->obu.tile_group;
946 1226 err = cbs_av1_ref_tile_data(ctx, unit, &gbc,
947 &tile_group->data_ref,
948 &tile_group->data,
949 &tile_group->data_size);
950
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1226 times.
1226 if (err < 0)
951 return err;
952
953 1226 err = cbs_av1_read_tile_group_obu(ctx, &gbc, tile_group);
954
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1226 times.
1226 if (err < 0)
955 return err;
956
957 1226 err = cbs_av1_ref_tile_data(ctx, unit, &gbc,
958 &tile_group->tile_data.data_ref,
959 &tile_group->tile_data.data,
960 &tile_group->tile_data.data_size);
961
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1226 times.
1226 if (err < 0)
962 return err;
963 }
964 1226 break;
965 #if CBS_AV1_OBU_TILE_LIST
966 case AV1_OBU_TILE_LIST:
967 {
968 err = cbs_av1_read_tile_list_obu(ctx, &gbc,
969 &obu->obu.tile_list);
970 if (err < 0)
971 return err;
972
973 err = cbs_av1_ref_tile_data(ctx, unit, &gbc,
974 &obu->obu.tile_list.tile_data.data_ref,
975 &obu->obu.tile_list.tile_data.data,
976 &obu->obu.tile_list.tile_data.data_size);
977 if (err < 0)
978 return err;
979 }
980 break;
981 #endif
982 #if CBS_AV1_OBU_METADATA
983 16 case AV1_OBU_METADATA:
984 {
985 16 err = cbs_av1_read_metadata_obu(ctx, &gbc, &obu->obu.metadata);
986
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (err < 0)
987 return err;
988 }
989 16 break;
990 #endif
991 #if CBS_AV1_OBU_PADDING
992 case AV1_OBU_PADDING:
993 {
994 err = cbs_av1_read_padding_obu(ctx, &gbc, &obu->obu.padding);
995 if (err < 0)
996 return err;
997 }
998 break;
999 #endif
1000 default:
1001 return AVERROR(ENOSYS);
1002 }
1003
1004 2929 end_pos = get_bits_count(&gbc);
1005
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2929 times.
2929 av_assert0(end_pos <= unit->data_size * 8);
1006
1007
2/2
✓ Branch 0 taken 1967 times.
✓ Branch 1 taken 962 times.
2929 if (obu->obu_size > 0 &&
1008
2/2
✓ Branch 0 taken 1746 times.
✓ Branch 1 taken 221 times.
1967 obu->header.obu_type != AV1_OBU_TILE_GROUP &&
1009
1/2
✓ Branch 0 taken 1746 times.
✗ Branch 1 not taken.
1746 obu->header.obu_type != AV1_OBU_TILE_LIST &&
1010
2/2
✓ Branch 0 taken 741 times.
✓ Branch 1 taken 1005 times.
1746 obu->header.obu_type != AV1_OBU_FRAME) {
1011 741 int nb_bits = obu->obu_size * 8 + start_pos - end_pos;
1012
1013
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 741 times.
741 if (nb_bits <= 0)
1014 return AVERROR_INVALIDDATA;
1015
1016 741 err = cbs_av1_read_trailing_bits(ctx, &gbc, nb_bits);
1017
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 741 times.
741 if (err < 0)
1018 return err;
1019 }
1020
1021 2929 return 0;
1022 #else
1023 return AVERROR(ENOSYS);
1024 #endif
1025 }
1026
1027 1017 static int cbs_av1_write_obu(CodedBitstreamContext *ctx,
1028 CodedBitstreamUnit *unit,
1029 PutBitContext *pbc)
1030 {
1031 #if CBS_WRITE
1032 1017 CodedBitstreamAV1Context *priv = ctx->priv_data;
1033 1017 AV1RawOBU *obu = unit->content;
1034 PutBitContext pbc_tmp;
1035 AV1RawTileData *td;
1036 size_t header_size;
1037 int err, start_pos, end_pos, data_pos;
1038 CodedBitstreamAV1Context av1ctx;
1039
1040 // OBUs in the normal bitstream format must contain a size field
1041 // in every OBU (in annex B it is optional, but we don't support
1042 // writing that).
1043 1017 obu->header.obu_has_size_field = 1;
1044 1017 av1ctx = *priv;
1045
1046
2/2
✓ Branch 0 taken 999 times.
✓ Branch 1 taken 18 times.
1017 if (priv->sequence_header_ref) {
1047 999 av1ctx.sequence_header_ref = av_refstruct_ref(priv->sequence_header_ref);
1048 }
1049
1050
2/2
✓ Branch 0 taken 942 times.
✓ Branch 1 taken 75 times.
1017 if (priv->frame_header_ref) {
1051 942 av1ctx.frame_header_ref = av_buffer_ref(priv->frame_header_ref);
1052
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 942 times.
942 if (!av1ctx.frame_header_ref) {
1053 err = AVERROR(ENOMEM);
1054 goto error;
1055 }
1056 }
1057
1058 1017 err = cbs_av1_write_obu_header(ctx, pbc, &obu->header);
1059
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1017 times.
1017 if (err < 0)
1060 goto error;
1061
1062
1/2
✓ Branch 0 taken 1017 times.
✗ Branch 1 not taken.
1017 if (obu->header.obu_has_size_field) {
1063 1017 pbc_tmp = *pbc;
1064
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1017 times.
1017 if (priv->fixed_obu_size_length) {
1065 for (int i = 0; i < priv->fixed_obu_size_length; i++)
1066 put_bits(pbc, 8, 0);
1067 } else {
1068 // Add space for the size field to fill later.
1069 1017 put_bits32(pbc, 0);
1070 1017 put_bits32(pbc, 0);
1071 }
1072 }
1073
1074 1017 td = NULL;
1075 1017 start_pos = put_bits_count(pbc);
1076
1077
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) {
1078 143 case AV1_OBU_SEQUENCE_HEADER:
1079 {
1080 143 err = cbs_av1_write_sequence_header_obu(ctx, pbc,
1081 &obu->obu.sequence_header);
1082
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (err < 0)
1083 goto error;
1084
1085 143 av_refstruct_unref(&priv->sequence_header_ref);
1086 143 priv->sequence_header = NULL;
1087
1088 143 err = CBS_FUNC(make_unit_refcounted)(ctx, unit);
1089
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
143 if (err < 0)
1090 goto error;
1091
1092 143 priv->sequence_header_ref = av_refstruct_ref(unit->content_ref);
1093 143 priv->sequence_header = &obu->obu.sequence_header;
1094 }
1095 143 break;
1096 337 case AV1_OBU_TEMPORAL_DELIMITER:
1097 {
1098 337 err = cbs_av1_write_temporal_delimiter_obu(ctx, pbc);
1099
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 337 times.
337 if (err < 0)
1100 goto error;
1101 }
1102 337 break;
1103 87 case AV1_OBU_FRAME_HEADER:
1104 case AV1_OBU_REDUNDANT_FRAME_HEADER:
1105 {
1106 87 err = cbs_av1_write_frame_header_obu(ctx, pbc,
1107 &obu->obu.frame_header,
1108 87 obu->header.obu_type ==
1109 AV1_OBU_REDUNDANT_FRAME_HEADER,
1110 NULL);
1111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 87 times.
87 if (err < 0)
1112 goto error;
1113 }
1114 87 break;
1115 334 case AV1_OBU_FRAME:
1116 334 err = cbs_av1_write_frame_obu(ctx, pbc, &obu->obu.frame, NULL);
1117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 334 times.
334 if (err < 0)
1118 goto error;
1119 // fall-through
1120 case AV1_OBU_TILE_GROUP:
1121 {
1122 876 AV1RawTileGroup *tile_group = obu->header.obu_type == AV1_OBU_FRAME ? &obu->obu.frame.tile_group
1123
2/2
✓ Branch 0 taken 334 times.
✓ Branch 1 taken 104 times.
438 : &obu->obu.tile_group;
1124 438 err = cbs_av1_write_tile_group_obu(ctx, pbc, tile_group);
1125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 438 times.
438 if (err < 0)
1126 goto error;
1127
1128 438 td = &tile_group->tile_data;
1129 }
1130 438 break;
1131 #if CBS_AV1_OBU_TILE_LIST
1132 case AV1_OBU_TILE_LIST:
1133 {
1134 err = cbs_av1_write_tile_list_obu(ctx, pbc, &obu->obu.tile_list);
1135 if (err < 0)
1136 goto error;
1137
1138 td = &obu->obu.tile_list.tile_data;
1139 }
1140 break;
1141 #endif
1142 #if CBS_AV1_OBU_METADATA
1143 12 case AV1_OBU_METADATA:
1144 {
1145 12 err = cbs_av1_write_metadata_obu(ctx, pbc, &obu->obu.metadata);
1146
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (err < 0)
1147 goto error;
1148 }
1149 12 break;
1150 #endif
1151 #if CBS_AV1_OBU_PADDING
1152 case AV1_OBU_PADDING:
1153 {
1154 err = cbs_av1_write_padding_obu(ctx, pbc, &obu->obu.padding);
1155 if (err < 0)
1156 goto error;
1157 }
1158 break;
1159 #endif
1160 default:
1161 err = AVERROR(ENOSYS);
1162 goto error;
1163 }
1164
1165 1017 end_pos = put_bits_count(pbc);
1166 1017 header_size = (end_pos - start_pos + 7) / 8;
1167
2/2
✓ Branch 0 taken 438 times.
✓ Branch 1 taken 579 times.
1017 if (td) {
1168 438 obu->obu_size = header_size + td->data_size;
1169
2/2
✓ Branch 0 taken 242 times.
✓ Branch 1 taken 337 times.
579 } else if (header_size > 0) {
1170 // Add trailing bits and recalculate.
1171 242 err = cbs_av1_write_trailing_bits(ctx, pbc, 8 - end_pos % 8);
1172
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 242 times.
242 if (err < 0)
1173 goto error;
1174 242 end_pos = put_bits_count(pbc);
1175 242 obu->obu_size = header_size = (end_pos - start_pos + 7) / 8;
1176 } else {
1177 // Empty OBU.
1178 337 obu->obu_size = 0;
1179 }
1180
1181 1017 end_pos = put_bits_count(pbc);
1182 // Must now be byte-aligned.
1183
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1017 times.
1017 av_assert0(end_pos % 8 == 0);
1184 1017 flush_put_bits(pbc);
1185 1017 start_pos /= 8;
1186 1017 end_pos /= 8;
1187
1188 1017 *pbc = pbc_tmp;
1189 1017 err = cbs_av1_write_leb128(ctx, pbc, "obu_size", obu->obu_size,
1190 priv->fixed_obu_size_length);
1191
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1017 times.
1017 if (err < 0)
1192 goto error;
1193
1194 1017 data_pos = put_bits_count(pbc) / 8;
1195 1017 flush_put_bits(pbc);
1196
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1017 times.
1017 av_assert0(data_pos <= start_pos);
1197
1198
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1017 times.
1017 if (8 * obu->obu_size > put_bits_left(pbc)) {
1199 av_refstruct_unref(&priv->sequence_header_ref);
1200 av_buffer_unref(&priv->frame_header_ref);
1201 *priv = av1ctx;
1202
1203 return AVERROR(ENOSPC);
1204 }
1205
1206
2/2
✓ Branch 0 taken 680 times.
✓ Branch 1 taken 337 times.
1017 if (obu->obu_size > 0) {
1207
1/2
✓ Branch 0 taken 680 times.
✗ Branch 1 not taken.
680 if (!priv->fixed_obu_size_length) {
1208 680 memmove(pbc->buf + data_pos,
1209 680 pbc->buf + start_pos, header_size);
1210 } else {
1211 // The size was fixed so the following data was
1212 // already written in the correct place.
1213 }
1214 680 skip_put_bytes(pbc, header_size);
1215
1216
2/2
✓ Branch 0 taken 438 times.
✓ Branch 1 taken 242 times.
680 if (td) {
1217 438 memcpy(pbc->buf + data_pos + header_size,
1218 438 td->data, td->data_size);
1219 438 skip_put_bytes(pbc, td->data_size);
1220 }
1221 }
1222
1223 // OBU data must be byte-aligned.
1224
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1017 times.
1017 av_assert0(put_bits_count(pbc) % 8 == 0);
1225 1017 err = 0;
1226
1227 1017 error:
1228 1017 av_refstruct_unref(&av1ctx.sequence_header_ref);
1229 1017 av_buffer_unref(&av1ctx.frame_header_ref);
1230
1231 1017 return err;
1232 #else
1233 return AVERROR(ENOSYS);
1234 #endif
1235 }
1236
1237 353 static int cbs_av1_assemble_fragment(CodedBitstreamContext *ctx,
1238 CodedBitstreamFragment *frag)
1239 {
1240 #if CBS_WRITE
1241 size_t size, pos;
1242 int i;
1243
1244 353 size = 0;
1245
2/2
✓ Branch 0 taken 1017 times.
✓ Branch 1 taken 353 times.
1370 for (i = 0; i < frag->nb_units; i++)
1246 1017 size += frag->units[i].data_size;
1247
1248 353 frag->data_ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
1249
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 353 times.
353 if (!frag->data_ref)
1250 return AVERROR(ENOMEM);
1251 353 frag->data = frag->data_ref->data;
1252 353 memset(frag->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1253
1254 353 pos = 0;
1255
2/2
✓ Branch 0 taken 1017 times.
✓ Branch 1 taken 353 times.
1370 for (i = 0; i < frag->nb_units; i++) {
1256 1017 memcpy(frag->data + pos, frag->units[i].data,
1257 1017 frag->units[i].data_size);
1258 1017 pos += frag->units[i].data_size;
1259 }
1260
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 353 times.
353 av_assert0(pos == size);
1261 353 frag->data_size = size;
1262
1263 353 return 0;
1264 #else
1265 return AVERROR(ENOSYS);
1266 #endif
1267 }
1268
1269 static av_cold void cbs_av1_flush(CodedBitstreamContext *ctx)
1270 {
1271 CodedBitstreamAV1Context *priv = ctx->priv_data;
1272
1273 av_buffer_unref(&priv->frame_header_ref);
1274 priv->sequence_header = NULL;
1275 priv->frame_header = NULL;
1276
1277 memset(priv->ref, 0, sizeof(priv->ref));
1278 priv->operating_point_idc = 0;
1279 priv->seen_frame_header = 0;
1280 priv->tile_num = 0;
1281 }
1282
1283 93 static av_cold void cbs_av1_close(CodedBitstreamContext *ctx)
1284 {
1285 93 CodedBitstreamAV1Context *priv = ctx->priv_data;
1286
1287 93 av_refstruct_unref(&priv->sequence_header_ref);
1288 93 av_buffer_unref(&priv->frame_header_ref);
1289 93 }
1290
1291 #if CBS_AV1_OBU_METADATA
1292 16 static void cbs_av1_free_metadata(AVRefStructOpaque unused, void *content)
1293 {
1294 16 AV1RawOBU *obu = content;
1295 AV1RawMetadata *md;
1296
1297
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 av_assert0(obu->header.obu_type == AV1_OBU_METADATA);
1298 16 md = &obu->obu.metadata;
1299
1300
1/3
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
16 switch (md->metadata_type) {
1301 16 case AV1_METADATA_TYPE_HDR_CLL:
1302 case AV1_METADATA_TYPE_HDR_MDCV:
1303 case AV1_METADATA_TYPE_SCALABILITY:
1304 case AV1_METADATA_TYPE_TIMECODE:
1305 16 break;
1306 case AV1_METADATA_TYPE_ITUT_T35:
1307 av_buffer_unref(&md->metadata.itut_t35.payload_ref);
1308 break;
1309 default:
1310 av_buffer_unref(&md->metadata.unknown.payload_ref);
1311 }
1312 16 }
1313 #endif
1314
1315 static const CodedBitstreamUnitTypeDescriptor cbs_av1_unit_types[] = {
1316 CBS_UNIT_TYPE_POD(AV1_OBU_SEQUENCE_HEADER, AV1RawOBU),
1317 CBS_UNIT_TYPE_POD(AV1_OBU_TEMPORAL_DELIMITER, AV1RawOBU),
1318 CBS_UNIT_TYPE_POD(AV1_OBU_FRAME_HEADER, AV1RawOBU),
1319 CBS_UNIT_TYPE_POD(AV1_OBU_REDUNDANT_FRAME_HEADER, AV1RawOBU),
1320 {
1321 .nb_unit_types = 1,
1322 .unit_type.list[0] = AV1_OBU_TILE_GROUP,
1323 .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS,
1324 .content_size = sizeof(AV1RawOBU),
1325 .type.ref = {
1326 .nb_offsets = 2,
1327 .offsets = { offsetof(AV1RawOBU, obu.tile_group.data),
1328 offsetof(AV1RawOBU, obu.tile_group.tile_data.data) }
1329 },
1330 },
1331
1332 {
1333 .nb_unit_types = 1,
1334 .unit_type.list[0] = AV1_OBU_FRAME,
1335 .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS,
1336 .content_size = sizeof(AV1RawOBU),
1337 .type.ref = {
1338 .nb_offsets = 2,
1339 .offsets = { offsetof(AV1RawOBU, obu.frame.tile_group.data),
1340 offsetof(AV1RawOBU, obu.frame.tile_group.tile_data.data) }
1341 },
1342 },
1343 #if CBS_AV1_OBU_TILE_LIST
1344 CBS_UNIT_TYPE_INTERNAL_REF(AV1_OBU_TILE_LIST, AV1RawOBU,
1345 obu.tile_list.tile_data.data),
1346 #endif
1347 #if CBS_AV1_OBU_PADDING
1348 CBS_UNIT_TYPE_INTERNAL_REF(AV1_OBU_PADDING, AV1RawOBU,
1349 obu.padding.payload),
1350 #endif
1351
1352 #if CBS_AV1_OBU_METADATA
1353 CBS_UNIT_TYPE_COMPLEX(AV1_OBU_METADATA, AV1RawOBU,
1354 &cbs_av1_free_metadata),
1355 #endif
1356
1357 CBS_UNIT_TYPE_END_OF_LIST
1358 };
1359
1360 #define OFFSET(x) offsetof(CodedBitstreamAV1Context, x)
1361 static const AVOption cbs_av1_options[] = {
1362 { "operating_point", "Set operating point to select layers to parse from a scalable bitstream",
1363 OFFSET(operating_point), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, AV1_MAX_OPERATING_POINTS - 1, 0 },
1364 { "fixed_obu_size_length", "Set fixed length of the obu_size field",
1365 OFFSET(fixed_obu_size_length), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8, 0 },
1366 { NULL }
1367 };
1368
1369 static const AVClass cbs_av1_class = {
1370 .class_name = "cbs_av1",
1371 .item_name = av_default_item_name,
1372 .option = cbs_av1_options,
1373 .version = LIBAVUTIL_VERSION_INT,
1374 };
1375
1376 const CodedBitstreamType CBS_FUNC(type_av1) = {
1377 .codec_id = AV_CODEC_ID_AV1,
1378
1379 .priv_class = &cbs_av1_class,
1380 .priv_data_size = sizeof(CodedBitstreamAV1Context),
1381
1382 .unit_types = cbs_av1_unit_types,
1383
1384 .split_fragment = &cbs_av1_split_fragment,
1385 .read_unit = &cbs_av1_read_unit,
1386 .write_unit = &cbs_av1_write_obu,
1387 .assemble_fragment = &cbs_av1_assemble_fragment,
1388
1389 .flush = &cbs_av1_flush,
1390 .close = &cbs_av1_close,
1391 };
1392