Skip to content

5.6.2

Choose a tag to compare

@superuser404notfound superuser404notfound released this 17 Jul 18:52

Two fixes on the live-TV ingest path, both from a detailed report by @digilearn-dev (#133).

Fixed

Live H.264 mid-stream joins: no more green frames or dead channels (#133 A)

Joining a running MPEG-TS H.264 broadcast, the video gate opened on any keyframe-flagged packet without confirming a decodable IDR access unit. Two failure modes resulted:

  • Green flash. The gate opened on an open-GOP recovery point rather than a clean IDR, so the decoder rendered an uninitialized reference until the real SPS/PPS/IDR arrived.
  • Dead channel. When the demuxer's probe joined before any SPS, codecpar stayed 0x0; the first fMP4 muxer allocation fed those 0x0 dimensions into avformat_write_header, which failed with -22, and the pump exited muxerFailed (which on the live path has no recovery arm). The channel produced an empty #EXTM3U that never recovered without a manual zap away.

A live-only pre-gate, scoped to H.264 with Annex-B framing (MPEG-TS ingest; fMP4 live carries valid out-of-band avcC, and VOD probes the whole file up front), now withholds video until a packet carries in-band SPS + PPS and a true IDR slice. When that gating access unit opens the gate and the probe left dimensions unresolved, the muxer's video config is reconstructed from the in-band SPS/PPS, so write_header gets real dimensions instead of failing. A gate miss is covered by the existing bounded live keyframe-gate timeout (which reopens), not the terminal muxerFailed exit. The existing PTS-based gate and open-GOP RASL-drop logic are unchanged; this is an additional precondition ahead of them.

Same-format live zaps: no more full display-mode settle on every channel change (#133 B)

Zapping between two channels of the same format (e.g. two SDR 50 Hz channels) re-applied identical AVDisplayCriteria unconditionally. On panels whose Dolby Vision switch is unobservable to the app, that redundant write starts a mode switch that sticks isDisplayModeSwitchInProgress true, and the post-load settle wait then burns its full ~3s cap on every zap (ttff_ms 2.5-3.0s for liveZap).

The engine now retains the last-applied criteria and, when the incoming criteria are already active, skips both the redundant panel write and the settle wait, cutting that redundant latency to zero. This is an internal optimization: no new host-facing option, it benefits every consumer, and it can never skip a switch that is genuinely needed. Any zap that actually changes format, refresh rate, or dynamic range still applies and settles exactly as before.


Full test suite: 681 tests across 115 suites, plus strict-concurrency and tvOS-simulator builds.