6.42.0 - A landing line has to stand on ground somebody read
Drop-in from 6.41.0. No API change. One behaviour change: a PGS set can no longer claim a seek landing over source nobody read.
A landing line has to stand on ground somebody read
@rrgomes reported a caption that survives a re-aimed restart: on the 6.40.0 path, a coalesced far seek lands on target and the overlay comes up carrying a set from half a minute earlier, closed at the far side of the authored silence instead of at its own clear. Two devices, same asset, same day: an Apple TV 4K and an M4 Pro under a controlled repro (drain target 199.1, boundary re-aimed twice, gate open at 191.983, the 187.729 set standing over the scene at 199.4).
A PGS display set has no end of its own, so the reconstruction pass at a landing decides which set is still on screen by the store holding nothing between that set and the playhead. Over a stretch nobody read, that silence is not evidence. A run re-aimed just after it harvested a set leaves the set's own clear inside the ground the re-aim skipped: it decodes at the landing looking unclosed, becomes the landing's active line, and alignCueEnds then closes it at the next stored packet, which is the far side of the silence rather than its successor.
The report's premise about the store is worth correcting because it changes the fix: the packet store does not prune behind the producer. Since #125 its retention is byte-bounded only (32 MiB per stream, evict-oldest); the time-based prune was removed precisely because a backward seek into cache-resident content could land on packets it had evicted. The clear was not dropped, it was never read.
#362 round 2 measured that the packets alone cannot show this. A reader restarted BEHIND leaves a descending harvest sequence at the boundary, which is what harvestGapCut reads; one re-anchored FORWARD hangs its packets in ascending order behind the stretch it skipped, so the pair is indistinguishable from an authored silence. The coverage ledger was named there as the precise signal and left unbuilt for want of a reproducible defect. This is that defect, so it is built now.
SubtitleHarvestCoverage keeps one span per harvest run inside the packet store. The forward prefetcher reports its anchor, every in-place re-anchor and its read position as it goes; the pump's run begins where the producer opens or restarts (native and software paths) and reaches at least the playhead, since playback is rendering there, plus every packet it harvests. A set whose ground up to the playhead is not covered can no longer be the landing's active line, and the same rule closes the #100 stale hold's door onto the identical claim. A store nobody reports coverage to answers every span with yes, so a harvest path without notes behaves exactly as it did before.
The cost is the landing line in the case where a set really is still up and the proof is missing, which takes an authored dwell long enough to span the whole unread stretch. The alternative was paying it for every normally authored set that ends inside one.
Neither of the two shapes the report offered was taken. A PGS dwell cap is an end nobody authored, and it would have to be short enough to cut a two-second caption off before the landing while cutting a long sign short in the same file; three rounds of #362 went into removing laundered ends rather than adding one. A one-shot backfill of the skipped ground is the better of the two and the ledger makes it possible, but it spends a read on a link that has just paid for a seek, and it buys nothing the refusal does not in the reported case: the authored state at the landing is an empty screen either way.
Measured
500 s H.264 + PGS fixture with a scheduled sup (set at 184, authored clear at 190, then silence to 240), served over a loopback origin, seeking from 100 to 197 so the initial run's park edge falls between the set and its clear while the restarted pump opens at 192, above it. Counted over 10 runs per arm:
| arm | landing tick met the hole | stale CUE 184.00-240.00 |
landingWithheld= |
authored set at 240 |
|---|---|---|---|---|
| 6.41.0 | 4/10 | 4/10 (every one of them) | 0/10 | 10/10 |
| 6.42.0 | 6/10 | 0/10 | 8/10 | 10/10 |
Whether the landing tick meets the hole is a race with the re-anchored side reader, which
repositions to target - 2 on the subtitle axis and so re-reads the clear it lands on; that is the
correction the report saw arriving after about seven seconds on the Mac and after tens of seconds on
the Apple TVs. The rows above are the same race on both arms. The refusal count is higher than the
hole count because the ground between the set and the playhead is unread in every run, whether or
not the clear has arrived by the time the tick decodes it; where it has, the outcome was already
correct and the refusal changes nothing.
Controls, unchanged in both arms: a far seek into fresh ground landing inside an authored dwell still publishes its line (CUE 292.00-295.50), and a plain playthrough delivers the same cues with no withholding.
A refusal names itself as landingWithheld=N on the #357 subtitle-delivery line, beside endsWithheld=.
2055 tests green (16 new), tvOS, iOS and visionOS Simulator builds green.