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:
+7
-1
@@ -132,12 +132,18 @@ pub async fn start(opts: &HostOpts) -> Result<CaptureHandle> {
|
|||||||
"!",
|
"!",
|
||||||
"fdsink",
|
"fdsink",
|
||||||
"fd=1",
|
"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",
|
"pipewiresrc",
|
||||||
&format!("fd={raw_fd}"),
|
&format!("fd={raw_fd}"),
|
||||||
&format!("path={node_id}"),
|
&format!("path={node_id}"),
|
||||||
"do-timestamp=true",
|
"do-timestamp=true",
|
||||||
"!",
|
"!",
|
||||||
|
"videorate",
|
||||||
|
"!",
|
||||||
|
&format!("video/x-raw,framerate={}/1", opts.framerate),
|
||||||
|
"!",
|
||||||
"queue",
|
"queue",
|
||||||
"!",
|
"!",
|
||||||
"videoconvert",
|
"videoconvert",
|
||||||
|
|||||||
+3
-1
@@ -46,7 +46,9 @@ fn print_viewer_banner(port: u16) {
|
|||||||
eprintln!("┌─ PixelPass · viewer ───────────────────────────────────────");
|
eprintln!("┌─ PixelPass · viewer ───────────────────────────────────────");
|
||||||
eprintln!("│ Connected to host. Open the stream in your player:");
|
eprintln!("│ Connected to host. Open the stream in your player:");
|
||||||
eprintln!("│");
|
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!("│ vlc --network-caching=200 --live-caching=200 {url}");
|
||||||
eprintln!("│");
|
eprintln!("│");
|
||||||
eprintln!("│ Press Ctrl+C to disconnect.");
|
eprintln!("│ Press Ctrl+C to disconnect.");
|
||||||
|
|||||||
Reference in New Issue
Block a user