use rusty_h264_decoder::Decoder;
fn main() {
let args: Vec<String> = std::env::args().skip(1).collect();
let path = args.first().expect("usage: decode_bench <stream.264> [reps]");
let reps: usize = args.get(1).and_then(|v| v.parse().ok()).unwrap_or(5);
let input = std::fs::read(path).expect("read stream");
let (mut best, mut worst) = (f64::MAX, 0f64);
let (mut frames, mut px) = (0usize, 0usize);
for _ in 0..reps {
let mut dec = Decoder::new();
let t = std::time::Instant::now();
let (mut f, mut p) = (0usize, 0usize);
for au in rusty_h264_decoder::split_access_units(&input) {
if let Some(fr) = dec.decode(au).expect("decode") {
f += 1;
p += fr.width * fr.height;
}
}
let e = t.elapsed().as_secs_f64();
best = best.min(e);
worst = worst.max(e);
frames = f;
px = p;
}
println!(
"{}: frames={frames} px={px} best={:.1}ms worst={:.1}ms spread={:.1}% -> {:.1} Mpx/s",
path,
best * 1e3,
worst * 1e3,
(worst - best) * 100.0 / best,
px as f64 / best / 1e6
);
#[cfg(feature = "profile")]
{
rusty_h264_common::prof::reset();
rusty_h264_common::deblock::census::reset();
let mut dec = Decoder::new();
for au in rusty_h264_decoder::split_access_units(&input) {
let _ = dec.decode(au).expect("decode");
}
rusty_h264_common::prof::dump();
rusty_h264_common::deblock::census::dump();
}
let snap = rusty_h264_common::prof::snapshot();
let total = snap[rusty_h264_common::prof::Stage::Total as usize].0.max(1e-9);
let first = rusty_h264_common::prof::Stage::Total as usize + 1;
if snap[first..].iter().all(|s| s.1 == 0) {
return; }
#[cfg(feature = "profile")]
{
let mc = rusty_h264_common::inter::mcstats::snapshot_cycles();
if !mc.is_empty() {
let tot: u64 = mc.iter().map(|r| r.3).sum();
eprintln!("--- MC census (size x phase), by CYCLES [total {tot} cyc] ---");
let mut rows = mc;
rows.sort_by_key(|r| std::cmp::Reverse(r.3));
for (size, phase, n, cyc) in rows.iter().take(12) {
eprintln!(
" {size:<10} {phase:<8} {n:>9} calls {:>5.1}% cycles {:>6.1} cyc/call",
100.0 * *cyc as f64 / tot.max(1) as f64,
*cyc as f64 / (*n).max(1) as f64
);
}
}
}
eprintln!("--- INFO / nested stages (not part of the residue sum) ---");
for i in first..snap.len() {
if snap[i].1 == 0 {
continue;
}
eprintln!(
" {:<20} {:>8.1} ms {:>5.1}% ({} calls)",
rusty_h264_common::prof::name(i),
snap[i].0,
100.0 * snap[i].0 / total,
snap[i].1
);
}
}