[pulseaudio-commits] src/modules

Tanu Kaskinen tanuk at kemper.freedesktop.org
Tue Oct 20 03:24:09 PDT 2015


 src/modules/alsa/module-alsa-card.c |   31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)

New commits:
commit 91313e60a81e96ce976f24c522656c57b4ab94ca
Author: David Henningsson <david.henningsson at canonical.com>
Date:   Tue May 5 17:01:13 2015 +0200

    module-alsa-card: Report available ports before unavailable ones
    
    In case the same jack causes one port to become available and another
    one unavailable, the available should be reported first.
    
    This is to avoid unnecessary changes: e g, consider a 'Headphone Jack'
    making 'Headphone' available and 'Speaker' unavailable. In case the
    unavailable change triggers first, and there is also a currently available
    third port (e g 'Digital out'), the routing system might choose to route
    to this port because neither of the 'Speaker' and 'Headphone' ports are
    available.
    
    Signed-off-by: David Henningsson <david.henningsson at canonical.com>

diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
index df4f848..e173e51 100644
--- a/src/modules/alsa/module-alsa-card.c
+++ b/src/modules/alsa/module-alsa-card.c
@@ -304,7 +304,7 @@ static void init_profile(struct userdata *u) {
             am->source = pa_alsa_source_new(u->module, u->modargs, __FILE__, u->card, am);
 }
 
-static void report_port_state(pa_device_port *p, struct userdata *u) {
+static pa_available_t calc_port_state(pa_device_port *p, struct userdata *u) {
     void *state;
     pa_alsa_jack *jack;
     pa_available_t pa = PA_AVAILABLE_UNKNOWN;
@@ -348,10 +348,14 @@ static void report_port_state(pa_device_port *p, struct userdata *u) {
           pa = cpa;
         }
     }
-
-    pa_device_port_set_available(p, pa);
+    return pa;
 }
 
+struct temp_port_avail {
+    pa_device_port *port;
+    pa_available_t avail;
+};
+
 static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
     struct userdata *u = snd_mixer_elem_get_callback_private(melem);
     snd_hctl_elem_t *elem = snd_mixer_elem_get_private(melem);
@@ -359,7 +363,7 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
     bool plugged_in;
     void *state;
     pa_alsa_jack *jack;
-    pa_device_port *port;
+    struct temp_port_avail *tp, *tports;
 
     pa_assert(u);
 
@@ -376,6 +380,8 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
 
     pa_log_debug("Jack '%s' is now %s", pa_strnull(snd_hctl_elem_get_name(elem)), plugged_in ? "plugged in" : "unplugged");
 
+    tports = tp = pa_xnew0(struct temp_port_avail, pa_hashmap_size(u->jacks)+1);
+
     PA_HASHMAP_FOREACH(jack, u->jacks, state)
         if (jack->melem == melem) {
             pa_alsa_jack_set_plugged_in(jack, plugged_in);
@@ -388,9 +394,22 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
 
             /* When not using UCM, we have to do the jack state -> port
              * availability mapping ourselves. */
-            pa_assert_se(port = jack->path->port);
-            report_port_state(port, u);
+            pa_assert_se(tp->port = jack->path->port);
+            tp->avail = calc_port_state(tp->port, u);
+            tp++;
         }
+
+    /* Report available ports before unavailable ones: in case port 1 becomes available when port 2 becomes unavailable,
+       this prevents an unnecessary switch port 1 -> port 3 -> port 2 */
+
+    for (tp = tports; tp->port; tp++)
+        if (tp->avail != PA_AVAILABLE_NO)
+           pa_device_port_set_available(tp->port, tp->avail);
+    for (tp = tports; tp->port; tp++)
+        if (tp->avail == PA_AVAILABLE_NO)
+           pa_device_port_set_available(tp->port, tp->avail);
+
+    pa_xfree(tports);
     return 0;
 }
 



More information about the pulseaudio-commits mailing list