From f7c229d8f9a4c67ff7ef0f3d351069a45ba19aff Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Apr 2009 01:26:04 +0200 Subject: core: add a seperate fixed_latency field for sinks/sources with fixed latency --- src/pulsecore/cli-text.c | 12 ++++++++++-- src/pulsecore/sink-input.c | 13 +++++++++---- src/pulsecore/sink.c | 25 +++++++++++++++++-------- src/pulsecore/sink.h | 2 ++ src/pulsecore/source-output.c | 13 +++++++++---- src/pulsecore/source.c | 28 ++++++++++++++++++---------- src/pulsecore/source.h | 2 ++ 7 files changed, 67 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/pulsecore/cli-text.c b/src/pulsecore/cli-text.c index 324f83c8..b0911ef1 100644 --- a/src/pulsecore/cli-text.c +++ b/src/pulsecore/cli-text.c @@ -288,7 +288,11 @@ char *pa_sink_list_to_string(pa_core *c) { (double) pa_sink_get_requested_latency(sink) / (double) PA_USEC_PER_MSEC, (double) min_latency / PA_USEC_PER_MSEC, (double) max_latency / PA_USEC_PER_MSEC); - } + } else + pa_strbuf_printf( + s, + "\tfixed latency: %0.2f ms\n", + (double) pa_sink_get_requested_latency(sink) / PA_USEC_PER_MSEC); if (sink->card) pa_strbuf_printf(s, "\tcard: %u <%s>\n", sink->card->index, sink->card->name); @@ -382,7 +386,11 @@ char *pa_source_list_to_string(pa_core *c) { (double) pa_source_get_requested_latency(source) / PA_USEC_PER_MSEC, (double) min_latency / PA_USEC_PER_MSEC, (double) max_latency / PA_USEC_PER_MSEC); - } + } else + pa_strbuf_printf( + s, + "\tfixed latency: %0.2f ms\n", + (double) pa_source_get_requested_latency(source) / PA_USEC_PER_MSEC); if (source->monitor_of) pa_strbuf_printf(s, "\tmonitor_of: %u\n", source->monitor_of->index); diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 9ae98edd..b1b9fb56 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -824,6 +824,9 @@ void pa_sink_input_update_max_request(pa_sink_input *i, size_t nbytes /* in the pa_usec_t pa_sink_input_set_requested_latency_within_thread(pa_sink_input *i, pa_usec_t usec) { pa_sink_input_assert_ref(i); + if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY)) + usec = i->sink->fixed_latency; + if (usec != (pa_usec_t) -1) usec = PA_CLAMP(usec, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency); @@ -835,8 +838,6 @@ pa_usec_t pa_sink_input_set_requested_latency_within_thread(pa_sink_input *i, pa /* Called from main context */ pa_usec_t pa_sink_input_set_requested_latency(pa_sink_input *i, pa_usec_t usec) { - pa_usec_t min_latency, max_latency; - pa_sink_input_assert_ref(i); if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) { @@ -848,10 +849,14 @@ pa_usec_t pa_sink_input_set_requested_latency(pa_sink_input *i, pa_usec_t usec) * we have to touch the thread info data directly */ if (i->sink) { - pa_sink_get_latency_range(i->sink, &min_latency, &max_latency); + if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY)) + usec = i->sink->fixed_latency; - if (usec != (pa_usec_t) -1) + if (usec != (pa_usec_t) -1) { + pa_usec_t min_latency, max_latency; + pa_sink_get_latency_range(i->sink, &min_latency, &max_latency); usec = PA_CLAMP(usec, min_latency, max_latency); + } } i->thread_info.requested_sink_latency = usec; diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 2771fecb..93800d14 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -50,6 +50,7 @@ #define MIX_BUFFER_LENGTH (PA_PAGE_SIZE) #define ABSOLUTE_MIN_LATENCY (500) #define ABSOLUTE_MAX_LATENCY (10*PA_USEC_PER_SEC) +#define DEFAULT_FIXED_LATENCY (250*PA_USEC_PER_MSEC) static PA_DEFINE_CHECK_TYPE(pa_sink, pa_msgobject); @@ -208,6 +209,8 @@ pa_sink* pa_sink_new( s->muted = data->muted; s->refresh_volume = s->refresh_muted = FALSE; + s->fixed_latency = flags & PA_SINK_DYNAMIC_LATENCY ? 0 : DEFAULT_FIXED_LATENCY; + reset_callbacks(s); s->userdata = NULL; @@ -363,8 +366,13 @@ void pa_sink_put(pa_sink* s) { if (s->flags & PA_SINK_LATENCY) s->monitor_source->flags |= PA_SOURCE_LATENCY; - if (s->flags & PA_SINK_DYNAMIC_LATENCY) + if (s->flags & PA_SINK_DYNAMIC_LATENCY) { s->monitor_source->flags |= PA_SOURCE_DYNAMIC_LATENCY; + s->fixed_latency = 0; + } else if (s->fixed_latency <= 0) + s->fixed_latency = DEFAULT_FIXED_LATENCY; + + s->monitor_source->fixed_latency = s->fixed_latency; pa_assert_se(sink_set_state(s, PA_SINK_IDLE) == 0); @@ -1824,6 +1832,9 @@ pa_usec_t pa_sink_get_requested_latency_within_thread(pa_sink *s) { pa_sink_assert_ref(s); + if (!(s->flags & PA_SINK_DYNAMIC_LATENCY)) + return PA_CLAMP(s->fixed_latency, s->thread_info.min_latency, s->thread_info.max_latency); + if (s->thread_info.requested_latency_valid) return s->thread_info.requested_latency; @@ -1839,13 +1850,8 @@ pa_usec_t pa_sink_get_requested_latency_within_thread(pa_sink *s) { (result == (pa_usec_t) -1 || result > monitor_latency)) result = monitor_latency; - if (result != (pa_usec_t) -1) { - if (result > s->thread_info.max_latency) - result = s->thread_info.max_latency; - - if (result < s->thread_info.min_latency) - result = s->thread_info.min_latency; - } + if (result != (pa_usec_t) -1) + result = PA_CLAMP(result, s->thread_info.min_latency, s->thread_info.max_latency); s->thread_info.requested_latency = result; s->thread_info.requested_latency_valid = TRUE; @@ -1934,6 +1940,9 @@ void pa_sink_invalidate_requested_latency(pa_sink *s) { pa_sink_assert_ref(s); + if (!(s->flags & PA_SINK_DYNAMIC_LATENCY)) + return; + s->thread_info.requested_latency_valid = FALSE; if (PA_SINK_IS_LINKED(s->thread_info.state)) { diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index 289054de..cb4697f9 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -86,6 +86,8 @@ struct pa_sink { pa_memchunk silence; + pa_usec_t fixed_latency; /* for sinks with PA_SINK_DYNAMIC_LATENCY this is 0 */ + /* Called when the main loop requests a state change. Called from * main loop context. If returns -1 the state change will be * inhibited */ diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index 489393a5..3ee26735 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -520,6 +520,9 @@ void pa_source_output_update_max_rewind(pa_source_output *o, size_t nbytes /* i pa_usec_t pa_source_output_set_requested_latency_within_thread(pa_source_output *o, pa_usec_t usec) { pa_source_output_assert_ref(o); + if (!(o->source->flags & PA_SOURCE_DYNAMIC_LATENCY)) + usec = o->source->fixed_latency; + if (usec != (pa_usec_t) -1) usec = PA_CLAMP(usec, o->source->thread_info.min_latency, o->source->thread_info.max_latency); @@ -531,8 +534,6 @@ pa_usec_t pa_source_output_set_requested_latency_within_thread(pa_source_output /* Called from main context */ pa_usec_t pa_source_output_set_requested_latency(pa_source_output *o, pa_usec_t usec) { - pa_usec_t min_latency, max_latency; - pa_source_output_assert_ref(o); if (PA_SOURCE_OUTPUT_IS_LINKED(o->state) && o->source) { @@ -544,10 +545,14 @@ pa_usec_t pa_source_output_set_requested_latency(pa_source_output *o, pa_usec_t * have to touch the thread info data directly */ if (o->source) { - pa_source_get_latency_range(o->source, &min_latency, &max_latency); + if (!(o->source->flags & PA_SOURCE_DYNAMIC_LATENCY)) + usec = o->source->fixed_latency; - if (usec != (pa_usec_t) -1) + if (usec != (pa_usec_t) -1) { + pa_usec_t min_latency, max_latency; + pa_source_get_latency_range(o->source, &min_latency, &max_latency); usec = PA_CLAMP(usec, min_latency, max_latency); + } } o->thread_info.requested_source_latency = usec; diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 693fab3c..21902509 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -43,6 +43,7 @@ #define ABSOLUTE_MIN_LATENCY (500) #define ABSOLUTE_MAX_LATENCY (10*PA_USEC_PER_SEC) +#define DEFAULT_FIXED_LATENCY (250*PA_USEC_PER_MSEC) static PA_DEFINE_CHECK_TYPE(pa_source, pa_msgobject); @@ -199,6 +200,8 @@ pa_source* pa_source_new( s->muted = data->muted; s->refresh_volume = s->refresh_muted = FALSE; + s->fixed_latency = flags & PA_SOURCE_DYNAMIC_LATENCY ? 0 : DEFAULT_FIXED_LATENCY; + reset_callbacks(s); s->userdata = NULL; @@ -303,8 +306,7 @@ void pa_source_put(pa_source *s) { /* The following fields must be initialized properly when calling _put() */ pa_assert(s->asyncmsgq); pa_assert(s->rtpoll); - pa_assert(!s->thread_info.min_latency || !s->thread_info.max_latency || - s->thread_info.min_latency <= s->thread_info.max_latency); + pa_assert(s->thread_info.min_latency <= s->thread_info.max_latency); if (!(s->flags & PA_SOURCE_HW_VOLUME_CTRL)) { s->flags |= PA_SOURCE_DECIBEL_VOLUME; @@ -316,6 +318,11 @@ void pa_source_put(pa_source *s) { if (s->flags & PA_SOURCE_DECIBEL_VOLUME) s->n_volume_steps = PA_VOLUME_NORM+1; + if (s->flags & PA_SOURCE_DYNAMIC_LATENCY) + s->fixed_latency = 0; + else if (s->fixed_latency <= 0) + s->fixed_latency = DEFAULT_FIXED_LATENCY; + pa_assert_se(source_set_state(s, PA_SOURCE_IDLE) == 0); pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index); @@ -1096,6 +1103,9 @@ pa_usec_t pa_source_get_requested_latency_within_thread(pa_source *s) { pa_source_assert_ref(s); + if (!(s->flags & PA_SOURCE_DYNAMIC_LATENCY)) + return PA_CLAMP(s->fixed_latency, s->thread_info.min_latency, s->thread_info.max_latency); + if (s->thread_info.requested_latency_valid) return s->thread_info.requested_latency; @@ -1105,13 +1115,8 @@ pa_usec_t pa_source_get_requested_latency_within_thread(pa_source *s) { (result == (pa_usec_t) -1 || result > o->thread_info.requested_source_latency)) result = o->thread_info.requested_source_latency; - if (result != (pa_usec_t) -1) { - if (s->thread_info.max_latency > 0 && result > s->thread_info.max_latency) - result = s->thread_info.max_latency; - - if (s->thread_info.min_latency > 0 && result < s->thread_info.min_latency) - result = s->thread_info.min_latency; - } + if (result != (pa_usec_t) -1) + result = PA_CLAMP(result, s->thread_info.min_latency, s->thread_info.max_latency); s->thread_info.requested_latency = result; s->thread_info.requested_latency_valid = TRUE; @@ -1121,7 +1126,7 @@ pa_usec_t pa_source_get_requested_latency_within_thread(pa_source *s) { /* Called from main thread */ pa_usec_t pa_source_get_requested_latency(pa_source *s) { - pa_usec_t usec; + pa_usec_t usec = 0; pa_source_assert_ref(s); pa_assert(PA_SOURCE_IS_LINKED(s->state)); @@ -1169,6 +1174,9 @@ void pa_source_invalidate_requested_latency(pa_source *s) { pa_source_assert_ref(s); + if (!(s->flags & PA_SOURCE_DYNAMIC_LATENCY)) + return; + s->thread_info.requested_latency_valid = FALSE; if (PA_SOURCE_IS_LINKED(s->thread_info.state)) { diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h index 652783ef..b502c228 100644 --- a/src/pulsecore/source.h +++ b/src/pulsecore/source.h @@ -87,6 +87,8 @@ struct pa_source { pa_memchunk silence; + pa_usec_t fixed_latency; /* for sources with PA_SOURCE_DYNAMIC_LATENCY this is 0 */ + /* Called when the main loop requests a state change. Called from * main loop context. If returns -1 the state change will be * inhibited */ -- cgit