Skip to content

AetherEngine 1.4.0

Choose a tag to compare

@superuser404notfound superuser404notfound released this 25 May 15:30
· 439 commits to main since this release

Features

LiveTelemetry

1 Hz diagnostic sampler covering both the native AVPlayer and software dav1d / VP9 paths. Exposes per-second snapshots of:

  • Producer restart count
  • Last A/V gap measurement (audio gate vs video gate, ms)
  • Local HLS server request count
  • Frames enqueued into the software path's display layer
  • Process resident memory

New LiveTelemetry value type plus AetherEngine.liveTelemetry published surface for hosts to consume. Powers Sodalite's "Stats for Nerds" overlay.

FFmpeg log bridge

av_log output now routes into EngineLog under the .ffmpeg category instead of going straight to stderr. Lets hosts (Sodalite's diagnostic overlay, aetherctl) pipe FFmpeg's internal noise through the same channel as engine logs, with category-level filtering. (#17)

Fixes

waitForSwitch async-handshake race

DisplayCriteriaController.apply() writes preferredDisplayCriteria and then immediately calls await waitForSwitch(). The setter is async-initiated, so the HDMI handshake kicks off a beat after the setter returns. The previous guard isDisplayModeSwitchInProgress else { return } mis-classified that window as "no switch needed" and bailed, letting asset.load proceed while the panel was still in its old mode. On DV / HDR sources this surfaced as AVPlayer -11848 "Cannot Open".

Replaced with a two-stage poll:

  1. Stage 1 (200 ms grace, 10 ms ticks): wait for isDisplayModeSwitchInProgress to flip true, OR for UIScreen.currentEDRHeadroom > 1.001 (panel was already in HDR mode and no transition is needed).
  2. Stage 2 (5 s cap, 100 ms ticks): wait for the switch to complete, then sanity-check currentEDRHeadroom to confirm the panel reached HDR. Warns if not.

Engine-sole-writer architectures can now rely on waitForSwitch as the actual gate, not just a "no in-progress switch right now" check.

Audio codec tag for Atmos JOC on iOS

EAC3 + JOC (Atmos) content now emits the correct ec-3 codec tag in the HLS manifest on iOS too. Was native-tvOS-only before. (#16)

externalMetadata applied on iOS

Now Playing artwork, title, and dynamic range hint via AVPlayerItem.externalMetadata now propagate on iOS in addition to tvOS. (#15)

Muxer interleaver drain

libavformat's interleaver buffer is now explicitly drained before each fragment cut. Was leaving samples queued in the muxer between fragments, surfaced as occasional missing audio at fragment boundaries. (#14)

Docs

README now documents the LiveTelemetry surface, sampler timing, and host integration points.

Acknowledgements

Big thanks to @DrHurt for the relentless on-device DV / HDR testing across builds 159 through 172 in #4. His matrix of panel-mode + match-content combinations exposed the waitForSwitch race, and his hunch that play() should gate on isDisplayModeSwitchInProgress is exactly the contract the two-stage poll now implements.


Full changelog: 1.3.2...1.4.0