ao_wasapi: UWP wrapper hack support

UWP does not support the whole IMMDevice API. Instead, you need to use a
new API (available starting from Windows 8), which is in addition not in
MinGW, and extremely unpleasant to use.

The wasapiuwp2.dll wrapper is a small custom MSVC DLL, which does this
instead, and returns a normal IAudioClient.

Before this, ao_wasapi did not initialize on UWP.
This commit is contained in:
wm4 2017-06-27 14:45:30 +02:00
parent 4637b029cd
commit 3e9075787f
2 changed files with 40 additions and 7 deletions

View File

@ -279,12 +279,15 @@ static int init(struct ao *ao)
state->opt_exclusive |= ao->init_flags & AO_INIT_EXCLUSIVE; state->opt_exclusive |= ao->init_flags & AO_INIT_EXCLUSIVE;
#if !HAVE_UWP
state->deviceID = wasapi_find_deviceID(ao); state->deviceID = wasapi_find_deviceID(ao);
if (!state->deviceID) { if (!state->deviceID) {
uninit(ao); uninit(ao);
return -1; return -1;
} }
#endif
if (state->deviceID)
wasapi_change_init(ao, false); wasapi_change_init(ao, false);
state->hInitDone = CreateEventW(NULL, FALSE, FALSE, NULL); state->hInitDone = CreateEventW(NULL, FALSE, FALSE, NULL);

View File

@ -922,8 +922,10 @@ HRESULT wasapi_thread_init(struct ao *ao)
MP_DBG(ao, "Init wasapi thread\n"); MP_DBG(ao, "Init wasapi thread\n");
int64_t retry_wait = 1; int64_t retry_wait = 1;
bool align_hack = false; bool align_hack = false;
HRESULT hr;
retry: ; retry: ;
HRESULT hr = load_device(ao->log, &state->pDevice, state->deviceID); if (state->deviceID) {
hr = load_device(ao->log, &state->pDevice, state->deviceID);
EXIT_ON_ERROR(hr); EXIT_ON_ERROR(hr);
MP_DBG(ao, "Activating pAudioClient interface\n"); MP_DBG(ao, "Activating pAudioClient interface\n");
@ -931,6 +933,34 @@ retry: ;
CLSCTX_ALL, NULL, CLSCTX_ALL, NULL,
(void **)&state->pAudioClient); (void **)&state->pAudioClient);
EXIT_ON_ERROR(hr); EXIT_ON_ERROR(hr);
} else {
MP_VERBOSE(ao, "Trying UWP wrapper.\n");
HRESULT (*wuCreateDefaultAudioRenderer)(IUnknown **res) = NULL;
HANDLE lib = LoadLibraryW(L"wasapiuwp2.dll");
if (!lib) {
MP_ERR(ao, "Wrapper not found: %d\n", (int)GetLastError());
hr = E_FAIL;
EXIT_ON_ERROR(hr);
}
if (lib) {
wuCreateDefaultAudioRenderer =
(void*)GetProcAddress(lib, "wuCreateDefaultAudioRenderer");
}
if (!wuCreateDefaultAudioRenderer) {
MP_ERR(ao, "Function not found.\n");
hr = E_FAIL;
EXIT_ON_ERROR(hr);
}
IUnknown *res = NULL;
hr = wuCreateDefaultAudioRenderer(&res);
MP_VERBOSE(ao, "Device: %s %p\n", mp_HRESULT_to_str(hr), res);
EXIT_ON_ERROR(hr);
hr = IUnknown_QueryInterface(res, &IID_IAudioClient,
(void **)&state->pAudioClient);
IUnknown_Release(res);
EXIT_ON_ERROR(hr);
}
MP_DBG(ao, "Probing formats\n"); MP_DBG(ao, "Probing formats\n");
if (!find_formats(ao)) { if (!find_formats(ao)) {