mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-04 13:29:59 -05:00
card-restore: Save and restore "preferred profile" of port
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
This commit is contained in:
parent
5c545ba38b
commit
9059fb3b4e
1 changed files with 44 additions and 5 deletions
|
|
@ -64,11 +64,12 @@ struct userdata {
|
||||||
pa_database *database;
|
pa_database *database;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ENTRY_VERSION 2
|
#define ENTRY_VERSION 3
|
||||||
|
|
||||||
struct port_info {
|
struct port_info {
|
||||||
char *name;
|
char *name;
|
||||||
int64_t offset;
|
int64_t offset;
|
||||||
|
char *profile;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct entry {
|
struct entry {
|
||||||
|
|
@ -102,6 +103,7 @@ static void trigger_save(struct userdata *u) {
|
||||||
static void port_info_free(struct port_info *p_info) {
|
static void port_info_free(struct port_info *p_info) {
|
||||||
pa_assert(p_info);
|
pa_assert(p_info);
|
||||||
|
|
||||||
|
pa_xfree(p_info->profile);
|
||||||
pa_xfree(p_info->name);
|
pa_xfree(p_info->name);
|
||||||
pa_xfree(p_info);
|
pa_xfree(p_info);
|
||||||
}
|
}
|
||||||
|
|
@ -117,9 +119,11 @@ static struct port_info *port_info_new(pa_device_port *port) {
|
||||||
struct port_info *p_info;
|
struct port_info *p_info;
|
||||||
|
|
||||||
if (port) {
|
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->name = pa_xstrdup(port->name);
|
||||||
p_info->offset = port->latency_offset;
|
p_info->offset = port->latency_offset;
|
||||||
|
if (port->preferred_profile)
|
||||||
|
p_info->profile = pa_xstrdup(port->preferred_profile);
|
||||||
} else
|
} else
|
||||||
p_info = pa_xnew0(struct port_info, 1);
|
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_HASHMAP_FOREACH(p_info, e->ports, state) {
|
||||||
pa_tagstruct_puts(t, p_info->name);
|
pa_tagstruct_puts(t, p_info->name);
|
||||||
pa_tagstruct_puts64(t, p_info->offset);
|
pa_tagstruct_puts64(t, p_info->offset);
|
||||||
|
if (e->version >= 3)
|
||||||
|
pa_tagstruct_puts(t, p_info->profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
key.data = (char *) name;
|
key.data = (char *) name;
|
||||||
|
|
@ -283,7 +289,7 @@ static struct entry* entry_read(struct userdata *u, const char *name) {
|
||||||
|
|
||||||
if (e->version >= 2) {
|
if (e->version >= 2) {
|
||||||
uint32_t port_count = 0;
|
uint32_t port_count = 0;
|
||||||
const char *port_name = NULL;
|
const char *port_name = NULL, *profile_name = NULL;
|
||||||
int64_t port_offset = 0;
|
int64_t port_offset = 0;
|
||||||
struct port_info *p_info;
|
struct port_info *p_info;
|
||||||
unsigned i;
|
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_hashmap_get(e->ports, port_name) ||
|
||||||
pa_tagstruct_gets64(t, &port_offset) < 0)
|
pa_tagstruct_gets64(t, &port_offset) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
if (e->version >= 3 && pa_tagstruct_gets(t, &profile_name) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
p_info = port_info_new(NULL);
|
p_info = port_info_new(NULL);
|
||||||
p_info->name = pa_xstrdup(port_name);
|
p_info->name = pa_xstrdup(port_name);
|
||||||
p_info->offset = port_offset;
|
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);
|
pa_assert_se(pa_hashmap_put(e->ports, p_info->name, p_info) >= 0);
|
||||||
}
|
}
|
||||||
|
|
@ -375,8 +385,30 @@ finish:
|
||||||
return PA_HOOK_OK;
|
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) {
|
static pa_hook_result_t card_profile_changed_callback(pa_core *c, pa_card *card, struct userdata *u) {
|
||||||
struct entry *entry;
|
struct entry *entry;
|
||||||
|
pa_sink *sink;
|
||||||
|
pa_source *source;
|
||||||
|
uint32_t state;
|
||||||
|
|
||||||
pa_assert(card);
|
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);
|
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))
|
if (entry_write(u, card->name, entry))
|
||||||
trigger_save(u);
|
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_log_info("Restoring port latency offsets for card %s.", new_data->name);
|
||||||
|
|
||||||
PA_HASHMAP_FOREACH(p_info, e->ports, state)
|
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;
|
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);
|
entry_free(e);
|
||||||
|
|
||||||
return PA_HOOK_OK;
|
return PA_HOOK_OK;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue