FFmpeg coverage


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