mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	WIP add subgraph
This commit is contained in:
		
							parent
							
								
									933635f63f
								
							
						
					
					
						commit
						3a9df8096b
					
				
					 4 changed files with 46 additions and 55 deletions
				
			
		| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue