1#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
5#![allow(dead_code, unused)]
8#![allow(clippy::unnecessary_unwrap, clippy::zombie_processes)]
9use rusty_h264_common::YuvFrame;
22use rusty_h264_encoder::{Encoder, EncoderConfig, Preset};
23
24fn load(path: &str, w: usize, h: usize, n: usize) -> Vec<YuvFrame> {
25 let raw = std::fs::read(path).expect("clip");
26 let fsz = w * h * 3 / 2;
27 raw.chunks_exact(fsz)
28 .take(n)
29 .map(|c| {
30 let mut fr = YuvFrame::black(w, h);
31 fr.y.copy_from_slice(&c[..w * h]);
32 fr.u.copy_from_slice(&c[w * h..w * h + w * h / 4]);
33 fr.v.copy_from_slice(&c[w * h + w * h / 4..]);
34 fr
35 })
36 .collect()
37}
38
39fn main() {
40 let a: Vec<String> = std::env::args().skip(1).collect();
41 let (w, h) = a[1].split_once('x').unwrap();
42 let (w, h): (usize, usize) = (w.parse().unwrap(), h.parse().unwrap());
43 let nf: usize = std::env::var("RS_FRAMES").ok().and_then(|v| v.parse().ok()).unwrap_or(20);
44 let frames = load(&a[0], w, h, nf);
45
46 let preset = match std::env::var("RS_PRESET").unwrap_or_default().as_str() {
47 "fast" => Preset::Fast,
48 "quality" => Preset::Quality,
49 _ => Preset::Balanced,
50 };
51 let mut cfg = EncoderConfig::new(w, h);
52 cfg.qp = std::env::var("RS_QP").ok().and_then(|v| v.parse().ok()).unwrap_or(27);
53 cfg.gop_size = 30;
54 cfg.preset = preset;
55 let mut enc = Encoder::new(cfg).expect("encoder");
56 for f in &frames {
57 let _ = enc.encode(f);
58 }
59
60 let p: Vec<u64> = rusty_h264_encoder::ME_PROBE
61 .iter()
62 .map(|c| c.load(std::sync::atomic::Ordering::Relaxed))
63 .collect();
64 let (n, ours, oracle, worse, evals) = (p[0].max(1), p[1], p[2], p[3], p[4]);
65 let (oracle_sp, worse_sp) = (p[5], p[6]);
66 println!("ME oracle — {} ({w}x{h}, {} frames, {preset:?})\n", a[0], frames.len());
67 println!(" searches {n}");
68 println!(" mean cost ours {:>10.1}", ours as f64 / n as f64);
69 println!(" mean cost exhaustive {:>10.1}", oracle as f64 / n as f64);
70 println!(" ---> we are {:>6.2}% above the achievable minimum",
71 100.0 * (ours as f64 - oracle as f64) / oracle as f64);
72 println!(" searches the oracle beat {:>9} ({:.1}%)", worse, 100.0 * worse as f64 / n as f64);
73 println!("
75 + exhaustive SUB-PEL (all quarter-pel in +-3):");
76 println!(" mean cost exhaustive {:>10.1}", oracle_sp as f64 / n as f64);
77 println!(" ---> we are {:>6.2}% above the achievable minimum",
78 100.0 * (ours as f64 - oracle_sp as f64) / oracle_sp as f64);
79 println!(" searches it beat {:>9} ({:.1}%)", worse_sp, 100.0 * worse_sp as f64 / n as f64);
80 let oracle_evals = 0;
81 println!("\n cost() evals/search {:>8.1} (ours, oracle's {oracle_evals} excluded)",
82 evals as f64 / n as f64 - oracle_evals as f64);
83}