Extends "conformance is a hash" to VIDEO. The float learned-video family (DCVC) propagates a float reference feature frame to frame, so ~1e-5 of drift compounds down the GOP and the reconstruction is reproducible only on the same build. This is the opposite: every frame is reconstructed by INTEGER block motion compensation from the previous reconstructed frame plus an INTEGER-quantized residual, no float anywhere — so each frame is byte-identical on every machine. Frame-state- equivalence: a per-frame portable hash, a whole clip you can put in a receipt. - src/int_video.rs (feature video_int, pure i64, wasm-ready): decode loop reads the residual symbols from the rANS stream (raster y,x,c); prediction is constant grey for the I-frame and prev[clamp(y+dy), clamp(x+dx)] per block for P-frames; frame = clamp(prediction + r·q, 0, 255). Dependency-free base64 for the rANS. - tools/wai_int_video_encode.py: encodes a deterministic clip — integer whole-pixel block-MC search against the previous *reconstructed* frame + quantized residual + CompressAI rANS (the byte-exact match of the Rust RansDecoder). Emits the bitstream + committed per-frame and whole-clip hashes. - Committed tiny vector (tests/vectors/int_video/, 5×48×48 RGB) + NEVER-skip test: decodes every frame to its committed FNV-1a + the clip hash 27573cdba1ad6628, byte-for-byte. Verified visually: the disc translates (MC works), decode exact. - Wired wai.video.int_motion (Lossy tier — quantized residual — StandardDefined replicate class — deterministic integer decode). SPEC table + capability comment. Co-Authored-By: Claude Opus 4.8 <[email protected]>
56 lines
2.3 KiB
Rust
56 lines
2.3 KiB
Rust
//! `wai.video.int_motion` — **frame-state-equivalence**: a deterministic integer
|
|
//! inter-frame codec reconstructs every frame byte-identically on every machine,
|
|
//! so each frame's hash (and the whole clip's) is portable. Committed vector under
|
|
//! `tests/vectors/int_video/`; never skips.
|
|
#![cfg(feature = "video_int")]
|
|
|
|
use std::path::PathBuf;
|
|
|
|
use wai::int_video::{decode, fnv1a};
|
|
|
|
fn dir() -> PathBuf {
|
|
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/vectors/int_video")
|
|
}
|
|
fn jload(name: &str) -> serde_json::Value {
|
|
serde_json::from_slice(&std::fs::read(dir().join(name)).unwrap()).unwrap()
|
|
}
|
|
|
|
#[test]
|
|
fn decodes_the_clip_byte_for_byte_frame_by_frame() {
|
|
// The committed integer bitstream (I-frame + integer-MC P-frames + quantized
|
|
// residual) decodes — no float anywhere — to the SAME frames the encoder
|
|
// produced, each verified by its own FNV-1a, plus the whole-clip hash.
|
|
let bs = jload("int_video_bitstream.json");
|
|
let conf = jload("int_video.json");
|
|
let clip = decode(&bs).expect("decode");
|
|
|
|
let (h, w) = (conf["h"].as_u64().unwrap() as usize, conf["w"].as_u64().unwrap() as usize);
|
|
let want_frames = conf["frame_hashes"].as_array().unwrap();
|
|
assert_eq!((clip.h, clip.w), (h, w));
|
|
assert_eq!(clip.frames.len(), want_frames.len(), "frame count");
|
|
|
|
let mut all = Vec::new();
|
|
for (i, frame) in clip.frames.iter().enumerate() {
|
|
assert_eq!(frame.len(), h * w * 3, "frame {i} size");
|
|
let got = format!("{:016x}", fnv1a(frame));
|
|
assert_eq!(got, want_frames[i].as_str().unwrap(), "frame {i} must reproduce its committed hash");
|
|
all.extend_from_slice(&hex16(&got));
|
|
}
|
|
// the whole-clip hash = FNV-1a over the concatenated frame-hash bytes
|
|
let clip_hash = format!("{:016x}", fnv1a(&all));
|
|
assert_eq!(clip_hash, conf["clip_hash"].as_str().unwrap(), "clip hash");
|
|
println!(
|
|
"int_video: {} frames {h}x{w} RGB -> per-frame byte-exact, clip {clip_hash}",
|
|
clip.frames.len()
|
|
);
|
|
}
|
|
|
|
/// The 8 bytes of a 16-hex string (the encoder hashes the concatenated raw
|
|
/// frame-hash bytes, not their hex text).
|
|
fn hex16(s: &str) -> [u8; 8] {
|
|
let mut o = [0u8; 8];
|
|
for (i, b) in o.iter_mut().enumerate() {
|
|
*b = u8::from_str_radix(&s[i * 2..i * 2 + 2], 16).unwrap();
|
|
}
|
|
o
|
|
}
|