826f544569494477bd222deb8f0d4a8b68f64552
Split synchronous encode pipeline so sws_scale + libx264 runs on a dedicated thread, leaving only VAAPI import + GPU scale + GPU→CPU transfer on the main capture thread. Problem: encode_p95 occasionally hit 74ms, blocking the entire capture pipeline and causing capture_gap_max=356ms stutter. Solution: - avhw.rs: Split SwEncState into SwEncImport (main thread: VAAPI import, filter_graph scale, GPU→CPU transfer) and SwEncEncode (encode thread: sws_scale NV12→YUV420P, libx264 encode). New CpuNv12Frame struct carries owned pixel data across threads via crossbeam channel. SwEncState wraps both for backward compat (MP4/sync path untouched). - state_portal.rs: WebRTC portal path spawns 'wl-webrtc-encode' thread with bounded(2) input channel (drop-newest backpressure) and separate timing channel. Graceful shutdown: drop webrtc_rx → drop input_tx → join encode thread → flush sync encoder. - stats.rs: Add record_import() + record_encode_thread() for async timing. Results: encode_p95 stable at 2.9-4.2ms (was 11-74ms), capture_fps stable 59-60fps, cap_gap_p95 17-19ms. Remaining capture stalls traced to PipeWire compositor frame delivery (external, not our code).
wl-webrtc
Wayland screen capture and encoding tool.
Prerequisites
- Rust toolchain (1.70+):
rustup default stable - FFmpeg 6.0+ dev libraries with VAAPI support:
- Arch:
pacman -S ffmpeg - Ubuntu/Debian:
apt install libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libva-dev - Fedora:
dnf install ffmpeg-devel libva-devel
- Arch:
- Wayland dev libraries:
- Arch:
pacman -S wayland-protocols - Ubuntu/Debian:
apt install libwayland-dev wayland-protocols - Fedora:
dnf install wayland-devel wayland-protocols-devel
- Arch:
- DRM dev libraries:
- Arch:
pacman -S libdrm - Ubuntu/Debian:
apt install libdrm-dev - Fedora:
dnf install libdrm-devel
- Arch:
Build
cargo build --release
Run
# Basic capture to file
wl-webrtc --output output.mp4
# With custom FPS and bitrate
wl-webrtc --output output.mp4 --fps 60 --bitrate 8000000
# Specify DRM device for hardware encoding
wl-webrtc --output output.mp4 --drm-device /dev/dri/renderD128
# Verbose mode
wl-webrtc --output output.mp4 -v
CLI Arguments
| Argument | Default | Description |
|---|---|---|
-o, --output |
(required) | Output file path (e.g., output.mp4) |
--output-name |
auto | Wayland output name to capture |
--fps |
30 | Target frames per second |
--codec |
h264 | Video codec (h264 only for MVP) |
--hw-accel |
vaapi | Hardware acceleration method |
--drm-device |
auto | DRM render device path |
--bitrate |
auto | Target bitrate in bps |
--gop-size |
auto | Group of Pictures size |
-v, --verbose |
false | Enable verbose logging |
--port |
0 | WebTransport server port (unused in MVP) |
Description
Languages
Rust
99.9%