Skip to content

Commit

Permalink
ao_alsa: assume device lost if we couldn't recover after 10 attempts
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
llyyr authored and sfan5 committed Sep 14, 2024
1 parent 44da754 commit a44a726
Showing 1 changed file with 4 additions and 1 deletion.
5 changes: 4 additions & 1 deletion audio/out/ao_alsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)
Expand Down

0 comments on commit a44a726

Please sign in to comment.