opt benchmark code

Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
21pages 2023-03-04 11:06:22 +08:00
parent 91977d4586
commit 0579ba5cfd
2 changed files with 32 additions and 35 deletions

View File

@ -1,14 +1,5 @@
use docopt::Docopt; use docopt::Docopt;
use hbb_common::env_logger::{init_from_env, Env, DEFAULT_FILTER_ENV}; use hbb_common::env_logger::{init_from_env, Env, DEFAULT_FILTER_ENV};
#[cfg(feature = "hwcodec")]
use hwcodec::{
decode::{DecodeContext, Decoder},
encode::{EncodeContext, Encoder},
ffmpeg::{CodecInfo, CodecInfos},
AVPixelFormat,
Quality::*,
RateControl::*,
};
use scrap::{ use scrap::{
codec::{EncoderApi, EncoderCfg}, codec::{EncoderApi, EncoderCfg},
Capturer, Display, TraitCapturer, VpxDecoder, VpxDecoderConfig, VpxEncoder, VpxEncoderConfig, Capturer, Display, TraitCapturer, VpxDecoder, VpxDecoderConfig, VpxEncoder, VpxEncoderConfig,
@ -26,17 +17,17 @@ Usage:
benchmark (-h | --help) benchmark (-h | --help)
Options: Options:
-h --help Show this screen. -h --help Show this screen.
--count=COUNT Capture frame count [default: 100]. --count=COUNT Capture frame count [default: 100].
--bitrate=KBS Video bitrate in kilobits per second [default: 5000]. --bitrate=KBS Video bitrate in kilobits per second [default: 5000].
--hw-pixfmt=PIXFMT Hareware codec pixfmt. [default: i420] --hw-pixfmt=PIXFMT Hardware codec pixfmt. [default: i420]
Valid values: i420, nv12. Valid values: i420, nv12.
"; ";
#[derive(Debug, serde::Deserialize)] #[derive(Debug, serde::Deserialize)]
struct Args { struct Args {
flag_count: u32, flag_count: usize,
flag_bitrate: u32, flag_bitrate: usize,
flag_hw_pixfmt: Pixfmt, flag_hw_pixfmt: Pixfmt,
} }
@ -51,16 +42,17 @@ fn main() {
let args: Args = Docopt::new(USAGE) let args: Args = Docopt::new(USAGE)
.and_then(|d| d.deserialize()) .and_then(|d| d.deserialize())
.unwrap_or_else(|e| e.exit()); .unwrap_or_else(|e| e.exit());
let bitrate_k = args.flag_bitrate as usize; let bitrate_k = args.flag_bitrate;
let yuv_count = args.flag_count as usize; let yuv_count = args.flag_count;
let (yuvs, width, height) = capture_yuv(yuv_count); let (yuvs, width, height) = capture_yuv(yuv_count);
println!( println!(
"benchmark {}x{} bitrate:{}k hw_pixfmt:{:?} count:{:?}", "benchmark {}x{} bitrate:{}k hw_pixfmt:{:?}",
width, height, bitrate_k, args.flag_hw_pixfmt, yuv_count width, height, bitrate_k, args.flag_hw_pixfmt
); );
test_vp9(&yuvs, width, height, bitrate_k, yuv_count); test_vp9(&yuvs, width, height, bitrate_k, yuv_count);
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
{ {
use hwcodec::AVPixelFormat;
let hw_pixfmt = match args.flag_hw_pixfmt { let hw_pixfmt = match args.flag_hw_pixfmt {
Pixfmt::I420 => AVPixelFormat::AV_PIX_FMT_YUV420P, Pixfmt::I420 => AVPixelFormat::AV_PIX_FMT_YUV420P,
Pixfmt::NV12 => AVPixelFormat::AV_PIX_FMT_NV12, Pixfmt::NV12 => AVPixelFormat::AV_PIX_FMT_NV12,
@ -82,19 +74,13 @@ fn capture_yuv(yuv_count: usize) -> (Vec<Vec<u8>>, usize, usize) {
let d = displays.remove(index); let d = displays.remove(index);
let mut c = Capturer::new(d, true).unwrap(); let mut c = Capturer::new(d, true).unwrap();
let mut v = vec![]; let mut v = vec![];
let start = Instant::now();
loop { loop {
if let Ok(frame) = c.frame(std::time::Duration::from_millis(30)) { if let Ok(frame) = c.frame(std::time::Duration::from_millis(30)) {
v.push(frame.0.to_vec()); v.push(frame.0.to_vec());
print!( print!("\rcapture {}/{}", v.len(), yuv_count);
"\rcapture {}/{}...{}s",
v.len(),
yuv_count,
start.elapsed().as_secs()
);
std::io::stdout().flush().ok(); std::io::stdout().flush().ok();
if v.len() == yuv_count { if v.len() == yuv_count {
println!("\rcapture {}/{} finish", yuv_count, yuv_count); println!();
return (v, c.width(), c.height()); return (v, c.width(), c.height());
} }
} }
@ -134,6 +120,7 @@ fn test_vp9(yuvs: &Vec<Vec<u8>>, width: usize, height: usize, bitrate_k: usize,
vp9s.push(frame.data.to_vec()); vp9s.push(frame.data.to_vec());
} }
} }
assert_eq!(vp9s.len(), yuv_count);
let mut decoder = VpxDecoder::new(VpxDecoderConfig { let mut decoder = VpxDecoder::new(VpxDecoderConfig {
codec: VpxVideoCodecId::VP9, codec: VpxVideoCodecId::VP9,
@ -150,7 +137,15 @@ fn test_vp9(yuvs: &Vec<Vec<u8>>, width: usize, height: usize, bitrate_k: usize,
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
mod hw { mod hw {
use hwcodec::ffmpeg::ffmpeg_linesize_offset_length; use super::*;
use hwcodec::{
decode::{DecodeContext, Decoder},
encode::{EncodeContext, Encoder},
ffmpeg::{ffmpeg_linesize_offset_length, CodecInfo, CodecInfos},
AVPixelFormat,
Quality::*,
RateControl::*,
};
use scrap::{ use scrap::{
convert::{ convert::{
hw::{hw_bgra_to_i420, hw_bgra_to_nv12}, hw::{hw_bgra_to_i420, hw_bgra_to_nv12},
@ -159,13 +154,12 @@ mod hw {
HW_STRIDE_ALIGN, HW_STRIDE_ALIGN,
}; };
use super::*;
pub fn test( pub fn test(
yuvs: &Vec<Vec<u8>>, yuvs: &Vec<Vec<u8>>,
width: usize, width: usize,
height: usize, height: usize,
bitrate_k: usize, bitrate_k: usize,
_yuv_count: usize, yuv_count: usize,
pixfmt: AVPixelFormat, pixfmt: AVPixelFormat,
) { ) {
let ctx = EncodeContext { let ctx = EncodeContext {
@ -181,17 +175,18 @@ mod hw {
rc: RC_DEFAULT, rc: RC_DEFAULT,
}; };
println!("hw encoders:");
let encoders = Encoder::available_encoders(ctx.clone()); let encoders = Encoder::available_encoders(ctx.clone());
println!("hw encoders: {}", encoders.len());
let best = CodecInfo::score(encoders.clone()); let best = CodecInfo::score(encoders.clone());
for info in encoders { for info in encoders {
test_encoder(info.clone(), ctx.clone(), yuvs, is_best(&best, &info)); test_encoder(info.clone(), ctx.clone(), yuvs, is_best(&best, &info));
} }
let (h264s, h265s) = prepare_h26x(best, ctx.clone(), yuvs); let (h264s, h265s) = prepare_h26x(best, ctx.clone(), yuvs);
assert!(h264s.is_empty() || h264s.len() == yuv_count);
println!("hw decoders:"); assert!(h265s.is_empty() || h265s.len() == yuv_count);
let decoders = Decoder::available_decoders(); let decoders = Decoder::available_decoders();
println!("hw decoders: {}", decoders.len());
let best = CodecInfo::score(decoders.clone()); let best = CodecInfo::score(decoders.clone());
for info in decoders { for info in decoders {
let h26xs = if info.name.contains("h264") { let h26xs = if info.name.contains("h264") {
@ -199,7 +194,7 @@ mod hw {
} else { } else {
&h265s &h265s
}; };
if h264s.len() == yuvs.len() { if h26xs.len() == yuvs.len() {
test_decoder(info.clone(), h26xs, is_best(&best, &info)); test_decoder(info.clone(), h26xs, is_best(&best, &info));
} }
} }
@ -234,11 +229,13 @@ mod hw {
let _ = decoder.decode(h26x).unwrap(); let _ = decoder.decode(h26x).unwrap();
cnt += 1; cnt += 1;
} }
let device = format!("{:?}", ctx.device_type).to_lowercase();
let device = device.split("_").last().unwrap();
println!( println!(
"{}{} {:?}: {:?}", "{}{} {}: {:?}",
if best { "*" } else { "" }, if best { "*" } else { "" },
ctx.name, ctx.name,
ctx.device_type, device,
start.elapsed() / cnt start.elapsed() / cnt
); );
} }

View File

@ -29,7 +29,7 @@ impl TraitCapturer for Capturer {
} }
} }
pub struct Frame<'a>(pub(crate) &'a [u8]); pub struct Frame<'a>(pub &'a [u8]);
impl<'a> ops::Deref for Frame<'a> { impl<'a> ops::Deref for Frame<'a> {
type Target = [u8]; type Target = [u8];