Bug Summary

File:root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c
Warning:line 1186, column 5
Value stored to 'end_pos' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name cbs_av1.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/media/ffvpx/libavcodec -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/media/ffvpx/libavcodec -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -include libavutil_visibility.h -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D HAVE_AV_CONFIG_H -D ASSERT_LEVEL=2 -I /root/firefox-clang/media/ffvpx/libavcodec -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/media/ffvpx/libavcodec -I /root/firefox-clang/modules/fdlibm/inexact-math-override -I /root/firefox-clang/third_party/khronos/vulkan-headers/include -I /root/firefox-clang/media/mozva -I /root/firefox-clang/media/libopus/include -I /root/firefox-clang/media/libvorbis -I /root/firefox-clang/media/libvpx -I /root/firefox-clang/media/ffvpx -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=tautological-type-limit-compare -Wno-range-loop-analysis -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-unknown-warning-option -Wno-character-conversion -Wno-parentheses -Wno-pointer-sign -Wno-sign-compare -Wno-switch -Wno-type-limits -Wno-unused-function -Wno-deprecated-declarations -Wno-absolute-value -Wno-incompatible-pointer-types -Wno-string-conversion -Wno-visibility -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c /root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c
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_READ1
32static 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()GetBitContext trace_start; do { if (ctx->trace_enable) trace_start
= *gbc; } while (0)
;
39
40 zeroes = 0;
41 while (zeroes < 32) {
42 if (get_bits_left(gbc) < 1) {
43 av_log(ctx->log_ctx, AV_LOG_ERROR16, "Invalid uvlc code at "
44 "%s: bitstream ended.\n", name);
45 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
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_ERROR16, "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(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
66 } else {
67 if (get_bits_left(gbc) < zeroes) {
68 av_log(ctx->log_ctx, AV_LOG_ERROR16, "Invalid uvlc code at "
69 "%s: bitstream ended.\n", name);
70 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
71 }
72
73 bits_value = get_bits_long(gbc, zeroes);
74 value = bits_value + (UINT32_C(1)1U << zeroes) - 1;
75 }
76
77 CBS_TRACE_READ_END_NO_SUBSCRIPTS()do { const int *subscripts = ((void*)0); do { if (ctx->trace_enable
) { int start_position = get_bits_count(&trace_start); int
end_position = get_bits_count(gbc); do { if (!(start_position
<= end_position)) { av_log(((void*)0), 0, "Assertion %s failed at %s:%d\n"
, "start_position <= end_position", "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c"
, 77); abort(); } } while (0); ctx->trace_read_callback(ctx
->trace_context, &trace_start, end_position - start_position
, name, subscripts, value); } } while (0); } while (0)
;
78
79 if (value < range_min || value > range_max) {
80 av_log(ctx->log_ctx, AV_LOG_ERROR16, "%s out of range: "
81 "%"PRIu32"u"", but must be in [%"PRIu32"u"",%"PRIu32"u""].\n",
82 name, value, range_min, range_max);
83 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
84 }
85
86 *write_to = value;
87 return 0;
88}
89#endif
90
91#if CBS_WRITE1
92static 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()int start_position; do { if (ctx->trace_enable) start_position
= put_bits_count(pbc);; } while (0)
;
100
101 if (value < range_min || value > range_max) {
102 av_log(ctx->log_ctx, AV_LOG_ERROR16, "%s out of range: "
103 "%"PRIu32"u"", but must be in [%"PRIu32"u"",%"PRIu32"u""].\n",
104 name, value, range_min, range_max);
105 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
106 }
107
108 zeroes = av_log2(value + 1)(31 - __builtin_clz((value + 1)|1));
109 v = value - (1U << zeroes) + 1;
110
111 if (put_bits_left(pbc) < 2 * zeroes + 1)
112 return AVERROR(ENOSPC)(-(28));
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()do { const int *subscripts = ((void*)0); do { if (ctx->trace_enable
) { int end_position = put_bits_count(pbc); do { if (!(start_position
<= end_position)) { av_log(((void*)0), 0, "Assertion %s failed at %s:%d\n"
, "start_position <= end_position", "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c"
, 118); abort(); } } while (0); ctx->trace_write_callback(
ctx->trace_context, pbc, end_position - start_position, name
, subscripts, value); } } while (0); } while (0)
;
119
120 return 0;
121}
122#endif
123
124#if CBS_READ1
125static 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 CBS_TRACE_READ_START()GetBitContext trace_start; do { if (ctx->trace_enable) trace_start
= *gbc; } while (0)
;
133
134 value = 0;
135 for (i = 0; i < 8; i++) {
136 if (get_bits_left(gbc) < 8) {
137 av_log(ctx->log_ctx, AV_LOG_ERROR16, "Invalid leb128 at "
138 "%s: bitstream ended.\n", name);
139 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
140 }
141 byte = get_bits(gbc, 8);
142 value |= (uint64_t)(byte & 0x7f) << (i * 7);
143 if (!(byte & 0x80))
144 break;
145 }
146
147 if (value > UINT32_MAX(4294967295U))
148 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
149
150 CBS_TRACE_READ_END_NO_SUBSCRIPTS()do { const int *subscripts = ((void*)0); do { if (ctx->trace_enable
) { int start_position = get_bits_count(&trace_start); int
end_position = get_bits_count(gbc); do { if (!(start_position
<= end_position)) { av_log(((void*)0), 0, "Assertion %s failed at %s:%d\n"
, "start_position <= end_position", "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c"
, 150); abort(); } } while (0); ctx->trace_read_callback(ctx
->trace_context, &trace_start, end_position - start_position
, name, subscripts, value); } } while (0); } while (0)
;
151
152 *write_to = value;
153 return 0;
154}
155#endif
156
157#if CBS_WRITE1
158static 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 CBS_TRACE_WRITE_START()int start_position; do { if (ctx->trace_enable) start_position
= put_bits_count(pbc);; } while (0)
;
165
166 len = (av_log2(value)(31 - __builtin_clz((value)|1)) + 7) / 7;
167
168 if (fixed_length) {
169 if (fixed_length < len) {
170 av_log(ctx->log_ctx, AV_LOG_ERROR16, "OBU is too large for "
171 "fixed length size field (%d > %d).\n",
172 len, fixed_length);
173 return AVERROR(EINVAL)(-(22));
174 }
175 len = fixed_length;
176 }
177
178 for (i = 0; i < len; i++) {
179 if (put_bits_left(pbc) < 8)
180 return AVERROR(ENOSPC)(-(28));
181
182 byte = value >> (7 * i) & 0x7f;
183 if (i < len - 1)
184 byte |= 0x80;
185
186 put_bits(pbc, 8, byte);
187 }
188
189 CBS_TRACE_WRITE_END_NO_SUBSCRIPTS()do { const int *subscripts = ((void*)0); do { if (ctx->trace_enable
) { int end_position = put_bits_count(pbc); do { if (!(start_position
<= end_position)) { av_log(((void*)0), 0, "Assertion %s failed at %s:%d\n"
, "start_position <= end_position", "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c"
, 189); abort(); } } while (0); ctx->trace_write_callback(
ctx->trace_context, pbc, end_position - start_position, name
, subscripts, value); } } while (0); } while (0)
;
190
191 return 0;
192}
193#endif
194
195#if CBS_READ1
196static 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 CBS_TRACE_READ_START()GetBitContext trace_start; do { if (ctx->trace_enable) trace_start
= *gbc; } while (0)
;
204
205 av_assert0(n > 0)do { if (!(n > 0)) { av_log(((void*)0), 0, "Assertion %s failed at %s:%d\n"
, "n > 0", "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c"
, 205); abort(); } } while (0)
;
206
207 w = av_log2(n)(31 - __builtin_clz((n)|1)) + 1;
208 m = (1 << w) - n;
209
210 if (get_bits_left(gbc) < w) {
211 av_log(ctx->log_ctx, AV_LOG_ERROR16, "Invalid non-symmetric value at "
212 "%s: bitstream ended.\n", name);
213 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
214 }
215
216 if (w - 1 > 0)
217 v = get_bits(gbc, w - 1);
218 else
219 v = 0;
220
221 if (v < m) {
222 value = v;
223 } else {
224 extra_bit = get_bits1(gbc);
225 value = (v << 1) - m + extra_bit;
226 }
227
228 CBS_TRACE_READ_END()do { if (ctx->trace_enable) { int start_position = get_bits_count
(&trace_start); int end_position = get_bits_count(gbc); do
{ if (!(start_position <= end_position)) { av_log(((void*
)0), 0, "Assertion %s failed at %s:%d\n", "start_position <= end_position"
, "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c", 228
); abort(); } } while (0); ctx->trace_read_callback(ctx->
trace_context, &trace_start, end_position - start_position
, name, subscripts, value); } } while (0)
;
229
230 *write_to = value;
231 return 0;
232}
233#endif
234
235#if CBS_WRITE1
236static 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 CBS_TRACE_WRITE_START()int start_position; do { if (ctx->trace_enable) start_position
= put_bits_count(pbc);; } while (0)
;
243
244 if (value > n) {
245 av_log(ctx->log_ctx, AV_LOG_ERROR16, "%s out of range: "
246 "%"PRIu32"u"", but must be in [0,%"PRIu32"u""].\n",
247 name, value, n);
248 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
249 }
250
251 w = av_log2(n)(31 - __builtin_clz((n)|1)) + 1;
252 m = (1 << w) - n;
253
254 if (put_bits_left(pbc) < w)
255 return AVERROR(ENOSPC)(-(28));
256
257 if (value < m) {
258 v = value;
259 put_bits(pbc, w - 1, v);
260 } else {
261 v = m + ((value - m) >> 1);
262 extra_bit = (value - m) & 1;
263 put_bits(pbc, w - 1, v);
264 put_bits(pbc, 1, extra_bit);
265 }
266
267 CBS_TRACE_WRITE_END()do { if (ctx->trace_enable) { int end_position = put_bits_count
(pbc); do { if (!(start_position <= end_position)) { av_log
(((void*)0), 0, "Assertion %s failed at %s:%d\n", "start_position <= end_position"
, "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c", 267
); abort(); } } while (0); ctx->trace_write_callback(ctx->
trace_context, pbc, end_position - start_position, name, subscripts
, value); } } while (0)
;
268
269 return 0;
270}
271#endif
272
273#if CBS_READ1
274static 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 CBS_TRACE_READ_START()GetBitContext trace_start; do { if (ctx->trace_enable) trace_start
= *gbc; } while (0)
;
281
282 av_assert0(range_min <= range_max && range_max - range_min < 32)do { if (!(range_min <= range_max && range_max - range_min
< 32)) { av_log(((void*)0), 0, "Assertion %s failed at %s:%d\n"
, "range_min <= range_max && range_max - range_min < 32"
, "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c", 282
); abort(); } } while (0)
;
283
284 for (value = range_min; value < range_max;) {
285 if (get_bits_left(gbc) < 1) {
286 av_log(ctx->log_ctx, AV_LOG_ERROR16, "Invalid increment value at "
287 "%s: bitstream ended.\n", name);
288 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
289 }
290 if (get_bits1(gbc))
291 ++value;
292 else
293 break;
294 }
295
296 CBS_TRACE_READ_END_NO_SUBSCRIPTS()do { const int *subscripts = ((void*)0); do { if (ctx->trace_enable
) { int start_position = get_bits_count(&trace_start); int
end_position = get_bits_count(gbc); do { if (!(start_position
<= end_position)) { av_log(((void*)0), 0, "Assertion %s failed at %s:%d\n"
, "start_position <= end_position", "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c"
, 296); abort(); } } while (0); ctx->trace_read_callback(ctx
->trace_context, &trace_start, end_position - start_position
, name, subscripts, value); } } while (0); } while (0)
;
297
298 *write_to = value;
299 return 0;
300}
301#endif
302
303#if CBS_WRITE1
304static 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 CBS_TRACE_WRITE_START()int start_position; do { if (ctx->trace_enable) start_position
= put_bits_count(pbc);; } while (0)
;
311
312 av_assert0(range_min <= range_max && range_max - range_min < 32)do { if (!(range_min <= range_max && range_max - range_min
< 32)) { av_log(((void*)0), 0, "Assertion %s failed at %s:%d\n"
, "range_min <= range_max && range_max - range_min < 32"
, "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c", 312
); abort(); } } while (0)
;
313 if (value < range_min || value > range_max) {
314 av_log(ctx->log_ctx, AV_LOG_ERROR16, "%s out of range: "
315 "%"PRIu32"u"", but must be in [%"PRIu32"u"",%"PRIu32"u""].\n",
316 name, value, range_min, range_max);
317 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
318 }
319
320 if (value == range_max)
321 len = range_max - range_min;
322 else
323 len = value - range_min + 1;
324 if (put_bits_left(pbc) < len)
325 return AVERROR(ENOSPC)(-(28));
326
327 if (len > 0)
328 put_bits(pbc, len, (1U << len) - 1 - (value != range_max));
329
330 CBS_TRACE_WRITE_END_NO_SUBSCRIPTS()do { const int *subscripts = ((void*)0); do { if (ctx->trace_enable
) { int end_position = put_bits_count(pbc); do { if (!(start_position
<= end_position)) { av_log(((void*)0), 0, "Assertion %s failed at %s:%d\n"
, "start_position <= end_position", "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c"
, 330); abort(); } } while (0); ctx->trace_write_callback(
ctx->trace_context, pbc, end_position - start_position, name
, subscripts, value); } } while (0); } while (0)
;
331
332 return 0;
333}
334#endif
335
336#if CBS_READ1
337static 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 CBS_TRACE_READ_START()GetBitContext trace_start; do { if (ctx->trace_enable) trace_start
= *gbc; } while (0)
;
345
346 av_assert0(range_max > 0)do { if (!(range_max > 0)) { av_log(((void*)0), 0, "Assertion %s failed at %s:%d\n"
, "range_max > 0", "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c"
, 346); abort(); } } while (0)
;
347 max_len = av_log2(range_max - 1)(31 - __builtin_clz((range_max - 1)|1)) - 3;
348
349 err = cbs_av1_read_increment(ctx, gbc, 0, max_len,
350 "subexp_more_bits", &len);
351 if (err < 0)
352 return err;
353
354 if (len) {
355 range_bits = 2 + len;
356 range_offset = 1 << range_bits;
357 } else {
358 range_bits = 3;
359 range_offset = 0;
360 }
361
362 if (len < max_len) {
363 err = CBS_FUNC(read_simple_unsigned)ff_cbs_read_simple_unsigned(ctx, gbc, range_bits,
364 "subexp_bits", &value);
365 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((void*)0), &value);
371 if (err < 0)
372 return err;
373 }
374 value += range_offset;
375
376 CBS_TRACE_READ_END_VALUE_ONLY()do { if (ctx->trace_enable) { ctx->trace_read_callback(
ctx->trace_context, &trace_start, 0, name, subscripts,
value); } } while (0)
;
377
378 *write_to = value;
379 return err;
380}
381#endif
382
383#if CBS_WRITE1
384static 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 CBS_TRACE_WRITE_START()int start_position; do { if (ctx->trace_enable) start_position
= put_bits_count(pbc);; } while (0)
;
392
393 if (value > range_max) {
394 av_log(ctx->log_ctx, AV_LOG_ERROR16, "%s out of range: "
395 "%"PRIu32"u"", but must be in [0,%"PRIu32"u""].\n",
396 name, value, range_max);
397 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
398 }
399
400 av_assert0(range_max > 0)do { if (!(range_max > 0)) { av_log(((void*)0), 0, "Assertion %s failed at %s:%d\n"
, "range_max > 0", "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c"
, 400); abort(); } } while (0)
;
401 max_len = av_log2(range_max - 1)(31 - __builtin_clz((range_max - 1)|1)) - 3;
402
403 if (value < 8) {
404 range_bits = 3;
405 range_offset = 0;
406 len = 0;
407 } else {
408 range_bits = av_log2(value)(31 - __builtin_clz((value)|1));
409 len = range_bits - 2;
410 if (len > max_len) {
411 // The top bin is combined with the one below it.
412 av_assert0(len == max_len + 1)do { if (!(len == max_len + 1)) { av_log(((void*)0), 0, "Assertion %s failed at %s:%d\n"
, "len == max_len + 1", "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c"
, 412); abort(); } } while (0)
;
413 --range_bits;
414 len = max_len;
415 }
416 range_offset = 1 << range_bits;
417 }
418
419 err = cbs_av1_write_increment(ctx, pbc, 0, max_len,
420 "subexp_more_bits", len);
421 if (err < 0)
422 return err;
423
424 if (len < max_len) {
425 err = CBS_FUNC(write_simple_unsigned)ff_cbs_write_simple_unsigned(ctx, pbc, range_bits,
426 "subexp_bits",
427 value - range_offset);
428 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((void*)0),
434 value - range_offset);
435 if (err < 0)
436 return err;
437 }
438
439 CBS_TRACE_WRITE_END_VALUE_ONLY()do { if (ctx->trace_enable) { PutBitContext tmp; init_put_bits
(&tmp, pbc->buf, start_position); skip_put_bits(&tmp
, start_position); ctx->trace_write_callback(ctx->trace_context
, &tmp, 0, name, subscripts, value); } } while (0)
;
440
441 return err;
442}
443#endif
444
445
446static int cbs_av1_tile_log2(int blksize, int target)
447{
448 int k;
449 for (k = 0; (blksize << k) < target; k++);
450 return k;
451}
452
453static int cbs_av1_get_relative_dist(const AV1RawSequenceHeader *seq,
454 unsigned int a, unsigned int b)
455{
456 unsigned int diff, m;
457 if (!seq->enable_order_hint)
458 return 0;
459 diff = a - b;
460 m = 1 << seq->order_hint_bits_minus_1;
461 diff = (diff & (m - 1)) - (diff & m);
462 return diff;
463}
464
465av_unused__attribute__((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 { ff_cbs_trace_header(ctx, name); } while (0) do { \
478 CBS_FUNC(trace_header)ff_cbs_trace_header(ctx, name); \
479 } while (0)
480
481#define CHECK(call)do { err = (call); if (err < 0) return err; } while (0) 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 cbs_ ## codec ## _ ## rw ## _ ## name
488#define FUNC_AV1(rw, name)cbs_av1_rw_name FUNC_NAME(rw, av1, name)cbs_av1_rw_name
489#define FUNC(name)cbs_av1_READWRITE_name FUNC_AV1(READWRITE, name)cbs_av1_READWRITE_name
490
491#define SUBSCRIPTS(subs, ...)(subs > 0 ? ((int[subs + 1]){ subs, ... }) : ((void*)0)) (subs > 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : NULL((void*)0))
492
493#if CBS_READ1
494#define fc(width, name, range_min, range_max)xf(width, name, current->name, range_min, range_max, 0, ) \
495 xf(width, name, current->name, range_min, range_max, 0, )
496#define flag(name)fb(1, name) fb(1, name)
497#define su(width, name)xsu(width, name, current->name, 0, ) \
498 xsu(width, name, current->name, 0, )
499
500#define fbs(width, name, subs, ...)xf(width, name, current->name, 0, ((1UL << (width)) -
1), subs, ...)
\
501 xf(width, name, current->name, 0, MAX_UINT_BITS(width)((1UL << (width)) - 1), subs, __VA_ARGS__)
502#define fcs(width, name, range_min, range_max, subs, ...)xf(width, name, current->name, range_min, range_max, subs,
...)
\
503 xf(width, name, current->name, range_min, range_max, subs, __VA_ARGS__)
504#define flags(name, subs, ...)xf(1, name, current->name, 0, 1, subs, ...) \
505 xf(1, name, current->name, 0, 1, subs, __VA_ARGS__)
506#define sus(width, name, subs, ...)xsu(width, name, current->name, subs, ...) \
507 xsu(width, name, current->name, subs, __VA_ARGS__)
508
509#define fixed(width, name, value)do { __attribute__((unused)) uint32_t fixed_value = value; xf
(width, name, fixed_value, value, value, 0, ); } while (0)
do { \
510 av_unused__attribute__((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, \do { err = (ff_cbs_read_simple_unsigned(ctx, rw, width, #name
, &value)); if (err < 0) return err; } while (0)
522 #name, &value))do { err = (ff_cbs_read_simple_unsigned(ctx, rw, width, #name
, &value)); if (err < 0) return err; } while (0)
; \
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, \do { err = (ff_cbs_read_unsigned(ctx, rw, width, #name, (subs
> 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)
), &value, range_min, range_max)); if (err < 0) return
err; } while (0)
529 SUBSCRIPTS(subs, __VA_ARGS__), \do { err = (ff_cbs_read_unsigned(ctx, rw, width, #name, (subs
> 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)
), &value, range_min, range_max)); if (err < 0) return
err; } while (0)
530 &value, range_min, range_max))do { err = (ff_cbs_read_unsigned(ctx, rw, width, #name, (subs
> 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)
), &value, range_min, range_max)); if (err < 0) return
err; } while (0)
; \
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, \do { err = (ff_cbs_read_signed(ctx, rw, width, #name, (subs >
0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)), &
value, (-(1L << ((width) - 1))), ((1L << ((width)
- 1)) - 1))); if (err < 0) return err; } while (0)
537 SUBSCRIPTS(subs, __VA_ARGS__), &value, \do { err = (ff_cbs_read_signed(ctx, rw, width, #name, (subs >
0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)), &
value, (-(1L << ((width) - 1))), ((1L << ((width)
- 1)) - 1))); if (err < 0) return err; } while (0)
538 MIN_INT_BITS(width), \do { err = (ff_cbs_read_signed(ctx, rw, width, #name, (subs >
0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)), &
value, (-(1L << ((width) - 1))), ((1L << ((width)
- 1)) - 1))); if (err < 0) return err; } while (0)
539 MAX_INT_BITS(width)))do { err = (ff_cbs_read_signed(ctx, rw, width, #name, (subs >
0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)), &
value, (-(1L << ((width) - 1))), ((1L << ((width)
- 1)) - 1))); if (err < 0) return err; } while (0)
; \
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, \do { err = (cbs_av1_read_uvlc(ctx, rw, #name, &value, range_min
, range_max)); if (err < 0) return err; } while (0)
546 &value, range_min, range_max))do { err = (cbs_av1_read_uvlc(ctx, rw, #name, &value, range_min
, range_max)); if (err < 0) return err; } while (0)
; \
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, \do { err = (cbs_av1_read_ns(ctx, rw, max_value, #name, (subs >
0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)), &
value)); if (err < 0) return err; } while (0)
553 SUBSCRIPTS(subs, __VA_ARGS__), &value))do { err = (cbs_av1_read_ns(ctx, rw, max_value, #name, (subs >
0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)), &
value)); if (err < 0) return err; } while (0)
; \
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))do { err = (cbs_av1_read_increment(ctx, rw, min, max, #name, &
value)); if (err < 0) return err; } while (0)
; \
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, \do { err = (cbs_av1_read_subexp(ctx, rw, max, #name, (subs >
0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)), &
value)); if (err < 0) return err; } while (0)
566 SUBSCRIPTS(subs, __VA_ARGS__), &value))do { err = (cbs_av1_read_subexp(ctx, rw, max, #name, (subs >
0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)), &
value)); if (err < 0) return err; } while (0)
; \
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))do { err = (cbs_av1_read_leb128(ctx, rw, #name, &value));
if (err < 0) return err; } while (0)
; \
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_WRITE1
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, \do { err = (ff_cbs_write_simple_unsigned(ctx, rw, width, #name
, current->name)); if (err < 0) return err; } while (0)
619 current->name))do { err = (ff_cbs_write_simple_unsigned(ctx, rw, width, #name
, current->name)); if (err < 0) return err; } while (0)
; \
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, \do { err = (ff_cbs_write_unsigned(ctx, rw, width, #name, (subs
> 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)
), var, range_min, range_max)); if (err < 0) return err; }
while (0)
624 SUBSCRIPTS(subs, __VA_ARGS__), \do { err = (ff_cbs_write_unsigned(ctx, rw, width, #name, (subs
> 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)
), var, range_min, range_max)); if (err < 0) return err; }
while (0)
625 var, range_min, range_max))do { err = (ff_cbs_write_unsigned(ctx, rw, width, #name, (subs
> 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)
), var, range_min, range_max)); if (err < 0) return err; }
while (0)
; \
626 } while (0)
627
628#define xsu(width, name, var, subs, ...) do { \
629 CHECK(CBS_FUNC(write_signed)(ctx, rw, width, #name, \do { err = (ff_cbs_write_signed(ctx, rw, width, #name, (subs >
0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)), var
, (-(1L << ((width) - 1))), ((1L << ((width) - 1)
) - 1))); if (err < 0) return err; } while (0)
630 SUBSCRIPTS(subs, __VA_ARGS__), var, \do { err = (ff_cbs_write_signed(ctx, rw, width, #name, (subs >
0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)), var
, (-(1L << ((width) - 1))), ((1L << ((width) - 1)
) - 1))); if (err < 0) return err; } while (0)
631 MIN_INT_BITS(width), \do { err = (ff_cbs_write_signed(ctx, rw, width, #name, (subs >
0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)), var
, (-(1L << ((width) - 1))), ((1L << ((width) - 1)
) - 1))); if (err < 0) return err; } while (0)
632 MAX_INT_BITS(width)))do { err = (ff_cbs_write_signed(ctx, rw, width, #name, (subs >
0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)), var
, (-(1L << ((width) - 1))), ((1L << ((width) - 1)
) - 1))); if (err < 0) return err; } while (0)
; \
633 } while (0)
634
635#define uvlc(name, range_min, range_max) do { \
636 CHECK(cbs_av1_write_uvlc(ctx, rw, #name, current->name, \do { err = (cbs_av1_write_uvlc(ctx, rw, #name, current->name
, range_min, range_max)); if (err < 0) return err; } while
(0)
637 range_min, range_max))do { err = (cbs_av1_write_uvlc(ctx, rw, #name, current->name
, range_min, range_max)); if (err < 0) return err; } while
(0)
; \
638 } while (0)
639
640#define ns(max_value, name, subs, ...) do { \
641 CHECK(cbs_av1_write_ns(ctx, rw, max_value, #name, \do { err = (cbs_av1_write_ns(ctx, rw, max_value, #name, (subs
> 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)
), current->name)); if (err < 0) return err; } while (0
)
642 SUBSCRIPTS(subs, __VA_ARGS__), \do { err = (cbs_av1_write_ns(ctx, rw, max_value, #name, (subs
> 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)
), current->name)); if (err < 0) return err; } while (0
)
643 current->name))do { err = (cbs_av1_write_ns(ctx, rw, max_value, #name, (subs
> 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)
), current->name)); if (err < 0) return err; } while (0
)
; \
644 } while (0)
645
646#define increment(name, min, max) do { \
647 CHECK(cbs_av1_write_increment(ctx, rw, min, max, #name, \do { err = (cbs_av1_write_increment(ctx, rw, min, max, #name,
current->name)); if (err < 0) return err; } while (0)
648 current->name))do { err = (cbs_av1_write_increment(ctx, rw, min, max, #name,
current->name)); if (err < 0) return err; } while (0)
; \
649 } while (0)
650
651#define subexp(name, max, subs, ...) do { \
652 CHECK(cbs_av1_write_subexp(ctx, rw, max, #name, \do { err = (cbs_av1_write_subexp(ctx, rw, max, #name, (subs >
0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)), current
->name)); if (err < 0) return err; } while (0)
653 SUBSCRIPTS(subs, __VA_ARGS__), \do { err = (cbs_av1_write_subexp(ctx, rw, max, #name, (subs >
0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)), current
->name)); if (err < 0) return err; } while (0)
654 current->name))do { err = (cbs_av1_write_subexp(ctx, rw, max, #name, (subs >
0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : ((void*)0)), current
->name)); if (err < 0) return err; } while (0)
; \
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))do { err = (cbs_av1_write_leb128(ctx, rw, #name, current->
name, 0)); if (err < 0) return err; } while (0)
; \
665 } while (0)
666
667#define infer(name, value) do { \
668 if (current->name != (value)) { \
669 av_log(ctx->log_ctx, AV_LOG_ERROR16, \
670 "%s does not match inferred value: " \
671 "%"PRId64"l" "d"", but should be %"PRId64"l" "d"".\n", \
672 #name, (int64_t)current->name, (int64_t)(value)); \
673 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
; \
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
697static int cbs_av1_split_fragment(CodedBitstreamContext *ctx,
698 CodedBitstreamFragment *frag,
699 int header)
700{
701#if CBS_READ1
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 trace = ctx->trace_enable;
710 ctx->trace_enable = 0;
711
712 data = frag->data;
713 size = frag->data_size;
714
715 if (INT_MAX2147483647 / 8 < size) {
716 av_log(ctx->log_ctx, AV_LOG_ERROR16, "Invalid fragment: "
717 "too large (%zu bytes).\n", size);
718 err = AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
719 goto fail;
720 }
721
722 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 int config_record_version = data[0] & 0x7f;
726
727 if (config_record_version != 1) {
728 av_log(ctx->log_ctx, AV_LOG_ERROR16,
729 "Unknown version %d of AV1CodecConfigurationRecord "
730 "found!\n",
731 config_record_version);
732 err = AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
733 goto fail;
734 }
735
736 if (size <= 4) {
737 if (size < 4) {
738 av_log(ctx->log_ctx, AV_LOG_WARNING24,
739 "Undersized AV1CodecConfigurationRecord v%d found!\n",
740 config_record_version);
741 err = AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
742 goto fail;
743 }
744
745 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 data += 4;
752 size -= 4;
753 }
754
755 while (size > 0) {
756 AV1RawOBUHeader obu_header;
757 uint64_t obu_size;
758
759 init_get_bits(&gbc, data, 8 * size);
760
761 err = cbs_av1_read_obu_header(ctx, &gbc, &obu_header);
762 if (err < 0)
763 goto fail;
764
765 if (obu_header.obu_has_size_field) {
766 if (get_bits_left(&gbc) < 8) {
767 av_log(ctx->log_ctx, AV_LOG_ERROR16, "Invalid OBU: fragment "
768 "too short (%zu bytes).\n", size);
769 err = AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
770 goto fail;
771 }
772 err = cbs_av1_read_leb128(ctx, &gbc, "obu_size", &obu_size);
773 if (err < 0)
774 goto fail;
775 } else
776 obu_size = size - 1 - obu_header.obu_extension_flag;
777
778 pos = get_bits_count(&gbc);
779 av_assert0(pos % 8 == 0 && pos / 8 <= size)do { if (!(pos % 8 == 0 && pos / 8 <= size)) { av_log
(((void*)0), 0, "Assertion %s failed at %s:%d\n", "pos % 8 == 0 && pos / 8 <= size"
, "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c", 779
); abort(); } } while (0)
;
780
781 obu_length = pos / 8 + obu_size;
782
783 if (size < obu_length) {
784 av_log(ctx->log_ctx, AV_LOG_ERROR16, "Invalid OBU length: "
785 "%"PRIu64"l" "u"", but only %zu bytes remaining in fragment.\n",
786 obu_length, size);
787 err = AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
788 goto fail;
789 }
790
791 err = CBS_FUNC(append_unit_data)ff_cbs_append_unit_data(frag, obu_header.obu_type,
792 data, obu_length, frag->data_ref);
793 if (err < 0)
794 goto fail;
795
796 data += obu_length;
797 size -= obu_length;
798 }
799
800success:
801 err = 0;
802fail:
803 ctx->trace_enable = trace;
804 return err;
805#else
806 return AVERROR(ENOSYS)(-(38));
807#endif
808}
809
810#if CBS_READ1
811static 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 pos = get_bits_count(gbc);
820 if (pos >= 8 * unit->data_size) {
821 av_log(ctx->log_ctx, AV_LOG_ERROR16, "Bitstream ended before "
822 "any data in tile group (%d bits read).\n", pos);
823 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
824 }
825 // Must be byte-aligned at this point.
826 av_assert0(pos % 8 == 0)do { if (!(pos % 8 == 0)) { av_log(((void*)0), 0, "Assertion %s failed at %s:%d\n"
, "pos % 8 == 0", "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c"
, 826); abort(); } } while (0)
;
827
828 *data_ref = av_buffer_ref(unit->data_ref);
829 if (!*data_ref)
830 return AVERROR(ENOMEM)(-(12));
831
832 *data = unit->data + pos / 8;
833 *data_size = unit->data_size - pos / 8;
834
835 return 0;
836}
837#endif
838
839static int cbs_av1_read_unit(CodedBitstreamContext *ctx,
840 CodedBitstreamUnit *unit)
841{
842#if CBS_READ1
843 CodedBitstreamAV1Context *priv = ctx->priv_data;
844 AV1RawOBU *obu;
845 GetBitContext gbc;
846 int err, start_pos, end_pos;
847
848 err = CBS_FUNC(alloc_unit_content)ff_cbs_alloc_unit_content(ctx, unit);
849 if (err < 0)
850 return err;
851 obu = unit->content;
852
853 err = init_get_bits(&gbc, unit->data, 8 * unit->data_size);
854 if (err < 0)
855 return err;
856
857 err = cbs_av1_read_obu_header(ctx, &gbc, &obu->header);
858 if (err < 0)
859 return err;
860 av_assert0(obu->header.obu_type == unit->type)do { if (!(obu->header.obu_type == unit->type)) { av_log
(((void*)0), 0, "Assertion %s failed at %s:%d\n", "obu->header.obu_type == unit->type"
, "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c", 860
); abort(); } } while (0)
;
861
862 if (obu->header.obu_has_size_field) {
863 uint64_t obu_size;
864 err = cbs_av1_read_leb128(ctx, &gbc, "obu_size", &obu_size);
865 if (err < 0)
866 return err;
867 obu->obu_size = obu_size;
868 } else {
869 if (unit->data_size < 1 + obu->header.obu_extension_flag) {
870 av_log(ctx->log_ctx, AV_LOG_ERROR16, "Invalid OBU length: "
871 "unit too short (%zu).\n", unit->data_size);
872 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
873 }
874 obu->obu_size = unit->data_size - 1 - obu->header.obu_extension_flag;
875 }
876
877 start_pos = get_bits_count(&gbc);
878
879 if (obu->header.obu_extension_flag) {
880 if (obu->header.obu_type != AV1_OBU_SEQUENCE_HEADER &&
881 obu->header.obu_type != AV1_OBU_TEMPORAL_DELIMITER &&
882 priv->operating_point_idc) {
883 int in_temporal_layer =
884 (priv->operating_point_idc >> priv->temporal_id ) & 1;
885 int in_spatial_layer =
886 (priv->operating_point_idc >> (priv->spatial_id + 8)) & 1;
887 if (!in_temporal_layer || !in_spatial_layer) {
888 return AVERROR(EAGAIN)(-(11)); // drop_obu()
889 }
890 }
891 }
892
893 switch (obu->header.obu_type) {
894 case AV1_OBU_SEQUENCE_HEADER:
895 {
896 err = cbs_av1_read_sequence_header_obu(ctx, &gbc,
897 &obu->obu.sequence_header);
898 if (err < 0)
899 return err;
900
901 if (priv->operating_point >= 0) {
902 AV1RawSequenceHeader *sequence_header = &obu->obu.sequence_header;
903
904 if (priv->operating_point > sequence_header->operating_points_cnt_minus_1) {
905 av_log(ctx->log_ctx, AV_LOG_ERROR16, "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)(-(22));
909 }
910 priv->operating_point_idc = sequence_header->operating_point_idc[priv->operating_point];
911 }
912
913 av_refstruct_replace(&priv->sequence_header_ref, unit->content_ref);
914 priv->sequence_header = &obu->obu.sequence_header;
915 }
916 break;
917 case AV1_OBU_TEMPORAL_DELIMITER:
918 {
919 err = cbs_av1_read_temporal_delimiter_obu(ctx, &gbc);
920 if (err < 0)
921 return err;
922 }
923 break;
924 case AV1_OBU_FRAME_HEADER:
925 case AV1_OBU_REDUNDANT_FRAME_HEADER:
926 {
927 err = cbs_av1_read_frame_header_obu(ctx, &gbc,
928 &obu->obu.frame_header,
929 obu->header.obu_type ==
930 AV1_OBU_REDUNDANT_FRAME_HEADER,
931 unit->data_ref);
932 if (err < 0)
933 return err;
934 }
935 break;
936 case AV1_OBU_FRAME:
937 err = cbs_av1_read_frame_obu(ctx, &gbc, &obu->obu.frame,
938 unit->data_ref);
939 if (err < 0)
940 return err;
941 // fall-through
942 case AV1_OBU_TILE_GROUP:
943 {
944 AV1RawTileGroup *tile_group = obu->header.obu_type == AV1_OBU_FRAME ? &obu->obu.frame.tile_group
945 : &obu->obu.tile_group;
946 err = cbs_av1_ref_tile_data(ctx, unit, &gbc,
947 &tile_group->data_ref,
948 &tile_group->data,
949 &tile_group->data_size);
950 if (err < 0)
951 return err;
952
953 err = cbs_av1_read_tile_group_obu(ctx, &gbc, tile_group);
954 if (err < 0)
955 return err;
956
957 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 if (err < 0)
962 return err;
963 }
964 break;
965#if CBS_AV1_OBU_TILE_LIST1
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_METADATA1
983 case AV1_OBU_METADATA:
984 {
985 err = cbs_av1_read_metadata_obu(ctx, &gbc, &obu->obu.metadata);
986 if (err < 0)
987 return err;
988 }
989 break;
990#endif
991#if CBS_AV1_OBU_PADDING1
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)(-(38));
1002 }
1003
1004 end_pos = get_bits_count(&gbc);
1005 av_assert0(end_pos <= unit->data_size * 8)do { if (!(end_pos <= unit->data_size * 8)) { av_log(((
void*)0), 0, "Assertion %s failed at %s:%d\n", "end_pos <= unit->data_size * 8"
, "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c", 1005
); abort(); } } while (0)
;
1006
1007 if (obu->obu_size > 0 &&
1008 obu->header.obu_type != AV1_OBU_TILE_GROUP &&
1009 obu->header.obu_type != AV1_OBU_TILE_LIST &&
1010 obu->header.obu_type != AV1_OBU_FRAME) {
1011 int nb_bits = obu->obu_size * 8 + start_pos - end_pos;
1012
1013 if (nb_bits <= 0)
1014 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
1015
1016 err = cbs_av1_read_trailing_bits(ctx, &gbc, nb_bits);
1017 if (err < 0)
1018 return err;
1019 }
1020
1021 return 0;
1022#else
1023 return AVERROR(ENOSYS)(-(38));
1024#endif
1025}
1026
1027static int cbs_av1_write_obu(CodedBitstreamContext *ctx,
1028 CodedBitstreamUnit *unit,
1029 PutBitContext *pbc)
1030{
1031#if CBS_WRITE1
1032 CodedBitstreamAV1Context *priv = ctx->priv_data;
1033 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 obu->header.obu_has_size_field = 1;
1044 av1ctx = *priv;
1045
1046 if (priv->sequence_header_ref) {
1047 av1ctx.sequence_header_ref = av_refstruct_ref(priv->sequence_header_ref);
1048 }
1049
1050 if (priv->frame_header_ref) {
1051 av1ctx.frame_header_ref = av_buffer_ref(priv->frame_header_ref);
1052 if (!av1ctx.frame_header_ref) {
1053 err = AVERROR(ENOMEM)(-(12));
1054 goto error;
1055 }
1056 }
1057
1058 err = cbs_av1_write_obu_header(ctx, pbc, &obu->header);
1059 if (err < 0)
1060 goto error;
1061
1062 if (obu->header.obu_has_size_field) {
1063 pbc_tmp = *pbc;
1064 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 put_bits32(pbc, 0);
1070 put_bits32(pbc, 0);
1071 }
1072 }
1073
1074 td = NULL((void*)0);
1075 start_pos = put_bits_count(pbc);
1076
1077 switch (obu->header.obu_type) {
1078 case AV1_OBU_SEQUENCE_HEADER:
1079 {
1080 err = cbs_av1_write_sequence_header_obu(ctx, pbc,
1081 &obu->obu.sequence_header);
1082 if (err < 0)
1083 goto error;
1084
1085 av_refstruct_unref(&priv->sequence_header_ref);
1086 priv->sequence_header = NULL((void*)0);
1087
1088 err = CBS_FUNC(make_unit_refcounted)ff_cbs_make_unit_refcounted(ctx, unit);
1089 if (err < 0)
1090 goto error;
1091
1092 priv->sequence_header_ref = av_refstruct_ref(unit->content_ref);
1093 priv->sequence_header = &obu->obu.sequence_header;
1094 }
1095 break;
1096 case AV1_OBU_TEMPORAL_DELIMITER:
1097 {
1098 err = cbs_av1_write_temporal_delimiter_obu(ctx, pbc);
1099 if (err < 0)
1100 goto error;
1101 }
1102 break;
1103 case AV1_OBU_FRAME_HEADER:
1104 case AV1_OBU_REDUNDANT_FRAME_HEADER:
1105 {
1106 err = cbs_av1_write_frame_header_obu(ctx, pbc,
1107 &obu->obu.frame_header,
1108 obu->header.obu_type ==
1109 AV1_OBU_REDUNDANT_FRAME_HEADER,
1110 NULL((void*)0));
1111 if (err < 0)
1112 goto error;
1113 }
1114 break;
1115 case AV1_OBU_FRAME:
1116 err = cbs_av1_write_frame_obu(ctx, pbc, &obu->obu.frame, NULL((void*)0));
1117 if (err < 0)
1118 goto error;
1119 // fall-through
1120 case AV1_OBU_TILE_GROUP:
1121 {
1122 AV1RawTileGroup *tile_group = obu->header.obu_type == AV1_OBU_FRAME ? &obu->obu.frame.tile_group
1123 : &obu->obu.tile_group;
1124 err = cbs_av1_write_tile_group_obu(ctx, pbc, tile_group);
1125 if (err < 0)
1126 goto error;
1127
1128 td = &tile_group->tile_data;
1129 }
1130 break;
1131#if CBS_AV1_OBU_TILE_LIST1
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_METADATA1
1143 case AV1_OBU_METADATA:
1144 {
1145 err = cbs_av1_write_metadata_obu(ctx, pbc, &obu->obu.metadata);
1146 if (err < 0)
1147 goto error;
1148 }
1149 break;
1150#endif
1151#if CBS_AV1_OBU_PADDING1
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)(-(38));
1162 goto error;
1163 }
1164
1165 end_pos = put_bits_count(pbc);
1166 header_size = (end_pos - start_pos + 7) / 8;
1167 if (td) {
1168 obu->obu_size = header_size + td->data_size;
1169 } else if (header_size > 0) {
1170 // Add trailing bits and recalculate.
1171 err = cbs_av1_write_trailing_bits(ctx, pbc, 8 - end_pos % 8);
1172 if (err < 0)
1173 goto error;
1174 end_pos = put_bits_count(pbc);
1175 obu->obu_size = header_size = (end_pos - start_pos + 7) / 8;
1176 } else {
1177 // Empty OBU.
1178 obu->obu_size = 0;
1179 }
1180
1181 end_pos = put_bits_count(pbc);
1182 // Must now be byte-aligned.
1183 av_assert0(end_pos % 8 == 0)do { if (!(end_pos % 8 == 0)) { av_log(((void*)0), 0, "Assertion %s failed at %s:%d\n"
, "end_pos % 8 == 0", "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c"
, 1183); abort(); } } while (0)
;
1184 flush_put_bits(pbc);
1185 start_pos /= 8;
1186 end_pos /= 8;
Value stored to 'end_pos' is never read
1187
1188 *pbc = pbc_tmp;
1189 err = cbs_av1_write_leb128(ctx, pbc, "obu_size", obu->obu_size,
1190 priv->fixed_obu_size_length);
1191 if (err < 0)
1192 goto error;
1193
1194 data_pos = put_bits_count(pbc) / 8;
1195 flush_put_bits(pbc);
1196 av_assert0(data_pos <= start_pos)do { if (!(data_pos <= start_pos)) { av_log(((void*)0), 0,
"Assertion %s failed at %s:%d\n", "data_pos <= start_pos"
, "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c", 1196
); abort(); } } while (0)
;
1197
1198 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)(-(28));
1204 }
1205
1206 if (obu->obu_size > 0) {
1207 if (!priv->fixed_obu_size_length) {
1208 memmove(pbc->buf + data_pos,
1209 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 skip_put_bytes(pbc, header_size);
1215
1216 if (td) {
1217 memcpy(pbc->buf + data_pos + header_size,
1218 td->data, td->data_size);
1219 skip_put_bytes(pbc, td->data_size);
1220 }
1221 }
1222
1223 // OBU data must be byte-aligned.
1224 av_assert0(put_bits_count(pbc) % 8 == 0)do { if (!(put_bits_count(pbc) % 8 == 0)) { av_log(((void*)0)
, 0, "Assertion %s failed at %s:%d\n", "put_bits_count(pbc) % 8 == 0"
, "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c", 1224
); abort(); } } while (0)
;
1225 err = 0;
1226
1227error:
1228 av_refstruct_unref(&av1ctx.sequence_header_ref);
1229 av_buffer_unref(&av1ctx.frame_header_ref);
1230
1231 return err;
1232#else
1233 return AVERROR(ENOSYS)(-(38));
1234#endif
1235}
1236
1237static int cbs_av1_assemble_fragment(CodedBitstreamContext *ctx,
1238 CodedBitstreamFragment *frag)
1239{
1240#if CBS_WRITE1
1241 size_t size, pos;
1242 int i;
1243
1244 size = 0;
1245 for (i = 0; i < frag->nb_units; i++)
1246 size += frag->units[i].data_size;
1247
1248 frag->data_ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE64);
1249 if (!frag->data_ref)
1250 return AVERROR(ENOMEM)(-(12));
1251 frag->data = frag->data_ref->data;
1252 memset(frag->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE64);
1253
1254 pos = 0;
1255 for (i = 0; i < frag->nb_units; i++) {
1256 memcpy(frag->data + pos, frag->units[i].data,
1257 frag->units[i].data_size);
1258 pos += frag->units[i].data_size;
1259 }
1260 av_assert0(pos == size)do { if (!(pos == size)) { av_log(((void*)0), 0, "Assertion %s failed at %s:%d\n"
, "pos == size", "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c"
, 1260); abort(); } } while (0)
;
1261 frag->data_size = size;
1262
1263 return 0;
1264#else
1265 return AVERROR(ENOSYS)(-(38));
1266#endif
1267}
1268
1269static av_cold__attribute__((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((void*)0);
1275 priv->frame_header = NULL((void*)0);
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
1283static av_cold__attribute__((cold)) void cbs_av1_close(CodedBitstreamContext *ctx)
1284{
1285 CodedBitstreamAV1Context *priv = ctx->priv_data;
1286
1287 av_refstruct_unref(&priv->sequence_header_ref);
1288 av_buffer_unref(&priv->frame_header_ref);
1289}
1290
1291#if CBS_AV1_OBU_METADATA1
1292static void cbs_av1_free_metadata(AVRefStructOpaque unused, void *content)
1293{
1294 AV1RawOBU *obu = content;
1295 AV1RawMetadata *md;
1296
1297 av_assert0(obu->header.obu_type == AV1_OBU_METADATA)do { if (!(obu->header.obu_type == AV1_OBU_METADATA)) { av_log
(((void*)0), 0, "Assertion %s failed at %s:%d\n", "obu->header.obu_type == AV1_OBU_METADATA"
, "/root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c", 1297
); abort(); } } while (0)
;
1298 md = &obu->obu.metadata;
1299
1300 switch (md->metadata_type) {
1301 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 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}
1313#endif
1314
1315static CodedBitstreamUnitTypeDescriptor cbs_av1_unit_types[] = {
1316 CBS_UNIT_TYPE_POD(AV1_OBU_SEQUENCE_HEADER, AV1RawOBU){ .nb_unit_types = 1, .unit_type.list = { AV1_OBU_SEQUENCE_HEADER
}, .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, .content_size
= sizeof(AV1RawOBU), .type.ref = { .nb_offsets = 0 }, }
,
1317 CBS_UNIT_TYPE_POD(AV1_OBU_TEMPORAL_DELIMITER, AV1RawOBU){ .nb_unit_types = 1, .unit_type.list = { AV1_OBU_TEMPORAL_DELIMITER
}, .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, .content_size
= sizeof(AV1RawOBU), .type.ref = { .nb_offsets = 0 }, }
,
1318 CBS_UNIT_TYPE_POD(AV1_OBU_FRAME_HEADER, AV1RawOBU){ .nb_unit_types = 1, .unit_type.list = { AV1_OBU_FRAME_HEADER
}, .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, .content_size
= sizeof(AV1RawOBU), .type.ref = { .nb_offsets = 0 }, }
,
1319 CBS_UNIT_TYPE_POD(AV1_OBU_REDUNDANT_FRAME_HEADER, AV1RawOBU){ .nb_unit_types = 1, .unit_type.list = { AV1_OBU_REDUNDANT_FRAME_HEADER
}, .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, .content_size
= sizeof(AV1RawOBU), .type.ref = { .nb_offsets = 0 }, }
,
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)__builtin_offsetof(AV1RawOBU, obu.tile_group.data),
1328 offsetof(AV1RawOBU, obu.tile_group.tile_data.data)__builtin_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)__builtin_offsetof(AV1RawOBU, obu.frame.tile_group.data),
1340 offsetof(AV1RawOBU, obu.frame.tile_group.tile_data.data)__builtin_offsetof(AV1RawOBU, obu.frame.tile_group.tile_data.
data)
}
1341 },
1342 },
1343#if CBS_AV1_OBU_TILE_LIST1
1344 CBS_UNIT_TYPE_INTERNAL_REF(AV1_OBU_TILE_LIST, AV1RawOBU,{ .nb_unit_types = (sizeof((CodedBitstreamUnitType[]){ AV1_OBU_TILE_LIST
}) / sizeof(((CodedBitstreamUnitType[]){ AV1_OBU_TILE_LIST }
)[0])), .unit_type.list = { AV1_OBU_TILE_LIST }, .content_type
= CBS_CONTENT_TYPE_INTERNAL_REFS, .content_size = sizeof(AV1RawOBU
), .type.ref = { .nb_offsets = 1, .offsets = { __builtin_offsetof
(AV1RawOBU, obu.tile_list.tile_data.data) } }, }
1345 obu.tile_list.tile_data.data){ .nb_unit_types = (sizeof((CodedBitstreamUnitType[]){ AV1_OBU_TILE_LIST
}) / sizeof(((CodedBitstreamUnitType[]){ AV1_OBU_TILE_LIST }
)[0])), .unit_type.list = { AV1_OBU_TILE_LIST }, .content_type
= CBS_CONTENT_TYPE_INTERNAL_REFS, .content_size = sizeof(AV1RawOBU
), .type.ref = { .nb_offsets = 1, .offsets = { __builtin_offsetof
(AV1RawOBU, obu.tile_list.tile_data.data) } }, }
,
1346#endif
1347#if CBS_AV1_OBU_PADDING1
1348 CBS_UNIT_TYPE_INTERNAL_REF(AV1_OBU_PADDING, AV1RawOBU,{ .nb_unit_types = (sizeof((CodedBitstreamUnitType[]){ AV1_OBU_PADDING
}) / sizeof(((CodedBitstreamUnitType[]){ AV1_OBU_PADDING })[
0])), .unit_type.list = { AV1_OBU_PADDING }, .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS
, .content_size = sizeof(AV1RawOBU), .type.ref = { .nb_offsets
= 1, .offsets = { __builtin_offsetof(AV1RawOBU, obu.padding.
payload) } }, }
1349 obu.padding.payload){ .nb_unit_types = (sizeof((CodedBitstreamUnitType[]){ AV1_OBU_PADDING
}) / sizeof(((CodedBitstreamUnitType[]){ AV1_OBU_PADDING })[
0])), .unit_type.list = { AV1_OBU_PADDING }, .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS
, .content_size = sizeof(AV1RawOBU), .type.ref = { .nb_offsets
= 1, .offsets = { __builtin_offsetof(AV1RawOBU, obu.padding.
payload) } }, }
,
1350#endif
1351
1352#if CBS_AV1_OBU_METADATA1
1353 CBS_UNIT_TYPE_COMPLEX(AV1_OBU_METADATA, AV1RawOBU,{ .nb_unit_types = (sizeof((CodedBitstreamUnitType[]){ AV1_OBU_METADATA
}) / sizeof(((CodedBitstreamUnitType[]){ AV1_OBU_METADATA })
[0])), .unit_type.list = { AV1_OBU_METADATA }, .content_type =
CBS_CONTENT_TYPE_COMPLEX, .content_size = sizeof(AV1RawOBU),
.type.complex = { .content_free = &cbs_av1_free_metadata
}, }
1354 &cbs_av1_free_metadata){ .nb_unit_types = (sizeof((CodedBitstreamUnitType[]){ AV1_OBU_METADATA
}) / sizeof(((CodedBitstreamUnitType[]){ AV1_OBU_METADATA })
[0])), .unit_type.list = { AV1_OBU_METADATA }, .content_type =
CBS_CONTENT_TYPE_COMPLEX, .content_size = sizeof(AV1RawOBU),
.type.complex = { .content_free = &cbs_av1_free_metadata
}, }
,
1355#endif
1356
1357 CBS_UNIT_TYPE_END_OF_LIST{ .nb_unit_types = 0 }
1358};
1359
1360#define OFFSET(x)__builtin_offsetof(CodedBitstreamAV1Context, x) offsetof(CodedBitstreamAV1Context, x)__builtin_offsetof(CodedBitstreamAV1Context, x)
1361static const AVOption cbs_av1_options[] = {
1362 { "operating_point", "Set operating point to select layers to parse from a scalable bitstream",
1363 OFFSET(operating_point)__builtin_offsetof(CodedBitstreamAV1Context, 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)__builtin_offsetof(CodedBitstreamAV1Context, fixed_obu_size_length
)
, AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8, 0 },
1366 { NULL((void*)0) }
1367};
1368
1369static 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((60)<<16 | (29)<<8 | (100)),
1374};
1375
1376const CodedBitstreamType CBS_FUNC(type_av1)ff_cbs_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};