6.6.0 - Live carriage read from the source, native layer public
Minor rather than patch because #288 adds two public read-only properties. Everything else in here is behaviour, and three of the four items come from @kskchaitanya1993, two of them as patches that had been carried downstream against every release.
Added
nativePlayerLayer,softwareHostFramesEnqueued. Read-only, no behaviour attached.AVPictureInPictureControllerwants anAVPlayerLayerrather than anAVPlayer, and the software path has published its layer since 5.13.0, so a host rendering throughbind(view:)had no route to the native layer already on screen and had to mount a second one to get there.nativePlayerLayeris nil outside a native session, which is also the honest signal for hiding a PiP button.softwareHostFramesEnqueuedwas already the engine's own answer to "are frames reaching the display layer" (LiveTelemetrySamplersamples it at 1 Hz) and simply was not public in a Release build: a host watchdog getsAVPlayerItemVideoOutput.hasNewPixelBufferon the native path and had nothing to ask on the software one, so it read every dav1d / libavcodec session as picture-less. Monotonic within a session, restarting at zero when aload()builds a new host (#288).
Changed
-
A live HEVC-in-MPEG-TS channel reaches the ingest without paying for a doomed native mount first. The carriage verdict used to come only from the #168 watchdog, which needs a full mount, readyToPlay and a 4 s grace before it can conclude that AVPlayer will never build a video track, so every first open of such a channel spent that grace as audio over black, in every process. The same question is now answered from the source itself, the playlist plus the head of one segment (the evidence chain #268 already uses for finite VOD), read concurrently with the mount so nothing is serialized in front of first frame. A master advertising H.264 never reaches the network for it, and a live media playlist URL with no master to judge is covered for the first time: its carriage was structurally unjudgeable before, which left it audio-only indefinitely. A video track that does build still wins at any point, so no working session is taken off the native path (#293).
Measured against a request-logging live origin with keyframe-aligned MPEG-TS segments:
origin verdict cost outcome master CODECS="hvc1...", HEVC in TShevcInMPEGTS1 master + 1 media playlist + 1 ranged segment head reroutes 4.0 s before the grace would have concluded it media playlist, no master, HEVC in TS hevcInMPEGTS1 media playlist + 1 ranged segment head same, the case the watchdog could not reach master CODECS="avc1...", H.264 in TSprobe never runs 0 requests stays native master + EXT-X-MAPotherCarriage0 segment fetches stays native master + EXT-X-KEY:METHOD=AES-128inconclusive0 segment fetches stays native
Fixed
- No play-gate wait for a display switch Match Content cannot start. With Match Content off,
waitForSwitch()still ran its poll on the path that gatesplay(), and nothing in that state can start a switch:apply()declines to write the criteria, and tvOS ignores a sole-writer host's AVKit write just the same. That budget was dead startup time on every load, 200 ms for an engine-writer host and 1000 ms for a sole-writer host on HDR / DV. The guard reads the toggle live off the display manager rather than the host'sLoadOptionssnapshot, which can be stale in the direction that matters, and the skip line names the budget it dropped. Sessions with Match Content on are untouched (#289). - A pixel aspect ratio is judged by the picture it produces, not by its own magnitude.
saneSARbounded each component to 256, which catches the pathological values and admits small-but-wrong ones: a live 1080p H.264 channel declaring 3:1 cleared it and smeared 1920x1080 into a 5.33:1 band. No bound on the ratio itself works, since 2:1 is a standard VUI value that is exactly right on a 960x1080 broadcast frame and the reported defect on 1920x1080. The display aspect the ratio resolves to on the frame it applies to is now bounded to 1:3 ... 3:1, a rejected candidate falls through frame to codec context to stream rather than ending resolution, and the FrameExtractor resolves through the same policy (#290). - A container-declared pixel aspect ratio reaches the decoder. The software path's container-SAR fallback read
codecpar->sample_aspect_ratioalone, which is the one place a container ratio never lands: Matroska writes its DisplayWidth quotient tost->sample_aspect_ratio, MP4 does the same withpasp. The fallback was dead in exactly the case it was written for, and MPEG-2 sources hid it because their ratio arrives per frame from the sequence header. A 960x1080 VP9 MKV declaring 2:1 drew at coded dimensions and now draws 16:9. A container ratio still runs the gates above like any other.
Tooling
aetherctl play --live --native-hls reaches the nativeRemoteHLS bypass, which no subcommand could do before, and hlsfixture gained --codecs / --resolution plus a request log. Without variant attributes AVFoundation reports no video for a master, so a fixture missing them runs green while exercising nothing.