Skip to content

fix(software-live): report the edge rebuffer and catch up after a pause - #882

Open
jpsts wants to merge 1 commit into
superuser404notfound:mainfrom
jpsts:fix/software-live-edge-rebuffer
Open

jpsts wants to merge 1 commit into
superuser404notfound:mainfrom
jpsts:fix/software-live-edge-rebuffer

Conversation

@jpsts

@jpsts jpsts commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

Summary

A live source that pauses for a while no longer leaves the software host's playbackPhase at .playing over a standing picture, and a source that comes back by handing its whole backlog over at once no longer leaves the picture the length of the pause behind the newest media.

What changed

  • SoftwarePlaybackHost.isRebuffering (new, published) follows the pumps' hold: the live feeder's dry ring at the edge (AU live tv #107) and the on-demand loop's exhausted audio lead. The engine folds it into isBuffering exactly as it folds the audio host's wait, so playbackPhase reads .rebuffering from the moment the clock stops. Before, the phase stayed .playing until the reader's own stall timeout promoted the source to .stalled, 20 s later. Measured with a host app that tears a session down on a frozen clock: it reloaded after 2 s, and each fresh join landed 4 s behind the same frozen connect burst, so the viewer saw the last seconds again three times over before the feed came back. With the phase published, the host can tell a paused source from a dead session.
  • After an edge rebuffer resumes, the feeder watches what the source hands over with SoftwareLiveJoinPolicy (from the clock instead of the ring's first packet). A backlog worth skipping moves the picture up to the join lead behind the newest media through the engine's own .liveRejoin seek (SoftwarePlaybackHost.liveResumeCatchUp); a source that skipped what it missed is left where it resumed.
  • Docs: architecture.md (playback status, live audio look-ahead), api.md ($playbackPhase row). CHANGELOG under Unreleased › Fixed.

Test plan

  • SoftwareLiveJoinPlacementTests: a backlog handed over at once after a pause is caught up the lead behind the newest media; a source that skipped its backlog stays put.
  • Full suite passes on a Mac; Scripts/check-doc-links.py passes.
  • Field: a Mac on macOS 26 playing an IPTV panel's live MPEG-TS channel through feed pauses of about 20 s. The host app's log shows the stall phase within 2 s of the underrun instead of its own reloads, and the picture continues on the same session when the feed resumes.

Checklist

  • Conventional commit
  • CHANGELOG and docs in the same commit
  • Tests in the topic's existing file
  • Scripts/check-doc-links.py passes

A live source that paused left the software host's phase at `.playing`
over a standing picture: the feeder parked the synchronizer to refill
but published nothing, and only the reader's own stall timeout, 20 s
later, promoted the source to `.stalled`. A host app watching the clock
reloaded the session after 2 s; each fresh join landed the lead behind
the same frozen connect burst, so the viewer saw the last four seconds
again, three times over, before the feed came back.

`SoftwarePlaybackHost.isRebuffering` now follows the pumps' hold (the
live feeder's dry ring, the on-demand loop's exhausted audio lead) and
the engine folds it into `isBuffering` as it does the audio host's wait,
so `playbackPhase` reads `.rebuffering` from the moment the clock stops.

A source that resumes by handing its whole backlog over at once also
left the picture the length of the pause behind the newest media, on a
path that never catches up. The feeder now watches a resume with the
join's own rule (`SoftwareLiveJoinPolicy`, from the clock) and, once the
backlog has landed, moves the picture up to the join lead behind the
newest media through the engine's `.liveRejoin` seek; a source that
skipped what it missed is left where it resumed.
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.

1 participant