summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-12-23 03:59:14 +0100
committerAlessandro Ghedini <alessandro@ghedini.me>2015-01-14 16:21:45 +0100
commit9b2b95ee5288a27569ce9e48655b4ee9652ef9d0 (patch)
tree5ba13cada5b51c755cf699d133549c69a84f2c7d
parent47d972102eee4150e427d5c4678607f85647f387 (diff)
downloadmpv-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.c16
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");