From 640d317df93f205d5830b9f7b106233ddb6d2f9e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 23 Jan 2009 22:40:02 +0100 Subject: add functions to move all inputs of a sink away/similar for source outputs --- src/pulsecore/sink.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/pulsecore/sink.h | 6 ++++++ src/pulsecore/source.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/pulsecore/source.h | 6 ++++++ 4 files changed, 116 insertions(+) diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index df46a2c4..083dbaae 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -474,6 +474,58 @@ int pa_sink_suspend(pa_sink *s, pa_bool_t suspend) { return sink_set_state(s, pa_sink_used_by(s) ? PA_SINK_RUNNING : PA_SINK_IDLE); } +/* Called from main context */ +pa_queue *pa_sink_move_all_start(pa_sink *s) { + pa_queue *q; + pa_sink_input *i, *n; + uint32_t idx; + + pa_sink_assert_ref(s); + pa_assert(PA_SINK_IS_LINKED(s->state)); + + q = pa_queue_new(); + + for (i = PA_SINK_INPUT(pa_idxset_first(s->inputs, &idx)); i; i = n) { + n = PA_SINK_INPUT(pa_idxset_next(s->inputs, &idx)); + + if (pa_sink_input_start_move(i) >= 0) + pa_queue_push(q, pa_sink_input_ref(i)); + } + + return q; +} + +/* Called from main context */ +void pa_sink_move_all_finish(pa_sink *s, pa_queue *q) { + pa_sink_input *i; + + pa_sink_assert_ref(s); + pa_assert(PA_SINK_IS_LINKED(s->state)); + pa_assert(q); + + while ((i = PA_SINK_INPUT(pa_queue_pop(q)))) { + if (pa_sink_input_finish_move(i, s) < 0) + pa_sink_input_unlink(i); + + pa_sink_input_unref(i); + } + + pa_queue_free(q, NULL, NULL); +} + +/* Called from main context */ +void pa_sink_move_all_fail(pa_queue *q) { + pa_sink_input *i; + pa_assert(q); + + while ((i = PA_SINK_INPUT(pa_queue_pop(q)))) { + pa_sink_input_unlink(i); + pa_sink_input_unref(i); + } + + pa_queue_free(q, NULL, NULL); +} + /* Called from IO thread context */ void pa_sink_process_rewind(pa_sink *s, size_t nbytes) { pa_sink_input *i; diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index 89ed6d4d..a30245d9 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -40,6 +40,7 @@ typedef struct pa_sink pa_sink; #include #include #include +#include #define PA_MAX_INPUTS_PER_SINK 32 @@ -254,6 +255,11 @@ unsigned pa_sink_used_by(pa_sink *s); /* Number of connected streams which are n unsigned pa_sink_check_suspend(pa_sink *s); /* Returns how many streams are active that don't allow suspensions */ #define pa_sink_get_state(s) ((s)->state) +/* Moves all inputs away, and stores them in pa_queue */ +pa_queue *pa_sink_move_all_start(pa_sink *s); +void pa_sink_move_all_finish(pa_sink *s, pa_queue *q); +void pa_sink_move_all_fail(pa_queue *q); + /* To be called exclusively by the sink driver, from IO context */ void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result); diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index fea66b7e..3cddd099 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -412,6 +412,58 @@ int pa_source_suspend(pa_source *s, pa_bool_t suspend) { return source_set_state(s, pa_source_used_by(s) ? PA_SOURCE_RUNNING : PA_SOURCE_IDLE); } +/* Called from main context */ +pa_queue *pa_source_move_all_start(pa_source *s) { + pa_queue *q; + pa_source_output *o, *n; + uint32_t idx; + + pa_source_assert_ref(s); + pa_assert(PA_SOURCE_IS_LINKED(s->state)); + + q = pa_queue_new(); + + for (o = PA_SOURCE_OUTPUT(pa_idxset_first(s->outputs, &idx)); o; o = n) { + n = PA_SOURCE_OUTPUT(pa_idxset_next(s->outputs, &idx)); + + if (pa_source_output_start_move(o) >= 0) + pa_queue_push(q, pa_source_output_ref(o)); + } + + return q; +} + +/* Called from main context */ +void pa_source_move_all_finish(pa_source *s, pa_queue *q) { + pa_source_output *o; + + pa_source_assert_ref(s); + pa_assert(PA_SOURCE_IS_LINKED(s->state)); + pa_assert(q); + + while ((o = PA_SOURCE_OUTPUT(pa_queue_pop(q)))) { + if (pa_source_output_finish_move(o, s) < 0) + pa_source_output_unlink(o); + + pa_source_output_unref(o); + } + + pa_queue_free(q, NULL, NULL); +} + +/* Called from main context */ +void pa_source_move_all_fail(pa_queue *q) { + pa_source_output *o; + pa_assert(q); + + while ((o = PA_SOURCE_OUTPUT(pa_queue_pop(q)))) { + pa_source_output_unlink(o); + pa_source_output_unref(o); + } + + pa_queue_free(q, NULL, NULL); +} + /* Called from IO thread context */ void pa_source_process_rewind(pa_source *s, size_t nbytes) { pa_source_output *o; diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h index 336599d6..479cade2 100644 --- a/src/pulsecore/source.h +++ b/src/pulsecore/source.h @@ -42,6 +42,7 @@ typedef struct pa_source pa_source; #include #include #include +#include #define PA_MAX_OUTPUTS_PER_SOURCE 32 @@ -233,6 +234,11 @@ unsigned pa_source_used_by(pa_source *s); /* Number of connected streams that ar unsigned pa_source_check_suspend(pa_source *s); /* Returns how many streams are active that don't allow suspensions */ #define pa_source_get_state(s) ((pa_source_state_t) (s)->state) +/* Moves all inputs away, and stores them in pa_queue */ +pa_queue *pa_source_move_all_start(pa_source *s); +void pa_source_move_all_finish(pa_source *s, pa_queue *q); +void pa_source_move_all_fail(pa_queue *q); + /* To be called exclusively by the source driver, from IO context */ void pa_source_post(pa_source*s, const pa_memchunk *chunk); -- cgit