Discussion:
[pulseaudio-discuss] Audio APP (sink-input) bind to the sink with only unplugged hdmi-audio ports on it
Hui Wang
2018-09-30 07:03:31 UTC
Permalink
This issue is also reported to:
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/579

Recently we found a weird issue on many laptops with the ubuntu 18.04,
it uses the pulseaudio-11.1 (I guess the PA of the latest version also
has this problem). The issue is like this:

1. boot the system up without plugging a hdmi monitor
2. run an audio app to play sound (e.g. $speaker-test)
3. the sound outputs from analog-speaker
4. plug a monitor with audio capability (through DP or HDMI port)
5. the sound still outputs from analog-speaker
6. open sound-setting (gnome-control-center --> choose sound), you will
see two output devies: speaker and HDMI audio
7. choose HDMI audio, the sound will switch to HDIM audio from speaker
(pa will remember speaker-test prefer to use hdmi-audio sink)
8. unplug the monitor, the default-sink is switching to analog-speaker,
but the sound of speaker-test still route to hdmi-audio sink
9. run other sound apps, they all route sound to default sink
(analog-speaker), but speaker-test always routes to hdmi-audio sink,
as a result, speaker-test can't output sound anymore unless we
replug a monitor with audio capability then the speaker-test output
from hdmi-audio again.
10. if we want the speaker-test to route to analog-speaker, two ways:
run pacmd move-sink-input or plug a monitor, after two audio devices
(hdmi audio and speaker) show up in the sound-setting, select
analog-speaker manually.

This issue only happens on the laptops with 2 audio cards, analog
devices on one card, hdmi audio on the other card. This kind of laptops
are very common, like I+A (Intel graphic + Amd Graphic), I+N(Intel +
Nvidia), and A AMD.

This issue will not happen on the laptops with only Intel graphic card,
since both analog and hdmi audio belong to one sound card. When hdmi
monitor is unplugged, the hdmi sink will be removed from PA, then all
sink-inputs will route to the only left sink: analog-sink.

This issue will not happen on BT or USB audio. Unlike hdmi audio, BT and
USB audio cards will be removed totally from PA when they are
unpluged/unconnected, so they don't have this issue as well.

The root cause of this issue is although the hdmi monitor is unplugged,
the hdmi-sink still exists, and sink-input is selected by user to bind
to this sink, so the pa doesn't care about if this sink has valid port
or not, it bind the sink-input to this sink unconditionally.

Maybe we could improve it like this: if the user selected sink only has
available_no ports, the pa will switch all sink-inputs of this sink to
other sinks (like default_sink) temporarily, once the selected sink has
availble ports, all sink-inputs switch back to this sink.

Any good ideas?

Thanks,

Hui.
Hui Wang
2018-09-30 08:53:13 UTC
Permalink
The tentative fix of this problem like this:

When a port is unplugged, it is caught by
module-switch-on-port-available.c, here we check if the sink of this
port is default_sink or not, if it is default_sink, it means the sink of
this port is still the highest priority one, no need to move
sink-inputs, otherwise, try to move all sink-inputs of this sink to
default_sink temporarily.

To restore the sink-inputs to its original sink, it depends on
module-stream-restore.c, but we don't let it restore unconditionally, if
the target sink has at least one port with avaialbe_yes/unknow, let it
restore.

So supposing one sink has speaker, the other sink has hdmi-audio, when
unplugging the hdmi cable, the audio will route to speaker, after
plugging the hdmi cable again, when app build new sink-input, it will
restore the sound to original sink.




diff --git a/src/modules/module-stream-restore.c
b/src/modules/module-stream-restore.c
index 228e9e4..2dd825f 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -1424,6 +1424,7 @@ static void subscribe_callback(pa_core *c,
pa_subscription_event_type_t t, uint3
 static pa_hook_result_t sink_input_new_hook_callback(pa_core *c,
pa_sink_input_new_data *new_data, struct userdata *u) {
     char *name;
     struct entry *e;
+    bool good = 0;

     pa_assert(c);
     pa_assert(new_data);
@@ -1450,6 +1451,21 @@ static pa_hook_result_t
sink_input_new_hook_callback(pa_core *c, pa_sink_input_n
                 s = pa_idxset_first(card->sinks, NULL);
         }

+       /* if all ports on this sink are all available_no, we don't set
this sink temporarily */
+       if (s) {
+         pa_device_port *i;
+          void *state_p;
+         PA_HASHMAP_FOREACH(i, s->ports, state_p) {
+           if (i->available != PA_AVAILABLE_NO) {
+             good = 1;
+             break;
+           }
+         }
+       }
+
+       if (!good)
+         s = NULL;
+
         /* It might happen that a stream and a sink are set up at the
            same time, in which case we want to make sure we don't
            interfere with that */
diff --git a/src/modules/module-switch-on-port-available.c
b/src/modules/module-switch-on-port-available.c
index 321db36..acd3252 100644
--- a/src/modules/module-switch-on-port-available.c
+++ b/src/modules/module-switch-on-port-available.c
@@ -272,6 +272,63 @@ static void switch_from_port(pa_device_port *port) {
         switch_to_port(best_port);
 }

+/* This function refers to sink_put_hook_callback() in the
module-switch-on-connect.c */
+static void move_input_to_default_sink(pa_core *c, pa_sink *ori_sink,
pa_sink *new_sink)
+{
+    pa_sink_input *i;
+    uint32_t idx;
+
+    /* Now move all old inputs over */
+    if (pa_idxset_size(ori_sink->inputs) <= 0) {
+       pa_log_debug("No sink inputs to move away.");
+       return;
+    }
+
+    PA_IDXSET_FOREACH(i, ori_sink->inputs, idx) {
+      /* don't check i->save_sink here, since we have to move input
temporarily */
+       if (!PA_SINK_INPUT_IS_LINKED(i->state))
+           continue;
+
+       if (pa_sink_input_move_to(i, new_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)),
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);
+    }
+}
+
+static void check_and_move_sink_inputs_to_default_sink(pa_core *c,
pa_device_port *port)
+{
+    struct port_pointers pp = find_port_pointers(port);
+    pa_sink *def_sink, *p_sink = pp.sink;
+
+    switch (port->direction) {
+    case PA_DIRECTION_OUTPUT:
+       def_sink = c->default_sink;
+
+       /* check if there is better sinks to move to, before here,the
default_sink is already
+           re-selected when the port is changing unavailble, if p_sink
equals default_sink,
+          it means there is no better sinks to replace the sink
containing this port */
+       if (p_sink != def_sink) {
+           void *state_p;
+           pa_device_port *i;
+
+           /* check if all ports on this sink are available_no, if not,
don't need to move the input */
+           PA_HASHMAP_FOREACH(i, p_sink->ports, state_p) {
+             if (i->available != PA_AVAILABLE_NO)
+               return;
+           }
+
+           /* now the default sink is the best sink already */
+           move_input_to_default_sink(c, pp.sink, def_sink);
+       }
+       break;
+
+    case PA_DIRECTION_INPUT:
+       break;
+    }
+}

 static pa_hook_result_t port_available_hook_callback(pa_core *c,
pa_device_port *port, void* userdata) {
     pa_assert(port);
@@ -295,6 +352,7 @@ static pa_hook_result_t
port_available_hook_callback(pa_core *c, pa_device_port
         break;
     case PA_AVAILABLE_NO:
         switch_from_port(port);
+       check_and_move_sink_inputs_to_default_sink(c, port);
         break;
     default:
         break;
Post by Hui Wang
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/579
Recently we found a weird issue on many laptops with the ubuntu 18.04,
it uses the pulseaudio-11.1 (I guess the PA of the latest version also
1. boot the system up without plugging a hdmi monitor
2. run an audio app to play sound (e.g. $speaker-test)
3. the sound outputs from analog-speaker
4. plug a monitor with audio capability (through DP or HDMI port)
5. the sound still outputs from analog-speaker
6. open sound-setting (gnome-control-center --> choose sound), you will
   see two output devies: speaker and HDMI audio
7. choose HDMI audio, the sound will switch to HDIM audio from speaker
   (pa will remember speaker-test prefer to use hdmi-audio sink)
8. unplug the monitor, the default-sink is switching to analog-speaker,
   but the sound of speaker-test still route to hdmi-audio sink
9. run other sound apps, they all route sound to default sink
   (analog-speaker), but speaker-test always routes to hdmi-audio sink,
   as a result, speaker-test can't output sound anymore unless we
   replug a monitor with audio capability then the speaker-test output
   from hdmi-audio again.
   run pacmd move-sink-input or plug a monitor, after two audio devices
   (hdmi audio and speaker) show up in the sound-setting, select
   analog-speaker manually.
This issue only happens on the laptops with 2 audio cards, analog
devices on one card, hdmi audio on the other card. This kind of
laptops are very common, like I+A (Intel graphic + Amd Graphic),
I+N(Intel + Nvidia), and A AMD.
This issue will not happen on the laptops with only Intel graphic
card, since both analog and hdmi audio belong to one sound card. When
hdmi monitor is unplugged, the hdmi sink will be removed from PA, then
all sink-inputs will route to the only left sink: analog-sink.
This issue will not happen on BT or USB audio. Unlike hdmi audio, BT
and USB audio cards will be removed totally from PA when they are
unpluged/unconnected, so they don't have this issue as well.
The root cause of this issue is although the hdmi monitor is
unplugged, the hdmi-sink still exists, and sink-input is selected by
user to bind to this sink, so the pa doesn't care about if this sink
has valid port or not, it bind the sink-input to this sink
unconditionally.
Maybe we could improve it like this: if the user selected sink only
has available_no ports, the pa will switch all sink-inputs of this
sink to other sinks (like default_sink) temporarily, once the selected
sink has availble ports, all sink-inputs switch back to this sink.
Any good ideas?
Thanks,
Hui.
_______________________________________________
pulseaudio-discuss mailing list
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Tanu Kaskinen
2018-09-30 10:30:42 UTC
Permalink
Post by Hui Wang
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/579
Recently we found a weird issue on many laptops with the ubuntu 18.04,
it uses the pulseaudio-11.1 (I guess the PA of the latest version also
1. boot the system up without plugging a hdmi monitor
2. run an audio app to play sound (e.g. $speaker-test)
3. the sound outputs from analog-speaker
4. plug a monitor with audio capability (through DP or HDMI port)
5. the sound still outputs from analog-speaker
6. open sound-setting (gnome-control-center --> choose sound), you will
see two output devies: speaker and HDMI audio
7. choose HDMI audio, the sound will switch to HDIM audio from speaker
(pa will remember speaker-test prefer to use hdmi-audio sink)
8. unplug the monitor, the default-sink is switching to analog-speaker,
but the sound of speaker-test still route to hdmi-audio sink
9. run other sound apps, they all route sound to default sink
(analog-speaker), but speaker-test always routes to hdmi-audio sink,
as a result, speaker-test can't output sound anymore unless we
replug a monitor with audio capability then the speaker-test output
from hdmi-audio again.
run pacmd move-sink-input or plug a monitor, after two audio devices
(hdmi audio and speaker) show up in the sound-setting, select
analog-speaker manually.
This issue only happens on the laptops with 2 audio cards, analog
devices on one card, hdmi audio on the other card. This kind of laptops
are very common, like I+A (Intel graphic + Amd Graphic), I+N(Intel +
Nvidia), and A AMD.
This issue will not happen on the laptops with only Intel graphic card,
since both analog and hdmi audio belong to one sound card. When hdmi
monitor is unplugged, the hdmi sink will be removed from PA, then all
sink-inputs will route to the only left sink: analog-sink.
This issue will not happen on BT or USB audio. Unlike hdmi audio, BT and
USB audio cards will be removed totally from PA when they are
unpluged/unconnected, so they don't have this issue as well.
The root cause of this issue is although the hdmi monitor is unplugged,
the hdmi-sink still exists, and sink-input is selected by user to bind
to this sink, so the pa doesn't care about if this sink has valid port
or not, it bind the sink-input to this sink unconditionally.
Maybe we could improve it like this: if the user selected sink only has
available_no ports, the pa will switch all sink-inputs of this sink to
other sinks (like default_sink) temporarily, once the selected sink has
availble ports, all sink-inputs switch back to this sink.
Any good ideas?
The plan has been to do the following (but I haven't found the time to
implement it):

Streams currently have a "save_sink" flag that tells whether the
current sink should be remembered and restored by module-stream-
restore. That flag should be replaced with a "preferred_sink" string
that is set when the user moves the stream. module-stream-restore
should remember and restore that string.

When the user moves a stream to the current default sink, the
"preferred_sink" string should be set to NULL and module-stream-restore
should clear the routing for that stream in the stream database. From
that point on the stream will be always routed to the default sink.

When a stream is created, module-stream-restore should set the
"preferred_sink" string and if that sink exists, the core should set
that sink as the initial routing for the new stream.

When the default sink changes, the streams from the old default sink
should be moved to the new default sink, unless the "preferred_sink"
string is set to the old default sink and the active port of the old
default sink is not unavailable. This should be done by the core.

When the active port of a sink becomes unavailable, all streams from
that sink should be moved to the default sink. This should be done by
the core.

When a new sink appears or 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. This should be
done by the core.

As a result, module-stream-restore doesn't need to move streams any
more, it only needs to manage the "preferred_sink" variables. Some
other modules can perhaps be simplified as well.

The same logic should of course be implemented for capture streams as
well.

Would you be willing to implement this?
--
Tanu

https://www.patreon.com/tanuk
https://liberapay.com/tanuk
Hui Wang
2018-10-01 02:18:53 UTC
Permalink
Post by Tanu Kaskinen
Post by Hui Wang
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/579
Recently we found a weird issue on many laptops with the ubuntu 18.04,
it uses the pulseaudio-11.1 (I guess the PA of the latest version also
1. boot the system up without plugging a hdmi monitor
2. run an audio app to play sound (e.g. $speaker-test)
3. the sound outputs from analog-speaker
4. plug a monitor with audio capability (through DP or HDMI port)
5. the sound still outputs from analog-speaker
6. open sound-setting (gnome-control-center --> choose sound), you will
see two output devies: speaker and HDMI audio
7. choose HDMI audio, the sound will switch to HDIM audio from speaker
(pa will remember speaker-test prefer to use hdmi-audio sink)
8. unplug the monitor, the default-sink is switching to analog-speaker,
but the sound of speaker-test still route to hdmi-audio sink
9. run other sound apps, they all route sound to default sink
(analog-speaker), but speaker-test always routes to hdmi-audio sink,
as a result, speaker-test can't output sound anymore unless we
replug a monitor with audio capability then the speaker-test output
from hdmi-audio again.
run pacmd move-sink-input or plug a monitor, after two audio devices
(hdmi audio and speaker) show up in the sound-setting, select
analog-speaker manually.
This issue only happens on the laptops with 2 audio cards, analog
devices on one card, hdmi audio on the other card. This kind of laptops
are very common, like I+A (Intel graphic + Amd Graphic), I+N(Intel +
Nvidia), and A AMD.
This issue will not happen on the laptops with only Intel graphic card,
since both analog and hdmi audio belong to one sound card. When hdmi
monitor is unplugged, the hdmi sink will be removed from PA, then all
sink-inputs will route to the only left sink: analog-sink.
This issue will not happen on BT or USB audio. Unlike hdmi audio, BT and
USB audio cards will be removed totally from PA when they are
unpluged/unconnected, so they don't have this issue as well.
The root cause of this issue is although the hdmi monitor is unplugged,
the hdmi-sink still exists, and sink-input is selected by user to bind
to this sink, so the pa doesn't care about if this sink has valid port
or not, it bind the sink-input to this sink unconditionally.
Maybe we could improve it like this: if the user selected sink only has
available_no ports, the pa will switch all sink-inputs of this sink to
other sinks (like default_sink) temporarily, once the selected sink has
availble ports, all sink-inputs switch back to this sink.
Any good ideas?
The plan has been to do the following (but I haven't found the time to
Streams currently have a "save_sink" flag that tells whether the
current sink should be remembered and restored by module-stream-
restore. That flag should be replaced with a "preferred_sink" string
that is set when the user moves the stream. module-stream-restore
should remember and restore that string.
When the user moves a stream to the current default sink, the
"preferred_sink" string should be set to NULL and module-stream-restore
should clear the routing for that stream in the stream database. From
that point on the stream will be always routed to the default sink.
When a stream is created, module-stream-restore should set the
"preferred_sink" string and if that sink exists, the core should set
that sink as the initial routing for the new stream.
When the default sink changes, the streams from the old default sink
should be moved to the new default sink, unless the "preferred_sink"
string is set to the old default sink and the active port of the old
default sink is not unavailable. This should be done by the core.
When the active port of a sink becomes unavailable, all streams from
that sink should be moved to the default sink. This should be done by
the core.
When a new sink appears or 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. This should be
done by the core.
As a result, module-stream-restore doesn't need to move streams any
more, it only needs to manage the "preferred_sink" variables. Some
other modules can perhaps be simplified as well.
The same logic should of course be implemented for capture streams as
well.
Would you be willing to implement this?
Got it, I will take some time to understand your plan first, then have a
try to implement it.

Thanks,

Hui.
Tanu Kaskinen
2018-10-02 09:49:13 UTC
Permalink
Post by Hui Wang
Post by Tanu Kaskinen
Post by Hui Wang
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/579
Recently we found a weird issue on many laptops with the ubuntu 18.04,
it uses the pulseaudio-11.1 (I guess the PA of the latest version also
1. boot the system up without plugging a hdmi monitor
2. run an audio app to play sound (e.g. $speaker-test)
3. the sound outputs from analog-speaker
4. plug a monitor with audio capability (through DP or HDMI port)
5. the sound still outputs from analog-speaker
6. open sound-setting (gnome-control-center --> choose sound), you will
see two output devies: speaker and HDMI audio
7. choose HDMI audio, the sound will switch to HDIM audio from speaker
(pa will remember speaker-test prefer to use hdmi-audio sink)
8. unplug the monitor, the default-sink is switching to analog-speaker,
but the sound of speaker-test still route to hdmi-audio sink
9. run other sound apps, they all route sound to default sink
(analog-speaker), but speaker-test always routes to hdmi-audio sink,
as a result, speaker-test can't output sound anymore unless we
replug a monitor with audio capability then the speaker-test output
from hdmi-audio again.
run pacmd move-sink-input or plug a monitor, after two audio devices
(hdmi audio and speaker) show up in the sound-setting, select
analog-speaker manually.
This issue only happens on the laptops with 2 audio cards, analog
devices on one card, hdmi audio on the other card. This kind of laptops
are very common, like I+A (Intel graphic + Amd Graphic), I+N(Intel +
Nvidia), and A AMD.
This issue will not happen on the laptops with only Intel graphic card,
since both analog and hdmi audio belong to one sound card. When hdmi
monitor is unplugged, the hdmi sink will be removed from PA, then all
sink-inputs will route to the only left sink: analog-sink.
This issue will not happen on BT or USB audio. Unlike hdmi audio, BT and
USB audio cards will be removed totally from PA when they are
unpluged/unconnected, so they don't have this issue as well.
The root cause of this issue is although the hdmi monitor is unplugged,
the hdmi-sink still exists, and sink-input is selected by user to bind
to this sink, so the pa doesn't care about if this sink has valid port
or not, it bind the sink-input to this sink unconditionally.
Maybe we could improve it like this: if the user selected sink only has
available_no ports, the pa will switch all sink-inputs of this sink to
other sinks (like default_sink) temporarily, once the selected sink has
availble ports, all sink-inputs switch back to this sink.
Any good ideas?
The plan has been to do the following (but I haven't found the time to
Streams currently have a "save_sink" flag that tells whether the
current sink should be remembered and restored by module-stream-
restore. That flag should be replaced with a "preferred_sink" string
that is set when the user moves the stream. module-stream-restore
should remember and restore that string.
When the user moves a stream to the current default sink, the
"preferred_sink" string should be set to NULL and module-stream-restore
should clear the routing for that stream in the stream database. From
that point on the stream will be always routed to the default sink.
When a stream is created, module-stream-restore should set the
"preferred_sink" string and if that sink exists, the core should set
that sink as the initial routing for the new stream.
When the default sink changes, the streams from the old default sink
should be moved to the new default sink, unless the "preferred_sink"
string is set to the old default sink and the active port of the old
default sink is not unavailable. This should be done by the core.
When the active port of a sink becomes unavailable, all streams from
that sink should be moved to the default sink. This should be done by
the core.
When a new sink appears or 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. This should be
done by the core.
As a result, module-stream-restore doesn't need to move streams any
more, it only needs to manage the "preferred_sink" variables. Some
other modules can perhaps be simplified as well.
The same logic should of course be implemented for capture streams as
well.
Would you be willing to implement this?
Got it, I will take some time to understand your plan first, then have a
try to implement it.
Maybe this rephrasing will help with understanding, maybe not:

The idea is to store the preferred routing in the core pa_sink_input
struct instead of hiding that information in module-stream-restore. The
core should then take care to ensure that streams are always routed to
their preferred sinks, or if the preferred sink is not set or not
available, then to the default sink.

There are some exceptions:

If a sink's active port is unavailable, no streams should be routed to
it, unless it's the default sink (and it shouldn't be the default sink
unless all sinks are similarly unavailable). [1]

An application may request a particular sink when it creates a stream.
The request should be honored, but the preferred_sink variable should
not be affected by the application request. The requested initial
routing should be treated as a temporary override.

Some policy modules may move streams temporarily to a sink that is
neither the default sink nor the stream's preferred sink. For example,
module-allow-passthrough creates a null sink for streams that are moved
away from the "main sink" when a passthrough stream needs to access the
main sink. Those policy modules need to continue working.


[1] I'm afraid this requires us to provide a way to disable jack
detection, because on some hardware the jack detection doesn't work
properly, and ports are marked as unavailable when they shouldn't be.
If a port is incorrectly marked as unavailable, the proposed logic
makes it impossible to play anything to it. So this is some extra
work... Disabling jack detection could be implemented as an argument to
module-udev-detect (and module-alsa-card) that would affect all ports
on all alsa cards, but it would be better to have a configuration file
(I'm thinking /etc/pulse/alsa.conf) where the jack detection could be
disabled on per-card, per-port and/or per-jack-element basis.
--
Tanu

https://www.patreon.com/tanuk
https://liberapay.com/tanuk
Georg Chini
2018-10-02 10:50:11 UTC
Permalink
Post by Tanu Kaskinen
Post by Hui Wang
Post by Tanu Kaskinen
Post by Hui Wang
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/579
Recently we found a weird issue on many laptops with the ubuntu 18.04,
it uses the pulseaudio-11.1 (I guess the PA of the latest version also
1. boot the system up without plugging a hdmi monitor
2. run an audio app to play sound (e.g. $speaker-test)
3. the sound outputs from analog-speaker
4. plug a monitor with audio capability (through DP or HDMI port)
5. the sound still outputs from analog-speaker
6. open sound-setting (gnome-control-center --> choose sound), you will
see two output devies: speaker and HDMI audio
7. choose HDMI audio, the sound will switch to HDIM audio from speaker
(pa will remember speaker-test prefer to use hdmi-audio sink)
8. unplug the monitor, the default-sink is switching to analog-speaker,
but the sound of speaker-test still route to hdmi-audio sink
9. run other sound apps, they all route sound to default sink
(analog-speaker), but speaker-test always routes to hdmi-audio sink,
as a result, speaker-test can't output sound anymore unless we
replug a monitor with audio capability then the speaker-test output
from hdmi-audio again.
run pacmd move-sink-input or plug a monitor, after two audio devices
(hdmi audio and speaker) show up in the sound-setting, select
analog-speaker manually.
This issue only happens on the laptops with 2 audio cards, analog
devices on one card, hdmi audio on the other card. This kind of laptops
are very common, like I+A (Intel graphic + Amd Graphic), I+N(Intel +
Nvidia), and A AMD.
This issue will not happen on the laptops with only Intel graphic card,
since both analog and hdmi audio belong to one sound card. When hdmi
monitor is unplugged, the hdmi sink will be removed from PA, then all
sink-inputs will route to the only left sink: analog-sink.
This issue will not happen on BT or USB audio. Unlike hdmi audio, BT and
USB audio cards will be removed totally from PA when they are
unpluged/unconnected, so they don't have this issue as well.
The root cause of this issue is although the hdmi monitor is unplugged,
the hdmi-sink still exists, and sink-input is selected by user to bind
to this sink, so the pa doesn't care about if this sink has valid port
or not, it bind the sink-input to this sink unconditionally.
Maybe we could improve it like this: if the user selected sink only has
available_no ports, the pa will switch all sink-inputs of this sink to
other sinks (like default_sink) temporarily, once the selected sink has
availble ports, all sink-inputs switch back to this sink.
Any good ideas?
The plan has been to do the following (but I haven't found the time to
Streams currently have a "save_sink" flag that tells whether the
current sink should be remembered and restored by module-stream-
restore. That flag should be replaced with a "preferred_sink" string
that is set when the user moves the stream. module-stream-restore
should remember and restore that string.
When the user moves a stream to the current default sink, the
"preferred_sink" string should be set to NULL and module-stream-restore
should clear the routing for that stream in the stream database. From
that point on the stream will be always routed to the default sink.
When a stream is created, module-stream-restore should set the
"preferred_sink" string and if that sink exists, the core should set
that sink as the initial routing for the new stream.
When the default sink changes, the streams from the old default sink
should be moved to the new default sink, unless the "preferred_sink"
string is set to the old default sink and the active port of the old
default sink is not unavailable. This should be done by the core.
When the active port of a sink becomes unavailable, all streams from
that sink should be moved to the default sink. This should be done by
the core.
When a new sink appears or 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. This should be
done by the core.
As a result, module-stream-restore doesn't need to move streams any
more, it only needs to manage the "preferred_sink" variables. Some
other modules can perhaps be simplified as well.
The same logic should of course be implemented for capture streams as
well.
Would you be willing to implement this?
Got it, I will take some time to understand your plan first, then have a
try to implement it.
The idea is to store the preferred routing in the core pa_sink_input
struct instead of hiding that information in module-stream-restore. The
core should then take care to ensure that streams are always routed to
their preferred sinks, or if the preferred sink is not set or not
available, then to the default sink.
If a sink's active port is unavailable, no streams should be routed to
it, unless it's the default sink (and it shouldn't be the default sink
unless all sinks are similarly unavailable). [1]
An application may request a particular sink when it creates a stream.
The request should be honored, but the preferred_sink variable should
not be affected by the application request. The requested initial
routing should be treated as a temporary override.
Some policy modules may move streams temporarily to a sink that is
neither the default sink nor the stream's preferred sink. For example,
module-allow-passthrough creates a null sink for streams that are moved
away from the "main sink" when a passthrough stream needs to access the
main sink. Those policy modules need to continue working.
[1] I'm afraid this requires us to provide a way to disable jack
detection, because on some hardware the jack detection doesn't work
properly, and ports are marked as unavailable when they shouldn't be.
If a port is incorrectly marked as unavailable, the proposed logic
makes it impossible to play anything to it. So this is some extra
work... Disabling jack detection could be implemented as an argument to
module-udev-detect (and module-alsa-card) that would affect all ports
on all alsa cards, but it would be better to have a configuration file
(I'm thinking /etc/pulse/alsa.conf) where the jack detection could be
disabled on per-card, per-port and/or per-jack-element basis.
There are already some patches to enable/disable jack detection,
but they are using the messaging interface which is not yet in the
tree.
Hui Wang
2018-10-03 02:41:39 UTC
Permalink
Post by Georg Chini
Post by Tanu Kaskinen
Post by Hui Wang
Post by Tanu Kaskinen
Post by Hui Wang
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/579
Recently we found a weird issue on many laptops with the ubuntu 18.04,
it uses the pulseaudio-11.1 (I guess the PA of the latest version also
   1. boot the system up without plugging a hdmi monitor
   2. run an audio app to play sound (e.g. $speaker-test)
   3. the sound outputs from analog-speaker
   4. plug a monitor with audio capability (through DP or HDMI port)
   5. the sound still outputs from analog-speaker
   6. open sound-setting (gnome-control-center --> choose sound),
you will
      see two output devies: speaker and HDMI audio
   7. choose HDMI audio, the sound will switch to HDIM audio from
speaker
      (pa will remember speaker-test prefer to use hdmi-audio sink)
   8. unplug the monitor, the default-sink is switching to
analog-speaker,
      but the sound of speaker-test still route to hdmi-audio sink
   9. run other sound apps, they all route sound to default sink
      (analog-speaker), but speaker-test always routes to
hdmi-audio sink,
      as a result, speaker-test can't output sound anymore unless we
      replug a monitor with audio capability then the speaker-test
output
      from hdmi-audio again.
      run pacmd move-sink-input or plug a monitor, after two audio
devices
      (hdmi audio and speaker) show up in the sound-setting, select
      analog-speaker manually.
This issue only happens on the laptops with 2 audio cards, analog
devices on one card, hdmi audio on the other card. This kind of laptops
are very common, like I+A (Intel graphic + Amd Graphic), I+N(Intel +
Nvidia), and A AMD.
This issue will not happen on the laptops with only Intel graphic card,
since both analog and hdmi audio belong to one sound card. When hdmi
monitor is unplugged, the hdmi sink will be removed from PA, then all
sink-inputs will route to the only left sink: analog-sink.
This issue will not happen on BT or USB audio. Unlike hdmi audio, BT and
USB audio cards will be removed totally from PA when they are
unpluged/unconnected, so they don't have this issue as well.
The root cause of this issue is although the hdmi monitor is unplugged,
the hdmi-sink still exists, and sink-input is selected by user to bind
to this sink, so the pa doesn't care about if this sink has valid port
or not, it bind the sink-input to this sink unconditionally.
Maybe we could improve it like this: if the user selected sink only has
available_no ports, the pa will switch all sink-inputs of this sink to
other sinks (like default_sink) temporarily, once the selected sink has
availble ports, all sink-inputs switch back to this sink.
Any good ideas?
The plan has been to do the following (but I haven't found the time to
Streams currently have a "save_sink" flag that tells whether the
current sink should be remembered and restored by module-stream-
restore. That flag should be replaced with a "preferred_sink" string
that is set when the user moves the stream. module-stream-restore
should remember and restore that string.
When the user moves a stream to the current default sink, the
"preferred_sink" string should be set to NULL and
module-stream-restore
should clear the routing for that stream in the stream database. From
that point on the stream will be always routed to the default sink.
When a stream is created, module-stream-restore should set the
"preferred_sink" string and if that sink exists, the core should set
that sink as the initial routing for the new stream.
When the default sink changes, the streams from the old default sink
should be moved to the new default sink, unless the "preferred_sink"
string is set to the old default sink and the active port of the old
default sink is not unavailable. This should be done by the core.
When the active port of a sink becomes unavailable, all streams from
that sink should be moved to the default sink. This should be done by
the core.
When a new sink appears or 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. This should be
done by the core.
As a result, module-stream-restore doesn't need to move streams any
more, it only needs to manage the "preferred_sink" variables. Some
other modules can perhaps be simplified as well.
The same logic should of course be implemented for capture streams as
well.
Would you be willing to implement this?
Got it, I will take some time to understand your plan first, then have a
try to implement it.
The idea is to store the preferred routing in the core pa_sink_input
struct instead of hiding that information in module-stream-restore. The
core should then take care to ensure that streams are always routed to
their preferred sinks, or if the preferred sink is not set or not
available, then to the default sink.
If a sink's active port is unavailable, no streams should be routed to
it, unless it's the default sink (and it shouldn't be the default sink
unless all sinks are similarly unavailable). [1]
An application may request a particular sink when it creates a stream.
The request should be honored, but the preferred_sink variable should
not be affected by the application request. The requested initial
routing should be treated as a temporary override.
Some policy modules may move streams temporarily to a sink that is
neither the default sink nor the stream's preferred sink. For example,
module-allow-passthrough creates a null sink for streams that are moved
away from the "main sink" when a passthrough stream needs to access the
main sink. Those policy modules need to continue working.
[1] I'm afraid this requires us to provide a way to disable jack
detection, because on some hardware the jack detection doesn't work
properly, and ports are marked as unavailable when they shouldn't be.
If a port is incorrectly marked as unavailable, the proposed logic
makes it impossible to play anything to it. So this is some extra
work... Disabling jack detection could be implemented as an argument to
module-udev-detect (and module-alsa-card) that would affect all ports
on all alsa cards, but it would be better to have a configuration file
(I'm thinking /etc/pulse/alsa.conf) where the jack detection could be
disabled on per-card, per-port and/or per-jack-element basis.
Yes, configurable enable/disable detection on per-card, per-port and/or
per-jack-element basis is a better idea.
Post by Georg Chini
There are already some patches to enable/disable jack detection,
but they are using the messaging interface which is not yet in the
tree.
Loading...