* av1enc: motion search with a visited set and early-exit SAD, fixed-size SATD, region-only BlockDecoded snapshot - motion_search remembered nothing: the diamond search evaluated the previous centre again and every SAD ran to the last row even when it had already lost. Full-sample and sub-sample positions are now tracked in a visited list (costs are deterministic, so a position that was evaluated cannot beat the best cost again), and the SAD stops after a row once sad + mv cost can no longer be below the best cost. The stop test is the same f64 expression as the strict "<" the callers apply, and it is monotone in the SAD, so the chosen vector is the same. - satd runs with a fixed block size (satd_k::<4> / satd_k::<8>): the difference block is a [[i32; K]; K], the vertical butterflies work on whole rows at once, and the old per-column gather is gone. The sum is an integer sum of the same values. - A snapshot copies only the BlockDecoded cells of the block area (at most 16x16 per plane), the only flags coding inside the block can change, instead of the whole 3x35x35 array. The encoded stream is unchanged. A unit test compares the new SATD with the previous implementation for 4..32 sample blocks at 8 and 10 bit. Fixes #2387 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * av1enc: tests for the region-only BlockDecoded snapshot and the bounded SADs - `snapshot_restore_brings_back_every_blockdecoded_flag`: for every block size of a 64x64 superblock (4x4 .. 64x64) at every aligned position in two superblocks, from an all-clear and a random flag state, marking every sub-block of every size inside the block and restoring gives back the whole 3x35x35 array, so the 16x16 region covers every flag coding can set and leaves the neighbours alone. - `bounded_sad_stops_only_once_the_cost_cannot_win`: `sad_ref` and `sad_bounded` return the full SAD whenever `sad + lb < bound`, and otherwise a partial sum that already loses the strict `<` of the callers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com> Co-authored-by: Codex <noreply@openai.com> Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
effectcraft-av1enc
Clean-room, pure-Rust AV1 encoder for EffectCraft's MP4 / WebM export (layer L0, std only,
no unsafe, builds for wasm32-unknown-unknown).
Output is decoded bit-exactly by libdav1d (ffmpeg -c:v libdav1d, checked in
tests/it/ffmpeg_oracle.rs when ffmpeg is installed) and by FilmCraft's spec-derived
filmcraft-av1 decoder (tests/it/roundtrip.rs): every decoded frame equals the encoder's own
reconstruction, so prediction never drifts.
What is implemented
- Stream: Main profile (
seq_profile0), 4:2:0, 8 or 10 bit, BT.709 colour description, limited or full range. Sequence header with one operating point;seq_level_idxgiven or the lowest Annex A level whose MaxPicSize / MaxH/VSize / MaxDisplayRate (and, in bitrate mode, Main tier MaxBitrate) fit. Order hints, film grain, superres, CDEF, loop restoration, intra edge filter, filter intra, inter-intra, masked / distance compound, warped motion and dual filter are disabled in the sequence header. - Packets: one temporal unit per frame as stored in MP4 / Matroska samples: OBUs with size
fields, no temporal delimiter; key frames start with the sequence header OBU, followed by one
OBU_FRAME(frame header + tile group). Every frame is shown, in input order.Encoder::av1c()returns theAV1CodecConfigurationRecord(also the WebMCodecPrivate). - Frames: a
KEY_FRAMEeverykeyintframes,INTER_FRAMEs otherwise. Inter frames use slot 0 (the previous reconstruction) for all seven references and refresh slot 0 only, soLAST_FRAMEis always the previous frame. CDFs adapt per symbol and are saved at the end of every frame; inter frames load them fromLAST_FRAME(primary_ref_frame= 0). One tile,TX_MODE_LARGEST,reduced_tx_set, no segmentation, no delta q / lf. - Deblocking: the normative loop filter (7.14) runs on the reconstruction; the frame level (the same for both luma directions and both chroma planes, no deltas, sharpness 0) is searched per frame for the lowest luma error.
- Tiles: the multi-symbol arithmetic encoder is the exact inverse of the spec's symbol decoder (8.2), including the exit process padding; CDF adaptation as in 8.2.6.
- Partitions: 64x64 superblocks,
PARTITION_NONE/PARTITION_SPLITdown to 8x8 chosen by a rate-distortion cost (SSE + λ·estimated bits); blocks crossing the frame edge are split as the syntax requires. 64x64 blocks are only used as inter skip blocks. - Intra: DC, V, H, Paeth, smooth, smooth-V, smooth-H for luma and chroma, ranked by SATD with a rate-distortion choice among the best three; the spec's edge preparation and above-right / below-left availability.
- Inter: single reference (
LAST_FRAME),NEWMV/NEARESTMV/NEARMV/GLOBALMVchosen from the spec's motion vector prediction stack (7.10.2, mirrored exactly); motion search from neighbour / co-located / parent candidates, a whole-sample diamond search and half- then quarter-sample refinement (allow_high_precision_mv= 0); the normative 8-tapEIGHTTAPprediction for luma and chroma; skip blocks; per-block intra / inter choice. - Residual: one transform per plane and block (4x4 ... 32x32): for intra luma
DCT_DCTor the mode's preferredADSTcombination (rate-distortion choice over the two best modes), the mode-dependent type for intra chroma,DCT_DCTfor inter blocks; dead-zone quantisation with the spec'sDc_Qlookup/Ac_Qlookup; the normative dequantisation and inverse transforms in the reconstruction loop; full coefficient coding (all_zero, tx type, eob_pt, eob_extra, coeff_base_eob, coeff_base, coeff_br, dc_sign, Golomb) with the exact contexts. - Rate control:
ConstantQ(base_q_idx);Bitrate { kbps }adaptsbase_q_idxper frame towards the average target (key frames get a lower quantizer and a larger share of the budget of their group ofkeyintframes, the inter frames the rest; the first key frame is searched in a few passes, a later key frame that misses its budget by more than 19 % is coded again; the deviation from the budget is paid back over 16 frames).
Limits
- One tile: width and height up to 4096 and at most 2304 superblocks (4096x2304 samples).
- No CDEF or loop restoration, no compound prediction, no rectangular or 4xN blocks, no directional intra modes other than V / H, no CfL or palette, no transform-size splits, so compression is below mature encoders.
- 4:2:0 only (Main profile), no 12 bit.
Specification and provenance
Implemented from the AV1 Bitstream & Decoding Process Specification, version 1.0.0 with
Errata 1 (AOMediaCodec, 2019; the edition FilmCraft's decoder follows) and the AV1 Codec
ISO Media File Format Binding (v1.2.0) for av1C.
The constant tables (default CDFs, scan orders, quantizer lookup tables, interpolation filter
taps, smooth weights, block / transform size tables, ...) and the decoder-side processes the
encoder must reproduce exactly (inverse transforms, intra and inter prediction rounding, context
derivations, motion vector prediction) are mirrored from FilmCraft's first-party, spec-derived
filmcraft-av1 decoder (MIT OR Apache-2.0), which is also the round-trip oracle. No source of
libaom, dav1d, rav1e, SVT-AV1, ffmpeg or any other third-party encoder or decoder was consulted;
ffmpeg / libdav1d is used only as an external test oracle.