[v2,6/8] device-port: moving streams due to changing the status of active_port

Submitted by Hui Wang on Jan. 17, 2019, 6:53 a.m.

Details

Message ID 20190117065340.18712-7-hui.wang@canonical.com
State New
Headers show
Series "Change the bool sink_save to char *preferred_sink" ( rev: 1 ) in PulseAudio

Not browsing as part of any series.

Commit Message

Hui Wang Jan. 17, 2019, 6:53 a.m.
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 a sink changes state from unavailable, all
streams that have their preferred_sink set to this sink should be moved
to this sink.

Signed-off-by: Hui Wang <hui.wang@canonical.com>
---
 src/pulsecore/device-port.c | 30 ++++++++++++++++++++++++++++++
 src/pulsecore/device-port.h |  2 ++
 2 files changed, 32 insertions(+)

Patch hide | download patch | download mbox

diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c
index 464c3f8a2..49de33b9e 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,22 @@  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_device_port_get_sink(p);
+        if (!sink)
+            return;
+        if (p != sink->active_port)
+            return;
+        switch (p->direction) {
+        case PA_DIRECTION_OUTPUT:
+            if (sink->active_port->available == PA_AVAILABLE_NO)
+                pa_sink_move_streams_to_default_sink(p->core, sink, false);
+            else
+                pa_core_move_streams_to_newly_available_preferred_sink(p->core, sink);
+            break;
+        case PA_DIRECTION_INPUT:
+            break;
+        }
     }
 }
 
@@ -224,3 +241,16 @@  pa_device_port *pa_device_port_find_best(pa_hashmap *ports)
 
     return best;
 }
+
+pa_sink *pa_device_port_get_sink(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/device-port.h b/src/pulsecore/device-port.h
index fbdce1aa0..41988e5bb 100644
--- a/src/pulsecore/device-port.h
+++ b/src/pulsecore/device-port.h
@@ -87,4 +87,6 @@  void pa_device_port_set_preferred_profile(pa_device_port *p, const char *new_pp)
 
 pa_device_port *pa_device_port_find_best(pa_hashmap *ports);
 
+pa_sink *pa_device_port_get_sink(pa_device_port *p);
+
 #endif

Comments

On 17.01.19 07:53, Hui Wang wrote:
> 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 a sink changes state from unavailable, all
> streams that have their preferred_sink set to this sink should be moved
> to this sink.
>
Is that necessary at all? If an additional port becomes available
or unavailable (lets say I plug in/out head phones) the sink does
not change. Only if the last port becomes available/unavailable
the sink also becomes available/unavailable and in that case the
switch to/from the sink will be handled elsewhere.

Or am I thinking wrong?
On 30.06.19 14:52, Georg Chini wrote:
> On 17.01.19 07:53, Hui Wang wrote:
>> 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 a sink changes state from unavailable, all
>> streams that have their preferred_sink set to this sink should be moved
>> to this sink.
>>
> Is that necessary at all? If an additional port becomes available
> or unavailable (lets say I plug in/out head phones) the sink does
> not change. Only if the last port becomes available/unavailable
> the sink also becomes available/unavailable and in that case the
> switch to/from the sink will be handled elsewhere.
>
> Or am I thinking wrong?
>
>
Well, I was thinking wrong. I understand now why it is needed,
so forget my previous mail.