From e68364e5b7eeaf703a38d69c1db7c46183e046e8 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 27 Apr 2022 11:12:02 +0200 Subject: [PATCH] stream: update node properties completely Add some more context to the match rules and return how many properties changed. If something changed, send all the properties as updates instead of just the original changed ones. --- src/pipewire/filter.c | 22 +++++++++++++++++----- src/pipewire/stream.c | 24 +++++++++++++++++++----- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/pipewire/filter.c b/src/pipewire/filter.c index df5b35519..0eb368def 100644 --- a/src/pipewire/filter.c +++ b/src/pipewire/filter.c @@ -1175,12 +1175,19 @@ static const struct pw_core_events core_events = { .error = on_core_error, }; +struct match { + struct pw_filter *filter; + int count; +}; +#define MATCH_INIT(f) (struct match){ .filter = f } + static int execute_match(void *data, const char *location, const char *action, const char *val, size_t len) { - struct pw_filter *this = data; + struct match *match = data; + struct pw_filter *this = match->filter; if (spa_streq(action, "update-props")) - pw_properties_update_string(this->properties, val, len); + match->count += pw_properties_update_string(this->properties, val, len); return 1; } @@ -1191,6 +1198,7 @@ filter_new(struct pw_context *context, const char *name, struct filter *impl; struct pw_filter *this; const char *str; + struct match match; int res; impl = calloc(1, sizeof(struct filter)); @@ -1216,8 +1224,9 @@ filter_new(struct pw_context *context, const char *name, pw_context_conf_update_props(context, "filter.properties", props); + match = MATCH_INIT(this); pw_context_conf_section_match_rules(context, "filter.rules", - &this->properties->dict, execute_match, this); + &this->properties->dict, execute_match, &match); if ((str = getenv("PIPEWIRE_PROPS")) != NULL) pw_properties_update_string(props, str, strlen(str)); @@ -1469,13 +1478,16 @@ int pw_filter_update_properties(struct pw_filter *filter, void *port_data, const emit_port_info(impl, port, false); } } else { + struct match match; + changed = pw_properties_update(filter->properties, dict); + match = MATCH_INIT(filter); pw_context_conf_section_match_rules(impl->context, "filter.rules", - &filter->properties->dict, execute_match, filter); + &filter->properties->dict, execute_match, &match); impl->info.props = &filter->properties->dict; - if (changed > 0) { + if (changed > 0 || match.count > 0) { impl->info.change_mask |= SPA_NODE_CHANGE_MASK_PROPS; emit_node_info(impl, false); } diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index 237e55dc2..0f8e9c1c1 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -1370,12 +1370,19 @@ static const struct pw_context_driver_events context_events = { .drained = context_drained, }; +struct match { + struct pw_stream *stream; + int count; +}; +#define MATCH_INIT(s) (struct match){ .stream = s } + static int execute_match(void *data, const char *location, const char *action, const char *val, size_t len) { - struct pw_stream *this = data; + struct match *match = data; + struct pw_stream *this = match->stream; if (spa_streq(action, "update-props")) - pw_properties_update_string(this->properties, val, len); + match->count += pw_properties_update_string(this->properties, val, len); return 1; } @@ -1386,6 +1393,7 @@ stream_new(struct pw_context *context, const char *name, struct stream *impl; struct pw_stream *this; const char *str; + struct match match; int res; impl = calloc(1, sizeof(struct stream)); @@ -1416,8 +1424,9 @@ stream_new(struct pw_context *context, const char *name, pw_context_conf_update_props(context, "stream.properties", props); + match = MATCH_INIT(this); pw_context_conf_section_match_rules(context, "stream.rules", - &this->properties->dict, execute_match, this); + &this->properties->dict, execute_match, &match); if ((str = getenv("PIPEWIRE_PROPS")) != NULL) pw_properties_update_string(props, str, strlen(str)); @@ -1654,16 +1663,21 @@ int pw_stream_update_properties(struct pw_stream *stream, const struct spa_dict { struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this); int changed, res = 0; + struct match match; changed = pw_properties_update(stream->properties, dict); if (!changed) return 0; + match = MATCH_INIT(stream); pw_context_conf_section_match_rules(impl->context, "stream.rules", - &stream->properties->dict, execute_match, stream); + &stream->properties->dict, execute_match, &match); if (impl->node) - res = pw_impl_node_update_properties(impl->node, dict); + res = pw_impl_node_update_properties(impl->node, + match.count == 0 ? + dict : + &stream->properties->dict); return res; }