wasapi: Deal with HDMI or DisplayPort-based audio devices.
They can vanish for UP TO EIGHT SECONDS...! This is for devices that connect to HDMI/DisplayPort/etc, where it presumably has to wait for a display to get up and running before it can play audio through it, so one can see the audio device fail when changing display modes, or the system returning from sleep. Since this can be triggered by a game changing video resolutions at startup (either before or after opening the audio device!), it's important to deal with. In normal conditions, it shouldn't take this long to open or recover an audio device, but this is better than unexpectedly losing the device in this situation. Fixes #7044. Fixes #5571. (cherry picked from commit 48e71ae87be425f117dece3735b148fbc5f2606e)main
parent
97a927b44e
commit
c6cecb0fb0
|
@ -357,10 +357,12 @@ void SDL_IMMDevice_Quit(void)
|
||||||
|
|
||||||
int SDL_IMMDevice_Get(LPCWSTR devid, IMMDevice **device, SDL_bool iscapture)
|
int SDL_IMMDevice_Get(LPCWSTR devid, IMMDevice **device, SDL_bool iscapture)
|
||||||
{
|
{
|
||||||
|
const Uint64 timeout = SDL_GetTicks64() + 8000; /* intel's audio drivers can fail for up to EIGHT SECONDS after a device is connected or we wake from sleep. */
|
||||||
HRESULT ret;
|
HRESULT ret;
|
||||||
|
|
||||||
SDL_assert(device != NULL);
|
SDL_assert(device != NULL);
|
||||||
|
|
||||||
|
while (SDL_TRUE) {
|
||||||
if (devid == NULL) {
|
if (devid == NULL) {
|
||||||
const EDataFlow dataflow = iscapture ? eCapture : eRender;
|
const EDataFlow dataflow = iscapture ? eCapture : eRender;
|
||||||
ret = IMMDeviceEnumerator_GetDefaultAudioEndpoint(enumerator, dataflow, SDL_IMMDevice_role, device);
|
ret = IMMDeviceEnumerator_GetDefaultAudioEndpoint(enumerator, dataflow, SDL_IMMDevice_role, device);
|
||||||
|
@ -368,8 +370,19 @@ int SDL_IMMDevice_Get(LPCWSTR devid, IMMDevice **device, SDL_bool iscapture)
|
||||||
ret = IMMDeviceEnumerator_GetDevice(enumerator, devid, device);
|
ret = IMMDeviceEnumerator_GetDevice(enumerator, devid, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(ret)) {
|
if (SUCCEEDED(ret)) {
|
||||||
SDL_assert(*device == NULL);
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == E_NOTFOUND) {
|
||||||
|
const Uint64 now = SDL_GetTicks64();
|
||||||
|
if (timeout > now) {
|
||||||
|
const Uint64 ticksleft = timeout - now;
|
||||||
|
SDL_Delay(SDL_min(ticksleft, 300)); /* wait awhile and try again. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return WIN_SetErrorFromHRESULT("WASAPI can't find requested audio endpoint", ret);
|
return WIN_SetErrorFromHRESULT("WASAPI can't find requested audio endpoint", ret);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue