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
This commit is contained in:
Wim Taymans 2023-07-17 16:28:18 +02:00
parent 9e0932b319
commit 9e44bd9982
2 changed files with 65 additions and 67 deletions

View file

@ -1222,7 +1222,6 @@ filter_new(struct pw_context *context, const char *name,
struct filter *impl; struct filter *impl;
struct pw_filter *this; struct pw_filter *this;
const char *str; const char *str;
struct match match;
int res; int res;
ensure_loop(context->main_loop, return NULL); 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); spa_hook_list_init(&impl->hooks);
this->properties = props; 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) { if (pw_properties_get(props, PW_KEY_NODE_NAME) == NULL && extra) {
str = pw_properties_get(extra, PW_KEY_APP_NAME); str = pw_properties_get(extra, PW_KEY_APP_NAME);
if (str == NULL) 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); 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->name = name ? strdup(name) : NULL;
this->node_id = SPA_ID_INVALID; 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 filter *impl = SPA_CONTAINER_OF(filter, struct filter, this);
struct pw_properties *props = NULL; struct pw_properties *props = NULL;
const char *str;
struct match match;
int res; int res;
uint32_t i; uint32_t i;
@ -1658,13 +1642,31 @@ pw_filter_connect(struct pw_filter *filter,
if (flags & PW_FILTER_FLAG_DRIVER) if (flags & PW_FILTER_FLAG_DRIVER)
pw_properties_set(filter->properties, PW_KEY_NODE_DRIVER, "true"); 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) { if (flags & PW_FILTER_FLAG_TRIGGER) {
pw_properties_set(filter->properties, PW_KEY_NODE_TRIGGER, "true"); pw_properties_set(filter->properties, PW_KEY_NODE_TRIGGER, "true");
impl->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) { if (filter->core == NULL) {
filter->core = pw_context_connect(impl->context, filter->core = pw_context_connect(impl->context,
pw_properties_copy(filter->properties), 0); pw_properties_copy(filter->properties), 0);

View file

@ -17,7 +17,6 @@
#include <spa/pod/filter.h> #include <spa/pod/filter.h>
#include <spa/pod/dynamic.h> #include <spa/pod/dynamic.h>
#include <spa/debug/types.h> #include <spa/debug/types.h>
#include <spa/debug/dict.h>
#define PW_ENABLE_DEPRECATED #define PW_ENABLE_DEPRECATED
@ -1481,7 +1480,6 @@ stream_new(struct pw_context *context, const char *name,
struct stream *impl; struct stream *impl;
struct pw_stream *this; struct pw_stream *this;
const char *str; const char *str;
struct match match;
int res; int res;
ensure_loop(context->main_loop, return NULL); 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); spa_hook_list_init(&impl->hooks);
this->properties = props; 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) if (pw_properties_get(props, PW_KEY_STREAM_IS_LIVE) == NULL)
pw_properties_set(props, PW_KEY_STREAM_IS_LIVE, "true"); pw_properties_set(props, PW_KEY_STREAM_IS_LIVE, "true");
if (pw_properties_get(props, PW_KEY_NODE_NAME) == NULL && extra) { 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; str = name;
pw_properties_set(props, PW_KEY_NODE_NAME, str); 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->name = name ? strdup(name) : NULL;
this->node_id = SPA_ID_INVALID; this->node_id = SPA_ID_INVALID;
@ -1914,6 +1894,7 @@ pw_stream_connect(struct pw_stream *stream,
struct pw_impl_factory *factory; struct pw_impl_factory *factory;
struct pw_properties *props = NULL; struct pw_properties *props = NULL;
const char *str; const char *str;
struct match match;
uint32_t i; uint32_t i;
int res; int res;
@ -2007,24 +1988,13 @@ pw_stream_connect(struct pw_stream *stream,
impl->using_trigger = false; impl->using_trigger = false;
stream_set_state(stream, PW_STREAM_STATE_CONNECTING, 0, NULL); stream_set_state(stream, PW_STREAM_STATE_CONNECTING, 0, NULL);
if ((str = getenv("PIPEWIRE_NODE")) != NULL) if (target_id != PW_ID_ANY)
pw_properties_set(stream->properties, PW_KEY_TARGET_OBJECT, str);
else if (target_id != PW_ID_ANY)
/* XXX this is deprecated but still used by the portal and its apps */ /* 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); pw_properties_setf(stream->properties, PW_KEY_NODE_TARGET, "%d", target_id);
if (flags & PW_STREAM_FLAG_AUTOCONNECT)
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) {
pw_properties_set(stream->properties, PW_KEY_NODE_AUTOCONNECT, "true"); pw_properties_set(stream->properties, PW_KEY_NODE_AUTOCONNECT, "true");
}
if (flags & PW_STREAM_FLAG_DRIVER) if (flags & PW_STREAM_FLAG_DRIVER)
pw_properties_set(stream->properties, PW_KEY_NODE_DRIVER, "true"); 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) if (flags & PW_STREAM_FLAG_EXCLUSIVE)
pw_properties_set(stream->properties, PW_KEY_NODE_EXCLUSIVE, "true"); pw_properties_set(stream->properties, PW_KEY_NODE_EXCLUSIVE, "true");
if (flags & PW_STREAM_FLAG_DONT_RECONNECT) 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"); pw_properties_set(stream->properties, PW_KEY_NODE_TRIGGER, "true");
impl->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)) { if ((pw_properties_get(stream->properties, PW_KEY_MEDIA_CLASS) == NULL)) {
const char *media_type = pw_properties_get(stream->properties, PW_KEY_MEDIA_TYPE); 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", pw_properties_setf(stream->properties, PW_KEY_MEDIA_CLASS, "Stream/%s/%s",
direction == PW_DIRECTION_INPUT ? "Input" : "Output", direction == PW_DIRECTION_INPUT ? "Input" : "Output",
media_type ? media_type : get_media_class(impl)); media_type ? media_type : get_media_class(impl));
} }
if ((str = pw_properties_get(stream->properties, PW_KEY_FORMAT_DSP)) != NULL) if ((str = pw_properties_get(stream->properties, PW_KEY_FORMAT_DSP)) != NULL)
pw_properties_set(impl->port_props, PW_KEY_FORMAT_DSP, str); pw_properties_set(impl->port_props, PW_KEY_FORMAT_DSP, str);
else if (impl->media_type == SPA_MEDIA_TYPE_application && else if (impl->media_type == SPA_MEDIA_TYPE_application &&
impl->media_subtype == SPA_MEDIA_SUBTYPE_control) impl->media_subtype == SPA_MEDIA_SUBTYPE_control)
pw_properties_set(impl->port_props, PW_KEY_FORMAT_DSP, "8 bit raw midi"); 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; impl->port_info.props = &impl->port_props->dict;
if (stream->core == NULL) { if (stream->core == NULL) {