What happened?
Playing an .avi file with codec=mpeg4 (XviD, "packed bitstream" variant) starts audio playback normally, but no video frame after the first one ever reaches the screen. The host app is left showing its loading spinner indefinitely while audio continues. No error is ever surfaced — AetherEngine's $state publisher never transitions to .error, so the host app has no way to detect or recover from this.
- AetherEngine version: 6.6.0 (Swift Package,
https://github.com/superuser404notfound/AetherEngine)
- tvOS 26.0, Apple TV 4K (3rd generation) Simulator, 1080p
- Swift 6.2, Xcode (tvOS 26.5 SDK)
- Host app integration:
AetherEngine() created per-playback, load(url:options:), $state observed via Combine — see reproduction context below.
Source file
Demuxer opened: 2 streams, duration=1292482883 us
stream[0] type=video codec=mpeg4 544x400
stream[1] type=audio codec=mp2
Delivered over HTTP (range requests, AVIOReader pump), .avi container, video track is MPEG-4 Part 2 (XviD) at 544×400, audio is MP2 at 44.1kHz/2ch. Filename: Sabrina, cosas de brujas 1x01 - El cumpleaños de Sabrina.avi.
Steps to reproduce
- Load and play an AVI file whose video track is a "packed" XviD/MPEG-4 bitstream (B-frames stored in the older "packed" layout).
- Playback starts: audio is audible immediately.
- Exactly one video frame is decoded, enqueued, and rendered.
- Within ~1.3s, the renderer's
ready flag flips to false and never recovers — no further frames are displayed, though decode/enqueue calls keep being logged.
- The host app (which shows a loading spinner until it receives a non-nil player/engine reference and an actual rendered frame) is stuck on that spinner for the rest of the file's duration, while audio plays normally.
Expected behavior
Either:
- Frames continue to be decoded and rendered normally (packed XviD is an old but well-documented format — FFmpeg's own
mpeg4 decoder has explicit (if imperfect) handling for it), or
- If the stream is genuinely unrecoverable,
AetherEngine's state publisher should transition to .error so the host app can show an error instead of hanging forever on "loading."
Actual behavior
Video rendering silently stalls with no error signaled anywhere. Audio pipeline is completely unaffected and keeps playing to completion.
Relevant logs (verbatim, de.superuser404.AetherEngine + related CoreMedia/AVKit subsystems, log stream --predicate 'process == "coreshub"' --style compact --level debug)
Session start — dispatched to the software decode path (expected, since AVFoundation has no native XviD/MPEG-4-in-AVI decoder):
[AetherEngine] load url=https://.../Sabrina%2C%20cosas%20de%20brujas%201x01%20-%20El%20cumplea%C3%B1os%20de%20Sabrina.avi?api_key=... source-format=sdr effective-format=sdr rate=23.976
[AetherEngine] dispatch: codec=12 → software
[AetherEngine] renderer audio session active: sourceCh=2 maxChannels=2 preferred=2 output=2
[SWHost] session start: videoCodecID=12 audioCodecID=86016 duration=1292.5s
[SWDecoder] Opened: 544x400, codec=mpeg4, threads=8, 8-bit
[AudioDecoder] Opened: 44100Hz, 2ch, codec=mp2
[AudioDecoder] Resampler ready: 44100Hz, 2ch, inFmt=6
Audio starts fine and keeps going (no further issues logged for this path for the rest of the session):
[AudioOutput] first enqueue: 44100.0Hz 2ch, 1152 samples, renderer.error=nil
[AudioOutput] seekClock to=0.000 rate=1.0
First video frame is decoded and rendered successfully:
[SWHost] first video frame enqueued: pixfmt=0x34323076 size=544x400 pts=0.042s
<<<< AVSampleBufferVideoRenderer >>>> -[AVSampleBufferVideoRenderer _setStatus:error:]_block_invoke: <VR/PEK|0x11670d2a0> Change status from Unknown to Rendering with success
[Renderer] enqueue #1: status=rendering ready=true error=nil
~1.3s later, ready flips to false and never recovers — this is the actual bug, reproduced identically at two later checkpoints ~3.5s apart, with no error ever attached:
[Renderer] enqueue #30: status=rendering ready=false error=nil (t≈+1.37s)
[Renderer] enqueue #100: status=rendering ready=false error=nil (t≈+4.74s)
FFmpeg's own decoder logs three warnings during this window, strongly suggesting the packed-bitstream handling is where this goes wrong:
[de.superuser404.AetherEngine:ffmpeg] [mpeg4 @ 0x11c712710] [warning] Discarding excessive bitstream in packed xvid
[de.superuser404.AetherEngine:ffmpeg] [mpeg4 @ 0x122006270] [warning] Discarding excessive bitstream in packed xvid
[de.superuser404.AetherEngine:ffmpeg] [mpeg4 @ 0x12200c380] [warning] Discarding excessive bitstream in packed xvid
For context, AVKit's own now-playing controls logic confirms the host is stuck in a perpetual "loading" state from the very start of this session (playerItem.status=0 = unknown, never progresses):
-[AVNowPlayingPlaybackControlsViewController _updateLoadingAndErrorIndicators_NoTimeline] spinner: playerItem.status=0, timeControlStatus=0, loading=YES, isSeeking=NO, isEffectiveRateNonZero=false
(There are also several -[AVPlayerViewController _becomeNowPlaying] denied: Error Domain=AVFoundationErrorDomain Code=-11862 "no player item" lines in the same window — these look like benign timing noise during the load transition, not the root cause, since they all cluster within milliseconds of session start and audio playback proceeds normally afterward. Flagging them only for completeness.)
Hypothesis
The software decode path's handling of packed XviD bitstreams (mpeg4 codec, B-frames stored in the pre-DivX-5/legacy "packed" layout) appears to desynchronize the renderer after the first frame — the FFmpeg decoder itself logs Discarding excessive bitstream in packed xvid, and immediately after, the Renderer's ready flag gets stuck at false for the rest of playback, even though decode/enqueue calls keep happening (audio is unaffected, confirming the demux/read/audio-decode pipeline is healthy — this is isolated to the video renderer's frame acceptance after the packed-bitstream discard).
Suggested improvements regardless of root cause
- Surface an
.error state (or at least a distinct "stalled"/"no video" state) when the renderer's ready flag stays false for an extended period after having previously been true — right now the host app has no signal at all and can only detect this via a user-visible symptom (audio with no video).
- Consider routing
AetherEngine's internal logging through os_log/Logger with a stable subsystem name if not already fully doing so — the de.superuser404.AetherEngine:* subsystems captured here were the only reason this was diagnosable at all; a plain print()-only path would leave zero trace for a downstream integrator.
Additional info available on request
- Full
log stream capture (33k+ lines, this excerpt is a small slice) for this exact repro if useful.
- Happy to test a patched build/branch against this same file.
AetherEngine version or commit SHA
6.6.0
Host app
Custom / my own integration
Platform
tvOS
OS version
tvOS 26.0
Device / chip
Apple TV 4K (3rd generation)
Playback path
Software (dav1d) host
Source media (for playback bugs)
AVI, MPEG-4 Part 2 (XviD, packed bitstream), 544x400, SDR, MP2 audio 44.1kHz 2ch
Error codes / log lines
[Renderer] enqueue #1: status=rendering ready=true error=nil
[Renderer] enqueue #30: status=rendering ready=false error=nil
[Renderer] enqueue #100: status=rendering ready=false error=nil
[mpeg4 @ 0x11c712710] [warning] Discarding excessive bitstream in packed xvid
[mpeg4 @ 0x122006270] [warning] Discarding excessive bitstream in packed xvid
[mpeg4 @ 0x12200c380] [warning] Discarding excessive bitstream in packed xvid
-[AVNowPlayingPlaybackControlsViewController _updateLoadingAndErrorIndicators_NoTimeline] spinner: playerItem.status=0, timeControlStatus=0, loading=YES, isSeeking=NO, isEffectiveRateNonZero=false
Anything else
No response
What happened?
Playing an
.avifile withcodec=mpeg4(XviD, "packed bitstream" variant) starts audio playback normally, but no video frame after the first one ever reaches the screen. The host app is left showing its loading spinner indefinitely while audio continues. No error is ever surfaced —AetherEngine's$statepublisher never transitions to.error, so the host app has no way to detect or recover from this.https://github.com/superuser404notfound/AetherEngine)AetherEngine()created per-playback,load(url:options:),$stateobserved via Combine — see reproduction context below.Source file
Delivered over HTTP (range requests,
AVIOReaderpump),.avicontainer, video track is MPEG-4 Part 2 (XviD) at 544×400, audio is MP2 at 44.1kHz/2ch. Filename:Sabrina, cosas de brujas 1x01 - El cumpleaños de Sabrina.avi.Steps to reproduce
readyflag flips tofalseand never recovers — no further frames are displayed, though decode/enqueue calls keep being logged.Expected behavior
Either:
mpeg4decoder has explicit (if imperfect) handling for it), orAetherEngine'sstatepublisher should transition to.errorso the host app can show an error instead of hanging forever on "loading."Actual behavior
Video rendering silently stalls with no error signaled anywhere. Audio pipeline is completely unaffected and keeps playing to completion.
Relevant logs (verbatim,
de.superuser404.AetherEngine+ related CoreMedia/AVKit subsystems,log stream --predicate 'process == "coreshub"' --style compact --level debug)Session start — dispatched to the software decode path (expected, since AVFoundation has no native XviD/MPEG-4-in-AVI decoder):
Audio starts fine and keeps going (no further issues logged for this path for the rest of the session):
First video frame is decoded and rendered successfully:
~1.3s later,
readyflips tofalseand never recovers — this is the actual bug, reproduced identically at two later checkpoints ~3.5s apart, with no error ever attached:FFmpeg's own decoder logs three warnings during this window, strongly suggesting the packed-bitstream handling is where this goes wrong:
For context, AVKit's own now-playing controls logic confirms the host is stuck in a perpetual "loading" state from the very start of this session (
playerItem.status=0= unknown, never progresses):(There are also several
-[AVPlayerViewController _becomeNowPlaying] denied: Error Domain=AVFoundationErrorDomain Code=-11862 "no player item"lines in the same window — these look like benign timing noise during the load transition, not the root cause, since they all cluster within milliseconds of session start and audio playback proceeds normally afterward. Flagging them only for completeness.)Hypothesis
The software decode path's handling of packed XviD bitstreams (
mpeg4codec, B-frames stored in the pre-DivX-5/legacy "packed" layout) appears to desynchronize the renderer after the first frame — the FFmpeg decoder itself logsDiscarding excessive bitstream in packed xvid, and immediately after, theRenderer'sreadyflag gets stuck atfalsefor the rest of playback, even though decode/enqueue calls keep happening (audio is unaffected, confirming the demux/read/audio-decode pipeline is healthy — this is isolated to the video renderer's frame acceptance after the packed-bitstream discard).Suggested improvements regardless of root cause
.errorstate (or at least a distinct "stalled"/"no video" state) when the renderer'sreadyflag staysfalsefor an extended period after having previously beentrue— right now the host app has no signal at all and can only detect this via a user-visible symptom (audio with no video).AetherEngine's internal logging throughos_log/Loggerwith a stable subsystem name if not already fully doing so — thede.superuser404.AetherEngine:*subsystems captured here were the only reason this was diagnosable at all; a plainprint()-only path would leave zero trace for a downstream integrator.Additional info available on request
log streamcapture (33k+ lines, this excerpt is a small slice) for this exact repro if useful.AetherEngine version or commit SHA
6.6.0
Host app
Custom / my own integration
Platform
tvOS
OS version
tvOS 26.0
Device / chip
Apple TV 4K (3rd generation)
Playback path
Software (dav1d) host
Source media (for playback bugs)
AVI, MPEG-4 Part 2 (XviD, packed bitstream), 544x400, SDR, MP2 audio 44.1kHz 2ch
Error codes / log lines
Anything else
No response