[pulseaudio-commits] 8 commits - src/modules src/pulsecore
Tanu Kaskinen
tanuk at kemper.freedesktop.org
Sat Nov 21 19:01:42 PST 2015
src/modules/alsa/alsa-mixer.c | 8 +
src/modules/alsa/alsa-mixer.h | 3
src/modules/alsa/module-alsa-card.c | 2
src/modules/module-card-restore.c | 58 ++++++--
src/modules/module-switch-on-port-available.c | 179 ++++++++++++++++----------
src/pulsecore/card.c | 20 ++
src/pulsecore/card.h | 8 +
src/pulsecore/device-port.c | 11 +
src/pulsecore/device-port.h | 2
9 files changed, 212 insertions(+), 79 deletions(-)
New commits:
commit bea37613ceda60c6843e2afc5e7c5859dbe570c1
Author: David Henningsson <david.henningsson at canonical.com>
Date: Tue Nov 17 15:10:36 2015 +0100
module-card-restore: Remove "version" from internal entry struct
If we always write entries of the latest version, we can simplify
code a little by only handling old versions in the "entry_read"
function and assume we have the latest version everywhere else.
Suggested-by: Tanu Kaskinen <tanuk at iki.fi>
Signed-off-by: David Henningsson <david.henningsson at canonical.com>
diff --git a/src/modules/module-card-restore.c b/src/modules/module-card-restore.c
index b30fa36..f906843 100644
--- a/src/modules/module-card-restore.c
+++ b/src/modules/module-card-restore.c
@@ -73,7 +73,6 @@ struct port_info {
};
struct entry {
- uint8_t version;
char *profile;
pa_hashmap *ports; /* Port name -> struct port_info */
};
@@ -110,7 +109,6 @@ static void port_info_free(struct port_info *p_info) {
static struct entry* entry_new(void) {
struct entry *r = pa_xnew0(struct entry, 1);
- r->version = ENTRY_VERSION;
r->ports = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) port_info_free);
return r;
}
@@ -193,15 +191,14 @@ static bool entry_write(struct userdata *u, const char *name, const struct entry
pa_assert(e);
t = pa_tagstruct_new();
- pa_tagstruct_putu8(t, e->version);
+ pa_tagstruct_putu8(t, ENTRY_VERSION);
pa_tagstruct_puts(t, e->profile);
pa_tagstruct_putu32(t, pa_hashmap_size(e->ports));
PA_HASHMAP_FOREACH(p_info, e->ports, state) {
pa_tagstruct_puts(t, p_info->name);
pa_tagstruct_puts64(t, p_info->offset);
- if (e->version >= 3)
- pa_tagstruct_puts(t, p_info->profile);
+ pa_tagstruct_puts(t, p_info->profile);
}
key.data = (char *) name;
@@ -258,6 +255,7 @@ static struct entry* entry_read(struct userdata *u, const char *name) {
struct entry *e = NULL;
pa_tagstruct *t = NULL;
const char* profile;
+ uint8_t version;
pa_assert(u);
pa_assert(name);
@@ -275,8 +273,8 @@ static struct entry* entry_read(struct userdata *u, const char *name) {
t = pa_tagstruct_new_fixed(data.data, data.size);
e = entry_new();
- if (pa_tagstruct_getu8(t, &e->version) < 0 ||
- e->version > ENTRY_VERSION ||
+ if (pa_tagstruct_getu8(t, &version) < 0 ||
+ version > ENTRY_VERSION ||
pa_tagstruct_gets(t, &profile) < 0) {
goto fail;
@@ -287,7 +285,7 @@ static struct entry* entry_read(struct userdata *u, const char *name) {
e->profile = pa_xstrdup(profile);
- if (e->version >= 2) {
+ if (version >= 2) {
uint32_t port_count = 0;
const char *port_name = NULL, *profile_name = NULL;
int64_t port_offset = 0;
@@ -303,7 +301,7 @@ static struct entry* entry_read(struct userdata *u, const char *name) {
pa_hashmap_get(e->ports, port_name) ||
pa_tagstruct_gets64(t, &port_offset) < 0)
goto fail;
- if (e->version >= 3 && pa_tagstruct_gets(t, &profile_name) < 0)
+ if (version >= 3 && pa_tagstruct_gets(t, &profile_name) < 0)
goto fail;
p_info = port_info_new(NULL);
@@ -399,7 +397,6 @@ static void update_profile_for_port(struct entry *entry, pa_card *card, pa_devic
if (!pa_safe_streq(p_info->profile, p->preferred_profile)) {
pa_xfree(p_info->profile);
p_info->profile = pa_xstrdup(p->preferred_profile);
- entry->version = ENTRY_VERSION;
pa_log_info("Storing profile %s for port %s on card %s.", p_info->profile, p->name, card->name);
}
}
commit e87100d41ef6d14f8dc7f803582191d9f8d8f183
Author: David Henningsson <david.henningsson at canonical.com>
Date: Tue Nov 17 15:10:35 2015 +0100
module-switch-on-port-available: Route to preferred profile
This makes the routing slightly more aggressive:
* It will try to route to another profile, if such a profile
is preferred by the port.
* It will allow changing profiles on transitions both to
PA_AVAILABLE_YES and PA_AVAILABLE_NO
To accommodate there is also some refactoring.
Signed-off-by: David Henningsson <david.henningsson at canonical.com>
diff --git a/src/modules/module-switch-on-port-available.c b/src/modules/module-switch-on-port-available.c
index 8de68a3..5dd9786 100644
--- a/src/modules/module-switch-on-port-available.c
+++ b/src/modules/module-switch-on-port-available.c
@@ -74,22 +74,25 @@ 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");
+ pa_log_debug("Finding best profile for port %s, preferred = %s",
+ port->name, pa_strnull(port->preferred_profile));
PA_HASHMAP_FOREACH(profile, port->profiles, state) {
bool good = false;
-
- if (best_profile && best_profile->priority >= profile->priority)
- continue;
+ const char *name;
+ unsigned prio = profile->priority;
/* 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;
}
@@ -97,7 +100,15 @@ 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) {
@@ -113,98 +124,125 @@ static int try_to_switch_profile(pa_device_port *port) {
return 0;
}
-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;
+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 };
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(sink, card->sinks, state)
- if (port == pa_hashmap_get(sink->ports, port->name))
+ PA_IDXSET_FOREACH(pp.sink, card->sinks, state)
+ if (port == pa_hashmap_get(pp.sink->ports, port->name))
break;
break;
case PA_DIRECTION_INPUT:
- PA_IDXSET_FOREACH(source, card->sources, state)
- if (port == pa_hashmap_get(source->ports, port->name))
+ PA_IDXSET_FOREACH(pp.source, card->sources, state)
+ if (port == pa_hashmap_get(pp.source->ports, port->name))
break;
break;
}
- *si = sink;
- *so = source;
-}
+ 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);
-static pa_hook_result_t port_available_hook_callback(pa_core *c, pa_device_port *port, void* userdata) {
- pa_card* card;
- pa_sink *sink;
- pa_source *source;
- bool is_active_profile, is_active_port;
+ return pp;
+}
- if (port->available == PA_AVAILABLE_UNKNOWN)
- return PA_HOOK_OK;
+/* 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);
- card = port->card;
+ if (pp.is_port_active)
+ return true; /* Already selected */
- if (!card) {
- pa_log_warn("Port %s does not have a card", port->name);
- return PA_HOOK_OK;
+ 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 (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;
+ 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;
+}
- find_sink_and_source(card, port, &sink, &source);
+/* 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;
- 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 (!pp.is_port_active)
+ return true; /* Already deselected */
- if (port->available == PA_AVAILABLE_NO && !is_active_port)
- return PA_HOOK_OK;
+ /* 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;
- if (port->available == PA_AVAILABLE_YES) {
- if (is_active_port)
- return PA_HOOK_OK;
+ pa_log_debug("Trying to switch away from port %s, found %s", port->name, best_port ? best_port->name : "no better option");
- if (!is_active_profile) {
- if (try_to_switch_profile(port) < 0)
- return PA_HOOK_OK;
+ if (best_port)
+ return switch_to_port(best_port);
- pa_assert(card->active_profile == pa_hashmap_get(port->profiles, card->active_profile->name));
+ return false;
+}
- /* 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);
+static pa_hook_result_t port_available_hook_callback(pa_core *c, pa_device_port *port, void* userdata) {
+ pa_assert(port);
- if (p2 && p2->available != PA_AVAILABLE_NO)
- pa_sink_set_port(sink, p2->name, false);
- else {
- /* Maybe try to switch to another profile? */
- }
- }
+ if (!port->card) {
+ pa_log_warn("Port %s does not have a card", port->name);
+ return PA_HOOK_OK;
+ }
- if (source) {
- pa_device_port *p2 = pa_device_port_find_best(source->ports);
+ if (pa_idxset_size(port->card->sinks) == 0 && pa_idxset_size(port->card->sources) == 0)
+ /* This card is not initialized yet. We'll handle it in
+ sink_new / source_new callbacks later. */
+ return PA_HOOK_OK;
- if (p2 && p2->available != PA_AVAILABLE_NO)
- pa_source_set_port(source, p2->name, false);
- else {
- /* Maybe try to switch to another profile? */
- }
- }
+ switch (port->available) {
+ case PA_AVAILABLE_YES:
+ switch_to_port(port);
+ break;
+ case PA_AVAILABLE_NO:
+ switch_from_port(port);
+ break;
+ default:
+ break;
}
return PA_HOOK_OK;
commit 063a1d350fad1cb6fac28dbffe26a7e805626cb2
Author: David Henningsson <david.henningsson at canonical.com>
Date: Tue Nov 17 15:10:34 2015 +0100
module-switch-on-port-available: Use input and output names
In case input or output names are filled in, we can use this to
get a better match in the profile_good_for_input/output functions
instead of guessing based on number of sources and channels.
Signed-off-by: David Henningsson <david.henningsson at canonical.com>
diff --git a/src/modules/module-switch-on-port-available.c b/src/modules/module-switch-on-port-available.c
index eb8f2d7..8de68a3 100644
--- a/src/modules/module-switch-on-port-available.c
+++ b/src/modules/module-switch-on-port-available.c
@@ -23,6 +23,7 @@
#endif
#include <pulsecore/core.h>
+#include <pulsecore/core-util.h>
#include <pulsecore/device-port.h>
#include <pulsecore/hashmap.h>
@@ -34,6 +35,9 @@ static bool profile_good_for_output(pa_card_profile *profile) {
pa_assert(profile);
+ if (!pa_safe_streq(profile->card->active_profile->input_name, profile->input_name))
+ return false;
+
if (profile->card->active_profile->n_sources != profile->n_sources)
return false;
@@ -55,6 +59,9 @@ static bool profile_good_for_output(pa_card_profile *profile) {
static bool profile_good_for_input(pa_card_profile *profile) {
pa_assert(profile);
+ if (!pa_safe_streq(profile->card->active_profile->output_name, profile->output_name))
+ return false;
+
if (profile->card->active_profile->n_sinks != profile->n_sinks)
return false;
commit 9059fb3b4ed7ade607846f4846842c2b1ce699fa
Author: David Henningsson <david.henningsson at canonical.com>
Date: Tue Nov 17 15:10:33 2015 +0100
card-restore: Save and restore "preferred profile" of port
Signed-off-by: David Henningsson <david.henningsson at canonical.com>
diff --git a/src/modules/module-card-restore.c b/src/modules/module-card-restore.c
index 3725d30..b30fa36 100644
--- a/src/modules/module-card-restore.c
+++ b/src/modules/module-card-restore.c
@@ -64,11 +64,12 @@ struct userdata {
pa_database *database;
};
-#define ENTRY_VERSION 2
+#define ENTRY_VERSION 3
struct port_info {
char *name;
int64_t offset;
+ char *profile;
};
struct entry {
@@ -102,6 +103,7 @@ static void trigger_save(struct userdata *u) {
static void port_info_free(struct port_info *p_info) {
pa_assert(p_info);
+ pa_xfree(p_info->profile);
pa_xfree(p_info->name);
pa_xfree(p_info);
}
@@ -117,9 +119,11 @@ static struct port_info *port_info_new(pa_device_port *port) {
struct port_info *p_info;
if (port) {
- p_info = pa_xnew(struct port_info, 1);
+ p_info = pa_xnew0(struct port_info, 1);
p_info->name = pa_xstrdup(port->name);
p_info->offset = port->latency_offset;
+ if (port->preferred_profile)
+ p_info->profile = pa_xstrdup(port->preferred_profile);
} else
p_info = pa_xnew0(struct port_info, 1);
@@ -196,6 +200,8 @@ static bool entry_write(struct userdata *u, const char *name, const struct entry
PA_HASHMAP_FOREACH(p_info, e->ports, state) {
pa_tagstruct_puts(t, p_info->name);
pa_tagstruct_puts64(t, p_info->offset);
+ if (e->version >= 3)
+ pa_tagstruct_puts(t, p_info->profile);
}
key.data = (char *) name;
@@ -283,7 +289,7 @@ static struct entry* entry_read(struct userdata *u, const char *name) {
if (e->version >= 2) {
uint32_t port_count = 0;
- const char *port_name = NULL;
+ const char *port_name = NULL, *profile_name = NULL;
int64_t port_offset = 0;
struct port_info *p_info;
unsigned i;
@@ -297,10 +303,14 @@ static struct entry* entry_read(struct userdata *u, const char *name) {
pa_hashmap_get(e->ports, port_name) ||
pa_tagstruct_gets64(t, &port_offset) < 0)
goto fail;
+ if (e->version >= 3 && pa_tagstruct_gets(t, &profile_name) < 0)
+ goto fail;
p_info = port_info_new(NULL);
p_info->name = pa_xstrdup(port_name);
p_info->offset = port_offset;
+ if (profile_name)
+ p_info->profile = pa_xstrdup(profile_name);
pa_assert_se(pa_hashmap_put(e->ports, p_info->name, p_info) >= 0);
}
@@ -375,8 +385,30 @@ finish:
return PA_HOOK_OK;
}
+static void update_profile_for_port(struct entry *entry, pa_card *card, pa_device_port *p) {
+ struct port_info *p_info;
+
+ if (p == NULL)
+ return;
+
+ if (!(p_info = pa_hashmap_get(entry->ports, p->name))) {
+ p_info = port_info_new(p);
+ pa_assert_se(pa_hashmap_put(entry->ports, p_info->name, p_info) >= 0);
+ }
+
+ if (!pa_safe_streq(p_info->profile, p->preferred_profile)) {
+ pa_xfree(p_info->profile);
+ p_info->profile = pa_xstrdup(p->preferred_profile);
+ entry->version = ENTRY_VERSION;
+ pa_log_info("Storing profile %s for port %s on card %s.", p_info->profile, p->name, card->name);
+ }
+}
+
static pa_hook_result_t card_profile_changed_callback(pa_core *c, pa_card *card, struct userdata *u) {
struct entry *entry;
+ pa_sink *sink;
+ pa_source *source;
+ uint32_t state;
pa_assert(card);
@@ -392,6 +424,11 @@ static pa_hook_result_t card_profile_changed_callback(pa_core *c, pa_card *card,
show_full_info(card);
}
+ PA_IDXSET_FOREACH(sink, card->sinks, state)
+ update_profile_for_port(entry, card, sink->active_port);
+ PA_IDXSET_FOREACH(source, card->sources, state)
+ update_profile_for_port(entry, card, source->active_port);
+
if (entry_write(u, card->name, entry))
trigger_save(u);
@@ -508,9 +545,11 @@ static pa_hook_result_t card_new_hook_callback(pa_core *c, pa_card_new_data *new
pa_log_info("Restoring port latency offsets for card %s.", new_data->name);
PA_HASHMAP_FOREACH(p_info, e->ports, state)
- if ((p = pa_hashmap_get(new_data->ports, p_info->name)))
+ if ((p = pa_hashmap_get(new_data->ports, p_info->name))) {
p->latency_offset = p_info->offset;
-
+ if (!p->preferred_profile && p_info->profile)
+ pa_device_port_set_preferred_profile(p, p_info->profile);
+ }
entry_free(e);
return PA_HOOK_OK;
commit 5c545ba38be33bfc5334a70edacba24f06271af5
Author: David Henningsson <david.henningsson at canonical.com>
Date: Tue Nov 17 15:10:32 2015 +0100
card: Update preferred_profile for ports when profile changes
Signed-off-by: David Henningsson <david.henningsson at canonical.com>
diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c
index bb21d0f..0ca78bb 100644
--- a/src/pulsecore/card.c
+++ b/src/pulsecore/card.c
@@ -250,8 +250,19 @@ void pa_card_add_profile(pa_card *c, pa_card_profile *profile) {
pa_hook_fire(&c->core->hooks[PA_CORE_HOOK_CARD_PROFILE_ADDED], profile);
}
+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;
+}
+
int pa_card_set_profile(pa_card *c, pa_card_profile *profile, bool save) {
int r;
+ pa_sink *sink;
+ pa_source *source;
+ uint32_t state;
pa_assert(c);
pa_assert(profile);
@@ -277,6 +288,13 @@ int pa_card_set_profile(pa_card *c, pa_card_profile *profile, bool save) {
c->active_profile = profile;
c->save_profile = save;
+ PA_IDXSET_FOREACH(sink, c->sinks, state)
+ if (sink->active_port)
+ pa_device_port_set_preferred_profile(sink->active_port, profile_name_for_dir(profile, PA_DIRECTION_OUTPUT));
+ PA_IDXSET_FOREACH(source, c->sources, state)
+ if (source->active_port)
+ pa_device_port_set_preferred_profile(source->active_port, profile_name_for_dir(profile, PA_DIRECTION_INPUT));
+
pa_hook_fire(&c->core->hooks[PA_CORE_HOOK_CARD_PROFILE_CHANGED], c);
return 0;
commit b1d9b4f62c2f132292efaba862e8490114882ad2
Author: David Henningsson <david.henningsson at canonical.com>
Date: Tue Nov 17 15:10:31 2015 +0100
device-port: Add preferred_profile field to pa_device_port
Signed-off-by: David Henningsson <david.henningsson at canonical.com>
diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c
index 906ab1f..5807d3e 100644
--- a/src/pulsecore/device-port.c
+++ b/src/pulsecore/device-port.c
@@ -21,6 +21,7 @@
#include "device-port.h"
#include <pulsecore/card.h>
+#include <pulsecore/core-util.h>
PA_DEFINE_PUBLIC_CLASS(pa_device_port, pa_object);
@@ -65,6 +66,15 @@ void pa_device_port_new_data_done(pa_device_port_new_data *data) {
pa_xfree(data->description);
}
+void pa_device_port_set_preferred_profile(pa_device_port *p, const char *new_pp) {
+ pa_assert(p);
+
+ if (!pa_safe_streq(p->preferred_profile, new_pp)) {
+ pa_xfree(p->preferred_profile);
+ p->preferred_profile = pa_xstrdup(new_pp);
+ }
+}
+
void pa_device_port_set_available(pa_device_port *p, pa_available_t status) {
pa_assert(p);
@@ -100,6 +110,7 @@ static void device_port_free(pa_object *o) {
if (p->profiles)
pa_hashmap_free(p->profiles);
+ pa_xfree(p->preferred_profile);
pa_xfree(p->name);
pa_xfree(p->description);
pa_xfree(p);
diff --git a/src/pulsecore/device-port.h b/src/pulsecore/device-port.h
index f35d07c..e3224fd 100644
--- a/src/pulsecore/device-port.h
+++ b/src/pulsecore/device-port.h
@@ -43,6 +43,7 @@ struct pa_device_port {
char *name;
char *description;
+ char *preferred_profile;
unsigned priority;
pa_available_t available; /* PA_AVAILABLE_UNKNOWN, PA_AVAILABLE_NO or PA_AVAILABLE_YES */
@@ -80,6 +81,7 @@ pa_device_port *pa_device_port_new(pa_core *c, pa_device_port_new_data *data, si
void pa_device_port_set_available(pa_device_port *p, pa_available_t available);
void pa_device_port_set_latency_offset(pa_device_port *p, int64_t offset);
+void pa_device_port_set_preferred_profile(pa_device_port *p, const char *new_pp);
pa_device_port *pa_device_port_find_best(pa_hashmap *ports);
commit 2a71fd7597dd76eb6abab867cd3762429792f680
Author: David Henningsson <david.henningsson at canonical.com>
Date: Tue Nov 17 15:10:30 2015 +0100
alsa-mixer: Fill in input and output names
Fill in input_name and output_name to make routing easier for
routing modules.
Signed-off-by: David Henningsson <david.henningsson at canonical.com>
diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index af7adea..3f51717 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -3473,6 +3473,8 @@ static void profile_free(pa_alsa_profile *p) {
pa_xfree(p->name);
pa_xfree(p->description);
+ pa_xfree(p->input_name);
+ pa_xfree(p->output_name);
pa_xstrfreev(p->input_mapping_names);
pa_xstrfreev(p->output_mapping_names);
@@ -4123,6 +4125,7 @@ static void profile_set_add_auto_pair(
p->name = name;
if (m) {
+ p->output_name = pa_xstrdup(m->name);
p->output_mappings = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
pa_idxset_put(p->output_mappings, m, NULL);
p->priority += m->priority * 100;
@@ -4130,6 +4133,7 @@ static void profile_set_add_auto_pair(
}
if (n) {
+ p->input_name = pa_xstrdup(n->name);
p->input_mappings = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
pa_idxset_put(p->input_mappings, n, NULL);
p->priority += n->priority;
@@ -4292,9 +4296,11 @@ void pa_alsa_profile_dump(pa_alsa_profile *p) {
pa_alsa_mapping *m;
pa_assert(p);
- pa_log_debug("Profile %s (%s), priority=%u, supported=%s n_input_mappings=%u, n_output_mappings=%u",
+ pa_log_debug("Profile %s (%s), input=%s, output=%s priority=%u, supported=%s n_input_mappings=%u, n_output_mappings=%u",
p->name,
pa_strnull(p->description),
+ pa_strnull(p->input_name),
+ pa_strnull(p->output_name),
p->priority,
pa_yes_no(p->supported),
p->input_mappings ? pa_idxset_size(p->input_mappings) : 0,
diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h
index 621a71b..4ebf192 100644
--- a/src/modules/alsa/alsa-mixer.h
+++ b/src/modules/alsa/alsa-mixer.h
@@ -293,6 +293,9 @@ struct pa_alsa_profile {
char *description;
unsigned priority;
+ char *input_name;
+ char *output_name;
+
bool supported:1;
bool fallback_input:1;
bool fallback_output:1;
diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
index e173e51..286cfc9 100644
--- a/src/modules/alsa/module-alsa-card.c
+++ b/src/modules/alsa/module-alsa-card.c
@@ -143,6 +143,8 @@ static void add_profiles(struct userdata *u, pa_hashmap *h, pa_hashmap *ports) {
cp = pa_card_profile_new(ap->name, ap->description, sizeof(struct profile_data));
cp->priority = ap->priority;
+ cp->input_name = pa_xstrdup(ap->input_name);
+ cp->output_name = pa_xstrdup(ap->output_name);
if (ap->output_mappings) {
cp->n_sinks = pa_idxset_size(ap->output_mappings);
commit b9818b016f021a80ab8c4ca9f2360756eefe2a87
Author: David Henningsson <david.henningsson at canonical.com>
Date: Tue Nov 17 15:10:29 2015 +0100
card: Add variables for splitting up a profile
It can be useful for routing modules to know a profile's input
and output parts, in order to e g change output profile
while keeping the input profile unchanged.
For now filling in these fields is optional and a routing module
must be able to handle NULL in these fields.
Signed-off-by: David Henningsson <david.henningsson at canonical.com>
diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c
index c8b97b7..bb21d0f 100644
--- a/src/pulsecore/card.c
+++ b/src/pulsecore/card.c
@@ -52,6 +52,8 @@ pa_card_profile *pa_card_profile_new(const char *name, const char *description,
void pa_card_profile_free(pa_card_profile *c) {
pa_assert(c);
+ pa_xfree(c->input_name);
+ pa_xfree(c->output_name);
pa_xfree(c->name);
pa_xfree(c->description);
pa_xfree(c);
diff --git a/src/pulsecore/card.h b/src/pulsecore/card.h
index 3e2c004..a72c8c2 100644
--- a/src/pulsecore/card.h
+++ b/src/pulsecore/card.h
@@ -40,6 +40,14 @@ typedef struct pa_card_profile {
char *name;
char *description;
+ /* Identifiers for the profile's input and output parts, i e, if two different profiles
+ have the same input_name string, they have the same source(s).
+ Same for output_name and sink(s).
+ Can be NULL (and in case of an input- or output- only profile, the other direction
+ will be NULL). */
+ char *input_name;
+ char *output_name;
+
unsigned priority;
pa_available_t available; /* PA_AVAILABLE_UNKNOWN, PA_AVAILABLE_NO or PA_AVAILABLE_YES */
More information about the pulseaudio-commits
mailing list