From 3a9df8096b4c33d3f817e4a244642ee79847d5d2 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 16 Mar 2018 12:46:18 +0100 Subject: [PATCH] WIP add subgraph --- meson.build | 4 +- spa/include/spa/graph/graph.h | 25 ++++++++++++- src/pipewire/node.c | 70 ++++++++++------------------------- src/pipewire/private.h | 2 - 4 files changed, 46 insertions(+), 55 deletions(-) diff --git a/meson.build b/meson.build index f3ceee9c3..9c9210e64 100644 --- a/meson.build +++ b/meson.build @@ -165,8 +165,8 @@ endif subdir('spa') subdir('src') subdir('pkgconfig') -subdir('pipewire-jack') -subdir('alsa-plugins') +#subdir('pipewire-jack') +#subdir('alsa-plugins') if get_option('enable_docs') doxygen = find_program('doxygen', required : false) diff --git a/spa/include/spa/graph/graph.h b/spa/include/spa/graph/graph.h index 80c63fa76..4c34deab5 100644 --- a/spa/include/spa/graph/graph.h +++ b/spa/include/spa/graph/graph.h @@ -47,11 +47,33 @@ struct spa_graph_callbacks { }; struct spa_graph { - struct spa_list nodes; + struct spa_list link; /* link for subgraph */ + struct spa_graph *parent; /* parent graph or NULL when driver */ + struct spa_list nodes; /* list of nodes of this graph */ + struct spa_list subgraphs; /* list of subgraphs */ const struct spa_graph_callbacks *callbacks; void *callbacks_data; }; +static inline struct spa_graph * spa_graph_find_root(struct spa_graph *graph) +{ + while (graph->parent) + graph = graph->parent; + return graph; +} + +static inline void spa_graph_add_subgraph(struct spa_graph *graph, struct spa_graph *subgraph) +{ + subgraph->parent = graph; + spa_list_append(&graph->subgraphs, &subgraph->link); +} + +static inline void spa_graph_remove_subgraph(struct spa_graph *subgraph) +{ + subgraph->parent = NULL; + spa_list_remove(&subgraph->link); +} + #define spa_graph_need_input(g,n) ((g)->callbacks->need_input((g)->callbacks_data, (n))) #define spa_graph_have_output(g,n) ((g)->callbacks->have_output((g)->callbacks_data, (n))) #define spa_graph_run(g) ((g)->callbacks->run((g)->callbacks_data)) @@ -101,6 +123,7 @@ struct spa_graph_port { static inline void spa_graph_init(struct spa_graph *graph) { spa_list_init(&graph->nodes); + spa_list_init(&graph->subgraphs); } static inline void diff --git a/src/pipewire/node.c b/src/pipewire/node.c index 80622ec1c..8b17cc388 100644 --- a/src/pipewire/node.c +++ b/src/pipewire/node.c @@ -46,7 +46,7 @@ struct impl { struct pw_work_queue *work; bool pause_on_idle; - struct spa_graph graph_driver; + struct spa_graph graph; struct spa_graph_data graph_data; struct pw_node_activation activation; @@ -324,42 +324,6 @@ static const struct pw_global_events global_events = { .bind = global_bind, }; -static int -do_node_join(struct spa_loop *loop, - bool async, uint32_t seq, const void *data, size_t size, void *user_data) -{ - struct pw_node *this = user_data; - struct spa_graph *graph = *(struct spa_graph **)data; - struct spa_graph_port *p; - - if (this->rt.node.graph != NULL) { - spa_graph_node_remove(&this->rt.node); - spa_list_for_each(p, &this->rt.node.ports[SPA_DIRECTION_INPUT], link) - spa_graph_node_remove(p->peer->node); - spa_list_for_each(p, &this->rt.node.ports[SPA_DIRECTION_OUTPUT], link) - spa_graph_node_remove(p->peer->node); - } - - if (graph) { - spa_graph_node_add(graph, &this->rt.node); - spa_list_for_each(p, &this->rt.node.ports[SPA_DIRECTION_INPUT], link) - spa_graph_node_add(graph, p->peer->node); - spa_list_for_each(p, &this->rt.node.ports[SPA_DIRECTION_OUTPUT], link) - spa_graph_node_add(graph, p->peer->node); - } - else - this->rt.node.graph = NULL; - - return 0; -} - -int pw_node_join_graph(struct pw_node *node, struct spa_graph *graph) -{ - pw_loop_invoke(node->data_loop, do_node_join, 1, - graph, sizeof(struct spa_graph *), false, node); - return 0; -} - int pw_node_register(struct pw_node *this, struct pw_client *owner, struct pw_global *parent, @@ -428,15 +392,16 @@ static void check_properties(struct pw_node *node) node->driver = pw_properties_parse_bool(str); else node->driver = false; +} - if (node->driver) { - spa_graph_init(&impl->graph_driver); - spa_graph_data_init(&impl->graph_data, &impl->graph_driver); - spa_graph_set_callbacks(&impl->graph_driver, - &spa_graph_impl_default, &impl->graph_data); - pw_node_join_graph(node, &impl->graph_driver); - } - +static int +do_node_join(struct spa_loop *loop, + bool async, uint32_t seq, const void *data, size_t size, void *user_data) +{ + struct pw_node *this = user_data; + struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this); + spa_graph_node_add(&impl->graph, &this->rt.node); + return 0; } struct pw_node *pw_node_new(struct pw_core *core, @@ -485,9 +450,16 @@ struct pw_node *pw_node_new(struct pw_core *core, spa_list_init(&this->output_ports); pw_map_init(&this->output_port_map, 64, 64); - this->rt.activation = &impl->activation; + spa_graph_init(&impl->graph); + spa_graph_data_init(&impl->graph_data, &impl->graph); + spa_graph_set_callbacks(&impl->graph, + &spa_graph_impl_default, &impl->graph_data); + this->rt.activation = &impl->activation; spa_graph_node_init(&this->rt.node, &this->rt.activation->state); + + pw_loop_invoke(this->data_loop, do_node_join, 1, NULL, 0, false, this); + spa_list_init(&this->rt.links[SPA_DIRECTION_INPUT]); spa_list_init(&this->rt.links[SPA_DIRECTION_OUTPUT]); impl->activation.state.status = SPA_STATUS_NEED_BUFFER; @@ -572,14 +544,13 @@ static void node_event(void *data, struct spa_event *event) static void node_need_input(void *data) { struct pw_node *node = data; - struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this); pw_log_trace("node %p: need input %d", node, node->rt.activation->state.status); spa_hook_list_call(&node->listener_list, struct pw_node_events, need_input); if (node->driver) - spa_graph_run(&impl->graph_driver); + spa_graph_run(node->rt.node.graph); else if (node->rt.node.graph) spa_graph_need_input(node->rt.node.graph, &node->rt.node); else @@ -589,14 +560,13 @@ static void node_need_input(void *data) static void node_have_output(void *data) { struct pw_node *node = data; - struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this); pw_log_trace("node %p: have output %d", node, node->driver); spa_hook_list_call(&node->listener_list, struct pw_node_events, have_output); if (node->driver) - spa_graph_run(&impl->graph_driver); + spa_graph_run(node->rt.node.graph); if (node->rt.node.graph) spa_graph_have_output(node->rt.node.graph, &node->rt.node); diff --git a/src/pipewire/private.h b/src/pipewire/private.h index c8b1a9d01..b5e160248 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -594,8 +594,6 @@ void pw_node_update_state(struct pw_node *node, enum pw_node_state state, char * int pw_node_update_ports(struct pw_node *node); -int pw_node_join_graph(struct pw_node *node, struct spa_graph *graph); - /** Activate a link \memberof pw_link * Starts the negotiation of formats and buffers on \a link and then * starts data streaming */