From da37a7e93db0f17e03f94f7835d7075faa3ac4ba Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 9 Apr 2008 01:16:43 +0000 Subject: [PATCH] export both min and max latency that is configured for a sink; add API for querying the requested latency of a sink/source from the main thread git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/glitch-free@2225 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink-input.c | 14 +++++++++++--- src/pulsecore/sink.c | 39 ++++++++++++++++++++++++++++++++++++--- src/pulsecore/sink.h | 7 +++++-- src/pulsecore/source-output.c | 15 ++++++++++++--- src/pulsecore/source.c | 39 ++++++++++++++++++++++++++++++++++++--- src/pulsecore/source.h | 5 ++++- 6 files changed, 104 insertions(+), 15 deletions(-) diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 989e2ae..ddd9980 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -677,13 +677,21 @@ void pa_sink_input_set_max_rewind(pa_sink_input *i, size_t nbytes /* in the sin pa_usec_t pa_sink_input_set_requested_latency(pa_sink_input *i, pa_usec_t usec) { pa_sink_input_assert_ref(i); - if (usec < i->sink->min_latency) - usec = i->sink->min_latency; + if (usec > 0) { + + if (i->sink->max_latency > 0 && usec > i->sink->max_latency) + usec = i->sink->max_latency; + + if (i->sink->min_latency > 0 && usec < i->sink->min_latency) + usec = i->sink->min_latency; + } if (PA_SINK_INPUT_LINKED(i->state)) pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY, NULL, (int64_t) usec, NULL, NULL); - else + else { i->thread_info.requested_sink_latency = usec; + i->sink->thread_info.requested_latency_valid = FALSE; + } return usec; } diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 39ce83f..02f568e 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -188,6 +188,7 @@ pa_sink* pa_sink_new( s->silence = pa_silence_memblock_new(core->mempool, &s->sample_spec, 0); s->min_latency = DEFAULT_MIN_LATENCY; + s->max_latency = s->min_latency; s->thread_info.inputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); s->thread_info.soft_volume = s->volume; @@ -278,6 +279,8 @@ void pa_sink_put(pa_sink* s) { pa_assert(s->asyncmsgq); pa_assert(s->rtpoll); + pa_assert(!s->min_latency || !s->max_latency || s->min_latency <= s->max_latency); + if (s->get_volume && s->set_volume) s->flags |= PA_SINK_HW_VOLUME_CTRL; else @@ -1132,13 +1135,20 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse * asyncmsgq and rtpoll fields can be changed without * problems */ pa_sink_detach_within_thread(s); - break; + return 0; case PA_SINK_MESSAGE_ATTACH: /* Reattach all streams */ pa_sink_attach_within_thread(s); - break; + return 0; + + case PA_SINK_MESSAGE_GET_REQUESTED_LATENCY: { + + pa_usec_t *usec = userdata; + *usec = pa_sink_get_requested_latency_within_thread(s); + return 0; + } case PA_SINK_MESSAGE_GET_LATENCY: case PA_SINK_MESSAGE_MAX: @@ -1223,7 +1233,7 @@ void pa_sink_request_rewind(pa_sink*s, size_t nbytes) { s->request_rewind(s); } -pa_usec_t pa_sink_get_requested_latency(pa_sink *s) { +pa_usec_t pa_sink_get_requested_latency_within_thread(pa_sink *s) { pa_usec_t result = 0; pa_sink_input *i; void *state = NULL; @@ -1239,12 +1249,35 @@ pa_usec_t pa_sink_get_requested_latency(pa_sink *s) { (!result || result > i->thread_info.requested_sink_latency)) result = i->thread_info.requested_sink_latency; + if (result > 0) { + if (s->max_latency > 0 && result > s->max_latency) + result = s->max_latency; + + if (s->min_latency > 0 && result < s->min_latency) + result = s->min_latency; + } + s->thread_info.requested_latency = result; s->thread_info.requested_latency_valid = TRUE; return result; } +pa_usec_t pa_sink_get_requested_latency(pa_sink *s) { + pa_usec_t usec = 0; + + pa_sink_assert_ref(s); + pa_assert(PA_SINK_LINKED(s->state)); + + if (!PA_SINK_OPENED(s->state)) + return 0; + + if (pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) < 0) + return 0; + + return usec; +} + void pa_sink_set_max_rewind(pa_sink *s, size_t max_rewind) { pa_sink_input *i; void *state = NULL; diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index 23f02c4..2dfd845 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -91,7 +91,8 @@ struct pa_sink { pa_memblock *silence; - pa_usec_t min_latency; /* we won't go below this latency setting */ + pa_usec_t min_latency; /* we won't go below this latency */ + pa_usec_t max_latency; /* An upper limit for the latencies */ int (*set_state)(pa_sink *s, pa_sink_state_t state); /* may be NULL */ int (*set_volume)(pa_sink *s); /* dito */ @@ -135,6 +136,7 @@ typedef enum pa_sink_message { PA_SINK_MESSAGE_GET_MUTE, PA_SINK_MESSAGE_SET_MUTE, PA_SINK_MESSAGE_GET_LATENCY, + PA_SINK_MESSAGE_GET_REQUESTED_LATENCY, PA_SINK_MESSAGE_SET_STATE, PA_SINK_MESSAGE_PING, PA_SINK_MESSAGE_REMOVE_INPUT_AND_BUFFER, @@ -191,6 +193,7 @@ void pa_sink_attach(pa_sink *s); /* The returned value is supposed to be in the time domain of the sound card! */ pa_usec_t pa_sink_get_latency(pa_sink *s); +pa_usec_t pa_sink_get_requested_latency(pa_sink *s); int pa_sink_update_status(pa_sink*s); int pa_sink_suspend(pa_sink *s, pa_bool_t suspend); @@ -227,7 +230,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse void pa_sink_attach_within_thread(pa_sink *s); void pa_sink_detach_within_thread(pa_sink *s); -pa_usec_t pa_sink_get_requested_latency(pa_sink *s); +pa_usec_t pa_sink_get_requested_latency_within_thread(pa_sink *s); void pa_sink_set_max_rewind(pa_sink *s, size_t max_rewind); diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index d6c2a2b..cf576ac 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -364,13 +364,22 @@ pa_usec_t pa_source_output_set_requested_latency(pa_source_output *o, pa_usec_t pa_source_output_assert_ref(o); pa_assert(PA_SOURCE_OUTPUT_LINKED(o->state)); - if (usec < o->source->min_latency) - usec = o->source->min_latency; + if (usec > 0) { + + if (o->source->max_latency > 0 && usec > o->source->max_latency) + usec = o->source->max_latency; + + if (o->source->min_latency > 0 && usec < o->source->min_latency) + usec = o->source->min_latency; + + } if (PA_SOURCE_OUTPUT_LINKED(o->state)) pa_asyncmsgq_post(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_REQUESTED_LATENCY, NULL, (int64_t) usec, NULL, NULL); - else + else { o->thread_info.requested_source_latency = usec; + o->source->thread_info.requested_latency_valid = FALSE; + } return usec; } diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index b150d8a..5a4b630 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -166,6 +166,7 @@ pa_source* pa_source_new( s->refresh_volume = s->refresh_muted = FALSE; s->min_latency = DEFAULT_MIN_LATENCY; + s->max_latency = s->min_latency; s->get_latency = NULL; s->set_volume = NULL; @@ -243,6 +244,8 @@ void pa_source_put(pa_source *s) { pa_assert(s->rtpoll); pa_assert(s->asyncmsgq); + pa_assert(!s->min_latency || !s->max_latency || s->min_latency <= s->max_latency); + if (s->get_volume && s->set_volume) s->flags |= PA_SOURCE_HW_VOLUME_CTRL; else { @@ -616,13 +619,20 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_ * asyncmsgq and rtpoll fields can be changed without * problems */ pa_source_detach_within_thread(s); - break; + return 0; case PA_SOURCE_MESSAGE_ATTACH: /* Reattach all streams */ pa_source_attach_within_thread(s); - break; + return 0; + + case PA_SOURCE_MESSAGE_GET_REQUESTED_LATENCY: { + + pa_usec_t *usec = userdata; + *usec = pa_source_get_requested_latency_within_thread(s); + return 0; + } case PA_SOURCE_MESSAGE_GET_LATENCY: case PA_SOURCE_MESSAGE_MAX: @@ -683,7 +693,7 @@ void pa_source_attach_within_thread(pa_source *s) { o->attach(o); } -pa_usec_t pa_source_get_requested_latency(pa_source *s) { +pa_usec_t pa_source_get_requested_latency_within_thread(pa_source *s) { pa_usec_t result = 0; pa_source_output *o; void *state = NULL; @@ -699,12 +709,35 @@ pa_usec_t pa_source_get_requested_latency(pa_source *s) { (!result || result > o->thread_info.requested_source_latency)) result = o->thread_info.requested_source_latency; + if (result > 0) { + if (s->max_latency > 0 && result > s->max_latency) + result = s->max_latency; + + if (s->min_latency > 0 && result < s->min_latency) + result = s->min_latency; + } + s->thread_info.requested_latency = result; s->thread_info.requested_latency_valid = TRUE; return result; } +pa_usec_t pa_source_get_requested_latency(pa_source *s) { + pa_usec_t usec; + + pa_source_assert_ref(s); + pa_assert(PA_SOURCE_LINKED(s->state)); + + if (!PA_SOURCE_OPENED(s->state)) + return 0; + + if (pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) < 0) + return 0; + + return usec; +} + void pa_source_invalidate_requested_latency(pa_source *s) { pa_source_assert_ref(s); diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h index 3ec8320..ab7236e 100644 --- a/src/pulsecore/source.h +++ b/src/pulsecore/source.h @@ -92,6 +92,7 @@ struct pa_source { pa_rtpoll *rtpoll; pa_usec_t min_latency; /* we won't go below this latency setting */ + pa_usec_t max_latency; /* An upper limit for the latencies */ int (*set_state)(pa_source*source, pa_source_state_t state); /* may be NULL */ int (*set_volume)(pa_source *s); /* dito */ @@ -127,6 +128,7 @@ typedef enum pa_source_message { PA_SOURCE_MESSAGE_GET_MUTE, PA_SOURCE_MESSAGE_SET_MUTE, PA_SOURCE_MESSAGE_GET_LATENCY, + PA_SOURCE_MESSAGE_GET_REQUESTED_LATENCY, PA_SOURCE_MESSAGE_SET_STATE, PA_SOURCE_MESSAGE_PING, PA_SOURCE_MESSAGE_ATTACH, @@ -181,6 +183,7 @@ void pa_source_attach(pa_source *s); /* May be called by everyone, from main context */ pa_usec_t pa_source_get_latency(pa_source *s); +pa_usec_t pa_source_get_requested_latency(pa_source *s); int pa_source_update_status(pa_source*s); int pa_source_suspend(pa_source *s, pa_bool_t suspend); @@ -206,7 +209,7 @@ int pa_source_process_msg(pa_msgobject *o, int code, void *userdata, int64_t, pa void pa_source_attach_within_thread(pa_source *s); void pa_source_detach_within_thread(pa_source *s); -pa_usec_t pa_source_get_requested_latency(pa_source *s); +pa_usec_t pa_source_get_requested_latency_within_thread(pa_source *s); /* To be called exclusively by source output drivers, from IO context */ -- 2.7.4