[pulseaudio-discuss] [PATCH 12/15] edge: Add support for connecting new streams
Tanu Kaskinen
tanu.kaskinen at linux.intel.com
Thu Feb 13 19:35:57 CET 2014
This allows routers to set the initial routing for new nodes without
caring about their type.
---
src/pulsecore/edge.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 171 insertions(+), 1 deletion(-)
diff --git a/src/pulsecore/edge.c b/src/pulsecore/edge.c
index 931bee1..177ae3f 100644
--- a/src/pulsecore/edge.c
+++ b/src/pulsecore/edge.c
@@ -119,7 +119,9 @@ pa_edge *pa_edge_new(pa_node *input, pa_node *output, int *ret) {
edge->output = output;
edge->string = pa_sprintf_malloc("%s -> %s", input->name, output->name);
- edge_put(edge);
+ r = edge_put(edge);
+ if (r < 0)
+ goto fail;
return edge;
@@ -133,15 +135,183 @@ fail:
return NULL;
}
+static int connect_source_to_source_output(pa_source *source, pa_source_output *output) {
+ int r;
+
+ pa_assert(source);
+ pa_assert(output);
+
+ if (output->state == PA_SOURCE_OUTPUT_INIT)
+ r = pa_source_output_set_initial_source(output, source);
+ else
+ r = -PA_ERR_NOTSUPPORTED;
+
+ return r;
+}
+
+static int connect_port_to_source_output(pa_device_port *port, pa_source_output *output) {
+ pa_assert(port);
+ pa_assert(output);
+
+ return connect_source_to_source_output(port->device, output);
+}
+
+static int connect_port_monitor_to_source_output(pa_device_port *port, pa_source_output *output) {
+ pa_assert(port);
+ pa_assert(output);
+
+ return connect_source_to_source_output(((pa_sink *) port->device)->monitor_source, output);
+}
+
+static int connect_sink_input_to_sink(pa_sink_input *input, pa_sink *sink) {
+ int r;
+
+ pa_assert(input);
+ pa_assert(sink);
+
+ if (input->state == PA_SINK_INPUT_INIT)
+ r = pa_sink_input_set_initial_sink(input, sink);
+ else
+ r = -PA_ERR_NOTSUPPORTED;
+
+ return r;
+}
+
+static int connect_sink_input_to_port(pa_sink_input *input, pa_device_port *port) {
+ pa_assert(input);
+ pa_assert(port);
+
+ return connect_sink_input_to_sink(input, port->device);
+}
+
+static int connect_sink_input_to_source_output(pa_sink_input *input, pa_source_output *output) {
+ int r;
+
+ pa_assert(input);
+ pa_assert(output);
+
+ if (output->state == PA_SOURCE_OUTPUT_INIT)
+ r = pa_source_output_set_direct_on_input(output, input);
+ else {
+ pa_log_info("Connecting a linked source output to a sink input is not supported.");
+ r = -PA_ERR_NOTSUPPORTED;
+ }
+
+ return r;
+}
+
+static int connect_nodes(pa_edge *edge) {
+ int r = 0;
+
+ pa_assert(edge);
+
+ switch (edge->input->type) {
+ case PA_NODE_TYPE_PORT:
+ switch (edge->output->type) {
+ case PA_NODE_TYPE_SOURCE_OUTPUT:
+ r = connect_port_to_source_output(edge->input->owner, edge->output->owner);
+ break;
+
+ case PA_NODE_TYPE_PORT:
+ case PA_NODE_TYPE_SINK:
+ goto not_supported;
+
+ case PA_NODE_TYPE_PORT_MONITOR:
+ case PA_NODE_TYPE_SOURCE:
+ case PA_NODE_TYPE_SINK_INPUT:
+ pa_assert_not_reached();
+ }
+ break;
+
+ case PA_NODE_TYPE_PORT_MONITOR:
+ switch (edge->output->type) {
+ case PA_NODE_TYPE_SOURCE_OUTPUT:
+ r = connect_port_monitor_to_source_output(edge->input->owner, edge->output->owner);
+ break;
+
+ case PA_NODE_TYPE_PORT:
+ case PA_NODE_TYPE_SINK:
+ goto not_supported;
+
+ case PA_NODE_TYPE_PORT_MONITOR:
+ case PA_NODE_TYPE_SOURCE:
+ case PA_NODE_TYPE_SINK_INPUT:
+ pa_assert_not_reached();
+ }
+ break;
+
+ case PA_NODE_TYPE_SOURCE:
+ switch (edge->output->type) {
+ case PA_NODE_TYPE_SOURCE_OUTPUT:
+ r = connect_source_to_source_output(edge->input->owner, edge->output->owner);
+ break;
+
+ case PA_NODE_TYPE_PORT:
+ case PA_NODE_TYPE_SINK:
+ goto not_supported;
+
+ case PA_NODE_TYPE_PORT_MONITOR:
+ case PA_NODE_TYPE_SOURCE:
+ case PA_NODE_TYPE_SINK_INPUT:
+ pa_assert_not_reached();
+ }
+ break;
+
+ case PA_NODE_TYPE_SINK_INPUT:
+ switch (edge->output->type) {
+ case PA_NODE_TYPE_PORT:
+ r = connect_sink_input_to_port(edge->input->owner, edge->output->owner);
+ break;
+
+ case PA_NODE_TYPE_SINK:
+ r = connect_sink_input_to_sink(edge->input->owner, edge->output->owner);
+ break;
+
+ case PA_NODE_TYPE_SOURCE_OUTPUT:
+ r = connect_sink_input_to_source_output(edge->input->owner, edge->output->owner);
+ break;
+
+ case PA_NODE_TYPE_PORT_MONITOR:
+ case PA_NODE_TYPE_SOURCE:
+ case PA_NODE_TYPE_SINK_INPUT:
+ pa_assert_not_reached();
+ }
+ break;
+
+ case PA_NODE_TYPE_SINK:
+ case PA_NODE_TYPE_SOURCE_OUTPUT:
+ pa_assert_not_reached();
+ }
+
+ return r;
+
+not_supported:
+ pa_log_info("Connecting node type %s to type %s is not supported.", pa_node_type_to_string(edge->input->type),
+ pa_node_type_to_string(edge->output->type));
+
+ return -PA_ERR_NOTSUPPORTED;
+}
+
static int edge_put(pa_edge *edge) {
+ int r;
+
pa_assert(edge);
pa_node_add_edge(edge->input, edge);
pa_node_add_edge(edge->output, edge);
+ r = connect_nodes(edge);
+ if (r < 0)
+ goto fail;
+
pa_log_debug("Created edge %s.", edge->string);
return 0;
+
+fail:
+ edge_unlink(edge);
+
+ return r;
}
static void edge_unlink(pa_edge *edge) {
--
1.8.3.1
More information about the pulseaudio-discuss
mailing list