Skip to content

jitter: shorten the restart run when it starts beyond the reorder window - #86

Merged
hechen-eng merged 1 commit into
livekit:mainfrom
ahsang:fix/jitter-backward-discontinuity
Sep 25, 2026
Merged

hechen-eng merged 1 commit into
livekit:mainfrom
ahsang:fix/jitter-backward-discontinuity

Conversation

@ahsang

@ahsang ahsang commented Sep 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Rebased on #93 / #95 as suggested. This is now a small change to sequenceRestart.

  • A sender that re-anchors its sequence far behind prevSN still had to wait out the full sequenceRestartRun (20). On a captured PBX transfer (same SSRC, 21294 → 12676) that is ~380 ms of dropped audio for packets that cannot be late: they are 8618 behind, well outside the 3000-packet reorder window.
  • When the first expired packet of a run is outside withinRange(sn, prevSN), the run only needs farSequenceRestartRun (2). The resync still goes through restartStream(), so SequenceRestarts, the flush and the drop counters are unchanged.
  • It still takes 2 packets, not 1, so a single stale packet from far behind cannot rewind the stream. A run that starts inside the window keeps the 20-packet rule, so TestSequenceRestart / TestSequenceRestartFalsePositive are unaffected.

Tests

  • TestSequenceRestartFar: the captured jump. It resyncs after 1 dropped packet. On main it drops 19.
  • TestSequenceRestartFarStray: a lone far-behind packet is dropped and the live stream carries on with no restart.
  • go test -race ./jitter/ passes. (TestResample in the root package fails under -race on main too. It is unrelated.)

Related

🤖 Generated with Claude Code

@CLAassistant

CLAassistant commented Sep 2, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@hechen-eng

Copy link
Copy Markdown
Contributor

within the window is probably not gonna fix everything. We do see traffic that restarts sn but still within range. #95

@hechen-eng

Copy link
Copy Markdown
Contributor

@ahsang we took a different approach, see #93 and #95. Can you rebase and make the change in sequenceRestart, e.g. shorten the required run when the first expired packet lands outside withinRange? this way we can keep the counters/flush, etc 👍

A sender that re-anchors its sequence far behind prevSN (a PBX transfer on
the same SSRC: 21294 -> 12676 on a captured call) cannot be sending late
packets, yet it still waited out the full 20-packet sequenceRestartRun.
A run whose first expired packet is outside withinRange of prevSN now
needs only farSequenceRestartRun (2): one packet lost instead of 19, while
a lone stale packet still cannot rewind the stream.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ahsang
ahsang force-pushed the fix/jitter-backward-discontinuity branch from 6df53d3 to 902b037 Compare September 23, 2026 20:49
@ahsang ahsang changed the title jitter: treat a large backward sequence jump as a discontinuity jitter: shorten the restart run when it starts beyond the reorder window Sep 23, 2026
@hechen-eng
hechen-eng merged commit 48db1a4 into livekit:main Sep 25, 2026
2 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants