Files
filmcraft/crates/h264/tests/perf.rs
Brandon ThomasandClaude Opus 5.5 374569e65e M2 perf: frame-threaded H.264 decoding and hot-path optimisation
- frame-level parallelism: the calling thread handles headers, POC, DPB and
  reference lists; each picture decodes as a job on a rayon pool (feature
  'threads') and publishes deblocked macroblock rows into a shared Frame;
  motion compensation and co-located lookups block per row on references
  still being decoded (safe Rust, OnceLock per MB row); outputs are handed
  out once their job has finished
- row-pipelined deblocking inside a picture (row r filtered after row r+1 is
  reconstructed), picture buffer recycling, panic/error isolation per job
- faster luma/chroma interpolation (row-wise filters, window fetch), direct
  interpolation into the picture for unweighted single-list blocks, merged
  motion compensation for uniform direct macroblocks, 8x8 direct derivation
  with direct_8x8_inference, vectorisable weighted prediction, deblocking
  with per-edge parameters and cached reference identities
- conformance tests now decode every fixture single- and multi-threaded and
  check pts/POC output order; ignored perf test (1080p High CRF20, 120 frames)

1080p: ~100 fps single-threaded, ~600 fps with 14 threads (M4 Pro, heavily
loaded machine).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 06:38:40 -04:00

35 lines
1.2 KiB
Rust

//! Decode speed on a 1080p High-profile stream (ignored by default; run with
//! `cargo test --release -p filmcraft-h264 --test perf -- --ignored --nocapture`).
mod common;
use filmcraft_h264::Decoder;
use std::time::Instant;
fn bench(data: &[u8], threads: usize, iters: usize) -> (usize, f64) {
let mut best = f64::MAX;
let mut frames = 0;
for _ in 0..iters {
let mut dec = Decoder::with_threads(threads);
let t0 = Instant::now();
frames = dec.decode(data, 0).expect("decode").len() + dec.flush().len();
best = best.min(t0.elapsed().as_secs_f64());
}
(frames, best)
}
#[test]
#[ignore]
fn perf_1080p() {
let f = common::fixture("bench_1080p");
let Some((h264, _)) = common::ensure(f) else { return };
// correctness first
common::check_fixture("bench_1080p").unwrap();
let data = std::fs::read(h264).unwrap();
let cores = std::thread::available_parallelism().map(|n| n.get()).unwrap_or(1);
for threads in [1, cores.min(16)] {
let (frames, secs) = bench(&data, threads, 5);
println!("1080p High CRF20 ({} KB): {threads} thread(s): {frames} frames in {secs:.3}s = {:.1} fps", data.len() / 1024, frames as f64 / secs);
}
}