On 2014-05-28 10:42, Hui Wang wrote:
Recently met a problem: when I disconnect the bluetooth headset, the
pulseaudio automatically switch the sound to sink of HDMI output
instead of the sink of internal speaker even though there is no HDMI
cable connected.

To fix this problem, I want to change the rule of selecting the target
sink(same rules apply to the source selecting):
If the sinks have the port with PA_AVAILABLE_YES, we will choose the
one from them with a highest priority port. If all sinks don't have
the port with PA_AVAILABLE_YES, we will choose the one with a highest
priority port.

Thanks for the patch.

I think it would be better to construct a new hashmap with all ports (of all relevant sinks) and then call find_best on the new hashmap. That would give a better handling of e g PA_AVAILABLE_UNKNOWN than what you're suggesting.

Also some types of sinks do not have ports at all. Your patch introduces a regression in this case because they are no longer considered valid to switch to.

(The same reasoning applies to sources.)


Signed-off-by: Hui Wang <hui.w...@canonical.com>
---
  src/modules/module-rescue-streams.c | 80 +++++++++++++++++++++++++------------
  1 file changed, 54 insertions(+), 26 deletions(-)

diff --git a/src/modules/module-rescue-streams.c 
b/src/modules/module-rescue-streams.c
index 7035a35..8a4c8d6 100644
--- a/src/modules/module-rescue-streams.c
+++ b/src/modules/module-rescue-streams.c
@@ -53,33 +53,47 @@ struct userdata {
  };

  static pa_sink* find_evacuation_sink(pa_core *c, pa_sink_input *i, pa_sink 
*skip) {
-    pa_sink *target, *def;
+    pa_sink *target, *best_target = NULL;
+    pa_device_port *port, *best_port = NULL;
      uint32_t idx;

      pa_assert(c);
      pa_assert(i);

-    def = pa_namereg_get_default_sink(c);
-
-    if (def && def != skip && pa_sink_input_may_move_to(i, def))
-        return def;
-
      PA_IDXSET_FOREACH(target, c->sinks, idx) {
-        if (target == def)
-            continue;
-
          if (target == skip)
              continue;

          if (!PA_SINK_IS_LINKED(pa_sink_get_state(target)))
              continue;

-        if (pa_sink_input_may_move_to(i, target))
-            return target;
+        if (!pa_sink_input_may_move_to(i, target))
+            continue;
+
+        port = pa_device_port_find_best(target->ports);
+        if (!port)
+           continue;
+
+       if (!best_target) {
+           best_target = target;
+            best_port = port;
+            continue;
+       }
+
+       if (best_port->available != port->available && best_port->available == 
PA_AVAILABLE_YES)
+           continue;
+
+       if (best_port->available == port->available && best_port->priority > 
port->priority)
+           continue;
+
+        best_target = target;
+        best_port = port;
      }

-    pa_log_debug("No evacuation sink found.");
-    return NULL;
+    if(!best_target)
+        pa_log_debug("No evacuation sink found.");
+
+    return best_target;
  }

  static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, 
void* userdata) {
@@ -141,21 +155,14 @@ static pa_hook_result_t 
sink_input_move_fail_hook_callback(pa_core *c, pa_sink_i
  }

  static pa_source* find_evacuation_source(pa_core *c, pa_source_output *o, 
pa_source *skip) {
-    pa_source *target, *def;
+    pa_source *target, *best_target = NULL;
+    pa_device_port *port, *best_port = NULL;
      uint32_t idx;

      pa_assert(c);
      pa_assert(o);

-    def = pa_namereg_get_default_source(c);
-
-    if (def && def != skip && pa_source_output_may_move_to(o, def))
-        return def;
-
      PA_IDXSET_FOREACH(target, c->sources, idx) {
-        if (target == def)
-            continue;
-
          if (target == skip)
              continue;

@@ -165,12 +172,33 @@ static pa_source* find_evacuation_source(pa_core *c, 
pa_source_output *o, pa_sou
          if (!PA_SOURCE_IS_LINKED(pa_source_get_state(target)))
              continue;

-        if (pa_source_output_may_move_to(o, target))
-            return target;
+        if (!pa_source_output_may_move_to(o, target))
+            continue;
+
+        port = pa_device_port_find_best(target->ports);
+        if (!port)
+           continue;
+
+       if (!best_target) {
+           best_target = target;
+            best_port = port;
+            continue;
+       }
+
+       if (best_port->available != port->available && best_port->available == 
PA_AVAILABLE_YES)
+           continue;
+
+       if (best_port->available == port->available && best_port->priority > 
port->priority)
+           continue;
+
+        best_target = target;
+        best_port = port;
      }

-    pa_log_debug("No evacuation source found.");
-    return NULL;
+    if (!best_target)
+        pa_log_debug("No evacuation source found.");
+
+    return best_target;
  }

  static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source 
*source, void* userdata) {


--
David Henningsson, Canonical Ltd.
https://launchpad.net/~diwic
_______________________________________________
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Reply via email to