summaryrefslogtreecommitdiffstats
path: root/src/modules/alsa-util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/alsa-util.c')
-rw-r--r--src/modules/alsa-util.c51
1 files changed, 49 insertions, 2 deletions
diff --git a/src/modules/alsa-util.c b/src/modules/alsa-util.c
index d0565556..11367d95 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;
+}