perf(portal): achieve 58-60fps PipeWire screen capture
- Force PipeWire quantum=512 via NODE_FORCE_QUANTUM (48000/512=93Hz scheduling) - Switch to libx264 ultrafast/zerolatency with 6 threads - Use two-phase poll_and_encode: blocking recv_timeout for first frame, non-blocking try_recv drain for subsequent frames - Remove fps_limit from portal path (PW already rate-limits via quantum/KWin; fps_limit's min_interval was silently dropping ~10% of valid frames) - Remove diagnostic instrumentation (TIMING/PIPEWIRE logs, timing fields, pw_stats counters) - Add lightweight production stats: per-10s fps log + shutdown summary - Prefer libx264 over libopenh264 (better quality at same speed)
This commit is contained in:
16
src/main.rs
16
src/main.rs
@@ -304,15 +304,14 @@ fn run_portal_pipewire(args: Args) -> Result<()> {
|
||||
poll.registry()
|
||||
.register(&mut signals, mio::Token(1), mio::Interest::READABLE)?;
|
||||
|
||||
// 主事件循环(超时 10ms,比 wlr-screencopy 更短,因为不依赖 Wayland fd 唤醒)
|
||||
// 10ms 超时的作用是让循环高频转动,以便及时处理 PipeWire 投递的帧
|
||||
// 如果没有信号,poll 最多阻塞 10ms 就会超时返回
|
||||
// 主事件循环(非阻塞信号检测 + recv_timeout 等待帧)
|
||||
// poll 超时为 0ms(非阻塞),实际等待由 poll_and_encode 的 recv_timeout 实现
|
||||
let mut running = true;
|
||||
while running {
|
||||
// poll 在此循环中只监听信号 fd,所以:
|
||||
// poll 在此循环中只监听信号 fd(非阻塞):
|
||||
// - 收到 SIGINT/SIGTERM → 事件触发,设置 running=false
|
||||
// - 超时 10ms → 事件为空,继续执行 poll_and_encode
|
||||
poll.poll(&mut events, Some(std::time::Duration::from_millis(10)))
|
||||
// - 无事件 → 立即返回,继续执行 poll_and_encode(内部 recv_timeout 等待帧)
|
||||
poll.poll(&mut events, Some(std::time::Duration::from_millis(0)))
|
||||
.unwrap_or_else(|e| {
|
||||
if e.kind() == std::io::ErrorKind::Interrupted {
|
||||
return;
|
||||
@@ -321,7 +320,6 @@ fn run_portal_pipewire(args: Args) -> Result<()> {
|
||||
running = false;
|
||||
});
|
||||
|
||||
// 遍历事件,检查是否收到退出信号
|
||||
for event in &events {
|
||||
if event.token() == mio::Token(1) {
|
||||
tracing::info!("Received quit signal");
|
||||
@@ -334,7 +332,9 @@ fn run_portal_pipewire(args: Args) -> Result<()> {
|
||||
// poll_and_encode 会从 PipeWire 缓冲区取出帧,
|
||||
// 编码为 H.264 并推送。返回 true 表示还有更多帧待处理,
|
||||
// 返回 false 表示当前没有帧了,while 循环退出等待下一轮 poll
|
||||
while state.poll_and_encode()? {}
|
||||
if state.poll_and_encode(true)? {
|
||||
while state.poll_and_encode(false)? {}
|
||||
}
|
||||
|
||||
// Portal 状态机遇到致命错误时退出
|
||||
if state.is_errored() {
|
||||
|
||||
Reference in New Issue
Block a user