nx_av1_obu.nx
buildroot/runtime/nx_av1_obu.nx
about
nx_av1_obu.nx -- AV1/AV2 OBU layer: reader and writer.
The layer directly above nx_av1_ec.nx. Every AV1 and AV2 bitstream is a
sequence of Open Bitstream Units, each a 1-2 byte header plus an optional
LEB128 size. AVIF's still-picture path uses the same units. Written both
directions so it proves by round-trip.
LEB128 IS UNSIGNED AND LITTLE-ENDIAN BY GROUP. Seven payload bits per byte,
low group first, high bit as the continuation flag. AV1 caps it at 8 bytes.
The natural mistake is to stop at the first byte with the high bit clear
WITHOUT bounding the count -- a hostile stream then walks the parser off
the buffer one byte at a time.
THE TWO RESERVED BITS ARE NOT DECORATION. obu_forbidden_bit must be 0 and
obu_reserved_1bit must be 0. A parser that ignores them will happily
consume arbitrary bytes as OBU headers and resynchronise onto garbage,
which is exactly how a fuzzer turns a malformed file into a long walk
through memory. Both are REFUSED here.
UVLC IS NOT LEB128. Frame headers use an Exp-Golomb-style variable code
read MSB-first off the bitstream: leading zeros, then that many value bits,
biased by (1 << zeros) - 1. Confusing the two silently misreads every frame
header field after the first.
genealogy_id: av1_spec_5_3_obu
lineage_id: nx_av1_obu_v1
license_tier: ORIGINAL
dependencies 2 imports · 1 importers
imports: nx_syscalls.nxnx_bitstream.nx
imported by: nx_av1_obu_gate.nx
structs
| none |
consts
| 32 | const NX_OBU_MAX_LEB: i64 = 8 |
| 33 | const NX_OBU_SEQ_HEADER: i64 = 1 |
| 34 | const NX_OBU_TEMPORAL_DELIM: i64 = 2 |
| 35 | const NX_OBU_FRAME_HEADER: i64 = 3 |
| 36 | const NX_OBU_TILE_GROUP: i64 = 4 |
| 37 | const NX_OBU_METADATA: i64 = 5 |
| 38 | const NX_OBU_FRAME: i64 = 6 |
| 39 | const NX_OBU_PADDING: i64 = 15 |
| 42 | const NX_OBU_FLD_TYPE: i64 = 0 |
| 43 | const NX_OBU_FLD_EXTFLAG: i64 = 1 |
| 44 | const NX_OBU_FLD_HASSIZE: i64 = 2 |
| 45 | const NX_OBU_FLD_TEMPORAL: i64 = 3 |
| 46 | const NX_OBU_FLD_SPATIAL: i64 = 4 |
| 47 | const NX_OBU_FLD_PAYOFF: i64 = 5 |
| 48 | const NX_OBU_FLD_PAYLEN: i64 = 6 |
| 49 | const NX_OBU_FLD_NEXT: i64 = 7 |
functions
| 56 | func nx_obu_leb128_read(d: *u8, n: i64, off: i64, out_len: *i64) -> i64 |
| 72 | func nx_obu_leb128_write(out: *u8, cap: i64, off: i64, v: i64) -> i64 |
| 94 | func nx_obu_uvlc(bs: *NxBitStream) -> i64 |
| 116 | func nx_obu_parse(d: *u8, n: i64, off: i64, fld: *i64) -> i64 |
| 164 | func nx_obu_write(out: *u8, cap: i64, off: i64, otype: i64, tid: i64, sid: i64, |
| 199 | func nx_obu_count(d: *u8, n: i64) -> i64 |