From 8389264d6560d32b3912c60474497742807efbde Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 15 Sep 2007 14:21:05 +0000 Subject: [PATCH] count corked streams per sink/source and make pa_sink_used_by() return only the number of streams that are not corked. Introduce pa_sink_linked_by() returning the number of streams connected at all. This will allow suspending of sinks/sources when all streams connected to a sink are corked. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1824 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-combine.c | 2 +- src/pulsecore/sink-input.c | 19 +++++++++++++++++-- src/pulsecore/sink.c | 19 +++++++++++++++++++ src/pulsecore/sink.h | 6 ++++-- src/pulsecore/source-output.c | 6 ++++++ src/pulsecore/source.c | 15 ++++++++++++++- src/pulsecore/source.h | 4 +++- 7 files changed, 64 insertions(+), 7 deletions(-) diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 91561ee..86ae0b1 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -385,7 +385,7 @@ static void sink_input_detach_cb(pa_sink_input *i) { o->rtpoll_item = NULL; if (o->userdata->master == o) - pa_sink_detach_from_thread(o->userdata->sink); + pa_sink_detach_within_thread(o->userdata->sink); } /* Called from main context */ diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 2687cfa..009000e 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -225,6 +225,15 @@ pa_sink_input* pa_sink_input_new( return i; } +static void update_n_corked(pa_sink_input *i, pa_sink_input_state_t state) { + pa_assert(i); + + if (i->state == PA_SINK_INPUT_CORKED && state != PA_SINK_INPUT_CORKED) + pa_assert_se(i->sink->n_corked -- >= 1); + else if (i->state != PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_CORKED) + i->sink->n_corked++; +} + static int sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) { pa_sink_input *ssync; pa_assert(i); @@ -238,11 +247,17 @@ static int sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) { if (pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) < 0) return -1; + update_n_corked(i, state); i->state = state; - for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev) + + for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev) { + update_n_corked(ssync, state); ssync->state = state; - for (ssync = i->sync_next; ssync; ssync = ssync->sync_next) + } + for (ssync = i->sync_next; ssync; ssync = ssync->sync_next) { + update_n_corked(ssync, state); ssync->state = state; + } return 0; } diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 9b19188..318b191 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -101,6 +101,7 @@ pa_sink* pa_sink_new( s->channel_map = *map; s->inputs = pa_idxset_new(NULL, NULL); + s->n_corked = 0; pa_cvolume_reset(&s->volume, spec->channels); s->muted = 0; @@ -735,6 +736,20 @@ void pa_sink_set_description(pa_sink *s, const char *description) { pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); } +unsigned pa_sink_linked_by(pa_sink *s) { + unsigned ret; + + pa_sink_assert_ref(s); + pa_assert(PA_SINK_LINKED(s->state)); + + ret = pa_idxset_size(s->inputs); + + if (s->monitor_source) + ret += pa_source_used_by(s->monitor_source); + + return ret; +} + unsigned pa_sink_used_by(pa_sink *s) { unsigned ret; @@ -743,6 +758,10 @@ unsigned pa_sink_used_by(pa_sink *s) { ret = pa_idxset_size(s->inputs); + pa_assert(ret >= s->n_corked); + + ret -= s->n_corked; + if (s->monitor_source) ret += pa_source_used_by(s->monitor_source); diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index be883ed..537e9cb 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -77,7 +77,8 @@ struct pa_sink { pa_channel_map channel_map; pa_idxset *inputs; - pa_source *monitor_source; + unsigned n_corked; + pa_source *monitor_source; pa_cvolume volume; int muted; @@ -166,7 +167,8 @@ const pa_cvolume *pa_sink_get_volume(pa_sink *sink); void pa_sink_set_mute(pa_sink *sink, int mute); int pa_sink_get_mute(pa_sink *sink); -unsigned pa_sink_used_by(pa_sink *s); +unsigned pa_sink_linked_by(pa_sink *s); /* Number of connected streams */ +unsigned pa_sink_used_by(pa_sink *s); /* Number of connected streams which are not corked */ #define pa_sink_get_state(s) ((s)->state) /* To be called exclusively by the sink driver, from IO context */ diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index b77a4ae..8650e53 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -182,7 +182,13 @@ static int source_output_set_state(pa_source_output *o, pa_source_output_state_t if (pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) < 0) return -1; + if (o->state == PA_SOURCE_OUTPUT_CORKED && state != PA_SOURCE_OUTPUT_CORKED) + pa_assert_se(o->source->n_corked -- >= 1); + else if (o->state != PA_SOURCE_OUTPUT_CORKED && state == PA_SOURCE_OUTPUT_CORKED) + o->source->n_corked++; + o->state = state; + return 0; } diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 63ff9d7..d72349f 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -93,6 +93,7 @@ pa_source* pa_source_new( s->channel_map = *map; s->outputs = pa_idxset_new(NULL, NULL); + s->n_corked = 0; s->monitor_of = NULL; pa_cvolume_reset(&s->volume, spec->channels); @@ -426,13 +427,25 @@ void pa_source_set_rtpoll(pa_source *s, pa_rtpoll *p) { s->rtpoll = p; } -unsigned pa_source_used_by(pa_source *s) { +unsigned pa_source_linked_by(pa_source *s) { pa_source_assert_ref(s); pa_assert(PA_SOURCE_LINKED(s->state)); return pa_idxset_size(s->outputs); } +unsigned pa_source_used_by(pa_source *s) { + unsigned ret; + + pa_source_assert_ref(s); + pa_assert(PA_SOURCE_LINKED(s->state)); + + ret = pa_idxset_size(s->outputs); + pa_assert(ret >= s->n_corked); + + return ret - s->n_corked; +} + int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_t offset, pa_memchunk *chunk) { pa_source *s = PA_SOURCE(object); pa_source_assert_ref(s); diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h index 0fd1486..4e488a7 100644 --- a/src/pulsecore/source.h +++ b/src/pulsecore/source.h @@ -79,6 +79,7 @@ struct pa_source { pa_channel_map channel_map; pa_idxset *outputs; + unsigned n_corked; pa_sink *monitor_of; /* may be NULL */ pa_cvolume volume; @@ -162,7 +163,8 @@ const pa_cvolume *pa_source_get_volume(pa_source *source); void pa_source_set_mute(pa_source *source, int mute); int pa_source_get_mute(pa_source *source); -unsigned pa_source_used_by(pa_source *s); +unsigned pa_source_linked_by(pa_source *s); /* Number of connected streams */ +unsigned pa_source_used_by(pa_source *s); /* Number of connected streams that are not corked */ #define pa_source_get_state(s) ((pa_source_state_t) (s)->state) /* To be called exclusively by the source driver, from IO context */ -- 2.7.4