summaryrefslogtreecommitdiffstats
path: root/audio/out/ao_alsa.c
diff options
context:
space:
mode:
authorfoo86 <foo86@users.noreply.github.com>2014-03-10 00:32:00 +0400
committerwm4 <wm4@nowhere>2014-03-09 22:06:06 +0100
commitd350181aafa2fb5fdb800b1cf05539b71697de44 (patch)
treeec7e3286691767ec385769945a3fcd10b16462ef /audio/out/ao_alsa.c
parent5c9c81efcc52e92569e8f03762870d5d97da3c46 (diff)
downloadmpv-d350181aafa2fb5fdb800b1cf05539b71697de44.tar.bz2
mpv-d350181aafa2fb5fdb800b1cf05539b71697de44.tar.xz
ao_alsa: check ALSA PCM state before pause and resume
It is possible to have ao->reset() called between ao->pause() and ao->resume() when seeking during the pause. If the underlying PCM supports pausing, resuming an already reset PCM will produce an error. Avoid that by explicitly checking PCM state before calling snd_pcm_pause(). Signed-off-by: wm4 <wm4@nowhere>
Diffstat (limited to 'audio/out/ao_alsa.c')
-rw-r--r--audio/out/ao_alsa.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/audio/out/ao_alsa.c b/audio/out/ao_alsa.c
index 291c6d7c1c..c91b6eda6d 100644
--- a/audio/out/ao_alsa.c
+++ b/audio/out/ao_alsa.c
@@ -565,9 +565,11 @@ static void audio_pause(struct ao *ao)
int err;
if (p->can_pause) {
- p->delay_before_pause = get_delay(ao);
- err = snd_pcm_pause(p->alsa, 1);
- CHECK_ALSA_ERROR("pcm pause error");
+ if (snd_pcm_state(p->alsa) == SND_PCM_STATE_RUNNING) {
+ p->delay_before_pause = get_delay(ao);
+ err = snd_pcm_pause(p->alsa, 1);
+ CHECK_ALSA_ERROR("pcm pause error");
+ }
} else {
MP_VERBOSE(ao, "pause not supported by hardware\n");
if (snd_pcm_delay(p->alsa, &p->prepause_frames) < 0
@@ -595,8 +597,10 @@ static void audio_resume(struct ao *ao)
}
if (p->can_pause) {
- err = snd_pcm_pause(p->alsa, 0);
- CHECK_ALSA_ERROR("pcm resume error");
+ if (snd_pcm_state(p->alsa) == SND_PCM_STATE_PAUSED) {
+ err = snd_pcm_pause(p->alsa, 0);
+ CHECK_ALSA_ERROR("pcm resume error");
+ }
} else {
MP_VERBOSE(ao, "resume not supported by hardware\n");
err = snd_pcm_prepare(p->alsa);