A direct-ingest live channel plays for about a minute and then rebuffers once, briefly, with the source never actually stopping. Captured on iOS 26.6 against Red Bull TV (rbmn-live.akamaized.net, 6 s upstream segments).
The upstream publishes 6 s of media per batch, but not every 6 s. Measured from one minute of live seg-N finalized lines, the interval between batches:
6.66 6.66 9.86 6.56 6.84 9.80 3.55 6.85
Each batch delivers exactly 6.0 s of media, so the deficit per batch is gap - 6, and it ACCUMULATES:
0.66 1.32 5.18 5.74 6.58 10.38 7.93 8.78
The chain's total slack is 12 s: the ingest joins 1.5 x upstream TARGETDURATION behind the upstream edge (2 segments, [HLSIngest] joined 2 segment(s), ~12s behind the live edge), and AVPlayer then joins at our own 3 x TD holdback, which on a 12 s window is the start of it. An AVPlayer playing at 1x therefore eats that slack at the rate the deficit accumulates, and at 10.4 s of it the runway is gone:
17:30:14.560 #446 the source has missed its cadence (quiet 9.55s, it delivers every 6.84s);
the consumer is at the end of what the window holds, so there is no runway
17:30:17.303 #1 playbackStalled
17:30:17.305 #1 timeControlStatus=waitingToPlay reason=AVPlayerWaitingToMinimizeStallsReason t+56.21s
17:30:18.678 #1 timeControlStatus=playing reason=- t+57.58s
1.4 s of stall, 57 s into the session, with the source delivering normally either side of it. HLSPlaylistTracker's own doc states the intent the 1.5x term was chosen for: "at least one upstream cadence of buffer across the bursty inter-batch arrival gap". One cadence is the right unit and one of them is not enough: this source's gaps run 10 to 65% over its segment length, repeatedly and in the same direction, so the deficit is cumulative rather than self-correcting.
The same log shows the second half of it. TARGETDURATION sealed at 4 s from measured floor 6.000s, which is the upstream's ADVERTISED segment length, and the arrival meter later reads the true rhythm as 6.84 s:
17:29:21.469 live TARGETDURATION sealed at 4s (holdback 12.000s): max EXTINF 3.000s,
1.5 x cut target 0.750s, measured floor 6.000s needs 4s of patience;
upstream advertises 6.000s (reported, not used)
1.5 x 4 = 6.0 s of client patience against a 6.84 s rhythm, so AVPlayer drew -12888 Playlist File unchanged three times in the captured minute. The advertised duration bounds the cadence from BELOW (a batch cannot arrive faster than it is cut, but it can arrive later), and it was used as if it bounded it from above.
Both halves are the shape AE#523 fixed one level up: a number derived from the nominal segment length where the measured delivery rhythm was the honest input.
Expected: a source that keeps delivering, however unevenly, does not rebuffer, and does not make the client draw -12888 on its ordinary rhythm.
The cost of the obvious fix is latency behind live and is worth stating: covering three upstream cadences instead of one and a half puts the viewer one upstream segment further back. HLSPlaylistTracker's own A/B says first picture does not pay for it (both arms fetch to the same upstream segment at the same wall clock, the backlog is caught up at I/O speed), so the cost is the standing distance from live and nothing else.
A direct-ingest live channel plays for about a minute and then rebuffers once, briefly, with the source never actually stopping. Captured on iOS 26.6 against Red Bull TV (
rbmn-live.akamaized.net, 6 s upstream segments).The upstream publishes 6 s of media per batch, but not every 6 s. Measured from one minute of
live seg-N finalizedlines, the interval between batches:Each batch delivers exactly 6.0 s of media, so the deficit per batch is
gap - 6, and it ACCUMULATES:The chain's total slack is 12 s: the ingest joins
1.5 x upstream TARGETDURATIONbehind the upstream edge (2 segments,[HLSIngest] joined 2 segment(s), ~12s behind the live edge), and AVPlayer then joins at our own3 x TDholdback, which on a 12 s window is the start of it. An AVPlayer playing at 1x therefore eats that slack at the rate the deficit accumulates, and at 10.4 s of it the runway is gone:1.4 s of stall, 57 s into the session, with the source delivering normally either side of it.
HLSPlaylistTracker's own doc states the intent the 1.5x term was chosen for: "at least one upstream cadence of buffer across the bursty inter-batch arrival gap". One cadence is the right unit and one of them is not enough: this source's gaps run 10 to 65% over its segment length, repeatedly and in the same direction, so the deficit is cumulative rather than self-correcting.The same log shows the second half of it. TARGETDURATION sealed at 4 s from
measured floor 6.000s, which is the upstream's ADVERTISED segment length, and the arrival meter later reads the true rhythm as 6.84 s:1.5 x 4 = 6.0 sof client patience against a 6.84 s rhythm, so AVPlayer drew-12888 Playlist File unchangedthree times in the captured minute. The advertised duration bounds the cadence from BELOW (a batch cannot arrive faster than it is cut, but it can arrive later), and it was used as if it bounded it from above.Both halves are the shape AE#523 fixed one level up: a number derived from the nominal segment length where the measured delivery rhythm was the honest input.
Expected: a source that keeps delivering, however unevenly, does not rebuffer, and does not make the client draw
-12888on its ordinary rhythm.The cost of the obvious fix is latency behind live and is worth stating: covering three upstream cadences instead of one and a half puts the viewer one upstream segment further back.
HLSPlaylistTracker's own A/B says first picture does not pay for it (both arms fetch to the same upstream segment at the same wall clock, the backlog is caught up at I/O speed), so the cost is the standing distance from live and nothing else.