Skip to content

AetherEngine 1.4.1

Choose a tag to compare

@superuser404notfound superuser404notfound released this 25 May 17:53
· 437 commits to main since this release

Fixes

Gate play() on panel handshake settle

In an AVKit-sole-writer architecture (host sets appliesPreferredDisplayCriteriaAutomatically = true and passes LoadOptions(suppressDisplayCriteria: true)), AVKit writes preferredDisplayCriteria from the live AVPlayerItem.formatDescription after asset.load reaches readyToPlay. The HDMI handshake kicks off a beat later than the engine's synchronous pre-flight would have, and nativeHost?.play() was firing before the panel finished switching into the target dynamic range. On DV / HDR sources this surfaced as a first-frame stall on the cold path.

Two changes:

  • DisplayCriteriaController.waitForSwitch Stage 1 grace extended from 200 ms to 1000 ms so the later-firing AVKit auto write is reliably caught by the gate's first-stage poll.
  • await displayCriteria.waitForSwitch() inserted before every nativeHost?.play() call (initial load path + audio-track-reload path). The 1.4.0 two-stage poll's existing logic handles both "panel already in target mode" (early return via currentEDRHeadroom > 1.001) and "switch in progress, wait for completion".

The gate is path-agnostic. Engine-sole-writer architectures continue to use the engine's pre-flight + waitForSwitch. AVKit-sole-writer architectures now get the same handshake guarantee, just with AVKit driving the criteria write instead.

Docs

README now credits @DrHurt for the on-device DV / HDR matrix testing.

Acknowledgements

Once again, @DrHurt for the diagnosis on #4: "I don't know if readyToPlay waits for display switch. If not, we could possibly gate play() on waitForSwitch / isDisplayModeSwitchInProgress." That's exactly the contract this release implements.


Full changelog: 1.4.0...1.4.1