# filmcraft-apv Clean-room Advanced Professional Video (APV) decoder and encoder in pure Rust, implemented strictly from the public **IETF RFC 9924** specification (*Advanced Professional Video*, February 2026, ISSN 2070-1721). Layer L0: depends only on `filmcraft-bitstream`, `thiserror`, and (optional, feature `threads`, default on) `rayon`. Builds for `wasm32-unknown-unknown`; `unsafe_code = "forbid"`. ## API ```rust use filmcraft_apv::*; // Decode one APV Access Unit (or raw bitstream AU prefixed with a 32-bit au_size). let frame: Frame = decode_frame(&au)?; let f8 = decode_frame_with(&au, &DecodeOptions { bit_depth: Some(8), threads: true })?; decode_frame_into(&au, &DecodeOptions::default(), &mut frame_buf)?; let hdr: FrameHeader = probe(&au)?; // Split a multi-AU raw .apv bitstream (RFC 9924 Appendix A). let aus: Vec<&[u8]> = split_raw_bitstream(&raw_apv_bytes)?; // Encode progressive intra frames. let mut enc = Encoder::new(Profile::P422_10, 1920, 1080)?; let au: Vec = enc.encode(&frame)?; // Access Unit starting with 'aPv1' let raw_au: Vec = enc.encode_raw_au(&frame)?; // Prefixed with 32-bit au_size (ISOBMFF apv1 / .apv) let apvc: Vec = enc.decoder_config_record(); // APVDecoderConfigurationRecord payload ``` ## Specification Coverage (IETF RFC 9924) ### Decoder - **Access Units & PBUs (§5.3.1–5.3.3, Appendix A)**: Accepts both unprefixed Access Units (`'aPv1'` signature) and length-prefixed `raw_bitstream_access_unit()` packets. Parses primary (`pbu_type == 1`), non-primary (`2`), preview (`25`), auxiliary alpha (`27`), AU info (`65`), metadata (`66`), and filler (`67`) PBUs. PBUs or frame headers with non-zero `reserved_zero_*` fields are ignored per §5.3.3 and §5.3.5. - **Profiles & Sampling (§9.3)**: All 7 standard profiles (`422-10` idc 33, `422-12` idc 44, `444-10` idc 55, `444-12` idc 66, `4444-10` idc 77, `4444-12` idc 88, `400-10` idc 99) at coded bit depths 10–16, with optional output depth rescaling (`8..=16`). - **Quantization Matrices & Tiles (§5.3.7–5.3.8, §5.3.12–5.3.14)**: Default flat (`16`) and custom per-component 8×8 quantization matrices (`use_q_matrix`), optional `tile_size_in_fh` verification, and independent per-tile, per-component byte-aligned entropy partitions. Tiles decode in parallel via `rayon` when `threads` is enabled. - **Entropy Decoding (§5.3.15–5.3.16, §7.1)**: Adaptive Golomb-Rice / Exp-Golomb VLC decoding for `abs_dc_coeff_diff`, `coeff_zero_run`, and `abs_ac_coeff_minus1` with state tracking (`PrevDC`, `PrevDcDiff`, `Prev1stAcLevel`, `PrevLevel`, `PrevRun`) across the 8×8 blocks of each macroblock. - **Scaling & Inverse Transform (§6.3)**: Exact integer dequantization (`levelScale = [40, 45, 51, 57, 64, 71]`, `bdShift = BitDepth - 2`) and 2-D separable 8×8 integer inverse transform using the RFC 9924 Figure 25 `transMatrix`. Note: in RFC 9924 §6.3.2.2, `transMatrix[m][n]` has row `m` as the frequency index (row 0 is `[64; 8]`) and column `n` as the spatial sample index, so the 1-D inverse transform evaluates `sum_j transMatrix[j][i] * x[j]`. - **Metadata (§8)**: Parses `metadata_mdcv` (`payloadType == 5`, Mastering Display Color Volume) and `metadata_cll` (`payloadType == 6`, Content Light-Level Information). - **Robustness (§10)**: All size fields, tile coordinates, VLC codeword lengths, and coefficient ranges (`-32768..=32767`) are checked before allocation or shift. Verified by `tests/fuzz.rs` across thousands of mutated and random inputs. ### Encoder - Progressive intra encoding for all 7 profiles (`422-10`, `422-12`, `444-10`, `444-12`, `4444-10`, `4444-12`, `400-10`). - Supports fixed `qp` or binary-search frame-budget rate control over forward-transformed tiles. - Emits conforming tile grids (`tile_width_in_mbs >= 16`, `tile_height_in_mbs >= 8`, `TileCols, TileRows <= 20`), optional custom quantization matrices, optional `MDCV`/`CLL` metadata PBUs, and `APVDecoderConfigurationRecord` (`apvC`) metadata. ## Accuracy (vs FFmpeg as an External Oracle) `tests/oracle.rs` encodes synthetic test patterns across all 7 profiles, odd dimensions, multiple tiles, custom asymmetric quantization matrices, and HDR metadata PBUs, then decodes the resulting `.apv` streams with `ffmpeg -v error -xerror -f apv` and compares against `filmcraft_apv::decode_frame`. Because APV specifies an exact integer inverse transform, **`filmcraft-apv` is 100% bit-exact (`max_diff = 0`) with FFmpeg's APV decoder across every profile and test case.**