From: Lars R. Damerow Date: Thu, 3 Nov 2011 20:14:45 +0000 (+0100) Subject: alsa: support fixed latency range in alsa modules X-Git-Tag: 1.0_branch~251 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7a387fed36ed5bc0b925269fb76b5e8e3a738a5f;p=profile%2Fivi%2Fpulseaudio.git alsa: support fixed latency range in alsa modules This adds a boolean module parameter to disable automatic dynamic latency readjustments on underruns, but leaves automatic dynamic watermark readjustments untouched. --- diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index 7b31b1b..1386196 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -134,7 +134,7 @@ struct userdata { char *device_name; /* name of the PCM device */ char *control_device; /* name of the control device */ - pa_bool_t use_mmap:1, use_tsched:1, deferred_volume:1; + pa_bool_t use_mmap:1, use_tsched:1, deferred_volume:1, fixed_latency_range:1; pa_bool_t first, after_rewind; @@ -331,7 +331,12 @@ static void increase_watermark(struct userdata *u) { return; } - /* Hmm, we cannot increase the watermark any further, hence let's raise the latency */ + /* Hmm, we cannot increase the watermark any further, hence let's + raise the latency, unless doing so was disabled in + configuration */ + if (u->fixed_latency_range) + return; + old_min_latency = u->sink->thread_info.min_latency; new_min_latency = PA_MIN(old_min_latency * 2, old_min_latency + TSCHED_WATERMARK_INC_STEP_USEC); new_min_latency = PA_MIN(new_min_latency, u->sink->thread_info.max_latency); @@ -1969,7 +1974,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca uint32_t nfrags, frag_size, buffer_size, tsched_size, tsched_watermark, rewind_safeguard; 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, namereg_fail = FALSE, deferred_volume = FALSE, set_formats = FALSE; + pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d, ignore_dB = FALSE, namereg_fail = FALSE, deferred_volume = FALSE, set_formats = FALSE, fixed_latency_range = FALSE; pa_sink_new_data data; pa_alsa_profile_set *profile_set = NULL; @@ -2039,6 +2044,11 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca goto fail; } + if (pa_modargs_get_value_boolean(ma, "fixed_latency_range", &fixed_latency_range) < 0) { + pa_log("Failed to parse fixed_latency_range argument."); + goto fail; + } + use_tsched = pa_alsa_may_tsched(use_tsched); u = pa_xnew0(struct userdata, 1); @@ -2047,6 +2057,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca u->use_mmap = use_mmap; u->use_tsched = use_tsched; u->deferred_volume = deferred_volume; + u->fixed_latency_range = fixed_latency_range; u->first = TRUE; u->rewind_safeguard = rewind_safeguard; u->rtpoll = pa_rtpoll_new(); @@ -2143,9 +2154,13 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca if (u->use_mmap) pa_log_info("Successfully enabled mmap() mode."); - if (u->use_tsched) + if (u->use_tsched) { pa_log_info("Successfully enabled timer-based scheduling mode."); + if (u->fixed_latency_range) + pa_log_info("Disabling latency range changes on underrun"); + } + if (is_iec958(u) || is_hdmi(u)) set_formats = TRUE; diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c index 7a51572..255a61d 100644 --- a/src/modules/alsa/alsa-source.c +++ b/src/modules/alsa/alsa-source.c @@ -121,7 +121,7 @@ struct userdata { char *device_name; /* name of the PCM device */ char *control_device; /* name of the control device */ - pa_bool_t use_mmap:1, use_tsched:1, deferred_volume:1; + pa_bool_t use_mmap:1, use_tsched:1, deferred_volume:1, fixed_latency_range:1; pa_bool_t first; @@ -306,7 +306,12 @@ static void increase_watermark(struct userdata *u) { return; } - /* Hmm, we cannot increase the watermark any further, hence let's raise the latency */ + /* Hmm, we cannot increase the watermark any further, hence let's + raise the latency unless doing so was disabled in + configuration */ + if (u->fixed_latency_range) + return; + old_min_latency = u->source->thread_info.min_latency; new_min_latency = PA_MIN(old_min_latency * 2, old_min_latency + TSCHED_WATERMARK_INC_STEP_USEC); new_min_latency = PA_MIN(new_min_latency, u->source->thread_info.max_latency); @@ -1710,7 +1715,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p 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, namereg_fail = FALSE, deferred_volume = FALSE; + pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d, ignore_dB = FALSE, namereg_fail = FALSE, deferred_volume = FALSE, fixed_latency_range = FALSE; pa_source_new_data data; pa_alsa_profile_set *profile_set = NULL; @@ -1774,6 +1779,11 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p goto fail; } + if (pa_modargs_get_value_boolean(ma, "fixed_latency_range", &fixed_latency_range) < 0) { + pa_log("Failed to parse fixed_latency_range argument."); + goto fail; + } + use_tsched = pa_alsa_may_tsched(use_tsched); u = pa_xnew0(struct userdata, 1); @@ -1782,6 +1792,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p u->use_mmap = use_mmap; u->use_tsched = use_tsched; u->deferred_volume = deferred_volume; + u->fixed_latency_range = fixed_latency_range; u->first = TRUE; u->rtpoll = pa_rtpoll_new(); pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll); @@ -1877,8 +1888,11 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p if (u->use_mmap) pa_log_info("Successfully enabled mmap() mode."); - if (u->use_tsched) + if (u->use_tsched) { pa_log_info("Successfully enabled timer-based scheduling mode."); + if (u->fixed_latency_range) + pa_log_info("Disabling latency range changes on overrun"); + } u->rates = pa_alsa_get_supported_rates(u->pcm_handle); if (!u->rates) { diff --git a/src/modules/alsa/module-alsa-sink.c b/src/modules/alsa/module-alsa-sink.c index 019ccf0..927f075 100644 --- a/src/modules/alsa/module-alsa-sink.c +++ b/src/modules/alsa/module-alsa-sink.c @@ -59,7 +59,8 @@ PA_MODULE_USAGE( "rewind_safeguard= " "deferred_volume= " "deferred_volume_safety_margin= " - "deferred_volume_extra_delay="); + "deferred_volume_extra_delay= " + "fixed_latency_range="); static const char* const valid_modargs[] = { "name", @@ -85,6 +86,7 @@ static const char* const valid_modargs[] = { "deferred_volume", "deferred_volume_safety_margin", "deferred_volume_extra_delay", + "fixed_latency_range", NULL }; diff --git a/src/modules/alsa/module-alsa-source.c b/src/modules/alsa/module-alsa-source.c index 2d2c8b6..efb2d0c 100644 --- a/src/modules/alsa/module-alsa-source.c +++ b/src/modules/alsa/module-alsa-source.c @@ -67,7 +67,8 @@ PA_MODULE_USAGE( "control=" "deferred_volume= " "deferred_volume_safety_margin= " - "deferred_volume_extra_delay="); + "deferred_volume_extra_delay= " + "fixed_latency_range="); static const char* const valid_modargs[] = { "name", @@ -92,6 +93,7 @@ static const char* const valid_modargs[] = { "deferred_volume", "deferred_volume_safety_margin", "deferred_volume_extra_delay", + "fixed_latency_range", NULL }; diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 0ee4ead..d6bff11 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -1008,6 +1008,10 @@ static void fix_playback_buffer_attr(playback_stream *s) { tlength_usec -= s->configured_sink_latency; } + pa_log_debug("Requested latency=%0.2f ms, Received latency=%0.2f ms", + (double) sink_usec / PA_USEC_PER_MSEC, + (double) s->configured_sink_latency / PA_USEC_PER_MSEC); + /* FIXME: This is actually larger than necessary, since not all of * the sink latency is actually rewritable. */ if (tlength_usec < s->configured_sink_latency + 2*minreq_usec)