Skip to content

[Windows] Disposal hangs in MDK audio flush or FrameReader teardown #402

Description

@JulienDev

Describe the bug

I reproduced two Windows disposal hangs in an isolated FVP example, without my application. My Store build uses Flutter 3.41.9, FVP 0.38.1 and MDK 0.38.0 (git 4540373). Only the audio-flush stack matches a Store-user dump.

Audio flush: The Store dump's UI thread is in Player::set(Stopped) -> AudioRenderer::flush -> waitForNextBuffer -> Semaphore::acquire. My local dump has the same MDK offsets. Partner Center recorded 557 events on 413 devices in this bucket for Store build 11.0.9.0 over the last 30 days. Its 3.98% hang rate includes other buckets.

On Windows 11 x64 build 26200, I served a synthetic 12-second H.264/AC-3 5.1 stream over localhost HTTP. The Windows Release example displayed a VideoPlayer, played 2.1 seconds, paused, sought to 4 seconds, resumed, changed speed to 1.5 and back, removed the widget and disposed the controller. FVP's texture-first disposal order blocked at DISPOSE_BEGIN 21 in a 30-cycle run. An earlier run blocked on cycle 1; other runs passed. Stopping MDK before texture unregistration passed 30 and 50 cycles. Direct MDK C API AC-3 controls with a surface or D3D11 callback also passed. FVP's texture/callback timing may matter; stop-first is only a mitigation.

My full local dump shows XAudio2, a zero buffer-semaphore count, one outstanding frame and a stopped source voice. AudioRenderer::flush waits with cancelable=false and no visible timeout. I cannot identify the missed callback. The Store minidump lacks the heap state needed to inspect its audio backend.

FrameReader teardown: This is a separate hang with no known Store match. A synthetic 12-second Matroska file with H.264 video, AAC track 0 and AC-3 5.1 track 1 blocked the FVP example on its first cycle after switching to track 1 and back. The stack enters FrameReaderImpl::waitFor during deletion, even with stop-first disposal. It reproduced with XAudio2 and DirectSound.

I reproduced the same teardown path using MDK's C API alone, without Flutter or FVP. Each cycle creates a player with a 640x360 surface, plays 2.1 seconds, pauses, seeks to 4 seconds, selects track 1, resumes for 0.9 seconds, restores track 0, changes speed to 1.5 and back, clears the surface, stops and deletes the player. mdkPlayerAPI_delete blocked on player 3 with MDK 0.38.0 and player 13 with 0.37.0. A 30-cycle control without track switches passed. A simpler variant without pause, seek or speed changes also passed 30 cycles.

I attached the reproducer ZIP with synthetic fixtures, the FVP target, C++ probe, my FVP diff, full logs and WinDbg stacks. Its README.md has exact PowerShell/CMake commands for both cases. I built the example against current FVP master in Windows Release mode. The included MDK Windows x64 SDK is pinned by SHA-256 87bfb0d61465c2d86683d9b7791b6162b6078f4527b359dfcb40e63c8cf0f61e. The native failure command is mdk_native_probe.exe multi-audio.mkv 30 TRACKS SURFACE; the passing control omits TRACKS.

Expected behavior

Stopping and deleting a player should complete. Could you check the XAudio2 buffer wait and FVP's stop-before-texture order, and advise a safe teardown sequence or MDK issue for the separate FrameReader hang? This is distinct from #397.

Log

The harness sets Logger.root.level = Level.ALL and listens before registerWith(). The ZIP has the full native logs and event streams under logs/fvp-audio-flush/ and logs/fvp-tracks/; logs/mdk-c-api/ has failed 0.38.0/0.37.0 runs and the passing control. The C API stack export lacks PDB symbols; the FVP WinDbg transcript resolves matching MDK offsets using the SDK PDB.

log
FVP audio-flush failure: DISPOSE_BEGIN 21, no DISPOSE_END 21
Store and local MDK stack (same offsets):
mdk!Semaphore::acquire+0x92
mdk!mdk::abi::AsyncPushBackend::acquireNextBuffer+0x15
mdk!mdk::abi::AudioRenderer::Private::waitForNextBuffer+0x91
mdk!mdk::abi::AudioRenderer::flush+0xf3
mdk!mdk::abi::MediaControlPush::stop+0x1af
mdk!mdk::abi::MediaControlPush::setState+0xd7
mdk!mdk::abi::Player::set+0x111  (Stopped)

FVP track-switch failure: AUDIO_TRACK_0 0, DISPOSE_BEGIN 0, no DISPOSE_END 0
MDK C API track-switch failure: DELETE 2, no DONE 2
Matching PDB-resolved teardown path:
mdkPlayerAPI_reset -> MediaPlayer::~MediaPlayer
  -> MediaControlPush::~MediaControlPush -> FrameReaderImpl::waitFor / waitThread

I have not attached a Store-user dump or any memory dump. My local full dumps are available privately if needed.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions