fix(webrtc): bypass str0m LeakyBucketPacer for low-latency LAN streaming
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.
This commit is contained in:
@@ -500,6 +500,12 @@ impl WebRtcInner {
|
||||
}
|
||||
};
|
||||
self.video_pt = None;
|
||||
// Disable str0m's LeakyBucketPacer for this video stream. Default pacing
|
||||
// adds ~100ms send latency per large IDR; our 8Mbps cap + VBV already
|
||||
// provide rate control. BWE stays enabled for adaptation feedback.
|
||||
if let Some(stream_tx) = self.rtc.direct_api().stream_tx_by_mid(mid, None) {
|
||||
stream_tx.set_unpaced(true);
|
||||
}
|
||||
if let Some(writer) = self.rtc.writer(mid) {
|
||||
for pp in writer.payload_params() {
|
||||
tracing::debug!("Codec: pt={:?} spec={:?}", pp.pt(), pp.spec());
|
||||
|
||||
Reference in New Issue
Block a user