From a44a726301f3197f125826a0d3b26aed9b599f02 Mon Sep 17 00:00:00 2001 From: llyyr Date: Tue, 10 Sep 2024 19:04:49 +0530 Subject: [PATCH] ao_alsa: assume device lost if we couldn't recover after 10 attempts ALSA API reports -EPIPE even when the the device is lost, which we currently always assume to be an XRUN. If we assumed XRUN 10 times and didn't manage to recover, just consider the device lost and try to reconnect. Allows ao_alsa to recover from alsa server being killed then reinitialized. And even in the worst case, this should be better than the status quo of mpv attempting to prepare a PCM device indefinitely until the user restarts mpv. This is admittedly not ideal, and I don't think the -EPIPE hack is necessary anymore, but I can only test on my setup and removing the 'assume -EPIPE is an XRUN' hack might break some setups for whatever mysterious reasons. --- audio/out/ao_alsa.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/audio/out/ao_alsa.c b/audio/out/ao_alsa.c index 35cae353d9..1bf6015c78 100644 --- a/audio/out/ao_alsa.c +++ b/audio/out/ao_alsa.c @@ -929,7 +929,7 @@ static bool recover_and_get_state(struct ao *ao, struct mp_pcm_state *state) // Give it a number of chances to recover. This tries to deal with the fact // that the API is asynchronous, and to account for some past cargo-cult // (where things were retried in a loop). - for (int n = 0; n < 10; n++) { + for (int n = 0; n <= 10; n++) { err = snd_pcm_status(p->alsa, st); if (err == -EPIPE) { // ALSA APIs can return -EPIPE when an XRUN happens, @@ -943,6 +943,9 @@ static bool recover_and_get_state(struct ao *ao, struct mp_pcm_state *state) pcmst = snd_pcm_status_get_state(st); } + if (n == 10) + pcmst = SND_PCM_STATE_DISCONNECTED; + if (pcmst == SND_PCM_STATE_PREPARED || pcmst == SND_PCM_STATE_RUNNING || pcmst == SND_PCM_STATE_PAUSED)