[pulseaudio-discuss] [PATCH v5] filter-apply: Fixed a stream moves to wrong sink or source.

Georg Chini georg at chini.tk
Wed Apr 19 17:46:13 UTC 2017


On 19.04.2017 11:03, KimJeongYeon wrote:
> For example, a normal stream tried to attach to filter sink or source, which
> filter loaded and managed by filter-apply. But, the stream goes to filter's
> ***master sink or source*** due to unexpected restoring operation.
> It should attached to filter sink or source properly.
>
> Also, includes further fix according to Georg's comment, [1]
>    If a stream that had filter.apply set initially is moved to another sink/source, then the filter
>    should be applied again (a new filter, since the master sink/source has changed).
>
>    If a stream that did not have filter.apply set initially is moved away, the property should
>    be removed and no new filter applied.
>
>    Also, a property list change might add or remove the filter.apply property. If it is added,
>    we want that the filter is applied. Your patch does nothing and assumes that the stream
>    is already filtered, even if the stream is not on a filter sink.
>
> [1] https://lists.freedesktop.org/archives/pulseaudio-discuss/2017-April/027980.html
>
> Signed-off-by: KimJeongYeon <jeongyeon.kim at samsung.com>

We are nearly there. Still some comments ...

> ---
>   src/modules/module-filter-apply.c | 107 +++++++++++++++++++++++++++++++-------
>   1 file changed, 89 insertions(+), 18 deletions(-)
>
> diff --git a/src/modules/module-filter-apply.c b/src/modules/module-filter-apply.c
> index e91fb37..562221a 100644
> --- a/src/modules/module-filter-apply.c
> +++ b/src/modules/module-filter-apply.c
> @@ -39,6 +39,7 @@
>   
>   #define PA_PROP_FILTER_APPLY_PARAMETERS PA_PROP_FILTER_APPLY".%s.parameters"
>   #define PA_PROP_FILTER_APPLY_MOVING     "filter.apply.moving"
> +#define PA_PROP_FILTER_APPLY_SET_BY_MFA "filter.apply.set_by_mfa"
>   #define PA_PROP_MDM_AUTO_FILTERED       "module-device-manager.auto_filtered"
>   
>   PA_MODULE_AUTHOR("Colin Guthrie");
> @@ -161,6 +162,53 @@ static const char* get_filter_parameters(pa_object *o, const char *want, bool is
>       return parameters;
>   }
>   

This function is very difficult to read. I'd rename "is_set" to 
"set_properties" and also
add another boolean "set_by_mfa" so that you set/unset all filter 
properties within
this function. More changes below.

> +static void set_filter_properties(pa_proplist *pl, struct filter* filter, bool is_set) {
> +    const char *apply;

Rename the variable "apply" to "old_filter_name", initialize it to NULL 
and move
the definition into the else clause.

> +    char *prop_parameters;
> +
> +    if (is_set) {
> +        pa_assert(filter);
> +
> +        pa_proplist_sets(pl, PA_PROP_FILTER_APPLY, filter->name);
> +        if (filter->parameters) {
> +            prop_parameters = pa_sprintf_malloc(PA_PROP_FILTER_APPLY_PARAMETERS, filter->name);
> +            pa_proplist_sets(pl, prop_parameters, filter->parameters);
> +            pa_xfree(prop_parameters);
> +        }

If "set_by_mfa" is true, you can set the filter.apply.set_by_mfa 
property here.

> +    } else {
> +        if (filter)
> +            prop_parameters = pa_sprintf_malloc(PA_PROP_FILTER_APPLY_PARAMETERS, filter->name);
> +        else {
> +            if (!(apply = pa_proplist_gets(pl, PA_PROP_FILTER_APPLY)))
> +                return;
> +            prop_parameters = pa_sprintf_malloc(PA_PROP_FILTER_APPLY_PARAMETERS, apply);
> +        }

To make it more easy to read, I would change the code above like this:

          if (filter)
              old_filter_name = filter->name;
          else
              old_filter_name = pa_proplist_gets(pl, PA_PROP_FILTER_APPLY);

          if (!old_filter_name)
             /* Filter name cannot be determined, nothing to do */
             return
          prop_parameters = 
pa_sprintf_malloc(PA_PROP_FILTER_APPLY_PARAMETERS, old_filter_name);

> +        pa_proplist_unset(pl, prop_parameters);
> +        pa_xfree(prop_parameters);
> +        pa_proplist_unset(pl, PA_PROP_FILTER_APPLY);

Here you can unconditionally unset the filter.apply.set_by_mfa property.

> +    }
> +}
> +
> +static struct filter* get_attached_filter(struct userdata *u, pa_object *o, bool is_sink_input) {

Maybe I would rename the function to get_filter_for_object(). But I 
don't mind if you
keep the name.

> +    pa_sink *sink = NULL;
> +    pa_source *source = NULL;
> +    struct filter *filter = NULL;
> +    void *state;
> +
> +    if (is_sink_input)
> +        sink = PA_SINK_INPUT(o)->sink;
> +    else
> +        source = PA_SOURCE_OUTPUT(o)->source;
> +
> +    PA_HASHMAP_FOREACH(filter, u->filters, state) {
> +        if ((is_sink_input && sink == filter->sink) || (!is_sink_input && source == filter->source)) {
> +            return filter;
> +        }
> +    }
> +
> +    return NULL;
> +}
> +
>   static bool should_group_filter(struct filter *filter) {
>       return pa_streq(filter->name, "echo-cancel");
>   }
> @@ -431,7 +479,7 @@ static bool can_unload_module(struct userdata *u, uint32_t idx) {
>       return true;
>   }
>   
> -static pa_hook_result_t process(struct userdata *u, pa_object *o, bool is_sink_input) {
> +static pa_hook_result_t process(struct userdata *u, pa_object *o, bool is_sink_input, bool is_put_or_move) {

I would prefer "is_property_change" instead of "is_put_or_move". But again,
I don't mind if you keep it.


 From your other mail:

I think it is able to eliminate redundant moving by check
PA_PROP_FILTER_APPLY_MOVING at 'sink_input_proplist_cb'.
No more need additional 'skip_prop_change' flag.

code:
     if (pa_proplist_gets(i->proplist, PA_PROP_FILTER_APPLY_MOVING))
         return PA_HOOK_OK;

How do you think? Are you agree that would be fix at new patch?

Yes, that looks like a good idea.

I hope you don't mind if I change the commit message like I did for
your other patches and add a few more comments to the code.




More information about the pulseaudio-discuss mailing list