Bug Summary

File:root/firefox-clang/media/ffvpx/libavcodec/cbs_av1.c
Warning:line 1190, 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-10-17-231001-351276-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 av_fallthrough__attribute__((fallthrough));
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
947 if (!priv->seen_frame_header)
948 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
949
950 err = cbs_av1_ref_tile_data(ctx, unit, &gbc,
951 &tile_group->data_ref,
952 &tile_group->data,
953 &tile_group->data_size);
954 if (err < 0)
955 return err;
956
957 err = cbs_av1_read_tile_group_obu(ctx, &gbc, tile_group);
958 if (err < 0)
959 return err;
960
961 err = cbs_av1_ref_tile_data(ctx, unit, &gbc,
962 &tile_group->tile_data.data_ref,
963 &tile_group->tile_data.data,
964 &tile_group->tile_data.data_size);
965 if (err < 0)
966 return err;
967 }
968 break;
969#if CBS_AV1_OBU_TILE_LIST1
970 case AV1_OBU_TILE_LIST:
971 {
972 err = cbs_av1_read_tile_list_obu(ctx, &gbc,
973 &obu->obu.tile_list);
974 if (err < 0)
975 return err;
976
977 err = cbs_av1_ref_tile_data(ctx, unit, &gbc,
978 &obu->obu.tile_list.tile_data.data_ref,
979 &obu->obu.tile_list.tile_data.data,
980 &obu->obu.tile_list.tile_data.data_size);
981 if (err < 0)
982 return err;
983 }
984 break;
985#endif
986#if CBS_AV1_OBU_METADATA1
987 case AV1_OBU_METADATA:
988 {
989 err = cbs_av1_read_metadata_obu(ctx, &gbc, &obu->obu.metadata);
990 if (err < 0)
991 return err;
992 }
993 break;
994#endif
995#if CBS_AV1_OBU_PADDING1
996 case AV1_OBU_PADDING:
997 {
998 err = cbs_av1_read_padding_obu(ctx, &gbc, &obu->obu.padding);
999 if (err < 0)
1000 return err;
1001 }
1002 break;
1003#endif
1004 default:
1005 return AVERROR(ENOSYS)(-(38));
1006 }
1007
1008 end_pos = get_bits_count(&gbc);
1009 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", 1009
); abort(); } } while (0)
;
1010
1011 if (obu->obu_size > 0 &&
1012 obu->header.obu_type != AV1_OBU_TILE_GROUP &&
1013 obu->header.obu_type != AV1_OBU_TILE_LIST &&
1014 obu->header.obu_type != AV1_OBU_FRAME) {
1015 int nb_bits = obu->obu_size * 8 + start_pos - end_pos;
1016
1017 if (nb_bits <= 0)
1018 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
1019
1020 err = cbs_av1_read_trailing_bits(ctx, &gbc, nb_bits);
1021 if (err < 0)
1022 return err;
1023 }
1024
1025 return 0;
1026#else
1027 return AVERROR(ENOSYS)(-(38));
1028#endif
1029}
1030
1031static int cbs_av1_write_obu(CodedBitstreamContext *ctx,
1032 CodedBitstreamUnit *unit,
1033 PutBitContext *pbc)
1034{
1035#if CBS_WRITE1
1036 CodedBitstreamAV1Context *priv = ctx->priv_data;
1037 AV1RawOBU *obu = unit->content;
1038 PutBitContext pbc_tmp;
1039 AV1RawTileData *td;
1040 size_t header_size;
1041 int err, start_pos, end_pos, data_pos;
1042 CodedBitstreamAV1Context av1ctx;
1043
1044 // OBUs in the normal bitstream format must contain a size field
1045 // in every OBU (in annex B it is optional, but we don't support
1046 // writing that).
1047 obu->header.obu_has_size_field = 1;
1048 av1ctx = *priv;
1049
1050 if (priv->sequence_header_ref) {
1051 av1ctx.sequence_header_ref = av_refstruct_ref(priv->sequence_header_ref);
1052 }
1053
1054 if (priv->frame_header_ref) {
1055 av1ctx.frame_header_ref = av_buffer_ref(priv->frame_header_ref);
1056 if (!av1ctx.frame_header_ref) {
1057 err = AVERROR(ENOMEM)(-(12));
1058 goto error;
1059 }
1060 }
1061
1062 err = cbs_av1_write_obu_header(ctx, pbc, &obu->header);
1063 if (err < 0)
1064 goto error;
1065
1066 if (obu->header.obu_has_size_field) {
1067 pbc_tmp = *pbc;
1068 if (priv->fixed_obu_size_length) {
1069 for (int i = 0; i < priv->fixed_obu_size_length; i++)
1070 put_bits(pbc, 8, 0);
1071 } else {
1072 // Add space for the size field to fill later.
1073 put_bits32(pbc, 0);
1074 put_bits32(pbc, 0);
1075 }
1076 }
1077
1078 td = NULL((void*)0);
1079 start_pos = put_bits_count(pbc);
1080
1081 switch (obu->header.obu_type) {
1082 case AV1_OBU_SEQUENCE_HEADER:
1083 {
1084 err = cbs_av1_write_sequence_header_obu(ctx, pbc,
1085 &obu->obu.sequence_header);
1086 if (err < 0)
1087 goto error;
1088
1089 av_refstruct_unref(&priv->sequence_header_ref);
1090 priv->sequence_header = NULL((void*)0);
1091
1092 err = CBS_FUNC(make_unit_refcounted)ff_cbs_make_unit_refcounted(ctx, unit);
1093 if (err < 0)
1094 goto error;
1095
1096 priv->sequence_header_ref = av_refstruct_ref(unit->content_ref);
1097 priv->sequence_header = &obu->obu.sequence_header;
1098 }
1099 break;
1100 case AV1_OBU_TEMPORAL_DELIMITER:
1101 {
1102 err = cbs_av1_write_temporal_delimiter_obu(ctx, pbc);
1103 if (err < 0)
1104 goto error;
1105 }
1106 break;
1107 case AV1_OBU_FRAME_HEADER:
1108 case AV1_OBU_REDUNDANT_FRAME_HEADER:
1109 {
1110 err = cbs_av1_write_frame_header_obu(ctx, pbc,
1111 &obu->obu.frame_header,
1112 obu->header.obu_type ==
1113 AV1_OBU_REDUNDANT_FRAME_HEADER,
1114 NULL((void*)0));
1115 if (err < 0)
1116 goto error;
1117 }
1118 break;
1119 case AV1_OBU_FRAME:
1120 err = cbs_av1_write_frame_obu(ctx, pbc, &obu->obu.frame, NULL((void*)0));
1121 if (err < 0)
1122 goto error;
1123 av_fallthrough__attribute__((fallthrough));
1124 case AV1_OBU_TILE_GROUP:
1125 {
1126 AV1RawTileGroup *tile_group = obu->header.obu_type == AV1_OBU_FRAME ? &obu->obu.frame.tile_group
1127 : &obu->obu.tile_group;
1128 err = cbs_av1_write_tile_group_obu(ctx, pbc, tile_group);
1129 if (err < 0)
1130 goto error;
1131
1132 td = &tile_group->tile_data;
1133 }
1134 break;
1135#if CBS_AV1_OBU_TILE_LIST1
1136 case AV1_OBU_TILE_LIST:
1137 {
1138 err = cbs_av1_write_tile_list_obu(ctx, pbc, &obu->obu.tile_list);
1139 if (err < 0)
1140 goto error;
1141
1142 td = &obu->obu.tile_list.tile_data;
1143 }
1144 break;
1145#endif
1146#if CBS_AV1_OBU_METADATA1
1147 case AV1_OBU_METADATA:
1148 {
1149 err = cbs_av1_write_metadata_obu(ctx, pbc, &obu->obu.metadata);
1150 if (err < 0)
1151 goto error;
1152 }
1153 break;
1154#endif
1155#if CBS_AV1_OBU_PADDING1
1156 case AV1_OBU_PADDING:
1157 {
1158 err = cbs_av1_write_padding_obu(ctx, pbc, &obu->obu.padding);
1159 if (err < 0)
1160 goto error;
1161 }
1162 break;
1163#endif
1164 default:
1165 err = AVERROR(ENOSYS)(-(38));
1166 goto error;
1167 }
1168
1169 end_pos = put_bits_count(pbc);
1170 header_size = (end_pos - start_pos + 7) / 8;
1171 if (td) {
1172 obu->obu_size = header_size + td->data_size;
1173 } else if (header_size > 0) {
1174 // Add trailing bits and recalculate.
1175 err = cbs_av1_write_trailing_bits(ctx, pbc, 8 - end_pos % 8);
1176 if (err < 0)
1177 goto error;
1178 end_pos = put_bits_count(pbc);
1179 obu->obu_size = header_size = (end_pos - start_pos + 7) / 8;
1180 } else {
1181 // Empty OBU.
1182 obu->obu_size = 0;
1183 }
1184
1185 end_pos = put_bits_count(pbc);
1186 // Must now be byte-aligned.
1187 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"
, 1187); abort(); } } while (0)
;
1188 flush_put_bits(pbc);
1189 start_pos /= 8;
1190 end_pos /= 8;
Value stored to 'end_pos' is never read
1191
1192 *pbc = pbc_tmp;
1193 err = cbs_av1_write_leb128(ctx, pbc, "obu_size", obu->obu_size,
1194 priv->fixed_obu_size_length);
1195 if (err < 0)
1196 goto error;
1197
1198 data_pos = put_bits_count(pbc) / 8;
1199 flush_put_bits(pbc);
1200 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", 1200
); abort(); } } while (0)
;
1201
1202 if (8 * obu->obu_size > put_bits_left(pbc)) {
1203 av_refstruct_unref(&priv->sequence_header_ref);
1204 av_buffer_unref(&priv->frame_header_ref);
1205 *priv = av1ctx;
1206
1207 return AVERROR(ENOSPC)(-(28));
1208 }
1209
1210 if (obu->obu_size > 0) {
1211 if (!priv->fixed_obu_size_length) {
1212 memmove(pbc->buf + data_pos,
1213 pbc->buf + start_pos, header_size);
1214 } else {
1215 // The size was fixed so the following data was
1216 // already written in the correct place.
1217 }
1218 skip_put_bytes(pbc, header_size);
1219
1220 if (td) {
1221 memcpy(pbc->buf + data_pos + header_size,
1222 td->data, td->data_size);
1223 skip_put_bytes(pbc, td->data_size);
1224 }
1225 }
1226
1227 // OBU data must be byte-aligned.
1228 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", 1228
); abort(); } } while (0)
;
1229 err = 0;
1230
1231error:
1232 av_refstruct_unref(&av1ctx.sequence_header_ref);
1233 av_buffer_unref(&av1ctx.frame_header_ref);
1234
1235 return err;
1236#else
1237 return AVERROR(ENOSYS)(-(38));
1238#endif
1239}
1240
1241static int cbs_av1_assemble_fragment(CodedBitstreamContext *ctx,
1242 CodedBitstreamFragment *frag)
1243{
1244#if CBS_WRITE1
1245 size_t size, pos;
1246 int i;
1247
1248 size = 0;
1249 for (i = 0; i < frag->nb_units; i++)
1250 size += frag->units[i].data_size;
1251
1252 frag->data_ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE64);
1253 if (!frag->data_ref)
1254 return AVERROR(ENOMEM)(-(12));
1255 frag->data = frag->data_ref->data;
1256 memset(frag->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE64);
1257
1258 pos = 0;
1259 for (i = 0; i < frag->nb_units; i++) {
1260 memcpy(frag->data + pos, frag->units[i].data,
1261 frag->units[i].data_size);
1262 pos += frag->units[i].data_size;
1263 }
1264 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"
, 1264); abort(); } } while (0)
;
1265 frag->data_size = size;
1266
1267 return 0;
1268#else
1269 return AVERROR(ENOSYS)(-(38));
1270#endif
1271}
1272
1273static av_cold__attribute__((cold)) void cbs_av1_flush(CodedBitstreamContext *ctx)
1274{
1275 CodedBitstreamAV1Context *priv = ctx->priv_data;
1276
1277 av_buffer_unref(&priv->frame_header_ref);
1278 priv->sequence_header = NULL((void*)0);
1279 priv->frame_header = NULL((void*)0);
1280
1281 memset(priv->ref, 0, sizeof(priv->ref));
1282 priv->operating_point_idc = 0;
1283 priv->seen_frame_header = 0;
1284 priv->tile_num = 0;
1285}
1286
1287static av_cold__attribute__((cold)) void cbs_av1_close(CodedBitstreamContext *ctx)
1288{
1289 CodedBitstreamAV1Context *priv = ctx->priv_data;
1290
1291 av_refstruct_unref(&priv->sequence_header_ref);
1292 av_buffer_unref(&priv->frame_header_ref);
1293}
1294
1295#if CBS_AV1_OBU_METADATA1
1296static void cbs_av1_free_metadata(AVRefStructOpaque unused, void *content)
1297{
1298 AV1RawOBU *obu = content;
1299 AV1RawMetadata *md;
1300
1301 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", 1301
); abort(); } } while (0)
;
1302 md = &obu->obu.metadata;
1303
1304 switch (md->metadata_type) {
1305 case AV1_METADATA_TYPE_HDR_CLL:
1306 case AV1_METADATA_TYPE_HDR_MDCV:
1307 case AV1_METADATA_TYPE_SCALABILITY:
1308 case AV1_METADATA_TYPE_TIMECODE:
1309 break;
1310 case AV1_METADATA_TYPE_ITUT_T35:
1311 av_buffer_unref(&md->metadata.itut_t35.payload_ref);
1312 break;
1313 default:
1314 av_buffer_unref(&md->metadata.unknown.payload_ref);
1315 }
1316}
1317#endif
1318
1319static CodedBitstreamUnitTypeDescriptor cbs_av1_unit_types[] = {
1320 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 }, }
,
1321 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 }, }
,
1322 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 }, }
,
1323 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 }, }
,
1324 {
1325 .nb_unit_types = 1,
1326 .unit_type.list[0] = AV1_OBU_TILE_GROUP,
1327 .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS,
1328 .content_size = sizeof(AV1RawOBU),
1329 .type.ref = {
1330 .nb_offsets = 2,
1331 .offsets = { offsetof(AV1RawOBU, obu.tile_group.data)__builtin_offsetof(AV1RawOBU, obu.tile_group.data),
1332 offsetof(AV1RawOBU, obu.tile_group.tile_data.data)__builtin_offsetof(AV1RawOBU, obu.tile_group.tile_data.data) }
1333 },
1334 },
1335
1336 {
1337 .nb_unit_types = 1,
1338 .unit_type.list[0] = AV1_OBU_FRAME,
1339 .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS,
1340 .content_size = sizeof(AV1RawOBU),
1341 .type.ref = {
1342 .nb_offsets = 2,
1343 .offsets = { offsetof(AV1RawOBU, obu.frame.tile_group.data)__builtin_offsetof(AV1RawOBU, obu.frame.tile_group.data),
1344 offsetof(AV1RawOBU, obu.frame.tile_group.tile_data.data)__builtin_offsetof(AV1RawOBU, obu.frame.tile_group.tile_data.
data)
}
1345 },
1346 },
1347#if CBS_AV1_OBU_TILE_LIST1
1348 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) } }, }
1349 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) } }, }
,
1350#endif
1351#if CBS_AV1_OBU_PADDING1
1352 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) } }, }
1353 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) } }, }
,
1354#endif
1355
1356#if CBS_AV1_OBU_METADATA1
1357 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
}, }
1358 &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
}, }
,
1359#endif
1360
1361 CBS_UNIT_TYPE_END_OF_LIST{ .nb_unit_types = 0 }
1362};
1363
1364#define OFFSET(x)__builtin_offsetof(CodedBitstreamAV1Context, x) offsetof(CodedBitstreamAV1Context, x)__builtin_offsetof(CodedBitstreamAV1Context, x)
1365static const AVOption cbs_av1_options[] = {
1366 { "operating_point", "Set operating point to select layers to parse from a scalable bitstream",
1367 OFFSET(operating_point)__builtin_offsetof(CodedBitstreamAV1Context, operating_point), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, AV1_MAX_OPERATING_POINTS - 1, 0 },
1368 { "fixed_obu_size_length", "Set fixed length of the obu_size field",
1369 OFFSET(fixed_obu_size_length)__builtin_offsetof(CodedBitstreamAV1Context, fixed_obu_size_length
)
, AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8, 0 },
1370 { NULL((void*)0) }
1371};
1372
1373static const AVClass cbs_av1_class = {
1374 .class_name = "cbs_av1",
1375 .item_name = av_default_item_name,
1376 .option = cbs_av1_options,
1377 .version = LIBAVUTIL_VERSION_INT((61)<<16 | (1)<<8 | (101)),
1378};
1379
1380const CodedBitstreamType CBS_FUNC(type_av1)ff_cbs_type_av1 = {
1381 .codec_id = AV_CODEC_ID_AV1,
1382
1383 .priv_class = &cbs_av1_class,
1384 .priv_data_size = sizeof(CodedBitstreamAV1Context),
1385
1386 .unit_types = cbs_av1_unit_types,
1387
1388 .split_fragment = &cbs_av1_split_fragment,
1389 .read_unit = &cbs_av1_read_unit,
1390 .write_unit = &cbs_av1_write_obu,
1391 .assemble_fragment = &cbs_av1_assemble_fragment,
1392
1393 .flush = &cbs_av1_flush,
1394 .close = &cbs_av1_close,
1395};