[pulseaudio-discuss] [PATCH 2/4] move stream after default sink is changed.

Hui Wang hui.wang at canonical.com
Sat Dec 15 06:48:23 UTC 2018


On 2018/12/13 下午5:16, Tanu Kaskinen wrote:
> On Mon, 2018-11-05 at 09:47 +0800, Hui Wang wrote:
>> When default sink changes, the stream should be moved to new
>> default_sink too.
> Except if the stream's preferred sink is the old default sink.
>
>> If it is user to call change default function,
>> all stream will move to new default sink unconditionally; if it
>> is not, will check if stream binds to old_default_sink and the
>> active_port staus of old_default_sink, then it will move the
>> stream conditionally.
> Why does it matter if the default sink changed due to user request or
> some other reason? I don't think streams should be moved
> unconditionally when the user changes the default sink.

Supposing  the sink0 is hdmi, sink1 is analog-speaker,  and a music is 
playing on sink0 (default_sink is sink0),  if users select the 
analog-speaker from UI (gnome-sound-setting), the sink1 is default_sink 
now, and the music should be played on sink1.  If the streams don't move 
to new default_sink unconditionally, I have no idea how to let music be 
played on sink1 here.


For the rest comments, I will fix them as suggested.


Thanks.


>
> I think it would be logical to not care about the port unavailability
> in this patch, because there's a separate patch for handling that.
>
>> diff --git a/src/modules/module-switch-on-connect.c b/src/modules/module-switch-on-connect.c
>> index faa0f289f..4f01c701f 100644
>> --- a/src/modules/module-switch-on-connect.c
>> +++ b/src/modules/module-switch-on-connect.c
>> @@ -100,29 +97,8 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void*
>>               return PA_HOOK_OK;
>>           }
>>   
>> -    old_default_sink = c->default_sink;
>> -
>>       /* Actually do the switch to the new sink */
> This comment isn't very helpful any more (not sure how helpful it was
> before either), I'd remove it.
>
>> -    pa_core_set_configured_default_sink(c, sink->name);
>> -
>> -    /* Now move all old inputs over */
>> -    if (pa_idxset_size(old_default_sink->inputs) <= 0) {
>> -        pa_log_debug("No sink inputs to move away.");
>> -        return PA_HOOK_OK;
>> -    }
>> -
>> -    PA_IDXSET_FOREACH(i, old_default_sink->inputs, idx) {
>> -        if (i->preferred_sink != NULL || !PA_SINK_INPUT_IS_LINKED(i->state))
>> -            continue;
>> -
>> -        if (pa_sink_input_move_to(i, sink, false) < 0)
>> -            pa_log_info("Failed to move sink input %u \"%s\" to %s.", i->index,
>> -                        pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME)), sink->name);
>> -        else
>> -            pa_log_info("Successfully moved sink input %u \"%s\" to %s.", i->index,
>> -                        pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME)), sink->name);
>> -    }
>> -
>> +    pa_core_set_configured_default_sink(c, sink->name, false);
>>       return PA_HOOK_OK;
>>   }
>> diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
>> index 566367f9e..63a3456e7 100644
>> --- a/src/pulsecore/sink.c
>> +++ b/src/pulsecore/sink.c
>> @@ -3886,3 +3886,36 @@ void pa_sink_set_reference_volume_direct(pa_sink *s, const pa_cvolume *volume) {
>>       pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
>>       pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_VOLUME_CHANGED], s);
>>   }
>> +
>> +void pa_sink_move_streams_from_oldsink_to_newsink(pa_sink *old_sink, pa_sink *new_sink, bool from_user) {
> I think "pa_sink_move_streams_to_default_sink" would be a better name
> for the function. It would also be good to have a comment explaining
> when the function is used and which streams are not moved (that could
> go to the header file).
>
>> +    pa_sink_input *i;
>> +    uint32_t idx;
>> +    pa_device_port *o_active_p;
>> +
>> +    if (old_sink == new_sink)
>> +	return;
>> +
>> +    if (old_sink == NULL)
>> +	return;
> It doesn't make sense to call this function with NULL, so this check
> should be an assertion instead.
>
>> +
>> +    o_active_p = old_sink->active_port;
> Note that not all sinks have ports, so this can be NULL.
>
> Since we only care about the availability of the active port, I'd add a
> "old_sink_is_unavailable" boolean to be used inside the loop.
>
>> +    if (pa_idxset_size(old_sink->inputs) > 0) {
>> +	    PA_IDXSET_FOREACH(i, old_sink->inputs, idx) {
>> +		if (!PA_SINK_INPUT_IS_LINKED(i->state))
>> +		    continue;
>> +
>> +		if (!from_user && i->preferred_sink != NULL && pa_safe_streq(old_sink->name, i->preferred_sink))
> No need to check if i->preferred_sink is NULL, because pa_safe_streq()
> checks that anyway.
>
>> +		    if (o_active_p->available != PA_AVAILABLE_NO)
>> +			continue;
>> +
>> +		if (pa_sink_input_move_to(i, new_sink, from_user) < 0)
>> +		    pa_log_info("Failed to move sink input %u \"%s\" to %s.", i->index,
>> +				pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME)), new_sink->name);
>> +		else
>> +		    pa_log_info("Successfully moved sink input %u \"%s\" to %s.", i->index,
>> +				pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME)), new_sink->name);
> Logging the reason for moving the stream before calling
> pa_sink_input_move_to() would be very useful.
>
> Here's a suggestion you don't need to implement, but you can if you
> want: it would be nice to have good enough logging in
> pa_sink_input_move_finish() so that callers don't all need to do their
> own logging about the move result. This should be done in a separate
> patch.
>



More information about the pulseaudio-discuss mailing list