AV2 loop restoration (NS-Wiener / PC-Wiener) — dav2d obu.c restoration parse state +
decode.c per-SB unit syntax + lr_apply_tmpl.c / looprestoration_tmpl.c collapsed to a
whole-frame pass. The dav stripe/row-backup machinery exists because dav filters in
place; the filter only ever READS pre-LR pixels (rows below the cursor are unfiltered,
rows above come from backups, left/right strips from pre-LR borders), so with a full
pre-wiener snapshot the pass is a pure src→dst transform with two boundary rules:
AV2 quantization matrices (QM): predefined-matrix lookup + the per-position dequant
weighting. Ports of avm quant_common.c (av2_qm_init layout / av2_iqmatrix /
av2_get_adjusted_tx_size) and decodetxb.c get_dqv:
dqv’ = (iqm[pos] * dqv + (1 << (AVM_QM_BITS-1))) >> AVM_QM_BITS, AVM_QM_BITS = 5.
QM applies to 2D transforms only (avm av2_get_iqmatrix: 1D/identity transforms use the
flat matrix = no weighting). 64-dim transforms reuse the 32-dim matrix
(av2_get_adjusted_tx_size) — their coded coefficient grid is the 32-clamped corner.
PANIC-FREEDOM: this module is compiled under #![deny(clippy::indexing_slicing)] (see the
attribute below) — every element access is a checked accessor, so no bounds panic is
reachable here BY CONSTRUCTION rather than by review or fuzzing. This is the pattern the
rest of the decode path should adopt module by module.
User-defined matrices (QM OBU payload) are NOT ported (loud error at the parse; every
avmenc mint so far signals no QM OBU and the decoder-default predefined list is used).