[pulseaudio-discuss] [PATCH v4] alsa-mixer: Cache failure to open inputs/output mappings

David Henningsson david.henningsson at canonical.com
Mon Oct 1 06:37:21 PDT 2012


I was hoping this would improve bootup speed, but it doesn't seem
to do so here, at least not much. But at least it reduces the logs
a little.

Signed-off-by: David Henningsson <david.henningsson at canonical.com>
---

Please ignore the just sent v3. It was identical to v2, sorry.

 src/modules/alsa/alsa-mixer.c |   54 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 50 insertions(+), 4 deletions(-)

diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index 8072fbb..ea24880 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -3920,6 +3920,16 @@ static void profile_set_add_auto(pa_alsa_profile_set *ps) {
 
     pa_assert(ps);
 
+    /* The order is important here:
+       1) try single inputs and outputs before trying their
+          combination, because if the half-duplex test failed, we don't have
+          to try full duplex.
+       2) try the output right before the input combinations with
+          that output, because then the output_pcm is not closed between tests.
+    */
+    PA_HASHMAP_FOREACH(n, ps->mappings, n_state)
+        profile_set_add_auto_pair(ps, NULL, n);
+
     PA_HASHMAP_FOREACH(m, ps->mappings, m_state) {
         profile_set_add_auto_pair(ps, m, NULL);
 
@@ -3927,8 +3937,6 @@ static void profile_set_add_auto(pa_alsa_profile_set *ps) {
             profile_set_add_auto_pair(ps, m, n);
     }
 
-    PA_HASHMAP_FOREACH(n, ps->mappings, n_state)
-        profile_set_add_auto_pair(ps, NULL, n);
 }
 
 static int profile_verify(pa_alsa_profile *p) {
@@ -4293,6 +4301,7 @@ void pa_alsa_profile_set_probe(
     void *state;
     pa_alsa_profile *p, *last = NULL;
     pa_alsa_mapping *m;
+    pa_hashmap *broken_inputs, *broken_outputs;
 
     pa_assert(ps);
     pa_assert(dev_id);
@@ -4301,18 +4310,43 @@ void pa_alsa_profile_set_probe(
     if (ps->probed)
         return;
 
+    broken_inputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+    broken_outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+
     PA_HASHMAP_FOREACH(p, ps->profiles, state) {
         uint32_t idx;
 
         /* Skip if this is already marked that it is supported (i.e. from the config file) */
         if (!p->supported) {
 
-            pa_log_debug("Looking at profile %s", p->name);
             profile_finalize_probing(last, p);
             p->supported = TRUE;
 
+            if (p->output_mappings) {
+                PA_IDXSET_FOREACH(m, p->output_mappings, idx) {
+                    if (pa_hashmap_get(broken_outputs, m) == m) {
+                        pa_log_debug("Skipping profile %s - will not be able to open output:%s", p->name, m->name);
+                        p->supported = FALSE;
+                        break;
+                    }
+                }
+            }
+
+            if (p->input_mappings && p->supported) {
+                PA_IDXSET_FOREACH(m, p->input_mappings, idx) {
+                    if (pa_hashmap_get(broken_inputs, m) == m) {
+                        pa_log_debug("Skipping profile %s - will not be able to open input:%s", p->name, m->name);
+                        p->supported = FALSE;
+                        break;
+                    }
+                }
+            }
+
+            if (p->supported)
+                pa_log_debug("Looking at profile %s", p->name);
+
             /* Check if we can open all new ones */
-            if (p->output_mappings)
+            if (p->output_mappings && p->supported)
                 PA_IDXSET_FOREACH(m, p->output_mappings, idx) {
 
                     if (m->output_pcm)
@@ -4324,6 +4358,11 @@ void pa_alsa_profile_set_probe(
                                                            default_n_fragments,
                                                            default_fragment_size_msec))) {
                         p->supported = FALSE;
+                        if (pa_idxset_size(p->output_mappings) == 1 &&
+                            ((!p->input_mappings) || pa_idxset_size(p->input_mappings) == 0)) {
+                            pa_log_debug("Caching failure to open output:%s", m->name);
+                            pa_hashmap_put(broken_outputs, m, m);
+                        }
                         break;
                     }
                 }
@@ -4340,6 +4379,11 @@ void pa_alsa_profile_set_probe(
                                                           default_n_fragments,
                                                           default_fragment_size_msec))) {
                         p->supported = FALSE;
+                        if (pa_idxset_size(p->input_mappings) == 1 &&
+                            ((!p->output_mappings) || pa_idxset_size(p->output_mappings) == 0)) {
+                            pa_log_debug("Caching failure to open input:%s", m->name);
+                            pa_hashmap_put(broken_inputs, m, m);
+                        }
                         break;
                     }
                 }
@@ -4370,6 +4414,8 @@ void pa_alsa_profile_set_probe(
 
     paths_drop_unsupported(ps->input_paths);
     paths_drop_unsupported(ps->output_paths);
+    pa_hashmap_free(broken_inputs, NULL, NULL);
+    pa_hashmap_free(broken_outputs, NULL, NULL);
 
     ps->probed = TRUE;
 }
-- 
1.7.9.5



More information about the pulseaudio-discuss mailing list