[pulseaudio-discuss] [PATCH] rescue-streams: try to find best one using availability and priority

David Henningsson david.henningsson at canonical.com
Wed May 28 03:07:09 PDT 2014



On 2014-05-28 10:42, Hui Wang wrote:
> Recently met a problem: when I disconnect the bluetooth headset, the
> pulseaudio automatically switch the sound to sink of HDMI output
> instead of the sink of internal speaker even though there is no HDMI
> cable connected.
>
> To fix this problem, I want to change the rule of selecting the target
> sink(same rules apply to the source selecting):
> If the sinks have the port with PA_AVAILABLE_YES, we will choose the
> one from them with a highest priority port. If all sinks don't have
> the port with PA_AVAILABLE_YES, we will choose the one with a highest
> priority port.

Thanks for the patch.

I think it would be better to construct a new hashmap with all ports (of 
all relevant sinks) and then call find_best on the new hashmap.
That would give a better handling of e g PA_AVAILABLE_UNKNOWN than what 
you're suggesting.

Also some types of sinks do not have ports at all. Your patch introduces 
a regression in this case because they are no longer considered valid to 
switch to.

(The same reasoning applies to sources.)

>
> Signed-off-by: Hui Wang <hui.wang at canonical.com>
> ---
>   src/modules/module-rescue-streams.c | 80 +++++++++++++++++++++++++------------
>   1 file changed, 54 insertions(+), 26 deletions(-)
>
> diff --git a/src/modules/module-rescue-streams.c b/src/modules/module-rescue-streams.c
> index 7035a35..8a4c8d6 100644
> --- a/src/modules/module-rescue-streams.c
> +++ b/src/modules/module-rescue-streams.c
> @@ -53,33 +53,47 @@ struct userdata {
>   };
>
>   static pa_sink* find_evacuation_sink(pa_core *c, pa_sink_input *i, pa_sink *skip) {
> -    pa_sink *target, *def;
> +    pa_sink *target, *best_target = NULL;
> +    pa_device_port *port, *best_port = NULL;
>       uint32_t idx;
>
>       pa_assert(c);
>       pa_assert(i);
>
> -    def = pa_namereg_get_default_sink(c);
> -
> -    if (def && def != skip && pa_sink_input_may_move_to(i, def))
> -        return def;
> -
>       PA_IDXSET_FOREACH(target, c->sinks, idx) {
> -        if (target == def)
> -            continue;
> -
>           if (target == skip)
>               continue;
>
>           if (!PA_SINK_IS_LINKED(pa_sink_get_state(target)))
>               continue;
>
> -        if (pa_sink_input_may_move_to(i, target))
> -            return target;
> +        if (!pa_sink_input_may_move_to(i, target))
> +            continue;
> +
> +        port = pa_device_port_find_best(target->ports);
> +        if (!port)
> +	    continue;
> +
> +	if (!best_target) {
> +	    best_target = target;
> +            best_port = port;
> +            continue;
> +	}
> +
> +	if (best_port->available != port->available && best_port->available == PA_AVAILABLE_YES)
> +	    continue;
> +
> +	if (best_port->available == port->available && best_port->priority > port->priority)
> +	    continue;
> +
> +        best_target = target;
> +        best_port = port;
>       }
>
> -    pa_log_debug("No evacuation sink found.");
> -    return NULL;
> +    if(!best_target)
> +        pa_log_debug("No evacuation sink found.");
> +
> +    return best_target;
>   }
>
>   static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, void* userdata) {
> @@ -141,21 +155,14 @@ static pa_hook_result_t sink_input_move_fail_hook_callback(pa_core *c, pa_sink_i
>   }
>
>   static pa_source* find_evacuation_source(pa_core *c, pa_source_output *o, pa_source *skip) {
> -    pa_source *target, *def;
> +    pa_source *target, *best_target = NULL;
> +    pa_device_port *port, *best_port = NULL;
>       uint32_t idx;
>
>       pa_assert(c);
>       pa_assert(o);
>
> -    def = pa_namereg_get_default_source(c);
> -
> -    if (def && def != skip && pa_source_output_may_move_to(o, def))
> -        return def;
> -
>       PA_IDXSET_FOREACH(target, c->sources, idx) {
> -        if (target == def)
> -            continue;
> -
>           if (target == skip)
>               continue;
>
> @@ -165,12 +172,33 @@ static pa_source* find_evacuation_source(pa_core *c, pa_source_output *o, pa_sou
>           if (!PA_SOURCE_IS_LINKED(pa_source_get_state(target)))
>               continue;
>
> -        if (pa_source_output_may_move_to(o, target))
> -            return target;
> +        if (!pa_source_output_may_move_to(o, target))
> +            continue;
> +
> +        port = pa_device_port_find_best(target->ports);
> +        if (!port)
> +	    continue;
> +
> +	if (!best_target) {
> +	    best_target = target;
> +            best_port = port;
> +            continue;
> +	}
> +
> +	if (best_port->available != port->available && best_port->available == PA_AVAILABLE_YES)
> +	    continue;
> +
> +	if (best_port->available == port->available && best_port->priority > port->priority)
> +	    continue;
> +
> +        best_target = target;
> +        best_port = port;
>       }
>
> -    pa_log_debug("No evacuation source found.");
> -    return NULL;
> +    if (!best_target)
> +        pa_log_debug("No evacuation source found.");
> +
> +    return best_target;
>   }
>
>   static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *source, void* userdata) {
>

-- 
David Henningsson, Canonical Ltd.
https://launchpad.net/~diwic


More information about the pulseaudio-discuss mailing list