Files
craft-libs/crates/video/tests/vp9_decode/perf.rs
Dylan M. Taylor 6ac2a6a34a craft-video: VP9 decoder from FilmCraft, with DeckCraft's memory budget (vp9-decode) (#821)
* craft-video: VP9 decoder from FilmCraft (`vp9-decode` feature)

FilmCraft's crates/vp9 at 4c0d2ad7 becomes craft_video::vp9::decode. The encoder moves to
vp9/encode and is still exported from craft_video::vp9. Feature vp9 now turns on vp9-decode and
vp9-encode, so either half can be built without the other.

The decoder's tests find ffmpeg and the fixture directory through craft-media-testkit; a fixture
that cannot be generated fails under CRAFT_MEDIA_REQUIRE_ORACLES=1. craft-video is built at
opt-level 3 in the dev profile, as FilmCraft built its codecs.

* craft-video: VP9 decoder checks its picture store against a memory budget

DeckCraft's copy of the decoder refuses a frame size whose pictures (eight reference slots, the
new frame and those in flight) would not fit a byte budget. The budget type comes with it as
craft_video::budget; FilmCraft's 2^26 luma sample cap stays.
2026-11-11 13:47:53 -05:00

49 lines
1.4 KiB
Rust

//! Decode speed (ignored by default; run with
//! `cargo test --release -p craft-video --features vp9-decode,threads --test vp9_decode perf:: -- --ignored --nocapture`).
use crate::common;
use craft_video::vp9::decode::Decoder;
use std::time::Instant;
fn bench(frames: &[&[u8]], threads: usize, iters: usize) -> (usize, f64) {
let mut best = f64::MAX;
let mut n = 0;
for _ in 0..iters {
let mut dec = Decoder::with_threads(threads);
let t0 = Instant::now();
n = 0;
for f in frames {
n += dec.decode(f, 0).expect("decode").len();
}
n += dec.flush().len();
best = best.min(t0.elapsed().as_secs_f64());
}
(n, best)
}
fn run(name: &str, label: &str) {
let f = common::fixture(name);
let Some((ivf, _)) = common::ensure(f) else { return };
common::check_fixture(name).unwrap();
let data = std::fs::read(ivf).unwrap();
let frames = common::ivf_frames(&data);
let cores = std::thread::available_parallelism().map(|n| n.get()).unwrap_or(1);
for threads in [1, cores.min(16)] {
let (n, secs) = bench(&frames, threads, 3);
println!("{label} ({} KB): {threads} thread(s): {n} frames in {secs:.3}s = {:.1} fps", data.len() / 1024, n as f64 / secs);
}
}
#[test]
#[ignore]
fn perf_1080p() {
run("bench_1080p", "1080p 8-bit, 4 tile columns");
}
#[test]
#[ignore]
fn perf_4k() {
run("bench_4k", "2160p 8-bit, 8 tile columns");
}