Fix latency drift: cap framerate + tune mpv buffers

Symptom: cross-machine streams drifted ~6-9 seconds per minute. mpv
showed continuous "Audio device underrun detected" with video packets
piling up in its demuxer queue while audio queue stayed at 0.

Root causes:
- pipewiresrc captured at the host monitor's refresh rate (180Hz),
  not at the configured framerate. The encoder + mux produced 6x more
  frames per wallclock second than mpv could consume at realtime,
  burying audio packet density in mpv's demuxer queue.
- `--profile=low-latency` sets `audio-buffer=0`, which is too
  aggressive — any sub-millisecond network jitter immediately
  starves the audio device. Underruns slowed mpv's audio clock, and
  with `video-sync=audio` (also from low-latency profile) video
  followed.

Fixes:
- `videorate ! video/x-raw,framerate=<fps>/1` after pipewiresrc to
  cap input to the requested rate deterministically.
- mpv command grows `--audio-buffer=0.2 --demuxer-max-bytes=2M
  --demuxer-readahead-secs=0.5`: small audio buffer to absorb network
  jitter, demuxer cap to prevent runaway buildup.

A leaky-queues attempt landed and was reverted in the same commit —
it removed backpressure without addressing the root cause and made
things worse.

Verified cross-machine 6m51s: drift held at ~1s floor, zero audio
underruns, perfect A-V sync.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-18 04:25:17 -04:00
parent d3bff65add
commit 7983701b03
2 changed files with 10 additions and 2 deletions
+7 -1
View File
@@ -132,12 +132,18 @@ pub async fn start(opts: &HostOpts) -> Result<CaptureHandle> {
"!",
"fdsink",
"fd=1",
// video branch
// video branch — videorate caps to 30fps so we don't ship at the
// monitor's refresh rate (e.g. 180Hz) and pile up frames in mpv's
// demuxer queue faster than realtime.
"pipewiresrc",
&format!("fd={raw_fd}"),
&format!("path={node_id}"),
"do-timestamp=true",
"!",
"videorate",
"!",
&format!("video/x-raw,framerate={}/1", opts.framerate),
"!",
"queue",
"!",
"videoconvert",
+3 -1
View File
@@ -46,7 +46,9 @@ fn print_viewer_banner(port: u16) {
eprintln!("┌─ PixelPass · viewer ───────────────────────────────────────");
eprintln!("│ Connected to host. Open the stream in your player:");
eprintln!("");
eprintln!("│ mpv --profile=low-latency --untimed {url}");
eprintln!(
"│ mpv --profile=low-latency --untimed --audio-buffer=0.2 --demuxer-max-bytes=2M --demuxer-readahead-secs=0.5 {url}"
);
eprintln!("│ vlc --network-caching=200 --live-caching=200 {url}");
eprintln!("");
eprintln!("│ Press Ctrl+C to disconnect.");