[pulseaudio-discuss] [PATCH 12/23] match: Do proplist updating already in the NEW hook

Tanu Kaskinen tanu.kaskinen at linux.intel.com
Wed Nov 20 01:26:04 PST 2013


I don't want any modules to update the sink input proplist in the
FIXATE hook. module-match is the only module that does that.

The reason for not wanting proplist updates in the FIXATE hook is that
the sink input description is stored in the proplist, and I want to
derive the node description from the sink input description, and the
sink input node should be created before the FIXATE hook is fired. If
module-match updates the sink input description in the FIXATE hook,
that update won't be visible at the time the node description is set.
---
 src/modules/module-match.c | 37 +++++++++++++++++++++++++++++++++----
 1 file changed, 33 insertions(+), 4 deletions(-)

diff --git a/src/modules/module-match.c b/src/modules/module-match.c
index 8ce3f00..185fdf9 100644
--- a/src/modules/module-match.c
+++ b/src/modules/module-match.c
@@ -80,6 +80,7 @@ struct rule {
 struct userdata {
     struct rule *rules;
     char *property_key;
+    pa_hook_slot *sink_input_new_hook_slot;
     pa_hook_slot *sink_input_fixate_hook_slot;
 };
 
@@ -213,6 +214,31 @@ finish:
     return ret;
 }
 
+static pa_hook_result_t sink_input_new_hook_callback(void *hook_data, void *call_data, void *userdata) {
+    struct userdata *u = userdata;
+    struct rule *r;
+    const char *n;
+    pa_sink_input_new_data *data = call_data;
+
+    pa_assert(u);
+    pa_assert(data);
+
+    if (!(n = pa_proplist_gets(data->proplist, u->property_key)))
+        return PA_HOOK_OK;
+
+    for (r = u->rules; r; r = r->next) {
+        if (!r->proplist)
+            continue;
+
+        if (!regexec(&r->regex, n, 0, NULL, 0)) {
+            pa_log_debug("Updating the proplist of sink input '%s'", n);
+            pa_proplist_update(data->proplist, r->mode, r->proplist);
+        }
+    }
+
+    return PA_HOOK_OK;
+}
+
 static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_input_new_data *si, struct userdata *u) {
     struct rule *r;
     const char *n;
@@ -227,10 +253,7 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_inpu
 
     for (r = u->rules; r; r = r->next) {
         if (!regexec(&r->regex, n, 0, NULL, 0)) {
-            if (r->proplist) {
-                pa_log_debug("updating proplist of sink input '%s'", n);
-                pa_proplist_update(si->proplist, r->mode, r->proplist);
-            } else if (si->volume_writable) {
+            if (si->volume_writable) {
                 pa_cvolume cv;
                 pa_log_debug("changing volume of sink input '%s' to 0x%03x", n, r->volume);
                 pa_cvolume_set(&cv, si->sample_spec.channels, r->volume);
@@ -263,6 +286,9 @@ int pa__init(pa_module*m) {
     if (load_rules(u, pa_modargs_get_value(ma, "table", NULL)) < 0)
         goto fail;
 
+    u->sink_input_new_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], PA_HOOK_NORMAL,
+                                                  sink_input_new_hook_callback, u);
+
     /* hook EARLY - 1, to match before stream-restore */
     u->sink_input_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], PA_HOOK_EARLY - 1, (pa_hook_cb_t) sink_input_fixate_hook_callback, u);
 
@@ -289,6 +315,9 @@ void pa__done(pa_module*m) {
     if (u->sink_input_fixate_hook_slot)
         pa_hook_slot_free(u->sink_input_fixate_hook_slot);
 
+    if (u->sink_input_new_hook_slot)
+        pa_hook_slot_free(u->sink_input_new_hook_slot);
+
     if (u->property_key)
         pa_xfree(u->property_key);
 
-- 
1.8.3.1



More information about the pulseaudio-discuss mailing list