summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorKevin Mitchell <kevmitch@gmail.com>2017-07-12 23:37:45 -0700
committerKevin Mitchell <kevmitch@gmail.com>2017-08-07 14:33:03 -0700
commitbee602da8287ba1ccf80a44f7c826429927bfc54 (patch)
tree64fddfd0ac6289a4103d950ce7cfb5280febce71 /audio
parent61c8a147b5fef7337ba4e68673d521d5479e49e5 (diff)
downloadmpv-bee602da8287ba1ccf80a44f7c826429927bfc54.tar.bz2
mpv-bee602da8287ba1ccf80a44f7c826429927bfc54.tar.xz
ao_wasapi: return bool instead of HRESULT from thread_init
Any bad HRESULTs should have been printed already and lots of failure modes don't have an HRESULT leading to awkward hr = E_FAIL business. This also checks the exit status of GetBufferSize in the align hack. A final fatal message is added if either of the retry hacks fail.
Diffstat (limited to 'audio')
-rw-r--r--audio/out/ao_wasapi.c8
-rw-r--r--audio/out/ao_wasapi.h4
-rw-r--r--audio/out/ao_wasapi_utils.c74
3 files changed, 48 insertions, 38 deletions
diff --git a/audio/out/ao_wasapi.c b/audio/out/ao_wasapi.c
index dbca270e00..e432266a09 100644
--- a/audio/out/ao_wasapi.c
+++ b/audio/out/ao_wasapi.c
@@ -201,9 +201,9 @@ static DWORD __stdcall AudioThread(void *lpParameter)
mpthread_set_name("wasapi event");
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
- state->init_ret = wasapi_thread_init(ao);
+ state->init_ok = wasapi_thread_init(ao);
SetEvent(state->hInitDone);
- if (FAILED(state->init_ret))
+ if (!state->init_ok)
goto exit_label;
MP_DBG(ao, "Entering dispatch loop\n");
@@ -302,7 +302,7 @@ static int init(struct ao *ao)
state->dispatch = mp_dispatch_create(state);
mp_dispatch_set_wakeup_fn(state->dispatch, thread_wakeup, ao);
- state->init_ret = E_FAIL;
+ state->init_ok = false;
state->hAudioThread = CreateThread(NULL, 0, &AudioThread, ao, 0, NULL);
if (!state->hAudioThread) {
MP_FATAL(ao, "Failed to create audio thread\n");
@@ -312,7 +312,7 @@ static int init(struct ao *ao)
WaitForSingleObject(state->hInitDone, INFINITE); // wait on init complete
SAFE_DESTROY(state->hInitDone,CloseHandle(state->hInitDone));
- if (FAILED(state->init_ret)) {
+ if (!state->init_ok) {
if (!ao->probing)
MP_FATAL(ao, "Received failure from audio thread\n");
uninit(ao);
diff --git a/audio/out/ao_wasapi.h b/audio/out/ao_wasapi.h
index 81c3d93386..82fa4eb419 100644
--- a/audio/out/ao_wasapi.h
+++ b/audio/out/ao_wasapi.h
@@ -64,8 +64,8 @@ enum wasapi_thread_state {
typedef struct wasapi_state {
struct mp_log *log;
+ bool init_ok; // status of init phase
// Thread handles
- HRESULT init_ret; // status of init phase
HANDLE hInitDone; // set when init is complete in audio thread
HANDLE hAudioThread; // the audio thread itself
HANDLE hWake; // thread wakeup event
@@ -114,7 +114,7 @@ bstr wasapi_get_specified_device_string(struct ao *ao);
LPWSTR wasapi_find_deviceID(struct ao *ao);
void wasapi_dispatch(struct ao *ao);
-HRESULT wasapi_thread_init(struct ao *ao);
+bool wasapi_thread_init(struct ao *ao);
void wasapi_thread_uninit(struct ao *ao);
void wasapi_receive_proxies(wasapi_state *state);
diff --git a/audio/out/ao_wasapi_utils.c b/audio/out/ao_wasapi_utils.c
index e3deb456cd..e2a315127a 100644
--- a/audio/out/ao_wasapi_utils.c
+++ b/audio/out/ao_wasapi_utils.c
@@ -833,7 +833,7 @@ exit_label:
destroy_enumerator(enumerator);
}
-static HRESULT load_device(struct mp_log *l,
+static bool load_device(struct mp_log *l,
IMMDevice **ppDevice, LPWSTR deviceID)
{
IMMDeviceEnumerator *pEnumerator = NULL;
@@ -849,7 +849,7 @@ exit_label:
if (FAILED(hr))
mp_err(l, "Error loading selected device: %s\n", mp_HRESULT_to_str(hr));
SAFE_RELEASE(pEnumerator);
- return hr;
+ return SUCCEEDED(hr);
}
static LPWSTR select_device(struct mp_log *l, struct device_desc *d)
@@ -934,7 +934,7 @@ exit_label:
return deviceID;
}
-HRESULT wasapi_thread_init(struct ao *ao)
+bool wasapi_thread_init(struct ao *ao)
{
struct wasapi_state *state = ao->priv;
MP_DBG(ao, "Init wasapi thread\n");
@@ -946,14 +946,18 @@ HRESULT wasapi_thread_init(struct ao *ao)
retry:
if (state->deviceID) {
- hr = load_device(ao->log, &state->pDevice, state->deviceID);
- EXIT_ON_ERROR(hr);
+ if (!load_device(ao->log, &state->pDevice, state->deviceID))
+ return false;
MP_DBG(ao, "Activating pAudioClient interface\n");
hr = IMMDeviceActivator_Activate(state->pDevice, &IID_IAudioClient,
CLSCTX_ALL, NULL,
(void **)&state->pAudioClient);
- EXIT_ON_ERROR(hr);
+ if (FAILED(hr)) {
+ MP_FATAL(ao, "Error activating device: %s\n",
+ mp_HRESULT_to_str(hr));
+ return false;
+ }
} else {
MP_VERBOSE(ao, "Trying UWP wrapper.\n");
@@ -961,67 +965,73 @@ retry:
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");
+ return false;
}
+
+ wuCreateDefaultAudioRenderer =
+ (void*)GetProcAddress(lib, "wuCreateDefaultAudioRenderer");
if (!wuCreateDefaultAudioRenderer) {
MP_ERR(ao, "Function not found.\n");
- hr = E_FAIL;
- EXIT_ON_ERROR(hr);
+ return false;
}
IUnknown *res = NULL;
hr = wuCreateDefaultAudioRenderer(&res);
MP_VERBOSE(ao, "Device: %s %p\n", mp_HRESULT_to_str(hr), res);
- EXIT_ON_ERROR(hr);
+ if (FAILED(hr)) {
+ MP_FATAL(ao, "Error activating device: %s\n",
+ mp_HRESULT_to_str(hr));
+ return false;
+ }
hr = IUnknown_QueryInterface(res, &IID_IAudioClient,
(void **)&state->pAudioClient);
IUnknown_Release(res);
- EXIT_ON_ERROR(hr);
+ if (FAILED(hr)) {
+ MP_FATAL(ao, "Failed to get UWP audio client: %s\n",
+ mp_HRESULT_to_str(hr));
+ return false;
+ }
}
// In the event of an align hack, we've already done this.
if (!align_hack) {
MP_DBG(ao, "Probing formats\n");
- if (!find_formats(ao)) {
- hr = E_FAIL;
- EXIT_ON_ERROR(hr);
- }
+ if (!find_formats(ao))
+ return false;
}
MP_DBG(ao, "Fixing format\n");
hr = fix_format(ao, align_hack);
switch (hr) {
case AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED:
- if (align_hack)
+ if (align_hack) {
+ MP_FATAL(ao, "Align hack failed\n");
break;
+ }
// According to MSDN, we must use this as base after the failure.
- IAudioClient_GetBufferSize(state->pAudioClient,
- &state->bufferFrameCount);
+ hr = IAudioClient_GetBufferSize(state->pAudioClient,
+ &state->bufferFrameCount);
+ if (FAILED(hr)) {
+ MP_FATAL(ao, "Error getting buffer size for align hack: %s\n",
+ mp_HRESULT_to_str(hr));
+ return false;
+ }
wasapi_thread_uninit(ao);
align_hack = true;
MP_WARN(ao, "This appears to require a weird Windows 7 hack. Retrying.\n");
goto retry;
case AUDCLNT_E_DEVICE_IN_USE:
case AUDCLNT_E_DEVICE_INVALIDATED:
- if (retry_wait > 8)
- break;
+ if (retry_wait > 8) {
+ MP_FATAL(ao, "Bad device retry failed\n");
+ return false;
+ }
wasapi_thread_uninit(ao);
MP_WARN(ao, "Retrying in %"PRId64" us\n", retry_wait);
mp_sleep_us(retry_wait);
retry_wait *= 2;
goto retry;
}
- EXIT_ON_ERROR(hr);
-
- MP_DBG(ao, "Init wasapi thread done\n");
- return S_OK;
-exit_label:
- MP_FATAL(state, "Error setting up audio thread: %s\n", mp_HRESULT_to_str(hr));
- return hr;
+ return SUCCEEDED(hr);
}
void wasapi_thread_uninit(struct ao *ao)