Skip to content

AetherEngine 5.20.1

Choose a tag to compare

@superuser404notfound superuser404notfound released this 23 Jul 04:23

Fixed

The restart scan-forward gate now opens on keyframe presentation time, so the tail of a B-frame VOD file is producible again instead of starving to EOF (#169, round 3).

Root cause

The gate that scans for a restart's anchor keyframe compared packet dts against a plan-boundary PTS (segmentPlan[baseIndex].startPts, a Cues timestamp). Under B-frame reorder a keyframe's dts sits a reorder delay below its own pts, so the gate dropped the exact IRAP the restart seeked for. This is the same defect class the #92 cutter fix removed from segment cutting; the pregate kept the dts comparison.

Mid-file the next IRAP rescued the miss one GOP late (subtle content misalignment). At the file tail there is no next IRAP, so the unbounded VOD gate dropped every remaining packet to EOF and the pump exited with packetsWritten=0, leaving the final segment unproducible under any anchoring. The 5.19.1 forward-wait escalation worked exactly as intended, but every restart it fired landed in the same starve (still waiting for video keyframe: dropped=200 lastDts=2880419 isKey=false target=2878501 into pump finished: reason=eof packetsWritten=0).

Fix, three layers

  1. pts-based gate (videoGateTargetSatisfied): packets are judged by presentation time (dts fallback for NOPTS), so the anchor IRAP opens its own segment. Byte-identical behavior for dts==pts sources.
  2. Starved-EOF re-anchor: a VOD pump whose gate starves to EOF proves no runtime keyframe exists at or after the targeted boundary (tail Cues drift, or a Cues entry whose block is not key-flagged at demux). The engine re-anchors production on the segment of the last keyframe the gate dropped (bounded), so the tail content gets produced and end-of-media completes through the 5.16.2 tail-park instead of dying at -12889.
  3. Readiness-gate liveness: the #35/#169 startup data-wait consults pump liveness. Production that already exited with nothing served fails over immediately instead of riding 8 rounds (24 s) behind a "still producing over a slow link" message describing the opposite of reality.

Expected retest signatures (5.20.1)

  • Tail playthrough and tail resume: video gate open: ... anchorPts=... at the tail anchor, the final content producing, and a clean tail-park completion instead of -12889.
  • If the tail boundary has no runtime keyframe at all: #169 VOD gate starved to EOF at segN: no keyframe at/after the plan boundary; re-anchoring on the last real keyframe (pts=...) -> segM, then the tail-park completion.
  • Sub-second tail resume with dead production: #169 readiness gate: production already finished with no data served; skipping the data-wait (not a slow link).

Acknowledgements

Traced across three rounds with exemplary lifecycle logs and a correct mechanism analysis each round by @rrgomes.

Verification

New Issue169GateStarvationTests (7) plus extended StartupReadinessGateTests (+2), TDD red-to-green; full suite 975 tests / 160 suites green; -strict-concurrency=complete clean; tvOS and iOS Simulator builds green.