summaryrefslogtreecommitdiffstats
path: root/src/modules/alsa/alsa-util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/alsa/alsa-util.c')
-rw-r--r--src/modules/alsa/alsa-util.c72
1 files changed, 66 insertions, 6 deletions
diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c
index 016e52ab..8eedeeb5 100644
--- a/src/modules/alsa/alsa-util.c
+++ b/src/modules/alsa/alsa-util.c
@@ -1578,14 +1578,55 @@ snd_pcm_sframes_t pa_alsa_safe_avail(snd_pcm_t *pcm, size_t hwbuf_size, const pa
k >= pa_bytes_per_second(ss)*10)
PA_ONCE_BEGIN {
- pa_log(_("snd_pcm_avail_update() returned a value that is exceptionally large: %lu bytes (%lu ms). "
- "Most likely this is an ALSA driver bug. Please report this issue to the ALSA developers."),
- (unsigned long) k, (unsigned long) (pa_bytes_to_usec(k, ss) / PA_USEC_PER_MSEC));
+ char *dn = pa_alsa_get_driver_name_by_pcm(pcm);
+ pa_log(_("snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu ms).\n"
+ "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."),
+ (unsigned long) k,
+ (unsigned long) (pa_bytes_to_usec(k, ss) / PA_USEC_PER_MSEC),
+ pa_strnull(dn));
+ pa_xfree(dn);
} PA_ONCE_END;
return n;
}
+int pa_alsa_safe_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delay, size_t hwbuf_size, const pa_sample_spec *ss) {
+ ssize_t k;
+ size_t abs_k;
+ int r;
+
+ pa_assert(pcm);
+ pa_assert(delay);
+ pa_assert(hwbuf_size > 0);
+ pa_assert(ss);
+
+ /* Some ALSA driver expose weird bugs, let's inform the user about
+ * what is going on */
+
+ if ((r = snd_pcm_delay(pcm, delay)) < 0)
+ return r;
+
+ k = (ssize_t) *delay * (ssize_t) pa_frame_size(ss);
+
+ abs_k = k >= 0 ? (size_t) k : (size_t) -k;
+
+ if (abs_k >= hwbuf_size * 3 ||
+ abs_k >= pa_bytes_per_second(ss)*10)
+
+ PA_ONCE_BEGIN {
+ char *dn = pa_alsa_get_driver_name_by_pcm(pcm);
+ pa_log(_("snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%lu ms).\n"
+ "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."),
+ (signed long) k,
+ k < 0 ? "-" : "",
+ (unsigned long) (pa_bytes_to_usec(abs_k, ss) / PA_USEC_PER_MSEC),
+ pa_strnull(dn));
+ pa_xfree(dn);
+ } PA_ONCE_END;
+
+ return 0;
+}
+
int pa_alsa_safe_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames, size_t hwbuf_size, const pa_sample_spec *ss) {
int r;
snd_pcm_uframes_t before;
@@ -1612,9 +1653,13 @@ int pa_alsa_safe_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas
k >= pa_bytes_per_second(ss)*10)
PA_ONCE_BEGIN {
- pa_log(_("snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes (%lu ms). "
- "Most likely this is an ALSA driver bug. Please report this issue to the ALSA developers."),
- (unsigned long) k, (unsigned long) (pa_bytes_to_usec(k, ss) / PA_USEC_PER_MSEC));
+ char *dn = pa_alsa_get_driver_name_by_pcm(pcm);
+ pa_log(_("snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes (%lu ms).\n"
+ "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."),
+ (unsigned long) k,
+ (unsigned long) (pa_bytes_to_usec(k, ss) / PA_USEC_PER_MSEC),
+ pa_strnull(dn));
+ pa_xfree(dn);
} PA_ONCE_END;
return r;
@@ -1637,3 +1682,18 @@ char *pa_alsa_get_driver_name(int card) {
return n;
}
+
+char *pa_alsa_get_driver_name_by_pcm(snd_pcm_t *pcm) {
+ int card;
+
+ snd_pcm_info_t* info;
+ snd_pcm_info_alloca(&info);
+
+ if (snd_pcm_info(pcm, info) < 0)
+ return NULL;
+
+ if ((card = snd_pcm_info_get_card(info)) < 0)
+ return NULL;
+
+ return pa_alsa_get_driver_name(card);
+}