diff options
Diffstat (limited to 'src/modules')
-rw-r--r-- | src/modules/alsa/alsa-mixer.c | 25 | ||||
-rw-r--r-- | src/modules/alsa/alsa-mixer.h | 2 | ||||
-rw-r--r-- | src/modules/alsa/alsa-sink.c | 54 | ||||
-rw-r--r-- | src/modules/alsa/alsa-source.c | 53 | ||||
-rw-r--r-- | src/modules/alsa/alsa-util.c | 255 | ||||
-rw-r--r-- | src/modules/alsa/alsa-util.h | 10 | ||||
-rw-r--r-- | src/modules/alsa/mixer/paths/analog-input.conf.common | 8 | ||||
-rw-r--r-- | src/modules/alsa/module-alsa-card.c | 2 | ||||
-rw-r--r-- | src/modules/bluetooth/module-bluetooth-device.c | 9 | ||||
-rw-r--r-- | src/modules/hal-util.c | 2 | ||||
-rw-r--r-- | src/modules/module-always-sink.c | 6 | ||||
-rw-r--r-- | src/modules/module-hal-detect.c | 4 | ||||
-rw-r--r-- | src/modules/module-null-sink.c | 5 | ||||
-rw-r--r-- | src/modules/module-tunnel.c | 15 | ||||
-rw-r--r-- | src/modules/module-udev-detect.c | 47 | ||||
-rw-r--r-- | src/modules/raop/base64.c | 1 | ||||
-rw-r--r-- | src/modules/rtp/rtsp_client.c | 2 | ||||
-rw-r--r-- | src/modules/x11/module-x11-publish.c | 2 |
18 files changed, 321 insertions, 181 deletions
diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c index 61c92cd0..685169b9 100644 --- a/src/modules/alsa/alsa-mixer.c +++ b/src/modules/alsa/alsa-mixer.c @@ -2889,7 +2889,7 @@ static void profile_set_add_auto_pair( else name = pa_sprintf_malloc("input:%s", n->name); - if ((p = pa_hashmap_get(ps->profiles, name))) { + if (pa_hashmap_get(ps->profiles, name)) { pa_xfree(name); return; } @@ -3145,7 +3145,13 @@ fail: return NULL; } -void pa_alsa_profile_set_probe(pa_alsa_profile_set *ps, const char *dev_id, const pa_sample_spec *ss) { +void pa_alsa_profile_set_probe( + pa_alsa_profile_set *ps, + const char *dev_id, + const pa_sample_spec *ss, + unsigned default_n_fragments, + unsigned default_fragment_size_msec) { + void *state; pa_alsa_profile *p, *last = NULL; pa_alsa_mapping *m; @@ -3160,6 +3166,7 @@ void pa_alsa_profile_set_probe(pa_alsa_profile_set *ps, const char *dev_id, cons PA_HASHMAP_FOREACH(p, ps->profiles, state) { pa_sample_spec try_ss; pa_channel_map try_map; + snd_pcm_uframes_t try_period_size, try_buffer_size; uint32_t idx; /* Is this already marked that it is supported? (i.e. from the config file) */ @@ -3213,13 +3220,18 @@ void pa_alsa_profile_set_probe(pa_alsa_profile_set *ps, const char *dev_id, cons try_ss = *ss; try_ss.channels = try_map.channels; + try_period_size = + pa_usec_to_bytes(default_fragment_size_msec * PA_USEC_PER_MSEC, &try_ss) / + pa_frame_size(&try_ss); + try_buffer_size = default_n_fragments * try_period_size; + if (!(m ->output_pcm = pa_alsa_open_by_template( m->device_strings, dev_id, NULL, &try_ss, &try_map, SND_PCM_STREAM_PLAYBACK, - NULL, NULL, 0, NULL, NULL, + &try_period_size, &try_buffer_size, 0, NULL, NULL, TRUE))) { p->supported = FALSE; break; @@ -3237,13 +3249,18 @@ void pa_alsa_profile_set_probe(pa_alsa_profile_set *ps, const char *dev_id, cons try_ss = *ss; try_ss.channels = try_map.channels; + try_period_size = + pa_usec_to_bytes(default_fragment_size_msec*PA_USEC_PER_MSEC, &try_ss) / + pa_frame_size(&try_ss); + try_buffer_size = default_n_fragments * try_period_size; + if (!(m ->input_pcm = pa_alsa_open_by_template( m->device_strings, dev_id, NULL, &try_ss, &try_map, SND_PCM_STREAM_CAPTURE, - NULL, NULL, 0, NULL, NULL, + &try_period_size, &try_buffer_size, 0, NULL, NULL, TRUE))) { p->supported = FALSE; break; diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h index 76788183..a0d4fcbe 100644 --- a/src/modules/alsa/alsa-mixer.h +++ b/src/modules/alsa/alsa-mixer.h @@ -269,7 +269,7 @@ void pa_alsa_mapping_dump(pa_alsa_mapping *m); void pa_alsa_profile_dump(pa_alsa_profile *p); pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel_map *bonus); -void pa_alsa_profile_set_probe(pa_alsa_profile_set *ps, const char *dev_id, const pa_sample_spec *ss); +void pa_alsa_profile_set_probe(pa_alsa_profile_set *ps, const char *dev_id, const pa_sample_spec *ss, unsigned default_n_fragments, unsigned default_fragment_size_msec); void pa_alsa_profile_set_free(pa_alsa_profile_set *s); void pa_alsa_profile_set_dump(pa_alsa_profile_set *s); diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index 195bdf6e..76cbe46f 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -116,7 +116,6 @@ struct userdata { pa_usec_t watermark_dec_not_before; - unsigned nfragments; pa_memchunk memchunk; char *device_name; /* name of the PCM device */ @@ -656,6 +655,7 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle snd_pcm_sframes_t n; size_t n_bytes; int r; + pa_bool_t after_avail = TRUE; if (PA_UNLIKELY((n = pa_alsa_safe_avail(u->pcm_handle, u->hwbuf_size, &u->sink->sample_spec)) < 0)) { @@ -710,7 +710,6 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle for (;;) { snd_pcm_sframes_t frames; void *p; - pa_bool_t after_avail = TRUE; /* pa_log_debug("%lu frames to write", (unsigned long) frames); */ @@ -943,8 +942,7 @@ static int unsuspend(struct userdata *u) { pa_sample_spec ss; int err; pa_bool_t b, d; - unsigned nfrags; - snd_pcm_uframes_t period_size; + snd_pcm_uframes_t period_size, buffer_size; pa_assert(u); pa_assert(!u->pcm_handle); @@ -952,7 +950,7 @@ static int unsuspend(struct userdata *u) { pa_log_info("Trying resume..."); if ((err = snd_pcm_open(&u->pcm_handle, u->device_name, SND_PCM_STREAM_PLAYBACK, - /*SND_PCM_NONBLOCK|*/ + SND_PCM_NONBLOCK| SND_PCM_NO_AUTO_RESAMPLE| SND_PCM_NO_AUTO_CHANNELS| SND_PCM_NO_AUTO_FORMAT)) < 0) { @@ -961,12 +959,12 @@ static int unsuspend(struct userdata *u) { } ss = u->sink->sample_spec; - nfrags = u->nfragments; period_size = u->fragment_size / u->frame_size; + buffer_size = u->hwbuf_size / u->frame_size; b = u->use_mmap; d = u->use_tsched; - if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, u->hwbuf_size / u->frame_size, &b, &d, TRUE)) < 0) { + if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &period_size, &buffer_size, 0, &b, &d, TRUE)) < 0) { pa_log("Failed to set hardware parameters: %s", pa_alsa_strerror(err)); goto fail; } @@ -981,10 +979,11 @@ static int unsuspend(struct userdata *u) { goto fail; } - if (nfrags != u->nfragments || period_size*u->frame_size != u->fragment_size) { - pa_log_warn("Resume failed, couldn't restore original fragment settings. (Old: %lu*%lu, New %lu*%lu)", - (unsigned long) u->nfragments, (unsigned long) u->fragment_size, - (unsigned long) nfrags, period_size * u->frame_size); + if (period_size*u->frame_size != u->fragment_size || + buffer_size*u->frame_size != u->hwbuf_size) { + pa_log_warn("Resume failed, couldn't restore original fragment settings. (Old: %lu/%lu, New %lu/%lu)", + (unsigned long) u->hwbuf_size, (unsigned long) u->fragment_size, + (unsigned long) (buffer_size*u->fragment_size), (unsigned long) (period_size*u->frame_size)); goto fail; } @@ -1638,8 +1637,8 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca const char *dev_id = NULL; pa_sample_spec ss, requested_ss; pa_channel_map map; - uint32_t nfrags, hwbuf_size, frag_size, tsched_size, tsched_watermark; - snd_pcm_uframes_t period_frames, tsched_frames; + uint32_t nfrags, frag_size, buffer_size, tsched_size, tsched_watermark; + snd_pcm_uframes_t period_frames, buffer_frames, tsched_frames; size_t frame_size; pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d, ignore_dB = FALSE; pa_sink_new_data data; @@ -1673,8 +1672,10 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca goto fail; } - hwbuf_size = frag_size * nfrags; + buffer_size = nfrags * frag_size; + period_frames = frag_size/frame_size; + buffer_frames = buffer_size/frame_size; tsched_frames = tsched_size/frame_size; if (pa_modargs_get_value_boolean(ma, "mmap", &use_mmap) < 0) { @@ -1741,7 +1742,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca &u->device_name, &ss, &map, SND_PCM_STREAM_PLAYBACK, - &nfrags, &period_frames, tsched_frames, + &period_frames, &buffer_frames, tsched_frames, &b, &d, mapping))) goto fail; @@ -1756,7 +1757,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca &u->device_name, &ss, &map, SND_PCM_STREAM_PLAYBACK, - &nfrags, &period_frames, tsched_frames, + &period_frames, &buffer_frames, tsched_frames, &b, &d, profile_set, &mapping))) goto fail; @@ -1768,7 +1769,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca &u->device_name, &ss, &map, SND_PCM_STREAM_PLAYBACK, - &nfrags, &period_frames, tsched_frames, + &period_frames, &buffer_frames, tsched_frames, &b, &d, FALSE))) goto fail; } @@ -1794,11 +1795,6 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca u->use_tsched = use_tsched = FALSE; } - if (use_tsched && !pa_alsa_pcm_is_hw(u->pcm_handle)) { - pa_log_info("Device is not a hardware device, disabling timer-based scheduling."); - u->use_tsched = use_tsched = FALSE; - } - if (u->use_mmap) pa_log_info("Successfully enabled mmap() mode."); @@ -1820,7 +1816,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca pa_alsa_init_proplist_pcm(m->core, data.proplist, u->pcm_handle); pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, u->device_name); - pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE, "%lu", (unsigned long) (period_frames * frame_size * nfrags)); + pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE, "%lu", (unsigned long) (buffer_frames * frame_size)); pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE, "%lu", (unsigned long) (period_frames * frame_size)); pa_proplist_sets(data.proplist, PA_PROP_DEVICE_ACCESS_MODE, u->use_tsched ? "mmap+timer" : (u->use_mmap ? "mmap" : "serial")); @@ -1861,13 +1857,15 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca pa_sink_set_rtpoll(u->sink, u->rtpoll); u->frame_size = frame_size; - u->fragment_size = frag_size = (uint32_t) (period_frames * frame_size); - u->nfragments = nfrags; - u->hwbuf_size = u->fragment_size * nfrags; + u->fragment_size = frag_size = (size_t) (period_frames * frame_size); + u->hwbuf_size = buffer_size = (size_t) (buffer_frames * frame_size); pa_cvolume_mute(&u->hardware_volume, u->sink->sample_spec.channels); - pa_log_info("Using %u fragments of size %lu bytes, buffer time is %0.2fms", - nfrags, (long unsigned) u->fragment_size, + pa_log_info("Using %0.1f fragments of size %lu bytes (%0.2fms), buffer size is %lu bytes (%0.2fms)", + (double) u->hwbuf_size / (double) u->fragment_size, + (long unsigned) u->fragment_size, + (double) pa_bytes_to_usec(u->fragment_size, &ss) / PA_USEC_PER_MSEC, + (long unsigned) u->hwbuf_size, (double) pa_bytes_to_usec(u->hwbuf_size, &ss) / PA_USEC_PER_MSEC); pa_sink_set_max_request(u->sink, u->hwbuf_size); diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c index f42d3542..88f2d8ae 100644 --- a/src/modules/alsa/alsa-source.c +++ b/src/modules/alsa/alsa-source.c @@ -111,8 +111,6 @@ struct userdata { pa_usec_t watermark_dec_not_before; - unsigned nfragments; - char *device_name; char *control_device; @@ -891,8 +889,7 @@ static int unsuspend(struct userdata *u) { pa_sample_spec ss; int err; pa_bool_t b, d; - unsigned nfrags; - snd_pcm_uframes_t period_size; + snd_pcm_uframes_t period_size, buffer_size; pa_assert(u); pa_assert(!u->pcm_handle); @@ -900,7 +897,7 @@ static int unsuspend(struct userdata *u) { pa_log_info("Trying resume..."); if ((err = snd_pcm_open(&u->pcm_handle, u->device_name, SND_PCM_STREAM_CAPTURE, - /*SND_PCM_NONBLOCK|*/ + SND_PCM_NONBLOCK| SND_PCM_NO_AUTO_RESAMPLE| SND_PCM_NO_AUTO_CHANNELS| SND_PCM_NO_AUTO_FORMAT)) < 0) { @@ -909,12 +906,12 @@ static int unsuspend(struct userdata *u) { } ss = u->source->sample_spec; - nfrags = u->nfragments; period_size = u->fragment_size / u->frame_size; + buffer_size = u->hwbuf_size / u->frame_size; b = u->use_mmap; d = u->use_tsched; - if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, u->hwbuf_size / u->frame_size, &b, &d, TRUE)) < 0) { + if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &period_size, &buffer_size, 0, &b, &d, TRUE)) < 0) { pa_log("Failed to set hardware parameters: %s", pa_alsa_strerror(err)); goto fail; } @@ -929,10 +926,11 @@ static int unsuspend(struct userdata *u) { goto fail; } - if (nfrags != u->nfragments || period_size*u->frame_size != u->fragment_size) { - pa_log_warn("Resume failed, couldn't restore original fragment settings. (Old: %lu*%lu, New %lu*%lu)", - (unsigned long) u->nfragments, (unsigned long) u->fragment_size, - (unsigned long) nfrags, period_size * u->frame_size); + if (period_size*u->frame_size != u->fragment_size || + buffer_size*u->frame_size != u->hwbuf_size) { + pa_log_warn("Resume failed, couldn't restore original fragment settings. (Old: %lu/%lu, New %lu/%lu)", + (unsigned long) u->hwbuf_size, (unsigned long) u->fragment_size, + (unsigned long) (buffer_size*u->fragment_size), (unsigned long) (period_size*u->frame_size)); goto fail; } @@ -1483,8 +1481,8 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p const char *dev_id = NULL; pa_sample_spec ss, requested_ss; pa_channel_map map; - uint32_t nfrags, hwbuf_size, frag_size, tsched_size, tsched_watermark; - snd_pcm_uframes_t period_frames, tsched_frames; + uint32_t nfrags, frag_size, buffer_size, tsched_size, tsched_watermark; + snd_pcm_uframes_t period_frames, buffer_frames, tsched_frames; size_t frame_size; pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d, ignore_dB = FALSE; pa_source_new_data data; @@ -1518,8 +1516,10 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p goto fail; } - hwbuf_size = frag_size * nfrags; + buffer_size = nfrags * frag_size; + period_frames = frag_size/frame_size; + buffer_frames = buffer_size/frame_size; tsched_frames = tsched_size/frame_size; if (pa_modargs_get_value_boolean(ma, "mmap", &use_mmap) < 0) { @@ -1585,7 +1585,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p &u->device_name, &ss, &map, SND_PCM_STREAM_CAPTURE, - &nfrags, &period_frames, tsched_frames, + &period_frames, &buffer_frames, tsched_frames, &b, &d, mapping))) goto fail; @@ -1599,7 +1599,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p &u->device_name, &ss, &map, SND_PCM_STREAM_CAPTURE, - &nfrags, &period_frames, tsched_frames, + &period_frames, &buffer_frames, tsched_frames, &b, &d, profile_set, &mapping))) goto fail; @@ -1610,7 +1610,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p &u->device_name, &ss, &map, SND_PCM_STREAM_CAPTURE, - &nfrags, &period_frames, tsched_frames, + &period_frames, &buffer_frames, tsched_frames, &b, &d, FALSE))) goto fail; } @@ -1636,11 +1636,6 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p u->use_tsched = use_tsched = FALSE; } - if (use_tsched && !pa_alsa_pcm_is_hw(u->pcm_handle)) { - pa_log_info("Device is not a hardware device, disabling timer-based scheduling."); - u->use_tsched = use_tsched = FALSE; - } - if (u->use_mmap) pa_log_info("Successfully enabled mmap() mode."); @@ -1662,7 +1657,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p pa_alsa_init_proplist_pcm(m->core, data.proplist, u->pcm_handle); pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, u->device_name); - pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE, "%lu", (unsigned long) (period_frames * frame_size * nfrags)); + pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE, "%lu", (unsigned long) (buffer_frames * frame_size)); pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE, "%lu", (unsigned long) (period_frames * frame_size)); pa_proplist_sets(data.proplist, PA_PROP_DEVICE_ACCESS_MODE, u->use_tsched ? "mmap+timer" : (u->use_mmap ? "mmap" : "serial")); @@ -1703,13 +1698,15 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p pa_source_set_rtpoll(u->source, u->rtpoll); u->frame_size = frame_size; - u->fragment_size = frag_size = (uint32_t) (period_frames * frame_size); - u->nfragments = nfrags; - u->hwbuf_size = u->fragment_size * nfrags; + u->fragment_size = frag_size = (size_t) (period_frames * frame_size); + u->hwbuf_size = buffer_size = (size_t) (buffer_frames * frame_size); pa_cvolume_mute(&u->hardware_volume, u->source->sample_spec.channels); - pa_log_info("Using %u fragments of size %lu bytes, buffer time is %0.2fms", - nfrags, (long unsigned) u->fragment_size, + pa_log_info("Using %0.1f fragments of size %lu bytes (%0.2fms), buffer size is %lu bytes (%0.2fms)", + (double) u->hwbuf_size / (double) u->fragment_size, + (long unsigned) u->fragment_size, + (double) pa_bytes_to_usec(u->fragment_size, &ss) / PA_USEC_PER_MSEC, + (long unsigned) u->hwbuf_size, (double) pa_bytes_to_usec(u->hwbuf_size, &ss) / PA_USEC_PER_MSEC); if (u->use_tsched) { diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c index a47a8958..f934285a 100644 --- a/src/modules/alsa/alsa-util.c +++ b/src/modules/alsa/alsa-util.c @@ -93,6 +93,7 @@ static int set_format(snd_pcm_t *pcm_handle, snd_pcm_hw_params_t *hwparams, pa_s int ret; pa_assert(pcm_handle); + pa_assert(hwparams); pa_assert(f); if ((ret = snd_pcm_hw_params_set_format(pcm_handle, hwparams, format_trans[*f])) >= 0) @@ -148,33 +149,71 @@ try_auto: return -1; } +static int set_period_size(snd_pcm_t *pcm_handle, snd_pcm_hw_params_t *hwparams, snd_pcm_uframes_t size) { + snd_pcm_uframes_t s; + int d, ret; + + pa_assert(pcm_handle); + pa_assert(hwparams); + + s = size; + d = 0; + if (snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &s, &d) < 0) { + s = size; + d = -1; + if (snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &s, &d) < 0) { + s = size; + d = 1; + if ((ret = snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &s, &d)) < 0) { + pa_log_info("snd_pcm_hw_params_set_period_size_near() failed: %s", pa_alsa_strerror(ret)); + return ret; + } + } + } + + return 0; +} + +static int set_buffer_size(snd_pcm_t *pcm_handle, snd_pcm_hw_params_t *hwparams, snd_pcm_uframes_t size) { + int ret; + + pa_assert(pcm_handle); + pa_assert(hwparams); + + if ((ret = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hwparams, &size)) < 0) { + pa_log_info("snd_pcm_hw_params_set_buffer_size_near() failed: %s", pa_alsa_strerror(ret)); + return ret; + } + + return 0; +} + /* Set the hardware parameters of the given ALSA device. Returns the - * selected fragment settings in *period and *period_size */ + * selected fragment settings in *buffer_size and *period_size. If tsched mode can be enabled */ int pa_alsa_set_hw_params( snd_pcm_t *pcm_handle, pa_sample_spec *ss, - uint32_t *periods, snd_pcm_uframes_t *period_size, + snd_pcm_uframes_t *buffer_size, snd_pcm_uframes_t tsched_size, pa_bool_t *use_mmap, pa_bool_t *use_tsched, pa_bool_t require_exact_channel_number) { int ret = -1; + snd_pcm_hw_params_t *hwparams, *hwparams_copy; + int dir; snd_pcm_uframes_t _period_size = period_size ? *period_size : 0; - unsigned int _periods = periods ? *periods : 0; - unsigned int r = ss->rate; - unsigned int c = ss->channels; - pa_sample_format_t f = ss->format; - snd_pcm_hw_params_t *hwparams; + snd_pcm_uframes_t _buffer_size = buffer_size ? *buffer_size : 0; pa_bool_t _use_mmap = use_mmap && *use_mmap; pa_bool_t _use_tsched = use_tsched && *use_tsched; - int dir; + pa_sample_spec _ss = *ss; pa_assert(pcm_handle); pa_assert(ss); snd_pcm_hw_params_alloca(&hwparams); + snd_pcm_hw_params_alloca(&hwparams_copy); if ((ret = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0) { pa_log_debug("snd_pcm_hw_params_any() failed: %s", pa_alsa_strerror(ret)); @@ -208,114 +247,143 @@ int pa_alsa_set_hw_params( if (!_use_mmap) _use_tsched = FALSE; - if ((ret = set_format(pcm_handle, hwparams, &f)) < 0) + if (!pa_alsa_pcm_is_hw(pcm_handle)) + _use_tsched = FALSE; + + if ((ret = set_format(pcm_handle, hwparams, &_ss.format)) < 0) goto finish; - if ((ret = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &r, NULL)) < 0) { + if ((ret = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &_ss.rate, NULL)) < 0) { pa_log_debug("snd_pcm_hw_params_set_rate_near() failed: %s", pa_alsa_strerror(ret)); goto finish; } if (require_exact_channel_number) { - if ((ret = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, c)) < 0) { - pa_log_debug("snd_pcm_hw_params_set_channels(%u) failed: %s", c, pa_alsa_strerror(ret)); + if ((ret = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, _ss.channels)) < 0) { + pa_log_debug("snd_pcm_hw_params_set_channels(%u) failed: %s", _ss.channels, pa_alsa_strerror(ret)); goto finish; } } else { + unsigned int c = _ss.channels; + if ((ret = snd_pcm_hw_params_set_channels_near(pcm_handle, hwparams, &c)) < 0) { - pa_log_debug("snd_pcm_hw_params_set_channels_near(%u) failed: %s", c, pa_alsa_strerror(ret)); + pa_log_debug("snd_pcm_hw_params_set_channels_near(%u) failed: %s", _ss.channels, pa_alsa_strerror(ret)); goto finish; } - } - if ((ret = snd_pcm_hw_params_set_periods_integer(pcm_handle, hwparams)) < 0) { - pa_log_debug("snd_pcm_hw_params_set_periods_integer() failed: %s", pa_alsa_strerror(ret)); - goto finish; + _ss.channels = c; } - if (_period_size > 0 && tsched_size > 0 && _periods > 0) { - snd_pcm_uframes_t buffer_size; - unsigned int p; + if (_use_tsched && tsched_size > 0) { + _buffer_size = pa_convert_size(tsched_size, ss, &_ss); + _period_size = _buffer_size; + } else { + _period_size = pa_convert_size(_period_size, ss, &_ss); + _buffer_size = pa_convert_size(_buffer_size, ss, &_ss); + } - /* Adjust the buffer sizes, if we didn't get the rate we were asking for */ - _period_size = (snd_pcm_uframes_t) (((uint64_t) _period_size * r) / ss->rate); - tsched_size = (snd_pcm_uframes_t) (((uint64_t) tsched_size * r) / ss->rate); + if (_buffer_size > 0 || _period_size > 0) { + snd_pcm_uframes_t max_frames = 0; - if (_use_tsched) { - buffer_size = 0; + if ((ret = snd_pcm_hw_params_get_buffer_size_max(hwparams, &max_frames)) < 0) + pa_log_warn("snd_pcm_hw_params_get_buffer_size_max() failed: %s", pa_alsa_strerror(ret)); + else + pa_log_debug("Maximum hw buffer size is %lu ms", (long unsigned) max_frames * PA_MSEC_PER_SEC / _ss.rate); - if ((ret = snd_pcm_hw_params_get_buffer_size_max(hwparams, &buffer_size)) < 0) - pa_log_warn("snd_pcm_hw_params_get_buffer_size_max() failed: %s", pa_alsa_strerror(ret)); - else - pa_log_debug("Maximum hw buffer size is %u ms", (unsigned) buffer_size * 1000 / r); + /* Some ALSA drivers really don't like if we set the buffer + * size first and the number of periods second. (which would + * make a lot more sense to me) So, try a few combinations + * before we give up. */ + + if (_buffer_size > 0 && _period_size > 0) { + snd_pcm_hw_params_copy(hwparams_copy, hwparams); + + /* First try: set buffer size first, followed by period size */ + if (set_buffer_size(pcm_handle, hwparams_copy, _buffer_size) >= 0 && + set_period_size(pcm_handle, hwparams_copy, _period_size) >= 0 && + snd_pcm_hw_params(pcm_handle, hwparams_copy) >= 0) { + pa_log_debug("Set buffer size first, period size second."); + goto success; + } - _period_size = tsched_size; - _periods = 1; + /* Second try: set period size first, followed by buffer size */ + if (set_period_size(pcm_handle, hwparams_copy, _period_size) >= 0 && + set_buffer_size(pcm_handle, hwparams_copy, _buffer_size) >= 0 && + snd_pcm_hw_params(pcm_handle, hwparams_copy) >= 0) { + pa_log_debug("Set period size first, buffer size second."); + goto success; + } } - /* Some ALSA drivers really don't like if we set the buffer - * size first and the number of periods second. (which would - * make a lot more sense to me) So, follow this rule and - * adjust the periods first and the buffer size second */ - - /* First we pass 0 as direction to get exactly what we - * asked for. That this is necessary is presumably a bug - * in ALSA. All in all this is mostly a hint to ALSA, so - * we don't care if this fails. */ - - p = _periods; - dir = 0; - if (snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &p, &dir) < 0) { - p = _periods; - dir = 1; - if (snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &p, &dir) < 0) { - p = _periods; - dir = -1; - if ((ret = snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &p, &dir)) < 0) - pa_log_info("snd_pcm_hw_params_set_periods_near() failed: %s", pa_alsa_strerror(ret)); + if (_buffer_size > 0) { + snd_pcm_hw_params_copy(hwparams_copy, hwparams); + + /* Third try: set only buffer size */ + if (set_buffer_size(pcm_handle, hwparams_copy, _buffer_size) >= 0 && + snd_pcm_hw_params(pcm_handle, hwparams_copy) >= 0) { + pa_log_debug("Set only buffer size second."); + goto success; } } - /* Now set the buffer size */ - buffer_size = _periods * _period_size; - if ((ret = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hwparams, &buffer_size)) < 0) - pa_log_info("snd_pcm_hw_params_set_buffer_size_near() failed: %s", pa_alsa_strerror(ret)); + if (_period_size > 0) { + snd_pcm_hw_params_copy(hwparams_copy, hwparams); + + /* Fourth try: set only period size */ + if (set_period_size(pcm_handle, hwparams_copy, _period_size) >= 0 && + snd_pcm_hw_params(pcm_handle, hwparams_copy) >= 0) { + pa_log_debug("Set only period size second."); + goto success; + } + } } - if ((ret = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) + pa_log_debug("Set neither period nor buffer size."); + + /* Last chance, set nothing */ + if ((ret = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) { + pa_log_info("snd_pcm_hw_params failed: %s", pa_alsa_strerror(ret)); goto finish; + } + +success: - if (ss->rate != r) - pa_log_info("Device %s doesn't support %u Hz, changed to %u Hz.", snd_pcm_name(pcm_handle), ss->rate, r); + if (ss->rate != _ss.rate) + pa_log_info("Device %s doesn't support %u Hz, changed to %u Hz.", snd_pcm_name(pcm_handle), ss->rate, _ss.rate); - if (ss->channels != c) - pa_log_info("Device %s doesn't support %u channels, changed to %u.", snd_pcm_name(pcm_handle), ss->channels, c); + if (ss->channels != _ss.channels) + pa_log_info("Device %s doesn't support %u channels, changed to %u.", snd_pcm_name(pcm_handle), ss->channels, _ss.channels); - if (ss->format != f) - pa_log_info("Device %s doesn't support sample format %s, changed to %s.", snd_pcm_name(pcm_handle), pa_sample_format_to_string(ss->format), pa_sample_format_to_string(f)); + if (ss->format != _ss.format) + pa_log_info("Device %s doesn't support sample format %s, changed to %s.", snd_pcm_name(pcm_handle), pa_sample_format_to_string(ss->format), pa_sample_format_to_string(_ss.format)); if ((ret = snd_pcm_prepare(pcm_handle)) < 0) { pa_log_info("snd_pcm_prepare() failed: %s", pa_alsa_strerror(ret)); goto finish; } + if ((ret = snd_pcm_hw_params_current(pcm_handle, hwparams)) < 0) { + pa_log_info("snd_pcm_hw_params_current() failed: %s", pa_alsa_strerror(ret)); + goto finish; + } + if ((ret = snd_pcm_hw_params_get_period_size(hwparams, &_period_size, &dir)) < 0 || - (ret = snd_pcm_hw_params_get_periods(hwparams, &_periods, &dir)) < 0) { - pa_log_info("snd_pcm_hw_params_get_period{s|_size}() failed: %s", pa_alsa_strerror(ret)); + (ret = snd_pcm_hw_params_get_buffer_size(hwparams, &_buffer_size)) < 0) { + pa_log_info("snd_pcm_hw_params_get_{period|buffer}_size() failed: %s", pa_alsa_strerror(ret)); goto finish; } /* If the sample rate deviates too much, we need to resample */ - if (r < ss->rate*.95 || r > ss->rate*1.05) - ss->rate = r; - ss->channels = (uint8_t) c; - ss->format = f; + if (_ss.rate < ss->rate*.95 || _ss.rate > ss->rate*1.05) + ss->rate = _ss.rate; + ss->channels = _ss.channels; + ss->format = _ss.format; - pa_assert(_periods > 0); pa_assert(_period_size > 0); + pa_assert(_buffer_size > 0); - if (periods) - *periods = _periods; + if (buffer_size) + *buffer_size = _buffer_size; if (period_size) *period_size = _period_size; @@ -393,8 +461,8 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto( pa_sample_spec *ss, pa_channel_map* map, int mode, - uint32_t *nfrags, snd_pcm_uframes_t *period_size, + snd_pcm_uframes_t *buffer_size, snd_pcm_uframes_t tsched_size, pa_bool_t *use_mmap, pa_bool_t *use_tsched, @@ -410,8 +478,6 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto( pa_assert(dev); pa_assert(ss); pa_assert(map); - pa_assert(nfrags); - pa_assert(period_size); pa_assert(ps); /* First we try to find a device string with a superset of the @@ -433,8 +499,8 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto( ss, map, mode, - nfrags, period_size, + buffer_size, tsched_size, use_mmap, use_tsched, @@ -460,8 +526,8 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto( ss, map, mode, - nfrags, period_size, + buffer_size, tsched_size, use_mmap, use_tsched, @@ -478,7 +544,18 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto( /* OK, we didn't find any good device, so let's try the raw hw: stuff */ d = pa_sprintf_malloc("hw:%s", dev_id); pa_log_debug("Trying %s as last resort...", d); - pcm_handle = pa_alsa_open_by_device_string(d, dev, ss, map, mode, nfrags, period_size, tsched_size, use_mmap, use_tsched, FALSE); + pcm_handle = pa_alsa_open_by_device_string( + d, + dev, + ss, + map, + mode, + period_size, + buffer_size, + tsched_size, + use_mmap, + use_tsched, + FALSE); pa_xfree(d); if (pcm_handle && mapping) @@ -493,8 +570,8 @@ snd_pcm_t *pa_alsa_open_by_device_id_mapping( pa_sample_spec *ss, pa_channel_map* map, int mode, - uint32_t *nfrags, snd_pcm_uframes_t *period_size, + snd_pcm_uframes_t *buffer_size, snd_pcm_uframes_t tsched_size, pa_bool_t *use_mmap, pa_bool_t *use_tsched, @@ -508,8 +585,6 @@ snd_pcm_t *pa_alsa_open_by_device_id_mapping( pa_assert(dev); pa_assert(ss); pa_assert(map); - pa_assert(nfrags); - pa_assert(period_size); pa_assert(m); try_ss.channels = m->channel_map.channels; @@ -524,8 +599,8 @@ snd_pcm_t *pa_alsa_open_by_device_id_mapping( &try_ss, &try_map, mode, - nfrags, period_size, + buffer_size, tsched_size, use_mmap, use_tsched, @@ -547,8 +622,8 @@ snd_pcm_t *pa_alsa_open_by_device_string( pa_sample_spec *ss, pa_channel_map* map, int mode, - uint32_t *nfrags, snd_pcm_uframes_t *period_size, + snd_pcm_uframes_t *buffer_size, snd_pcm_uframes_t tsched_size, pa_bool_t *use_mmap, pa_bool_t *use_tsched, @@ -579,7 +654,15 @@ snd_pcm_t *pa_alsa_open_by_device_string( pa_log_debug("Managed to open %s", d); - if ((err = pa_alsa_set_hw_params(pcm_handle, ss, nfrags, period_size, tsched_size, use_mmap, use_tsched, require_exact_channel_number)) < 0) { + if ((err = pa_alsa_set_hw_params( + pcm_handle, + ss, + period_size, + buffer_size, + tsched_size, + use_mmap, + use_tsched, + require_exact_channel_number)) < 0) { if (!reformat) { reformat = TRUE; @@ -632,8 +715,8 @@ snd_pcm_t *pa_alsa_open_by_template( pa_sample_spec *ss, pa_channel_map* map, int mode, - uint32_t *nfrags, snd_pcm_uframes_t *period_size, + snd_pcm_uframes_t *buffer_size, snd_pcm_uframes_t tsched_size, pa_bool_t *use_mmap, pa_bool_t *use_tsched, @@ -653,8 +736,8 @@ snd_pcm_t *pa_alsa_open_by_template( ss, map, mode, - nfrags, period_size, + buffer_size, tsched_size, use_mmap, use_tsched, @@ -900,7 +983,7 @@ void pa_alsa_init_proplist_ctl(pa_proplist *p, const char *name) { snd_ctl_card_info_alloca(&info); if ((err = snd_ctl_open(&ctl, name, 0)) < 0) { - pa_log_warn("Error opening low-level control device '%s'", name); + pa_log_warn("Error opening low-level control device '%s': %s", name, snd_strerror(err)); return; } diff --git a/src/modules/alsa/alsa-util.h b/src/modules/alsa/alsa-util.h index 830a922e..265cd28c 100644 --- a/src/modules/alsa/alsa-util.h +++ b/src/modules/alsa/alsa-util.h @@ -42,8 +42,8 @@ int pa_alsa_set_hw_params( snd_pcm_t *pcm_handle, pa_sample_spec *ss, /* modified at return */ - uint32_t *periods, /* modified at return */ snd_pcm_uframes_t *period_size, /* modified at return */ + snd_pcm_uframes_t *buffer_size, /* modified at return */ snd_pcm_uframes_t tsched_size, pa_bool_t *use_mmap, /* modified at return */ pa_bool_t *use_tsched, /* modified at return */ @@ -60,8 +60,8 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto( pa_sample_spec *ss, /* modified at return */ pa_channel_map* map, /* modified at return */ int mode, - uint32_t *nfrags, /* modified at return */ snd_pcm_uframes_t *period_size, /* modified at return */ + snd_pcm_uframes_t *buffer_size, /* modified at return */ snd_pcm_uframes_t tsched_size, pa_bool_t *use_mmap, /* modified at return */ pa_bool_t *use_tsched, /* modified at return */ @@ -75,8 +75,8 @@ snd_pcm_t *pa_alsa_open_by_device_id_mapping( pa_sample_spec *ss, /* modified at return */ pa_channel_map* map, /* modified at return */ int mode, - uint32_t *nfrags, /* modified at return */ snd_pcm_uframes_t *period_size, /* modified at return */ + snd_pcm_uframes_t *buffer_size, /* modified at return */ snd_pcm_uframes_t tsched_size, pa_bool_t *use_mmap, /* modified at return */ pa_bool_t *use_tsched, /* modified at return */ @@ -89,8 +89,8 @@ snd_pcm_t *pa_alsa_open_by_device_string( pa_sample_spec *ss, /* modified at return */ pa_channel_map* map, /* modified at return */ int mode, - uint32_t *nfrags, /* modified at return */ snd_pcm_uframes_t *period_size, /* modified at return */ + snd_pcm_uframes_t *buffer_size, /* modified at return */ snd_pcm_uframes_t tsched_size, pa_bool_t *use_mmap, /* modified at return */ pa_bool_t *use_tsched, /* modified at return */ @@ -104,8 +104,8 @@ snd_pcm_t *pa_alsa_open_by_template( pa_sample_spec *ss, /* modified at return */ pa_channel_map* map, /* modified at return */ int mode, - uint32_t *nfrags, /* modified at return */ snd_pcm_uframes_t *period_size, /* modified at return */ + snd_pcm_uframes_t *buffer_size, /* modified at return */ snd_pcm_uframes_t tsched_size, pa_bool_t *use_mmap, /* modified at return */ pa_bool_t *use_tsched, /* modified at return */ diff --git a/src/modules/alsa/mixer/paths/analog-input.conf.common b/src/modules/alsa/mixer/paths/analog-input.conf.common index 6728a6ae..87af38b3 100644 --- a/src/modules/alsa/mixer/paths/analog-input.conf.common +++ b/src/modules/alsa/mixer/paths/analog-input.conf.common @@ -78,6 +78,10 @@ priority = 19 name = input-microphone priority = 19 +[Option Input Source:Internal Mic] +name = input-microphone +priority = 19 + [Option Input Source:Line] name = input-linein priority = 18 @@ -90,6 +94,10 @@ priority = 18 name = input-linein priority = 18 +[Option Input Source:Docking-Station] +name = input-docking +priority = 17 + ;;; ' Capture Source' [Element Capture Source] diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c index 55f6a6e2..6bea33d7 100644 --- a/src/modules/alsa/module-alsa-card.c +++ b/src/modules/alsa/module-alsa-card.c @@ -329,7 +329,7 @@ int pa__init(pa_module *m) { if (!u->profile_set) goto fail; - pa_alsa_profile_set_probe(u->profile_set, u->device_id, &m->core->default_sample_spec); + pa_alsa_profile_set_probe(u->profile_set, u->device_id, &m->core->default_sample_spec, m->core->default_n_fragments, m->core->default_fragment_size_msec); pa_card_new_data_init(&data); data.driver = __FILE__; diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index b8a88042..4592fca1 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -221,9 +221,7 @@ static int service_recv(struct userdata *u, bt_audio_msg_header_t *msg, size_t r pa_assert(u); pa_assert(u->service_fd >= 0); pa_assert(msg); - - if (room <= 0) - room = BT_SUGGESTED_BUFFER_SIZE; + pa_assert(room >= sizeof(*msg)); pa_log_debug("Trying to receive message from audio service..."); @@ -236,6 +234,11 @@ static int service_recv(struct userdata *u, bt_audio_msg_header_t *msg, size_t r return -1; } + if (msg->length > room) { + pa_log_error("Not enough room."); + return -1; + } + /* Secondly, read the payload */ if (msg->length > sizeof(*msg)) { diff --git a/src/modules/hal-util.c b/src/modules/hal-util.c index e2a2d8d7..2d59f51d 100644 --- a/src/modules/hal-util.c +++ b/src/modules/hal-util.c @@ -65,7 +65,7 @@ int pa_hal_get_info(pa_core *core, pa_proplist *p, int card) { goto finish; } - if (!(udis = libhal_find_device_by_capability(hal, "sound", &n, &error)) < 0) { + if (!(udis = libhal_find_device_by_capability(hal, "sound", &n, &error))) { pa_log_error("Couldn't find devices: %s: %s", error.name, error.message); goto finish; } diff --git a/src/modules/module-always-sink.c b/src/modules/module-always-sink.c index aee1c650..3d7de9c6 100644 --- a/src/modules/module-always-sink.c +++ b/src/modules/module-always-sink.c @@ -24,6 +24,7 @@ #endif #include <pulse/xmalloc.h> +#include <pulse/i18n.h> #include <pulsecore/core.h> #include <pulsecore/sink-input.h> @@ -35,7 +36,7 @@ #include "module-always-sink-symdef.h" PA_MODULE_AUTHOR("Colin Guthrie"); -PA_MODULE_DESCRIPTION("Always keeps at least one sink loaded even if it's a null one"); +PA_MODULE_DESCRIPTION(_("Always keeps at least one sink loaded even if it's a null one")); PA_MODULE_VERSION(PACKAGE_VERSION); PA_MODULE_LOAD_ONCE(TRUE); PA_MODULE_USAGE( @@ -78,7 +79,8 @@ static void load_null_sink_if_needed(pa_core *c, pa_sink *sink, struct userdata* u->ignore = TRUE; - t = pa_sprintf_malloc("sink_name=%s", u->sink_name); + t = pa_sprintf_malloc("sink_name=%s sink_properties='device.description=\"%s\"'", u->sink_name, + _("Dummy Output")); m = pa_module_load(c, "module-null-sink", t); u->null_module = m ? m->index : PA_INVALID_INDEX; pa_xfree(t); diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index 6034d0ee..18519131 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -435,9 +435,7 @@ static int hal_device_add_all(struct userdata *u) { int i; for (i = 0; i < n; i++) { - struct device *d; - - if ((d = hal_device_add(u, udis[i]))) { + if (hal_device_add(u, udis[i])) { count++; pa_log_debug("Loaded device %s", udis[i]); } else diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c index 36c50b05..74a2ebb1 100644 --- a/src/modules/module-null-sink.c +++ b/src/modules/module-null-sink.c @@ -35,6 +35,7 @@ #include <pulse/rtclock.h> #include <pulse/timeval.h> #include <pulse/xmalloc.h> +#include <pulse/i18n.h> #include <pulsecore/macro.h> #include <pulsecore/sink.h> @@ -51,7 +52,7 @@ #include "module-null-sink-symdef.h" PA_MODULE_AUTHOR("Lennart Poettering"); -PA_MODULE_DESCRIPTION("Clocked NULL sink"); +PA_MODULE_DESCRIPTION(_("Clocked NULL sink")); PA_MODULE_VERSION(PACKAGE_VERSION); PA_MODULE_LOAD_ONCE(FALSE); PA_MODULE_USAGE( @@ -287,7 +288,7 @@ int pa__init(pa_module*m) { pa_sink_new_data_set_name(&data, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME)); pa_sink_new_data_set_sample_spec(&data, &ss); pa_sink_new_data_set_channel_map(&data, &map); - pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, pa_modargs_get_value(ma, "description", "Null Output")); + pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, pa_modargs_get_value(ma, "description", _("Null Output"))); pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "abstract"); if (pa_modargs_get_proplist(ma, "sink_properties", data.proplist, PA_UPDATE_REPLACE) < 0) { diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c index 5ccb81d0..af4b8b2a 100644 --- a/src/modules/module-tunnel.c +++ b/src/modules/module-tunnel.c @@ -332,7 +332,7 @@ static void command_moved(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa static void command_stream_buffer_attr_changed(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { struct userdata *u = userdata; - uint32_t channel, maxlength, tlength, fragsize, prebuf, minreq; + uint32_t channel, maxlength, tlength = 0, fragsize, prebuf, minreq; pa_usec_t usec; pa_assert(pd); @@ -1097,7 +1097,7 @@ static void sink_input_info_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag uint32_t idx, owner_module, client, sink; pa_usec_t buffer_usec, sink_usec; const char *name, *driver, *resample_method; - pa_bool_t mute; + pa_bool_t mute = FALSE; pa_sample_spec sample_spec; pa_channel_map channel_map; pa_cvolume volume; @@ -1345,12 +1345,11 @@ static void command_subscribe_event(pa_pdispatch *pd, uint32_t command, uint32 /* Called from main context */ static void start_subscribe(struct userdata *u) { pa_tagstruct *t; - uint32_t tag; pa_assert(u); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_SUBSCRIBE); - pa_tagstruct_putu32(t, tag = u->ctag++); + pa_tagstruct_putu32(t, u->ctag++); pa_tagstruct_putu32(t, PA_SUBSCRIPTION_MASK_SERVER| #ifdef TUNNEL_SINK PA_SUBSCRIPTION_MASK_SINK_INPUT|PA_SUBSCRIPTION_MASK_SINK @@ -1526,7 +1525,7 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t reply = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(reply, PA_COMMAND_SET_CLIENT_NAME); - pa_tagstruct_putu32(reply, tag = u->ctag++); + pa_tagstruct_putu32(reply, u->ctag++); if (u->version >= 13) { pa_proplist *pl; @@ -1753,7 +1752,6 @@ static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata static void sink_set_volume(pa_sink *sink) { struct userdata *u; pa_tagstruct *t; - uint32_t tag; pa_assert(sink); u = sink->userdata; @@ -1761,7 +1759,7 @@ static void sink_set_volume(pa_sink *sink) { t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_INPUT_VOLUME); - pa_tagstruct_putu32(t, tag = u->ctag++); + pa_tagstruct_putu32(t, u->ctag++); pa_tagstruct_putu32(t, u->device_index); pa_tagstruct_put_cvolume(t, &sink->real_volume); pa_pstream_send_tagstruct(u->pstream, t); @@ -1771,7 +1769,6 @@ static void sink_set_volume(pa_sink *sink) { static void sink_set_mute(pa_sink *sink) { struct userdata *u; pa_tagstruct *t; - uint32_t tag; pa_assert(sink); u = sink->userdata; @@ -1782,7 +1779,7 @@ static void sink_set_mute(pa_sink *sink) { t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_INPUT_MUTE); - pa_tagstruct_putu32(t, tag = u->ctag++); + pa_tagstruct_putu32(t, u->ctag++); pa_tagstruct_putu32(t, u->device_index); pa_tagstruct_put_boolean(t, !!sink->muted); pa_pstream_send_tagstruct(u->pstream, t); diff --git a/src/modules/module-udev-detect.c b/src/modules/module-udev-detect.c index b41b9c0f..1b1e9c1a 100644 --- a/src/modules/module-udev-detect.c +++ b/src/modules/module-udev-detect.c @@ -29,10 +29,13 @@ #include <sys/inotify.h> #include <libudev.h> +#include <pulse/timeval.h> + #include <pulsecore/modargs.h> #include <pulsecore/core-error.h> #include <pulsecore/core-util.h> #include <pulsecore/namereg.h> +#include <pulsecore/ratelimit.h> #include "module-udev-detect-symdef.h" @@ -50,6 +53,7 @@ struct device { char *card_name; char *args; uint32_t module; + pa_ratelimit ratelimit; }; struct userdata { @@ -110,6 +114,9 @@ static pa_bool_t is_card_busy(const char *id) { pa_assert(id); + /* This simply uses /proc/asound/card.../pcm.../sub.../status to + * check whether there is still a process using this audio device. */ + card_path = pa_sprintf_malloc("/proc/asound/card%s", id); if (!(card_dir = opendir(card_path))) { @@ -234,14 +241,41 @@ static void verify_access(struct userdata *u, struct device *d) { pa_log_debug("%s is busy: %s", d->path, pa_yes_no(busy)); if (!busy) { - pa_log_debug("Loading module-alsa-card with arguments '%s'", d->args); - m = pa_module_load(u->core, "module-alsa-card", d->args); - if (m) { - d->module = m->index; - pa_log_info("Card %s (%s) module loaded.", d->path, d->card_name); + /* So, why do we rate limit here? It's certainly ugly, + * but there seems to be no other way. Problem is + * this: if we are unable to configure/probe an audio + * device after opening it we will close it again and + * the module initialization will fail. This will then + * cause an inotify event on the device node which + * will be forwarded to us. We then try to reopen the + * audio device again, practically entering a busy + * loop. + * + * A clean fix would be if we would be able to ignore + * our own inotify close events. However, inotify + * lacks such functionality. Also, during probing of + * the device we cannot really distuingish between + * other processes causing EBUSY or ourselves, which + * means we have no way to figure out if the probing + * during opening was canceled by a "try again" + * failure or a "fatal" failure. */ + + if (pa_ratelimit_test(&d->ratelimit)) { + pa_log_debug("Loading module-alsa-card with arguments '%s'", d->args); + m = pa_module_load(u->core, "module-alsa-card", d->args); + + if (m) { + d->module = m->index; + pa_log_info("Card %s (%s) module loaded.", d->path, d->card_name); + } else + pa_log_info("Card %s (%s) failed to load module.", d->path, d->card_name); } else - pa_log_info("Card %s (%s) failed to load module.", d->path, d->card_name); + pa_log_warn("Tried to configure %s (%s) more often than %u times in %llus", + d->path, + d->card_name, + d->ratelimit.burst, + (long long unsigned) (d->ratelimit.interval / PA_USEC_PER_SEC)); } } @@ -277,6 +311,7 @@ static void card_changed(struct userdata *u, struct udev_device *dev) { d = pa_xnew0(struct device, 1); d->path = pa_xstrdup(path); d->module = PA_INVALID_INDEX; + PA_INIT_RATELIMIT(d->ratelimit, 10*PA_USEC_PER_SEC, 5); if (!(t = udev_device_get_property_value(dev, "PULSE_NAME"))) if (!(t = udev_device_get_property_value(dev, "ID_ID"))) diff --git a/src/modules/raop/base64.c b/src/modules/raop/base64.c index e1cbed02..5b061034 100644 --- a/src/modules/raop/base64.c +++ b/src/modules/raop/base64.c @@ -57,7 +57,6 @@ int pa_base64_encode(const void *data, int size, char **str) p = s = pa_xnew(char, size * 4 / 3 + 4); q = (const unsigned char *) data; - i = 0; for (i = 0; i < size;) { c = q[i++]; c *= 256; diff --git a/src/modules/rtp/rtsp_client.c b/src/modules/rtp/rtsp_client.c index ba657f74..915c1072 100644 --- a/src/modules/rtp/rtsp_client.c +++ b/src/modules/rtp/rtsp_client.c @@ -456,6 +456,8 @@ static int rtsp_exec(pa_rtsp_client* c, const char* cmd, l = pa_iochannel_write(c->io, hdrs, strlen(hdrs)); pa_xfree(hdrs); + /* FIXME: this is broken, not necessarily all bytes are written */ + return 0; } diff --git a/src/modules/x11/module-x11-publish.c b/src/modules/x11/module-x11-publish.c index 2c7fdc12..7ee1b6da 100644 --- a/src/modules/x11/module-x11-publish.c +++ b/src/modules/x11/module-x11-publish.c @@ -90,7 +90,7 @@ static void publish_servers(struct userdata *u, pa_strlist *l) { l = pa_strlist_reverse(l); s = pa_strlist_tostring(l); - l = pa_strlist_reverse(l); + pa_strlist_reverse(l); pa_x11_set_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_SERVER", s); pa_xfree(s); |