Skip to content

6.25.1 - A pump that produced nothing says so

Choose a tag to compare

@superuser404notfound superuser404notfound released this 13 Aug 13:52
· 800 commits to main since this release

Drop-in from 6.25.0. One arm added on the loopback VOD path, no API change.

A pump that produced nothing now says so, whatever killed it

isFatalVODPumpExit decides that a non-live pump exit with nothing ever produced (no packets written, empty segment cache) is a dead source: the playlist exists, no segment will ever land, and AVPlayer parks in waitingToPlay forever unless it surfaces. That reasoning, from #126, is entirely about what the pump produced. The guard on it also required case .readError, which does not follow from it, and in the meantime nothing called the predicate at all: the read-error arm had grown its own inline copy of the same decision, leaving the tested predicate as dead code.

So a source that reaches EOF having written nothing fell through every arm on the way out. Measured on such a file: reason=eof packetsRead=322 packetsWritten=0 cacheCount=0, then 404 init.mp4 empty from the provider, and the host reporting state=playing phase=rebuffering for the whole session, with nothing in it to act on. It now reports state=error("Source produced no playable media (code -5)") in about a second.

The gate-starvation re-anchor (#169 round 3) reports whether it actually re-anchored, so a spent budget or a keyframe that maps to no plan segment falls through to that same surface instead of ending on a bare return. That is the third arm of this shape found in this file after 6.25.0, and the pattern is worth naming: an exhausted recovery that returns silently leaves a session no one can distinguish from a slow one.

What keeps this safe is the produced-nothing condition rather than the exit reason. An ordinary EOF after real playback carries packets and segments and is untouched (the control fixture still reaches state=ended), teardown is excluded, and every reason that owns its own recovery arm returns before this decision is reached.

How it was found

While checking whether #365 needed an AVC counterpart. It does not: matroskadec.c routes every video codec except HEVC through libavformat's parser, so an H.264 file whose config record and packets disagree cannot be demuxed at all, with or without the 6.25.0 framing repair, and there is nothing left for an engine-side fix to act on. That file is, however, exactly the shape above: demuxable enough to open, incapable of yielding a keyframed packet, and previously silent about it.

1827 swift-testing plus 504 XCTest green, tvOS build clean.