From 986dd6387d64e98f9cafa9124cc5a16d4b018f7c Mon Sep 17 00:00:00 2001 From: Richasy Date: Fri, 1 May 2026 10:24:14 +0800 Subject: [PATCH] ao_wasapi: fix retry budget on DEVICE_INVALIDATED The retry path in wasapi_thread_init() used MP_TIME_US_TO_NS, giving a total budget of ~15 us before MP_FATAL killed the audio thread. The resulting log line "Retrying in 1000 ns" makes the unit confusion obvious. In practice AUDCLNT_E_DEVICE_INVALIDATED is most often hit right after the system resumes from sleep, or when the default endpoint changes, where the audio endpoint typically needs hundreds of milliseconds to come back. The current budget never covers that window, so the first playback after wake-up permanently fell back to "no audio" until the user manually restarted playback. Switch the retry schedule to milliseconds: start at 1 ms (~one Windows timer tick, effectively an immediate yield), multiply by 10 each iteration, and cap at 1 s -- i.e. 1/10/100/1000 ms, 4 retries, ~1.1 s total. Use MP_TIME_NS_TO_MS for the warning so the unit in the log matches reality. --- audio/out/ao_wasapi_utils.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/audio/out/ao_wasapi_utils.c b/audio/out/ao_wasapi_utils.c index 1c89e107e7..a1e116b6c6 100644 --- a/audio/out/ao_wasapi_utils.c +++ b/audio/out/ao_wasapi_utils.c @@ -1013,7 +1013,7 @@ bool wasapi_thread_init(struct ao *ao) { struct wasapi_state *state = ao->priv; MP_DBG(ao, "Init wasapi thread\n"); - int64_t retry_wait = MP_TIME_US_TO_NS(1); + int64_t retry_wait = MP_TIME_MS_TO_NS(1); bool align_hack = false; HRESULT hr; @@ -1096,14 +1096,14 @@ retry: goto retry; case AUDCLNT_E_DEVICE_IN_USE: case AUDCLNT_E_DEVICE_INVALIDATED: - if (retry_wait > MP_TIME_US_TO_NS(8)) { + if (retry_wait > MP_TIME_MS_TO_NS(1000)) { MP_FATAL(ao, "Bad device retry failed\n"); return false; } wasapi_thread_uninit(ao); - MP_WARN(ao, "Retrying in %"PRId64" ns\n", retry_wait); + MP_WARN(ao, "Retrying in %.0f ms\n", MP_TIME_NS_TO_MS(retry_wait)); mp_sleep_ns(retry_wait); - retry_wait *= 2; + retry_wait *= 10; goto retry; } return SUCCEEDED(hr);