filter-chain: improve filter.graph parsing

First collect all the graph objects and then parse them in the
right order. Otherwise, we might try to parse links before the nodes if
they are first in the JSON string.

Fixes #1950
This commit is contained in:
Wim Taymans 2022-05-07 15:53:10 +02:00
parent 211abaef5e
commit 0c8cd4ab52

View file

@ -1903,8 +1903,9 @@ error:
*/ */
static int load_graph(struct graph *graph, struct pw_properties *props) static int load_graph(struct graph *graph, struct pw_properties *props)
{ {
struct spa_json it[4]; struct spa_json it[3];
struct spa_json inputs, outputs, *pinputs = NULL, *poutputs = NULL; struct spa_json inputs, outputs, *pinputs = NULL, *poutputs = NULL;
struct spa_json nodes, *pnodes = NULL, links, *plinks = NULL;
const char *json, *val; const char *json, *val;
char key[256]; char key[256];
int res; int res;
@ -1925,24 +1926,18 @@ static int load_graph(struct graph *graph, struct pw_properties *props)
while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) { while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) {
if (spa_streq("nodes", key)) { if (spa_streq("nodes", key)) {
if (spa_json_enter_array(&it[1], &it[2]) <= 0) { if (spa_json_enter_array(&it[1], &nodes) <= 0) {
pw_log_error("nodes expects an array"); pw_log_error("nodes expects an array");
return -EINVAL; return -EINVAL;
} }
while (spa_json_enter_object(&it[2], &it[3]) > 0) { pnodes = &nodes;
if ((res = load_node(graph, &it[3])) < 0)
return res;
}
} }
else if (spa_streq("links", key)) { else if (spa_streq("links", key)) {
if (spa_json_enter_array(&it[1], &it[2]) <= 0) { if (spa_json_enter_array(&it[1], &links) <= 0) {
pw_log_error("links expects an array"); pw_log_error("links expects an array");
return -EINVAL; return -EINVAL;
} }
while (spa_json_enter_object(&it[2], &it[3]) > 0) { plinks = &links;
if ((res = parse_link(graph, &it[3])) < 0)
return res;
}
} }
else if (spa_streq("inputs", key)) { else if (spa_streq("inputs", key)) {
if (spa_json_enter_array(&it[1], &inputs) <= 0) { if (spa_json_enter_array(&it[1], &inputs) <= 0) {
@ -1960,6 +1955,20 @@ static int load_graph(struct graph *graph, struct pw_properties *props)
} else if (spa_json_next(&it[1], &val) < 0) } else if (spa_json_next(&it[1], &val) < 0)
break; break;
} }
if (pnodes == NULL) {
pw_log_error("filter.graph is missing a nodes array");
return -EINVAL;
}
while (spa_json_enter_object(pnodes, &it[2]) > 0) {
if ((res = load_node(graph, &it[2])) < 0)
return res;
}
if (plinks != NULL) {
while (spa_json_enter_object(plinks, &it[2]) > 0) {
if ((res = parse_link(graph, &it[2])) < 0)
return res;
}
}
return setup_graph(graph, pinputs, poutputs); return setup_graph(graph, pinputs, poutputs);
} }