nx_av1_ec.nx
buildroot/runtime/nx_av1_ec.nx
about
nx_av1_ec.nx -- the AV1/AV2 multi-symbol CDF arithmetic decoder.
THE MOAT FOUNDATION. AV1, AVIF and AV2 all rest on this one primitive: a
multi-symbol (not binary) arithmetic coder whose probability tables ADAPT
as they decode. Nothing in this tree had it. nx_rangecoder.nx is the older
BINARY range coder (CABAC/VP8 class) -- it cannot decode AV1, because AV1
draws an N-ary symbol per call against a cumulative distribution rather
than a sequence of bits against a single probability.
AV2 v1.0.0 (spec frozen 2026-05-28) inherits this coder essentially intact,
so this module is the shared substrate for both. Build it once, correctly.
CDF CONVENTION -- FORWARD, PER THE SPEC. cdf[i] is the cumulative
probability of symbols <= i scaled to 32768, so the array INCREASES and
cdf[N-1] == 32768. libaom stores the INVERSE internally (32768 minus this,
decreasing to 0) and its update formula is written for that form. Mixing
the two is the classic porting error and it is nearly invisible: the
terminating entry agrees under BOTH conventions, so the first symbol of a
stream often decodes correctly and everything after it diverges. This file
is spec-form throughout; do not paste libaom arithmetic into it.
THE TRAILING SLOT. cdf has N+1 entries: N probabilities plus a COUNTER at
cdf[N] that tracks how many times this context has been used. The counter
drives the adaptation rate -- a fresh context adapts fast, a mature one
slowly. Dropping it (sizing the array at N) both breaks adaptation and
writes one past the end.
genealogy_id: av1_spec_8_3_symbol_decoder
lineage_id: nx_av1_ec_v1
license_tier: ORIGINAL
dependencies 2 imports · 1 importers
imports: nx_syscalls.nxnx_bitstream.nx
imported by: nx_av1_ec_gate.nx
structs
| 38 | struct NxAv1Ec |
consts
| 35 | const NX_AV1_CDF_TOTAL: i64 = 32768 |
| 36 | const NX_AV1_EC_BYTES: i64 = 40 |
functions
| 49 | func nx_av1_floor_log2(v: i64) -> i64 |
| 57 | func nx_av1_min(a: i64, b: i64) -> i64 { if a < b { return a } return b } |
| 58 | func nx_av1_max(a: i64, b: i64) -> i64 { if a > b { return a } return b } called by 1: nx_av1_ec_renorm |
| 67 | func nx_av1_ec_init(bs: *NxBitStream, sz: i64) -> *NxAv1Ec |
| 87 | func nx_av1_ec_renorm(ec: *NxAv1Ec) -> i64 called by 1: nx_av1_decode_symbol calls 4: nx_av1_floor_log2nx_av1_minnx_av1_maxnx_bitstream_read_msb |
| 108 | func nx_av1_decode_symbol(ec: *NxAv1Ec, cdf: *i64, n: i64) -> i64 |
| 142 | func nx_av1_update_cdf(cdf: *i64, symbol: i64, n: i64) -> i64 |
| 172 | func nx_av1_cdf_uniform(n: i64) -> *i64 |