diff --git a/src/pipewire/impl-client.c b/src/pipewire/impl-client.c index becbc1956..9fa3bbc9b 100644 --- a/src/pipewire/impl-client.c +++ b/src/pipewire/impl-client.c @@ -133,21 +133,39 @@ static int client_error(void *object, uint32_t id, int res, const char *error) return 0; } +static bool has_key(const char *keys[], const char *key) +{ + int i; + for (i = 0; keys[i]; i++) { + if (strcmp(keys[i], key) == 0) + return true; + } + return false; +} + static int update_properties(struct pw_impl_client *client, const struct spa_dict *dict, bool filter) { struct pw_resource *resource; int changed = 0; uint32_t i; - const char *old; + const char *old, *ignored[] = { + PW_KEY_OBJECT_ID, + NULL + }; for (i = 0; i < dict->n_items; i++) { - if (filter && strstr(dict->items[i].key, "pipewire.") == dict->items[i].key && - (old = pw_properties_get(client->properties, dict->items[i].key)) != NULL && - (dict->items[i].value == NULL || strcmp(old, dict->items[i].value) != 0)) { - pw_log_warn(NAME" %p: refuse property update '%s' from '%s' to '%s'", - client, dict->items[i].key, old, - dict->items[i].value); - continue; + if (filter) { + if (strstr(dict->items[i].key, "pipewire.") == dict->items[i].key && + (old = pw_properties_get(client->properties, dict->items[i].key)) != NULL && + (dict->items[i].value == NULL || strcmp(old, dict->items[i].value) != 0)) { + pw_log_warn(NAME" %p: refuse property update '%s' from '%s' to '%s'", + client, dict->items[i].key, old, + dict->items[i].value); + continue; + + } + if (has_key(ignored, dict->items[i].key)) + continue; } changed += pw_properties_set(client->properties, dict->items[i].key, dict->items[i].value); } diff --git a/src/pipewire/impl-device.c b/src/pipewire/impl-device.c index 414bf5c84..e04a26849 100644 --- a/src/pipewire/impl-device.c +++ b/src/pipewire/impl-device.c @@ -643,11 +643,18 @@ static void emit_info_changed(struct pw_impl_device *device) device->info.change_mask = 0; } -static int update_properties(struct pw_impl_device *device, const struct spa_dict *dict) +static int update_properties(struct pw_impl_device *device, const struct spa_dict *dict, bool filter) { int changed; + const char *ignored[] = { + PW_KEY_OBJECT_ID, + PW_KEY_MODULE_ID, + PW_KEY_FACTORY_ID, + PW_KEY_CLIENT_ID, + NULL + }; - changed = pw_properties_update(device->properties, dict); + changed = pw_properties_update_ignore(device->properties, dict, filter ? ignored : NULL); device->info.props = &device->properties->dict; pw_log_debug(NAME" %p: updated %d properties", device, changed); @@ -726,7 +733,7 @@ static void device_info(void *data, const struct spa_device_info *info) device, info->flags, info->change_mask); if (info->change_mask & SPA_DEVICE_CHANGE_MASK_PROPS) { - update_properties(device, info->props); + update_properties(device, info->props, true); } if (info->change_mask & SPA_DEVICE_CHANGE_MASK_PARAMS) { uint32_t i; @@ -894,7 +901,7 @@ const struct pw_properties *pw_impl_device_get_properties(struct pw_impl_device SPA_EXPORT int pw_impl_device_update_properties(struct pw_impl_device *device, const struct spa_dict *dict) { - int changed = update_properties(device, dict); + int changed = update_properties(device, dict, false); emit_info_changed(device); return changed; } diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index e1cfbe481..152f46908 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -1220,11 +1220,19 @@ const struct pw_properties *pw_impl_node_get_properties(struct pw_impl_node *nod return node->properties; } -static int update_properties(struct pw_impl_node *node, const struct spa_dict *dict) +static int update_properties(struct pw_impl_node *node, const struct spa_dict *dict, bool filter) { int changed; + const char *ignored[] = { + PW_KEY_OBJECT_ID, + PW_KEY_MODULE_ID, + PW_KEY_FACTORY_ID, + PW_KEY_CLIENT_ID, + PW_KEY_DEVICE_ID, + NULL + }; - changed = pw_properties_update(node->properties, dict); + changed = pw_properties_update_ignore(node->properties, dict, filter ? ignored : NULL); node->info.props = &node->properties->dict; pw_log_debug(NAME" %p: updated %d properties", node, changed); @@ -1239,7 +1247,7 @@ static int update_properties(struct pw_impl_node *node, const struct spa_dict *d SPA_EXPORT int pw_impl_node_update_properties(struct pw_impl_node *node, const struct spa_dict *dict) { - int changed = update_properties(node, dict); + int changed = update_properties(node, dict, false); emit_info_changed(node, false); return changed; } @@ -1265,7 +1273,7 @@ static void node_info(void *data, const struct spa_node_info *info) } } if (info->change_mask & SPA_NODE_CHANGE_MASK_PROPS) { - update_properties(node, info->props); + update_properties(node, info->props, true); } if (info->change_mask & SPA_NODE_CHANGE_MASK_PARAMS) { uint32_t i; diff --git a/src/pipewire/impl-port.c b/src/pipewire/impl-port.c index ecc2a16ef..bd6074d7f 100644 --- a/src/pipewire/impl-port.c +++ b/src/pipewire/impl-port.c @@ -266,11 +266,19 @@ int pw_impl_port_release_mix(struct pw_impl_port *port, struct pw_impl_port_mix return res; } -static int update_properties(struct pw_impl_port *port, const struct spa_dict *dict) +static int update_properties(struct pw_impl_port *port, const struct spa_dict *dict, bool filter) { int changed; + const char *ignored[] = { + PW_KEY_OBJECT_ID, + PW_KEY_PORT_DIRECTION, + PW_KEY_PORT_CONTROL, + PW_KEY_NODE_ID, + PW_KEY_PORT_ID, + NULL + }; - changed = pw_properties_update(port->properties, dict); + changed = pw_properties_update_ignore(port->properties, dict, filter ? ignored : NULL); port->info.props = &port->properties->dict; if (changed) { @@ -354,7 +362,7 @@ static void update_info(struct pw_impl_port *port, const struct spa_port_info *i } if (info->change_mask & SPA_PORT_CHANGE_MASK_PROPS) { if (info->props) { - update_properties(port, info->props); + update_properties(port, info->props, true); } else { pw_log_warn(NAME" %p: port PROPS update but no properties", port); } @@ -617,10 +625,8 @@ const struct pw_properties *pw_impl_port_get_properties(struct pw_impl_port *por SPA_EXPORT int pw_impl_port_update_properties(struct pw_impl_port *port, const struct spa_dict *dict) { - int changed = update_properties(port, dict); - + int changed = update_properties(port, dict, false); emit_info_changed(port); - return changed; } diff --git a/src/pipewire/properties.c b/src/pipewire/properties.c index c57df300e..d4499543a 100644 --- a/src/pipewire/properties.c +++ b/src/pipewire/properties.c @@ -248,6 +248,30 @@ int pw_properties_update_keys(struct pw_properties *props, return changed; } +static bool has_key(const char *keys[], const char *key) +{ + int i; + for (i = 0; keys[i]; i++) { + if (strcmp(keys[i], key) == 0) + return true; + } + return false; +} + +SPA_EXPORT +int pw_properties_update_ignore(struct pw_properties *props, + const struct spa_dict *dict, const char *ignore[]) +{ + const struct spa_dict_item *it; + int changed = 0; + + spa_dict_for_each(it, dict) { + if (ignore == NULL || !has_key(ignore, it->key)) + changed += pw_properties_set(props, it->key, it->value); + } + return changed; +} + /** Clear a properties object * * \param properties properties to clear diff --git a/src/pipewire/properties.h b/src/pipewire/properties.h index 120bbf423..1784d0c0c 100644 --- a/src/pipewire/properties.h +++ b/src/pipewire/properties.h @@ -30,7 +30,7 @@ extern "C" { #endif #include - + #include /** \class pw_properties @@ -61,6 +61,8 @@ pw_properties_copy(const struct pw_properties *properties); int pw_properties_update_keys(struct pw_properties *props, const struct spa_dict *dict, const char *keys[]); +int pw_properties_update_ignore(struct pw_properties *props, + const struct spa_dict *dict, const char *ignore[]); int pw_properties_update(struct pw_properties *oldprops, const struct spa_dict *dict);