From 9e44bd998212c697547fad2fcbc8130d36e6bf9f Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 17 Jul 2023 16:28:18 +0200 Subject: [PATCH] stream: reorder property rules evaluation First update some stream defaults, then apply generic property updates. Before connecting, fill in some more default with the flags and the direction of the stream, then evaluate the rules, then overwrite with environment values. This ensure that the rules can also use the flags and direction used during _connect(). See #3355 --- src/pipewire/filter.c | 52 ++++++++++++++-------------- src/pipewire/stream.c | 80 ++++++++++++++++++++----------------------- 2 files changed, 65 insertions(+), 67 deletions(-) diff --git a/src/pipewire/filter.c b/src/pipewire/filter.c index 271f2bafa..abfb573ae 100644 --- a/src/pipewire/filter.c +++ b/src/pipewire/filter.c @@ -1222,7 +1222,6 @@ filter_new(struct pw_context *context, const char *name, struct filter *impl; struct pw_filter *this; const char *str; - struct match match; int res; ensure_loop(context->main_loop, return NULL); @@ -1250,28 +1249,6 @@ filter_new(struct pw_context *context, const char *name, spa_hook_list_init(&impl->hooks); this->properties = props; - 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, &match); - - if ((str = getenv("PIPEWIRE_PROPS")) != NULL) - pw_properties_update_string(props, str, strlen(str)); - if ((str = getenv("PIPEWIRE_QUANTUM")) != NULL) { - struct spa_fraction q; - if (sscanf(str, "%u/%u", &q.num, &q.denom) == 2 && q.denom != 0) { - pw_properties_setf(props, PW_KEY_NODE_RATE, - "1/%u", q.denom); - pw_properties_setf(props, PW_KEY_NODE_LATENCY, - "%u/%u", q.num, q.denom); - } - } - if ((str = getenv("PIPEWIRE_LATENCY")) != NULL) - pw_properties_set(props, PW_KEY_NODE_LATENCY, str); - if ((str = getenv("PIPEWIRE_RATE")) != NULL) - pw_properties_set(props, PW_KEY_NODE_RATE, str); - if (pw_properties_get(props, PW_KEY_NODE_NAME) == NULL && extra) { str = pw_properties_get(extra, PW_KEY_APP_NAME); if (str == NULL) @@ -1281,6 +1258,11 @@ filter_new(struct pw_context *context, const char *name, pw_properties_set(props, PW_KEY_NODE_NAME, str); } + if ((pw_properties_get(props, PW_KEY_NODE_WANT_DRIVER) == NULL)) + pw_properties_set(props, PW_KEY_NODE_WANT_DRIVER, "true"); + + pw_context_conf_update_props(context, "filter.properties", props); + this->name = name ? strdup(name) : NULL; this->node_id = SPA_ID_INVALID; @@ -1605,6 +1587,8 @@ pw_filter_connect(struct pw_filter *filter, { struct filter *impl = SPA_CONTAINER_OF(filter, struct filter, this); struct pw_properties *props = NULL; + const char *str; + struct match match; int res; uint32_t i; @@ -1658,13 +1642,31 @@ pw_filter_connect(struct pw_filter *filter, if (flags & PW_FILTER_FLAG_DRIVER) pw_properties_set(filter->properties, PW_KEY_NODE_DRIVER, "true"); - if ((pw_properties_get(filter->properties, PW_KEY_NODE_WANT_DRIVER) == NULL)) - pw_properties_set(filter->properties, PW_KEY_NODE_WANT_DRIVER, "true"); if (flags & PW_FILTER_FLAG_TRIGGER) { pw_properties_set(filter->properties, PW_KEY_NODE_TRIGGER, "true"); impl->trigger = true; } + match = MATCH_INIT(filter); + pw_context_conf_section_match_rules(impl->context, "filter.rules", + &filter->properties->dict, execute_match, &match); + + if ((str = getenv("PIPEWIRE_PROPS")) != NULL) + pw_properties_update_string(filter->properties, str, strlen(str)); + if ((str = getenv("PIPEWIRE_QUANTUM")) != NULL) { + struct spa_fraction q; + if (sscanf(str, "%u/%u", &q.num, &q.denom) == 2 && q.denom != 0) { + pw_properties_setf(filter->properties, PW_KEY_NODE_RATE, + "1/%u", q.denom); + pw_properties_setf(filter->properties, PW_KEY_NODE_LATENCY, + "%u/%u", q.num, q.denom); + } + } + if ((str = getenv("PIPEWIRE_LATENCY")) != NULL) + pw_properties_set(filter->properties, PW_KEY_NODE_LATENCY, str); + if ((str = getenv("PIPEWIRE_RATE")) != NULL) + pw_properties_set(filter->properties, PW_KEY_NODE_RATE, str); + if (filter->core == NULL) { filter->core = pw_context_connect(impl->context, pw_properties_copy(filter->properties), 0); diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index a40418400..067ecad4a 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -17,7 +17,6 @@ #include #include #include -#include #define PW_ENABLE_DEPRECATED @@ -1481,7 +1480,6 @@ stream_new(struct pw_context *context, const char *name, struct stream *impl; struct pw_stream *this; const char *str; - struct match match; int res; ensure_loop(context->main_loop, return NULL); @@ -1513,28 +1511,6 @@ stream_new(struct pw_context *context, const char *name, spa_hook_list_init(&impl->hooks); this->properties = props; - 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, &match); - - if ((str = getenv("PIPEWIRE_PROPS")) != NULL) - pw_properties_update_string(props, str, strlen(str)); - if ((str = getenv("PIPEWIRE_QUANTUM")) != NULL) { - struct spa_fraction q; - if (sscanf(str, "%u/%u", &q.num, &q.denom) == 2 && q.denom != 0) { - pw_properties_setf(props, PW_KEY_NODE_RATE, - "1/%u", q.denom); - pw_properties_setf(props, PW_KEY_NODE_LATENCY, - "%u/%u", q.num, q.denom); - } - } - if ((str = getenv("PIPEWIRE_LATENCY")) != NULL) - pw_properties_set(props, PW_KEY_NODE_LATENCY, str); - if ((str = getenv("PIPEWIRE_RATE")) != NULL) - pw_properties_set(props, PW_KEY_NODE_RATE, str); - if (pw_properties_get(props, PW_KEY_STREAM_IS_LIVE) == NULL) pw_properties_set(props, PW_KEY_STREAM_IS_LIVE, "true"); if (pw_properties_get(props, PW_KEY_NODE_NAME) == NULL && extra) { @@ -1545,6 +1521,10 @@ stream_new(struct pw_context *context, const char *name, str = name; pw_properties_set(props, PW_KEY_NODE_NAME, str); } + if ((pw_properties_get(props, PW_KEY_NODE_WANT_DRIVER) == NULL)) + pw_properties_set(props, PW_KEY_NODE_WANT_DRIVER, "true"); + + pw_context_conf_update_props(context, "stream.properties", props); this->name = name ? strdup(name) : NULL; this->node_id = SPA_ID_INVALID; @@ -1914,6 +1894,7 @@ pw_stream_connect(struct pw_stream *stream, struct pw_impl_factory *factory; struct pw_properties *props = NULL; const char *str; + struct match match; uint32_t i; int res; @@ -2007,24 +1988,13 @@ pw_stream_connect(struct pw_stream *stream, impl->using_trigger = false; stream_set_state(stream, PW_STREAM_STATE_CONNECTING, 0, NULL); - if ((str = getenv("PIPEWIRE_NODE")) != NULL) - pw_properties_set(stream->properties, PW_KEY_TARGET_OBJECT, str); - else if (target_id != PW_ID_ANY) + if (target_id != PW_ID_ANY) /* XXX this is deprecated but still used by the portal and its apps */ pw_properties_setf(stream->properties, PW_KEY_NODE_TARGET, "%d", target_id); - - if ((str = getenv("PIPEWIRE_AUTOCONNECT")) != NULL) - pw_properties_set(stream->properties, - PW_KEY_NODE_AUTOCONNECT, spa_atob(str) ? "true" : "false"); - else if ((flags & PW_STREAM_FLAG_AUTOCONNECT) && - pw_properties_get(stream->properties, PW_KEY_NODE_AUTOCONNECT) == NULL) { + if (flags & PW_STREAM_FLAG_AUTOCONNECT) pw_properties_set(stream->properties, PW_KEY_NODE_AUTOCONNECT, "true"); - } if (flags & PW_STREAM_FLAG_DRIVER) pw_properties_set(stream->properties, PW_KEY_NODE_DRIVER, "true"); - if ((pw_properties_get(stream->properties, PW_KEY_NODE_WANT_DRIVER) == NULL)) - pw_properties_set(stream->properties, PW_KEY_NODE_WANT_DRIVER, "true"); - if (flags & PW_STREAM_FLAG_EXCLUSIVE) pw_properties_set(stream->properties, PW_KEY_NODE_EXCLUSIVE, "true"); if (flags & PW_STREAM_FLAG_DONT_RECONNECT) @@ -2033,23 +2003,49 @@ pw_stream_connect(struct pw_stream *stream, pw_properties_set(stream->properties, PW_KEY_NODE_TRIGGER, "true"); impl->trigger = true; } - - if ((str = pw_properties_get(stream->properties, "mem.warn-mlock")) != NULL) - impl->warn_mlock = pw_properties_parse_bool(str); - if ((pw_properties_get(stream->properties, PW_KEY_MEDIA_CLASS) == NULL)) { const char *media_type = pw_properties_get(stream->properties, PW_KEY_MEDIA_TYPE); pw_properties_setf(stream->properties, PW_KEY_MEDIA_CLASS, "Stream/%s/%s", direction == PW_DIRECTION_INPUT ? "Input" : "Output", media_type ? media_type : get_media_class(impl)); } - if ((str = pw_properties_get(stream->properties, PW_KEY_FORMAT_DSP)) != NULL) pw_properties_set(impl->port_props, PW_KEY_FORMAT_DSP, str); else if (impl->media_type == SPA_MEDIA_TYPE_application && impl->media_subtype == SPA_MEDIA_SUBTYPE_control) pw_properties_set(impl->port_props, PW_KEY_FORMAT_DSP, "8 bit raw midi"); + match = MATCH_INIT(stream); + pw_context_conf_section_match_rules(impl->context, "stream.rules", + &stream->properties->dict, execute_match, &match); + + if ((str = getenv("PIPEWIRE_NODE")) != NULL) + pw_properties_set(stream->properties, PW_KEY_TARGET_OBJECT, str); + if ((str = getenv("PIPEWIRE_AUTOCONNECT")) != NULL) + pw_properties_set(stream->properties, + PW_KEY_NODE_AUTOCONNECT, spa_atob(str) ? "true" : "false"); + + if ((str = getenv("PIPEWIRE_PROPS")) != NULL) + pw_properties_update_string(stream->properties, str, strlen(str)); + if ((str = getenv("PIPEWIRE_QUANTUM")) != NULL) { + struct spa_fraction q; + if (sscanf(str, "%u/%u", &q.num, &q.denom) == 2 && q.denom != 0) { + pw_properties_setf(stream->properties, PW_KEY_NODE_RATE, + "1/%u", q.denom); + pw_properties_setf(stream->properties, PW_KEY_NODE_LATENCY, + "%u/%u", q.num, q.denom); + } + } + if ((str = getenv("PIPEWIRE_LATENCY")) != NULL) + pw_properties_set(stream->properties, PW_KEY_NODE_LATENCY, str); + if ((str = getenv("PIPEWIRE_RATE")) != NULL) + pw_properties_set(stream->properties, PW_KEY_NODE_RATE, str); + + if ((str = pw_properties_get(stream->properties, "mem.warn-mlock")) != NULL) + impl->warn_mlock = pw_properties_parse_bool(str); + if ((str = pw_properties_get(stream->properties, "mem.allow-mlock")) != NULL) + impl->allow_mlock = pw_properties_parse_bool(str); + impl->port_info.props = &impl->port_props->dict; if (stream->core == NULL) {