From 59ea4ef897aa7a3c7d1a1c56f9ca27cfb00e0f29 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 13 Feb 2024 16:01:10 +0100 Subject: [PATCH] adapter: move node.params to impl-node.c Move configuration of initial Params from the adapter to the node to make it more generally useful. Add the same device.param config to devices. This makes it possible to configure the default settings statically while creating the nodes and devices. --- src/daemon/minimal.conf.in | 17 +++++++-- src/modules/module-adapter/adapter.c | 40 +-------------------- src/pipewire/impl-device.c | 53 ++++++++++++++++++++++++++-- src/pipewire/impl-node.c | 39 ++++++++++++++++++++ 4 files changed, 105 insertions(+), 44 deletions(-) diff --git a/src/daemon/minimal.conf.in b/src/daemon/minimal.conf.in index b4e064b9d..673424d41 100644 --- a/src/daemon/minimal.conf.in +++ b/src/daemon/minimal.conf.in @@ -211,7 +211,14 @@ context.objects = [ control = false position = unknown # unknown, preserve } + #node.param.Props = { + # channelVolumes = [ 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.6 ] + #} } + #device.param.Profile = { + # #idx = 0 + # name = pro-audio + #} } } condition = [ { minimal.use-udev = true } ] @@ -226,7 +233,7 @@ context.objects = [ node.name = "system" node.description = "system" media.class = "Audio/Source" - api.alsa.path = "hw:0" + api.alsa.path = "hw:4" #api.alsa.period-size = 0 #api.alsa.period-num = 0 #api.alsa.headroom = 0 @@ -281,6 +288,9 @@ context.objects = [ # position = [ FL FR RL RR ] # } #} + #node.param.Props = { + # channelVolumes = [ 0.5 0.4 0.3 0.5 ] + #} } condition = [ { minimal.use-udev = false } ] } @@ -290,7 +300,7 @@ context.objects = [ node.name = "system" node.description = "system" media.class = "Audio/Sink" - api.alsa.path = "hw:0" + api.alsa.path = "hw:4" #api.alsa.period-size = 0 #api.alsa.period-num = 0 #api.alsa.headroom = 0 @@ -344,6 +354,9 @@ context.objects = [ # channels = 4 # } #} + #node.param.Props = { + # channelVolumes = [ 0.5 0.4 0.3 0.5 ] + #} } condition = [ { minimal.use-udev = false } ] } diff --git a/src/modules/module-adapter/adapter.c b/src/modules/module-adapter/adapter.c index ec1cd068c..800a3fa1d 100644 --- a/src/modules/module-adapter/adapter.c +++ b/src/modules/module-adapter/adapter.c @@ -70,30 +70,6 @@ static const struct pw_impl_node_events node_events = { .free = node_free, }; -static int handle_node_param(struct pw_impl_node *node, const char *key, const char *value) -{ - const struct spa_type_info *ti; - uint8_t buffer[1024]; - struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); - struct spa_pod *pod; - int res; - - ti = spa_debug_type_find_short(spa_type_param, key); - if (ti == NULL) - return -ENOENT; - - if ((res = spa_json_to_pod(&b, 0, ti, value, strlen(value))) < 0) - return res; - - if ((pod = spa_pod_builder_deref(&b, 0)) == NULL) - return -ENOSPC; - - if ((res = pw_impl_node_set_param(node, ti->type, 0, pod)) < 0) - return res; - - return 0; -} - static int find_format(struct spa_node *node, enum pw_direction direction, uint32_t *media_type, uint32_t *media_subtype) { @@ -172,8 +148,6 @@ struct pw_impl_node *pw_adapter_new(struct pw_context *context, enum pw_direction direction; int res; uint32_t media_type, media_subtype; - const struct spa_dict_item *it; - struct pw_properties *copy; struct info_data info; spa_zero(info); @@ -233,16 +207,10 @@ struct pw_impl_node *pw_adapter_new(struct pw_context *context, goto error; } - copy = pw_properties_new(NULL, NULL); - spa_dict_for_each(it, &props->dict) { - if (!spa_strstartswith(it->key, "node.param.") && - !spa_strstartswith(it->key, "port.param.")) - pw_properties_set(copy, it->key, it->value); - } node = pw_spa_node_load(context, factory_name, PW_SPA_NODE_FLAG_ACTIVATE | PW_SPA_NODE_FLAG_NO_REGISTER, - copy, sizeof(struct node) + user_data_size); + pw_properties_copy(props), sizeof(struct node) + user_data_size); if (node == NULL) { res = -errno; pw_log_error("can't load spa node: %m"); @@ -264,12 +232,6 @@ struct pw_impl_node *pw_adapter_new(struct pw_context *context, pw_impl_node_add_listener(node, &n->node_listener, &node_events, n); - spa_dict_for_each(it, &props->dict) { - if (spa_strstartswith(it->key, "node.param.")) { - if ((res = handle_node_param(node, &it->key[11], it->value)) < 0) - pw_log_warn("can't set node param: %s", spa_strerror(res)); - } - } return node; error: diff --git a/src/pipewire/impl-device.c b/src/pipewire/impl-device.c index b090203f5..ff243f7cd 100644 --- a/src/pipewire/impl-device.c +++ b/src/pipewire/impl-device.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "pipewire/impl.h" #include "pipewire/cleanup.h" @@ -361,6 +362,16 @@ int pw_impl_device_for_each_param(struct pw_impl_device *device, return res; } +SPA_EXPORT +int pw_impl_device_set_param(struct pw_impl_device *device, + uint32_t id, uint32_t flags, const struct spa_pod *param) +{ + pw_log_debug("%p: set_param id:%d (%s) flags:%08x param:%p", device, id, + spa_debug_type_find_name(spa_type_param, id), flags, param); + return spa_device_set_param(device->device, id, flags, param); +} + + static int reply_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, struct spa_pod *param) { @@ -912,9 +923,36 @@ static const struct spa_device_events device_events = { .object_info = device_object_info, }; +static int handle_device_param(struct pw_impl_device *device, const char *key, const char *value) +{ + const struct spa_type_info *ti; + uint8_t buffer[1024]; + struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); + struct spa_pod *pod; + int res; + + ti = spa_debug_type_find_short(spa_type_param, key); + if (ti == NULL) + return -ENOENT; + + if ((res = spa_json_to_pod(&b, 0, ti, value, strlen(value))) < 0) + return res; + + if ((pod = spa_pod_builder_deref(&b, 0)) == NULL) + return -ENOSPC; + + if ((res = pw_impl_device_set_param(device, ti->type, 0, pod)) < 0) + return res; + + return 0; +} + SPA_EXPORT int pw_impl_device_set_implementation(struct pw_impl_device *device, struct spa_device *spa_device) { + int res; + const struct spa_dict_item *it; + pw_log_debug("%p: implementation %p", device, spa_device); if (device->device) { @@ -923,10 +961,19 @@ int pw_impl_device_set_implementation(struct pw_impl_device *device, struct spa_ return -EEXIST; } device->device = spa_device; - spa_device_add_listener(device->device, - &device->listener, &device_events, device); - return 0; +again: + spa_dict_for_each(it, &device->properties->dict) { + if (spa_strstartswith(it->key, "device.param.")) { + if ((res = handle_device_param(device, &it->key[13], it->value)) < 0) + pw_log_warn("can't set device param: %s", spa_strerror(res)); + pw_properties_set(device->properties, it->key, NULL); + goto again; + } + } + res = spa_device_add_listener(device->device, + &device->listener, &device_events, device); + return res; } SPA_EXPORT diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index dbb7b21ec..d36ac60a5 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "pipewire/impl-node.h" #include "pipewire/private.h" @@ -921,6 +922,8 @@ static void check_properties(struct pw_impl_node *node) uint32_t value; bool driver, trigger; + + if ((str = pw_properties_get(node->properties, PW_KEY_PRIORITY_DRIVER))) { value = pw_properties_parse_int(str); if (value != node->priority_driver) { @@ -1937,11 +1940,36 @@ static const struct spa_node_callbacks node_callbacks = { .xrun = node_xrun, }; +static int handle_node_param(struct pw_impl_node *node, const char *key, const char *value) +{ + const struct spa_type_info *ti; + uint8_t buffer[1024]; + struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); + struct spa_pod *pod; + int res; + + ti = spa_debug_type_find_short(spa_type_param, key); + if (ti == NULL) + return -ENOENT; + + if ((res = spa_json_to_pod(&b, 0, ti, value, strlen(value))) < 0) + return res; + + if ((pod = spa_pod_builder_deref(&b, 0)) == NULL) + return -ENOSPC; + + if ((res = pw_impl_node_set_param(node, ti->type, 0, pod)) < 0) + return res; + + return 0; +} + SPA_EXPORT int pw_impl_node_set_implementation(struct pw_impl_node *node, struct spa_node *spa_node) { int res; + const struct spa_dict_item *it; pw_log_debug("%p: implementation %p", node, spa_node); @@ -1952,6 +1980,17 @@ int pw_impl_node_set_implementation(struct pw_impl_node *node, node->node = spa_node; spa_node_set_callbacks(node->node, &node_callbacks, node); + +again: + spa_dict_for_each(it, &node->properties->dict) { + if (spa_strstartswith(it->key, "node.param.")) { + if ((res = handle_node_param(node, &it->key[11], it->value)) < 0) + pw_log_warn("can't set node param: %s", spa_strerror(res)); + pw_properties_set(node->properties, it->key, NULL); + goto again; + } + } + res = spa_node_add_listener(node->node, &node->listener, &node_events, node); if (node->registered)