summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-05-29 23:57:18 +0200
committerwm4 <wm4@nowhere>2014-05-30 02:16:35 +0200
commitb7c6981278067b22930c6193d79a6d96cb277143 (patch)
tree77d481a239243594782e286839d100314b4993e0 /audio
parent5dcfc4f6048329e72c077af7a152983c14c8ffd0 (diff)
downloadmpv-b7c6981278067b22930c6193d79a6d96cb277143.tar.bz2
mpv-b7c6981278067b22930c6193d79a6d96cb277143.tar.xz
ao_alsa: use poll() to wait for device
This means the audio feed thread is woken up exactly at the time new data is needed, instead of using a time-based heuristic.
Diffstat (limited to 'audio')
-rw-r--r--audio/out/ao_alsa.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/audio/out/ao_alsa.c b/audio/out/ao_alsa.c
index 63cba45aac..6b755a6d5c 100644
--- a/audio/out/ao_alsa.c
+++ b/audio/out/ao_alsa.c
@@ -698,6 +698,34 @@ static float get_delay(struct ao *ao)
return (float)delay / (float)ao->samplerate;
}
+#define MAX_POLL_FDS 20
+static int audio_wait(struct ao *ao, pthread_mutex_t *lock)
+{
+ struct priv *p = ao->priv;
+ int err;
+
+ int num_fds = snd_pcm_poll_descriptors_count(p->alsa);
+ if (num_fds <= 0 || num_fds >= MAX_POLL_FDS)
+ goto alsa_error;
+
+ struct pollfd fds[MAX_POLL_FDS];
+ 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");
+
+ return 0;
+
+alsa_error:
+ return -1;
+}
+
#define OPT_BASE_STRUCT struct priv
const struct ao_driver audio_out_alsa = {
@@ -713,6 +741,8 @@ const struct ao_driver audio_out_alsa = {
.resume = audio_resume,
.reset = reset,
.drain = drain,
+ .wait = audio_wait,
+ .wakeup = ao_wakeup_poll,
.priv_size = sizeof(struct priv),
.priv_defaults = &(const struct priv) {
.cfg_block = 1,