From 3c921acb48a4310be363e10a7c6271b7d2decaf7 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 22 Sep 2025 14:21:46 +0200 Subject: [PATCH] impl-port: rework port properties Don't update info.props all the time, just once when we create the properties, the dict will not change after that. Move the port property check code to a new function. Keep track if we auto generated path, name or alias and if we explicitly update it or not. Listen for node property changes and update the port properties if necessary. Some of the port properties or feature depend on the node properties so we want to keep those in sync. --- src/pipewire/impl-client.c | 5 +- src/pipewire/impl-core.c | 3 +- src/pipewire/impl-device.c | 4 - src/pipewire/impl-factory.c | 2 - src/pipewire/impl-link.c | 3 +- src/pipewire/impl-module.c | 3 +- src/pipewire/impl-node.c | 3 - src/pipewire/impl-port.c | 319 +++++++++++++++++++----------------- src/pipewire/private.h | 4 +- 9 files changed, 173 insertions(+), 173 deletions(-) diff --git a/src/pipewire/impl-client.c b/src/pipewire/impl-client.c index 06234e2b7..36b4370b2 100644 --- a/src/pipewire/impl-client.c +++ b/src/pipewire/impl-client.c @@ -216,7 +216,6 @@ static int update_properties(struct pw_impl_client *client, const struct spa_dic } changed += pw_properties_set(client->properties, dict->items[i].key, dict->items[i].value); } - client->info.props = &client->properties->dict; pw_log_debug("%p: updated %d properties", client, changed); @@ -481,6 +480,8 @@ struct pw_impl_client *pw_context_create_client(struct pw_impl_core *core, pw_mempool_add_listener(this->pool, &impl->pool_listener, &pool_events, impl); this->properties = properties; + this->info.props = &this->properties->dict; + this->permission_func = client_permission_func; this->permission_data = impl; @@ -493,7 +494,6 @@ struct pw_impl_client *pw_context_create_client(struct pw_impl_core *core, pw_context_add_listener(this->context, &impl->context_listener, &context_events, impl); - this->info.props = &this->properties->dict; return this; @@ -559,7 +559,6 @@ int pw_impl_client_register(struct pw_impl_client *client, pw_properties_setf(client->properties, PW_KEY_OBJECT_ID, "%d", client->info.id); pw_properties_setf(client->properties, PW_KEY_OBJECT_SERIAL, "%"PRIu64, pw_global_get_serial(client->global)); - client->info.props = &client->properties->dict; pw_global_add_listener(client->global, &client->global_listener, &global_events, client); pw_global_update_keys(client->global, client->info.props, keys); diff --git a/src/pipewire/impl-core.c b/src/pipewire/impl-core.c index 1901b4b52..3a43a8e88 100644 --- a/src/pipewire/impl-core.c +++ b/src/pipewire/impl-core.c @@ -416,6 +416,7 @@ struct pw_impl_core *pw_context_create_core(struct pw_context *context, this->info.version = pw_get_library_version(); this->info.cookie = pw_rand32(); this->info.name = name; + this->info.props = &this->properties->dict; spa_hook_list_init(&this->listener_list); if (user_data_size > 0) @@ -552,7 +553,6 @@ int pw_impl_core_update_properties(struct pw_impl_core *core, const struct spa_d int changed; changed = pw_properties_update(core->properties, dict); - core->info.props = &core->properties->dict; pw_log_debug("%p: updated %d properties", core, changed); @@ -603,7 +603,6 @@ int pw_impl_core_register(struct pw_impl_core *core, pw_properties_setf(core->properties, PW_KEY_OBJECT_ID, "%d", core->info.id); pw_properties_setf(core->properties, PW_KEY_OBJECT_SERIAL, "%"PRIu64, pw_global_get_serial(core->global)); - core->info.props = &core->properties->dict; pw_global_update_keys(core->global, core->info.props, keys); diff --git a/src/pipewire/impl-device.c b/src/pipewire/impl-device.c index 73af60cdf..53b76b236 100644 --- a/src/pipewire/impl-device.c +++ b/src/pipewire/impl-device.c @@ -143,7 +143,6 @@ static int execute_match(void *data, const char *location, const char *action, struct pw_impl_device *this = match->device; if (spa_streq(action, "update-props")) { match->count += pw_properties_update_string(this->properties, val, len); - this->info.props = &this->properties->dict; } return 1; } @@ -197,7 +196,6 @@ struct pw_impl_device *pw_context_create_device(struct pw_context *context, this->context = context; this->properties = properties; - this->info.props = &properties->dict; this->info.params = this->params; spa_hook_list_init(&this->listener_list); @@ -617,7 +615,6 @@ int pw_impl_device_register(struct pw_impl_device *device, pw_properties_setf(device->properties, PW_KEY_OBJECT_ID, "%d", device->info.id); pw_properties_setf(device->properties, PW_KEY_OBJECT_SERIAL, "%"PRIu64, pw_global_get_serial(device->global)); - device->info.props = &device->properties->dict; pw_global_update_keys(device->global, device->info.props, global_keys); @@ -690,7 +687,6 @@ static int update_properties(struct pw_impl_device *device, const struct spa_dic int changed; changed = pw_properties_update_ignore(device->properties, dict, filter ? ignored : NULL); - device->info.props = &device->properties->dict; pw_log_debug("%p: updated %d properties", device, changed); diff --git a/src/pipewire/impl-factory.c b/src/pipewire/impl-factory.c index 413fa3391..9a8e1c508 100644 --- a/src/pipewire/impl-factory.c +++ b/src/pipewire/impl-factory.c @@ -139,7 +139,6 @@ int pw_impl_factory_update_properties(struct pw_impl_factory *factory, const str int changed; changed = pw_properties_update(factory->properties, dict); - factory->info.props = &factory->properties->dict; pw_log_debug("%p: updated %d properties", factory, changed); @@ -192,7 +191,6 @@ int pw_impl_factory_register(struct pw_impl_factory *factory, pw_properties_set(factory->properties, PW_KEY_FACTORY_NAME, factory->info.name); pw_properties_setf(factory->properties, PW_KEY_FACTORY_TYPE_NAME, "%s", factory->info.type); pw_properties_setf(factory->properties, PW_KEY_FACTORY_TYPE_VERSION, "%d", factory->info.version); - factory->info.props = &factory->properties->dict; pw_global_update_keys(factory->global, factory->info.props, keys); diff --git a/src/pipewire/impl-link.c b/src/pipewire/impl-link.c index 5f1dc1b10..f810f597b 100644 --- a/src/pipewire/impl-link.c +++ b/src/pipewire/impl-link.c @@ -1493,6 +1493,7 @@ struct pw_impl_link *pw_context_create_link(struct pw_context *context, this->context = context; this->properties = properties; + this->info.props = &this->properties->dict; this->info.state = PW_LINK_STATE_INIT; this->output = output; @@ -1518,7 +1519,6 @@ struct pw_impl_link *pw_context_create_link(struct pw_context *context, impl->format_filter = format_filter; this->info.format = NULL; - this->info.props = &this->properties->dict; this->rt.out_mix.peer_id = input->global->id; this->rt.in_mix.peer_id = output->global->id; @@ -1682,7 +1682,6 @@ int pw_impl_link_register(struct pw_impl_link *link, pw_properties_setf(link->properties, PW_KEY_LINK_OUTPUT_PORT, "%u", link->info.output_port_id); pw_properties_setf(link->properties, PW_KEY_LINK_INPUT_NODE, "%u", link->info.input_node_id); pw_properties_setf(link->properties, PW_KEY_LINK_INPUT_PORT, "%u", link->info.input_port_id); - link->info.props = &link->properties->dict; pw_global_update_keys(link->global, link->info.props, keys); diff --git a/src/pipewire/impl-module.c b/src/pipewire/impl-module.c index 10aa432fe..22c8e91fa 100644 --- a/src/pipewire/impl-module.c +++ b/src/pipewire/impl-module.c @@ -206,6 +206,7 @@ pw_context_load_module(struct pw_context *context, this = &impl->this; this->context = context; this->properties = properties; + this->info.props = &this->properties->dict; properties = NULL; spa_hook_list_init(&this->listener_list); @@ -234,7 +235,6 @@ pw_context_load_module(struct pw_context *context, pw_properties_setf(this->properties, PW_KEY_OBJECT_ID, "%d", this->info.id); pw_properties_setf(this->properties, PW_KEY_OBJECT_SERIAL, "%"PRIu64, pw_global_get_serial(this->global)); - this->info.props = &this->properties->dict; pw_global_update_keys(this->global, &this->properties->dict, keys); @@ -354,7 +354,6 @@ int pw_impl_module_update_properties(struct pw_impl_module *module, const struct int changed; changed = pw_properties_update(module->properties, dict); - module->info.props = &module->properties->dict; pw_log_debug("%p: updated %d properties", module, changed); diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index 754dbe602..75e945617 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -989,7 +989,6 @@ int pw_impl_node_register(struct pw_impl_node *this, pw_properties_setf(this->properties, PW_KEY_OBJECT_ID, "%d", this->global->id); pw_properties_setf(this->properties, PW_KEY_OBJECT_SERIAL, "%"PRIu64, pw_global_get_serial(this->global)); - this->info.props = &this->properties->dict; pw_global_update_keys(this->global, &this->properties->dict, global_keys); @@ -1114,7 +1113,6 @@ static int execute_match(void *data, const char *location, const char *action, struct pw_impl_node *this = match->node; if (spa_streq(action, "update-props")) { match->count += pw_properties_update_string(this->properties, val, len); - this->info.props = &this->properties->dict; } return 1; } @@ -1785,7 +1783,6 @@ static int update_properties(struct pw_impl_node *node, const struct spa_dict *d int changed; changed = pw_properties_update_ignore(node->properties, dict, filter ? ignored : NULL); - node->info.props = &node->properties->dict; pw_log_debug("%p: updated %d properties", node, changed); diff --git a/src/pipewire/impl-port.c b/src/pipewire/impl-port.c index efd9e27f1..221f907cd 100644 --- a/src/pipewire/impl-port.c +++ b/src/pipewire/impl-port.c @@ -39,6 +39,8 @@ struct impl { struct spa_list param_list; struct spa_list pending_list; + struct spa_hook node_listener; + unsigned int cache_params:1; }; @@ -452,6 +454,134 @@ int pw_impl_port_release_mix(struct pw_impl_port *port, struct pw_impl_port_mix return res; } +static int check_properties(struct pw_impl_port *port) +{ + struct pw_impl_node *node = port->node; + bool is_control, is_network, is_monitor, is_device, is_duplex, is_virtual; + const char *media_class, *override_device_prefix, *channel_names; + const char *str, *prefix, *path, *desc, *nick, *name; + const struct pw_properties *nprops; + char position[256]; + int changed = 0; + + nprops = pw_impl_node_get_properties(node); + media_class = pw_properties_get(nprops, PW_KEY_MEDIA_CLASS); + is_network = pw_properties_get_bool(nprops, PW_KEY_NODE_NETWORK, false); + + is_control = PW_IMPL_PORT_IS_CONTROL(port); + is_monitor = pw_properties_get_bool(port->properties, PW_KEY_PORT_MONITOR, false); + + if (!is_monitor) { + if ((str = pw_properties_get(nprops, PW_KEY_NODE_TERMINAL)) != NULL) + changed += pw_properties_set(port->properties, PW_KEY_PORT_TERMINAL, str); + if ((str = pw_properties_get(nprops, PW_KEY_NODE_PHYSICAL)) != NULL) + changed += pw_properties_set(port->properties, PW_KEY_PORT_PHYSICAL, str); + } + + port->ignore_latency = pw_properties_get_bool(port->properties, PW_KEY_PORT_IGNORE_LATENCY, false); + port->exclusive = pw_properties_get_bool(port->properties, PW_KEY_PORT_EXCLUSIVE, node->exclusive); + + /* inherit passive state from parent node */ + port->passive = pw_properties_get_bool(port->properties, PW_KEY_PORT_PASSIVE, + port->direction == PW_DIRECTION_INPUT ? + node->in_passive : node->out_passive); + + 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 || + port->auto_path) { + if ((str = name) == NULL && (str = nick) == NULL && (str = desc) == NULL) + str = "node"; + + changed += pw_properties_setf(port->properties, PW_KEY_OBJECT_PATH, "%s:%s_%d", + path ? path : str, prefix, pw_impl_port_get_id(port)); + port->auto_path = true; + } + + 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[1]; + char v[256]; + uint32_t i; + + if (spa_json_begin_array_relax(&it[0], channel_names, strlen(channel_names)) > 0) { + for (i = 0; i < port->port_id + 1; i++) + if (spa_json_get_string(&it[0], 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 || + port->auto_name) { + if (is_control) + changed += pw_properties_setf(port->properties, PW_KEY_PORT_NAME, "%s", prefix); + else if (prefix == NULL || strlen(prefix) == 0) + changed += pw_properties_setf(port->properties, PW_KEY_PORT_NAME, "%s", position); + else + changed += pw_properties_setf(port->properties, PW_KEY_PORT_NAME, "%s_%s", prefix, position); + port->auto_name = true; + } + if (pw_properties_get(port->properties, PW_KEY_PORT_ALIAS) == NULL || + port->auto_alias) { + if ((str = nick) == NULL && (str = desc) == NULL && (str = name) == NULL) + str = "node"; + + if (is_control) + changed += pw_properties_setf(port->properties, PW_KEY_PORT_ALIAS, "%s:%s", + str, prefix); + else { + changed += pw_properties_setf(port->properties, PW_KEY_PORT_ALIAS, "%s:%s", + str, pw_properties_get(port->properties, PW_KEY_PORT_NAME)); + } + port->auto_alias = true; + } + return changed; +} + static int update_properties(struct pw_impl_port *port, const struct spa_dict *dict, bool filter) { static const char * const ignored[] = { @@ -462,37 +592,21 @@ static int update_properties(struct pw_impl_port *port, const struct spa_dict *d PW_KEY_PORT_ID, NULL }; - int changed; changed = pw_properties_update_ignore(port->properties, dict, filter ? ignored : NULL); - if (changed) { - const char *name, *alias; - name = spa_dict_lookup(dict, PW_KEY_PORT_NAME); - alias = spa_dict_lookup(dict, PW_KEY_PORT_ALIAS); - - if (alias != NULL) { - /* alias was explicitly updated, don't generate one from - * the port.name */ - port->alias_port_name = false; - } - else if (name != NULL && port->alias_port_name) { - const struct pw_properties *nprops = pw_impl_node_get_properties(port->node); - const char *node_desc = pw_properties_get(nprops, PW_KEY_NODE_DESCRIPTION); - const char *node_nick = pw_properties_get(nprops, PW_KEY_NODE_NICK); - const char *node_name = pw_properties_get(nprops, PW_KEY_NODE_NAME); - const char *str; - - if ((str = node_nick) == NULL && (str = node_desc) == NULL && (str = node_name) == NULL) - str = "node"; - pw_properties_setf(port->properties, PW_KEY_PORT_ALIAS, "%s:%s", str, name); - } - } - port->info.props = &port->properties->dict; + pw_log_debug("%p: updated %d properties", port, changed); if (changed) { - pw_log_debug("%p: updated %d properties", port, changed); + /* check for explicit updates so we don't have to autogenerate */ + if (spa_dict_lookup(dict, PW_KEY_OBJECT_PATH) != NULL) + port->auto_path = false; + if (spa_dict_lookup(dict, PW_KEY_PORT_NAME) != NULL) + port->auto_name = false; + if (spa_dict_lookup(dict, PW_KEY_PORT_ALIAS) != NULL) + port->auto_alias = false; + check_properties(port); port->info.change_mask |= PW_PORT_CHANGE_MASK_PROPS; } return changed; @@ -1185,7 +1299,6 @@ int pw_impl_port_register(struct pw_impl_port *port, pw_properties_setf(port->properties, PW_KEY_OBJECT_ID, "%d", port->info.id); pw_properties_setf(port->properties, PW_KEY_OBJECT_SERIAL, "%"PRIu64, pw_global_get_serial(port->global)); - port->info.props = &port->properties->dict; pw_global_update_keys(port->global, &port->properties->dict, global_keys); @@ -1194,18 +1307,32 @@ int pw_impl_port_register(struct pw_impl_port *port, return pw_global_register(port->global); } +static void node_info_changed(void *data, const struct pw_node_info *info) +{ + struct pw_impl_port *port = data; + if (info->change_mask & PW_NODE_CHANGE_MASK_PROPS) { + if (check_properties(port) > 0) { + port->info.change_mask |= PW_PORT_CHANGE_MASK_PROPS; + emit_info_changed(port); + } + } + +} +static const struct pw_impl_node_events node_events = { + PW_VERSION_IMPL_NODE_EVENTS, + .info_changed = node_info_changed, +}; + SPA_EXPORT int pw_impl_port_add(struct pw_impl_port *port, struct pw_impl_node *node) { + struct impl *impl = SPA_CONTAINER_OF(port, struct impl, this); uint32_t port_id = port->port_id; struct spa_list *ports; struct pw_map *portmap; struct pw_impl_port *find; - bool is_control, is_network, is_monitor, is_device, is_duplex, is_virtual; - 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]; + const char *dir; + bool is_control; int res; if (port->node != NULL) @@ -1227,146 +1354,28 @@ int pw_impl_port_add(struct pw_impl_port *port, struct pw_impl_node *node) return res; port->node = node; + pw_impl_node_add_listener(node, &impl->node_listener, &node_events, port); pw_impl_node_emit_port_init(node, port); check_params(port); - nprops = pw_impl_node_get_properties(node); - 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); - - if (!is_monitor) { - if ((str = pw_properties_get(nprops, PW_KEY_NODE_TERMINAL)) != NULL) - pw_properties_set(port->properties, PW_KEY_PORT_TERMINAL, str); - if ((str = pw_properties_get(nprops, PW_KEY_NODE_PHYSICAL)) != NULL) - pw_properties_set(port->properties, PW_KEY_PORT_PHYSICAL, str); - } - - port->ignore_latency = pw_properties_get_bool(port->properties, PW_KEY_PORT_IGNORE_LATENCY, false); - port->exclusive = pw_properties_get_bool(port->properties, PW_KEY_PORT_EXCLUSIVE, node->exclusive); + check_properties(port); is_control = PW_IMPL_PORT_IS_CONTROL(port); if (is_control) { dir = port->direction == PW_DIRECTION_INPUT ? "control" : "notify"; - pw_properties_set(port->properties, PW_KEY_PORT_CONTROL, "true"); - } - else { - dir = port->direction == PW_DIRECTION_INPUT ? "in" : "out"; - } - pw_properties_set(port->properties, PW_KEY_PORT_DIRECTION, dir); - - /* inherit passive state from parent node */ - if (port->direction == PW_DIRECTION_INPUT) - port->passive = node->in_passive; - else - port->passive = node->out_passive; - /* override with specific port property if available */ - port->passive = pw_properties_get_bool(port->properties, PW_KEY_PORT_PASSIVE, - port->passive); - - 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[1]; - char v[256]; - uint32_t i; - - if (spa_json_begin_array_relax(&it[0], channel_names, strlen(channel_names)) > 0) { - for (i = 0; i < port->port_id + 1; i++) - if (spa_json_get_string(&it[0], 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 (is_control) - pw_properties_setf(port->properties, PW_KEY_PORT_NAME, "%s", prefix); - else if (prefix == NULL || strlen(prefix) == 0) - pw_properties_setf(port->properties, PW_KEY_PORT_NAME, "%s", position); - else - 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 ((str = nick) == NULL && (str = desc) == NULL && (str = name) == NULL) - str = "node"; - - if (is_control) - pw_properties_setf(port->properties, PW_KEY_PORT_ALIAS, "%s:%s", - str, prefix); - else { - pw_properties_setf(port->properties, PW_KEY_PORT_ALIAS, "%s:%s", - str, pw_properties_get(port->properties, PW_KEY_PORT_NAME)); - port->alias_port_name = true; - } - } - - port->info.props = &port->properties->dict; - - if (is_control) { pw_log_debug("%p: setting node control", port); + pw_properties_set(port->properties, PW_KEY_PORT_CONTROL, "true"); } else { + dir = port->direction == PW_DIRECTION_INPUT ? "in" : "out"; pw_log_debug("%p: setting mixer position io", port); spa_node_set_io(port->mix, SPA_IO_Position, node->rt.position, sizeof(struct spa_io_position)); } + pw_properties_set(port->properties, PW_KEY_PORT_DIRECTION, dir); pw_log_debug("%p: %d add to node %p", port, port_id, node); @@ -1419,6 +1428,7 @@ static int do_remove_port(struct spa_loop *loop, static void pw_impl_port_remove(struct pw_impl_port *port) { + struct impl *impl = SPA_CONTAINER_OF(port, struct impl, this); struct pw_impl_node *node = port->node; int res; @@ -1448,6 +1458,7 @@ static void pw_impl_port_remove(struct pw_impl_port *port) spa_list_remove(&port->link); pw_impl_node_emit_port_removed(node, port); + spa_hook_remove(&impl->node_listener); port->node = NULL; } diff --git a/src/pipewire/private.h b/src/pipewire/private.h index b5d609256..072eac596 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -959,7 +959,9 @@ struct pw_impl_port { } rt; /**< data only accessed from the data thread */ unsigned int destroying:1; unsigned int passive:1; - unsigned int alias_port_name:1; + unsigned int auto_path:1; /* path was automatically generated */ + unsigned int auto_name:1; /* name was automatically generated */ + unsigned int auto_alias:1; /* alias was automatically generated */ int busy_count; struct spa_latency_info latency[2]; /**< latencies */