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:
Wim Taymans 2023-03-02 11:59:08 +01:00
parent 5c180a57a5
commit 5ab1d898ca
2 changed files with 100 additions and 153 deletions

View file

@ -65,138 +65,9 @@ static void node_free(void *data)
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 = {
PW_VERSION_IMPL_NODE_EVENTS,
.free = node_free,
.port_init = node_port_init,
};
static int handle_node_param(struct pw_impl_node *node, const char *key, const char *value)