diff --git a/0001-alsa-fix-infinite-loop-with-Intel-HDMI-LPE.patch b/0001-alsa-fix-infinite-loop-with-Intel-HDMI-LPE.patch new file mode 100644 index 0000000..bef4f5c --- /dev/null +++ b/0001-alsa-fix-infinite-loop-with-Intel-HDMI-LPE.patch @@ -0,0 +1,131 @@ +From 94fc586c011537536cfb434376354699357af785 Mon Sep 17 00:00:00 2001 +From: Tanu Kaskinen +Date: Thu, 28 Dec 2017 12:09:17 +0200 +Subject: [PATCH] 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 +--- + src/modules/alsa/alsa-mixer.h | 1 + + src/modules/alsa/alsa-sink.c | 22 ++++++++++++++++++++++ + src/modules/alsa/module-alsa-card.c | 34 ++++++++++++++++++++++++++++++++++ + src/pulsecore/core.h | 1 + + 4 files changed, 58 insertions(+) + +--- a/src/modules/alsa/alsa-mixer.h ++++ b/src/modules/alsa/alsa-mixer.h +@@ -364,6 +364,7 @@ int pa_alsa_set_mixer_rtpoll(struct pa_a + struct pa_alsa_port_data { + pa_alsa_path *path; + pa_alsa_setting *setting; ++ bool suspend_when_unavailable; + }; + + void pa_alsa_add_ports(void *sink_or_source_new_data, pa_alsa_path_set *ps, pa_card *card); +--- a/src/modules/alsa/alsa-sink.c ++++ b/src/modules/alsa/alsa-sink.c +@@ -1513,6 +1513,11 @@ static int sink_set_port_cb(pa_sink *s, + s->set_volume(s); + } + ++ if (data->suspend_when_unavailable && p->available == PA_AVAILABLE_NO) ++ pa_sink_suspend(s, true, PA_SUSPEND_UNAVAILABLE); ++ else ++ pa_sink_suspend(s, false, PA_SUSPEND_UNAVAILABLE); ++ + return 0; + } + +@@ -2455,6 +2460,23 @@ pa_sink *pa_alsa_sink_new(pa_module *m, + if (profile_set) + pa_alsa_profile_set_free(profile_set); + ++ /* Suspend if necessary. FIXME: It would be better to start suspended, but ++ * that would require some core changes. It's possible to set ++ * pa_sink_new_data.suspend_cause, but that has to be done before the ++ * pa_sink_new() call, and we know if we need to suspend only after the ++ * pa_sink_new() call when the initial port has been chosen. Calling ++ * pa_sink_suspend() between pa_sink_new() and pa_sink_put() would ++ * otherwise work, but currently pa_sink_suspend() will crash if ++ * pa_sink_put() hasn't been called. */ ++ if (u->sink->active_port) { ++ pa_alsa_port_data *port_data; ++ ++ port_data = PA_DEVICE_PORT_DATA(u->sink->active_port); ++ ++ if (port_data->suspend_when_unavailable && u->sink->active_port->available == PA_AVAILABLE_NO) ++ pa_sink_suspend(u->sink, true, PA_SUSPEND_UNAVAILABLE); ++ } ++ + return u->sink; + + fail: +--- a/src/modules/alsa/module-alsa-card.c ++++ b/src/modules/alsa/module-alsa-card.c +@@ -427,6 +427,22 @@ static int report_jack_state(snd_mixer_e + 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 +@@ -837,6 +853,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); + +--- a/src/pulsecore/core.h ++++ b/src/pulsecore/core.h +@@ -34,6 +34,7 @@ typedef enum pa_suspend_cause { + PA_SUSPEND_SESSION = 8, /* Used by module-hal for mark inactive sessions */ + PA_SUSPEND_PASSTHROUGH = 16, /* Used to suspend monitor sources when the sink is in passthrough mode */ + PA_SUSPEND_INTERNAL = 32, /* This is used for short period server-internal suspends, such as for sample rate updates */ ++ PA_SUSPEND_UNAVAILABLE = 64, /* Used by device implementations that have to suspend when the device is unavailable */ + PA_SUSPEND_ALL = 0xFFFF /* Magic cause that can be used to resume forcibly */ + } pa_suspend_cause_t; + diff --git a/0002-alsa-mixer-add-hw_device_index-to-pa_alsa_mapping.patch b/0002-alsa-mixer-add-hw_device_index-to-pa_alsa_mapping.patch new file mode 100644 index 0000000..e7d7689 --- /dev/null +++ b/0002-alsa-mixer-add-hw_device_index-to-pa_alsa_mapping.patch @@ -0,0 +1,89 @@ +From 09ff3fca2fa9fe928990b3f0effeb1ddfbba0df1 Mon Sep 17 00:00:00 2001 +From: Tanu Kaskinen +Date: Sun, 8 Oct 2017 19:48:24 +0300 +Subject: [PATCH] alsa-mixer: add hw_device_index to pa_alsa_mapping + +We have so far assumed that HDMI always uses device indexes 3, 7, 8, 9, +10, 11, 12 and 13. These values are hardcoded in the path configuration. +The Intel HDMI LPE driver, however, uses different device numbering +scheme. Since the indexes aren't always the same, we need to query the +hw device index from ALSA. + +Later patches will use the queried index for HDMI jack detection and ELD +information reading. + +BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=100488 +--- + src/modules/alsa/alsa-mixer.c | 26 ++++++++++++++++++++++++++ + src/modules/alsa/alsa-mixer.h | 4 ++++ + 2 files changed, 30 insertions(+) + +--- a/src/modules/alsa/alsa-mixer.c ++++ b/src/modules/alsa/alsa-mixer.c +@@ -3504,6 +3504,7 @@ pa_alsa_mapping *pa_alsa_mapping_get(pa_ + pa_sample_spec_init(&m->sample_spec); + pa_channel_map_init(&m->channel_map); + m->proplist = pa_proplist_new(); ++ m->hw_device_index = -1; + + pa_hashmap_put(ps->mappings, m->name, m); + +@@ -4531,6 +4532,25 @@ static int add_profiles_to_probe( + return i; + } + ++static void mapping_query_hw_device(pa_alsa_mapping *mapping, snd_pcm_t *pcm) { ++ int r; ++ snd_pcm_info_t* pcm_info; ++ snd_pcm_info_alloca(&pcm_info); ++ ++ r = snd_pcm_info(pcm, pcm_info); ++ if (r < 0) { ++ pa_log("Mapping %s: snd_pcm_info() failed %s: ", mapping->name, pa_alsa_strerror(r)); ++ return; ++ } ++ ++ /* XXX: It's not clear what snd_pcm_info_get_device() does if the device is ++ * not backed by a hw device or if it's backed by multiple hw devices. We ++ * only use hw_device_index for HDMI devices, however, and for those the ++ * return value is expected to be always valid, so this shouldn't be a ++ * significant problem. */ ++ mapping->hw_device_index = snd_pcm_info_get_device(pcm_info); ++} ++ + void pa_alsa_profile_set_probe( + pa_alsa_profile_set *ps, + const char *dev_id, +@@ -4621,6 +4641,9 @@ void pa_alsa_profile_set_probe( + } + break; + } ++ ++ if (m->hw_device_index < 0) ++ mapping_query_hw_device(m, m->output_pcm); + } + + if (p->input_mappings && p->supported) +@@ -4642,6 +4665,9 @@ void pa_alsa_profile_set_probe( + } + break; + } ++ ++ if (m->hw_device_index < 0) ++ mapping_query_hw_device(m, m->input_pcm); + } + + last = p; +--- a/src/modules/alsa/alsa-mixer.h ++++ b/src/modules/alsa/alsa-mixer.h +@@ -275,6 +275,10 @@ struct pa_alsa_mapping { + bool exact_channels:1; + bool fallback:1; + ++ /* The "y" in "hw:x,y". This is set to -1 before the device index has been ++ * queried, or if the query failed. */ ++ int hw_device_index; ++ + /* Temporarily used during probing */ + snd_pcm_t *input_pcm; + snd_pcm_t *output_pcm; diff --git a/0003-alsa-mixer-autodetect-the-HDMI-jack-PCM-device.patch b/0003-alsa-mixer-autodetect-the-HDMI-jack-PCM-device.patch new file mode 100644 index 0000000..869b6d0 --- /dev/null +++ b/0003-alsa-mixer-autodetect-the-HDMI-jack-PCM-device.patch @@ -0,0 +1,263 @@ +From 67f11ff30177d40e408523bdce0eeff27b8e6f9b Mon Sep 17 00:00:00 2001 +From: Tanu Kaskinen +Date: Sun, 8 Oct 2017 19:48:25 +0300 +Subject: [PATCH] alsa-mixer: autodetect the HDMI jack PCM device + +This removes the need to hardcode the PCM device index in the HDMI jack +names. The hardcoded values don't work with the Intel HDMI LPE driver. + +BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=100488 +--- + src/modules/alsa/alsa-mixer.c | 53 +++++++++++++++-- + src/modules/alsa/alsa-mixer.h | 4 - + src/modules/alsa/alsa-sink.c | 2 + src/modules/alsa/alsa-source.c | 2 + src/modules/alsa/mixer/paths/analog-output.conf.common | 4 + + src/modules/alsa/mixer/paths/hdmi-output-0.conf | 3 + src/modules/alsa/mixer/paths/hdmi-output-1.conf | 3 + src/modules/alsa/mixer/paths/hdmi-output-2.conf | 3 + src/modules/alsa/mixer/paths/hdmi-output-3.conf | 3 + src/modules/alsa/mixer/paths/hdmi-output-4.conf | 3 + src/modules/alsa/mixer/paths/hdmi-output-5.conf | 3 + src/modules/alsa/mixer/paths/hdmi-output-6.conf | 3 + src/modules/alsa/mixer/paths/hdmi-output-7.conf | 3 + 13 files changed, 73 insertions(+), 16 deletions(-) + +--- a/src/modules/alsa/alsa-mixer.c ++++ b/src/modules/alsa/alsa-mixer.c +@@ -1812,12 +1812,31 @@ static int element_probe(pa_alsa_element + return 0; + } + +-static int jack_probe(pa_alsa_jack *j, snd_mixer_t *m) { ++static int jack_probe(pa_alsa_jack *j, pa_alsa_mapping *mapping, snd_mixer_t *m) { + bool has_control; + + pa_assert(j); + pa_assert(j->path); + ++ if (j->append_pcm_to_name) { ++ char *new_name; ++ ++ if (!mapping) { ++ /* This could also be an assertion, because this should never ++ * happen. At the time of writing, mapping can only be NULL when ++ * module-alsa-sink/source synthesizes a path, and those ++ * synthesized paths never have any jacks, so jack_probe() should ++ * never be called with a NULL mapping. */ ++ pa_log("Jack %s: append_pcm_to_name is set, but mapping is NULL. Can't use this jack.", j->name); ++ return -1; ++ } ++ ++ new_name = pa_sprintf_malloc("%s,pcm=%i Jack", j->name, mapping->hw_device_index); ++ pa_xfree(j->alsa_name); ++ j->alsa_name = new_name; ++ j->append_pcm_to_name = false; ++ } ++ + has_control = pa_alsa_mixer_find(m, j->alsa_name, 0) != NULL; + pa_alsa_jack_set_has_control(j, has_control); + +@@ -2326,6 +2345,30 @@ static int jack_parse_state(pa_config_pa + return 0; + } + ++static int jack_parse_append_pcm_to_name(pa_config_parser_state *state) { ++ pa_alsa_path *path; ++ pa_alsa_jack *jack; ++ int b; ++ ++ pa_assert(state); ++ ++ path = state->userdata; ++ if (!(jack = jack_get(path, state->section))) { ++ pa_log("[%s:%u] Option 'append_pcm_to_name' not expected in section '%s'", ++ state->filename, state->lineno, state->section); ++ return -1; ++ } ++ ++ b = pa_parse_boolean(state->rvalue); ++ if (b < 0) { ++ pa_log("[%s:%u] Invalid value for 'append_pcm_to_name': %s", state->filename, state->lineno, state->rvalue); ++ return -1; ++ } ++ ++ jack->append_pcm_to_name = b; ++ return 0; ++} ++ + static int element_set_option(pa_alsa_element *e, snd_mixer_t *m, int alsa_idx) { + snd_mixer_selem_id_t *sid; + snd_mixer_elem_t *me; +@@ -2533,6 +2576,7 @@ pa_alsa_path* pa_alsa_path_new(const cha + /* [Jack ...] */ + { "state.plugged", jack_parse_state, NULL, NULL }, + { "state.unplugged", jack_parse_state, NULL, NULL }, ++ { "append-pcm-to-name", jack_parse_append_pcm_to_name, NULL, NULL }, + + /* [Element ...] */ + { "switch", element_parse_switch, NULL, NULL }, +@@ -2745,7 +2789,7 @@ static void path_create_settings(pa_alsa + element_create_settings(p->elements, NULL); + } + +-int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, bool ignore_dB) { ++int pa_alsa_path_probe(pa_alsa_path *p, pa_alsa_mapping *mapping, snd_mixer_t *m, bool ignore_dB) { + pa_alsa_element *e; + pa_alsa_jack *j; + double min_dB[PA_CHANNEL_POSITION_MAX], max_dB[PA_CHANNEL_POSITION_MAX]; +@@ -2765,7 +2809,7 @@ int pa_alsa_path_probe(pa_alsa_path *p, + pa_log_debug("Probing path '%s'", p->name); + + PA_LLIST_FOREACH(j, p->jacks) { +- if (jack_probe(j, m) < 0) { ++ if (jack_probe(j, mapping, m) < 0) { + p->supported = false; + pa_log_debug("Probe of jack '%s' failed.", j->alsa_name); + return -1; +@@ -3967,9 +4011,8 @@ static void mapping_paths_probe(pa_alsa_ + } + + PA_HASHMAP_FOREACH(p, ps->paths, state) { +- if (pa_alsa_path_probe(p, mixer_handle, m->profile_set->ignore_dB) < 0) { ++ if (pa_alsa_path_probe(p, m, mixer_handle, m->profile_set->ignore_dB) < 0) + pa_hashmap_remove(ps->paths, p); +- } + } + + path_set_condense(ps, mixer_handle); +--- a/src/modules/alsa/alsa-mixer.h ++++ b/src/modules/alsa/alsa-mixer.h +@@ -171,6 +171,8 @@ struct pa_alsa_jack { + + pa_dynarray *ucm_devices; /* pa_alsa_ucm_device */ + pa_dynarray *ucm_hw_mute_devices; /* pa_alsa_ucm_device */ ++ ++ bool append_pcm_to_name; + }; + + pa_alsa_jack *pa_alsa_jack_new(pa_alsa_path *path, const char *name); +@@ -234,7 +236,7 @@ void pa_alsa_element_dump(pa_alsa_elemen + + pa_alsa_path *pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa_direction_t direction); + pa_alsa_path *pa_alsa_path_synthesize(const char *element, pa_alsa_direction_t direction); +-int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, bool ignore_dB); ++int pa_alsa_path_probe(pa_alsa_path *p, pa_alsa_mapping *mapping, snd_mixer_t *m, bool ignore_dB); + void pa_alsa_path_dump(pa_alsa_path *p); + int pa_alsa_path_get_volume(pa_alsa_path *p, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v); + int pa_alsa_path_get_mute(pa_alsa_path *path, snd_mixer_t *m, bool *muted); +--- a/src/modules/alsa/alsa-sink.c ++++ b/src/modules/alsa/alsa-sink.c +@@ -1917,7 +1917,7 @@ static void find_mixer(struct userdata * + if (!(u->mixer_path = pa_alsa_path_synthesize(element, PA_ALSA_DIRECTION_OUTPUT))) + goto fail; + +- if (pa_alsa_path_probe(u->mixer_path, u->mixer_handle, ignore_dB) < 0) ++ if (pa_alsa_path_probe(u->mixer_path, NULL, u->mixer_handle, ignore_dB) < 0) + goto fail; + + pa_log_debug("Probed mixer path %s:", u->mixer_path->name); +--- a/src/modules/alsa/alsa-source.c ++++ b/src/modules/alsa/alsa-source.c +@@ -1615,7 +1615,7 @@ static void find_mixer(struct userdata * + if (!(u->mixer_path = pa_alsa_path_synthesize(element, PA_ALSA_DIRECTION_INPUT))) + goto fail; + +- if (pa_alsa_path_probe(u->mixer_path, u->mixer_handle, ignore_dB) < 0) ++ if (pa_alsa_path_probe(u->mixer_path, NULL, u->mixer_handle, ignore_dB) < 0) + goto fail; + + pa_log_debug("Probed mixer path %s:", u->mixer_path->name); +--- a/src/modules/alsa/mixer/paths/analog-output.conf.common ++++ b/src/modules/alsa/mixer/paths/analog-output.conf.common +@@ -122,6 +122,10 @@ + ; # the required-any are present. + ; state.plugged = yes | no | unknown # Normally a plugged jack would mean the port becomes available, and an unplugged means it's + ; state.unplugged = yes | no | unknown # unavailable, but the port status can be overridden by specifying state.plugged and/or state.unplugged. ++; append-pcm-to-name = no | yes # Add ",pcm=N" to the jack name? N is the hw PCM device index. HDMI jacks have ++; # the PCM device index in their name, but different drivers use different ++; # numbering schemes, so we can't hardcode the full jack name in our configuration ++; # files. + + [Element PCM] + switch = mute +--- a/src/modules/alsa/mixer/paths/hdmi-output-0.conf ++++ b/src/modules/alsa/mixer/paths/hdmi-output-0.conf +@@ -6,5 +6,6 @@ eld-device = 3 + [Properties] + device.icon_name = video-display + +-[Jack HDMI/DP,pcm=3] ++[Jack HDMI/DP] ++append-pcm-to-name = yes + required = ignore +--- a/src/modules/alsa/mixer/paths/hdmi-output-1.conf ++++ b/src/modules/alsa/mixer/paths/hdmi-output-1.conf +@@ -6,5 +6,6 @@ eld-device = 7 + [Properties] + device.icon_name = video-display + +-[Jack HDMI/DP,pcm=7] ++[Jack HDMI/DP] ++append-pcm-to-name = yes + required = ignore +--- a/src/modules/alsa/mixer/paths/hdmi-output-2.conf ++++ b/src/modules/alsa/mixer/paths/hdmi-output-2.conf +@@ -6,5 +6,6 @@ eld-device = 8 + [Properties] + device.icon_name = video-display + +-[Jack HDMI/DP,pcm=8] ++[Jack HDMI/DP] ++append-pcm-to-name = yes + required = ignore +--- a/src/modules/alsa/mixer/paths/hdmi-output-3.conf ++++ b/src/modules/alsa/mixer/paths/hdmi-output-3.conf +@@ -6,5 +6,6 @@ eld-device = 9 + [Properties] + device.icon_name = video-display + +-[Jack HDMI/DP,pcm=9] ++[Jack HDMI/DP] ++append-pcm-to-name = yes + required = ignore +--- a/src/modules/alsa/mixer/paths/hdmi-output-4.conf ++++ b/src/modules/alsa/mixer/paths/hdmi-output-4.conf +@@ -6,5 +6,6 @@ eld-device = 10 + [Properties] + device.icon_name = video-display + +-[Jack HDMI/DP,pcm=10] ++[Jack HDMI/DP] ++append-pcm-to-name = yes + required = ignore +--- a/src/modules/alsa/mixer/paths/hdmi-output-5.conf ++++ b/src/modules/alsa/mixer/paths/hdmi-output-5.conf +@@ -6,5 +6,6 @@ eld-device = 11 + [Properties] + device.icon_name = video-display + +-[Jack HDMI/DP,pcm=11] ++[Jack HDMI/DP] ++append-pcm-to-name = yes + required = ignore +--- a/src/modules/alsa/mixer/paths/hdmi-output-6.conf ++++ b/src/modules/alsa/mixer/paths/hdmi-output-6.conf +@@ -6,5 +6,6 @@ eld-device = 12 + [Properties] + device.icon_name = video-display + +-[Jack HDMI/DP,pcm=12] ++[Jack HDMI/DP] ++append-pcm-to-name = yes + required = ignore +--- a/src/modules/alsa/mixer/paths/hdmi-output-7.conf ++++ b/src/modules/alsa/mixer/paths/hdmi-output-7.conf +@@ -6,5 +6,6 @@ eld-device = 13 + [Properties] + device.icon_name = video-display + +-[Jack HDMI/DP,pcm=13] ++[Jack HDMI/DP] ++append-pcm-to-name = yes + required = ignore diff --git a/0004-alsa-mixer-autodetect-the-ELD-device.patch b/0004-alsa-mixer-autodetect-the-ELD-device.patch new file mode 100644 index 0000000..a47074d --- /dev/null +++ b/0004-alsa-mixer-autodetect-the-ELD-device.patch @@ -0,0 +1,197 @@ +From 72fa468a45031ba4be4d24d70fddf282b5c9da66 Mon Sep 17 00:00:00 2001 +From: Tanu Kaskinen +Date: Sun, 8 Oct 2017 19:48:26 +0300 +Subject: [PATCH] alsa-mixer: autodetect the ELD device + +This removes the need to hardcode the ELD device index in the path +configuration. The hardcoded values don't work with the Intel HDMI LPE +driver. + +BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=100488 +--- + src/modules/alsa/alsa-mixer.c | 28 +++++++++++++++-- + src/modules/alsa/alsa-mixer.h | 1 + src/modules/alsa/mixer/paths/analog-output.conf.common | 8 +++- + src/modules/alsa/mixer/paths/hdmi-output-0.conf | 2 - + src/modules/alsa/mixer/paths/hdmi-output-1.conf | 2 - + src/modules/alsa/mixer/paths/hdmi-output-2.conf | 2 - + src/modules/alsa/mixer/paths/hdmi-output-3.conf | 2 - + src/modules/alsa/mixer/paths/hdmi-output-4.conf | 2 - + src/modules/alsa/mixer/paths/hdmi-output-5.conf | 2 - + src/modules/alsa/mixer/paths/hdmi-output-6.conf | 2 - + src/modules/alsa/mixer/paths/hdmi-output-7.conf | 2 - + 11 files changed, 41 insertions(+), 12 deletions(-) + +--- a/src/modules/alsa/alsa-mixer.c ++++ b/src/modules/alsa/alsa-mixer.c +@@ -2051,6 +2051,28 @@ static int element_parse_enumeration(pa_ + return 0; + } + ++static int parse_eld_device(pa_config_parser_state *state) { ++ pa_alsa_path *path; ++ uint32_t eld_device; ++ ++ path = state->userdata; ++ ++ if (pa_atou(state->rvalue, &eld_device) >= 0) { ++ path->autodetect_eld_device = false; ++ path->eld_device = eld_device; ++ return 0; ++ } ++ ++ if (pa_streq(state->rvalue, "auto")) { ++ path->autodetect_eld_device = true; ++ path->eld_device = -1; ++ return 0; ++ } ++ ++ pa_log("[%s:%u] Invalid value for option 'eld-device': %s", state->filename, state->lineno, state->rvalue); ++ return -1; ++} ++ + static int option_parse_priority(pa_config_parser_state *state) { + pa_alsa_path *p; + pa_alsa_option *o; +@@ -2567,7 +2589,7 @@ pa_alsa_path* pa_alsa_path_new(const cha + { "description-key", pa_config_parse_string, NULL, "General" }, + { "description", pa_config_parse_string, NULL, "General" }, + { "mute-during-activation", pa_config_parse_bool, NULL, "General" }, +- { "eld-device", pa_config_parse_int, NULL, "General" }, ++ { "eld-device", parse_eld_device, NULL, "General" }, + + /* [Option ...] */ + { "priority", option_parse_priority, NULL, NULL }, +@@ -2607,7 +2629,6 @@ pa_alsa_path* pa_alsa_path_new(const cha + items[1].data = &p->description_key; + items[2].data = &p->description; + items[3].data = &mute_during_activation; +- items[4].data = &p->eld_device; + + if (!paths_dir) + paths_dir = get_default_paths_dir(); +@@ -4011,6 +4032,9 @@ static void mapping_paths_probe(pa_alsa_ + } + + PA_HASHMAP_FOREACH(p, ps->paths, state) { ++ if (p->autodetect_eld_device) ++ p->eld_device = m->hw_device_index; ++ + if (pa_alsa_path_probe(p, m, mixer_handle, m->profile_set->ignore_dB) < 0) + pa_hashmap_remove(ps->paths, p); + } +--- a/src/modules/alsa/alsa-mixer.h ++++ b/src/modules/alsa/alsa-mixer.h +@@ -193,6 +193,7 @@ struct pa_alsa_path { + char *description_key; + char *description; + unsigned priority; ++ bool autodetect_eld_device; + int eld_device; + pa_proplist *proplist; + +--- a/src/modules/alsa/mixer/paths/analog-output.conf.common ++++ b/src/modules/alsa/mixer/paths/analog-output.conf.common +@@ -64,8 +64,12 @@ + ; mute-during-activation = yes | no # If this path supports hardware mute, should the hw mute be used while activating this + ; # path? In some cases this can reduce extra noises during port switching, while in other + ; # cases this can increase such noises. Default: no. +-; eld-device = ... # If this is an HDMI port, here's where to specify the device number for the ELD mixer +-; # control. The default is to not make use of ELD information. ++; eld-device = ... # If this is an HDMI port, set to "auto" so that PulseAudio will try to read ++; # the monitor ELD information from the ALSA mixer. By default the ELD information ++; # is not read, because it's only applicable with HDMI. Earlier the "auto" option ++; # didn't exist, and the hw device index had to be manually configured. For ++; # backwards compatibility, it's still possible to manually configure the device ++; # index using this option. + ; + ; [Properties] # Property list for this path. The list is merged into the port property list. + ; = # Each property is defined on its own line. +--- a/src/modules/alsa/mixer/paths/hdmi-output-0.conf ++++ b/src/modules/alsa/mixer/paths/hdmi-output-0.conf +@@ -1,7 +1,7 @@ + [General] + description = HDMI / DisplayPort + priority = 59 +-eld-device = 3 ++eld-device = auto + + [Properties] + device.icon_name = video-display +--- a/src/modules/alsa/mixer/paths/hdmi-output-1.conf ++++ b/src/modules/alsa/mixer/paths/hdmi-output-1.conf +@@ -1,7 +1,7 @@ + [General] + description = HDMI / DisplayPort 2 + priority = 58 +-eld-device = 7 ++eld-device = auto + + [Properties] + device.icon_name = video-display +--- a/src/modules/alsa/mixer/paths/hdmi-output-2.conf ++++ b/src/modules/alsa/mixer/paths/hdmi-output-2.conf +@@ -1,7 +1,7 @@ + [General] + description = HDMI / DisplayPort 3 + priority = 57 +-eld-device = 8 ++eld-device = auto + + [Properties] + device.icon_name = video-display +--- a/src/modules/alsa/mixer/paths/hdmi-output-3.conf ++++ b/src/modules/alsa/mixer/paths/hdmi-output-3.conf +@@ -1,7 +1,7 @@ + [General] + description = HDMI / DisplayPort 4 + priority = 56 +-eld-device = 9 ++eld-device = auto + + [Properties] + device.icon_name = video-display +--- a/src/modules/alsa/mixer/paths/hdmi-output-4.conf ++++ b/src/modules/alsa/mixer/paths/hdmi-output-4.conf +@@ -1,7 +1,7 @@ + [General] + description = HDMI / DisplayPort 5 + priority = 55 +-eld-device = 10 ++eld-device = auto + + [Properties] + device.icon_name = video-display +--- a/src/modules/alsa/mixer/paths/hdmi-output-5.conf ++++ b/src/modules/alsa/mixer/paths/hdmi-output-5.conf +@@ -1,7 +1,7 @@ + [General] + description = HDMI / DisplayPort 6 + priority = 54 +-eld-device = 11 ++eld-device = auto + + [Properties] + device.icon_name = video-display +--- a/src/modules/alsa/mixer/paths/hdmi-output-6.conf ++++ b/src/modules/alsa/mixer/paths/hdmi-output-6.conf +@@ -1,7 +1,7 @@ + [General] + description = HDMI / DisplayPort 7 + priority = 53 +-eld-device = 12 ++eld-device = auto + + [Properties] + device.icon_name = video-display +--- a/src/modules/alsa/mixer/paths/hdmi-output-7.conf ++++ b/src/modules/alsa/mixer/paths/hdmi-output-7.conf +@@ -1,7 +1,7 @@ + [General] + description = HDMI / DisplayPort 8 + priority = 52 +-eld-device = 13 ++eld-device = auto + + [Properties] + device.icon_name = video-display diff --git a/pulseaudio.changes b/pulseaudio.changes index 98a6a79..2d13aab 100644 --- a/pulseaudio.changes +++ b/pulseaudio.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Thu Mar 1 10:53:15 CET 2018 - tiwai@suse.de + +- Fix the crash with Intel LPE HDMI audio (bsc#1083195): + 0001-alsa-fix-infinite-loop-with-Intel-HDMI-LPE.patch + 0002-alsa-mixer-add-hw_device_index-to-pa_alsa_mapping.patch + 0003-alsa-mixer-autodetect-the-HDMI-jack-PCM-device.patch + 0004-alsa-mixer-autodetect-the-ELD-device.patch + ------------------------------------------------------------------- Wed Feb 28 17:23:25 CET 2018 - tiwai@suse.de diff --git a/pulseaudio.spec b/pulseaudio.spec index df17090..105618b 100644 --- a/pulseaudio.spec +++ b/pulseaudio.spec @@ -52,6 +52,11 @@ Patch2: pulseaudio-wrong-memset.patch # PATCH-FIX-UPSTREAM pulseaudio-glibc2.27.patch boo#1081023 fdo#104733 dimstar@opensuse.org -- Fix build with glibc 2.27 Patch3: pulseaudio-glibc2.27.patch Patch4: pa-set-exit-idle-time-to-0-when-we-detect-a-session.patch +# upstream fixes for crash with Intel LPE HDMI audio +Patch5: 0001-alsa-fix-infinite-loop-with-Intel-HDMI-LPE.patch +Patch6: 0002-alsa-mixer-add-hw_device_index-to-pa_alsa_mapping.patch +Patch7: 0003-alsa-mixer-autodetect-the-HDMI-jack-PCM-device.patch +Patch8: 0004-alsa-mixer-autodetect-the-ELD-device.patch BuildRequires: alsa-devel >= 1.0.19 # require only minimal bluez, if we are on bluez 5 we will determine in build phase BuildRequires: bluez-devel >= 4.99 @@ -332,6 +337,10 @@ Optional dependency offering zsh completion for various PulseAudio utilities %patch2 %patch3 -p1 %patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 %build ./bootstrap.sh