On 2019/1/1 上午2:33, Tanu Kaskinen wrote:
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.
I will change this part and make it follow the correct logic.
+ 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().
OK, got it.
+ 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
_______________________________________________
pulseaudio-discuss mailing list
pulseaudio-discuss@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss