diff options
Diffstat (limited to 'audio/out/ao_wasapi.c')
-rw-r--r-- | audio/out/ao_wasapi.c | 53 |
1 files changed, 37 insertions, 16 deletions
diff --git a/audio/out/ao_wasapi.c b/audio/out/ao_wasapi.c index 89f51c4295..75318c22ee 100644 --- a/audio/out/ao_wasapi.c +++ b/audio/out/ao_wasapi.c @@ -113,6 +113,33 @@ exit_label: return; } +static void thread_resume(struct ao *ao) +{ + struct wasapi_state *state = (struct wasapi_state *)ao->priv; + HRESULT hr; + + MP_DBG(state, "Thread Resume\n"); + UINT32 padding = 0; + hr = IAudioClient_GetCurrentPadding(state->pAudioClient, &padding); + if (hr != S_OK) { + MP_ERR(state, "IAudioClient_GetCurrentPadding returned %s (0x%"PRIx32")\n", + wasapi_explain_err(hr), (uint32_t) hr); + } + + /* Fill the buffer before starting, but only if there is no audio queued to play. */ + /* This prevents overfilling the buffer, which leads to problems in exclusive mode */ + if (padding < (UINT32)state->bufferFrameCount) + thread_feed(ao); + + hr = IAudioClient_Start(state->pAudioClient); + if (hr != S_OK) { + MP_ERR(state, "IAudioClient_Start returned %s (0x%"PRIx32")\n", + wasapi_explain_err(hr), (uint32_t) hr); + } + + return; +} + static void thread_reset(struct ao *ao) { struct wasapi_state *state = (struct wasapi_state *)ao->priv; @@ -151,7 +178,7 @@ static DWORD __stdcall ThreadLoop(void *lpParameter) DWORD waitstatus; HANDLE playcontrol[] = - {state->hUninit, state->hFeed, state->hForceFeed, state->hReset, NULL}; + {state->hUninit, state->hFeed, state->hReset, state->hResume, NULL}; MP_DBG(ao, "Entering dispatch loop\n"); while (true) { /* watch events */ waitstatus = MsgWaitForMultipleObjects(4, playcontrol, FALSE, INFINITE, @@ -163,13 +190,12 @@ static DWORD __stdcall ThreadLoop(void *lpParameter) case (WAIT_OBJECT_0 + 1): /* feed */ thread_feed(ao); break; - case (WAIT_OBJECT_0 + 2): /* force feed */ - thread_feed(ao); - SetEvent(state->hFeedDone); - break; - case (WAIT_OBJECT_0 + 3): /* reset */ + case (WAIT_OBJECT_0 + 2): /* reset */ thread_reset(ao); - break; + break; + case (WAIT_OBJECT_0 + 3): /* resume */ + thread_resume(ao); + break; case (WAIT_OBJECT_0 + 4): /* messages to dispatch (COM marshalling) */ MP_DBG(ao, "Dispatch\n"); wasapi_dispatch(); @@ -193,8 +219,7 @@ static void closehandles(struct ao *ao) if (state->init_done) CloseHandle(state->init_done); if (state->hUninit) CloseHandle(state->hUninit); if (state->hFeed) CloseHandle(state->hFeed); - if (state->hForceFeed) CloseHandle(state->hForceFeed); - if (state->hFeedDone) CloseHandle(state->hFeedDone); + if (state->hResume) CloseHandle(state->hResume); if (state->hReset) CloseHandle(state->hReset); if (state->threadLoop) CloseHandle(state->threadLoop); } @@ -249,11 +274,10 @@ static int init(struct ao *ao) state->init_done = CreateEventW(NULL, FALSE, FALSE, NULL); state->hUninit = CreateEventW(NULL, FALSE, FALSE, NULL); state->hFeed = CreateEventW(NULL, FALSE, FALSE, NULL); /* for wasapi event mode */ - state->hForceFeed = CreateEventW(NULL, FALSE, FALSE, NULL); - state->hFeedDone = CreateEventW(NULL, FALSE, FALSE, NULL); + state->hResume = CreateEventW(NULL, FALSE, FALSE, NULL); state->hReset = CreateEventW(NULL, FALSE, FALSE, NULL); if (!state->init_done || !state->hFeed || !state->hUninit || - !state->hForceFeed || !state->hFeedDone || !state->hReset) + !state->hResume || !state->hReset) { MP_ERR(ao, "Error initing events\n"); uninit(ao); @@ -371,10 +395,7 @@ static void audio_reset(struct ao *ao) static void audio_resume(struct ao *ao) { struct wasapi_state *state = (struct wasapi_state *)ao->priv; - - SetEvent(state->hForceFeed); - WaitForSingleObject(state->hFeedDone, INFINITE); - IAudioClient_Start(state->pAudioClientProxy); + SetEvent(state->hResume); } static void list_devs(struct ao *ao, struct ao_device_list *list) |