[pulseaudio-discuss] [PATCH 09/17] alsa: Add pa_alsa_profile_set_create_ports()

Tanu Kaskinen tanu.kaskinen at linux.intel.com
Mon Dec 30 05:04:44 PST 2013


Currently, card ports, device prototypes and profiles are all created
together in an "interleaved" manner. My goal is to split that process
so that first all ports are created, then all device prototypes are
created and finally all profiles are created. This patch is the first
major step in that refactoring: all ports are created in
pa_alsa_profile_set_create_ports() before any device prototypes or
profiles are created. Most of the code in device_port_alsa_init() is
moved to create_port().
---
 src/modules/alsa/alsa-mixer.c       | 160 ++++++++++++++++++++++++------------
 src/modules/alsa/alsa-mixer.h       |   3 +-
 src/modules/alsa/module-alsa-card.c |   5 +-
 3 files changed, 111 insertions(+), 57 deletions(-)

diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index 4645817..bd243ba 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -4483,61 +4483,21 @@ static pa_device_port* device_port_alsa_init(pa_hashmap *ports, /* card ports */
     pa_alsa_path *path,
     pa_alsa_setting *setting,
     pa_card_profile *cp,
-    pa_hashmap *extra, /* sink/source ports */
-    pa_core *core) {
+    pa_hashmap *extra /* sink/source ports */) {
 
     char *name = NULL;
-    char *description = NULL;
     pa_device_port *p;
 
     pa_assert(path);
 
-    if (setting) {
+    if (setting)
         name = pa_sprintf_malloc("%s;%s", path->name, setting->name);
-
-        if (setting->description[0])
-            description = pa_sprintf_malloc("%s / %s", path->description, setting->description);
-        else
-            description = pa_xstrdup(path->description);
-    } else {
+    else
         name = pa_xstrdup(path->name);
-        description = pa_xstrdup(path->description);
-    }
 
     p = pa_hashmap_get(ports, name);
-
-    if (!p) {
-        pa_alsa_port_data *data;
-        pa_device_port_new_data port_data;
-
-        pa_device_port_new_data_init(&port_data);
-        pa_device_port_new_data_set_name(&port_data, name);
-        pa_device_port_new_data_set_description(&port_data, description);
-        pa_device_port_new_data_set_direction(&port_data, path->direction == PA_ALSA_DIRECTION_OUTPUT ? PA_DIRECTION_OUTPUT : PA_DIRECTION_INPUT);
-        pa_node_new_data_set_fallback_name_prefix(&port_data.node_data, "alsa");
-
-        p = pa_device_port_new(core, &port_data, sizeof(pa_alsa_port_data));
-        pa_device_port_new_data_done(&port_data);
-
-        if (!p) {
-            pa_log("Failed to create port %s.", name);
-            goto finish;
-        }
-
-        p->priority = path->priority * 100;
-
-        if (setting)
-            p->priority += setting->priority;
-
-        pa_hashmap_put(ports, p->name, p);
-        pa_proplist_update(p->proplist, PA_UPDATE_REPLACE, path->proplist);
-
-        data = PA_DEVICE_PORT_DATA(p);
-        data->path = path;
-        data->setting = setting;
-
-        pa_dynarray_append(path->ports, p);
-    }
+    pa_assert(p);
+    pa_xfree(name);
 
     if (cp)
         pa_hashmap_put(p->profiles, cp->name, cp);
@@ -4547,10 +4507,6 @@ static pa_device_port* device_port_alsa_init(pa_hashmap *ports, /* card ports */
         pa_device_port_ref(p);
     }
 
-finish:
-    pa_xfree(description);
-    pa_xfree(name);
-
     return p;
 }
 
@@ -4558,8 +4514,7 @@ void pa_alsa_path_set_add_ports(
         pa_alsa_path_set *ps,
         pa_card_profile *cp,
         pa_hashmap *ports, /* card ports */
-        pa_hashmap *extra, /* sink/source ports */
-        pa_core *core) {
+        pa_hashmap *extra /* sink/source ports */) {
 
     pa_alsa_path *path;
     void *state;
@@ -4573,11 +4528,11 @@ void pa_alsa_path_set_add_ports(
         if (!path->settings || !path->settings->next)
             /* If there is no or just one setting we only need a
              * single entry */
-            device_port_alsa_init(ports, path, path->settings, cp, extra, core);
+            device_port_alsa_init(ports, path, path->settings, cp, extra);
         else {
             pa_alsa_setting *s;
             PA_LLIST_FOREACH(s, path->settings)
-                device_port_alsa_init(ports, path, s, cp, extra, core);
+                device_port_alsa_init(ports, path, s, cp, extra);
         }
     }
 }
@@ -4595,8 +4550,105 @@ void pa_alsa_add_ports(void *sink_or_source_new_data, pa_alsa_path_set *ps, pa_c
 
     if (ps->paths && pa_hashmap_size(ps->paths) > 0) {
         pa_assert(card);
-        pa_alsa_path_set_add_ports(ps, NULL, card->ports, ports, card->core);
+        pa_alsa_path_set_add_ports(ps, NULL, card->ports, ports);
     }
 
     pa_log_debug("Added %u ports", pa_hashmap_size(ports));
 }
+
+static pa_device_port *create_port(pa_core *core, pa_alsa_path *path, pa_alsa_setting *setting) {
+    char *name = NULL;
+    char *description = NULL;
+    pa_device_port_new_data port_data;
+    pa_device_port *port;
+    pa_alsa_port_data *data;
+
+    pa_assert(core);
+    pa_assert(path);
+
+    if (setting) {
+        name = pa_sprintf_malloc("%s;%s", path->name, setting->name);
+
+        if (setting->description[0])
+            description = pa_sprintf_malloc("%s / %s", path->description, setting->description);
+        else
+            description = pa_xstrdup(path->description);
+    } else {
+        name = pa_xstrdup(path->name);
+        description = pa_xstrdup(path->description);
+    }
+
+    pa_device_port_new_data_init(&port_data);
+    pa_device_port_new_data_set_name(&port_data, name);
+    pa_device_port_new_data_set_description(&port_data, description);
+    pa_device_port_new_data_set_direction(&port_data,
+            path->direction == PA_ALSA_DIRECTION_OUTPUT ? PA_DIRECTION_OUTPUT : PA_DIRECTION_INPUT);
+    pa_node_new_data_set_fallback_name_prefix(&port_data.node_data, "alsa");
+
+    port = pa_device_port_new(core, &port_data, sizeof(pa_alsa_port_data));
+    pa_device_port_new_data_done(&port_data);
+
+    if (!port) {
+        pa_log("Failed to create port %s.", name);
+        goto finish;
+    }
+
+    port->priority = path->priority * 100;
+
+    if (setting)
+        port->priority += setting->priority;
+
+    pa_proplist_update(port->proplist, PA_UPDATE_REPLACE, path->proplist);
+
+    data = PA_DEVICE_PORT_DATA(port);
+    data->path = path;
+    data->setting = setting;
+
+    pa_dynarray_append(path->ports, port);
+
+finish:
+    pa_xfree(description);
+    pa_xfree(name);
+
+    return port;
+}
+
+static void path_create_ports(pa_core *core, pa_alsa_path *path, pa_hashmap *ports) {
+    pa_device_port *port;
+
+    pa_assert(core);
+    pa_assert(path);
+    pa_assert(ports);
+
+    if (!path->settings || !path->settings->next) {
+        /* If there is no or just one setting we only need a single entry. */
+        port = create_port(core, path, NULL);
+
+        if (port)
+            pa_hashmap_put(ports, port->name, port);
+    } else {
+        pa_alsa_setting *setting;
+
+        PA_LLIST_FOREACH(setting, path->settings) {
+            port = create_port(core, path, setting);
+
+            if (port)
+                pa_hashmap_put(ports, port->name, port);
+        }
+    }
+}
+
+void pa_alsa_profile_set_create_ports(pa_core *core, pa_alsa_profile_set *profile_set, pa_hashmap *ports) {
+    pa_alsa_path *path;
+    void *state;
+
+    pa_assert(core);
+    pa_assert(profile_set);
+    pa_assert(ports);
+
+    PA_HASHMAP_FOREACH(path, profile_set->output_paths, state)
+        path_create_ports(core, path, ports);
+
+    PA_HASHMAP_FOREACH(path, profile_set->input_paths, state)
+        path_create_ports(core, path, ports);
+}
diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h
index 7a27ac3..a39befe 100644
--- a/src/modules/alsa/alsa-mixer.h
+++ b/src/modules/alsa/alsa-mixer.h
@@ -355,6 +355,7 @@ struct pa_alsa_port_data {
 };
 
 void pa_alsa_add_ports(void *sink_or_source_new_data, pa_alsa_path_set *ps, pa_card *card);
-void pa_alsa_path_set_add_ports(pa_alsa_path_set *ps, pa_card_profile *cp, pa_hashmap *ports, pa_hashmap *extra, pa_core *core);
+void pa_alsa_path_set_add_ports(pa_alsa_path_set *ps, pa_card_profile *cp, pa_hashmap *ports, pa_hashmap *extra);
+void pa_alsa_profile_set_create_ports(pa_core *core, pa_alsa_profile_set *profile_set, pa_hashmap *ports);
 
 #endif
diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
index 7576043..4b09c95 100644
--- a/src/modules/alsa/module-alsa-card.c
+++ b/src/modules/alsa/module-alsa-card.c
@@ -163,7 +163,7 @@ static void add_profiles(struct userdata *u, pa_card_new_data *data) {
                 if (u->use_ucm)
                     pa_alsa_ucm_add_ports_combination(NULL, &m->ucm_context, true, data->ports, cp, u->core);
                 else
-                    pa_alsa_path_set_add_ports(m->output_path_set, cp, data->ports, NULL, u->core);
+                    pa_alsa_path_set_add_ports(m->output_path_set, cp, data->ports, NULL);
                 if (m->channel_map.channels > cp->max_sink_channels)
                     cp->max_sink_channels = m->channel_map.channels;
             }
@@ -179,7 +179,7 @@ static void add_profiles(struct userdata *u, pa_card_new_data *data) {
                 if (u->use_ucm)
                     pa_alsa_ucm_add_ports_combination(NULL, &m->ucm_context, false, data->ports, cp, u->core);
                 else
-                    pa_alsa_path_set_add_ports(m->input_path_set, cp, data->ports, NULL, u->core);
+                    pa_alsa_path_set_add_ports(m->input_path_set, cp, data->ports, NULL);
                 if (m->channel_map.channels > cp->max_source_channels)
                     cp->max_source_channels = m->channel_map.channels;
             }
@@ -711,6 +711,7 @@ int pa__init(pa_module *m) {
         if ((description = pa_proplist_gets(data.proplist, PA_PROP_DEVICE_DESCRIPTION)))
             pa_reserve_wrapper_set_application_device_name(reserve, description);
 
+    pa_alsa_profile_set_create_ports(u->core, u->profile_set, data.ports);
     add_profiles(u, &data);
 
     if (pa_hashmap_isempty(data.profiles)) {
-- 
1.8.3.1



More information about the pulseaudio-discuss mailing list