summaryrefslogtreecommitdiffstats
path: root/audio/out/ao_alsa.c
diff options
context:
space:
mode:
authorJan Ekström <jeebjp@gmail.com>2020-11-04 23:43:27 +0200
committersfan5 <sfan5@live.de>2020-11-09 16:12:49 +0100
commit8ddd4547fc2d3b813c88b586cf8a579bff4afa4f (patch)
tree73ec590fd73d923f0d8841ea9aef60c949114234 /audio/out/ao_alsa.c
parent976fcf57c17da91e37be781cb86664d4510bbe4e (diff)
downloadmpv-8ddd4547fc2d3b813c88b586cf8a579bff4afa4f.tar.bz2
mpv-8ddd4547fc2d3b813c88b586cf8a579bff4afa4f.tar.xz
ao_alsa: handle -EPIPE XRUNs from snd_pcm_status
Set pcm state to SND_PCM_STATE_XRUN in case -EPIPE is received, and handle this state as per the usual logic. This way snd_pcm_prepare gets called, and the loop continued. Inspired by a patch posted by malc_ on #mpv.
Diffstat (limited to 'audio/out/ao_alsa.c')
-rw-r--r--audio/out/ao_alsa.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/audio/out/ao_alsa.c b/audio/out/ao_alsa.c
index cbb3bc7c78..762805541f 100644
--- a/audio/out/ao_alsa.c
+++ b/audio/out/ao_alsa.c
@@ -933,9 +933,18 @@ static bool recover_and_get_state(struct ao *ao, struct mp_pcm_state *state)
// (where things were retried in a loop).
for (int n = 0; n < 10; n++) {
err = snd_pcm_status(p->alsa, st);
- CHECK_ALSA_ERROR("snd_pcm_status");
+ if (err == -EPIPE) {
+ // ALSA APIs can return -EPIPE when an XRUN happens,
+ // we skip right to handling it by setting pcmst
+ // manually.
+ pcmst = SND_PCM_STATE_XRUN;
+ } else {
+ // Otherwise do error checking and query the PCM state properly.
+ CHECK_ALSA_ERROR("snd_pcm_status");
+
+ pcmst = snd_pcm_status_get_state(st);
+ }
- pcmst = snd_pcm_status_get_state(st);
if (pcmst == SND_PCM_STATE_PREPARED ||
pcmst == SND_PCM_STATE_RUNNING ||
pcmst == SND_PCM_STATE_PAUSED)