stream-manager: Update filter parameters to filter_info structure and to each stream...
[platform/core/multimedia/pulseaudio-modules-tizen.git] / src / stream-manager-filter.c
index e8a447e..1257328 100644 (file)
@@ -166,47 +166,60 @@ finish:
     return ret;
 }
 
+static void update_prop_filter_apply_group(pa_sink_input *si, filter_info *f, const char *filter_apply) {
+    char *prop_group = NULL;
+
+    pa_assert(si);
+    pa_assert(filter_apply);
+
+    prop_group = pa_sprintf_malloc(PA_PROP_FILTER_APPLY_GROUP, filter_apply);
+
+    if (!f)
+        pa_proplist_unset(si->proplist, prop_group);
+    else if (f->group)
+        pa_proplist_sets(si->proplist, prop_group, f->group);
+
+    pa_xfree(prop_group);
+}
+
+static void update_prop_filter_apply_params(pa_sink_input *si, filter_info *f, const char *filter_apply) {
+    char *prop_parameters = NULL;
+
+    pa_assert(si);
+    pa_assert(filter_apply);
+
+    prop_parameters = pa_sprintf_malloc(PA_PROP_FILTER_APPLY_PARAMETERS, filter_apply);
+
+    if (!f)
+        pa_proplist_unset(si->proplist, prop_parameters);
+    else if (f->parameters)
+        pa_proplist_sets(si->proplist, prop_parameters, f->parameters);
+
+    pa_xfree(prop_parameters);
+}
+
 /* Invoked from dbus method call or hook fire */
 int32_t apply_filter_to_sink_input(pa_sink_input *si, filter_info *f, bool need_to_hook) {
-    const char *filter_apply = NULL;
-    char *prop_group;
-    char *prop_parameters;
-
     pa_assert(si);
 
+    if (f && (!f->filter_apply || pa_streq(f->filter_apply, ""))) {
+        pa_log_error("Try to applying empty filter module");
+        return -1;
+    }
+
     if (!f) {
+        const char *filter_apply = NULL;
         /* Unload filter using module-filter-apply */
         if ((filter_apply = pa_proplist_gets(si->proplist, PA_PROP_FILTER_APPLY))) {
-            prop_group = pa_sprintf_malloc(PA_PROP_FILTER_APPLY_GROUP, filter_apply);
-            pa_proplist_unset(si->proplist, prop_group);
-            pa_xfree(prop_group);
-
-            prop_parameters = pa_sprintf_malloc(PA_PROP_FILTER_APPLY_PARAMETERS, filter_apply);
-            pa_proplist_unset(si->proplist, prop_parameters);
-            pa_xfree(prop_parameters);
-
+            update_prop_filter_apply_group(si, f, filter_apply);
+            update_prop_filter_apply_params(si, f, filter_apply);
             pa_proplist_unset(si->proplist, PA_PROP_FILTER_APPLY);
         }
     } else {
-        if (!f->filter_apply || pa_streq(f->filter_apply, "")) {
-            pa_log_error("Try to applying empty filter module");
-            return -1;
-        }
-
         /* Load filter using module-filter-apply */
         pa_proplist_sets(si->proplist, PA_PROP_FILTER_APPLY, f->filter_apply);
-
-        /* Optional properties */
-        if (f->group) {
-            prop_group = pa_sprintf_malloc(PA_PROP_FILTER_APPLY_GROUP, f->filter_apply);
-            pa_proplist_sets(si->proplist, prop_group, f->group);
-            pa_xfree(prop_group);
-        }
-        if (f->parameters) {
-            prop_parameters = pa_sprintf_malloc(PA_PROP_FILTER_APPLY_PARAMETERS, f->filter_apply);
-            pa_proplist_sets(si->proplist, prop_parameters, f->parameters);
-            pa_xfree(prop_parameters);
-        }
+        update_prop_filter_apply_group(si, f, f->filter_apply);
+        update_prop_filter_apply_params(si, f, f->filter_apply);
     }
 
     if (need_to_hook)
@@ -265,6 +278,44 @@ int32_t update_filter(pa_stream_manager *m, const char *filter_name, const char
     return 0;
 }
 
+#define MAX_ELEMENT_LENGTH 64
+#define MAX_PARAMETERS_LENGTH 256
+static void update_filter_parameters(filter_info *f) {
+    const char *split_state = NULL;
+    const char *control_element = "control=";
+    char *param_element = NULL;
+    char control_values[MAX_ELEMENT_LENGTH] = {'\0',};
+    char result_buf[MAX_PARAMETERS_LENGTH] = {'\0',};
+    uint32_t i;
+    int32_t len;
+    int32_t c_len;
+
+    pa_assert(f);
+
+    if (f->n_controls == 0)
+        return;
+
+    while ((param_element = pa_split(f->parameters, " ", &split_state))) {
+        len = strlen(result_buf);
+        if (!strncmp(param_element, control_element, strlen(control_element))) {
+            for (i = 0; i < f->n_controls; i++) {
+                c_len = strlen(control_values);
+                pa_snprintf(control_values + c_len, MAX_ELEMENT_LENGTH - c_len,
+                            (i == f->n_controls - 1) ? "%1.1f" : "%1.1f,", f->controls.values[i]);
+            }
+            pa_snprintf(result_buf + len, MAX_PARAMETERS_LENGTH - len, "%s%s", control_element, control_values);
+        } else {
+            pa_snprintf(result_buf + len, MAX_PARAMETERS_LENGTH - len, "%s ", param_element);
+        }
+        pa_xfree((void *)param_element);
+    }
+
+    pa_xfree((void *)f->parameters);
+    f->parameters = pa_xstrdup(result_buf);
+
+    pa_log_info("new filter parameters: %s", f->parameters);
+}
+
 /* Invoked from dbus method call */
 int32_t control_filter(pa_stream_manager *m, const char *filter_name, const char *filter_controls, const char *stream_type,
                        DBusConnection *conn) {
@@ -281,8 +332,12 @@ int32_t control_filter(pa_stream_manager *m, const char *filter_name, const char
     }
 
     /* Search filter_info according to stream type, then get index of sink */
-    f = pa_hashmap_get(m->filter_infos, (const void*)stream_type);
-    if (f && pa_safe_streq(f->filter_apply, filter_name)) {
+    if (!(f = pa_hashmap_get(m->filter_infos, (const void*)stream_type))) {
+        pa_log_error("No filter information or sink to control");
+        return -1;
+    }
+
+    if (pa_safe_streq(f->filter_apply, filter_name)) {
         PA_IDXSET_FOREACH(si, m->core->sink_inputs, si_idx) {
             role = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_ROLE);
             if (pa_safe_streq(role, stream_type)) {
@@ -293,35 +348,41 @@ int32_t control_filter(pa_stream_manager *m, const char *filter_name, const char
         }
     }
 
-    if (f && s) {
-        if (pa_safe_streq(f->filter_apply, "ladspa-sink") && pa_safe_streq(s->module->name, "module-ladspa-sink")) {
-            double read_values[FILTER_MAX_CONTROLS];
-            bool use_default[FILTER_MAX_CONTROLS];
-            int32_t n_controls;
-
-            /* Parse control parameters (e.g, "0.0, 0.1, 3.0") */
-            n_controls = parse_filter_control_parameters(filter_controls, read_values, use_default, FILTER_MAX_CONTROLS);
-            if (n_controls > 0) {
-                /* Save control parameters to filter_info */
-                uint32_t i;
-                for (i = 0; i < n_controls; i++) {
-                    f->controls.values[i] = read_values[i];
-                    f->controls.use_default[i] = use_default[i];
-                    f->n_controls = (uint32_t)n_controls;
-                }
-            } else {
-                pa_log_error("No filter controls to filter");
-                return -1;
+    if (pa_safe_streq(f->filter_apply, "ladspa-sink") || (s && pa_safe_streq(s->module->name, "module-ladspa-sink"))) {
+        double read_values[FILTER_MAX_CONTROLS];
+        bool use_default[FILTER_MAX_CONTROLS];
+        int32_t n_controls;
+
+        /* Parse control parameters (e.g, "0.0, 0.1, 3.0") */
+        n_controls = parse_filter_control_parameters(filter_controls, read_values, use_default, FILTER_MAX_CONTROLS);
+        if (n_controls > 0) {
+            /* Save control parameters to filter_info */
+            uint32_t i;
+            for (i = 0; i < n_controls; i++) {
+                f->controls.values[i] = read_values[i];
+                f->controls.use_default[i] = use_default[i];
+                f->n_controls = (uint32_t)n_controls;
             }
 
-            /* Send control parameters to ladspa-sink */
-            control_filter_ladspa(conn, f, s_idx);
+            /* update parameters */
+            update_filter_parameters(f);
+            if (s) {
+                PA_IDXSET_FOREACH(si, m->core->sink_inputs, si_idx) {
+                    role = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_ROLE);
+                    if (pa_safe_streq(role, stream_type))
+                        update_prop_filter_apply_params(si, f, f->filter_apply);
+                }
+            }
         } else {
-            pa_log_error("Sorry, it is able to control ladspa-sink only");
+            pa_log_error("No filter controls to filter");
             return -1;
         }
+
+        /* Send control parameters to ladspa-sink */
+        if (s)
+            control_filter_ladspa(conn, f, s_idx);
     } else {
-        pa_log_error("No filter information or sink to control");
+        pa_log_error("Sorry, it is able to control ladspa-sink only");
         return -1;
     }
 
@@ -416,9 +477,9 @@ int32_t reload_filter(pa_stream_manager *m, const char *stream_role, pa_sink *ne
     pa_log_info("reload filter successfully for [stream_role:%s, sink:%s]", stream_role, new_master_sink->name);
 
 leave:
-    pa_xfree((void*)filter_name);
-    pa_xfree((void*)filter_params);
-    pa_xfree((void*)filter_group);
+    pa_xfree((void *)filter_name);
+    pa_xfree((void *)filter_params);
+    pa_xfree((void *)filter_group);
 
     return ret;
 }