diff options
author | wm4 <wm4@nowhere> | 2014-05-30 02:14:45 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-05-30 02:17:15 +0200 |
commit | 8ba346a5541294cb17b0e0e53306dd96c985eab4 (patch) | |
tree | 141d6348f545a03e287e4575d96ee65c5e576554 /audio/out/push.c | |
parent | c79689206c489b2ba449b8d21e0b5819298c949a (diff) | |
download | mpv-8ba346a5541294cb17b0e0e53306dd96c985eab4.tar.bz2 mpv-8ba346a5541294cb17b0e0e53306dd96c985eab4.tar.xz |
audio/out/push: handle draining correctly
This did not flush remaining audio in the buffer correctly (in case an
AO has an internal block size). So we have to make the audio feed thread
to write the remaining audio, and wait until it's done.
Checking the avoid_ao_wait variable should be enough to be sure that all
data that can be written was written to the AO driver.
Diffstat (limited to 'audio/out/push.c')
-rw-r--r-- | audio/out/push.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/audio/out/push.c b/audio/out/push.c index b779dac69a..409a5f50e0 100644 --- a/audio/out/push.c +++ b/audio/out/push.c @@ -44,12 +44,14 @@ struct ao_push_state { pthread_t thread; pthread_mutex_t lock; pthread_cond_t wakeup; + pthread_cond_t wakeup_drain; // --- protected by lock struct mp_audio_buffer *buffer; bool terminate; + bool drain; bool buffers_full; bool avoid_ao_wait; bool need_wakeup; @@ -141,14 +143,18 @@ static void resume(struct ao *ao) static void drain(struct ao *ao) { - if (ao->driver->drain) { - struct ao_push_state *p = ao->api_priv; - pthread_mutex_lock(&p->lock); - ao->driver->drain(ao); - pthread_mutex_unlock(&p->lock); - } else { + struct ao_push_state *p = ao->api_priv; + + pthread_mutex_lock(&p->lock); + p->final_chunk = true; + p->drain = true; + wakeup_playthread(ao); + while (p->drain) + pthread_cond_wait(&p->wakeup_drain, &p->lock); + pthread_mutex_unlock(&p->lock); + + if (!ao->driver->drain) ao_wait_drain(ao); - } } static int unlocked_get_space(struct ao *ao) @@ -290,6 +296,13 @@ static void *playthread(void *arg) p->requested_data = true; } + if (p->drain && p->avoid_ao_wait) { + if (ao->driver->drain) + ao->driver->drain(ao); + p->drain = false; + pthread_cond_signal(&p->wakeup_drain); + } + if (!p->need_wakeup) { MP_STATS(ao, "start audio wait"); if (p->avoid_ao_wait) { @@ -334,6 +347,7 @@ static void uninit(struct ao *ao) close(p->wakeup_pipe[n]); pthread_cond_destroy(&p->wakeup); + pthread_cond_destroy(&p->wakeup_drain); pthread_mutex_destroy(&p->lock); } @@ -343,6 +357,7 @@ static int init(struct ao *ao) pthread_mutex_init(&p->lock, NULL); pthread_cond_init(&p->wakeup, NULL); + pthread_cond_init(&p->wakeup_drain, NULL); mp_make_wakeup_pipe(p->wakeup_pipe); p->buffer = mp_audio_buffer_create(ao); |