mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-05 13:30:02 -05:00
impl-port: improve port properties
Move the port property logic from the adapter to the port itself. The port was already doing some of the same work as a fallback but can just as well do everything. This also makes things more unified when there is no adapter used.
This commit is contained in:
parent
5c180a57a5
commit
5ab1d898ca
2 changed files with 100 additions and 153 deletions
|
|
@ -65,138 +65,9 @@ static void node_free(void *data)
|
||||||
pw_properties_free(n->props);
|
pw_properties_free(n->props);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void node_port_init(void *data, struct pw_impl_port *port)
|
|
||||||
{
|
|
||||||
struct node *n = data;
|
|
||||||
const struct pw_properties *old;
|
|
||||||
enum pw_direction direction;
|
|
||||||
struct pw_properties *new;
|
|
||||||
const char *str, *path, *desc, *nick, *name, *node_name, *media_class, *prop_port_names, *override_device_prefix;
|
|
||||||
char position[8], *prefix;
|
|
||||||
bool is_monitor, is_device, is_duplex, is_virtual, is_control = false, no_device_port_prefix;
|
|
||||||
|
|
||||||
direction = pw_impl_port_get_direction(port);
|
|
||||||
|
|
||||||
old = pw_impl_port_get_properties(port);
|
|
||||||
|
|
||||||
is_monitor = pw_properties_get_bool(old, PW_KEY_PORT_MONITOR, false);
|
|
||||||
if (!is_monitor && direction != n->direction)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ((str = pw_properties_get(old, PW_KEY_FORMAT_DSP)) != NULL)
|
|
||||||
is_control = spa_streq(str, "8 bit raw midi");
|
|
||||||
|
|
||||||
path = pw_properties_get(n->props, PW_KEY_OBJECT_PATH);
|
|
||||||
media_class = pw_properties_get(n->props, PW_KEY_MEDIA_CLASS);
|
|
||||||
|
|
||||||
if (media_class != NULL &&
|
|
||||||
(strstr(media_class, "Sink") != NULL ||
|
|
||||||
strstr(media_class, "Source") != NULL))
|
|
||||||
is_device = true;
|
|
||||||
else
|
|
||||||
is_device = false;
|
|
||||||
|
|
||||||
is_duplex = media_class != NULL && strstr(media_class, "Duplex") != NULL;
|
|
||||||
is_virtual = media_class != NULL && strstr(media_class, "Virtual") != NULL;
|
|
||||||
|
|
||||||
new = pw_properties_new(NULL, NULL);
|
|
||||||
|
|
||||||
override_device_prefix = pw_properties_get(n->props, PW_KEY_NODE_DEVICE_PORT_NAME_PREFIX);
|
|
||||||
|
|
||||||
if (is_control)
|
|
||||||
prefix = direction == PW_DIRECTION_INPUT ?
|
|
||||||
"control" : "notify";
|
|
||||||
else if (is_duplex)
|
|
||||||
prefix = direction == PW_DIRECTION_INPUT ?
|
|
||||||
"playback" : "capture";
|
|
||||||
else if (is_virtual)
|
|
||||||
prefix = direction == PW_DIRECTION_INPUT ?
|
|
||||||
"input" : "capture";
|
|
||||||
else if (is_device)
|
|
||||||
prefix = direction == PW_DIRECTION_INPUT ?
|
|
||||||
override_device_prefix != NULL ?
|
|
||||||
strdup(override_device_prefix) : "playback"
|
|
||||||
: is_monitor ? "monitor" : override_device_prefix != NULL ?
|
|
||||||
strdup(override_device_prefix) : "capture";
|
|
||||||
else
|
|
||||||
prefix = direction == PW_DIRECTION_INPUT ?
|
|
||||||
"input" : is_monitor ? "monitor" : "output";
|
|
||||||
|
|
||||||
if ((str = pw_properties_get(old, PW_KEY_AUDIO_CHANNEL)) == NULL ||
|
|
||||||
spa_streq(str, "UNK")) {
|
|
||||||
snprintf(position, sizeof(position), "%d", pw_impl_port_get_id(port) + 1);
|
|
||||||
str = position;
|
|
||||||
}
|
|
||||||
if (direction == n->direction) {
|
|
||||||
if (is_device) {
|
|
||||||
pw_properties_set(new, PW_KEY_PORT_PHYSICAL, "true");
|
|
||||||
pw_properties_set(new, PW_KEY_PORT_TERMINAL, "true");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
desc = pw_properties_get(n->props, PW_KEY_NODE_DESCRIPTION);
|
|
||||||
nick = pw_properties_get(n->props, PW_KEY_NODE_NICK);
|
|
||||||
name = pw_properties_get(n->props, PW_KEY_NODE_NAME);
|
|
||||||
|
|
||||||
if ((node_name = desc) == NULL && (node_name = nick) == NULL &&
|
|
||||||
(node_name = name) == NULL)
|
|
||||||
node_name = "node";
|
|
||||||
|
|
||||||
pw_properties_setf(new, PW_KEY_OBJECT_PATH, "%s:%s_%d",
|
|
||||||
path ? path : node_name, prefix, pw_impl_port_get_id(port));
|
|
||||||
|
|
||||||
no_device_port_prefix = is_device && !is_monitor
|
|
||||||
&& override_device_prefix != NULL && strlen(override_device_prefix) == 0;
|
|
||||||
|
|
||||||
if (is_control)
|
|
||||||
pw_properties_setf(new, PW_KEY_PORT_NAME, "%s", prefix);
|
|
||||||
else if (no_device_port_prefix)
|
|
||||||
pw_properties_setf(new, PW_KEY_PORT_NAME, "%s", str);
|
|
||||||
else
|
|
||||||
pw_properties_setf(new, PW_KEY_PORT_NAME, "%s_%s", prefix, str);
|
|
||||||
|
|
||||||
if ((node_name = nick) == NULL && (node_name = desc) == NULL &&
|
|
||||||
(node_name = name) == NULL)
|
|
||||||
node_name = "node";
|
|
||||||
|
|
||||||
if (is_control)
|
|
||||||
pw_properties_setf(new, PW_KEY_PORT_ALIAS, "%s:%s",
|
|
||||||
node_name, prefix);
|
|
||||||
else
|
|
||||||
pw_properties_setf(new, PW_KEY_PORT_ALIAS, "%s:%s_%s",
|
|
||||||
node_name, prefix, str);
|
|
||||||
|
|
||||||
prop_port_names = pw_properties_get(n->props, PW_KEY_NODE_CHANNELNAMES);
|
|
||||||
if (prop_port_names) {
|
|
||||||
struct spa_json it[2];
|
|
||||||
char v[256];
|
|
||||||
|
|
||||||
spa_json_init(&it[0], prop_port_names, strlen(prop_port_names));
|
|
||||||
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
|
|
||||||
spa_json_init(&it[1], prop_port_names, strlen(prop_port_names));
|
|
||||||
|
|
||||||
uint32_t i;
|
|
||||||
for (i = 0; i < pw_impl_port_get_id(port) + 1; i++)
|
|
||||||
if (spa_json_get_string(&it[1], v, sizeof(v)) <= 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (i == pw_impl_port_get_id(port) + 1 && strlen(v) > 0) {
|
|
||||||
if (no_device_port_prefix) {
|
|
||||||
pw_properties_setf(new, PW_KEY_PORT_NAME, "%s", v);
|
|
||||||
} else {
|
|
||||||
pw_properties_setf(new, PW_KEY_PORT_NAME, "%s_%s", prefix, v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pw_impl_port_update_properties(port, &new->dict);
|
|
||||||
pw_properties_free(new);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct pw_impl_node_events node_events = {
|
static const struct pw_impl_node_events node_events = {
|
||||||
PW_VERSION_IMPL_NODE_EVENTS,
|
PW_VERSION_IMPL_NODE_EVENTS,
|
||||||
.free = node_free,
|
.free = node_free,
|
||||||
.port_init = node_port_init,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int handle_node_param(struct pw_impl_node *node, const char *key, const char *value)
|
static int handle_node_param(struct pw_impl_node *node, const char *key, const char *value)
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
#include <spa/node/utils.h>
|
#include <spa/node/utils.h>
|
||||||
#include <spa/utils/names.h>
|
#include <spa/utils/names.h>
|
||||||
#include <spa/utils/string.h>
|
#include <spa/utils/string.h>
|
||||||
|
#include <spa/utils/json.h>
|
||||||
#include <spa/debug/types.h>
|
#include <spa/debug/types.h>
|
||||||
#include <spa/pod/filter.h>
|
#include <spa/pod/filter.h>
|
||||||
#include <spa/pod/dynamic.h>
|
#include <spa/pod/dynamic.h>
|
||||||
|
|
@ -953,8 +954,11 @@ int pw_impl_port_add(struct pw_impl_port *port, struct pw_impl_node *node)
|
||||||
struct spa_list *ports;
|
struct spa_list *ports;
|
||||||
struct pw_map *portmap;
|
struct pw_map *portmap;
|
||||||
struct pw_impl_port *find;
|
struct pw_impl_port *find;
|
||||||
bool control;
|
bool is_control, is_network, is_monitor, is_device, is_duplex, is_virtual;
|
||||||
const char *str, *dir;
|
const char *media_class, *override_device_prefix, *channel_names;
|
||||||
|
const char *str, *dir, *prefix, *path, *desc, *nick, *name;
|
||||||
|
const struct pw_properties *nprops;
|
||||||
|
char position[256];
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (port->node != NULL)
|
if (port->node != NULL)
|
||||||
|
|
@ -982,43 +986,115 @@ int pw_impl_port_add(struct pw_impl_port *port, struct pw_impl_node *node)
|
||||||
pw_impl_port_for_each_param(port, 0, SPA_PARAM_IO, 0, 0, NULL, check_param_io, port);
|
pw_impl_port_for_each_param(port, 0, SPA_PARAM_IO, 0, 0, NULL, check_param_io, port);
|
||||||
pw_impl_port_for_each_param(port, 0, SPA_PARAM_Latency, 0, 0, NULL, process_latency_param, port);
|
pw_impl_port_for_each_param(port, 0, SPA_PARAM_Latency, 0, 0, NULL, process_latency_param, port);
|
||||||
|
|
||||||
control = PW_IMPL_PORT_IS_CONTROL(port);
|
nprops = pw_impl_node_get_properties(node);
|
||||||
if (control) {
|
media_class = pw_properties_get(nprops, PW_KEY_MEDIA_CLASS);
|
||||||
|
is_network = pw_properties_get_bool(nprops, PW_KEY_NODE_NETWORK, false);
|
||||||
|
|
||||||
|
is_monitor = pw_properties_get_bool(port->properties, PW_KEY_PORT_MONITOR, false);
|
||||||
|
|
||||||
|
is_control = PW_IMPL_PORT_IS_CONTROL(port);
|
||||||
|
if (is_control) {
|
||||||
dir = port->direction == PW_DIRECTION_INPUT ? "control" : "notify";
|
dir = port->direction == PW_DIRECTION_INPUT ? "control" : "notify";
|
||||||
pw_properties_set(port->properties, PW_KEY_PORT_CONTROL, "true");
|
pw_properties_set(port->properties, PW_KEY_PORT_CONTROL, "true");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dir = port->direction == PW_DIRECTION_INPUT ? "in" : "out";
|
dir = port->direction == PW_DIRECTION_INPUT ? "in" : "out";
|
||||||
|
|
||||||
}
|
}
|
||||||
pw_properties_set(port->properties, PW_KEY_PORT_DIRECTION, dir);
|
pw_properties_set(port->properties, PW_KEY_PORT_DIRECTION, dir);
|
||||||
|
|
||||||
|
if (media_class != NULL &&
|
||||||
|
(strstr(media_class, "Sink") != NULL ||
|
||||||
|
strstr(media_class, "Source") != NULL))
|
||||||
|
is_device = true;
|
||||||
|
else
|
||||||
|
is_device = false;
|
||||||
|
|
||||||
|
is_duplex = media_class != NULL && strstr(media_class, "Duplex") != NULL;
|
||||||
|
is_virtual = media_class != NULL && strstr(media_class, "Virtual") != NULL;
|
||||||
|
|
||||||
|
override_device_prefix = pw_properties_get(nprops, PW_KEY_NODE_DEVICE_PORT_NAME_PREFIX);
|
||||||
|
|
||||||
|
if (is_network) {
|
||||||
|
prefix = port->direction == PW_DIRECTION_INPUT ?
|
||||||
|
"send" : is_monitor ? "monitor" : "receive";
|
||||||
|
} else if (is_duplex) {
|
||||||
|
prefix = port->direction == PW_DIRECTION_INPUT ?
|
||||||
|
"playback" : "capture";
|
||||||
|
} else if (is_virtual) {
|
||||||
|
prefix = port->direction == PW_DIRECTION_INPUT ?
|
||||||
|
"input" : "capture";
|
||||||
|
} else if (is_device) {
|
||||||
|
if (override_device_prefix != NULL)
|
||||||
|
prefix = is_monitor ? "monitor" : override_device_prefix;
|
||||||
|
else
|
||||||
|
prefix = port->direction == PW_DIRECTION_INPUT ?
|
||||||
|
"playback" : is_monitor ? "monitor" : "capture";
|
||||||
|
} else {
|
||||||
|
prefix = port->direction == PW_DIRECTION_INPUT ?
|
||||||
|
"input" : is_monitor ? "monitor" : "output";
|
||||||
|
}
|
||||||
|
|
||||||
|
path = pw_properties_get(nprops, PW_KEY_OBJECT_PATH);
|
||||||
|
desc = pw_properties_get(nprops, PW_KEY_NODE_DESCRIPTION);
|
||||||
|
nick = pw_properties_get(nprops, PW_KEY_NODE_NICK);
|
||||||
|
name = pw_properties_get(nprops, PW_KEY_NODE_NAME);
|
||||||
|
|
||||||
|
if (pw_properties_get(port->properties, PW_KEY_OBJECT_PATH) == NULL) {
|
||||||
|
if ((str = name) == NULL && (str = nick) == NULL && (str = desc) == NULL)
|
||||||
|
str = "node";
|
||||||
|
|
||||||
|
pw_properties_setf(port->properties, PW_KEY_OBJECT_PATH, "%s:%s_%d",
|
||||||
|
path ? path : str, prefix, pw_impl_port_get_id(port));
|
||||||
|
}
|
||||||
|
|
||||||
|
str = pw_properties_get(port->properties, PW_KEY_AUDIO_CHANNEL);
|
||||||
|
if (str == NULL || spa_streq(str, "UNK"))
|
||||||
|
snprintf(position, sizeof(position), "%d", port->port_id + 1);
|
||||||
|
else if (str != NULL)
|
||||||
|
snprintf(position, sizeof(position), "%s", str);
|
||||||
|
|
||||||
|
channel_names = pw_properties_get(nprops, PW_KEY_NODE_CHANNELNAMES);
|
||||||
|
if (channel_names != NULL) {
|
||||||
|
struct spa_json it[2];
|
||||||
|
char v[256];
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
spa_json_init(&it[0], channel_names, strlen(channel_names));
|
||||||
|
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
|
||||||
|
spa_json_init(&it[1], channel_names, strlen(channel_names));
|
||||||
|
|
||||||
|
for (i = 0; i < port->port_id + 1; i++)
|
||||||
|
if (spa_json_get_string(&it[1], v, sizeof(v)) <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i == port->port_id + 1 && strlen(v) > 0)
|
||||||
|
snprintf(position, sizeof(position), "%s", v);
|
||||||
|
}
|
||||||
|
|
||||||
if (pw_properties_get(port->properties, PW_KEY_PORT_NAME) == NULL) {
|
if (pw_properties_get(port->properties, PW_KEY_PORT_NAME) == NULL) {
|
||||||
if ((str = pw_properties_get(port->properties, PW_KEY_AUDIO_CHANNEL)) != NULL &&
|
if (is_control)
|
||||||
!spa_streq(str, "UNK")) {
|
pw_properties_setf(port->properties, PW_KEY_PORT_NAME, "%s", prefix);
|
||||||
pw_properties_setf(port->properties, PW_KEY_PORT_NAME, "%s_%s", dir, str);
|
else if (prefix == NULL || strlen(prefix) == 0)
|
||||||
}
|
pw_properties_setf(port->properties, PW_KEY_PORT_NAME, "%s", position);
|
||||||
else {
|
else
|
||||||
pw_properties_setf(port->properties, PW_KEY_PORT_NAME, "%s_%d", dir, port->port_id);
|
pw_properties_setf(port->properties, PW_KEY_PORT_NAME, "%s_%s", prefix, position);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (pw_properties_get(port->properties, PW_KEY_PORT_ALIAS) == NULL) {
|
if (pw_properties_get(port->properties, PW_KEY_PORT_ALIAS) == NULL) {
|
||||||
const struct pw_properties *nprops;
|
if ((str = nick) == NULL && (str = desc) == NULL && (str = name) == NULL)
|
||||||
const char *node_name;
|
str = "node";
|
||||||
|
|
||||||
nprops = pw_impl_node_get_properties(node);
|
if (is_control)
|
||||||
if ((node_name = pw_properties_get(nprops, PW_KEY_NODE_NICK)) == NULL &&
|
pw_properties_setf(port->properties, PW_KEY_PORT_ALIAS, "%s:%s",
|
||||||
(node_name = pw_properties_get(nprops, PW_KEY_NODE_DESCRIPTION)) == NULL &&
|
str, prefix);
|
||||||
(node_name = pw_properties_get(nprops, PW_KEY_NODE_NAME)) == NULL)
|
else
|
||||||
node_name = "node";
|
pw_properties_setf(port->properties, PW_KEY_PORT_ALIAS, "%s:%s",
|
||||||
|
str, pw_properties_get(port->properties, PW_KEY_PORT_NAME));
|
||||||
pw_properties_setf(port->properties, PW_KEY_PORT_ALIAS, "%s:%s",
|
|
||||||
node_name,
|
|
||||||
pw_properties_get(port->properties, PW_KEY_PORT_NAME));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
port->info.props = &port->properties->dict;
|
port->info.props = &port->properties->dict;
|
||||||
|
|
||||||
if (control) {
|
if (is_control) {
|
||||||
pw_log_debug("%p: setting node control", port);
|
pw_log_debug("%p: setting node control", port);
|
||||||
} else {
|
} else {
|
||||||
pw_log_debug("%p: setting mixer io", port);
|
pw_log_debug("%p: setting mixer io", port);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue