60 lines
2.8 KiB
Rust
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);
|
|
}
|
|
}
|
|
}
|