From c6ef0336bb508f510204f5681dfb95ba9fb23f74 Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Tue, 11 Jul 2017 16:57:04 +0900 Subject: [PATCH] stream-manager: Update filter parameters to filter_info structure and to each stream in case of changing control value Previously, filter_info was not updated even after changing control value. So if a stream which should be applied with the filter is created, the last control value was not applied. Also, filter apply parameters property of a stream was not updated with changing control value. Now these things are fixed. [Version] 5.0.160 [Issue Type] Enhancement Change-Id: I101becfe9a23c888bf311e9e2534775927e23a6c Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/stream-manager-filter.c | 175 +++++++++++++++++++++----------- 2 files changed, 119 insertions(+), 58 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index ab1a50f..70a18dc 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 5.0.159 +Version: 5.0.160 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/stream-manager-filter.c b/src/stream-manager-filter.c index e8a447e..1257328 100644 --- a/src/stream-manager-filter.c +++ b/src/stream-manager-filter.c @@ -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; } -- 2.7.4