open-standards/wai/wai-rs/examples/platform_encode_smoke.rs

60 lines
2.8 KiB
Rust

//! Encode a synthetic moving picture through one encoder interface and check the stream
//! ([platform-encode] §4.3), or list what every interface offers here.
//!
//! ```text
//! platform_encode_smoke probe [library]
//! platform_encode_smoke <api> <avc|hevc> <w> <h> <frames> <kbps> <idr-every> <out> [device|-] [library|-]
//! ```
//!
//! [platform-encode]: ../../extensions/platform-encode.md
use wai::platform_encode::{self as pe, Api, Codec, Config, Options};
use wai::platform_encode::corpus::frame;
fn main() {
let a: Vec<String> = std::env::args().collect();
let opt = |i: usize| a.get(i).filter(|s| s.as_str() != "-").cloned();
if a.get(1).map(String::as_str) == Some("probe") {
let opts = Options { library: opt(2).map(Into::into), ..Options::default() };
for p in pe::probe(&opts) {
match p.result {
Ok(id) => println!("{:<10} {:<4} ok {id:?}", p.api.name(), p.codec.name()),
Err(e) => println!("{:<10} {:<4} -- {e}", p.api.name(), p.codec.name()),
}
}
return;
}
if a.len() < 9 {
eprintln!("usage: platform_encode_smoke <api> <avc|hevc> <w> <h> <frames> <kbps> <idr-every> <out> [device|-] [library|-]");
std::process::exit(2);
}
let api = Api::from_name(&a[1]).expect("api: platform, va, gpu-driver or software");
let codec = match a[2].as_str() {
"avc" => Codec::Avc,
"hevc" => Codec::Hevc,
c => panic!("codec {c}"),
};
let num = |i: usize| a[i].parse::<u32>().expect("a number");
let cfg = Config { codec, width: num(3), height: num(4), fps_num: 30, fps_den: 1, kbps: num(6), full_range: false };
let frames = u64::from(num(5));
let opts = Options { device: opt(9), library: opt(10).map(Into::into), ..Options::default() };
let pics: Vec<Vec<u8>> = (0..frames as usize).map(|t| frame(cfg.width as usize, cfg.height as usize, t)).collect();
let idr = pe::idr_every(frames, u64::from(num(7)));
match pe::encode(api, &cfg, &opts, pics.iter().map(Vec::as_slice), &idr) {
Ok(e) => {
std::fs::write(&a[8], &e.stream).expect("write the stream");
let fps = frames as f64 * 1e6 / e.wall_us.max(1) as f64;
println!("identity {:?}", e.identity);
println!("sps {:?}", e.sps);
println!("units {} for {frames} frames; IDR at {idr:?}", e.units.len());
println!("bytes {} ({:.1} kb/s at 30 fps)", e.stream.len(), e.stream.len() as f64 * 8.0 * 30.0 / frames as f64 / 1000.0);
println!("wall {} us ({fps:.1} fps)", e.wall_us);
println!("sha256 {}", pe::sha256_hex(&e.stream));
}
Err(e) => {
eprintln!("refused: {e}");
std::process::exit(1);
}
}
}