Date: Sunday, February 21, 2016 @ 13:07:08 Author: heftig Revision: 260119
Stopgap for https://bugs.freedesktop.org/show_bug.cgi?id=93946 Added: pulseaudio/trunk/0001-Revert-module-switch-on-port-available-Route-to-pref.patch Modified: pulseaudio/trunk/PKGBUILD -----------------------------------------------------------------+ 0001-Revert-module-switch-on-port-available-Route-to-pref.patch | 258 ++++++++++ PKGBUILD | 6 2 files changed, 263 insertions(+), 1 deletion(-) Added: 0001-Revert-module-switch-on-port-available-Route-to-pref.patch =================================================================== --- 0001-Revert-module-switch-on-port-available-Route-to-pref.patch (rev 0) +++ 0001-Revert-module-switch-on-port-available-Route-to-pref.patch 2016-02-21 12:07:08 UTC (rev 260119) @@ -0,0 +1,258 @@ +From 343a86252241c591114b064a3340f7beb2d1ff44 Mon Sep 17 00:00:00 2001 +From: "Jan Alexander Steffens (heftig)" <[email protected]> +Date: Sun, 21 Feb 2016 12:59:50 +0100 +Subject: [PATCH] Revert "module-switch-on-port-available: Route to preferred + profile" + +This reverts commit e87100d41ef6d14f8dc7f803582191d9f8d8f183. +--- + src/modules/module-switch-on-port-available.c | 182 ++++++++++---------------- + 1 file changed, 72 insertions(+), 110 deletions(-) + +diff --git a/src/modules/module-switch-on-port-available.c b/src/modules/module-switch-on-port-available.c +index 5dd9786..8de68a3 100644 +--- a/src/modules/module-switch-on-port-available.c ++++ b/src/modules/module-switch-on-port-available.c +@@ -74,25 +74,22 @@ static bool profile_good_for_input(pa_card_profile *profile) { + static int try_to_switch_profile(pa_device_port *port) { + pa_card_profile *best_profile = NULL, *profile; + void *state; +- unsigned best_prio = 0; + +- pa_log_debug("Finding best profile for port %s, preferred = %s", +- port->name, pa_strnull(port->preferred_profile)); ++ pa_log_debug("Finding best profile"); + + PA_HASHMAP_FOREACH(profile, port->profiles, state) { + bool good = false; +- const char *name; +- unsigned prio = profile->priority; ++ ++ if (best_profile && best_profile->priority >= profile->priority) ++ continue; + + /* We make a best effort to keep other direction unchanged */ + switch (port->direction) { + case PA_DIRECTION_OUTPUT: +- name = profile->output_name; + good = profile_good_for_output(profile); + break; + + case PA_DIRECTION_INPUT: +- name = profile->input_name; + good = profile_good_for_input(profile); + break; + } +@@ -100,15 +97,7 @@ static int try_to_switch_profile(pa_device_port *port) { + if (!good) + continue; + +- /* Give a high bonus in case this is the preferred profile */ +- if (port->preferred_profile && pa_streq(name ? name : profile->name, port->preferred_profile)) +- prio += 1000000; +- +- if (best_profile && best_prio >= prio) +- continue; +- + best_profile = profile; +- best_prio = prio; + } + + if (!best_profile) { +@@ -124,125 +113,98 @@ static int try_to_switch_profile(pa_device_port *port) { + return 0; + } + +-struct port_pointers { +- pa_device_port *port; +- pa_sink *sink; +- pa_source *source; +- bool is_possible_profile_active; +- bool is_preferred_profile_active; +- bool is_port_active; +-}; +- +-static const char* profile_name_for_dir(pa_card_profile *cp, pa_direction_t dir) { +- if (dir == PA_DIRECTION_OUTPUT && cp->output_name) +- return cp->output_name; +- if (dir == PA_DIRECTION_INPUT && cp->input_name) +- return cp->input_name; +- return cp->name; +-} +- +-static struct port_pointers find_port_pointers(pa_device_port *port) { +- struct port_pointers pp = { .port = port }; ++static void find_sink_and_source(pa_card *card, pa_device_port *port, pa_sink **si, pa_source **so) { ++ pa_sink *sink = NULL; ++ pa_source *source = NULL; + uint32_t state; +- pa_card *card; +- +- pa_assert(port); +- pa_assert_se(card = port->card); + + switch (port->direction) { + case PA_DIRECTION_OUTPUT: +- PA_IDXSET_FOREACH(pp.sink, card->sinks, state) +- if (port == pa_hashmap_get(pp.sink->ports, port->name)) ++ PA_IDXSET_FOREACH(sink, card->sinks, state) ++ if (port == pa_hashmap_get(sink->ports, port->name)) + break; + break; + + case PA_DIRECTION_INPUT: +- PA_IDXSET_FOREACH(pp.source, card->sources, state) +- if (port == pa_hashmap_get(pp.source->ports, port->name)) ++ PA_IDXSET_FOREACH(source, card->sources, state) ++ if (port == pa_hashmap_get(source->ports, port->name)) + break; + break; + } + +- pp.is_possible_profile_active = +- card->active_profile == pa_hashmap_get(port->profiles, card->active_profile->name); +- pp.is_preferred_profile_active = pp.is_possible_profile_active && (!port->preferred_profile || +- pa_safe_streq(port->preferred_profile, profile_name_for_dir(card->active_profile, port->direction))); +- pp.is_port_active = (pp.sink && pp.sink->active_port == port) || (pp.source && pp.source->active_port == port); +- +- return pp; ++ *si = sink; ++ *so = source; + } + +-/* Switches to a port, switching profiles if necessary or preferred */ +-static bool switch_to_port(pa_device_port *port) { +- struct port_pointers pp = find_port_pointers(port); +- +- if (pp.is_port_active) +- return true; /* Already selected */ +- +- pa_log_debug("Trying to switch to port %s", port->name); +- if (!pp.is_preferred_profile_active) { +- if (try_to_switch_profile(port) < 0) { +- if (pp.is_possible_profile_active) +- return false; +- } +- else +- /* Now that profile has changed, our sink and source pointers must be updated */ +- pp = find_port_pointers(port); +- } +- +- if (pp.source) +- pa_source_set_port(pp.source, port->name, false); +- if (pp.sink) +- pa_sink_set_port(pp.sink, port->name, false); +- return true; +-} +- +-/* Switches away from a port, switching profiles if necessary or preferred */ +-static bool switch_from_port(pa_device_port *port) { +- struct port_pointers pp = find_port_pointers(port); +- pa_device_port *p, *best_port = NULL; +- void *state; +- +- if (!pp.is_port_active) +- return true; /* Already deselected */ +- +- /* Try to find a good enough port to switch to */ +- PA_HASHMAP_FOREACH(p, port->card->ports, state) +- if (p->direction == port->direction && p != port && p->available != PA_AVAILABLE_NO && +- (!best_port || best_port->priority < p->priority)) +- best_port = p; +- +- pa_log_debug("Trying to switch away from port %s, found %s", port->name, best_port ? best_port->name : "no better option"); +- +- if (best_port) +- return switch_to_port(best_port); +- +- return false; +-} +- +- + static pa_hook_result_t port_available_hook_callback(pa_core *c, pa_device_port *port, void* userdata) { +- pa_assert(port); ++ pa_card* card; ++ pa_sink *sink; ++ pa_source *source; ++ bool is_active_profile, is_active_port; + +- if (!port->card) { ++ if (port->available == PA_AVAILABLE_UNKNOWN) ++ return PA_HOOK_OK; ++ ++ card = port->card; ++ ++ if (!card) { + pa_log_warn("Port %s does not have a card", port->name); + return PA_HOOK_OK; + } + +- if (pa_idxset_size(port->card->sinks) == 0 && pa_idxset_size(port->card->sources) == 0) ++ if (pa_idxset_size(card->sinks) == 0 && pa_idxset_size(card->sources) == 0) + /* This card is not initialized yet. We'll handle it in + sink_new / source_new callbacks later. */ + return PA_HOOK_OK; + +- switch (port->available) { +- case PA_AVAILABLE_YES: +- switch_to_port(port); +- break; +- case PA_AVAILABLE_NO: +- switch_from_port(port); +- break; +- default: +- break; ++ find_sink_and_source(card, port, &sink, &source); ++ ++ is_active_profile = card->active_profile == pa_hashmap_get(port->profiles, card->active_profile->name); ++ is_active_port = (sink && sink->active_port == port) || (source && source->active_port == port); ++ ++ if (port->available == PA_AVAILABLE_NO && !is_active_port) ++ return PA_HOOK_OK; ++ ++ if (port->available == PA_AVAILABLE_YES) { ++ if (is_active_port) ++ return PA_HOOK_OK; ++ ++ if (!is_active_profile) { ++ if (try_to_switch_profile(port) < 0) ++ return PA_HOOK_OK; ++ ++ pa_assert(card->active_profile == pa_hashmap_get(port->profiles, card->active_profile->name)); ++ ++ /* Now that profile has changed, our sink and source pointers must be updated */ ++ find_sink_and_source(card, port, &sink, &source); ++ } ++ ++ if (source) ++ pa_source_set_port(source, port->name, false); ++ if (sink) ++ pa_sink_set_port(sink, port->name, false); ++ } ++ ++ if (port->available == PA_AVAILABLE_NO) { ++ if (sink) { ++ pa_device_port *p2 = pa_device_port_find_best(sink->ports); ++ ++ if (p2 && p2->available != PA_AVAILABLE_NO) ++ pa_sink_set_port(sink, p2->name, false); ++ else { ++ /* Maybe try to switch to another profile? */ ++ } ++ } ++ ++ if (source) { ++ pa_device_port *p2 = pa_device_port_find_best(source->ports); ++ ++ if (p2 && p2->available != PA_AVAILABLE_NO) ++ pa_source_set_port(source, p2->name, false); ++ else { ++ /* Maybe try to switch to another profile? */ ++ } ++ } + } + + return PA_HOOK_OK; +-- +2.7.1 + Modified: PKGBUILD =================================================================== --- PKGBUILD 2016-02-21 11:33:38 UTC (rev 260118) +++ PKGBUILD 2016-02-21 12:07:08 UTC (rev 260119) @@ -8,7 +8,7 @@ pkgname=(pulseaudio libpulse pulseaudio-{gconf,zeroconf,lirc,xen,jack,bluetooth,equalizer}) pkgdesc="A featureful, general-purpose sound server" pkgver=8.0 -pkgrel=1 +pkgrel=2 arch=(i686 x86_64) url="http://www.freedesktop.org/wiki/Software/PulseAudio" license=(LGPL) @@ -18,12 +18,16 @@ check) options=(!emptydirs) source=(http://freedesktop.org/software/$pkgbase/releases/$pkgbase-$pkgver.tar.xz + 0001-Revert-module-switch-on-port-available-Route-to-pref.patch padsp-lib32.patch) sha256sums=('690eefe28633466cfd1ab9d85ebfa9376f6b622deec6bfee5091ac9737cd1989' + 'a1dba5ee625d08cd44bed7fb656a572f76e35751ca7fe450380800cba0cfa394' '7832fc59df76538ff10aedd297c03cb7ff117235da8bfad26082994bb5b84332') prepare() { cd $pkgbase-$pkgver + # https://bugs.freedesktop.org/show_bug.cgi?id=93946 + patch -Np1 -i ../0001-Revert-module-switch-on-port-available-Route-to-pref.patch } build() {
