diff options
Diffstat (limited to 'src/modules/alsa/alsa-util.c')
| -rw-r--r-- | src/modules/alsa/alsa-util.c | 72 | 
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); +} | 
