diff options
author | wm4 <wm4@nowhere> | 2014-05-29 23:57:18 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-05-30 02:16:35 +0200 |
commit | b7c6981278067b22930c6193d79a6d96cb277143 (patch) | |
tree | 77d481a239243594782e286839d100314b4993e0 | |
parent | 5dcfc4f6048329e72c077af7a152983c14c8ffd0 (diff) | |
download | mpv-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.
-rw-r--r-- | audio/out/ao_alsa.c | 30 |
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, |