summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-05-30 23:54:11 +0200
committerwm4 <wm4@nowhere>2014-05-30 23:54:11 +0200
commit9c9f23eee90f1df49098080dee0c10c7b9883ea6 (patch)
treee8fd06855ea72198a3672e9f131b9c503a820434
parent3053a68d2dffe79106e9515f5978de3e184f2594 (diff)
downloadmpv-9c9f23eee90f1df49098080dee0c10c7b9883ea6.tar.bz2
mpv-9c9f23eee90f1df49098080dee0c10c7b9883ea6.tar.xz
ao_alsa: reduce spurious wakeups
Apparently this can happen. So actually only return from waiting if ALSA excplicitly signals that new output is available, or if we are woken up externally.
-rw-r--r--audio/out/ao_alsa.c22
-rw-r--r--audio/out/push.c6
2 files changed, 18 insertions, 10 deletions
diff --git a/audio/out/ao_alsa.c b/audio/out/ao_alsa.c
index 6b755a6d5c..081f9efebf 100644
--- a/audio/out/ao_alsa.c
+++ b/audio/out/ao_alsa.c
@@ -712,14 +712,20 @@ static int audio_wait(struct ao *ao, pthread_mutex_t *lock)
err = snd_pcm_poll_descriptors(p->alsa, fds, num_fds);
CHECK_ALSA_ERROR("cannot get pollfds");
- int r = ao_wait_poll(ao, fds, num_fds, lock);
- if (r < 0)
- return r;
-
- unsigned short revents;
- snd_pcm_poll_descriptors_revents(p->alsa, fds, num_fds, &revents);
- CHECK_ALSA_ERROR("cannot read poll events");
-
+ while (1) {
+ int r = ao_wait_poll(ao, fds, num_fds, lock);
+ if (r)
+ return r;
+
+ unsigned short revents;
+ snd_pcm_poll_descriptors_revents(p->alsa, fds, num_fds, &revents);
+ CHECK_ALSA_ERROR("cannot read poll events");
+
+ if (revents & POLLERR)
+ return -1;
+ if (revents & POLLOUT)
+ return 0;
+ }
return 0;
alsa_error:
diff --git a/audio/out/push.c b/audio/out/push.c
index 409a5f50e0..cd7b8dc329 100644
--- a/audio/out/push.c
+++ b/audio/out/push.c
@@ -410,7 +410,7 @@ int ao_play_silence(struct ao *ao, int samples)
// Call poll() for the given fds. This will extend the given fds with the
// wakeup pipe, so ao_wakeup_poll() will basically interrupt this function.
// Unlocks the lock temporarily.
-// Returns <0 on error, 0 on success.
+// Returns <0 on error, 0 on success, 1 if the caller should return immediately.
int ao_wait_poll(struct ao *ao, struct pollfd *fds, int num_fds,
pthread_mutex_t *lock)
{
@@ -434,13 +434,15 @@ int ao_wait_poll(struct ao *ao, struct pollfd *fds, int num_fds,
pthread_mutex_lock(&p->lock);
memcpy(fds, p_fds, num_fds * sizeof(fds[0]));
+ bool wakeup = false;
if (p_fds[num_fds].revents & POLLIN) {
+ wakeup = true;
// flush the wakeup pipe contents - might "drown" some wakeups, but
// that's ok for our use-case
char buf[100];
read(p->wakeup_pipe[0], buf, sizeof(buf));
}
- return (r >= 0 || r == -EINTR) ? 0 : -1;
+ return (r >= 0 || r == -EINTR) ? wakeup : -1;
}
void ao_wakeup_poll(struct ao *ao)