mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	filter-chain: use node name and port name for control
Address controls with node_name:port_name to access all properties in the graph.
This commit is contained in:
		
							parent
							
								
									4d1fa14774
								
							
						
					
					
						commit
						f9a29c5424
					
				
					 1 changed files with 81 additions and 73 deletions
				
			
		| 
						 | 
					@ -128,7 +128,10 @@ struct ladspa_descriptor {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct port {
 | 
					struct port {
 | 
				
			||||||
 | 
						struct spa_list link;
 | 
				
			||||||
	struct node *node;
 | 
						struct node *node;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t idx;
 | 
				
			||||||
	unsigned long p;
 | 
						unsigned long p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct spa_list link_list;
 | 
						struct spa_list link_list;
 | 
				
			||||||
| 
						 | 
					@ -140,6 +143,8 @@ struct port {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct node {
 | 
					struct node {
 | 
				
			||||||
	struct spa_list link;
 | 
						struct spa_list link;
 | 
				
			||||||
 | 
						struct graph *graph;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct ladspa_descriptor *desc;
 | 
						struct ladspa_descriptor *desc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char name[256];
 | 
						char name[256];
 | 
				
			||||||
| 
						 | 
					@ -351,6 +356,59 @@ static float get_default(struct impl *impl, struct ladspa_descriptor *desc, uint
 | 
				
			||||||
	return def;
 | 
						return def;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct node *find_node(struct graph *graph, const char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct node *node;
 | 
				
			||||||
 | 
						spa_list_for_each(node, &graph->node_list, link) {
 | 
				
			||||||
 | 
							if (strcmp(node->name, name) == 0)
 | 
				
			||||||
 | 
								return node;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct port *find_port(struct graph *graph, const char *name, int descriptor)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct node *node;
 | 
				
			||||||
 | 
						char *col, *node_name, *port_name, *str;
 | 
				
			||||||
 | 
						struct port *ports;
 | 
				
			||||||
 | 
						const LADSPA_Descriptor *d;
 | 
				
			||||||
 | 
						uint32_t i, n_ports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						str = strdupa(name);
 | 
				
			||||||
 | 
						col = strchr(str, ':');
 | 
				
			||||||
 | 
						if (col != NULL) {
 | 
				
			||||||
 | 
							node_name = str;
 | 
				
			||||||
 | 
							port_name = col + 1;
 | 
				
			||||||
 | 
							*col = '\0';
 | 
				
			||||||
 | 
							node = find_node(graph, node_name);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							node = LADSPA_IS_PORT_INPUT(descriptor) ?
 | 
				
			||||||
 | 
								spa_list_first(&graph->node_list, struct node, link) :
 | 
				
			||||||
 | 
								spa_list_last(&graph->node_list, struct node, link);
 | 
				
			||||||
 | 
							node_name = node->name;
 | 
				
			||||||
 | 
							port_name = str;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (node == NULL)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (LADSPA_IS_PORT_INPUT(descriptor)) {
 | 
				
			||||||
 | 
							ports = node->input_port;
 | 
				
			||||||
 | 
							n_ports = node->desc->n_input;
 | 
				
			||||||
 | 
						} else if (LADSPA_IS_PORT_OUTPUT(descriptor)) {
 | 
				
			||||||
 | 
							ports = node->output_port;
 | 
				
			||||||
 | 
							n_ports = node->desc->n_output;
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						d = node->desc->desc;
 | 
				
			||||||
 | 
						for (i = 0; i < n_ports; i++) {
 | 
				
			||||||
 | 
							struct port *port = &ports[i];
 | 
				
			||||||
 | 
							if (strcmp(d->PortNames[port->p], port_name) == 0)
 | 
				
			||||||
 | 
								return port;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct spa_pod *get_prop_info(struct graph *graph, struct spa_pod_builder *b, uint32_t idx)
 | 
					static struct spa_pod *get_prop_info(struct graph *graph, struct spa_pod_builder *b, uint32_t idx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_pod_frame f[2];
 | 
						struct spa_pod_frame f[2];
 | 
				
			||||||
| 
						 | 
					@ -362,6 +420,7 @@ static struct spa_pod *get_prop_info(struct graph *graph, struct spa_pod_builder
 | 
				
			||||||
	const LADSPA_Descriptor *d = desc->desc;
 | 
						const LADSPA_Descriptor *d = desc->desc;
 | 
				
			||||||
	LADSPA_PortRangeHintDescriptor hint = d->PortRangeHints[p].HintDescriptor;
 | 
						LADSPA_PortRangeHintDescriptor hint = d->PortRangeHints[p].HintDescriptor;
 | 
				
			||||||
	float def, upper, lower;
 | 
						float def, upper, lower;
 | 
				
			||||||
 | 
						char name[512];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def = get_default(impl, desc, p);
 | 
						def = get_default(impl, desc, p);
 | 
				
			||||||
	lower = d->PortRangeHints[p].LowerBound;
 | 
						lower = d->PortRangeHints[p].LowerBound;
 | 
				
			||||||
| 
						 | 
					@ -372,11 +431,13 @@ static struct spa_pod *get_prop_info(struct graph *graph, struct spa_pod_builder
 | 
				
			||||||
		upper *= (LADSPA_Data) impl->rate;
 | 
							upper *= (LADSPA_Data) impl->rate;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						snprintf(name, sizeof(name), "%s:%s", node->name, d->PortNames[p]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_pod_builder_push_object(b, &f[0],
 | 
						spa_pod_builder_push_object(b, &f[0],
 | 
				
			||||||
			SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo);
 | 
								SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo);
 | 
				
			||||||
	spa_pod_builder_add (b,
 | 
						spa_pod_builder_add (b,
 | 
				
			||||||
			SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_START_CUSTOM + idx),
 | 
								SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_START_CUSTOM + idx),
 | 
				
			||||||
			SPA_PROP_INFO_name, SPA_POD_String(d->PortNames[p]),
 | 
								SPA_PROP_INFO_name, SPA_POD_String(name),
 | 
				
			||||||
			0);
 | 
								0);
 | 
				
			||||||
	spa_pod_builder_prop(b, SPA_PROP_INFO_type, 0);
 | 
						spa_pod_builder_prop(b, SPA_PROP_INFO_type, 0);
 | 
				
			||||||
	if (lower == upper) {
 | 
						if (lower == upper) {
 | 
				
			||||||
| 
						 | 
					@ -408,20 +469,18 @@ static struct spa_pod *get_props_param(struct graph *graph, struct spa_pod_build
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int set_control_value(struct node *node, const char *name, float *value)
 | 
					static int set_control_value(struct node *node, const char *name, float *value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint32_t i;
 | 
					 | 
				
			||||||
	struct ladspa_descriptor *desc = node->desc;
 | 
						struct ladspa_descriptor *desc = node->desc;
 | 
				
			||||||
 | 
						struct port *port;
 | 
				
			||||||
 | 
						float old;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < desc->n_control; i++) {
 | 
						port = find_port(node->graph, name, LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL);
 | 
				
			||||||
		uint32_t p = desc->control[i];
 | 
						if (port == NULL)
 | 
				
			||||||
		if (strcmp(desc->desc->PortNames[p], name) == 0) {
 | 
					 | 
				
			||||||
			struct port *port = &node->control_port[i];
 | 
					 | 
				
			||||||
			float old = port->control_data;
 | 
					 | 
				
			||||||
			port->control_data = value ? *value : desc->default_control[i];
 | 
					 | 
				
			||||||
			pw_log_info("control %d ('%s') to %f", i, name, port->control_data);
 | 
					 | 
				
			||||||
			return old == port->control_data ? 0 : 1;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						old = port->control_data;
 | 
				
			||||||
 | 
						port->control_data = value ? *value : desc->default_control[port->idx];
 | 
				
			||||||
 | 
						pw_log_info("control %d ('%s') to %f", port->idx, name, port->control_data);
 | 
				
			||||||
 | 
						return old == port->control_data ? 0 : 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void param_changed(void *data, uint32_t id, const struct spa_pod *param)
 | 
					static void param_changed(void *data, uint32_t id, const struct spa_pod *param)
 | 
				
			||||||
| 
						 | 
					@ -591,62 +650,6 @@ static const LADSPA_Descriptor *find_descriptor(LADSPA_Descriptor_Function desc_
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct node *find_node(struct graph *graph, const char *name)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct node *node;
 | 
					 | 
				
			||||||
	spa_list_for_each(node, &graph->node_list, link) {
 | 
					 | 
				
			||||||
		if (strcmp(node->name, name) == 0)
 | 
					 | 
				
			||||||
			return node;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct port *find_port(struct node *node, const char *name, struct port ports[], uint32_t n_ports)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	const LADSPA_Descriptor *d = node->desc->desc;
 | 
					 | 
				
			||||||
	uint32_t i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (i = 0; i < n_ports; i++) {
 | 
					 | 
				
			||||||
		struct port *port = &ports[i];
 | 
					 | 
				
			||||||
		if (strcmp(d->PortNames[port->p], name) == 0)
 | 
					 | 
				
			||||||
			return port;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct port *find_node_port(struct graph *graph, char *name, int mask)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct node *node;
 | 
					 | 
				
			||||||
	char *col, *node_name, *port_name;
 | 
					 | 
				
			||||||
	struct port *ports;
 | 
					 | 
				
			||||||
	uint32_t n_ports;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	col = strchr(name, ':');
 | 
					 | 
				
			||||||
	if (col != NULL) {
 | 
					 | 
				
			||||||
		node_name = name;
 | 
					 | 
				
			||||||
		port_name = col + 1;
 | 
					 | 
				
			||||||
		*col = '\0';
 | 
					 | 
				
			||||||
		node = find_node(graph, node_name);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		node = (mask & LADSPA_PORT_INPUT) ?
 | 
					 | 
				
			||||||
			spa_list_first(&graph->node_list, struct node, link) :
 | 
					 | 
				
			||||||
			spa_list_last(&graph->node_list, struct node, link);
 | 
					 | 
				
			||||||
		node_name = node->name;
 | 
					 | 
				
			||||||
		port_name = name;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (node == NULL)
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (mask & LADSPA_PORT_INPUT) {
 | 
					 | 
				
			||||||
		ports = node->input_port;
 | 
					 | 
				
			||||||
		n_ports = node->desc->n_input;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		ports = node->output_port;
 | 
					 | 
				
			||||||
		n_ports = node->desc->n_output;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return find_port(node, port_name, ports, n_ports);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static uint32_t count_array(struct spa_json *json)
 | 
					static uint32_t count_array(struct spa_json *json)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_json it = *json;
 | 
						struct spa_json it = *json;
 | 
				
			||||||
| 
						 | 
					@ -861,11 +864,11 @@ static int parse_link(struct graph *graph, struct spa_json *json)
 | 
				
			||||||
		else if (spa_json_next(json, &val) < 0)
 | 
							else if (spa_json_next(json, &val) < 0)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if ((out_port = find_node_port(graph, output, LADSPA_PORT_OUTPUT)) == NULL) {
 | 
						if ((out_port = find_port(graph, output, LADSPA_PORT_OUTPUT)) == NULL) {
 | 
				
			||||||
		pw_log_error("unknown output port %s", output);
 | 
							pw_log_error("unknown output port %s", output);
 | 
				
			||||||
		return -ENOENT;
 | 
							return -ENOENT;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if ((in_port = find_node_port(graph, input, LADSPA_PORT_INPUT)) == NULL) {
 | 
						if ((in_port = find_port(graph, input, LADSPA_PORT_INPUT)) == NULL) {
 | 
				
			||||||
		pw_log_error("unknown input port %s", input);
 | 
							pw_log_error("unknown input port %s", input);
 | 
				
			||||||
		return -ENOENT;
 | 
							return -ENOENT;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -956,24 +959,28 @@ static int load_node(struct graph *graph, struct spa_json *json)
 | 
				
			||||||
	if (node == NULL)
 | 
						if (node == NULL)
 | 
				
			||||||
		return -errno;
 | 
							return -errno;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						node->graph = graph;
 | 
				
			||||||
	node->desc = desc;
 | 
						node->desc = desc;
 | 
				
			||||||
	snprintf(node->name, sizeof(node->name), "%s", name);
 | 
						snprintf(node->name, sizeof(node->name), "%s", name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < desc->n_input; i++) {
 | 
						for (i = 0; i < desc->n_input; i++) {
 | 
				
			||||||
		struct port *port = &node->input_port[i];
 | 
							struct port *port = &node->input_port[i];
 | 
				
			||||||
		port->node = node;
 | 
							port->node = node;
 | 
				
			||||||
 | 
							port->idx = i;
 | 
				
			||||||
		port->p = desc->input[i];
 | 
							port->p = desc->input[i];
 | 
				
			||||||
		spa_list_init(&port->link_list);
 | 
							spa_list_init(&port->link_list);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for (i = 0; i < desc->n_output; i++) {
 | 
						for (i = 0; i < desc->n_output; i++) {
 | 
				
			||||||
		struct port *port = &node->output_port[i];
 | 
							struct port *port = &node->output_port[i];
 | 
				
			||||||
		port->node = node;
 | 
							port->node = node;
 | 
				
			||||||
 | 
							port->idx = i;
 | 
				
			||||||
		port->p = desc->output[i];
 | 
							port->p = desc->output[i];
 | 
				
			||||||
		spa_list_init(&port->link_list);
 | 
							spa_list_init(&port->link_list);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for (i = 0; i < desc->n_control; i++) {
 | 
						for (i = 0; i < desc->n_control; i++) {
 | 
				
			||||||
		struct port *port = &node->control_port[i];
 | 
							struct port *port = &node->control_port[i];
 | 
				
			||||||
		port->node = node;
 | 
							port->node = node;
 | 
				
			||||||
 | 
							port->idx = i;
 | 
				
			||||||
		port->p = desc->control[i];
 | 
							port->p = desc->control[i];
 | 
				
			||||||
		spa_list_init(&port->link_list);
 | 
							spa_list_init(&port->link_list);
 | 
				
			||||||
		port->control_data = desc->default_control[i];
 | 
							port->control_data = desc->default_control[i];
 | 
				
			||||||
| 
						 | 
					@ -981,6 +988,7 @@ static int load_node(struct graph *graph, struct spa_json *json)
 | 
				
			||||||
	for (i = 0; i < desc->n_notify; i++) {
 | 
						for (i = 0; i < desc->n_notify; i++) {
 | 
				
			||||||
		struct port *port = &node->notify_port[i];
 | 
							struct port *port = &node->notify_port[i];
 | 
				
			||||||
		port->node = node;
 | 
							port->node = node;
 | 
				
			||||||
 | 
							port->idx = i;
 | 
				
			||||||
		port->p = desc->notify[i];
 | 
							port->p = desc->notify[i];
 | 
				
			||||||
		spa_list_init(&port->link_list);
 | 
							spa_list_init(&port->link_list);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1163,7 +1171,7 @@ static int setup_graph(struct graph *graph, struct spa_json *inputs, struct spa_
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			struct spa_json it = *inputs;
 | 
								struct spa_json it = *inputs;
 | 
				
			||||||
			while (spa_json_get_string(&it, v, sizeof(v)) > 0) {
 | 
								while (spa_json_get_string(&it, v, sizeof(v)) > 0) {
 | 
				
			||||||
				if ((port = find_node_port(graph, v, LADSPA_PORT_INPUT)) == NULL) {
 | 
									if ((port = find_port(graph, v, LADSPA_PORT_INPUT)) == NULL) {
 | 
				
			||||||
					res = -ENOENT;
 | 
										res = -ENOENT;
 | 
				
			||||||
					pw_log_error("input port %s not found", v);
 | 
										pw_log_error("input port %s not found", v);
 | 
				
			||||||
					goto error;
 | 
										goto error;
 | 
				
			||||||
| 
						 | 
					@ -1192,7 +1200,7 @@ static int setup_graph(struct graph *graph, struct spa_json *inputs, struct spa_
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			struct spa_json it = *outputs;
 | 
								struct spa_json it = *outputs;
 | 
				
			||||||
			while (spa_json_get_string(&it, v, sizeof(v)) > 0) {
 | 
								while (spa_json_get_string(&it, v, sizeof(v)) > 0) {
 | 
				
			||||||
				if ((port = find_node_port(graph, v, LADSPA_PORT_OUTPUT)) == NULL) {
 | 
									if ((port = find_port(graph, v, LADSPA_PORT_OUTPUT)) == NULL) {
 | 
				
			||||||
					res = -ENOENT;
 | 
										res = -ENOENT;
 | 
				
			||||||
					pw_log_error("output port %s not found", v);
 | 
										pw_log_error("output port %s not found", v);
 | 
				
			||||||
					goto error;
 | 
										goto error;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue