From 47e0f91aa2ca6eb3ea8b7be8aa03cd03a28c3fbe Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Mon, 28 Feb 2011 13:00:20 +0530 Subject: sink: Extend API for compressed formats support This adds a get_formats() vfunc for sinks to provide a list of formats they can support. pa_sink_check_formats() can be used during or after routing to determine what formats from a stream the sink can support. --- src/pulsecore/sink.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'src/pulsecore/sink.c') diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 839b7d44..345d090c 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -177,6 +178,7 @@ static void reset_callbacks(pa_sink *s) { s->request_rewind = NULL; s->update_requested_latency = NULL; s->set_port = NULL; + s->get_formats = NULL; } /* Called from main context */ @@ -3258,3 +3260,52 @@ static void pa_sink_volume_change_rewind(pa_sink *s, size_t nbytes) { } pa_sink_volume_change_apply(s, NULL); } + +/* Called from the main thread */ +/* Gets the list of formats supported by the sink. The members and idxset must + * be freed by the caller. */ +pa_idxset* pa_sink_get_formats(pa_sink *s) { + pa_idxset *ret; + + pa_assert(s); + + if (s->get_formats) { + /* Sink supports format query, all is good */ + ret = s->get_formats(s); + } else { + /* Sink doesn't support format query, so assume it does PCM */ + pa_format_info *f = pa_format_info_new(); + f->encoding = PA_ENCODING_PCM; + + ret = pa_idxset_new(NULL, NULL); + pa_idxset_put(ret, f, NULL); + } + + return ret; +} + +/* Called from the main thread */ +/* Calculates the intersection between formats supported by the sink and + * in_formats, and returns these, in the order of the sink's formats. */ +pa_idxset* pa_sink_check_formats(pa_sink *s, pa_idxset *in_formats) { + pa_idxset *out_formats = pa_idxset_new(NULL, NULL), *sink_formats; + pa_format_info *f_sink, *f_in; + uint32_t i, j; + + pa_assert(s); + + if (!in_formats || pa_idxset_isempty(in_formats)) + goto done; + + sink_formats = pa_sink_get_formats(s); + + PA_IDXSET_FOREACH(f_sink, sink_formats, i) { + PA_IDXSET_FOREACH(f_in, in_formats, j) { + if (pa_format_info_is_compatible(f_sink, f_in)) + pa_idxset_put(out_formats, pa_format_info_copy(f_in), NULL); + } + } + +done: + return out_formats; +} -- cgit From 71ec9577cf052558cfddb051c7d038c91b397bc5 Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Wed, 2 Mar 2011 02:06:54 +0530 Subject: sink: Remove PASSTHROUGH flag This removes the passthrough flag from sinks since we will drop exclusively passthrough sinks in favour of providing a list of formats supported by each sink. We can still determine whether a sink is in passthrough mode by checking if any non-PCM streams are attached to it. --- src/pulsecore/sink.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'src/pulsecore/sink.c') diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 345d090c..33923e1f 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -1241,6 +1241,24 @@ pa_bool_t pa_sink_flat_volume_enabled(pa_sink *s) { return (s->flags & PA_SINK_FLAT_VOLUME); } +/* Called from main context */ +pa_bool_t pa_sink_is_passthrough(pa_sink *s) { + pa_sink_input *alt_i; + uint32_t idx; + + pa_sink_assert_ref(s); + + /* one and only one PASSTHROUGH input can possibly be connected */ + if (pa_idxset_size(s->inputs) == 1) { + alt_i = pa_idxset_first(s->inputs, &idx); + + if (!pa_format_info_is_pcm(alt_i->format)) + return TRUE; + } + + return FALSE; +} + /* Called from main context. */ static void compute_reference_ratio(pa_sink_input *i) { unsigned c = 0; @@ -1632,21 +1650,10 @@ void pa_sink_set_volume( pa_assert(!volume || volume->channels == 1 || pa_cvolume_compatible(volume, &s->sample_spec)); /* make sure we don't change the volume when a PASSTHROUGH input is connected */ - if (s->flags & PA_SINK_PASSTHROUGH) { - pa_sink_input *alt_i; - uint32_t idx; - - /* one and only one PASSTHROUGH input can possibly be connected */ - if (pa_idxset_size(s->inputs) == 1) { - - alt_i = pa_idxset_first(s->inputs, &idx); - - if (alt_i->flags & PA_SINK_INPUT_PASSTHROUGH) { - /* FIXME: Need to notify client that volume control is disabled */ - pa_log_warn("Cannot change volume, Sink is connected to PASSTHROUGH input"); - return; - } - } + if (pa_sink_is_passthrough(s)) { + /* FIXME: Need to notify client that volume control is disabled */ + pa_log_warn("Cannot change volume, Sink is connected to PASSTHROUGH input"); + return; } /* In case of volume sharing, the volume is set for the root sink first, -- cgit From 8b3e68a202084467086af6c83e89c07adb9aa18a Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Wed, 2 Mar 2011 11:16:48 +0530 Subject: sink: Fix leak in pa_sink_check_formats() We weren't freeing the sink formats idxset. --- src/pulsecore/sink.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/pulsecore/sink.c') diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 33923e1f..2b9402ab 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -3295,7 +3295,7 @@ pa_idxset* pa_sink_get_formats(pa_sink *s) { /* Calculates the intersection between formats supported by the sink and * in_formats, and returns these, in the order of the sink's formats. */ pa_idxset* pa_sink_check_formats(pa_sink *s, pa_idxset *in_formats) { - pa_idxset *out_formats = pa_idxset_new(NULL, NULL), *sink_formats; + pa_idxset *out_formats = pa_idxset_new(NULL, NULL), *sink_formats = NULL; pa_format_info *f_sink, *f_in; uint32_t i, j; @@ -3314,5 +3314,8 @@ pa_idxset* pa_sink_check_formats(pa_sink *s, pa_idxset *in_formats) { } done: + if (sink_formats) + pa_idxset_free(sink_formats, (pa_free2_cb_t) pa_format_info_free2, NULL); + return out_formats; } -- cgit From 658a9153f094db9a30ac94428f4e46985e7096eb Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Wed, 2 Mar 2011 11:38:01 +0530 Subject: sink-input: Kill passthrough streams if moving to an unsupported sink This will eventually be replaced by a hook to let clients know that the stream has moved so that they can gracefully reconnect and renegotiate a supported format. --- src/pulsecore/sink.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src/pulsecore/sink.c') diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 2b9402ab..626c7278 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -3291,6 +3291,33 @@ pa_idxset* pa_sink_get_formats(pa_sink *s) { return ret; } +/* Called from the main thread */ +/* Checks if the sink can accept this format */ +pa_bool_t pa_sink_check_format(pa_sink *s, pa_format_info *f) +{ + pa_idxset *sink_formats = NULL; + pa_format_info *f_sink; + uint32_t i; + pa_bool_t ret = FALSE; + + pa_assert(s); + pa_assert(f); + + sink_formats = pa_sink_get_formats(s); + + PA_IDXSET_FOREACH(f_sink, sink_formats, i) { + if (pa_format_info_is_compatible(f_sink, f)) { + ret = TRUE; + break; + } + } + + if (sink_formats) + pa_idxset_free(sink_formats, (pa_free2_cb_t) pa_format_info_free2, NULL); + + return ret; +} + /* Called from the main thread */ /* Calculates the intersection between formats supported by the sink and * in_formats, and returns these, in the order of the sink's formats. */ -- cgit From 4c9d53f3f50162e19ad7934e62c8f35453bdbfbc Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Thu, 3 Mar 2011 18:35:14 +0530 Subject: sink: Trivial typo fix in comment --- src/pulsecore/sink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/pulsecore/sink.c') diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 626c7278..5959a5ce 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -2153,7 +2153,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse /* If you change anything here, make sure to change the * sink input handling a few lines down at - * PA_SINK_MESSAGE_PREPAPRE_MOVE, too. */ + * PA_SINK_MESSAGE_START_MOVE, too. */ if (i->detach) i->detach(i); -- cgit From 4fb68b91acef3cb37c014814d9e9de8ca9f22bf4 Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Wed, 16 Mar 2011 16:08:23 +0530 Subject: core: Factor out passthrough checks into their own functions Since we currently have two mechanisms to signal a passthrough connection (non-PCM format or PA_SINK_INPUT_PASSTHROUGH flag), we move all the related checks into functions and use those everywhere. This makes things more consistent, and should we decide to get rid of the flag, we only need to change pa_sink_input_*_is_passthrough() accordingly. --- src/pulsecore/sink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/pulsecore/sink.c') diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 5959a5ce..bc4ddd21 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -1252,7 +1252,7 @@ pa_bool_t pa_sink_is_passthrough(pa_sink *s) { if (pa_idxset_size(s->inputs) == 1) { alt_i = pa_idxset_first(s->inputs, &idx); - if (!pa_format_info_is_pcm(alt_i->format)) + if (pa_sink_input_is_passthrough(alt_i)) return TRUE; } -- cgit