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;
18use rusty_h264_encoder::{Encoder, EncoderConfig, Preset};
19
20fn load(path: &str, w: usize, h: usize, n: usize) -> Vec<YuvFrame> {
21 let raw = std::fs::read(path).expect("clip");
22 let fsz = w * h * 3 / 2;
23 raw.chunks_exact(fsz).take(n).map(|c| {
24 let mut fr = YuvFrame::black(w, h);
25 fr.y.copy_from_slice(&c[..w * h]);
26 fr.u.copy_from_slice(&c[w * h..w * h + w * h / 4]);
27 fr.v.copy_from_slice(&c[w * h + w * h / 4..]);
28 fr
29 }).collect()
30}
31
32fn main() {
33 let a: Vec<String> = std::env::args().skip(1).collect();
34 let (w, h) = a[1].split_once('x').unwrap();
35 let (w, h): (usize, usize) = (w.parse().unwrap(), h.parse().unwrap());
36 let frames = load(&a[0], w, h, std::env::var("RS_FRAMES").ok().and_then(|v| v.parse().ok()).unwrap_or(60));
37 let preset = match std::env::var("RS_PRESET").unwrap_or_default().as_str() {
38 "fast" => Preset::Fast, "quality" => Preset::Quality, _ => Preset::Balanced,
39 };
40 let arm_off: u32 = std::env::var("RS_ARM_OFF").ok().and_then(|v| v.parse().ok()).unwrap_or(0);
41 let arm_on: u32 = std::env::var("RS_ARM_ON").ok().and_then(|v| v.parse().ok()).unwrap_or(3);
42 let run = |on: bool| {
43 let m = if on { arm_on } else { arm_off };
44 let mut cfg = EncoderConfig::new(w, h);
45 cfg.qp = std::env::var("RS_QP").ok().and_then(|v| v.parse().ok()).unwrap_or(27);
46 cfg.gop_size = 30;
47 cfg.preset = preset;
48 cfg.tune_me_snap = m & 1 != 0;
49 cfg.tune_me_subpel_iter = m & 2 != 0;
50 let mut enc = Encoder::new(cfg).expect("enc");
51 let t = std::time::Instant::now();
52 let mut b = 0usize;
53 for f in &frames { b += enc.encode(f).len(); }
54 (t.elapsed().as_secs_f64(), b)
55 };
56 let mut best = [f64::MAX; 2];
57 let mut bytes = [0usize; 2];
58 for pass in 0..10 {
59 let arm = pass % 2;
60 let (t, b) = run(arm == 1);
61 if t < best[arm] { best[arm] = t; }
62 bytes[arm] = b;
63 }
64 let px = (w * h * frames.len()) as f64;
65 println!("arm {arm_off} -> {arm_on} — {} {w}x{h} {} frames {preset:?}", a[0], frames.len());
66 println!(" off : {:>7.1} ms {:>6.2} Mpx/s {:>9} bytes", best[0]*1e3, px/best[0]/1e6, bytes[0]);
67 println!(" on : {:>7.1} ms {:>6.2} Mpx/s {:>9} bytes", best[1]*1e3, px/best[1]/1e6, bytes[1]);
68 println!(" speed {:>6.3}x size {:>+6.2}%", best[0]/best[1],
69 100.0*(bytes[1] as f64/bytes[0] as f64 - 1.0));
70}