m-default-nodes{-api}: optimize for event-stack

- Sharpen the hooks, so that they are called only when needed.
- Make settings live, apply them when they are changed.
- Remove the state saver after events hook, call it directly.
- Remove the settings bookkeeping as the gobject properties.
- Remove the scheduling of default-nodes-changed signal via core.
This commit is contained in:
Ashok Sidipotu
2022-08-30 11:47:43 +05:30
committed by Julian Bouzas
parent a5a6300662
commit a060c6a130
5 changed files with 215 additions and 237 deletions

View File

@@ -326,8 +326,7 @@ wp_event_source_dispatch (GSource * s, GSourceFunc callback, gpointer user_data)
g_steal_pointer (&lhook));
event->hooks_chain = build_chain (name, priority, event->hooks_chain);
wp_trace_object (d, "running hook <%p>(%s) and hooks chain (%s)", hook, name,
event->hooks_chain);
wp_trace_object (d, "running hook <%p>(%s)", hook, name);
if ((event == d->rescan_event) &&
(type == WP_EVENT_HOOK_EXEC_TYPE_AFTER_EVENTS_WITH_EVENT)) {

View File

@@ -36,8 +36,7 @@ typedef enum
WP_EVENT_HOOK_DEFAULT_PRIORITY_FIND_DEFAULT_TARGET_SI = WP_EVENT_HOOK_DEFAULT_PRIORITY_FIND_BEST_TARGET_SI + PRIORITY_STEP,
WP_EVENT_HOOK_DEFAULT_PRIORITY_FIND_DEFINED_TARGET_SI = WP_EVENT_HOOK_DEFAULT_PRIORITY_FIND_DEFAULT_TARGET_SI + PRIORITY_STEP,
WP_EVENT_HOOK_DEFAULT_PRIORITY_RESCAN_POLICY = WP_EVENT_HOOK_DEFAULT_PRIORITY_FIND_DEFINED_TARGET_SI + PRIORITY_STEP,
WP_EVENT_HOOK_DEFAULT_PRIORITY_AFTER_EVENTS_DEFAULT_NODES_STATE_SAVE = WP_EVENT_HOOK_DEFAULT_PRIORITY_RESCAN_POLICY + PRIORITY_STEP,
WP_EVENT_HOOK_DEFAULT_PRIORITY_RESCAN_DEFAULT_NODES = WP_EVENT_HOOK_DEFAULT_PRIORITY_AFTER_EVENTS_DEFAULT_NODES_STATE_SAVE + PRIORITY_STEP,
WP_EVENT_HOOK_DEFAULT_PRIORITY_RESCAN_DEFAULT_NODES = WP_EVENT_HOOK_DEFAULT_PRIORITY_RESCAN_POLICY + PRIORITY_STEP,
WP_EVENT_HOOK_DEFAULT_PRIORITY_NODE_ADDED = WP_EVENT_HOOK_DEFAULT_PRIORITY_RESCAN_POLICY + PRIORITY_JUMP,
WP_EVENT_HOOK_DEFAULT_PRIORITY_NODE_ADDED_RESTORE_STREAM = WP_EVENT_HOOK_DEFAULT_PRIORITY_NODE_ADDED,

View File

@@ -50,31 +50,6 @@ wp_default_nodes_api_init (WpDefaultNodesApi * self)
{
}
static void
sync_changed_notification (WpCore * core, GAsyncResult * res,
WpDefaultNodesApi * self)
{
g_autoptr (GError) error = NULL;
if (!wp_core_sync_finish (core, res, &error)) {
wp_warning_object (self, "core sync error: %s", error->message);
return;
}
g_signal_emit (self, signals[SIGNAL_CHANGED], 0);
return;
}
static void
schedule_changed_notification (WpDefaultNodesApi *self)
{
g_autoptr (WpCore) core = wp_object_get_core (WP_OBJECT (self));
g_return_if_fail (core);
// Event-Stack TBD: do we need to retain this behavior? or push this as a
// event & hook pair on to event stack
wp_core_sync_closure (core, NULL, g_cclosure_new_object (
G_CALLBACK (sync_changed_notification), G_OBJECT (self)));
}
static void
on_metadata_changed (WpMetadata *m, guint32 subject,
const gchar *key, const gchar *type, const gchar *value, gpointer d)
@@ -98,7 +73,7 @@ on_metadata_changed (WpMetadata *m, guint32 subject,
}
}
schedule_changed_notification (self);
g_signal_emit (self, signals [SIGNAL_CHANGED], 0);
break;
} else if (!g_strcmp0 (key, DEFAULT_CONFIG_KEY[i])) {
@@ -149,8 +124,10 @@ on_metadata_added (WpEvent *event, gpointer d)
for (; wp_iterator_next (it, &val); g_value_unset (&val)) {
guint32 subject_id;
const gchar *key, *type, *value;
wp_metadata_iterator_item_extract (&val, &subject_id, &key, &type, &value);
on_metadata_changed (WP_METADATA (obj), subject_id, key, type, value, self);
wp_metadata_iterator_item_extract (&val, &subject_id, &key, &type,
&value);
on_metadata_changed (WP_METADATA (obj), subject_id, key, type, value,
self);
}
}
}
@@ -190,11 +167,31 @@ wp_default_nodes_api_enable (WpPlugin * plugin, WpTransition * transition)
WP_EVENT_HOOK_DEFAULT_PRIORITY_DEFAULT_METADATA_CHANGED_DEFAULT_NODES_API,
WP_EVENT_HOOK_EXEC_TYPE_ON_EVENT,
g_cclosure_new ((GCallback) on_metadata_changed_hook, self, NULL));
wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook),
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata",
WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default",
NULL);
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.key", "=s",
"default.audio.sink",
WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default",
NULL);
wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook),
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.key", "=s",
"default.video.sink",
WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default",
NULL);
wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook),
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.key", "=s",
"default.audio.source",
WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default",
NULL);
wp_event_dispatcher_register_hook (dispatcher, hook);
g_clear_object(&hook);

View File

@@ -21,22 +21,13 @@
#define DEFAULT_ECHO_CANCEL_SOURCE_NAME "echo-cancel-source"
#define N_PREV_CONFIGS 16
enum {
PROP_0,
PROP_SAVE_INTERVAL_MS,
PROP_USE_PERSISTENT_STORAGE,
PROP_AUTO_ECHO_CANCEL,
PROP_ECHO_CANCEL_SINK_NAME,
PROP_ECHO_CANCEL_SOURCE_NAME,
};
/*
* Module maintains the default devices to be used for a given media class. The
* module looks for changes in user preference and the changes in devices(when
* new devices like headsets, BT devices, HDMI etc are plugged in). User
* preference can be expressed via pavuctrl, gnome settings or metadata etc.
* These apps typically update the
* default.configured.*(default-configured-nodes) keys.
* Module comes up with the default audio and video devices. It looks for
* changes in user preference and the changes in devices(when new devices like
* headsets, BT devices, HDMI etc are plugged in or removed). User preference
* can be expressed via pavuctrl, gnome settings or metadata etc. These apps
* typically update the default.configured.*(default-configured-nodes) keys.
* Additionally the user preferences are remembered across reboots.
*/
/*
@@ -62,19 +53,34 @@ struct _WpDefaultNodes
GSource *timeout_source;
/* properties */
guint save_interval_ms;
gint save_interval_ms;
gboolean use_persistent_storage;
gboolean auto_echo_cancel;
gchar *echo_cancel_names[2];
gchar *echo_cancel_names [2];
WpSettings *settings;
guintptr settings_sub_id;
};
G_DECLARE_FINAL_TYPE (WpDefaultNodes, wp_default_nodes,
WP, DEFAULT_NODES, WpPlugin)
G_DEFINE_TYPE (WpDefaultNodes, wp_default_nodes, WP_TYPE_PLUGIN)
static void
init_settings (WpDefaultNodes *self)
{
self->save_interval_ms = DEFAULT_SAVE_INTERVAL_MS;
self->use_persistent_storage = DEFAULT_USE_PERSISTENT_STORAGE;
self->auto_echo_cancel = DEFAULT_AUTO_ECHO_CANCEL;
self->echo_cancel_names [WP_DIRECTION_INPUT] =
g_strdup (DEFAULT_ECHO_CANCEL_SOURCE_NAME);
self->echo_cancel_names [WP_DIRECTION_OUTPUT] =
g_strdup (DEFAULT_ECHO_CANCEL_SINK_NAME);
}
static void
wp_default_nodes_init (WpDefaultNodes * self)
{
init_settings (self);
}
static void
@@ -149,9 +155,8 @@ timeout_save_state_callback (WpDefaultNodes *self)
}
static void
timer_start (WpEvent *event, gpointer d)
timer_start (WpDefaultNodes *self)
{
WpDefaultNodes * self = WP_DEFAULT_NODES (d);
if (!self->timeout_source && self->use_persistent_storage) {
g_autoptr (WpCore) core = wp_object_get_core (WP_OBJECT (self));
g_return_if_fail (core);
@@ -419,15 +424,10 @@ reevaluate_default_node (WpDefaultNodes * self, WpMetadata *m, gint node_t)
}
static void
sync_rescan (WpCore * core, GAsyncResult * res, WpDefaultNodes * self)
rescan (WpEvent *event, gpointer d)
{
WpDefaultNodes *self = WP_DEFAULT_NODES (d);
g_autoptr (WpMetadata) metadata = NULL;
g_autoptr (GError) error = NULL;
if (!wp_core_sync_finish (core, res, &error)) {
wp_warning_object (self, "core sync error: %s", error->message);
return;
}
/* Get the metadata */
metadata = wp_object_manager_lookup (self->metadata_om, WP_TYPE_METADATA,
@@ -441,20 +441,6 @@ sync_rescan (WpCore * core, GAsyncResult * res, WpDefaultNodes * self)
reevaluate_default_node (self, metadata, VIDEO_SOURCE);
}
static void
schedule_rescan (WpEvent *event, gpointer d)
{
WpDefaultNodes * self = WP_DEFAULT_NODES (d);
g_autoptr (WpCore) core = wp_object_get_core (WP_OBJECT (self));
g_return_if_fail (core);
wp_debug_object (self, "scheduling default nodes rescan");
// Event-Stack TBD: do we need to retain this behavior? or push this as a
// event & hook pair on to event stack
wp_core_sync_closure (core, NULL, g_cclosure_new_object (
G_CALLBACK (sync_rescan), G_OBJECT (self)));
}
static void
on_metadata_changed (WpEvent *event, gpointer d)
{
@@ -493,9 +479,6 @@ on_metadata_changed (WpEvent *event, gpointer d)
wp_debug_object (m, "changed '%s' -> '%s'", key,
self->defaults[node_t].config_value);
/* schedule rescan */
schedule_rescan (self);
/* Save state after specific interval */
timer_start (self);
}
@@ -520,6 +503,75 @@ on_metadata_added (WpEvent *event, gpointer d)
}
}
static void
get_settings (WpDefaultNodes *self, const gchar *setting)
{
if (!setting || (g_str_equal ("device.save-interval-ms", setting)))
{
g_autoptr (WpSpaJson) j = wp_settings_get (self->settings,
"device.save-interval-ms");
if (j && !wp_spa_json_parse_int (j, &self->save_interval_ms))
wp_warning ("Failed to parse integer in device.save-interval-ms");
}
if (!setting || (g_str_equal ("device.use-persistent-storage", setting)))
{
g_autoptr (WpSpaJson) j = wp_settings_get (self->settings,
"device.use-persistent-storage");
if (j && !wp_spa_json_parse_boolean (j, &self->use_persistent_storage))
wp_warning ("Failed to parse boolean in device.use-persistent-storage");
}
if (!setting || (g_str_equal ("device.auto-echo-cancel", setting)))
{
g_autoptr (WpSpaJson) j = wp_settings_get (self->settings,
"device.auto-echo-cancel");
if (j && !wp_spa_json_parse_boolean (j, &self->auto_echo_cancel))
wp_warning ("Failed to parse boolean in device.auto-echo-cancel");
}
if (!setting || (g_str_equal ("device.echo-cancel-sink-name", setting)))
{
g_autoptr (WpSpaJson) j = wp_settings_get (self->settings,
"device.echo-cancel-sink-name");
if (j) {
gchar *value = wp_spa_json_parse_string (j);
if (!value)
wp_warning ("Failed to parse string in device.echo-cancel-sink-name");
else {
g_free (self->echo_cancel_names [WP_DIRECTION_OUTPUT]);
self->echo_cancel_names [WP_DIRECTION_OUTPUT] = value;
}
}
}
if (!setting || (g_str_equal ("device.echo-cancel-source-name", setting)))
{
g_autoptr (WpSpaJson) j = wp_settings_get (self->settings,
"device.echo-cancel-source-name");
if (j) {
gchar *value = wp_spa_json_parse_string (j);
if (!value)
wp_warning ("Failed to parse string in device.echo-cancel-source-name");
else {
g_free (self->echo_cancel_names [WP_DIRECTION_INPUT]);
self->echo_cancel_names [WP_DIRECTION_INPUT] = value;
}
}
}
}
void
wp_settings_changed_callback (WpSettings *obj, const gchar *setting,
const gchar *raw_value, gpointer user_data)
{
WpDefaultNodes *self = WP_DEFAULT_NODES (user_data);
g_return_if_fail (self);
g_return_if_fail (setting);
get_settings (self, setting);
}
static void
wp_default_nodes_enable (WpPlugin * plugin, WpTransition * transition)
{
@@ -531,6 +583,13 @@ wp_default_nodes_enable (WpPlugin * plugin, WpTransition * transition)
g_autoptr (WpEventHook) hook = NULL;
g_return_if_fail (dispatcher);
self->settings = wp_settings_get_instance (core, NULL);
g_return_if_fail (self->settings);
self->settings_sub_id = wp_settings_subscribe (self->settings, "device*",
wp_settings_changed_callback, (gpointer) self);
get_settings (self, NULL);
/* default metadata added */
hook = wp_simple_event_hook_new ("metadata-added@default-nodes",
WP_EVENT_HOOK_DEFAULT_PRIORITY_DEFAULT_METADATA_ADDED_DEFAULT_NODES,
@@ -549,58 +608,92 @@ wp_default_nodes_enable (WpPlugin * plugin, WpTransition * transition)
WP_EVENT_HOOK_DEFAULT_PRIORITY_DEFAULT_METADATA_CHANGED_DEFAULT_NODES,
WP_EVENT_HOOK_EXEC_TYPE_ON_EVENT,
g_cclosure_new ((GCallback) on_metadata_changed, self, NULL));
wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook),
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata",
WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default",
NULL);
wp_event_dispatcher_register_hook (dispatcher, hook);
g_clear_object(&hook);
/* register rescan hook as an after event */
hook = wp_simple_event_hook_new("rescan-default-nodes",
WP_EVENT_HOOK_DEFAULT_PRIORITY_RESCAN_DEFAULT_NODES,
WP_EVENT_HOOK_EXEC_TYPE_AFTER_EVENTS,
g_cclosure_new ((GCallback) schedule_rescan, self, NULL));
/* default metadata changed */
wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook),
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata",
WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default",
NULL);
/* device changed */
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.key", "=s",
"default.configured.audio.sink",
WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default",
NULL);
wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook),
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "device",
NULL);
/* node changed */
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.key", "=s",
"default.configured.video.sink",
WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default",
NULL);
wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook),
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "node",
NULL);
/* device parms changed */
wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook),
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "params-changed",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "device",
NULL);
/* node parms changed */
wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook),
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "params-changed",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "node",
NULL);
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.key", "=s",
"default.configured.audio.source",
WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default",
NULL);
wp_event_dispatcher_register_hook (dispatcher, hook);
g_clear_object (&hook);
/* register state save hook as an after event */
hook = wp_simple_event_hook_new ("default-nodes-state-saver",
WP_EVENT_HOOK_DEFAULT_PRIORITY_AFTER_EVENTS_DEFAULT_NODES_STATE_SAVE,
/* register rescan hook as an after event */
hook = wp_simple_event_hook_new("rescan@default-nodes",
WP_EVENT_HOOK_DEFAULT_PRIORITY_RESCAN_DEFAULT_NODES,
WP_EVENT_HOOK_EXEC_TYPE_AFTER_EVENTS,
g_cclosure_new ((GCallback) timer_start, self, NULL));
g_cclosure_new ((GCallback) rescan, self, NULL));
/* default.configured.audio.sink changed */
wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook),
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata",
WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.key", "=s", "default.configured.audio.sink",
WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default",
NULL);
/* default.configured.video.sink changed */
wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook),
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.key", "=s", "default.configured.video.sink",
WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default",
NULL);
/* default.configured.audio.source changed */
wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook),
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.key", "=s", "default.configured.audio.source",
WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default",
NULL);
/* new video device node added */
wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook),
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-added",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "node",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "media.class", "#s", "Video/*",
NULL);
/* new audio device node added */
wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook),
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-added",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "node",
WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "media.class", "#s", "Audio/*",
NULL);
/* video device node removed */
wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook),
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-removed",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "node",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "media.class", "#s", "Video/*",
NULL);
/* audio device node removed */
wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook),
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-removed",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "node",
WP_CONSTRAINT_TYPE_PW_PROPERTY, "media.class", "#s", "Audio/*",
NULL);
wp_event_dispatcher_register_hook (dispatcher, hook);
g_clear_object (&hook);
@@ -657,35 +750,6 @@ wp_default_nodes_disable (WpPlugin * plugin)
g_clear_object (&self->state);
}
static void
wp_default_nodes_set_property (GObject * object, guint property_id,
const GValue * value, GParamSpec * pspec)
{
WpDefaultNodes * self = WP_DEFAULT_NODES (object);
switch (property_id) {
case PROP_SAVE_INTERVAL_MS:
self->save_interval_ms = g_value_get_uint (value);
break;
case PROP_USE_PERSISTENT_STORAGE:
self->use_persistent_storage = g_value_get_boolean (value);
break;
case PROP_AUTO_ECHO_CANCEL:
self->auto_echo_cancel = g_value_get_boolean (value);
break;
case PROP_ECHO_CANCEL_SINK_NAME:
g_clear_pointer (&self->echo_cancel_names[WP_DIRECTION_INPUT], g_free);
self->echo_cancel_names[WP_DIRECTION_INPUT] = g_value_dup_string (value);
break;
case PROP_ECHO_CANCEL_SOURCE_NAME:
g_clear_pointer (&self->echo_cancel_names[WP_DIRECTION_OUTPUT], g_free);
self->echo_cancel_names[WP_DIRECTION_OUTPUT] = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
wp_default_nodes_finalize (GObject * object)
@@ -695,6 +759,9 @@ wp_default_nodes_finalize (GObject * object)
g_clear_pointer (&self->echo_cancel_names[WP_DIRECTION_INPUT], g_free);
g_clear_pointer (&self->echo_cancel_names[WP_DIRECTION_OUTPUT], g_free);
if (self->settings_sub_id)
wp_settings_unsubscribe (self->settings, self->settings_sub_id);
G_OBJECT_CLASS (wp_default_nodes_parent_class)->finalize (object);
}
@@ -705,101 +772,20 @@ wp_default_nodes_class_init (WpDefaultNodesClass * klass)
WpPluginClass *plugin_class = (WpPluginClass *) klass;
object_class->finalize = wp_default_nodes_finalize;
object_class->set_property = wp_default_nodes_set_property;
plugin_class->enable = wp_default_nodes_enable;
plugin_class->disable = wp_default_nodes_disable;
g_object_class_install_property (object_class, PROP_SAVE_INTERVAL_MS,
g_param_spec_uint ("save-interval-ms", "save-interval-ms",
"save-interval-ms", 1, G_MAXUINT32, DEFAULT_SAVE_INTERVAL_MS,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_USE_PERSISTENT_STORAGE,
g_param_spec_boolean ("use-persistent-storage", "use-persistent-storage",
"use-persistent-storage", DEFAULT_USE_PERSISTENT_STORAGE,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_AUTO_ECHO_CANCEL,
g_param_spec_boolean ("auto-echo-cancel", "auto-echo-cancel",
"auto-echo-cancel", DEFAULT_AUTO_ECHO_CANCEL,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_ECHO_CANCEL_SINK_NAME,
g_param_spec_string ("echo-cancel-sink-name", "echo-cancel-sink-name",
"echo-cancel-sink-name", DEFAULT_ECHO_CANCEL_SINK_NAME,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_ECHO_CANCEL_SOURCE_NAME,
g_param_spec_string ("echo-cancel-source-name", "echo-cancel-source-name",
"echo-cancel-source-name", DEFAULT_ECHO_CANCEL_SOURCE_NAME,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
}
WP_PLUGIN_EXPORT gboolean
wireplumber__module_init (WpCore * core, GVariant * args, GError ** error)
{
gint save_interval_ms = DEFAULT_SAVE_INTERVAL_MS;
gboolean use_persistent_storage = DEFAULT_USE_PERSISTENT_STORAGE;
gboolean auto_echo_cancel = DEFAULT_AUTO_ECHO_CANCEL;
g_autofree gchar *echo_cancel_sink_name = NULL;
g_autofree gchar *echo_cancel_source_name = NULL;
g_autoptr (WpSettings) settings = wp_settings_get_instance(core, NULL);
{
g_autoptr (WpSpaJson) j = wp_settings_get (settings,
"device.save-interval-ms");
if (j && !wp_spa_json_parse_int (j, &save_interval_ms))
wp_warning ("Failed to parse integer in device.save-interval-ms");
}
{
g_autoptr (WpSpaJson) j = wp_settings_get (settings,
"device.use-persistent-storage");
if (j && !wp_spa_json_parse_boolean (j, &save_interval_ms))
wp_warning ("Failed to parse boolean in device.use-persistent-storage");
}
{
g_autoptr (WpSpaJson) j = wp_settings_get (settings,
"device.auto-echo-cancel");
if (j && !wp_spa_json_parse_boolean (j, &auto_echo_cancel))
wp_warning ("Failed to parse boolean in device.auto-echo-cancel");
}
{
g_autoptr (WpSpaJson) j = wp_settings_get (settings,
"device.echo-cancel-sink-name");
if (j) {
echo_cancel_sink_name = wp_spa_json_parse_string (j);
if (!echo_cancel_sink_name)
wp_warning ("Failed to parse string in device.echo-cancel-sink-name");
}
}
{
g_autoptr (WpSpaJson) j = wp_settings_get (settings,
"device.echo-cancel-source-name");
if (j) {
echo_cancel_sink_name = wp_spa_json_parse_string (j);
if (!echo_cancel_sink_name)
wp_warning ("Failed to parse string in device.echo-cancel-source-name");
}
}
wp_plugin_register (g_object_new (wp_default_nodes_get_type (),
"name", NAME,
"core", core,
"save-interval-ms", save_interval_ms > 0 ?
(guint)save_interval_ms : DEFAULT_SAVE_INTERVAL_MS,
"use-persistent-storage", use_persistent_storage,
"auto-echo-cancel", auto_echo_cancel,
"echo-cancel-sink-name", echo_cancel_sink_name ?
echo_cancel_sink_name : DEFAULT_ECHO_CANCEL_SINK_NAME,
"echo-cancel-source-name", echo_cancel_source_name ?
echo_cancel_source_name : DEFAULT_ECHO_CANCEL_SOURCE_NAME,
NULL));
return TRUE;
}

View File

@@ -24,17 +24,14 @@ wireplumber.settings = {
# their priorities and any runtime changes do not persist after restart
device.use-persistent-storage = true
# the default volume to apply to ACP device nodes, in the linear scale
# default-volume = 0.4
# Whether to auto-switch to echo cancel sink and source nodes or not
device.auto-echo-cancel = true
# Sets the default echo-cancel-sink node name to automatically switch to
device.echo-cancel-sink-name = echo-cancel-sink
# device.echo-cancel-sink-name = "echo-cancel-sink"
# Sets the default echo-cancel-source node name to automatically switch to
device.echo-cancel-source-name = echo-cancel-source
# device.echo-cancel-source-name = "echo-cancel-source"
# device default volume level
# device.default-volume = 0.5