From 233ef98bf19ab311c1cb19867b1e8bcb4c36f66d Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Mon, 2 May 2011 10:08:27 +0530 Subject: filter-apply: Mark modules as being autoloaded (Based on Colin's review) We mark modules as being autoloaded so that they can handle this as a special case if needed (which is required by module-echo-cancel for now). This inverts how things were done and makes using these modules manually less error-prone. --- src/modules/echo-cancel/module-echo-cancel.c | 18 +++++++++--------- src/modules/module-equalizer-sink.c | 13 ++++++++++++- src/modules/module-filter-apply.c | 2 +- src/modules/module-virtual-sink.c | 3 +++ src/modules/module-virtual-source.c | 3 +++ 5 files changed, 28 insertions(+), 11 deletions(-) (limited to 'src/modules') diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c index 746028bb..37879629 100644 --- a/src/modules/echo-cancel/module-echo-cancel.c +++ b/src/modules/echo-cancel/module-echo-cancel.c @@ -78,7 +78,7 @@ PA_MODULE_USAGE( "aec_method= " "aec_args= " "save_aec= " - "manual_load= " + "autoloaded= " )); /* NOTE: Make sure the enum and ec_table are maintained in the correct order */ @@ -107,7 +107,7 @@ static const pa_echo_canceller ec_table[] = { #define DEFAULT_ADJUST_TIME_USEC (1*PA_USEC_PER_SEC) #define DEFAULT_SAVE_AEC 0 -#define DEFAULT_MANUAL_LOAD FALSE +#define DEFAULT_AUTOLOADED FALSE #define MEMBLOCKQ_MAXLENGTH (16*1024*1024) @@ -158,7 +158,7 @@ struct userdata { pa_core *core; pa_module *module; - pa_bool_t manual_load; + pa_bool_t autoloaded; uint32_t save_aec; pa_echo_canceller *ec; @@ -213,7 +213,7 @@ static const char* const valid_modargs[] = { "aec_method", "aec_args", "save_aec", - "manual_load", + "autoloaded", NULL }; @@ -1398,9 +1398,9 @@ int pa__init(pa_module*m) { goto fail; } - u->manual_load = DEFAULT_MANUAL_LOAD; - if (pa_modargs_get_value_boolean(ma, "manual_load", &u->manual_load) < 0) { - pa_log("Failed to parse manual_load value"); + u->autoloaded = DEFAULT_AUTOLOADED; + if (pa_modargs_get_value_boolean(ma, "autoloaded", &u->autoloaded) < 0) { + pa_log("Failed to parse autoloaded value"); goto fail; } @@ -1423,7 +1423,7 @@ int pa__init(pa_module*m) { pa_source_new_data_set_channel_map(&source_data, &source_map); pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, source_master->name); pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_CLASS, "filter"); - if (u->manual_load) + if (!u->autoloaded) pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone"); pa_proplist_sets(source_data.proplist, "device.echo-cancel.name", source_data.name); @@ -1471,7 +1471,7 @@ int pa__init(pa_module*m) { pa_sink_new_data_set_channel_map(&sink_data, &sink_map); pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, sink_master->name); pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_CLASS, "filter"); - if (u->manual_load) + if (!u->autoloaded) pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone"); pa_proplist_sets(sink_data.proplist, "device.echo-cancel.name", sink_data.name); diff --git a/src/modules/module-equalizer-sink.c b/src/modules/module-equalizer-sink.c index 0bbb23a8..9a85fe59 100644 --- a/src/modules/module-equalizer-sink.c +++ b/src/modules/module-equalizer-sink.c @@ -83,14 +83,18 @@ PA_MODULE_USAGE( "format= " "rate= " "channels= " - "channel_map=")); + "channel_map= " + "autoloaded= " + )); #define MEMBLOCKQ_MAXLENGTH (16*1024*1024) +#define DEFAULT_AUTOLOADED FALSE struct userdata { pa_module *module; pa_sink *sink; pa_sink_input *sink_input; + pa_bool_t autoloaded; size_t channels; size_t fft_size;//length (res) of fft @@ -138,6 +142,7 @@ static const char* const valid_modargs[] = { "rate", "channels", "channel_map", + "autoloaded", NULL }; @@ -1170,6 +1175,12 @@ int pa__init(pa_module*m) { goto fail; } + u->autoloaded = DEFAULT_AUTOLOADED; + if (pa_modargs_get_value_boolean(ma, "autoloaded", &u->autoloaded) < 0) { + pa_log("Failed to parse autoloaded value"); + goto fail; + } + u->sink = pa_sink_new(m->core, &sink_data, PA_SINK_HW_MUTE_CTRL|PA_SINK_HW_VOLUME_CTRL|PA_SINK_DECIBEL_VOLUME| (master->flags & (PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY))); diff --git a/src/modules/module-filter-apply.c b/src/modules/module-filter-apply.c index 79558f2e..e9c9f65b 100644 --- a/src/modules/module-filter-apply.c +++ b/src/modules/module-filter-apply.c @@ -314,7 +314,7 @@ static pa_hook_result_t process(struct userdata *u, pa_object *o, pa_bool_t is_s char *args; pa_module *m; - args = pa_sprintf_malloc("%s_master=%s", is_sink_input ? "sink" : "source", parent_name); + args = pa_sprintf_malloc("autoloaded=1 %s_master=%s", is_sink_input ? "sink" : "source", parent_name); pa_log_debug("Loading %s with arguments '%s'", module_name, args); if ((m = pa_module_load(u->core, module_name, args))) { diff --git a/src/modules/module-virtual-sink.c b/src/modules/module-virtual-sink.c index f7723148..9bcff8c3 100644 --- a/src/modules/module-virtual-sink.c +++ b/src/modules/module-virtual-sink.c @@ -66,6 +66,9 @@ PA_MODULE_USAGE( struct userdata { pa_module *module; + /* FIXME: Uncomment this and take "autoloaded" as a modarg if this is a filter */ + /* pa_bool_t autoloaded; */ + pa_sink *sink; pa_sink_input *sink_input; diff --git a/src/modules/module-virtual-source.c b/src/modules/module-virtual-source.c index b8f2ab06..835cf3ce 100644 --- a/src/modules/module-virtual-source.c +++ b/src/modules/module-virtual-source.c @@ -69,6 +69,9 @@ PA_MODULE_USAGE( struct userdata { pa_module *module; + /* FIXME: Uncomment this and take "autoloaded" as a modarg if this is a filter */ + /* pa_bool_t autoloaded; */ + pa_source *source; pa_source_output *source_output; -- cgit From 0ac2cfce6d1a3d7ab5af6aca659e46625c32d3c4 Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Mon, 28 Feb 2011 13:23:23 +0530 Subject: core: Add extended stream API to support compressed formats This is the beginning of work to support compressed formats natively in PulseAudio. This adds a pa_stream_new_extended() that takes a format structure, sends it to the server (=> protocol extension) and has the server negotiate with the appropropriate sink to figure out what format it should use. This is work in progress, and works only with PCM streams. Actual compressed format support in some sink needs to be implemented, and extensive testing is required. More details on how this is supposed to work is available at: http://pulseaudio.org/wiki/PassthroughSupport --- src/modules/echo-cancel/module-echo-cancel.c | 2 +- src/modules/module-combine-sink.c | 2 +- src/modules/module-device-manager.c | 4 ++-- src/modules/module-equalizer-sink.c | 2 +- src/modules/module-intended-roles.c | 10 ++-------- src/modules/module-ladspa-sink.c | 2 +- src/modules/module-loopback.c | 2 +- src/modules/module-remap-sink.c | 2 +- src/modules/module-sine.c | 2 +- src/modules/module-stream-restore.c | 8 +++----- src/modules/module-virtual-sink.c | 2 +- src/modules/rtp/module-rtp-recv.c | 2 +- 12 files changed, 16 insertions(+), 24 deletions(-) (limited to 'src/modules') diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c index 37879629..a06e481d 100644 --- a/src/modules/echo-cancel/module-echo-cancel.c +++ b/src/modules/echo-cancel/module-echo-cancel.c @@ -1549,7 +1549,7 @@ int pa__init(pa_module*m) { pa_sink_input_new_data_init(&sink_input_data); sink_input_data.driver = __FILE__; sink_input_data.module = m; - sink_input_data.sink = sink_master; + pa_sink_input_new_data_set_sink(&sink_input_data, sink_master, FALSE); sink_input_data.origin_sink = u->sink; pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Echo-Cancel Sink Stream"); pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter"); diff --git a/src/modules/module-combine-sink.c b/src/modules/module-combine-sink.c index 09af942d..f6d64531 100644 --- a/src/modules/module-combine-sink.c +++ b/src/modules/module-combine-sink.c @@ -845,7 +845,7 @@ static int output_create_sink_input(struct output *o) { return 0; pa_sink_input_new_data_init(&data); - data.sink = o->sink; + pa_sink_input_new_data_set_sink(&data, o->sink, FALSE); data.driver = __FILE__; pa_proplist_setf(data.proplist, PA_PROP_MEDIA_NAME, "Simultaneous output on %s", pa_strnull(pa_proplist_gets(o->sink->proplist, PA_PROP_DEVICE_DESCRIPTION))); pa_proplist_sets(data.proplist, PA_PROP_MEDIA_ROLE, "filter"); diff --git a/src/modules/module-device-manager.c b/src/modules/module-device-manager.c index 47469b06..c28affd1 100644 --- a/src/modules/module-device-manager.c +++ b/src/modules/module-device-manager.c @@ -832,8 +832,8 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n pa_sink *sink; if ((sink = pa_idxset_get_by_index(u->core->sinks, device_index))) { - new_data->sink = sink; - new_data->save_sink = FALSE; + if (!pa_sink_input_new_data_set_sink(new_data, sink, FALSE)) + pa_log_debug("Not restoring device for stream because no supported format was found"); } } } diff --git a/src/modules/module-equalizer-sink.c b/src/modules/module-equalizer-sink.c index 9a85fe59..e20ee4ab 100644 --- a/src/modules/module-equalizer-sink.c +++ b/src/modules/module-equalizer-sink.c @@ -1212,7 +1212,7 @@ int pa__init(pa_module*m) { pa_sink_input_new_data_init(&sink_input_data); sink_input_data.driver = __FILE__; sink_input_data.module = m; - sink_input_data.sink = master; + pa_sink_input_new_data_set_sink(&sink_input_data, master, FALSE); sink_input_data.origin_sink = u->sink; pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Equalized Stream"); pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter"); diff --git a/src/modules/module-intended-roles.c b/src/modules/module-intended-roles.c index d19444d2..90385622 100644 --- a/src/modules/module-intended-roles.c +++ b/src/modules/module-intended-roles.c @@ -117,11 +117,8 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n /* Prefer the default sink over any other sink, just in case... */ if ((def = pa_namereg_get_default_sink(c))) - if (role_match(def->proplist, role)) { - new_data->sink = def; - new_data->save_sink = FALSE; + if (role_match(def->proplist, role) && pa_sink_input_new_data_set_sink(new_data, def, FALSE)) return PA_HOOK_OK; - } /* @todo: favour the highest priority device, not the first one we find? */ PA_IDXSET_FOREACH(s, c->sinks, idx) { @@ -131,11 +128,8 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n if (!PA_SINK_IS_LINKED(pa_sink_get_state(s))) continue; - if (role_match(s->proplist, role)) { - new_data->sink = s; - new_data->save_sink = FALSE; + if (role_match(s->proplist, role) && pa_sink_input_new_data_set_sink(new_data, s, FALSE)) return PA_HOOK_OK; - } } return PA_HOOK_OK; diff --git a/src/modules/module-ladspa-sink.c b/src/modules/module-ladspa-sink.c index f6430f29..6489f3f7 100644 --- a/src/modules/module-ladspa-sink.c +++ b/src/modules/module-ladspa-sink.c @@ -907,7 +907,7 @@ int pa__init(pa_module*m) { pa_sink_input_new_data_init(&sink_input_data); sink_input_data.driver = __FILE__; sink_input_data.module = m; - sink_input_data.sink = master; + pa_sink_input_new_data_set_sink(&sink_input_data, master, FALSE); sink_input_data.origin_sink = u->sink; pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "LADSPA Stream"); pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter"); diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c index 9a8640b1..ca813b00 100644 --- a/src/modules/module-loopback.c +++ b/src/modules/module-loopback.c @@ -695,7 +695,7 @@ int pa__init(pa_module *m) { pa_sink_input_new_data_init(&sink_input_data); sink_input_data.driver = __FILE__; sink_input_data.module = m; - sink_input_data.sink = sink; + pa_sink_input_new_data_set_sink(&sink_input_data, sink, FALSE); if ((n = pa_modargs_get_value(ma, "sink_input_name", NULL))) pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, n); diff --git a/src/modules/module-remap-sink.c b/src/modules/module-remap-sink.c index 7f64f306..79627f7a 100644 --- a/src/modules/module-remap-sink.c +++ b/src/modules/module-remap-sink.c @@ -419,7 +419,7 @@ int pa__init(pa_module*m) { pa_sink_input_new_data_init(&sink_input_data); sink_input_data.driver = __FILE__; sink_input_data.module = m; - sink_input_data.sink = master; + pa_sink_input_new_data_set_sink(&sink_input_data, master, FALSE); sink_input_data.origin_sink = u->sink; pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Remapped Stream"); pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter"); diff --git a/src/modules/module-sine.c b/src/modules/module-sine.c index 69b20028..cee01f1a 100644 --- a/src/modules/module-sine.c +++ b/src/modules/module-sine.c @@ -157,7 +157,7 @@ int pa__init(pa_module*m) { pa_sink_input_new_data_init(&data); data.driver = __FILE__; data.module = m; - data.sink = sink; + pa_sink_input_new_data_set_sink(&data, sink, FALSE); pa_proplist_setf(data.proplist, PA_PROP_MEDIA_NAME, "%u Hz Sine", frequency); pa_proplist_sets(data.proplist, PA_PROP_MEDIA_ROLE, "abstract"); pa_proplist_setf(data.proplist, "sine.hz", "%u", frequency); diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c index 77b6949d..fa2c0210 100644 --- a/src/modules/module-stream-restore.c +++ b/src/modules/module-stream-restore.c @@ -1301,11 +1301,9 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n /* It might happen that a stream and a sink are set up at the same time, in which case we want to make sure we don't interfere with that */ - if (s && PA_SINK_IS_LINKED(pa_sink_get_state(s))) { - pa_log_info("Restoring device for stream %s.", name); - new_data->sink = s; - new_data->save_sink = TRUE; - } + if (s && PA_SINK_IS_LINKED(pa_sink_get_state(s))) + if (pa_sink_input_new_data_set_sink(new_data, s, TRUE)) + pa_log_info("Restoring device for stream %s.", name); pa_xfree(e); } diff --git a/src/modules/module-virtual-sink.c b/src/modules/module-virtual-sink.c index 9bcff8c3..fe269304 100644 --- a/src/modules/module-virtual-sink.c +++ b/src/modules/module-virtual-sink.c @@ -579,7 +579,7 @@ int pa__init(pa_module*m) { pa_sink_input_new_data_init(&sink_input_data); sink_input_data.driver = __FILE__; sink_input_data.module = m; - sink_input_data.sink = master; + pa_sink_input_new_data_set_sink(&sink_input_data, master, FALSE); sink_input_data.origin_sink = u->sink; pa_proplist_setf(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Virtual Sink Stream from %s", pa_proplist_gets(u->sink->proplist, PA_PROP_DEVICE_DESCRIPTION)); pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter"); diff --git a/src/modules/rtp/module-rtp-recv.c b/src/modules/rtp/module-rtp-recv.c index 1144169b..fb3bccb4 100644 --- a/src/modules/rtp/module-rtp-recv.c +++ b/src/modules/rtp/module-rtp-recv.c @@ -512,7 +512,7 @@ static struct session *session_new(struct userdata *u, const pa_sdp_info *sdp_in goto fail; pa_sink_input_new_data_init(&data); - data.sink = sink; + pa_sink_input_new_data_set_sink(&data, sink, FALSE); data.driver = __FILE__; pa_proplist_sets(data.proplist, PA_PROP_MEDIA_ROLE, "stream"); pa_proplist_setf(data.proplist, PA_PROP_MEDIA_NAME, -- 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/modules/alsa/alsa-sink.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'src/modules') diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index ccbc0628..ec840afd 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -1707,13 +1707,6 @@ static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB, pa_bool_t sync_v return 0; } - /* FIXME: need automatic detection rather than hard-coded path */ - if (!strcmp(u->mixer_path->name, "iec958-passthrough-output")) { - u->sink->flags |= PA_SINK_PASSTHROUGH; - } else { - u->sink->flags &= ~PA_SINK_PASSTHROUGH; - } - if (!u->mixer_path->has_volume) pa_log_info("Driver does not support hardware volume control, falling back to software volume control."); else { -- cgit From 20f1fa17bebe086cb9cff09a5157dc7ca009ba61 Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Thu, 3 Mar 2011 12:52:21 +0530 Subject: alsa-mixer: Remove passthrough profiles These aren't used any more - we handle passthrough mode in the iec958* profiles now. --- .../alsa/mixer/paths/iec958-passthrough-output.conf | 19 ------------------- src/modules/alsa/mixer/profile-sets/default.conf | 7 ------- 2 files changed, 26 deletions(-) delete mode 100644 src/modules/alsa/mixer/paths/iec958-passthrough-output.conf (limited to 'src/modules') diff --git a/src/modules/alsa/mixer/paths/iec958-passthrough-output.conf b/src/modules/alsa/mixer/paths/iec958-passthrough-output.conf deleted file mode 100644 index 8506a580..00000000 --- a/src/modules/alsa/mixer/paths/iec958-passthrough-output.conf +++ /dev/null @@ -1,19 +0,0 @@ -# This file is part of PulseAudio. -# -# PulseAudio is free software; you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as -# published by the Free Software Foundation; either version 2.1 of the -# License, or (at your option) any later version. -# -# PulseAudio is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with PulseAudio; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - - -[Element IEC958] -switch = mute diff --git a/src/modules/alsa/mixer/profile-sets/default.conf b/src/modules/alsa/mixer/profile-sets/default.conf index 9f7b5f2b..283edfb3 100644 --- a/src/modules/alsa/mixer/profile-sets/default.conf +++ b/src/modules/alsa/mixer/profile-sets/default.conf @@ -155,13 +155,6 @@ paths-input = iec958-stereo-input paths-output = iec958-stereo-output priority = 5 -[Mapping iec958-passthrough] -device-strings = iec958:%f -channel-map = left,right -direction = output -paths-output = iec958-passthrough-output -priority = 5 - [Mapping iec958-ac3-surround-40] device-strings = a52:%f channel-map = front-left,front-right,rear-left,rear-right -- cgit From 49b10ba6941ea61e551ccee482b12bb78db8a4b3 Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Tue, 8 Mar 2011 14:22:24 +0530 Subject: alsa: Reconfigure sink sample rate for passthrough inputs When a passthrough sink-input is added, we need to reconfigure the sink's sample rate since no resampling occurs. We revert to the original rate when the passthrough sink-input is removed. --- src/modules/alsa/alsa-sink.c | 52 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'src/modules') diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index ec840afd..3f8f6d20 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -108,6 +108,8 @@ struct userdata { pa_cvolume hardware_volume; + uint32_t old_rate; + size_t frame_size, fragment_size, @@ -1051,6 +1053,56 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse switch (code) { + case PA_SINK_MESSAGE_FINISH_MOVE: + case PA_SINK_MESSAGE_ADD_INPUT: { + pa_sink_input *i = PA_SINK_INPUT(data); + int r = 0; + + if (PA_LIKELY(pa_format_info_is_pcm(i->format))) + break; + + u->old_rate = u->sink->sample_spec.rate; + + /* Passthrough format, see if we need to reset sink sample rate */ + if (u->sink->sample_spec.rate == i->thread_info.sample_spec.rate) + break; + + /* .. we do */ + if ((r = suspend(u)) < 0) + return r; + + u->sink->sample_spec.rate = i->thread_info.sample_spec.rate; + + if ((r = unsuspend(u)) < 0) + return r; + + break; + } + + case PA_SINK_MESSAGE_START_MOVE: + case PA_SINK_MESSAGE_REMOVE_INPUT: { + pa_sink_input *i = PA_SINK_INPUT(data); + int r = 0; + + if (PA_LIKELY(pa_format_info_is_pcm(i->format))) + break; + + /* Passthrough format, see if we need to reset sink sample rate */ + if (u->sink->sample_spec.rate == u->old_rate) + break; + + /* .. we do */ + if ((r = suspend(u)) < 0) + return r; + + u->sink->sample_spec.rate = u->old_rate; + + if ((r = unsuspend(u)) < 0) + return r; + + break; + } + case PA_SINK_MESSAGE_GET_LATENCY: { pa_usec_t r = 0; -- 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/modules/alsa/alsa-sink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/modules') diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index 3f8f6d20..b98340b7 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -1058,7 +1058,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse pa_sink_input *i = PA_SINK_INPUT(data); int r = 0; - if (PA_LIKELY(pa_format_info_is_pcm(i->format))) + if (PA_LIKELY(!pa_sink_input_is_passthrough(i))) break; u->old_rate = u->sink->sample_spec.rate; @@ -1084,7 +1084,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse pa_sink_input *i = PA_SINK_INPUT(data); int r = 0; - if (PA_LIKELY(pa_format_info_is_pcm(i->format))) + if (PA_LIKELY(!pa_sink_input_is_passthrough(i))) break; /* Passthrough format, see if we need to reset sink sample rate */ -- cgit From 7ebc5033637d7f0ca8ece80259d8a5dc6b30557b Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Sun, 15 May 2011 09:54:17 +0530 Subject: module-tunnel: Update for recent protocol changes This updates the tunnel module for protocol version >= 19. module-tunnel-sink does not proxy server-side passthrough support (yet). This would require a few more changes, namely keeping track of what formats are available and if any other sink inputs are connected on the server-side. --- src/modules/module-tunnel.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'src/modules') diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c index 6cb22e03..1b2d3a1a 100644 --- a/src/modules/module-tunnel.c +++ b/src/modules/module-tunnel.c @@ -1095,6 +1095,23 @@ static void sink_info_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_t } } + if (u->version >= 21) { + uint8_t n_formats; + pa_format_info format; + + if (pa_tagstruct_getu8(t, &n_formats) < 0) { /* no. of formats */ + pa_log("Parse failure"); + goto fail; + } + + for (uint8_t j = 0; j < n_formats; j++) { + if (pa_tagstruct_get_format_info(t, &format)) { /* format info */ + pa_log("Parse failure"); + goto fail; + } + } + } + if (!pa_tagstruct_eof(t)) { pa_log("Packet too long"); goto fail; @@ -1128,6 +1145,7 @@ static void sink_input_info_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag pa_channel_map channel_map; pa_cvolume volume; pa_proplist *pl; + pa_bool_t b; pa_assert(pd); pa_assert(u); @@ -1175,6 +1193,33 @@ static void sink_input_info_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag } } + if (u->version >= 19) { + if (pa_tagstruct_get_boolean(t, &b) < 0) { + + pa_log("Parse failure"); + goto fail; + } + } + + if (u->version >= 20) { + if (pa_tagstruct_get_boolean(t, &b) < 0 || + pa_tagstruct_get_boolean(t, &b) < 0) { + + pa_log("Parse failure"); + goto fail; + } + } + + if (u->version >= 21) { + pa_format_info format; + + if (pa_tagstruct_get_format_info(t, &format) < 0) { + + pa_log("Parse failure"); + goto fail; + } + } + if (!pa_tagstruct_eof(t)) { pa_log("Packet too long"); goto fail; @@ -1491,6 +1536,13 @@ static void create_stream_callback(pa_pdispatch *pd, uint32_t command, uint32_t /* #endif */ } + if (u->version >= 21) { + pa_format_info format; + + if (pa_tagstruct_get_format_info(t, &format) < 0) + goto parse_error; + } + if (!pa_tagstruct_eof(t)) goto parse_error; @@ -1693,6 +1745,13 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t pa_tagstruct_put_boolean(reply, FALSE); /* passthrough stream */ #endif +#ifdef TUNNEL_SINK + if (u->version >= 21) { + /* We're not using the extended API, so n_formats = 0 and that's that */ + pa_tagstruct_putu8(t, 0); + } +#endif + pa_pstream_send_tagstruct(u->pstream, reply); pa_pdispatch_register_reply(u->pdispatch, tag, DEFAULT_TIMEOUT, create_stream_callback, u, NULL); -- cgit