media-session: add conf file for v4l2 and bluez as well

This commit is contained in:
Wim Taymans 2021-01-12 20:38:47 +01:00
parent 4cba8fc7e9
commit fac80e76d2
9 changed files with 292 additions and 116 deletions

View file

@ -202,118 +202,13 @@ static const struct sm_object_methods node_methods = {
.release = node_release,
};
static bool find_match(struct spa_json *arr, struct pw_properties *props)
{
struct spa_json it[1];
while (spa_json_enter_object(arr, &it[0]) > 0) {
char key[256], val[1024];
const char *str, *value;
int match = 0, fail = 0;
int len;
while (spa_json_get_string(&it[0], key, sizeof(key)-1) > 0) {
bool success = false;
if ((len = spa_json_next(&it[0], &value)) <= 0)
break;
if (key[0] == '#')
continue;
str = pw_properties_get(props, key);
if (spa_json_is_null(value, len)) {
success = str == NULL;
} else {
spa_json_parse_string(value, SPA_MIN(len, 1024), val);
value = val;
len = strlen(val);
}
if (str != NULL) {
if (value[0] == '~') {
regex_t preg;
if (regcomp(&preg, value+1, REG_EXTENDED | REG_NOSUB) == 0) {
if (regexec(&preg, str, 0, NULL, 0) == 0)
success = true;
regfree(&preg);
}
} else if (strncmp(str, value, len) == 0) {
success = true;
}
}
if (success) {
match++;
pw_log_debug("'%s' match '%s' < > '%.*s'", key, str, len, value);
}
else
fail++;
}
if (match > 0 && fail == 0)
return true;
}
return false;
}
static int apply_matches(struct impl *impl, struct pw_properties *props)
{
const char *rules, *val;
struct spa_json it[4], actions;;
if ((rules = pw_properties_get(impl->conf, "rules")) == NULL)
return 0;
spa_json_init(&it[0], rules, strlen(rules));
if (spa_json_enter_array(&it[0], &it[1]) < 0)
return 0;
while (spa_json_enter_object(&it[1], &it[2]) > 0) {
char key[64];
bool have_match = false, have_actions = false;
while (spa_json_get_string(&it[2], key, sizeof(key)-1) > 0) {
if (strcmp(key, "matches") == 0) {
if (spa_json_enter_array(&it[2], &it[3]) < 0)
break;
have_match = find_match(&it[3], props);
}
else if (strcmp(key, "actions") == 0) {
if (spa_json_enter_object(&it[2], &actions) > 0)
have_actions = true;
}
else if (spa_json_next(&it[2], &val) <= 0)
break;
}
if (!have_match || !have_actions)
continue;
while (spa_json_get_string(&actions, key, sizeof(key)-1) > 0) {
int len;
pw_log_debug("action %s", key);
if (strcmp(key, "update-props") == 0) {
if ((len = spa_json_next(&actions, &val)) <= 0)
continue;
if (!spa_json_is_object(val, len))
continue;
len = spa_json_container_len(&actions, val, len);
pw_properties_update_string(props, val, len);
}
else if (spa_json_next(&actions, &val) <= 0)
break;
}
}
return 1;
}
static struct node *alsa_create_node(struct device *device, uint32_t id,
const struct spa_device_object_info *info)
{
struct node *node;
struct impl *impl = device->impl;
int res;
const char *dev, *subdev, *stream, *profile, *profile_desc;
const char *dev, *subdev, *stream, *profile, *profile_desc, *rules;
int i, priority;
pw_log_debug("new node %u", id);
@ -443,7 +338,8 @@ static struct node *alsa_create_node(struct device *device, uint32_t id,
node->device = device;
node->id = id;
apply_matches(impl, node->props);
if ((rules = pw_properties_get(impl->conf, "rules")) != NULL)
sm_media_session_match_rules(rules, strlen(rules), node->props);
node->snode = sm_media_session_create_node(impl->session,
"adapter",
@ -946,7 +842,7 @@ static struct device *alsa_create_device(struct impl *impl, uint32_t id,
{
struct device *device;
int res;
const char *str, *card;
const char *str, *card, *rules;
pw_log_debug("new device %u", id);
@ -971,7 +867,8 @@ static struct device *alsa_create_device(struct impl *impl, uint32_t id,
device->pending_profile = 1;
spa_list_append(&impl->device_list, &device->link);
apply_matches(impl, device->props);
if ((rules = pw_properties_get(impl->conf, "rules")) != NULL)
sm_media_session_match_rules(rules, strlen(rules), device->props);
str = pw_properties_get(device->props, "api.alsa.use-acp");
device->use_acp = str ? pw_properties_parse_bool(str) : true;
@ -1101,7 +998,7 @@ int sm_alsa_monitor_start(struct sm_media_session *session)
impl->conf = pw_properties_new(NULL, NULL);
if (impl->conf == NULL) {
free(impl);
return -ENOMEM;
return -errno;
}
if ((res = sm_media_session_load_conf(impl->session,