[pulseaudio-discuss] [PATCH 2/3] alsa-mixer/card: Move to use the new mixer interface

David Henningsson david.henningsson at canonical.com
Mon Sep 1 07:08:52 PDT 2014


Use the new mixer API to get callbacks, instead of using the hctl
API. Using the hctl API caused a memory leak, because alsa-lib itself
used the hctl callbacks, which we were previously overriding.

Signed-off-by: David Henningsson <david.henningsson at canonical.com>
---
 src/modules/alsa/alsa-mixer.c       |  7 +++----
 src/modules/alsa/alsa-mixer.h       |  2 +-
 src/modules/alsa/module-alsa-card.c | 41 +++++++++++++++++++------------------
 3 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index ead601a..a12f578 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -1682,12 +1682,11 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t *m) {
     return 0;
 }
 
-static int jack_probe(pa_alsa_jack *j, snd_hctl_t *h) {
-    pa_assert(h);
+static int jack_probe(pa_alsa_jack *j, snd_mixer_t *m) {
     pa_assert(j);
     pa_assert(j->path);
 
-    j->has_control = pa_alsa_find_jack(h, j->alsa_name) != NULL;
+    j->has_control = pa_alsa_mixer_find(m, j->alsa_name, 0) != NULL;
 
     if (j->has_control) {
         if (j->required_absent != PA_ALSA_REQUIRED_IGNORE)
@@ -2635,7 +2634,7 @@ int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, snd_hctl_t *hctl, bool i
     pa_log_debug("Probing path '%s'", p->name);
 
     PA_LLIST_FOREACH(j, p->jacks) {
-        if (jack_probe(j, hctl) < 0) {
+        if (jack_probe(j, m) < 0) {
             p->supported = false;
             pa_log_debug("Probe of jack '%s' failed.", j->alsa_name);
             return -1;
diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h
index 4949560..ff3cb2d 100644
--- a/src/modules/alsa/alsa-mixer.h
+++ b/src/modules/alsa/alsa-mixer.h
@@ -164,7 +164,7 @@ struct pa_alsa_jack {
     char *alsa_name; /* E g "Headphone Jack" */
     bool has_control; /* is the jack itself present? */
     bool plugged_in; /* is this jack currently plugged in? */
-    snd_hctl_elem_t *hctl_elem; /* Jack detection handle */
+    snd_mixer_elem_t *melem; /* Jack detection handle */
     pa_available_t state_unplugged, state_plugged;
 
     pa_alsa_required_t required;
diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
index 63ff6e6..d39d13e 100644
--- a/src/modules/alsa/module-alsa-card.c
+++ b/src/modules/alsa/module-alsa-card.c
@@ -350,8 +350,9 @@ static void report_port_state(pa_device_port *p, struct userdata *u) {
     pa_device_port_set_available(p, pa);
 }
 
-static int report_jack_state(snd_hctl_elem_t *elem, unsigned int mask) {
-    struct userdata *u = snd_hctl_elem_get_callback_private(elem);
+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);
     snd_ctl_elem_value_t *elem_value;
     bool plugged_in;
     void *state;
@@ -374,7 +375,7 @@ static int report_jack_state(snd_hctl_elem_t *elem, unsigned int mask) {
     pa_log_debug("Jack '%s' is now %s", pa_strnull(snd_hctl_elem_get_name(elem)), plugged_in ? "plugged in" : "unplugged");
 
     PA_HASHMAP_FOREACH(jack, u->jacks, state)
-        if (jack->hctl_elem == elem) {
+        if (jack->melem == melem) {
             jack->plugged_in = plugged_in;
             if (u->use_ucm) {
                 pa_assert(u->card->ports);
@@ -403,8 +404,9 @@ static pa_device_port* find_port_with_eld_device(pa_hashmap *ports, int device)
     return NULL;
 }
 
-static int hdmi_eld_changed(snd_hctl_elem_t *elem, unsigned int mask) {
-    struct userdata *u = snd_hctl_elem_get_callback_private(elem);
+static int hdmi_eld_changed(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);
     int device = snd_hctl_elem_get_device(elem);
     const char *old_monitor_name;
     pa_device_port *p;
@@ -447,7 +449,7 @@ static void init_eld_ctls(struct userdata *u) {
 
     PA_HASHMAP_FOREACH(port, u->card->ports, state) {
         pa_alsa_port_data *data = PA_DEVICE_PORT_DATA(port);
-        snd_hctl_elem_t* hctl_elem;
+        snd_mixer_elem_t* melem;
         int device;
 
         pa_assert(data->path);
@@ -455,15 +457,14 @@ static void init_eld_ctls(struct userdata *u) {
         if (device < 0)
             continue;
 
-        hctl_elem = pa_alsa_find_eld_ctl(u->hctl_handle, device);
-        if (!hctl_elem) {
-            pa_log_debug("No ELD device found for port %s.", port->name);
-            continue;
+        melem = pa_alsa_mixer_find(u->mixer_handle, "ELD", device);
+        if (melem) {
+            snd_mixer_elem_set_callback(melem, hdmi_eld_changed);
+            snd_mixer_elem_set_callback_private(melem, u);
+            hdmi_eld_changed(melem, 0);
         }
-
-        snd_hctl_elem_set_callback_private(hctl_elem, u);
-        snd_hctl_elem_set_callback(hctl_elem, hdmi_eld_changed);
-        hdmi_eld_changed(hctl_elem, 0);
+        else
+            pa_log_debug("No ELD device found for port %s.", port->name);
     }
 }
 
@@ -501,17 +502,17 @@ static void init_jacks(struct userdata *u) {
     u->mixer_fdl = pa_alsa_fdlist_new();
 
     u->mixer_handle = pa_alsa_open_mixer(u->alsa_card_index, NULL, &u->hctl_handle);
-    if (u->mixer_handle && pa_alsa_fdlist_set_handle(u->mixer_fdl, NULL, u->hctl_handle, u->core->mainloop) >= 0) {
+    if (u->mixer_handle && pa_alsa_fdlist_set_handle(u->mixer_fdl, u->mixer_handle, NULL, u->core->mainloop) >= 0) {
         PA_HASHMAP_FOREACH(jack, u->jacks, state) {
-            jack->hctl_elem = pa_alsa_find_jack(u->hctl_handle, jack->alsa_name);
-            if (!jack->hctl_elem) {
+            jack->melem = pa_alsa_mixer_find(u->mixer_handle, jack->alsa_name, 0);
+            if (!jack->melem) {
                 pa_log_warn("Jack '%s' seems to have disappeared.", jack->alsa_name);
                 jack->has_control = false;
                 continue;
             }
-            snd_hctl_elem_set_callback_private(jack->hctl_elem, u);
-            snd_hctl_elem_set_callback(jack->hctl_elem, report_jack_state);
-            report_jack_state(jack->hctl_elem, 0);
+            snd_mixer_elem_set_callback(jack->melem, report_jack_state);
+            snd_mixer_elem_set_callback_private(jack->melem, u);
+            report_jack_state(jack->melem, 0);
         }
 
     } else
-- 
1.9.1



More information about the pulseaudio-discuss mailing list