Skip to content

6.16.2 - A first frame the receiver is holding

Choose a tag to compare

@superuser404notfound superuser404notfound released this 09 Aug 15:09
· 889 commits to main since this release

One fix on the #315 first-frame signal, for hosts that gate presentation on it. Drop-in from 6.16.1, no API change.

The shape

hasFirstFrameReadyForDisplay (6.13.0) folds AVPlayerLayer.isReadyForDisplay on the native path and AVSampleBufferDisplayLayer.isReadyForDisplay on the software one. That layer is the whole basis for the statement, and on an external screen it never makes it.

Measured on a device, iPhone 17 Pro to Apple TV 4K, one session, seven loads:

Load Origin External playback layer.isReadyForDisplay
#1 loopback inactive true after 0.22 s
#2 LAN active never, 14 s
#3 loopback inactive true after 0.16 s
#4 loopback inactive true after 0.17 s
#5 LAN active never
#6 LAN, fresh title active never
#7 LAN, fresh title active never

Loads #6 and #7 are the ones that matter most: titles started while the receiver already held the route, so there is no earlier local frame to have latched on. A host lifting a black cover on this flag therefore covered the whole AirPlay session, not one load, and the failure reads exactly like the audio-only case hosts already carve out: a video session waiting on a frame that is never coming.

What changed

There is no local first frame coming while an external screen holds the picture, and no way to observe the receiver's screen, so the item's readiness is the honest edge: past it the picture is the receiver's business.

AetherEngine.shouldLatchFirstFrameForExternalPlayback(
    alreadyLatched:hasVideoDisplaySignal:isSessionReady:externalPlaybackHoldsThePicture:)

Deliberately not the clock advancing, which would hang the paused mount this signal exists for. Audio-only sessions still never arm it, so the flag stays usable as a video-only gate, and the seam rules stay the layer's: this only ever adds a rise, never a fall.

Wired HDMI takes the same latch. It flips isExternalPlaybackActive too and keeps no local picture either, it just needs no LAN reload.

Contract correction

The property documentation listed the AE#158 in-place handover among the seams the latch survives. It is not one of them, and the doc contradicted itself two lines earlier ("false at every load()").

The discriminator is the entry point, not the inPlaceSwap flag a swap is made with:

  • The media fallback, the wired-HDMI AirPlay master swap and the #93 recovery reload call host.load(inPlaceSwap:) themselves, reach no stopInternal, and keep the latch through their few tens of milliseconds without a picture. Unchanged.
  • The AE#158 handover is a full load(). It keeps the outgoing item attached so a system PiP window survives the teardown, which is what makes it look like the three above, but its content is new and has to reach its own first frame. Holding the latch there would lift a cover onto the previous episode's frozen frame.

Behaviour was already correct; the documentation was not, and a suite that only exercised the fold operator could not catch a mis-stated entry point.

Verification

3 new tests, 1661 tests in 243 suites green.

The AirPlay half is device-verified, not inferred: on the rebuilt LAN load the latch now lands 84 ms after the load starts, where before it never landed at all.

280.788  #2 load url=http://10.20.30.34:54276/master.m3u8
280.788  #2 layer.isReadyForDisplay=false t+0.00s
280.863  #315: an external screen holds the picture, so no local first frame
         is coming; latching hasFirstFrameReadyForDisplay at readiness
280.872  hasFirstFrameReadyForDisplay=true

Reported in #315 by @edde746.