AetherEngine 5.20.0
Fixed
A #168-rerouted live session that loses its ingest now recovers in-engine instead of cycling through the doomed native mount (#199)
When the live-ingest loopback session behind the #168 reroute (HEVC-in-MPEG-TS masters that AVPlayer plays audio-only) lost its source mid-session, the pump exit delegated straight to a host retune. A host that answers by re-tuning the same URL relanded on the native bypass, which deterministically builds no video track for that master, so the session re-ran the whole reroute dance (native mount, ~4 s carriage-watchdog grace, reroute, loopback rejoin) roughly every 13 s. The trigger class is real beyond test-beds: MEDIA-SEQUENCE resets from encoder restarts, CDN gaps that outlive the refresh-retry budget, and upstream ENDLIST all funneled into the same teardown.
Three layers, from source to session:
- MEDIA-SEQUENCE reset rejoin. The ingest playlist tracker treats three consecutive refreshes whose whole window sits behind the cursor as an axis reset and rejoins at the new edge under an
EXT-X-DISCONTINUITYseam, instead of starving the reader into itsingestStalledterminal. Isolated stale-CDN-edge regressions do not trip it, and regressions never feed the stall counter. - Reroute verdict memory. Masters whose video-carriage watchdog fired are remembered (bounded to 32 entries, 6 h expiry, exact-URL keyed). A later
load()of the same URL under the same gates (live, ingest fallback enabled) routes straight onto the live-ingest loopback, skipping the doomed native mount and its watchdog grace entirely. Survives stop()/load() seams, so zap-away-and-back stays cheap. - In-session reopen for engine-created ingest readers.
eof/readError/keyframeStarvationpump exits on an engine-createdHLSLiveIngestReadersession now rebuild a fresh reader through the existing bounded live-reopen machinery (fresh demuxer over the new reader, continuation segment indices, discontinuity seam) instead of tearing the player session down. Only an exhausted reopen budget (attempt cap or barren cycles) halts production and surfacesliveSourceReset, so hosts keep their last-resort retune signal. Host-provided custom readers (disc, SMB) and demuxed-audio companion sessions keep the immediate host-retune contract.
New public surface (hence the minor bump): HLSVideoEngine.CustomSourceReopenFactory. Behavior of LoadOptions.nativeRemoteHLSIngestFallback is unchanged; hosts that opted out of the #168 fallback are never silently rerouted by the verdict memory either.
Covered by Issue199RerouteRecoveryTests, extended HLSPlaylistTrackerTests, and the reopenable-semantics update in LiveProductionHaltTests.
Acknowledgements
Thanks to @kskchaitanya1993 for the deep-window field trace on #189/#199 that separated this defect from the live-edge holdback fix and pinned the ~13 s cycle end to end.