D2c M4, gate 7 (delete). - int_hyper_synth::decode_conditional, the unchecked conditional decode, is deleted; its callers decode through decode_conditional_checked (the lowering, with its check ranges): the int_hyper_decode_frame example (step 3 of tools/wai_sota_vectors.sh), wai_decode_bench's tiny-vector case, int_payload's JSON-equivalence unit tests, tests/int_hyper_synth.rs, int_kernels_vectors.rs, int_video_keyframe.rs, int_video_sota_keyframe.rs, and byte-exact's neural_keyframe_golden (the trap: it gains the check ranges, outputs equal; gate 2's duplicate test through ops::decode goes). - The pretrained synthesis-only and hyper-decoder-only goldens (tests/int_hyper_synth.rs) are also held through the lowering. - The conditional codec's direct guard (legacy's run_checked) is test-only since gate 6. run_net_checked, check_layer and igdn_check stay: their one production caller left is int_mlicpp (M5); run_net and decode stay for the world renderer (M6), and int_hyper_synth's kernel_equivalence with them, since their conv dispatch is still run_net's. Docs say so. - Doc references (int_video, int_video_golden, two tools) and CHANGELOG. Co-Authored-By: Claude Opus 5.5 <[email protected]>
58 lines
2.7 KiB
Rust
58 lines
2.7 KiB
Rust
//! `wai.video.int_hyper` — the NEURAL-KEYFRAME inter-frame codec: the I-frame is
|
|
//! decoded by the learned integer codec `int_hyper`, the P-frames are integer
|
|
//! block-MC residuals on top. The whole decode is integer, so every frame is
|
|
//! byte-identical on every machine — a learned keyframe you can put in a receipt,
|
|
//! plus integer inter-frames. Composes the two committed tiny vectors; never skips.
|
|
#![cfg(all(feature = "neural_int", feature = "video_int"))]
|
|
|
|
use std::path::PathBuf;
|
|
|
|
use wai::int_hyper_synth::{decode_conditional_checked, CondBitstream, CondEntropy, IntModel};
|
|
use wai::int_video::{decode_pframes, fnv1a};
|
|
|
|
fn vroot() -> PathBuf {
|
|
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/vectors")
|
|
}
|
|
fn jload(p: &std::path::Path) -> serde_json::Value {
|
|
serde_json::from_slice(&std::fs::read(p).unwrap()).unwrap()
|
|
}
|
|
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
|
|
}
|
|
|
|
#[test]
|
|
fn neural_keyframe_clip_decodes_byte_for_byte() {
|
|
let ih = vroot().join("int_hyper");
|
|
let iv = vroot().join("int_video");
|
|
|
|
// frame 0: the learned int_hyper I-frame (the committed tiny conditional codec).
|
|
let g_s = IntModel::from_json(&jload(&ih.join("tiny_g_s.json")));
|
|
let h_s = IntModel::from_json(&jload(&ih.join("tiny_h_s.json")));
|
|
let ent = CondEntropy::from_value(&jload(&ih.join("tiny_entropy.json")));
|
|
let bs = CondBitstream::from_value(&jload(&ih.join("tiny_bitstream.json")));
|
|
let (frame0, h, w) = decode_conditional_checked(&g_s, &h_s, &ent, &bs.stream()).expect("int_hyper I-frame");
|
|
|
|
// frames 1..N: integer block-MC residuals on top.
|
|
let conf = jload(&iv.join("video_nk.json"));
|
|
let vbs = jload(&iv.join("video_nk_bitstream.json"));
|
|
let clip = decode_pframes(&frame0, h, w, &vbs).expect("p-frames");
|
|
|
|
let want = conf["frame_hashes"].as_array().unwrap();
|
|
assert_eq!(clip.frames.len(), want.len(), "frame count");
|
|
// frame 0's hash IS the int_hyper image hash — the keyframe is the learned codec.
|
|
assert_eq!(format!("{:016x}", fnv1a(&frame0)), want[0].as_str().unwrap(), "I-frame = int_hyper decode");
|
|
|
|
let mut all = Vec::new();
|
|
for (i, frame) in clip.frames.iter().enumerate() {
|
|
let got = format!("{:016x}", fnv1a(frame));
|
|
assert_eq!(got, want[i].as_str().unwrap(), "frame {i} must reproduce its committed hash");
|
|
all.extend_from_slice(&hex16(&got));
|
|
}
|
|
let clip_hash = format!("{:016x}", fnv1a(&all));
|
|
assert_eq!(clip_hash, conf["clip_hash"].as_str().unwrap(), "clip hash");
|
|
println!("int_hyper-keyframe video: {} frames {h}x{w}, I-frame={}, clip {clip_hash}", clip.frames.len(), &want[0].as_str().unwrap()[..8]);
|
|
}
|