[pulseaudio-discuss] [PATCH 4/4] move stream when the active_port changes

Hui Wang hui.wang at canonical.com
Mon Nov 5 01:47:16 UTC 2018


When the active port of a sink becomes unavailable, all streams from
that sink should be moved to the default sink.

When the active port of an existing sink changes state from
unavailable, all streams that have their "preferred_sink"
set to the new sink should be moved to the new sink.

Signed-off-by: Hui Wang <hui.wang at canonical.com>
---
 src/pulsecore/device-port.c | 16 ++++++++++++++++
 src/pulsecore/sink.c        | 13 +++++++++++++
 src/pulsecore/sink.h        |  1 +
 3 files changed, 30 insertions(+)

diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c
index 464c3f8a2..2604c9051 100644
--- a/src/pulsecore/device-port.c
+++ b/src/pulsecore/device-port.c
@@ -92,6 +92,7 @@ void pa_device_port_set_available(pa_device_port *p, pa_available_t status) {
      * be created before port objects, and then p->card could be non-NULL for
      * the whole lifecycle of pa_device_port. */
     if (p->card && p->card->linked) {
+	pa_sink *sink;
         /* A sink or source whose active port is unavailable can't be the
          * default sink/source, so port availability changes may affect the
          * default sink/source choice. */
@@ -102,6 +103,21 @@ void pa_device_port_set_available(pa_device_port *p, pa_available_t status) {
 
         pa_subscription_post(p->core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE, p->card->index);
         pa_hook_fire(&p->core->hooks[PA_CORE_HOOK_PORT_AVAILABLE_CHANGED], p);
+
+	sink = pa_sink_get_sink_from_device_port(p);
+	if (!sink)
+	    return;
+	switch (p->direction) {
+        case PA_DIRECTION_OUTPUT:
+	    if (sink->active_port->available == PA_AVAILABLE_NO)
+		pa_sink_move_streams_from_oldsink_to_newsink(sink, p->core->default_sink, false);
+	    else
+		pa_sink_bind_preferred_stream_to_a_sink(sink);
+
+            break;
+        case PA_DIRECTION_INPUT:
+	    break;
+	}
     }
 }
 
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index a2a390beb..9ebc18fa1 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -3950,3 +3950,16 @@ void pa_sink_bind_preferred_stream_to_a_sink(pa_sink *s) {
            pa_sink_input_move_to(si, s, false);
     }
 }
+
+pa_sink *pa_sink_get_sink_from_device_port(pa_device_port *p) {
+    pa_sink *rs = NULL;
+    pa_sink *sink;
+    uint32_t state;
+
+    PA_IDXSET_FOREACH(sink, p->card->sinks, state)
+	if (p == pa_hashmap_get(sink->ports, p->name)) {
+	    rs = sink;
+	    break;
+	}
+    return rs;
+}
diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h
index 24e4678b1..693344ac3 100644
--- a/src/pulsecore/sink.h
+++ b/src/pulsecore/sink.h
@@ -563,4 +563,5 @@ void pa_sink_set_reference_volume_direct(pa_sink *s, const pa_cvolume *volume);
 
 void pa_sink_move_streams_from_oldsink_to_newsink(pa_sink *old_sink, pa_sink *new_sink, bool from_user);
 void pa_sink_bind_preferred_stream_to_a_sink(pa_sink *s);
+pa_sink *pa_sink_get_sink_from_device_port(pa_device_port *p);
 #endif
-- 
2.17.1



More information about the pulseaudio-discuss mailing list