mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2026-02-18 22:05:37 -05:00
alsa: fix infinite loop with Intel HDMI LPE
The Intel HDMI LPE driver works in a peculiar way when the HDMI cable is not plugged in: any written audio is immediately discarded and underrun is reported. That resulted in an infinite loop, because PulseAudio tried to keep the buffer filled, which was futile since the written audio was immediately consumed/discarded. This patch adds special handling for the LPE driver: if the active port of the sink is unavailable, the sink suspends itself. A new suspend cause is added: PA_SUSPEND_UNAVAILABLE. BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=100488
This commit is contained in:
parent
d9624e0382
commit
94fc586c01
4 changed files with 58 additions and 0 deletions
|
|
@ -426,6 +426,22 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
|
|||
if (tp->avail == PA_AVAILABLE_NO)
|
||||
pa_device_port_set_available(tp->port, tp->avail);
|
||||
|
||||
for (tp = tports; tp->port; tp++) {
|
||||
pa_alsa_port_data *data;
|
||||
pa_sink *sink;
|
||||
uint32_t idx;
|
||||
|
||||
data = PA_DEVICE_PORT_DATA(tp->port);
|
||||
|
||||
if (!data->suspend_when_unavailable)
|
||||
continue;
|
||||
|
||||
PA_IDXSET_FOREACH(sink, u->core->sinks, idx) {
|
||||
if (sink->active_port == tp->port)
|
||||
pa_sink_suspend(sink, tp->avail == PA_AVAILABLE_NO, PA_SUSPEND_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update profile availabilities. The logic could be improved; for now we
|
||||
* only set obviously unavailable profiles (those that contain only
|
||||
* unavailable ports) to PA_AVAILABLE_NO and all others to
|
||||
|
|
@ -836,6 +852,24 @@ int pa__init(pa_module *m) {
|
|||
goto fail;
|
||||
}
|
||||
|
||||
/* The Intel HDMI LPE driver needs some special handling. When the HDMI
|
||||
* cable is not plugged in, trying to play audio doesn't work. Any written
|
||||
* audio is immediately discarded and an underrun is reported, and that
|
||||
* results in an infinite loop of "fill buffer, handle underrun". To work
|
||||
* around this issue, the suspend_when_unavailable flag is used to stop
|
||||
* playback when the HDMI cable is unplugged. */
|
||||
if (pa_safe_streq(pa_proplist_gets(data.proplist, "alsa.driver_name"), "snd_hdmi_lpe_audio")) {
|
||||
pa_device_port *port;
|
||||
void *state;
|
||||
|
||||
PA_HASHMAP_FOREACH(port, data.ports, state) {
|
||||
pa_alsa_port_data *port_data;
|
||||
|
||||
port_data = PA_DEVICE_PORT_DATA(port);
|
||||
port_data->suspend_when_unavailable = true;
|
||||
}
|
||||
}
|
||||
|
||||
u->card = pa_card_new(m->core, &data);
|
||||
pa_card_new_data_done(&data);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue