summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-06-27 14:45:30 +0200
committerwm4 <wm4@nowhere>2017-06-28 15:31:23 +0200
commit2020786f986a836ce118b1bc76654f2b93ae047c (patch)
treea599bc283b65606766f18dea307b59bff7cf6a59
parentb616d18b4538ddfec5a9fe8736145507e895cf98 (diff)
downloadmpv-2020786f986a836ce118b1bc76654f2b93ae047c.tar.bz2
mpv-2020786f986a836ce118b1bc76654f2b93ae047c.tar.xz
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.
-rw-r--r--audio/out/ao_wasapi.c5
-rw-r--r--audio/out/ao_wasapi_utils.c42
2 files changed, 40 insertions, 7 deletions
diff --git a/audio/out/ao_wasapi.c b/audio/out/ao_wasapi.c
index 3ddb9a113e..1337717f7b 100644
--- a/audio/out/ao_wasapi.c
+++ b/audio/out/ao_wasapi.c
@@ -279,13 +279,16 @@ static int init(struct ao *ao)
state->opt_exclusive |= ao->init_flags & AO_INIT_EXCLUSIVE;
+#if !HAVE_UWP
state->deviceID = wasapi_find_deviceID(ao);
if (!state->deviceID) {
uninit(ao);
return -1;
}
+#endif
- wasapi_change_init(ao, false);
+ if (state->deviceID)
+ wasapi_change_init(ao, false);
state->hInitDone = CreateEventW(NULL, FALSE, FALSE, NULL);
state->hWake = CreateEventW(NULL, FALSE, FALSE, NULL);
diff --git a/audio/out/ao_wasapi_utils.c b/audio/out/ao_wasapi_utils.c
index 427a372e62..f6e7b4633f 100644
--- a/audio/out/ao_wasapi_utils.c
+++ b/audio/out/ao_wasapi_utils.c
@@ -942,15 +942,45 @@ HRESULT wasapi_thread_init(struct ao *ao)
struct wasapi_state *state = ao->priv;
MP_DBG(ao, "Init wasapi thread\n");
int64_t retry_wait = 1;
+ HRESULT hr;
retry: ;
- HRESULT hr = load_device(ao->log, &state->pDevice, state->deviceID);
- EXIT_ON_ERROR(hr);
+ if (state->deviceID) {
+ hr = load_device(ao->log, &state->pDevice, state->deviceID);
+ EXIT_ON_ERROR(hr);
+
+ MP_DBG(ao, "Activating pAudioClient interface\n");
+ hr = IMMDeviceActivator_Activate(state->pDevice, &IID_IAudioClient,
+ CLSCTX_ALL, NULL,
+ (void **)&state->pAudioClient);
+ EXIT_ON_ERROR(hr);
+ } else {
+ MP_VERBOSE(ao, "Trying UWP wrapper.\n");
- MP_DBG(ao, "Activating pAudioClient interface\n");
- hr = IMMDeviceActivator_Activate(state->pDevice, &IID_IAudioClient,
- CLSCTX_ALL, NULL,
+ 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);
- EXIT_ON_ERROR(hr);
+ IUnknown_Release(res);
+ EXIT_ON_ERROR(hr);
+ }
MP_DBG(ao, "Probing formats\n");
if (!find_formats(ao)) {