The experimental router will be used as a tool for exercising new routing functionality in the core. Another goal is to evolve the module into a Murphy module - it's expected that the module will gain features that are only used in the Murphy module. A rename to module-murphy should happen at some point. I don't want to use the name module-murphy at this early stage, because I want to avoid the confusion that would arise from having module-murphy in upstream, while Tizen continues to use a different Murphy module. Once Tizen starts to use the upstream module, that might be the right time to do the renaming, but let's worry about that later. This first version just routes streams to the default sink/source when the streams are created. --- src/Makefile.am | 8 ++ src/modules/module-experimental-router.c | 128 +++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 src/modules/module-experimental-router.c diff --git a/src/Makefile.am b/src/Makefile.am index 4e71af8..3a25049 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1075,6 +1075,7 @@ endif modlibexec_LTLIBRARIES += \ module-cli.la \ module-cli-protocol-tcp.la \ + module-experimental-router.la \ module-simple-protocol-tcp.la \ module-null-sink.la \ module-null-source.la \ @@ -1358,6 +1359,7 @@ SYMDEF_FILES = \ module-cli-symdef.h \ module-cli-protocol-tcp-symdef.h \ module-cli-protocol-unix-symdef.h \ + module-experimental-router-symdef.h \ module-pipe-sink-symdef.h \ module-pipe-source-symdef.h \ module-simple-protocol-tcp-symdef.h \ @@ -1916,6 +1918,12 @@ module_intended_roles_la_LDFLAGS = $(MODULE_LDFLAGS) module_intended_roles_la_LIBADD = $(MODULE_LIBADD) module_intended_roles_la_CFLAGS = $(AM_CFLAGS) +# An experimental router module +module_experimental_router_la_SOURCES = modules/module-experimental-router.c +module_experimental_router_la_LDFLAGS = $(MODULE_LDFLAGS) +module_experimental_router_la_LIBADD = $(MODULE_LIBADD) +module_experimental_router_la_CFLAGS = $(AM_CFLAGS) + # Suspend-on-idle module module_suspend_on_idle_la_SOURCES = modules/module-suspend-on-idle.c module_suspend_on_idle_la_LDFLAGS = $(MODULE_LDFLAGS) diff --git a/src/modules/module-experimental-router.c b/src/modules/module-experimental-router.c new file mode 100644 index 0000000..ac5f46e --- /dev/null +++ b/src/modules/module-experimental-router.c @@ -0,0 +1,128 @@ +/*** + This file is part of PulseAudio. + + Copyright 2013 Intel Corporation + + 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. +***/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "module-experimental-router-symdef.h" + +#include <pulsecore/i18n.h> +#include <pulsecore/module.h> +#include <pulsecore/namereg.h> +#include <pulsecore/router.h> + +PA_MODULE_AUTHOR("Tanu Kaskinen"); +PA_MODULE_DESCRIPTION(_("An experimental router module")); +PA_MODULE_VERSION(PACKAGE_VERSION); +PA_MODULE_LOAD_ONCE(true); + +struct userdata { + pa_router *router; +}; + +static void router_add_node_cb(pa_router *router, pa_node *node) { + int r; + + pa_assert(router); + pa_assert(node); + + if (node->type != PA_NODE_TYPE_SINK_INPUT && node->type != PA_NODE_TYPE_SOURCE_OUTPUT) + return; + + if (node->type == PA_NODE_TYPE_SINK_INPUT) { + pa_sink_input *sink_input = node->owner; + pa_sink *default_sink; + + pa_assert(sink_input->state == PA_SINK_INPUT_INIT); + + if (sink_input->sink) + return; + + default_sink = pa_namereg_get_default_sink(router->core); + + if (!default_sink) + return; + + r = pa_sink_input_set_initial_sink(sink_input, default_sink); + } else { + pa_source_output *source_output = node->owner; + pa_source *default_source; + + pa_assert(source_output->state == PA_SOURCE_OUTPUT_INIT); + + if (source_output->source) + return; + + default_source = pa_namereg_get_default_source(router->core); + + if (!default_source) + return; + + r = pa_source_output_set_initial_source(source_output, default_source); + } + + if (r >= 0) + pa_log_debug("Successfully routed node %s.", node->name); + else + pa_log_debug("Failed to route node %s.", node->name); +} + +int pa__init(pa_module *module) { + struct userdata *u; + int r; + + pa_assert(module); + + module->userdata = u = pa_xnew0(struct userdata, 1); + u->router = pa_router_new(module->core); + + if (!u->router) + goto fail; + + u->router->add_node = router_add_node_cb; + + r = pa_router_put(u->router); + + if (r < 0) + goto fail; + + return 0; + +fail: + pa__done(module); + + return -1; +} + +void pa__done(pa_module *module) { + struct userdata *u; + + pa_assert(module); + + if (!(u = module->userdata)) + return; + + if (u->router) + pa_router_free(u->router); + + pa_xfree(u); +} -- 1.8.3.1