summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-06-28 18:28:19 +0200
committerwm4 <wm4@nowhere>2017-06-28 18:43:18 +0200
commit3b7e292844f52783cdefe068bb7bc5cd35a8dcdb (patch)
treec8e1eb95edce47a3df87fc369df0db560e554988 /audio
parent36fadac7506a1fdb8f5b8d20e28e6977da7bbea7 (diff)
downloadmpv-3b7e292844f52783cdefe068bb7bc5cd35a8dcdb.tar.bz2
mpv-3b7e292844f52783cdefe068bb7bc5cd35a8dcdb.tar.xz
ao_wasapi: remove duplicate code for creating IAudioClient
The code accounting for the terrible AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED semantics (which MSDN claims can happen "starting with Windows 7" - so probably on Windows 10 too) duplicated the call for creating the IAudioClient. That's not great, so get rid of it. Let wasapi_thread_init() handle this. It has a retry loop anyway. This redoes device lookup and format negotiation, but potential failures due to race conditions (what if the driver decides to change behavior) shouldn't be worse than before.
Diffstat (limited to 'audio')
-rw-r--r--audio/out/ao_wasapi_utils.c58
1 files changed, 24 insertions, 34 deletions
diff --git a/audio/out/ao_wasapi_utils.c b/audio/out/ao_wasapi_utils.c
index f1895eb49e..9751b82fac 100644
--- a/audio/out/ao_wasapi_utils.c
+++ b/audio/out/ao_wasapi_utils.c
@@ -592,7 +592,7 @@ exit_label:
mp_HRESULT_to_str(hr));
}
-static HRESULT fix_format(struct ao *ao)
+static HRESULT fix_format(struct ao *ao, bool align_hack)
{
struct wasapi_state *state = ao->priv;
@@ -612,13 +612,20 @@ static HRESULT fix_format(struct ao *ao)
bufferPeriod = bufferDuration = devicePeriod;
}
+ // handle unsupported buffer size if AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED was
+ // returned in a previous attempt. hopefully this shouldn't happen because
+ // of the above integer device period
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/dd370875%28v=vs.85%29.aspx
+ if (align_hack) {
+ bufferDuration = (REFERENCE_TIME) (0.5 +
+ (10000.0 * 1000 / state->format.Format.nSamplesPerSec
+ * state->bufferFrameCount));
+ if (state->share_mode == AUDCLNT_SHAREMODE_EXCLUSIVE)
+ bufferPeriod = bufferDuration;
+ }
+
ao->format = af_fmt_from_planar(ao->format);
- // handle unsupported buffer size hopefully this shouldn't happen because of
- // the above integer device period
- // http://msdn.microsoft.com/en-us/library/windows/desktop/dd370875%28v=vs.85%29.aspx
- int retries=0;
-reinit:
MP_DBG(state, "IAudioClient::Initialize\n");
hr = IAudioClient_Initialize(state->pAudioClient,
state->share_mode,
@@ -627,33 +634,6 @@ reinit:
bufferPeriod,
&(state->format.Format),
NULL);
- // something about buffer sizes on Win7
- if (hr == AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED) {
- if (retries > 0) {
- EXIT_ON_ERROR(hr);
- } else {
- retries ++;
- }
- MP_VERBOSE(state, "IAudioClient::Initialize negotiation failed with %s,"
- "used %lld * 100ns\n",
- mp_HRESULT_to_str(hr), bufferDuration);
-
- IAudioClient_GetBufferSize(state->pAudioClient,
- &state->bufferFrameCount);
- bufferDuration = (REFERENCE_TIME) (0.5 +
- (10000.0 * 1000 / state->format.Format.nSamplesPerSec
- * state->bufferFrameCount));
- if (state->share_mode == AUDCLNT_SHAREMODE_EXCLUSIVE)
- bufferPeriod = bufferDuration;
-
-
- IAudioClient_Release(state->pAudioClient);
- state->pAudioClient = NULL;
- hr = IMMDeviceActivator_Activate(state->pDevice,
- &IID_IAudioClient, CLSCTX_ALL,
- NULL, (void **)&state->pAudioClient);
- goto reinit;
- }
EXIT_ON_ERROR(hr);
MP_DBG(state, "IAudioClient::Initialize pRenderClient\n");
@@ -940,6 +920,7 @@ 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;
+ bool align_hack = false;
retry: ;
HRESULT hr = load_device(ao->log, &state->pDevice, state->deviceID);
EXIT_ON_ERROR(hr);
@@ -957,7 +938,16 @@ retry: ;
}
MP_DBG(ao, "Fixing format\n");
- hr = fix_format(ao);
+ hr = fix_format(ao, align_hack);
+ if (hr == AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED && !align_hack) {
+ // According to MSDN, we must use this as base after the failure.
+ IAudioClient_GetBufferSize(state->pAudioClient,
+ &state->bufferFrameCount);
+ SAFE_RELEASE(state->pAudioClient);
+ align_hack = true;
+ MP_WARN(ao, "This appears to require a weird Windows 7 hack. Retrying.\n");
+ goto retry;
+ }
if ((hr == AUDCLNT_E_DEVICE_IN_USE || hr == AUDCLNT_E_DEVICE_INVALIDATED) &&
retry_wait <= 8)
{