Blame SOURCES/0001-alsa-card-add-dynamic-priority-bonus-base-for-alsa-p.patch

0356fa
From 832d7ac1144416306de1b6990d70115079bd1935 Mon Sep 17 00:00:00 2001
0356fa
From: Hui Wang <hui.wang@canonical.com>
0356fa
Date: Fri, 21 Aug 2020 17:34:25 +0800
0356fa
Subject: [PATCH] alsa-card: add dynamic priority bonus base for alsa profiles
0356fa
0356fa
After applying the commit 0d50e787 ("alsa-card: improve the profile
0356fa
availability logic"), we met an new issue. when system selects the
0356fa
initial profile, the profile off is selected instead of a profile with
0356fa
a valid output device on it. That is the issue we met:
0356fa
0356fa
Profiles:
0356fa
  HiFi: Default (sinks: 2, sources: 2, priority: 8000, available: no)
0356fa
  off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
0356fa
Active Profile: off
0356fa
Ports:
0356fa
  [Out] Headphones: Headphones (priority: 300, latency offset: 0 usec, not available)
0356fa
   Part of profile(s): HiFi
0356fa
  [Out] Speaker: Speaker (priority: 100, latency offset: 0 usec)
0356fa
   Part of profile(s): HiFi
0356fa
...
0356fa
0356fa
I know the commit 0d50e787 really fixed something, but we still need
0356fa
to fix the new issue, to do so, this patch introduces a priority bonus
0356fa
for alsa profiles and separate the alsa profiles to 3 groups:
0356fa
group a (will be granted priority bonus dynamically):
0356fa
a profile has only output ports and at least one port is not unavailable
0356fa
a profile has only input ports and at least one port is not unavailable
0356fa
a profile has both input and output ports, and at least one output and
0356fa
one input ports are not unavailable
0356fa
0356fa
group b (will be marked unavailable)
0356fa
a profile has only output ports and all ports are unavailable
0356fa
a profile has only input ports and all ports are unavailable
0356fa
a profile has both output and input ports, and all ports are unavailable
0356fa
0356fa
group c
0356fa
the rest profiles, their priority and availability is not changed.
0356fa
0356fa
With this change, the profile HiFi will become avaialbe:yes, and will
0356fa
not be granted priority bonus if no input port is plugged.
0356fa
0356fa
The priority bonus provides a higher priority base to profiles, this
0356fa
guarantees this patch doesn't break the fix of 0d50e787.
0356fa
0356fa
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/issues/927
0356fa
0356fa
Signed-off-by: Hui Wang <hui.wang@canonical.com>
0356fa
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/355>
0356fa
---
0356fa
 src/modules/alsa/module-alsa-card.c | 35 ++++++++++++++++++++++++-----
0356fa
 1 file changed, 30 insertions(+), 5 deletions(-)
0356fa
0356fa
diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
0356fa
index de2fe9cc4..5349314b5 100644
0356fa
--- a/src/modules/alsa/module-alsa-card.c
0356fa
+++ b/src/modules/alsa/module-alsa-card.c
0356fa
@@ -104,6 +104,13 @@ static const char* const valid_modargs[] = {
0356fa
 
0356fa
 #define DEFAULT_DEVICE_ID "0"
0356fa
 
0356fa
+/* dynamic profile priority bonus, for all alsa profiles, the original priority
0356fa
+   needs to be less than 0x7fff (32767), then could apply the rule of priority
0356fa
+   bonus. So far there are 2 kinds of alsa profiles, one is from alsa ucm, the
0356fa
+   other is from mixer profile-sets, their priorities are all far less than 0x7fff
0356fa
+*/
0356fa
+#define PROFILE_PRIO_BONUS 0x8000
0356fa
+
0356fa
 struct userdata {
0356fa
     pa_core *core;
0356fa
     pa_module *module;
0356fa
@@ -459,9 +466,19 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
0356fa
      * as available (well, "unknown" to be precise, but there's little
0356fa
      * practical difference).
0356fa
      *
0356fa
-     * When all output ports are unavailable, we know that all sinks are
0356fa
-     * unavailable, and therefore the profile is marked unavailable as well.
0356fa
-     * The same applies to input ports as well, of course.
0356fa
+     * A profile will be marked unavailable:
0356fa
+     * only contains output ports and all ports are unavailable
0356fa
+     * only contains input ports and all ports are unavailable
0356fa
+     * contains both input and output ports and all ports are unavailable
0356fa
+     *
0356fa
+     * A profile will be awarded priority bonus:
0356fa
+     * only contains output ports and at least one port is available
0356fa
+     * only contains input ports and at least one port is available
0356fa
+     * contains both output and input ports and at least one output port
0356fa
+     * and one input port are available
0356fa
+     *
0356fa
+     * The rest profiles will not be marked unavailable and will not be
0356fa
+     * awarded priority bonus
0356fa
      *
0356fa
      * If there are no output ports at all, but the profile contains at least
0356fa
      * one sink, then the output is considered to be available. */
0356fa
@@ -476,6 +493,7 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
0356fa
         bool found_available_output_port = false;
0356fa
         pa_available_t available = PA_AVAILABLE_UNKNOWN;
0356fa
 
0356fa
+        profile->priority &= ~PROFILE_PRIO_BONUS;
0356fa
         PA_HASHMAP_FOREACH(port, u->card->ports, state2) {
0356fa
             if (!pa_hashmap_get(port->profiles, profile->name))
0356fa
                 continue;
0356fa
@@ -493,8 +511,15 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
0356fa
             }
0356fa
         }
0356fa
 
0356fa
-        if ((has_input_port && !found_available_input_port) || (has_output_port && !found_available_output_port))
0356fa
-            available = PA_AVAILABLE_NO;
0356fa
+        if ((has_input_port && found_available_input_port && !has_output_port) ||
0356fa
+            (has_output_port && found_available_output_port && !has_input_port) ||
0356fa
+            (has_input_port && found_available_input_port && has_output_port && found_available_output_port))
0356fa
+                profile->priority |= PROFILE_PRIO_BONUS;
0356fa
+
0356fa
+        if ((has_input_port && !found_available_input_port && has_output_port && !found_available_output_port) ||
0356fa
+            (has_input_port && !found_available_input_port && !has_output_port) ||
0356fa
+            (has_output_port && !found_available_output_port && !has_input_port))
0356fa
+                available = PA_AVAILABLE_NO;
0356fa
 
0356fa
         /* We want to update the active profile's status last, so logic that
0356fa
          * may change the active profile based on profile availability status
0356fa
-- 
0356fa
2.36.1
0356fa