Skip to content

6.25.3 - A set can take its end back

Choose a tag to compare

@superuser404notfound superuser404notfound released this 14 Aug 08:30
· 692 commits to main since this release

Drop-in from 6.25.2. One fix on the PGS subtitle path, no API change. Reported, diagnosed and retested by @rrgomes in #362, which this is the second round of: 6.23.1 fixed the ends that reached a set from its own clear, and this fixes the ones that reached it from the far side of a stretch nobody read.

The answer was in the store, and it was final

A PGS display set has no end of its own; whatever packet follows on the stream closes it. Since 6.23.1 an open set takes the PTS of the next packet the store holds, which is the end the author put there and is available from the harvest long before the drain window reaches it.

After a seek burst the store also holds islands an earlier run harvested, so the first packet after a set can be a real packet that is not this set's successor. Two from the report, on a 4K HEVC Dolby Vision Profile 7 title after nine seeks in twelve seconds: a set at 75.117 s closed at 144.978 s with its own clear at 78.579 s, and a set at 145.187 s closed at 223.306 s, which is not a clear at all but the next set, 78 s out.

Publishing that packet is still right. The true successor can only be nearer, so the answer is an upper bound, and the alternative is a placeholder window that renders until something else closes it. Refusing was measured end to end in the first round and was worse (4 to 5 late ends per run against 0 to 2, worst by 74 s), because an open cue is laundered by the next seek into the reconstruction boundary. That boundary sits 15 s behind the landing, which on this round's worst fixture cue works out at +46 s against the island answer's measured +37 s.

What was wrong is that it was final. The close ran only over cues still carrying the placeholder window, so the moment a set took any end short of it, it was never revisited, and the clear that lands a second later, whose entire job is to trim that set, found a cue it was no longer allowed to touch. Nothing else was going to correct it either: the drain cursor moves forward only, so a packet that fills a hole behind it is never decoded and its pgsTrimAt never runs. A bitmap set has no end of its own, so every stored packet after it is a bound on its end and taking the nearest is monotone. The derivation now runs every tick and can only ever shorten, which is what makes the bound self-correcting rather than merely bounded. Text cues keep the placeholder gate: an authored duration is nobody else's to set.

A horizon, because the store cannot answer where it has been

The derivation walked the whole retained window with no bound at all, so it could answer with a packet the drain was not even looking at. It now stops at the drain window plus the forward prefetch's park margin, which is exactly as far as the harvest is designed to lead the drain, and which is why that margin exists (6.23.1, so the set at the window's forward edge has its own clear stored). Inside it, a stored packet is evidence the harvest was here and found this. Beyond it, the store holds whatever earlier runs left behind. The report's second case is 18 s past the window's edge and is now withheld, so the clear 5 s after the set wins the race it was losing.

Withholding is the only option that needed a bound, because the property it wants is not one the packets can carry. Whether the ground between a set and a stored packet was ever read is not a function of what arrived: a reader restarted BEHIND leaves a descending harvest sequence at the boundary, which is the discriminator 6.23.1 introduced, and a reader re-anchored FORWARD leaves an ascending one across the ground it skipped. On the fixture that reads as sequence 19, then 20, with 46 s of unread source between them. That one-sidedness is also why the harvestHole line stayed silent through all of this, which the report noticed and asked about.

It has no consequence on the delivery side, and that was measured rather than assumed: the ground a forward re-anchor skips lies behind the playhead that caused it, delivery deliberately never waits on a hole behind the playhead, and a return to that ground is a seek, which restarts the pump there and fills it. Across three seek shapes on the fixture, every authored set in the stretch the playhead actually played was delivered (23/23, 15/15, 13/13), including one run whose store carried that exact 46 s gap.

Diagnostics

A tick now reports endsWithheld=N when it left bitmap cues open because the only answer lay past that horizon. harvestGapAt reports where DELIVERY stopped and says nothing about an end derived from the same store on a different horizon, so a window carrying a wrong end with no gapAt beside it had no line of its own at all.

aetherctl play gained DROP #id and a closing WINDOW census next to its CUE and TRIM lines. It reported arrivals and end changes and nothing for a cue LEAVING the window, so a wrong end that a later reconstruction replaced read exactly like one the host still carries, which made the first two rounds of measurement here worthless.

Not fixed, and named

For a region a session abandons, no signal in the engine can produce the authored end: the ground is never read, so the nearest stored packet stays the best bound anyone has. On the fixture that leaves ends up to +37 s in a burst that never returns, unchanged from 6.25.2 and unchanged by any of the alternatives measured.

Measured

400 s H.264 fixture with a real PGS stream repeated every 26 s, 80 authored sets, clears 3.5 to 4 s later, served through an origin with a 250 ms delay on every request. Loopback cannot show this: it refills an island before the island can matter, and every arm reads identical there. Three runs per arm of the report's own recipe, scrub hard then land before a dense stretch and play through: 8 of 10 wrong ends corrected before, 9 of 10 after, and 9 of 9 on the release build.