perf(agent): 60fps上限/零拷贝转换/多线程编码/发送缓冲512KB + encbench基准
- capture: min_frame 33→16ms,RC 60fps;with_mapped 映射窗口内直接 BGRA→YUV(行距连续零拷贝) - capture: num_threads(4) + 每120帧输出 convert/encode 耗时(实测:convert 2ms,encode 41ms/帧真实工况) - agent: send_window 2MB→512KB,E2E 排队天花板 ~0.15s(修复 E2E 633ms 红) - encbench: 1080p 编码基准(合成 5ms/帧,真实工况 41ms/帧 → 软编 1080p 上限 ~24fps,60fps 需 NVENC) - tools/bench.md
This commit is contained in:
1 parent
881341be3a
commit
e7472fa12f
3 files changed
+154
-40
No files matched your search
@@ -0,0 +1,59 @@
|
||||
//! 编码基准:1080p 噪声帧(最恶劣压缩工况)对比单线程与 4 线程 openh264。
|
||||
//! 运行:cargo run --release -p agent --bin encbench
|
||||
|
||||
use openh264::encoder::{
|
||||
BitRate, Encoder, EncoderConfig, FrameRate, IntraFramePeriod, RateControlMode, UsageType,
|
||||
};
|
||||
use openh264::formats::{BgraSliceU8, YUVBuffer};
|
||||
use openh264::OpenH264API;
|
||||
use std::time::Instant;
|
||||
|
||||
fn bench(threads: u16, frames: usize) -> f64 {
|
||||
let mut enc = Encoder::with_api_config(
|
||||
OpenH264API::from_source(),
|
||||
EncoderConfig::new()
|
||||
.bitrate(BitRate::from_bps(5_000_000))
|
||||
.max_frame_rate(FrameRate::from_hz(30.0))
|
||||
.rate_control_mode(RateControlMode::Bitrate)
|
||||
.usage_type(UsageType::ScreenContentRealTime)
|
||||
.intra_frame_period(IntraFramePeriod::from_num_frames(300))
|
||||
.num_threads(threads),
|
||||
)
|
||||
.expect("encoder");
|
||||
|
||||
// 预生成 10 张不同噪声帧轮换(保证每帧 P 帧都真实编码,避免运动估计空转)
|
||||
let mut frames_in = Vec::with_capacity(10);
|
||||
for f in 0..10u32 {
|
||||
let mut frame = vec![0u8; 1920 * 1080 * 4];
|
||||
let mut seed = 12345u32.wrapping_add(f * 7919);
|
||||
for px in frame.chunks_exact_mut(4) {
|
||||
seed = seed.wrapping_mul(1103515245).wrapping_add(12345);
|
||||
px.copy_from_slice(&seed.to_le_bytes());
|
||||
}
|
||||
frames_in.push(YUVBuffer::from_bgra8_source(BgraSliceU8::new(&frame, (1920, 1080))));
|
||||
}
|
||||
|
||||
// 预热 5 帧(首帧 IDR、线程池初始化)
|
||||
for (i, y) in frames_in.iter().enumerate().take(5) {
|
||||
let _ = enc.encode(y).unwrap_or_else(|_| panic!("frame {i}"));
|
||||
}
|
||||
let t = Instant::now();
|
||||
for (i, y) in frames_in.iter().cycle().take(frames).enumerate() {
|
||||
let _ = enc.encode(y).unwrap_or_else(|_| panic!("frame {i}"));
|
||||
}
|
||||
t.elapsed().as_millis() as f64 / frames as f64
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("1080p 噪声帧编码基准(含 BGRA→YUV 转换)");
|
||||
let t = Instant::now();
|
||||
let _ = YUVBuffer::from_bgra8_source(BgraSliceU8::new(
|
||||
&vec![7u8; 1920 * 1080 * 4],
|
||||
(1920, 1080),
|
||||
));
|
||||
println!("BGRA→YUV 转换: {}ms/帧", t.elapsed().as_millis());
|
||||
let s = bench(1, 20);
|
||||
println!("单线程: {s:.1}ms/帧 → {}fps", (1000.0 / s) as u32);
|
||||
let m = bench(4, 20);
|
||||
println!("4 线程: {m:.1}ms/帧 → {}fps", (1000.0 / m) as u32);
|
||||
}
|
||||
Reference in new issue
Block a user