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.
This commit is contained in:
Wim Taymans 2024-02-13 16:01:10 +01:00
parent 4ab3ab6081
commit 59ea4ef897
4 changed files with 105 additions and 44 deletions

View file

@ -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 } ]
}

View file

@ -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:

View file

@ -9,6 +9,7 @@
#include <spa/pod/filter.h>
#include <spa/pod/dynamic.h>
#include <spa/utils/string.h>
#include <spa/utils/json-pod.h>
#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

View file

@ -18,6 +18,7 @@
#include <spa/node/utils.h>
#include <spa/debug/types.h>
#include <spa/utils/string.h>
#include <spa/utils/json-pod.h>
#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)