mirror of
https://github.com/Relintai/sdl2_frt.git
synced 2024-12-16 11:06:49 +01:00
WinRT: Wait until audio device activation is complete and PrepDevice during OpenAudio
This commit is contained in:
parent
aa9683bb6f
commit
7f9854b9b2
@ -725,6 +725,12 @@ WASAPI_ThreadDeinit(_THIS)
|
|||||||
WASAPI_PlatformThreadDeinit(this);
|
WASAPI_PlatformThreadDeinit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WASAPI_BeginLoopIteration(_THIS)
|
||||||
|
{
|
||||||
|
/* no-op. */
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
WASAPI_Deinitialize(void)
|
WASAPI_Deinitialize(void)
|
||||||
{
|
{
|
||||||
|
@ -405,12 +405,6 @@ WASAPI_PlatformDeleteActivationHandler(void *handler)
|
|||||||
SDL_assert(!"This function should have only been called on WinRT.");
|
SDL_assert(!"This function should have only been called on WinRT.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
WASAPI_BeginLoopIteration(_THIS)
|
|
||||||
{
|
|
||||||
/* no-op. */
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* SDL_AUDIO_DRIVER_WASAPI && !defined(__WINRT__) */
|
#endif /* SDL_AUDIO_DRIVER_WASAPI && !defined(__WINRT__) */
|
||||||
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
@ -185,20 +185,9 @@ struct SDL_WasapiActivationHandler : public RuntimeClass< RuntimeClassFlags< Cla
|
|||||||
HRESULT
|
HRESULT
|
||||||
SDL_WasapiActivationHandler::ActivateCompleted(IActivateAudioInterfaceAsyncOperation *async)
|
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.
|
// 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);
|
SDL_AtomicSet(&device->hidden->just_activated, 1);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WASAPI_UnrefDevice(device);
|
WASAPI_UnrefDevice(device);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,27 +225,47 @@ WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
|
|||||||
IActivateAudioInterfaceAsyncOperation *async = nullptr;
|
IActivateAudioInterfaceAsyncOperation *async = nullptr;
|
||||||
const HRESULT ret = ActivateAudioInterfaceAsync(devid, __uuidof(IAudioClient), nullptr, handler.Get(), &async);
|
const HRESULT ret = ActivateAudioInterfaceAsync(devid, __uuidof(IAudioClient), nullptr, handler.Get(), &async);
|
||||||
|
|
||||||
|
if (FAILED(ret) || async == nullptr) {
|
||||||
if (async != nullptr) {
|
if (async != nullptr) {
|
||||||
async->Release();
|
async->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(ret)) {
|
|
||||||
handler.Get()->Release();
|
handler.Get()->Release();
|
||||||
WASAPI_UnrefDevice(_this);
|
WASAPI_UnrefDevice(_this);
|
||||||
return WIN_SetErrorFromHRESULT("WASAPI can't activate requested audio endpoint", ret);
|
return WIN_SetErrorFromHRESULT("WASAPI can't activate requested audio endpoint", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
HRESULT activateRes = S_OK;
|
||||||
WASAPI_BeginLoopIteration(_THIS)
|
IUnknown *iunknown = nullptr;
|
||||||
{
|
const HRESULT getActivateRes = async->GetActivateResult(&activateRes, &iunknown);
|
||||||
if (SDL_AtomicCAS(&_this->hidden->just_activated, 1, 0)) {
|
async->Release();
|
||||||
if (WASAPI_PrepDevice(_this, SDL_TRUE) == -1) {
|
if (FAILED(getActivateRes)) {
|
||||||
SDL_OpenedAudioDeviceDisconnected(_this);
|
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
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user