//! `wai.pack.scenecut/1` on the corpus fixtures, stated as the cuts a reader can check //! against the fixture's definition (`src/fixture.rs`), beside the corpus's pinned //! vectors. use wai_pack::classify::classify; use wai_pack::policy::Policy; use wai_pack::scenecut::{segment, SegParams, FLAG_FORCED, FLAG_SCENE_CUT}; use wai_pack::{fixture, source::y4m}; const POLICY: &str = include_str!("../../pack-conformance/scenecut/policy.toml"); fn run(name: &str, lookahead: u64) -> Vec<(u64, u8, &'static str)> { let p = Policy::parse(POLICY).unwrap(); let mut sp = SegParams::from_policy(&p.segmentation, p.component("v").unwrap().timebase); sp.lookahead = lookahead; let (hd, frames) = y4m::read_all(&fixture::generate(name).unwrap()).unwrap(); let (pieces, _) = segment(sp, hd.w, hd.h, frames.iter().map(|f| &f.rgb)); pieces.iter().map(|x| (x.start, x.flags, classify(&x.stats, &p.classify).label())).collect() } fn starts(v: &[(u64, u8, &str)]) -> Vec { v.iter().map(|x| x.0).collect() } /// cuts-01: hard cuts at 60, 140 and 230, and at every switch between E and F (260, /// 290, 320), each a return after more than the lookahead. The flash at 90..96 lasts /// exactly the lookahead: neither its first frame (the return clause) nor the frame /// that returns to B (the revisit clause) is a cut. The fade from C to D (160..200) /// is not cut. #[test] fn cuts_01_cuts_where_its_shots_change() { let got = run("cuts-01", 6); assert_eq!(starts(&got), vec![0, 60, 140, 230, 260, 290, 320]); assert!(got[1..].iter().all(|x| x.1 == FLAG_SCENE_CUT)); } /// With a lookahead one frame shorter than the flash, its first frame is a cut: live /// and on-demand packing agree only at equal lookahead. #[test] fn a_shorter_lookahead_cuts_the_flash() { let got = starts(&run("cuts-01", 5)); assert!(got.contains(&90), "{got:?}"); assert!(!starts(&run("cuts-01", 6)).contains(&90)); } /// kinds-01: one shot of each kind, then a static shot longer than `max` (100 frames /// at 25 per second), forced at 260. #[test] fn kinds_01_classifies_each_shot() { let got = run("kinds-01", 6); let want = [ (0, 0, "static"), (40, FLAG_SCENE_CUT, "synthetic"), (80, FLAG_SCENE_CUT, "motion_high"), (120, FLAG_SCENE_CUT, "natural"), (160, FLAG_SCENE_CUT, "static"), (260, FLAG_FORCED, "static"), ]; assert_eq!(got, want); }