context: add loader.rules

Add loader.rules that are executed right before the loader tries to load
the plugin with the info. This can be used to add or change properties
for the plugin.

One example would be to pass extra properties to the alsa or v4l2
plugin, even when this plugin is loaded by another process like
wireplumber.
This commit is contained in:
Wim Taymans 2024-06-07 11:45:22 +02:00
parent d6c17681da
commit cfeb937443

View File

@ -1930,6 +1930,25 @@ const char *pw_context_find_spa_lib(struct pw_context *context, const char *fact
return NULL;
}
struct match {
const struct spa_dict *info;
struct pw_properties *props;
int count;
};
#define MATCH_INIT(i) ((struct match){ .info = (i) })
static int execute_match(void *data, const char *location, const char *action,
const char *val, size_t len)
{
struct match *match = data;
if (spa_streq(action, "update-props")) {
if (match->props == NULL)
match->props = pw_properties_new_dict(match->info);
match->count += pw_properties_update_string(match->props, val, len);
}
return 1;
}
SPA_EXPORT
struct spa_handle *pw_context_load_spa_handle(struct pw_context *context,
const char *factory_name,
@ -1939,6 +1958,7 @@ struct spa_handle *pw_context_load_spa_handle(struct pw_context *context,
const struct spa_support *support;
uint32_t n_support;
struct spa_handle *handle;
struct match match;
pw_log_debug("%p: load factory %s", context, factory_name);
@ -1952,11 +1972,20 @@ struct spa_handle *pw_context_load_spa_handle(struct pw_context *context,
return NULL;
}
support = context_get_support(context, &n_support, info);
match = MATCH_INIT(info);
if (info) {
pw_context_conf_section_match_rules(context, "loader.rules",
info, execute_match, &match);
if (match.props)
info = &match.props->dict;
}
support = context_get_support(context, &n_support, info);
handle = pw_load_spa_handle(lib, factory_name,
info, n_support, support);
pw_properties_free(match.props);
return handle;
}