feat(portal): independent WebRTC thread + channel tuning for 60fps mouse latency
- Move WebRTC send to dedicated wl-webrtc-webrtc thread (was inline in main loop) - Reduce frame_rx 16→1, input_tx 2→1 (drop-on-full), webrtc_tx 32→2 - Recv_timeout 10ms→2ms to reduce pipeline latency - Fix sent_gap_p95 stats bug: compute gap at actual send time in WebRTC thread instead of batch-draining at snapshot time (was always 0.0ms) - High profile via AVCodecContext.profile, veryfast preset, 5x bitrate - Stats drain via sent_gap channel with record_send_from_thread() - Shutdown: drop input_tx → join encode → drop webrtc_tx → join webrtc
This commit is contained in:
+7
-6
@@ -98,7 +98,7 @@ impl CapPortal {
|
||||
/// 执行流程:
|
||||
/// 1. 创建 Tokio 运行时(用于异步 Portal 调用)
|
||||
/// 2. 通过 XDG Desktop Portal 请求屏幕录制权限,获取 PipeWire fd 和 node_id
|
||||
/// 3. 创建有界通道(容量 16)用于帧传递
|
||||
/// 3. 创建有界通道(容量 1)用于帧传递(最新帧优先,避免队列积压延迟)
|
||||
/// 4. 创建 eventfd 对,用于线程安全的关闭信号传递
|
||||
/// 5. 启动 PipeWire 捕获线程
|
||||
pub fn new(args: &Args) -> Result<Self> {
|
||||
@@ -107,7 +107,7 @@ impl CapPortal {
|
||||
let no_persist = args.no_persist;
|
||||
let (pw_fd, node_id) = rt.block_on(async { Self::setup_portal(no_persist).await })?;
|
||||
|
||||
let (frame_tx, frame_rx) = bounded(16);
|
||||
let (frame_tx, frame_rx) = bounded(1);
|
||||
let (event_tx, event_rx) = bounded(8);
|
||||
|
||||
let efd = unsafe { libc::eventfd(0, libc::EFD_CLOEXEC | libc::EFD_NONBLOCK) };
|
||||
@@ -722,11 +722,12 @@ fn pipewire_thread(ctx: PwThreadCtx) {
|
||||
pts,
|
||||
};
|
||||
|
||||
if let Err(crossbeam_channel::TrySendError::Full(_)) = frame_tx.try_send(frame) {
|
||||
let prev = dropped.fetch_add(1, Ordering::Relaxed);
|
||||
if prev > 0 && prev % 30 == 0 {
|
||||
tracing::warn!("dropped {prev} frames total: encoder backlog");
|
||||
match frame_tx.try_send(frame) {
|
||||
Ok(()) => {}
|
||||
Err(crossbeam_channel::TrySendError::Full(_)) => {
|
||||
dropped.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
Err(crossbeam_channel::TrySendError::Disconnected(_)) => {}
|
||||
}
|
||||
unsafe { stream.queue_raw_buffer(raw_buf) };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user