summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-10-05 00:31:20 +0200
committerwm4 <wm4@nowhere>2014-10-05 00:31:20 +0200
commitaeefb8511c3d2476df3d83d385cb1efe41ab5bd1 (patch)
treefd341a3edcf99d3cc024f6fe04b801b35495aaea
parent6431e09fb3f1d50cfe7e586106c3f225c731f3bb (diff)
downloadmpv-aeefb8511c3d2476df3d83d385cb1efe41ab5bd1.tar.bz2
mpv-aeefb8511c3d2476df3d83d385cb1efe41ab5bd1.tar.xz
audio/out/push: make draining more robust
It was more complicated than it had to be: the audio thread already determines whether audio has ended, so we can use that. Remove the separate logic for draining.
-rw-r--r--audio/out/push.c35
1 files changed, 15 insertions, 20 deletions
diff --git a/audio/out/push.c b/audio/out/push.c
index dd3a02b79a..b4c1ab3950 100644
--- a/audio/out/push.c
+++ b/audio/out/push.c
@@ -44,14 +44,12 @@ 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 wait_on_ao;
bool still_playing;
bool need_wakeup;
@@ -153,22 +151,27 @@ static void drain(struct ao *ao)
{
struct ao_push_state *p = ao->api_priv;
+ MP_VERBOSE(ao, "draining...\n");
+
pthread_mutex_lock(&p->lock);
- if (p->paused) {
- pthread_mutex_unlock(&p->lock);
- return;
- }
+ if (p->paused)
+ goto done;
+
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);
+ while (p->still_playing)
+ pthread_cond_wait(&p->wakeup, &p->lock);
- if (!ao->driver->drain) {
+ if (ao->driver->drain) {
+ ao->driver->drain(ao);
+ } else {
double time = get_delay(ao);
mp_sleep_us(MPMIN(time, ao->buffer / (double)ao->samplerate + 1) * 1e6);
}
+
+done:
+ pthread_mutex_unlock(&p->lock);
+
reset(ao);
}
@@ -314,13 +317,6 @@ static void *playthread(void *arg)
if (!p->paused)
ao_play_data(ao);
- if (p->drain && (!p->wait_on_ao || p->paused)) {
- 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->wait_on_ao || p->paused) {
@@ -342,6 +338,7 @@ static void *playthread(void *arg)
if (was_playing && !p->still_playing)
mp_input_wakeup(ao->input_ctx);
+ pthread_cond_signal(&p->wakeup); // for draining
if (p->still_playing && timeout > 0) {
mpthread_cond_timedwait_rel(&p->wakeup, &p->lock, timeout);
@@ -376,7 +373,6 @@ static void destroy_no_thread(struct ao *ao)
close(p->wakeup_pipe[n]);
pthread_cond_destroy(&p->wakeup);
- pthread_cond_destroy(&p->wakeup_drain);
pthread_mutex_destroy(&p->lock);
}
@@ -400,7 +396,6 @@ 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);
if (ao->device_buffer <= 0) {