//! `wai.video.encode` (extensions/platform-encode.md): the committed corpus //! `encode-conformance/` regenerates byte for byte from its pinned fixture streams and decoded //! pictures, every case gets the outcome it states, every record reason of §12 is in it, and //! §12 lists exactly the reasons the reference reports. Where the platform's media framework is built in (macOS), an //! encode through it of each codec holds to §4.3, signs a record that verifies, and decodes in //! the platform's decoder to one picture per frame, and `wai_encode_measure run` signs the //! quality of that decode; a host with no hardware engine fails those tests rather than //! skipping them. #![cfg(feature = "platform_encode")] use std::collections::{BTreeMap, BTreeSet}; use std::path::PathBuf; use wai::platform_encode::{corpus, record::Reason, sha256_hex}; fn dir() -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../encode-conformance") } fn streams() -> BTreeMap> { corpus::FIXTURES.iter().map(|f| (f.file.to_string(), std::fs::read(dir().join("streams").join(f.file)).expect("a fixture stream"))).collect() } fn decoded() -> BTreeMap> { corpus::DECODED.iter().map(|d| (d.file.to_string(), std::fs::read(dir().join("decoded").join(d.file)).expect("decoded pictures"))).collect() } #[test] fn the_fixture_streams_are_the_pinned_bytes() { let pins: serde_json::Value = serde_json::from_slice(&std::fs::read(dir().join("streams.json")).expect("streams.json")).expect("JSON"); let s = streams(); assert_eq!(pins.as_object().expect("an object").len(), s.len(), "streams.json pins every fixture and nothing else"); for (k, v) in &s { assert_eq!(pins[k].as_str(), Some(sha256_hex(v).as_str()), "{k} is not the bytes streams.json pins"); } let pins: serde_json::Value = serde_json::from_slice(&std::fs::read(dir().join("decoded.json")).expect("decoded.json")).expect("JSON"); let d = decoded(); assert_eq!(pins.as_object().expect("an object").len(), d.len(), "decoded.json pins every decoded fixture and nothing else"); for (k, v) in &d { assert_eq!(pins[k].as_str(), Some(sha256_hex(v).as_str()), "{k} is not the bytes decoded.json pins"); } let held: BTreeSet = std::fs::read_dir(dir().join("decoded")).expect("decoded/").flatten().map(|e| e.file_name().to_string_lossy().into_owned()).collect(); assert_eq!(held, d.keys().cloned().collect::>(), "decoded/ holds the decoded fixtures and nothing else"); } #[test] fn the_committed_corpus_regenerates_byte_for_byte() { let generated = corpus::generate(&streams(), &decoded()); for (p, b) in &generated { assert_eq!(std::fs::read(dir().join(p)).ok().as_ref(), Some(b), "{p} does not regenerate: run `wai_encode_vectors gen`"); } for sub in ["records", "mutated", "handed"] { for e in std::fs::read_dir(dir().join(sub)).expect("the corpus").flatten() { let rel = format!("{sub}/{}", e.file_name().to_string_lossy()); assert!(generated.contains_key(&rel), "{rel} is not generated"); } } } #[test] fn every_case_gets_its_outcome_and_every_reason_appears() { assert!(corpus::check(&dir()).is_ok(), "{:?}", corpus::check(&dir())); let cases = corpus::cases(&streams(), &decoded()); let seen: BTreeSet<&str> = cases.iter().filter_map(|c| c.expect.map(Reason::code)).collect(); // The rendition's reason is the packager's corpus's (wai-pack tests/encode_rung.rs). let want: BTreeSet<&str> = Reason::ALL.iter().map(|r| r.code()).filter(|c| *c != "encode-package-mismatch").collect(); assert_eq!(seen, want, "every record reason but the rendition's has a case"); assert!(cases.iter().filter(|c| c.expect.is_none()).count() >= corpus::FIXTURES.len(), "every fixture is accepted"); // The quality figures are checked: an accepted record states them over held pictures, and // its verdict says what they rest on, each of the three words reached. assert!(cases.iter().any(|c| c.expect.is_none() && c.decoded.is_some() && c.record.contains("\"quality\":{")), "a record with quality is accepted with its pictures held"); let words: BTreeSet<&str> = cases.iter().filter_map(|c| c.quality).collect(); assert_eq!(words, BTreeSet::from(["decoded", "handed", "stated"]), "a verdict reaches each of §7's words"); // `null` is not measured: accepted with pictures held, which have no figures to hold to. assert!(cases.iter().any(|c| c.expect.is_none() && c.decoded.is_some() && c.quality.is_none() && c.record.contains("\"quality\":null")), "a record stating null is accepted, and its verdict names nothing"); } /// Pictures handed over prove nothing of the stream (§7): a record stating a perfect score its /// stream does not give holds against the encoder's own input, is `handed` and not `decoded`, /// and is refused the moment the pictures are what the stream decodes to. #[test] fn only_a_decode_of_the_held_stream_makes_the_figures_the_streams() { use wai::platform_encode::record::{self, Held, Pictures, QualityBasis}; let d = dir(); let read = |p: &str| std::fs::read(d.join(p)).expect("a corpus file"); let text = String::from_utf8(read("records/accept-quality-own-pictures-software-avc-128x72.json")).expect("a record"); let v: serde_json::Value = serde_json::from_str(&text).expect("JSON"); assert_eq!((v["quality"]["sse_y"].as_str(), v["quality"]["ssim_y_q32"].as_str()), (Some("0"), Some("4294967296")), "the figures of the encoder's own input"); let stream = read("streams/software-avc-128x72.h264"); let (hd, frames) = wai::platform_encode::y4m::read_all(&read("source.y4m")).expect("the source"); let planes = frames.concat(); let held = Held { stream: Some(&stream), source: Some((&hd, &planes)) }; let own = read("handed/software-avc-128x72.yuv"); let real = read("decoded/software-avc-128x72.yuv"); assert_eq!(record::verify_with(&text, &held, Some(Pictures::Handed(&own))).expect("the figures are the pictures'").quality, QualityBasis::Handed); assert_eq!(record::verify_with(&text, &held, Some(Pictures::Handed(&real))).map(|v| v.quality), Err(Reason::QualityMismatch)); assert_eq!(record::verify_with(&text, &held, Some(Pictures::Decoded(&real))).map(|v| v.quality), Err(Reason::QualityMismatch)); assert_eq!(record::verify_with(&text, &held, None).expect("step 11 not made").quality, QualityBasis::Stated); // No stream held: a decode of what? The pictures tie to nothing, whatever the caller says. let no_stream = Held { stream: None, source: held.source }; assert_eq!(record::verify_with(&text, &no_stream, Some(Pictures::Decoded(&own))).expect("the figures are the pictures'").quality, QualityBasis::Handed); // A record stating no figures says so in its verdict, whatever pictures are held, whether // its `quality` is `null` or it has none: a reader takes the verdict, and never tells the two // apart. for name in ["records/accept-software-avc-128x72.json", "records/accept-quality-null-software-avc-128x72.json"] { let none = String::from_utf8(read(name)).expect("a record"); assert_eq!(record::verify_with(&none, &held, Some(Pictures::Decoded(&real))).expect("nothing to check").quality, QualityBasis::NotMeasured, "{name}"); } } /// A record says `null` until its signer measures (§6.1, §8.3.2): what `record::body` builds /// states it, verifies with stream, source and pictures all held, and rests on nothing; its /// signer's figures then take its place. #[test] fn a_record_states_null_until_its_signer_measures() { use wai::platform_encode::{self as pe, Codec, Encoded, Identity, record::{self, Held, Pictures, QualityBasis}}; let d = dir(); let read = |p: &str| std::fs::read(d.join(p)).expect("a corpus file"); let src = read("source.y4m"); let stream = read("streams/software-avc-128x72.h264"); let pictures = read("decoded/software-avc-128x72.yuv"); let p = pe::prepare(&src, Codec::Avc, Some((128, 72)), corpus::KBPS).expect("the corpus source"); let c = pe::annexb::check_stream(Codec::Avc, &stream, corpus::FRAMES, &corpus::PLAN).expect("a fixture stream holds to §4.3"); let identity = Identity { api: "software", encoder: "corpus".into(), version: "1".into(), hardware: false, device: "corpus".into(), driver: "corpus".into(), library_sha256: Some(sha256_hex(b"a library")) }; let e = Encoded { identity, stream: stream.clone(), units: c.units, sps: c.sps, wall_us: 1000 }; let body = record::body(&e, &p.cfg, &p.source, &corpus::PLAN, None, None, corpus::ISSUED_AT); assert!(body.get("quality").is_some_and(serde_json::Value::is_null), "a body states null: {body}"); let key = ed25519_dalek::SigningKey::from_bytes(&corpus::SEED); let (hd, frames) = pe::y4m::read_all(&src).expect("the source"); let planes = frames.concat(); let held = Held { stream: Some(&stream), source: Some((&hd, &planes)) }; let signed = record::sign(body, &key); let text = record::to_text(&signed); assert!(text.contains("\"quality\":null"), "the record's text states it"); assert_eq!(record::verify_with(&text, &held, Some(Pictures::Decoded(&pictures))).expect("a record of no figures").quality, QualityBasis::NotMeasured); let q = record::Quality::measure(p.frames.iter().map(Vec::as_slice), &pictures, 128, 72).expect("a picture per frame"); let measured = record::to_text(&record::add_quality(&signed, &q, &key, "2026-11-06T09:30:00Z").expect("its own signer")); assert_eq!(record::verify_with(&measured, &held, Some(Pictures::Decoded(&pictures))).expect("its figures hold").quality, QualityBasis::Decoded); } /// `wai_encode_measure quality --record`, end to end through the tool: the record gains its /// figures, its own signer signs it again, and `issued_at` is when; a record is not signed /// again without its signer's key, nor by another's. A record of `null` gains them as one with /// no such member does. A sum of 0 prints as `exact`. #[test] fn the_measure_tool_signs_quality_into_a_record_as_its_signer() { use std::process::Command; use wai::platform_encode::record::{self, Held, Pictures, QualityBasis}; let d = dir(); let tmp = std::env::temp_dir().join(format!("wai-encode-measure-{}", std::process::id())); std::fs::create_dir_all(&tmp).expect("a directory"); let out = tmp.join("out.json"); let path = |p: &str| d.join(p).to_string_lossy().into_owned(); let run_on = |rec: &str, pictures: &str, key: Option<&str>| { let mut c = Command::new(env!("CARGO_BIN_EXE_wai_encode_measure")); c.args(["quality", "--codec", "avc", "--stream", &path("streams/software-avc-128x72.h264"), "--source", &path("source.y4m"), "--size", "128x72"]); c.args(["--decoded", &path(pictures), "--record", &path(rec), "--record-out", &out.to_string_lossy()]); if let Some(k) = key { let seed = tmp.join("seed"); std::fs::write(&seed, k).expect("a seed"); c.args(["--key", &seed.to_string_lossy()]); } c.output().expect("the tool runs") }; let run = |pictures: &str, key: Option<&str>| run_on("records/accept-software-avc-128x72.json", pictures, key); let corpus_key = "45".repeat(32); let _ = std::fs::remove_file(&out); let no_key = run("decoded/software-avc-128x72.yuv", None); assert!(!no_key.status.success() && !out.exists(), "--record with no --key signs nothing: {no_key:?}"); let other_key = run("decoded/software-avc-128x72.yuv", Some(&"46".repeat(32))); assert!(!other_key.status.success() && !out.exists(), "another's key signs nothing: {other_key:?}"); let good = run("decoded/software-avc-128x72.yuv", Some(&corpus_key)); assert!(good.status.success(), "{good:?}"); let line: serde_json::Value = serde_json::from_slice(&good.stdout).expect("one JSON line"); assert_eq!(line["pictures_read"], "handed", "--decoded hands the pictures over"); assert!(line["psnr_y"].is_number()); let text = std::fs::read_to_string(&out).expect("the record"); let stream = std::fs::read(d.join("streams/software-avc-128x72.h264")).expect("the stream"); let pictures = std::fs::read(d.join("decoded/software-avc-128x72.yuv")).expect("the pictures"); let src = std::fs::read(d.join("source.y4m")).expect("the source"); let (hd, frames) = wai::platform_encode::y4m::read_all(&src).expect("the source"); let planes = frames.concat(); let held = Held { stream: Some(&stream), source: Some((&hd, &planes)) }; let v = record::verify_with(&text, &held, Some(Pictures::Handed(&pictures))).expect("the record verifies"); assert_eq!(v.quality, QualityBasis::Handed); let before: serde_json::Value = serde_json::from_slice(&std::fs::read(d.join("records/accept-software-avc-128x72.json")).expect("the record")).expect("JSON"); assert_eq!(v.record["signer_pubkey"], before["signer_pubkey"], "the record keeps its signer"); assert_ne!(v.record["issued_at"], before["issued_at"], "issued_at is when it was signed again"); assert_eq!(v.record["stream"], before["stream"]); let of_null = run_on("records/accept-quality-null-software-avc-128x72.json", "decoded/software-avc-128x72.yuv", Some(&corpus_key)); assert!(of_null.status.success(), "{of_null:?}"); let text = std::fs::read_to_string(&out).expect("the record"); assert_eq!(record::verify_with(&text, &held, Some(Pictures::Handed(&pictures))).expect("the record verifies").quality, QualityBasis::Handed, "a record of null takes its figures"); let perfect = run("handed/software-avc-128x72.yuv", Some(&corpus_key)); assert!(perfect.status.success(), "{perfect:?}"); let line: serde_json::Value = serde_json::from_slice(&perfect.stdout).expect("one JSON line"); for k in ["psnr_y", "psnr_u", "psnr_v", "psnr_yuv_611"] { assert_eq!(line[k], "exact", "{k}: a sum of 0 has no finite PSNR (staged-measurement §4.7)"); } let _ = std::fs::remove_dir_all(&tmp); } #[test] fn the_reasons_table_is_the_references() { let text = std::fs::read_to_string(PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../extensions/platform-encode.md")).expect("the extension"); let at = text.find("## 12. Reasons").expect("§12"); let end = text[at + 1..].find("\n## ").map_or(text.len(), |e| at + 1 + e); let table: BTreeSet = text[at..end] .lines() .filter(|l| l.starts_with("| `") && !l.contains("| producer |")) .filter_map(|l| l.split('`').nth(1).map(String::from)) .collect(); let code: BTreeSet = Reason::ALL.iter().map(|r| r.code().to_string()).collect(); assert_eq!(table, code, "§12's record reasons are exactly Reason::ALL"); } /// The pictures the corpus pins under `decoded/` are what the platform's decoder makes of their /// stream, byte for byte, so a `decoded` verdict in the corpus stands for a verifier's own decode /// (§10.1). #[cfg(target_vendor = "apple")] #[test] fn the_pinned_pictures_are_what_the_platform_decodes_their_stream_to() { use wai::platform_encode::{self as pe, Codec}; let (s, d) = (streams(), decoded()); for f in corpus::DECODED { let stream = &s[f.stream]; let units = pe::annexb::check_stream(Codec::Avc, stream, corpus::FRAMES, &corpus::PLAN).expect("a fixture stream holds to §4.3").units; let mut pictures = Vec::new(); let n = pe::platform_decode(Codec::Avc, stream, &units, |p| { pictures.extend_from_slice(p); Ok(()) }) .expect("the platform decodes it"); assert_eq!(n, corpus::FRAMES, "{}: one picture per frame", f.file); assert!(pictures == d[f.file], "{}: not what the platform decodes {} to", f.file, f.stream); } } /// `wai_encode_measure run`, end to end through the tool, each codec on this host's encoder: the /// record it writes states the quality of what its stream decodes to, a verifier's own decode /// of that stream recomputes every figure, and the verdict is `decoded`. With nothing measured /// the encode stands: the record states `null`, and the tool's line says why. #[cfg(target_vendor = "apple")] #[test] fn the_measure_tools_run_signs_the_quality_of_its_stream() { use std::process::Command; use wai::platform_encode::{self as pe, Codec, record::{self, Held, Pictures, QualityBasis}}; let tmp = std::env::temp_dir().join(format!("wai-encode-measure-run-{}", std::process::id())); let source = dir().join("source.y4m"); let src = std::fs::read(&source).expect("the source"); let (hd, frames) = pe::y4m::read_all(&src).expect("the source"); let planes = frames.concat(); for (codec, flag) in [(Codec::Avc, "avc"), (Codec::Hevc, "hevc")] { let run = |name: &str, more: &[&str]| -> (serde_json::Value, String, Vec) { let out = Command::new(env!("CARGO_BIN_EXE_wai_encode_measure")) .args(["run", "--api", "platform", "--codec", flag, "--kbps", "400", "--idr-every", "5", "--name", name]) .arg("--source") .arg(&source) .arg("--out") .arg(&tmp) .args(more) .output() .expect("the tool runs"); assert!(out.status.success(), "{name}: {out:?}"); let line = serde_json::from_slice(&out.stdout).expect("one JSON line"); let text = std::fs::read_to_string(tmp.join(format!("{name}.record.json"))).expect("the record"); let stream = std::fs::read(tmp.join(format!("{name}.{}", codec.extension()))).expect("the stream"); (line, text, stream) }; let (line, text, stream) = run(flag, &[]); let plan: Vec = serde_json::from_str::(&text).expect("JSON")["idr"].as_array().expect("a plan").iter().filter_map(serde_json::Value::as_u64).collect(); let units = pe::annexb::check_stream(codec, &stream, corpus::FRAMES, &plan).expect("the stream holds to §4.3").units; let mut pictures = Vec::new(); let n = pe::platform_decode(codec, &stream, &units, |f| { pictures.extend_from_slice(f); Ok(()) }) .expect("the platform decodes it"); assert_eq!(n, corpus::FRAMES, "{flag}: one picture per frame"); let held = Held { stream: Some(&stream), source: Some((&hd, &planes)) }; let v = record::verify_with(&text, &held, Some(Pictures::Decoded(&pictures))).unwrap_or_else(|r| panic!("{flag}: {r}")); assert_eq!(v.quality, QualityBasis::Decoded, "{flag}"); assert_eq!(line["quality"], v.record["quality"], "{flag}: the line prints what the record signs"); assert!(line["quality_not_measured"].is_null(), "{flag}: {line}"); let (line, text, stream) = run(&format!("{flag}-not-measured"), &["--no-decode"]); assert!(text.contains("\"quality\":null"), "{flag}: the record states null"); let held = Held { stream: Some(&stream), source: Some((&hd, &planes)) }; assert_eq!(record::verify_with(&text, &held, None).unwrap_or_else(|r| panic!("{flag}: {r}")).quality, QualityBasis::NotMeasured, "{flag}"); assert!(line["quality"].is_null() && line["quality_not_measured"].is_string(), "{flag}: {line}"); } let _ = std::fs::remove_dir_all(&tmp); } /// The media framework's encoders, each codec, on this host: §4.3 holds, a signed record /// verifies with the stream and the source held, and the platform's decoder gives one /// picture per frame. #[cfg(target_vendor = "apple")] #[test] fn the_platform_encoder_makes_a_stream_that_holds_and_decodes() { use wai::platform_encode::{self as pe, Api, Codec, Options, record}; let src = corpus::source(); for codec in [Codec::Avc, Codec::Hevc] { let p = pe::prepare(&src, codec, None, 400).expect("the corpus source"); let e = pe::encode(Api::Platform, &p.cfg, &Options::default(), p.frames.iter().map(Vec::as_slice), &corpus::PLAN).unwrap_or_else(|e| panic!("{}: {e}", codec.name())); assert!(e.identity.hardware, "{}: the framework chose its software encoder: {:?}", codec.name(), e.identity); let body = record::body(&e, &p.cfg, &p.source, &corpus::PLAN, None, None, corpus::ISSUED_AT); let text = record::to_text(&record::sign(body, &ed25519_dalek::SigningKey::from_bytes(&corpus::SEED))); let (hd, frames) = pe::y4m::read_all(&src).expect("the source"); let planes = frames.concat(); record::verify(&text, &record::Held { stream: Some(&e.stream), source: Some((&hd, &planes)) }).unwrap_or_else(|r| panic!("{}: {r}", codec.name())); let mut pictures = Vec::new(); let n = pe::platform_decode(codec, &e.stream, &e.units, |f| { if f.len() != p.cfg.picture_len() { return Err("a picture of another size".into()); } pictures.extend_from_slice(f); Ok(()) }) .expect("the platform decodes it"); assert_eq!(n, corpus::FRAMES, "{}: one picture per frame", codec.name()); // The figures of what the platform decoded, signed and recomputed from that decode: // the one verdict that makes them the stream's (§7). let q = record::Quality::measure(p.frames.iter().map(Vec::as_slice), &pictures, p.cfg.width, p.cfg.height).expect("a picture per frame"); let body = record::with_quality(record::body(&e, &p.cfg, &p.source, &corpus::PLAN, None, None, corpus::ISSUED_AT), &q); let text = record::to_text(&record::sign(body, &ed25519_dalek::SigningKey::from_bytes(&corpus::SEED))); let held = record::Held { stream: Some(&e.stream), source: Some((&hd, &planes)) }; let v = record::verify_with(&text, &held, Some(record::Pictures::Decoded(&pictures))).unwrap_or_else(|r| panic!("{}: {r}", codec.name())); assert_eq!(v.quality, record::QualityBasis::Decoded, "{}", codec.name()); } }