On Mon, 2018-11-05 at 09:47 +0800, Hui Wang wrote: > When the active port of a sink becomes unavailable, all streams from > that sink should be moved to the default sink. > > When the active port of an existing sink changes state from > unavailable, all streams that have their "preferred_sink" > set to the new sink should be moved to the new sink. > > Signed-off-by: Hui Wang <hui.wang@xxxxxxxxxxxxx> > --- > src/pulsecore/device-port.c | 16 ++++++++++++++++ > src/pulsecore/sink.c | 13 +++++++++++++ > src/pulsecore/sink.h | 1 + > 3 files changed, 30 insertions(+) > > diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c > index 464c3f8a2..2604c9051 100644 > --- a/src/pulsecore/device-port.c > +++ b/src/pulsecore/device-port.c > @@ -92,6 +92,7 @@ void pa_device_port_set_available(pa_device_port *p, pa_available_t status) { > * be created before port objects, and then p->card could be non-NULL for > * the whole lifecycle of pa_device_port. */ > if (p->card && p->card->linked) { > + pa_sink *sink; > /* A sink or source whose active port is unavailable can't be the > * default sink/source, so port availability changes may affect the > * default sink/source choice. */ > @@ -102,6 +103,21 @@ void pa_device_port_set_available(pa_device_port *p, pa_available_t status) { > > pa_subscription_post(p->core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE, p->card->index); > pa_hook_fire(&p->core->hooks[PA_CORE_HOOK_PORT_AVAILABLE_CHANGED], p); > + > + sink = pa_sink_get_sink_from_device_port(p); > + if (!sink) > + return; > + switch (p->direction) { > + case PA_DIRECTION_OUTPUT: > + if (sink->active_port->available == PA_AVAILABLE_NO) > + pa_sink_move_streams_from_oldsink_to_newsink(sink, p->core->default_sink, false); This logic isn't quite right. We should move streams away from the sink only if the active port is the same that just changed its availability status. If the current port is something other than the port that changed, then we should ignore the change event. > + else > + pa_sink_bind_preferred_stream_to_a_sink(sink); > + > + break; > + case PA_DIRECTION_INPUT: > + break; > + } > } > } > > diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c > index a2a390beb..9ebc18fa1 100644 > --- a/src/pulsecore/sink.c > +++ b/src/pulsecore/sink.c > @@ -3950,3 +3950,16 @@ void pa_sink_bind_preferred_stream_to_a_sink(pa_sink *s) { > pa_sink_input_move_to(si, s, false); > } > } > + > +pa_sink *pa_sink_get_sink_from_device_port(pa_device_port *p) { This is a good helper function, but I think it would fit slightly better in the pa_device_port namespace. So I'd rename it to pa_device_port_get_sink(). > + pa_sink *rs = NULL; > + pa_sink *sink; > + uint32_t state; > + > + PA_IDXSET_FOREACH(sink, p->card->sinks, state) > + if (p == pa_hashmap_get(sink->ports, p->name)) { > + rs = sink; > + break; > + } > + return rs; > +} > diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h > index 24e4678b1..693344ac3 100644 > --- a/src/pulsecore/sink.h > +++ b/src/pulsecore/sink.h > @@ -563,4 +563,5 @@ void pa_sink_set_reference_volume_direct(pa_sink *s, const pa_cvolume *volume); > > void pa_sink_move_streams_from_oldsink_to_newsink(pa_sink *old_sink, pa_sink *new_sink, bool from_user); > void pa_sink_bind_preferred_stream_to_a_sink(pa_sink *s); > +pa_sink *pa_sink_get_sink_from_device_port(pa_device_port *p); > #endif -- Tanu https://www.patreon.com/tanuk https://liberapay.com/tanuk _______________________________________________ pulseaudio-discuss mailing list pulseaudio-discuss@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss