diff options
Diffstat (limited to 'audio/out')
-rw-r--r-- | audio/out/ao_wasapi.c | 53 | ||||
-rw-r--r-- | audio/out/ao_wasapi.h | 2 |
2 files changed, 33 insertions, 22 deletions
diff --git a/audio/out/ao_wasapi.c b/audio/out/ao_wasapi.c index 58d2acd09a..34c3b6193f 100644 --- a/audio/out/ao_wasapi.c +++ b/audio/out/ao_wasapi.c @@ -193,17 +193,19 @@ static void thread_resume(struct ao *ao) thread_unpause(ao); } -static void set_state_and_wakeup_thread(struct ao *ao, - enum wasapi_thread_state thread_state) +static void thread_wakeup(void *ptr) { + struct ao *ao = ptr; struct wasapi_state *state = ao->priv; - atomic_store(&state->thread_state, thread_state); - SetEvent(state->hWake); + SetEvent(state->hUserWake); } -static void thread_process_dispatch(void *ptr) +static void set_thread_state(struct ao *ao, + enum wasapi_thread_state thread_state) { - set_state_and_wakeup_thread(ptr, WASAPI_THREAD_DISPATCH); + struct wasapi_state *state = ao->priv; + atomic_store(&state->thread_state, thread_state); + thread_wakeup(ao); } static DWORD __stdcall AudioThread(void *lpParameter) @@ -220,18 +222,25 @@ static DWORD __stdcall AudioThread(void *lpParameter) MP_DBG(ao, "Entering dispatch loop\n"); while (true) { - if (WaitForSingleObject(state->hWake, INFINITE) != WAIT_OBJECT_0) - MP_ERR(ao, "Unexpected return value from WaitForSingleObject\n"); - - int thread_state = atomic_load(&state->thread_state); - switch (thread_state) { - case WASAPI_THREAD_FEED: + HANDLE handles[] = {state->hWake, state->hUserWake}; + switch (WaitForMultipleObjects(MP_ARRAY_SIZE(handles), handles, FALSE, INFINITE)) { + case WAIT_OBJECT_0: // fill twice on under-full buffer (see comment in thread_feed) if (thread_feed(ao) && thread_feed(ao)) MP_ERR(ao, "Unable to fill buffer fast enough\n"); + continue; + case WAIT_OBJECT_0 + 1: break; - case WASAPI_THREAD_DISPATCH: - mp_dispatch_queue_process(state->dispatch, 0); + default: + MP_ERR(ao, "Unexpected return value from WaitForMultipleObjects\n"); + break; + } + + mp_dispatch_queue_process(state->dispatch, 0); + + int thread_state = atomic_load(&state->thread_state); + switch (thread_state) { + case WASAPI_THREAD_FEED: break; case WASAPI_THREAD_RESET: thread_reset(ao); @@ -267,8 +276,8 @@ static void uninit(struct ao *ao) { MP_DBG(ao, "Uninit wasapi\n"); struct wasapi_state *state = ao->priv; - if (state->hWake) - set_state_and_wakeup_thread(ao, WASAPI_THREAD_SHUTDOWN); + if (state->hWake && state->hUserWake) + set_thread_state(ao, WASAPI_THREAD_SHUTDOWN); if (state->hAudioThread && WaitForSingleObject(state->hAudioThread, INFINITE) != WAIT_OBJECT_0) @@ -279,6 +288,7 @@ static void uninit(struct ao *ao) SAFE_DESTROY(state->hInitDone, CloseHandle(state->hInitDone)); SAFE_DESTROY(state->hWake, CloseHandle(state->hWake)); + SAFE_DESTROY(state->hUserWake, CloseHandle(state->hUserWake)); SAFE_DESTROY(state->hAudioThread,CloseHandle(state->hAudioThread)); wasapi_change_uninit(ao); @@ -312,14 +322,15 @@ static int init(struct ao *ao) state->hInitDone = CreateEventW(NULL, FALSE, FALSE, NULL); state->hWake = CreateEventW(NULL, FALSE, FALSE, NULL); - if (!state->hInitDone || !state->hWake) { + state->hUserWake = CreateEventW(NULL, FALSE, FALSE, NULL); + if (!state->hInitDone || !state->hWake || !state->hUserWake) { MP_FATAL(ao, "Error creating events\n"); uninit(ao); return -1; } state->dispatch = mp_dispatch_create(state); - mp_dispatch_set_wakeup_fn(state->dispatch, thread_process_dispatch, ao); + mp_dispatch_set_wakeup_fn(state->dispatch, thread_wakeup, ao); state->init_ok = false; state->hAudioThread = CreateThread(NULL, 0, &AudioThread, ao, 0, NULL); @@ -474,17 +485,17 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg) static void audio_reset(struct ao *ao) { - set_state_and_wakeup_thread(ao, WASAPI_THREAD_RESET); + set_thread_state(ao, WASAPI_THREAD_RESET); } static void audio_resume(struct ao *ao) { - set_state_and_wakeup_thread(ao, WASAPI_THREAD_RESUME); + set_thread_state(ao, WASAPI_THREAD_RESUME); } static bool audio_set_pause(struct ao *ao, bool paused) { - set_state_and_wakeup_thread(ao, paused ? WASAPI_THREAD_PAUSE : WASAPI_THREAD_UNPAUSE); + set_thread_state(ao, paused ? WASAPI_THREAD_PAUSE : WASAPI_THREAD_UNPAUSE); return true; } diff --git a/audio/out/ao_wasapi.h b/audio/out/ao_wasapi.h index e294e317c3..cbd4a3f933 100644 --- a/audio/out/ao_wasapi.h +++ b/audio/out/ao_wasapi.h @@ -48,7 +48,6 @@ void wasapi_change_uninit(struct ao* ao); enum wasapi_thread_state { WASAPI_THREAD_FEED = 0, - WASAPI_THREAD_DISPATCH, WASAPI_THREAD_RESUME, WASAPI_THREAD_RESET, WASAPI_THREAD_SHUTDOWN, @@ -66,6 +65,7 @@ typedef struct wasapi_state { HANDLE hWake; // thread wakeup event atomic_int thread_state; // enum wasapi_thread_state (what to do on wakeup) struct mp_dispatch_queue *dispatch; // for volume/mute/session display + HANDLE hUserWake; // mpv-requested wakeup event // for setting the audio thread priority HANDLE hTask; |