[Commits] SDL: WinRT: Wait until audio device activation is complete and P...

libsdl.org revision control commits-owner at libsdl.org
Tue Sep 25 19:49:23 PDT 2018


details:   https://hg.libsdl.org/SDL/rev/09e314140a28
changeset: 12222:09e314140a28
user:      Ethan Lee <flibitijibibo at flibitijibibo.com>
date:      Tue Sep 25 01:45:12 2018 -0400
description:
WinRT: Wait until audio device activation is complete and PrepDevice during OpenAudio

diffstat:

 src/audio/wasapi/SDL_wasapi.c         |   6 +++
 src/audio/wasapi/SDL_wasapi_win32.c   |   6 ---
 src/audio/wasapi/SDL_wasapi_winrt.cpp |  65 +++++++++++++++++++---------------
 3 files changed, 43 insertions(+), 34 deletions(-)

diffs (124 lines):

diff -r e50b720b73e9 -r 09e314140a28 src/audio/wasapi/SDL_wasapi.c
--- a/src/audio/wasapi/SDL_wasapi.c	Tue Sep 25 19:41:33 2018 -0700
+++ b/src/audio/wasapi/SDL_wasapi.c	Tue Sep 25 01:45:12 2018 -0400
@@ -725,6 +725,12 @@
     WASAPI_PlatformThreadDeinit(this);
 }
 
+void
+WASAPI_BeginLoopIteration(_THIS)
+{
+	/* no-op. */
+}
+
 static void
 WASAPI_Deinitialize(void)
 {
diff -r e50b720b73e9 -r 09e314140a28 src/audio/wasapi/SDL_wasapi_win32.c
--- a/src/audio/wasapi/SDL_wasapi_win32.c	Tue Sep 25 19:41:33 2018 -0700
+++ b/src/audio/wasapi/SDL_wasapi_win32.c	Tue Sep 25 01:45:12 2018 -0400
@@ -405,12 +405,6 @@
     SDL_assert(!"This function should have only been called on WinRT.");
 }
 
-void
-WASAPI_BeginLoopIteration(_THIS)
-{
-    /* no-op. */
-}
-
 #endif  /* SDL_AUDIO_DRIVER_WASAPI && !defined(__WINRT__) */
 
 /* vi: set ts=4 sw=4 expandtab: */
diff -r e50b720b73e9 -r 09e314140a28 src/audio/wasapi/SDL_wasapi_winrt.cpp
--- a/src/audio/wasapi/SDL_wasapi_winrt.cpp	Tue Sep 25 19:41:33 2018 -0700
+++ b/src/audio/wasapi/SDL_wasapi_winrt.cpp	Tue Sep 25 01:45:12 2018 -0400
@@ -185,20 +185,9 @@
 HRESULT
 SDL_WasapiActivationHandler::ActivateCompleted(IActivateAudioInterfaceAsyncOperation *async)
 {
-    HRESULT result = S_OK;
-    IUnknown *iunknown = nullptr;
-    const HRESULT ret = async->GetActivateResult(&result, &iunknown);
-
-    if (SUCCEEDED(ret) && SUCCEEDED(result)) {
-        iunknown->QueryInterface(IID_PPV_ARGS(&device->hidden->client));
-        if (device->hidden->client) {
-            // Just set a flag, since we're probably in a different thread. We'll pick it up and init everything on our own thread to prevent races.
-            SDL_AtomicSet(&device->hidden->just_activated, 1);
-        }
-    }
-
+    // Just set a flag, since we're probably in a different thread. We'll pick it up and init everything on our own thread to prevent races.
+    SDL_AtomicSet(&device->hidden->just_activated, 1);
     WASAPI_UnrefDevice(device);
-
     return S_OK;
 }
 
@@ -236,30 +225,50 @@
     IActivateAudioInterfaceAsyncOperation *async = nullptr;
     const HRESULT ret = ActivateAudioInterfaceAsync(devid, __uuidof(IAudioClient), nullptr, handler.Get(), &async);
 
-    if (async != nullptr) {
-        async->Release();
-    }
-
-    if (FAILED(ret)) {
+    if (FAILED(ret) || async == nullptr) {
+        if (async != nullptr) {
+            async->Release();
+        }
         handler.Get()->Release();
         WASAPI_UnrefDevice(_this);
         return WIN_SetErrorFromHRESULT("WASAPI can't activate requested audio endpoint", ret);
     }
 
+    /* Spin until the async operation is complete.
+     * If we don't PrepDevice before leaving this function, the bug list gets LONG:
+     * - device.spec is not filled with the correct information
+     * - The 'obtained' spec will be wrong for ALLOW_CHANGE properties
+     * - SDL_AudioStreams will/will not be allocated at the right time
+     * - SDL_assert(device->callbackspec.size == device->spec.size) will fail
+     * - When the assert is ignored, skipping or a buffer overflow will occur
+     */
+    while (!SDL_AtomicCAS(&_this->hidden->just_activated, 1, 0)) {
+        SDL_Delay(1);
+    }
+
+    HRESULT activateRes = S_OK;
+    IUnknown *iunknown = nullptr;
+    const HRESULT getActivateRes = async->GetActivateResult(&activateRes, &iunknown);
+    async->Release();
+    if (FAILED(getActivateRes)) {
+        return WIN_SetErrorFromHRESULT("Failed to get WASAPI activate result", getActivateRes);
+    } else if (FAILED(activateRes)) {
+        return WIN_SetErrorFromHRESULT("Failed to activate WASAPI device", activateRes);
+    }
+
+    iunknown->QueryInterface(IID_PPV_ARGS(&_this->hidden->client));
+    if (!_this->hidden->client) {
+        return SDL_SetError("Failed to query WASAPI client interface");
+    }
+
+    if (WASAPI_PrepDevice(_this, isrecovery) == -1) {
+        return -1;
+    }
+
     return 0;
 }
 
 void
-WASAPI_BeginLoopIteration(_THIS)
-{
-    if (SDL_AtomicCAS(&_this->hidden->just_activated, 1, 0)) {
-        if (WASAPI_PrepDevice(_this, SDL_TRUE) == -1) {
-            SDL_OpenedAudioDeviceDisconnected(_this);
-        } 
-    }
-}
-
-void
 WASAPI_PlatformThreadInit(_THIS)
 {
     // !!! FIXME: set this thread to "Pro Audio" priority.


More information about the commits mailing list