[pulseaudio-discuss] [PATCH 14/30] node: Add pa_node.active

Tanu Kaskinen tanu.kaskinen at linux.intel.com
Thu Jan 16 07:02:40 PST 2014


Nodes can be active or inactive. Sink, source and stream nodes are
always active, but the port node activity follows the port activity.

Routing policy implementations must activate nodes before they can be
be connected to any other nodes.
---
 src/pulsecore/device-port.c   | 13 +++++++++++++
 src/pulsecore/node.c          | 21 +++++++++++++++++++++
 src/pulsecore/node.h          |  6 ++++++
 src/pulsecore/sink-input.c    |  1 +
 src/pulsecore/sink.c          | 21 ++++++++++++++++++---
 src/pulsecore/source-output.c |  1 +
 src/pulsecore/source.c        | 22 +++++++++++++++++++---
 7 files changed, 79 insertions(+), 6 deletions(-)

diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c
index 9511940..5fd9a9a 100644
--- a/src/pulsecore/device-port.c
+++ b/src/pulsecore/device-port.c
@@ -201,6 +201,19 @@ void pa_device_port_set_device(pa_device_port *port, void *device) {
     pa_assert(port);
 
     port->device = device;
+
+    if (!device) {
+        pa_node_active_changed(port->node, false);
+        return;
+    }
+
+    if (port->direction == PA_DIRECTION_OUTPUT) {
+        if (port == ((pa_sink *) device)->active_port)
+            pa_node_active_changed(port->node, true);
+    } else {
+        if (port == ((pa_source *) device)->active_port)
+            pa_node_active_changed(port->node, true);
+    }
 }
 
 void pa_device_port_set_latency_offset(pa_device_port *p, int64_t offset) {
diff --git a/src/pulsecore/node.c b/src/pulsecore/node.c
index 155ff4b..c7cd11d 100644
--- a/src/pulsecore/node.c
+++ b/src/pulsecore/node.c
@@ -84,6 +84,12 @@ void pa_node_new_data_set_monitor_of(pa_node_new_data *data, pa_node *monitor_of
     data->monitor_of = monitor_of;
 }
 
+void pa_node_new_data_set_active(pa_node_new_data *data, bool active) {
+    pa_assert(data);
+
+    data->active = active;
+}
+
 void pa_node_new_data_done(pa_node_new_data *data) {
     pa_assert(data);
 
@@ -139,6 +145,7 @@ pa_node *pa_node_new(pa_core *core, pa_node_new_data *data) {
     n->type = data->type;
     n->direction = data->direction;
     n->monitor_of = data->monitor_of;
+    n->active = data->active;
 
     return n;
 
@@ -410,3 +417,17 @@ void pa_node_unlink(pa_node *node) {
 
     node->state = PA_NODE_STATE_UNLINKED;
 }
+
+void pa_node_active_changed(pa_node *node, bool new_active) {
+    pa_assert(node);
+
+    if (new_active == node->active)
+        return;
+
+    node->active = new_active;
+
+    pa_log_debug("Node %s %s.", node->name, new_active ? "activated" : "deactivated");
+
+    if (node->monitor)
+        pa_node_active_changed(node->monitor, new_active);
+}
diff --git a/src/pulsecore/node.h b/src/pulsecore/node.h
index 306096a..ab31d96 100644
--- a/src/pulsecore/node.h
+++ b/src/pulsecore/node.h
@@ -60,6 +60,7 @@ struct pa_node_new_data {
     pa_node_type_t type;
     pa_direction_t direction;
     pa_node *monitor_of;
+    bool active;
 };
 
 struct pa_node {
@@ -75,6 +76,7 @@ struct pa_node {
     pa_node_state_t state;
     pa_node *monitor;
     pa_node *monitor_of;
+    bool active;
 
     void *owner;
 };
@@ -95,6 +97,7 @@ void pa_node_new_data_set_description(pa_node_new_data *data, const char *descri
 void pa_node_new_data_set_type(pa_node_new_data *data, pa_node_type_t type);
 void pa_node_new_data_set_direction(pa_node_new_data *data, pa_direction_t direction);
 void pa_node_new_data_set_monitor_of(pa_node_new_data *data, pa_node *monitor_of);
+void pa_node_new_data_set_active(pa_node_new_data *data, bool active);
 void pa_node_new_data_done(pa_node_new_data *data);
 
 pa_node *pa_node_new(pa_core *core, pa_node_new_data *data);
@@ -103,4 +106,7 @@ void pa_node_free(pa_node *node);
 int pa_node_put(pa_node *node, pa_node **requested_connections, unsigned n_requested_connections);
 void pa_node_unlink(pa_node *node);
 
+/* To be called by the node back end when its active state changes. */
+void pa_node_active_changed(pa_node *node, bool new_active);
+
 #endif
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index fa67a13..aea25eb 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -117,6 +117,7 @@ pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data
     pa_node_new_data_init(&data->node_data);
     pa_node_new_data_set_type(&data->node_data, PA_NODE_TYPE_SINK_INPUT);
     pa_node_new_data_set_direction(&data->node_data, PA_DIRECTION_INPUT);
+    pa_node_new_data_set_active(&data->node_data, true);
 
     return data;
 }
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index 96a4a22..1792538 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -86,6 +86,7 @@ pa_sink_new_data* pa_sink_new_data_init(pa_sink_new_data *data) {
     pa_node_new_data_init(&data->node_data);
     pa_node_new_data_set_type(&data->node_data, PA_NODE_TYPE_SINK);
     pa_node_new_data_set_direction(&data->node_data, PA_DIRECTION_OUTPUT);
+    pa_node_new_data_set_active(&data->node_data, true);
 
     return data;
 }
@@ -3425,6 +3426,7 @@ size_t pa_sink_get_max_request(pa_sink *s) {
 /* Called from main context */
 int pa_sink_set_port(pa_sink *s, const char *name, bool save) {
     pa_device_port *port;
+    pa_device_port *old_port;
     int ret;
 
     pa_sink_assert_ref(s);
@@ -3441,11 +3443,15 @@ int pa_sink_set_port(pa_sink *s, const char *name, bool save) {
     if (!(port = pa_hashmap_get(s->ports, name)))
         return -PA_ERR_NOENTITY;
 
-    if (s->active_port == port) {
+    old_port = s->active_port;
+
+    if (port == old_port) {
         s->save_port = s->save_port || save;
         return 0;
     }
 
+    pa_node_active_changed(old_port->node, false);
+
     if (s->flags & PA_SINK_DEFERRED_VOLUME) {
         struct sink_message_set_port msg = { .port = port, .ret = 0 };
         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_PORT, &msg, 0, NULL) == 0);
@@ -3454,17 +3460,26 @@ int pa_sink_set_port(pa_sink *s, const char *name, bool save) {
     else
         ret = s->set_port(s, port);
 
-    if (ret < 0)
+    if (ret < 0) {
+        pa_log("Failed to change the port of sink %s from %s to %s.", s->name, old_port->name, port->name);
+
+        /* We don't know the real state of the device, but let's assume that
+         * the old port is still active, because s->active_port is left to
+         * point to the old port anyway. */
+        pa_node_active_changed(old_port->node, true);
+
         return ret;
+    }
 
     pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
 
-    pa_log_info("Changed port of sink %u \"%s\" to %s", s->index, s->name, port->name);
+    pa_log_info("Changed port of sink %u \"%s\" from %s to %s", s->index, s->name, old_port->name, port->name);
 
     s->active_port = port;
     s->save_port = save;
 
     pa_sink_set_latency_offset(s, s->active_port->latency_offset);
+    pa_node_active_changed(port->node, true);
 
     pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PORT_CHANGED], s);
 
diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c
index 7d6f060..62d421b 100644
--- a/src/pulsecore/source-output.c
+++ b/src/pulsecore/source-output.c
@@ -59,6 +59,7 @@ pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_d
     pa_node_new_data_init(&data->node_data);
     pa_node_new_data_set_type(&data->node_data, PA_NODE_TYPE_SOURCE_OUTPUT);
     pa_node_new_data_set_direction(&data->node_data, PA_DIRECTION_OUTPUT);
+    pa_node_new_data_set_active(&data->node_data, true);
 
     return data;
 }
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index 050e519..0843795 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -77,6 +77,7 @@ pa_source_new_data* pa_source_new_data_init(pa_source_new_data *data) {
     pa_node_new_data_init(&data->node_data);
     pa_node_new_data_set_type(&data->node_data, PA_NODE_TYPE_SOURCE);
     pa_node_new_data_set_direction(&data->node_data, PA_DIRECTION_INPUT);
+    pa_node_new_data_set_active(&data->node_data, true);
 
     return data;
 }
@@ -2718,6 +2719,7 @@ size_t pa_source_get_max_rewind(pa_source *s) {
 /* Called from main context */
 int pa_source_set_port(pa_source *s, const char *name, bool save) {
     pa_device_port *port;
+    pa_device_port *old_port;
     int ret;
 
     pa_source_assert_ref(s);
@@ -2734,11 +2736,15 @@ int pa_source_set_port(pa_source *s, const char *name, bool save) {
     if (!(port = pa_hashmap_get(s->ports, name)))
         return -PA_ERR_NOENTITY;
 
-    if (s->active_port == port) {
+    old_port = s->active_port;
+
+    if (port == old_port) {
         s->save_port = s->save_port || save;
         return 0;
     }
 
+    pa_node_active_changed(old_port->node, false);
+
     if (s->flags & PA_SOURCE_DEFERRED_VOLUME) {
         struct source_message_set_port msg = { .port = port, .ret = 0 };
         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_PORT, &msg, 0, NULL) == 0);
@@ -2747,16 +2753,26 @@ int pa_source_set_port(pa_source *s, const char *name, bool save) {
     else
         ret = s->set_port(s, port);
 
-    if (ret < 0)
+    if (ret < 0) {
+        pa_log("Failed to change the port of source %s from %s to %s.", s->name, old_port->name, port->name);
+
+        /* We don't know the real state of the device, but let's assume that
+         * the old port is still active, because s->active_port is left to
+         * point to the old port anyway. */
+        pa_node_active_changed(old_port->node, true);
+
         return ret;
+    }
 
     pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
 
-    pa_log_info("Changed port of source %u \"%s\" to %s", s->index, s->name, port->name);
+    pa_log_info("Changed port of source %u \"%s\" from %s to %s", s->index, s->name, old_port->name, port->name);
 
     s->active_port = port;
     s->save_port = save;
 
+    pa_node_active_changed(port->node, true);
+
     pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PORT_CHANGED], s);
 
     return 0;
-- 
1.8.3.1



More information about the pulseaudio-discuss mailing list