Skip to content

AetherEngine 5.23.6

Choose a tag to compare

@superuser404notfound superuser404notfound released this 26 Jul 12:39

Patch release. One fix: a FLAC source whose STREAMINFO carries an illegal min_blocksize now plays instead of refusing to open.

Fixed

A FLAC source whose STREAMINFO declares an illegal min_blocksize plays instead of failing to open

A 1080p H.264 file with FLAC 5.1 never started. The master and media playlists were served, init.mp4 and seg0.mp4 were fetched, and then the item failed outright:

[HLSVideoEngine] audio: codec=flac -> stream-copy as `fLaC`
[NativeAVPlayerHost] item.status=failed err=AVFoundationErrorDomain/-11829 'Cannot Open'
[NativeAVPlayerHost] item.error.underlying=CoreMediaErrorDomain/-12848
[HLSLocalServer] send failed /seg0.mp4: errno=32

The same file played fine in QuickTime, which is what makes this look like missing FLAC support and is why it was reported that way. It is not: FLAC in fMP4 works, and the same file re-encoded to FLAC with a freshly written STREAMINFO plays untouched.

The source declares min_blocksize = 0. The FLAC specification requires at least 16, but 0 occurs in the wild: an MKV to MP4 remux copies the source CodecPrivate verbatim, and encoders that never rewrite STREAMINFO after a streaming pass leave the field zeroed. libavcodec's decoder ignores it entirely, so such a source demuxes, probes, and stream-copies without a single complaint anywhere upstream of the muxer. CoreMedia validates it and rejects the whole audio sample description.

Because stream-copy hands the source extradata straight to movenc, which serialises it into dfLa byte for byte, the defect reached every segment of the session rather than degrading one of them.

Bisected by patching individual STREAMINFO fields in the reporter's asset and replaying each variant:

Patch Result
unmodified Cannot Open
min_blocksize 0 to 8192 plays
total_samples corrected (it also describes the pre-cut source) Cannot Open
both plays

min_blocksize alone decides whether the session opens. Any plausible value works; 192, 1024, 2048, 4096, 4608 and 8192 were all verified. Only 0 is fatal, so nothing else in that STREAMINFO is worth touching, and touching it would risk a regression on sources that are merely unusual rather than invalid.

An illegal min_blocksize is now clamped up to max_blocksize, the only blocksize the container actually attests to, and every other STREAMINFO byte is left exactly as it was, md5 and total_samples included. When max_blocksize is illegal too there is nothing honest to clamp to, so the extradata passes through unchanged rather than carrying a value the engine invented.

The clamp sits in configureStreamsAndWriteHeader, the single path shared by the session muxer and the stream-copy pre-flight probe, so the probe cannot pass while the real muxer goes on to emit a box CoreMedia rejects.

One note for anyone writing tests against this: a STREAMINFO with both blocksize fields zeroed cannot be exercised through a fixture, because libavformat refuses to open such a file at all. That branch needs a hand-built codecpar.

Thanks to @bitxeno for the report and for attaching a sample that reproduced the failure exactly.