summaryrefslogtreecommitdiffstats
path: root/audio/out
diff options
context:
space:
mode:
Diffstat (limited to 'audio/out')
-rw-r--r--audio/out/ao_wasapi.c53
-rw-r--r--audio/out/ao_wasapi.h2
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;