From a24d936696f47bf92da1a72c8295e5299fa32b0b Mon Sep 17 00:00:00 2001 From: Janos Kovacs Date: Sun, 12 Aug 2012 23:01:07 +0300 Subject: [PATCH] discovery: add loopback support for sinks --- murphy/classify.c | 2 +- murphy/discover.c | 40 ++++++++++++++++++++++++++++++++-------- murphy/loopback.c | 39 ++++++++++++++++++++++++++++----------- murphy/loopback.h | 1 + 4 files changed, 62 insertions(+), 20 deletions(-) diff --git a/murphy/classify.c b/murphy/classify.c index a8bb065..c18e88b 100644 --- a/murphy/classify.c +++ b/murphy/classify.c @@ -341,7 +341,7 @@ const char *pa_classify_loopback_stream(mir_node *node) pa_assert(node); - if (node->implement == mir_device && node->direction == mir_input) { + if (node->implement == mir_device) { class = node->type; if (class >= mir_device_class_begin && class < mir_device_class_end) { diff --git a/murphy/discover.c b/murphy/discover.c index b240550..14f9419 100644 --- a/murphy/discover.c +++ b/murphy/discover.c @@ -372,23 +372,28 @@ void pa_discover_port_available_changed(struct userdata *u, void pa_discover_add_sink(struct userdata *u, pa_sink *sink, pa_bool_t route) { - pa_module *module; + pa_core *core; pa_discover *discover; + pa_module *module; mir_node *node; pa_card *card; char *key; - mir_node_type type; + char kbf[256]; + char nbf[2048]; + const char *loopback_role; + pa_source *ns; mir_node data; - char buf[256]; + mir_node_type type; pa_assert(u); pa_assert(sink); + pa_assert_se((core = u->core)); pa_assert_se((discover = u->discover)); module = sink->module; if ((card = sink->card)) { - if (!(key = node_key(u, mir_output,sink,ACTIVE_PORT, buf,sizeof(buf)))) + if (!(key = node_key(u, mir_output,sink,ACTIVE_PORT, kbf,sizeof(kbf)))) return; if (!(node = pa_discover_find_node_by_key(u, key))) { if (u->state.profile) @@ -402,9 +407,22 @@ void pa_discover_add_sink(struct userdata *u, pa_sink *sink, pa_bool_t route) node->paidx = sink->index; pa_discover_add_node_to_ptr_hash(u, sink, node); - type = node->type; + if ((loopback_role = pa_classify_loopback_stream(node))) { + if (!(ns = pa_utils_get_null_source(u))) { + pa_log("Can't load loopback module: no initial null source"); + return; + } + node->loop = pa_loopback_create(u->loopback, core, node->index, + ns->index, sink->index, + loopback_role); + + mir_node_print(node, nbf, sizeof(nbf)); + pa_log_debug("updated node:\n%s", nbf); + } if (route) { + type = node->type; + if (type != mir_bluetooth_a2dp && type != mir_bluetooth_sco) mir_router_make_routing(u); else { @@ -754,10 +772,16 @@ void pa_discover_add_sink_input(struct userdata *u, pa_sink_input *sinp) pa_log_debug("New stream is a combine stream. Nothing to do ..."); return; } else if (!strncmp(media, loopback_pattern, sizeof(loopback_pattern)-1)) { - pa_log_debug("New stream is a loopback stream"); + pa_log_debug("New stream is a loopback output stream"); - if ((node = pa_utils_get_node_from_stream(u, sinp))) - pa_log_debug("loopback stream node '%s' found", node->amname); + if ((node = pa_utils_get_node_from_stream(u, sinp))) { + if (node->direction == mir_input) + pa_log_debug("loopback stream node '%s' found", node->amname); + else { + pa_log_debug("ignoring it"); + return; + } + } else { pa_log_debug("can't find node for the loopback stream"); return; diff --git a/murphy/loopback.c b/murphy/loopback.c index de5275e..bea6573 100644 --- a/murphy/loopback.c +++ b/murphy/loopback.c @@ -64,13 +64,14 @@ pa_loopnode *pa_loopback_create(pa_loopback *loopback, { static char *modnam = "module-loopback"; - pa_loopnode *loop; - pa_source *source; - pa_sink *sink; - pa_module *module; - pa_sink_input *sink_input; - char args[512]; - uint32_t idx; + pa_loopnode *loop; + pa_source *source; + pa_sink *sink; + pa_module *module; + pa_sink_input *sink_input; + pa_source_output *source_output; + char args[512]; + uint32_t idx; pa_assert(core); @@ -89,9 +90,12 @@ pa_loopnode *pa_loopback_create(pa_loopback *loopback, media_role = "music"; snprintf(args, sizeof(args), "source=\"%s\" sink=\"%s\" " - "sink_input_properties=\"%s=%s %s=%u\"", + "sink_input_properties=\"%s=%s %s=%u\" " + "source_output_properties=\"%s=%s %s=%u\"", source->name, sink->name, PA_PROP_MEDIA_ROLE, media_role, + PA_PROP_NODE_INDEX, node_index, + PA_PROP_MEDIA_ROLE, media_role, PA_PROP_NODE_INDEX, node_index); pa_log_debug("loading %s %s", modnam, args); @@ -106,19 +110,32 @@ pa_loopnode *pa_loopback_create(pa_loopback *loopback, break; } - if (!sink_input) { - pa_log("can't find output stream of loopback module (index %u)", - module->index); + PA_IDXSET_FOREACH(source_output, core->source_outputs, idx) { + if (source_output->module == module) + break; + } + + if (!sink_input || !source_output) { + if (!sink_input) { + pa_log("can't find output stream of loopback module (index %u)", + module->index); + } + if (!source_output) { + pa_log("can't find input stream of loopback module (index %u)", + module->index); + } pa_module_unload(core, module, FALSE); return NULL; } pa_assert(sink_input->index != PA_IDXSET_INVALID); + pa_assert(source_output->index != PA_IDXSET_INVALID); loop = pa_xnew0(pa_loopnode, 1); loop->module_index = module->index; loop->node_index = node_index; loop->sink_input_index = sink_input->index; + loop->source_output_index = source_output->index; PA_LLIST_PREPEND(pa_loopnode, loopback->loopnodes, loop); diff --git a/murphy/loopback.h b/murphy/loopback.h index 6d09838..f201756 100644 --- a/murphy/loopback.h +++ b/murphy/loopback.h @@ -37,6 +37,7 @@ struct pa_loopnode { uint32_t module_index; uint32_t node_index; uint32_t sink_input_index; + uint32_t source_output_index; }; pa_loopback *pa_loopback_init(void); -- 2.7.4