mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2026-05-06 09:28:18 +02:00
module-default-nodes: prioritize previous configured defaults
The node priorities are difficult to configure for users, and are not necessarily meaningful for them. When there is no configured default node, or the configured default node does not exist, prioritize previously configured default nodes over the automatic node priorities. Keep track of a stack of previous configured nodes, and update the stack when the configured node changes.
This commit is contained in:
parent
41a6a9d65a
commit
7a1b48b741
1 changed files with 70 additions and 9 deletions
|
|
@ -19,6 +19,7 @@
|
|||
#define DEFAULT_AUTO_ECHO_CANCEL TRUE
|
||||
#define DEFAULT_ECHO_CANCEL_SINK_NAME "echo-cancel-sink"
|
||||
#define DEFAULT_ECHO_CANCEL_SOURCE_NAME "echo-cancel-source"
|
||||
#define N_PREV_CONFIGS 16
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
|
|
@ -34,6 +35,7 @@ struct _WpDefaultNode
|
|||
{
|
||||
gchar *value;
|
||||
gchar *config_value;
|
||||
gchar *prev_config_value[N_PREV_CONFIGS];
|
||||
};
|
||||
|
||||
struct _WpDefaultNodes
|
||||
|
|
@ -62,13 +64,49 @@ wp_default_nodes_init (WpDefaultNodes * self)
|
|||
{
|
||||
}
|
||||
|
||||
static void
|
||||
update_prev_config_values (WpDefaultNode *def)
|
||||
{
|
||||
gint pos = N_PREV_CONFIGS - 1;
|
||||
|
||||
if (!def->config_value)
|
||||
return;
|
||||
|
||||
/* Find if the current configured value is already in the stack */
|
||||
for (gint i = 0; i < N_PREV_CONFIGS; ++i) {
|
||||
if (!g_strcmp0(def->config_value, def->prev_config_value[i])) {
|
||||
pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos == 0)
|
||||
return;
|
||||
|
||||
/* Insert on top position */
|
||||
g_clear_pointer (&def->prev_config_value[pos], g_free);
|
||||
|
||||
for (gint i = pos; i > 0; --i)
|
||||
def->prev_config_value[i] = def->prev_config_value[i-1];
|
||||
|
||||
def->prev_config_value[0] = g_strdup(def->config_value);
|
||||
}
|
||||
|
||||
static void
|
||||
load_state (WpDefaultNodes * self)
|
||||
{
|
||||
g_autoptr (WpProperties) props = wp_state_load (self->state);
|
||||
for (gint i = 0; i < N_DEFAULT_NODES; i++) {
|
||||
const gchar *value = wp_properties_get (props, DEFAULT_CONFIG_KEY[i]);
|
||||
|
||||
self->defaults[i].config_value = g_strdup (value);
|
||||
|
||||
for (gint j = 0; j < N_PREV_CONFIGS; ++j) {
|
||||
g_autofree gchar *key = g_strdup_printf("%s.%d", DEFAULT_CONFIG_KEY[i], j);
|
||||
|
||||
value = wp_properties_get (props, key);
|
||||
self->defaults[i].prev_config_value[j] = g_strdup(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -82,6 +120,12 @@ timeout_save_state_callback (WpDefaultNodes *self)
|
|||
if (self->defaults[i].config_value)
|
||||
wp_properties_set (props, DEFAULT_CONFIG_KEY[i],
|
||||
self->defaults[i].config_value);
|
||||
|
||||
for (gint j = 0; j < N_PREV_CONFIGS; ++j) {
|
||||
g_autofree gchar *key = g_strdup_printf("%s.%d", DEFAULT_CONFIG_KEY[i], j);
|
||||
|
||||
wp_properties_set (props, key, self->defaults[i].prev_config_value[j]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!wp_state_save (self->state, props, &error))
|
||||
|
|
@ -209,7 +253,7 @@ is_echo_cancel_node (WpDefaultNodes * self, WpNode *node, WpDirection direction)
|
|||
|
||||
static WpNode *
|
||||
find_best_media_class_node (WpDefaultNodes * self, const gchar *media_class,
|
||||
const gchar *node_name, WpDirection direction, gint *priority)
|
||||
const WpDefaultNode *def, WpDirection direction, gint *priority)
|
||||
{
|
||||
g_autoptr (WpIterator) it = NULL;
|
||||
g_auto (GValue) val = G_VALUE_INIT;
|
||||
|
|
@ -243,8 +287,20 @@ find_best_media_class_node (WpDefaultNodes * self, const gchar *media_class,
|
|||
if (self->auto_echo_cancel && is_echo_cancel_node (self, node, direction))
|
||||
prio += 10000;
|
||||
|
||||
if (name && node_name && g_strcmp0 (name, node_name) == 0)
|
||||
prio += 20000;
|
||||
if (name && def->config_value && g_strcmp0 (name, def->config_value) == 0) {
|
||||
prio += 20000 * (N_PREV_CONFIGS + 1);
|
||||
} else if (name) {
|
||||
for (gint i = 0; i < N_PREV_CONFIGS; ++i) {
|
||||
if (!def->prev_config_value[i])
|
||||
continue;
|
||||
|
||||
/* Match by name */
|
||||
if (g_strcmp0 (name, def->prev_config_value[i]) == 0) {
|
||||
prio += (N_PREV_CONFIGS - i) * 20000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prio > highest_prio || res == NULL) {
|
||||
highest_prio = prio;
|
||||
|
|
@ -260,14 +316,14 @@ find_best_media_class_node (WpDefaultNodes * self, const gchar *media_class,
|
|||
|
||||
static WpNode *
|
||||
find_best_media_classes_node (WpDefaultNodes * self,
|
||||
const gchar **media_classes, const gchar *node_name, WpDirection direction)
|
||||
const gchar **media_classes, const WpDefaultNode *def, WpDirection direction)
|
||||
{
|
||||
gint highest_prio = -1;
|
||||
WpNode *res = NULL;
|
||||
for (guint i = 0; media_classes[i]; i++) {
|
||||
gint prio = -1;
|
||||
WpNode *node = find_best_media_class_node (self, media_classes[i],
|
||||
node_name, direction, &prio);
|
||||
def, direction, &prio);
|
||||
if (node && (!res || prio > highest_prio)) {
|
||||
highest_prio = prio;
|
||||
res = node;
|
||||
|
|
@ -279,7 +335,7 @@ find_best_media_classes_node (WpDefaultNodes * self,
|
|||
static WpNode *
|
||||
find_best_node (WpDefaultNodes * self, gint node_t)
|
||||
{
|
||||
const gchar *name = self->defaults[node_t].config_value;
|
||||
const WpDefaultNode *def = &self->defaults[node_t];
|
||||
|
||||
switch (node_t) {
|
||||
case AUDIO_SINK: {
|
||||
|
|
@ -287,7 +343,7 @@ find_best_node (WpDefaultNodes * self, gint node_t)
|
|||
"Audio/Sink",
|
||||
"Audio/Duplex",
|
||||
NULL};
|
||||
return find_best_media_classes_node (self, media_classes, name,
|
||||
return find_best_media_classes_node (self, media_classes, def,
|
||||
WP_DIRECTION_INPUT);
|
||||
}
|
||||
case AUDIO_SOURCE: {
|
||||
|
|
@ -297,7 +353,7 @@ find_best_node (WpDefaultNodes * self, gint node_t)
|
|||
"Audio/Duplex",
|
||||
"Audio/Sink",
|
||||
NULL};
|
||||
return find_best_media_classes_node (self, media_classes, name,
|
||||
return find_best_media_classes_node (self, media_classes, def,
|
||||
WP_DIRECTION_OUTPUT);
|
||||
}
|
||||
case VIDEO_SOURCE: {
|
||||
|
|
@ -305,7 +361,7 @@ find_best_node (WpDefaultNodes * self, gint node_t)
|
|||
"Video/Source",
|
||||
"Video/Source/Virtual",
|
||||
NULL};
|
||||
return find_best_media_classes_node (self, media_classes, name,
|
||||
return find_best_media_classes_node (self, media_classes, def,
|
||||
WP_DIRECTION_OUTPUT);
|
||||
}
|
||||
default:
|
||||
|
|
@ -408,6 +464,8 @@ on_metadata_changed (WpMetadata *m, guint32 subject,
|
|||
self->defaults[node_t].config_value = g_strdup (name);
|
||||
}
|
||||
|
||||
update_prev_config_values (&self->defaults[node_t]);
|
||||
|
||||
wp_debug_object (m, "changed '%s' -> '%s'", key,
|
||||
self->defaults[node_t].config_value);
|
||||
|
||||
|
|
@ -507,6 +565,9 @@ wp_default_nodes_disable (WpPlugin * plugin)
|
|||
for (guint i = 0; i < N_DEFAULT_NODES; i++) {
|
||||
g_clear_pointer (&self->defaults[i].value, g_free);
|
||||
g_clear_pointer (&self->defaults[i].config_value, g_free);
|
||||
|
||||
for (guint j = 0; j < N_PREV_CONFIGS; j++)
|
||||
g_clear_pointer (&self->defaults[i].prev_config_value[j], g_free);
|
||||
}
|
||||
|
||||
g_clear_object (&self->metadata_om);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue