diff options
author | wm4 <wm4@nowhere> | 2014-12-23 03:59:14 +0100 |
---|---|---|
committer | Alessandro Ghedini <alessandro@ghedini.me> | 2015-01-14 16:21:45 +0100 |
commit | 9b2b95ee5288a27569ce9e48655b4ee9652ef9d0 (patch) | |
tree | 5ba13cada5b51c755cf699d133549c69a84f2c7d | |
parent | 47d972102eee4150e427d5c4678607f85647f387 (diff) | |
download | mpv-9b2b95ee5288a27569ce9e48655b4ee9652ef9d0.tar.bz2 mpv-9b2b95ee5288a27569ce9e48655b4ee9652ef9d0.tar.xz |
ao_alsa: fix resuming from suspend mode
snd_pcm_prepare() was not always called, which could result in an
infinite loop.
Whether snd_pcm_prepare() was actually called depended on whether the
device was a hw device (or other characteristics; depending on
snd_pcm_hw_params_can_pause()), and required real suspend (annoying for
testing), so it was somewhat tricky to reproduce without knowing these
things.
-rw-r--r-- | audio/out/ao_alsa.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/audio/out/ao_alsa.c b/audio/out/ao_alsa.c index 3958bf8107..16fac8be95 100644 --- a/audio/out/ao_alsa.c +++ b/audio/out/ao_alsa.c @@ -769,7 +769,7 @@ static void audio_pause(struct ao *ao) alsa_error: ; } -static void audio_resume(struct ao *ao) +static void resume_device(struct ao *ao) { struct priv *p = ao->priv; int err; @@ -780,6 +780,12 @@ static void audio_resume(struct ao *ao) while ((err = snd_pcm_resume(p->alsa)) == -EAGAIN) sleep(1); } +} + +static void audio_resume(struct ao *ao) +{ + struct priv *p = ao->priv; + int err; if (p->can_pause) { if (snd_pcm_state(p->alsa) == SND_PCM_STATE_PAUSED) { @@ -831,10 +837,12 @@ static int play(struct ao *ao, void **data, int samples, int flags) if (res == -EINTR || res == -EAGAIN) { /* retry */ res = 0; - } else if (res == -ESTRPIPE) { /* suspend */ - audio_resume(ao); } else if (res < 0) { - MP_ERR(ao, "Write error: %s\n", snd_strerror(res)); + if (res == -ESTRPIPE) { /* suspend */ + resume_device(ao); + } else { + MP_ERR(ao, "Write error: %s\n", snd_strerror(res)); + } res = snd_pcm_prepare(p->alsa); int err = res; CHECK_ALSA_ERROR("pcm prepare error"); |