[PATCH 12/15] edge: Add support for connecting new streams

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux Audio Users]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux