46e7a9785dc99d3ff9b52ec701af63eddaf97cc3
Final piece of the latency puzzle. Server-side frame_age was 6ms but browser jitterBufferDelay still spiked to 500+ ms during active periods. Root cause found via librarian investigation of str0m 0.20 source: str0m LeakyBucketPacer (active when BWE enabled) limits send rate to BWE_estimate * 1.1. For a 100KB IDR frame at 8Mbps pacing, the pacer queue adds ~100ms of send-side latency. Multiple frames stack during burst encode, causing receiver jitter buffer to grow. Video streams are PACED BY DEFAULT in str0m (audio is unpaced). Evidence: str0m/src/streams/send.rs:1116 default unpaced logic. Fix: call stream_tx.set_unpaced(true) on the video stream when media is added. BWE remains enabled for bitrate adaptation / TWCC feedback, but the pacer no longer throttles our video egress. Why this is the right call for wl-webrtc: - LAN scenario: dedicated link, no competing flows to smooth against - Encoder cap (8 Mbps) + VBV buffer (250ms) already provide rate control - The pacer's smoothing benefit (avoid bursts that compete with TCP) is irrelevant for our use case - BWE adaptation still works (we still receive EgressBitrateEstimate events and adapt encoder bitrate via BitrateCommand::UpdateBitrate) Verification expectations: - Active-period jitterBufferDelay: 500+ ms -> < 200 ms - 'Stop mouse, client continues 10s' symptom: should disappear entirely - Server-side frame_age: unchanged (~6ms) - Bitrate/resolution adaptation: unchanged (still uses BWE) - MP4 mode: unaffected (different code path) Tests: - cargo build --release: 0 new warnings (19 baseline preserved) - cargo test: 96 lib + 3 integration, 0 failed - SAFETY comments preserved verbatim - 1 file changed, 7 insertions(+), 1 deletion(-) Closes the latency investigation started in #23 / #24 / #25.
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) |
Languages
Rust
98.7%
Shell
1.2%