From 69f6bdf1557fa9d8edd590222c17b5c2450ec8bd Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 22 Apr 2008 02:44:25 +0000 Subject: [PATCH] add new function pa_alsa_recover_from_poll() to merge common core from module-alsa-sink and module-alsa-source git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/glitch-free@2294 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/alsa-util.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++-- src/modules/alsa-util.h | 2 ++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/modules/alsa-util.c b/src/modules/alsa-util.c index d056555..11367d9 100644 --- a/src/modules/alsa-util.c +++ b/src/modules/alsa-util.c @@ -974,7 +974,6 @@ void pa_alsa_redirect_errors_dec(void) { snd_lib_error_set_handler(NULL); } - void pa_alsa_init_proplist(pa_proplist *p, snd_pcm_info_t *pcm_info) { static const char * const alsa_class_table[SND_PCM_CLASS_LAST+1] = { @@ -1030,7 +1029,7 @@ void pa_alsa_init_proplist(pa_proplist *p, snd_pcm_info_t *pcm_info) { pa_proplist_setf(p, "alsa.device", "%u", snd_pcm_info_get_device(pcm_info)); if ((card = snd_pcm_info_get_card(pcm_info)) >= 0) { - pa_proplist_setf(p, "card", "%i", card); + pa_proplist_setf(p, "alsa.card", "%i", card); if (snd_card_get_name(card, &cn) >= 0) pa_proplist_sets(p, "alsa.card_name", cn); @@ -1046,3 +1045,51 @@ void pa_alsa_init_proplist(pa_proplist *p, snd_pcm_info_t *pcm_info) { else if (n) pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, n); } + +int pa_alsa_recover_from_poll(snd_pcm_t *pcm, int revents) { + snd_pcm_state_t state; + int err; + + pa_assert(pcm); + + if (revents & POLLERR) + pa_log_warn("Got POLLERR from ALSA"); + if (revents & POLLNVAL) + pa_log_warn("Got POLLNVAL from ALSA"); + if (revents & POLLHUP) + pa_log_warn("Got POLLHUP from ALSA"); + + state = snd_pcm_state(pcm); + pa_log_warn("PCM state is %s", snd_pcm_state_name(state)); + + /* Try to recover from this error */ + + switch (state) { + + case SND_PCM_STATE_XRUN: + if ((err = snd_pcm_recover(pcm, -EPIPE, 1)) != 0) { + pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP and XRUN: %s", snd_strerror(err)); + return -1; + } + break; + + case SND_PCM_STATE_SUSPENDED: + if ((err = snd_pcm_recover(pcm, -ESTRPIPE, 1)) != 0) { + pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP and SUSPENDED: %s", snd_strerror(err)); + return -1; + } + break; + + default: + + snd_pcm_drop(pcm); + + if ((err = snd_pcm_prepare(pcm)) < 0) { + pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP with snd_pcm_prepare(): %s", snd_strerror(err)); + return -1; + } + break; + } + + return 0; +} diff --git a/src/modules/alsa-util.h b/src/modules/alsa-util.h index 03de61e..5494b40 100644 --- a/src/modules/alsa-util.h +++ b/src/modules/alsa-util.h @@ -90,4 +90,6 @@ void pa_alsa_redirect_errors_dec(void); void pa_alsa_init_proplist(pa_proplist *p, snd_pcm_info_t *pcm_info); +int pa_alsa_recover_from_poll(snd_pcm_t *pcm, int revents); + #endif -- 2.7.4