From 0db9edf88fd4ebce5581c7bb22402dc312bffc69 Mon Sep 17 00:00:00 2001 From: Frank Enderle Date: Sun, 11 Apr 2010 15:57:38 +0100 Subject: Fix a flaw on recovering from ALSA-reported errors in ao_alsa_delay() I noticed some alsa dropouts (losing audio) while hunting a bug which has been related to a broken streaming server. This resulted in buffers running empty and therefore showed some issues in the ALSA driver not correctly applying some recovery procedures provided by ALSA itself (snd_pcm_recover() and friends). --- src/audio_out/audio_alsa_out.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/audio_out/audio_alsa_out.c b/src/audio_out/audio_alsa_out.c index b18637a7b..3d5393f63 100644 --- a/src/audio_out/audio_alsa_out.c +++ b/src/audio_out/audio_alsa_out.c @@ -668,6 +668,34 @@ static int ao_alsa_delay (ao_driver_t *this_gen) { printf("audio_alsa_out:delay:FINISHED\n"); #endif + /* + * try to recover from errors and recalculate delay + */ + if(err) { +#ifdef LOG_DEBUG + printf("gap audio_alsa_out:delay: recovery\n"); +#endif + err = snd_pcm_recover( this->audio_fd, err, 1 ); + err = snd_pcm_delay( this->audio_fd, &delay ); + } + + /* + * if we have a negative delay try to forward within the buffer + */ + if(!err && (delay < 0)) { +#ifdef LOG_DEBUG + printf("gap audio_alsa_out:delay: forwarding frames: %d\n", (int)-delay); +#endif + err = snd_pcm_forward( this->audio_fd, -delay ); + if(err >= 0) { + err = snd_pcm_delay( this->audio_fd, &delay ); + } + } + + /* + * on error or (still) negative delays ensure delay + * is not negative + */ if (err || (delay < 0)) delay = 0; -- cgit v1.2.3