mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	spa: allocate ports dynamically
So that we don't need to allocate large memory blocks that are mostly unused. See #1840
This commit is contained in:
		
							parent
							
								
									3f87741b27
								
							
						
					
					
						commit
						2ed62f53d9
					
				
					 5 changed files with 107 additions and 44 deletions
				
			
		| 
						 | 
				
			
			@ -160,8 +160,8 @@ struct impl {
 | 
			
		|||
 | 
			
		||||
	uint32_t port_count;
 | 
			
		||||
	uint32_t monitor_count;
 | 
			
		||||
	struct port in_ports[MAX_PORTS];
 | 
			
		||||
	struct port out_ports[MAX_PORTS + 1];
 | 
			
		||||
	struct port *in_ports[MAX_PORTS];
 | 
			
		||||
	struct port *out_ports[MAX_PORTS + 1];
 | 
			
		||||
 | 
			
		||||
	struct spa_audio_info format;
 | 
			
		||||
	unsigned int have_profile:1;
 | 
			
		||||
| 
						 | 
				
			
			@ -187,8 +187,8 @@ struct impl {
 | 
			
		|||
#define CHECK_IN_PORT(this,d,p)		((d) == SPA_DIRECTION_INPUT && (p) < this->port_count)
 | 
			
		||||
#define CHECK_OUT_PORT(this,d,p)	((d) == SPA_DIRECTION_OUTPUT && (p) <= this->monitor_count)
 | 
			
		||||
#define CHECK_PORT(this,d,p)		(CHECK_OUT_PORT(this,d,p) || CHECK_IN_PORT (this,d,p))
 | 
			
		||||
#define GET_IN_PORT(this,p)		(&this->in_ports[p])
 | 
			
		||||
#define GET_OUT_PORT(this,p)		(&this->out_ports[p])
 | 
			
		||||
#define GET_IN_PORT(this,p)		(this->in_ports[p])
 | 
			
		||||
#define GET_OUT_PORT(this,p)		(this->out_ports[p])
 | 
			
		||||
#define GET_PORT(this,d,p)		(d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,p) : GET_OUT_PORT(this,p))
 | 
			
		||||
 | 
			
		||||
#define PORT_IS_DSP(d,p) (p != 0 || d != SPA_DIRECTION_OUTPUT)
 | 
			
		||||
| 
						 | 
				
			
			@ -232,6 +232,15 @@ static int init_port(struct impl *this, enum spa_direction direction, uint32_t p
 | 
			
		|||
	struct port *port = GET_PORT(this, direction, port_id);
 | 
			
		||||
	const char *name;
 | 
			
		||||
 | 
			
		||||
	if (port == NULL) {
 | 
			
		||||
		port = calloc(1, sizeof(struct port));
 | 
			
		||||
		if (port == NULL)
 | 
			
		||||
			return -errno;
 | 
			
		||||
		if (direction == SPA_DIRECTION_INPUT)
 | 
			
		||||
			this->in_ports[port_id] = port;
 | 
			
		||||
		else
 | 
			
		||||
			this->out_ports[port_id] = port;
 | 
			
		||||
	}
 | 
			
		||||
	port->direction = direction;
 | 
			
		||||
	port->id = port_id;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1500,6 +1509,17 @@ static int impl_get_interface(struct spa_handle *handle, const char *type, void
 | 
			
		|||
 | 
			
		||||
static int impl_clear(struct spa_handle *handle)
 | 
			
		||||
{
 | 
			
		||||
	struct impl *this;
 | 
			
		||||
	uint32_t i;
 | 
			
		||||
 | 
			
		||||
	spa_return_val_if_fail(handle != NULL, -EINVAL);
 | 
			
		||||
 | 
			
		||||
	this = (struct impl *) handle;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < MAX_PORTS; i++)
 | 
			
		||||
		free(this->in_ports[i]);
 | 
			
		||||
	for (i = 0; i < MAX_PORTS+1; i++)
 | 
			
		||||
		free(this->out_ports[i]);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1518,7 +1538,6 @@ impl_init(const struct spa_handle_factory *factory,
 | 
			
		|||
	  uint32_t n_support)
 | 
			
		||||
{
 | 
			
		||||
	struct impl *this;
 | 
			
		||||
	struct port *port;
 | 
			
		||||
	uint32_t i;
 | 
			
		||||
 | 
			
		||||
	spa_return_val_if_fail(factory != NULL, -EINVAL);
 | 
			
		||||
| 
						 | 
				
			
			@ -1564,22 +1583,7 @@ impl_init(const struct spa_handle_factory *factory,
 | 
			
		|||
	this->info.params = this->params;
 | 
			
		||||
	this->info.n_params = N_NODE_PARAMS;
 | 
			
		||||
 | 
			
		||||
	port = GET_OUT_PORT(this, 0);
 | 
			
		||||
	port->direction = SPA_DIRECTION_OUTPUT;
 | 
			
		||||
	port->id = 0;
 | 
			
		||||
	port->info_all = SPA_PORT_CHANGE_MASK_FLAGS |
 | 
			
		||||
			SPA_PORT_CHANGE_MASK_PARAMS;
 | 
			
		||||
	port->info = SPA_PORT_INFO_INIT();
 | 
			
		||||
	port->info.flags = SPA_PORT_FLAG_DYNAMIC_DATA;
 | 
			
		||||
	port->params[IDX_EnumFormat] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
 | 
			
		||||
	port->params[IDX_Meta] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ);
 | 
			
		||||
	port->params[IDX_IO] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
 | 
			
		||||
	port->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
 | 
			
		||||
	port->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
 | 
			
		||||
	port->params[IDX_Latency] = SPA_PARAM_INFO(SPA_PARAM_Latency, SPA_PARAM_INFO_READWRITE);
 | 
			
		||||
	port->info.params = port->params;
 | 
			
		||||
	port->info.n_params = N_PORT_PARAMS;
 | 
			
		||||
	spa_list_init(&port->queue);
 | 
			
		||||
	init_port(this, SPA_DIRECTION_OUTPUT, 0, 0);
 | 
			
		||||
 | 
			
		||||
	this->volume.cpu_flags = this->cpu_flags;
 | 
			
		||||
	volume_init(&this->volume);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -118,7 +118,7 @@ struct impl {
 | 
			
		|||
	struct spa_hook_list hooks;
 | 
			
		||||
 | 
			
		||||
	struct port in_ports[1];
 | 
			
		||||
	struct port out_ports[MAX_PORTS];
 | 
			
		||||
	struct port *out_ports[MAX_PORTS];
 | 
			
		||||
	uint32_t port_count;
 | 
			
		||||
 | 
			
		||||
	struct spa_audio_info format;
 | 
			
		||||
| 
						 | 
				
			
			@ -141,7 +141,7 @@ struct impl {
 | 
			
		|||
#define CHECK_IN_PORT(this,d,p)		((d) == SPA_DIRECTION_INPUT && (p) == 0)
 | 
			
		||||
#define CHECK_PORT(this,d,p)		(CHECK_OUT_PORT(this,d,p) || CHECK_IN_PORT (this,d,p))
 | 
			
		||||
#define GET_IN_PORT(this,p)		(&this->in_ports[p])
 | 
			
		||||
#define GET_OUT_PORT(this,p)		(&this->out_ports[p])
 | 
			
		||||
#define GET_OUT_PORT(this,p)		(this->out_ports[p])
 | 
			
		||||
#define GET_PORT(this,d,p)		(d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,p) : GET_OUT_PORT(this,p))
 | 
			
		||||
 | 
			
		||||
static void emit_node_info(struct impl *this, bool full)
 | 
			
		||||
| 
						 | 
				
			
			@ -172,6 +172,12 @@ static int init_port(struct impl *this, enum spa_direction direction,
 | 
			
		|||
	struct port *port = GET_OUT_PORT(this, port_id);
 | 
			
		||||
	const char *name;
 | 
			
		||||
 | 
			
		||||
	if (port == NULL) {
 | 
			
		||||
		port = calloc(1, sizeof(struct port));
 | 
			
		||||
		if (port == NULL)
 | 
			
		||||
			return -errno;
 | 
			
		||||
		this->out_ports[port_id] = port;
 | 
			
		||||
	}
 | 
			
		||||
	port->direction = direction;
 | 
			
		||||
	port->id = port_id;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1101,6 +1107,15 @@ static int impl_get_interface(struct spa_handle *handle, const char *type, void
 | 
			
		|||
 | 
			
		||||
static int impl_clear(struct spa_handle *handle)
 | 
			
		||||
{
 | 
			
		||||
	struct impl *this;
 | 
			
		||||
	uint32_t i;
 | 
			
		||||
 | 
			
		||||
	spa_return_val_if_fail(handle != NULL, -EINVAL);
 | 
			
		||||
 | 
			
		||||
	this = (struct impl *) handle;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < MAX_PORTS; i++)
 | 
			
		||||
		free(this->out_ports[i]);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -118,7 +118,7 @@ struct impl {
 | 
			
		|||
 | 
			
		||||
	uint32_t port_count;
 | 
			
		||||
	uint32_t last_port;
 | 
			
		||||
	struct port in_ports[MAX_PORTS];
 | 
			
		||||
	struct port *in_ports[MAX_PORTS];
 | 
			
		||||
	struct port out_ports[1];
 | 
			
		||||
 | 
			
		||||
	int n_formats;
 | 
			
		||||
| 
						 | 
				
			
			@ -133,11 +133,12 @@ struct impl {
 | 
			
		|||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define CHECK_FREE_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && !this->in_ports[(p)].valid)
 | 
			
		||||
#define CHECK_IN_PORT(this,d,p)      ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && this->in_ports[(p)].valid)
 | 
			
		||||
#define PORT_VALID(p)                ((p) != NULL && (p)->valid)
 | 
			
		||||
#define CHECK_FREE_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && !PORT_VALID(this->in_ports[(p)]))
 | 
			
		||||
#define CHECK_IN_PORT(this,d,p)      ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && PORT_VALID(this->in_ports[(p)]))
 | 
			
		||||
#define CHECK_OUT_PORT(this,d,p)     ((d) == SPA_DIRECTION_OUTPUT && (p) == 0)
 | 
			
		||||
#define CHECK_PORT(this,d,p)         (CHECK_OUT_PORT(this,d,p) || CHECK_IN_PORT (this,d,p))
 | 
			
		||||
#define GET_IN_PORT(this,p)          (&this->in_ports[p])
 | 
			
		||||
#define GET_IN_PORT(this,p)          (this->in_ports[p])
 | 
			
		||||
#define GET_OUT_PORT(this,p)         (&this->out_ports[p])
 | 
			
		||||
#define GET_PORT(this,d,p)           (d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,p) : GET_OUT_PORT(this,p))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -218,7 +219,7 @@ static int impl_node_add_listener(void *object,
 | 
			
		|||
	emit_node_info(this, true);
 | 
			
		||||
	emit_port_info(this, GET_OUT_PORT(this, 0), true);
 | 
			
		||||
	for (i = 0; i < this->last_port; i++) {
 | 
			
		||||
		if (this->in_ports[i].valid)
 | 
			
		||||
		if (PORT_VALID(this->in_ports[i]))
 | 
			
		||||
			emit_port_info(this, GET_IN_PORT(this, i), true);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -245,6 +246,12 @@ static int impl_node_add_port(void *object, enum spa_direction direction, uint32
 | 
			
		|||
	spa_return_val_if_fail(CHECK_FREE_IN_PORT(this, direction, port_id), -EINVAL);
 | 
			
		||||
 | 
			
		||||
	port = GET_IN_PORT(this, port_id);
 | 
			
		||||
	if (port == NULL) {
 | 
			
		||||
		port = calloc(1, sizeof(struct port));
 | 
			
		||||
		if (port == NULL)
 | 
			
		||||
			return -errno;
 | 
			
		||||
		this->in_ports[port_id] = port;
 | 
			
		||||
	}
 | 
			
		||||
	port->direction = SPA_DIRECTION_INPUT;
 | 
			
		||||
	port->id = port_id;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -301,7 +308,7 @@ impl_node_remove_port(void *object, enum spa_direction direction, uint32_t port_
 | 
			
		|||
		int i;
 | 
			
		||||
 | 
			
		||||
		for (i = this->last_port - 1; i >= 0; i--)
 | 
			
		||||
			if (GET_IN_PORT (this, i)->valid)
 | 
			
		||||
			if (PORT_VALID(GET_IN_PORT(this, i)))
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
		this->last_port = i + 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -749,13 +756,13 @@ static int impl_node_process(void *object)
 | 
			
		|||
		struct spa_io_buffers *inio = NULL;
 | 
			
		||||
		struct buffer *inb;
 | 
			
		||||
 | 
			
		||||
		if (SPA_UNLIKELY(!inport->valid ||
 | 
			
		||||
		if (SPA_UNLIKELY(!PORT_VALID(inport) ||
 | 
			
		||||
		    (inio = inport->io) == NULL ||
 | 
			
		||||
		    inio->buffer_id >= inport->n_buffers ||
 | 
			
		||||
		    inio->status != SPA_STATUS_HAVE_DATA)) {
 | 
			
		||||
			spa_log_trace_fp(this->log, "%p: skip input idx:%d valid:%d "
 | 
			
		||||
					"io:%p status:%d buf_id:%d n_buffers:%d", this,
 | 
			
		||||
				i, inport->valid, inio,
 | 
			
		||||
				i, PORT_VALID(inport), inio,
 | 
			
		||||
				inio ? inio->status : -1,
 | 
			
		||||
				inio ? inio->buffer_id : SPA_ID_INVALID,
 | 
			
		||||
				inport->n_buffers);
 | 
			
		||||
| 
						 | 
				
			
			@ -841,11 +848,14 @@ static int impl_get_interface(struct spa_handle *handle, const char *type, void
 | 
			
		|||
static int impl_clear(struct spa_handle *handle)
 | 
			
		||||
{
 | 
			
		||||
	struct impl *this;
 | 
			
		||||
	uint32_t i;
 | 
			
		||||
 | 
			
		||||
	spa_return_val_if_fail(handle != NULL, -EINVAL);
 | 
			
		||||
 | 
			
		||||
	this = (struct impl *) handle;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < MAX_PORTS; i++)
 | 
			
		||||
		free(this->in_ports[i]);
 | 
			
		||||
	mix_ops_free(&this->ops);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -117,7 +117,7 @@ struct impl {
 | 
			
		|||
 | 
			
		||||
	uint32_t port_count;
 | 
			
		||||
	uint32_t last_port;
 | 
			
		||||
	struct port in_ports[MAX_PORTS];
 | 
			
		||||
	struct port *in_ports[MAX_PORTS];
 | 
			
		||||
	struct port out_ports[1];
 | 
			
		||||
 | 
			
		||||
	int n_formats;
 | 
			
		||||
| 
						 | 
				
			
			@ -130,11 +130,12 @@ struct impl {
 | 
			
		|||
	float empty[MAX_SAMPLES + MAX_ALIGN];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define CHECK_FREE_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && !this->in_ports[(p)].valid)
 | 
			
		||||
#define CHECK_IN_PORT(this,d,p)      ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && this->in_ports[(p)].valid)
 | 
			
		||||
#define PORT_VALID(p)                ((p) != NULL && (p)->valid)
 | 
			
		||||
#define CHECK_FREE_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && !PORT_VALID(this->in_ports[(p)]))
 | 
			
		||||
#define CHECK_IN_PORT(this,d,p)      ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && PORT_VALID(this->in_ports[(p)]))
 | 
			
		||||
#define CHECK_OUT_PORT(this,d,p)     ((d) == SPA_DIRECTION_OUTPUT && (p) == 0)
 | 
			
		||||
#define CHECK_PORT(this,d,p)         (CHECK_OUT_PORT(this,d,p) || CHECK_IN_PORT (this,d,p))
 | 
			
		||||
#define GET_IN_PORT(this,p)          (&this->in_ports[p])
 | 
			
		||||
#define GET_IN_PORT(this,p)          (this->in_ports[p])
 | 
			
		||||
#define GET_OUT_PORT(this,p)         (&this->out_ports[p])
 | 
			
		||||
#define GET_PORT(this,d,p)           (d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,p) : GET_OUT_PORT(this,p))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -215,7 +216,7 @@ static int impl_node_add_listener(void *object,
 | 
			
		|||
	emit_node_info(this, true);
 | 
			
		||||
	emit_port_info(this, GET_OUT_PORT(this, 0), true);
 | 
			
		||||
	for (i = 0; i < this->last_port; i++) {
 | 
			
		||||
		if (this->in_ports[i].valid)
 | 
			
		||||
		if (PORT_VALID(this->in_ports[i]))
 | 
			
		||||
			emit_port_info(this, GET_IN_PORT(this, i), true);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -242,6 +243,13 @@ static int impl_node_add_port(void *object, enum spa_direction direction, uint32
 | 
			
		|||
	spa_return_val_if_fail(CHECK_FREE_IN_PORT(this, direction, port_id), -EINVAL);
 | 
			
		||||
 | 
			
		||||
	port = GET_IN_PORT (this, port_id);
 | 
			
		||||
	if (port == NULL) {
 | 
			
		||||
		port = calloc(1, sizeof(struct port));
 | 
			
		||||
		if (port == NULL)
 | 
			
		||||
			return -errno;
 | 
			
		||||
		this->in_ports[port_id] = port;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	port->direction = direction;
 | 
			
		||||
	port->id = port_id;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -298,7 +306,7 @@ impl_node_remove_port(void *object, enum spa_direction direction, uint32_t port_
 | 
			
		|||
		int i;
 | 
			
		||||
 | 
			
		||||
		for (i = this->last_port - 1; i >= 0; i--)
 | 
			
		||||
			if (GET_IN_PORT (this, i)->valid)
 | 
			
		||||
			if (PORT_VALID(GET_IN_PORT(this, i)))
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
		this->last_port = i + 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -695,13 +703,13 @@ static int impl_node_process(void *object)
 | 
			
		|||
		struct spa_io_buffers *inio = NULL;
 | 
			
		||||
		struct buffer *inb;
 | 
			
		||||
 | 
			
		||||
		if (SPA_UNLIKELY(!inport->valid ||
 | 
			
		||||
		if (SPA_UNLIKELY(!PORT_VALID(inport) ||
 | 
			
		||||
		    (inio = inport->io) == NULL ||
 | 
			
		||||
		    inio->buffer_id >= inport->n_buffers ||
 | 
			
		||||
		    inio->status != SPA_STATUS_HAVE_DATA)) {
 | 
			
		||||
			spa_log_trace_fp(this->log, "%p: skip input idx:%d valid:%d "
 | 
			
		||||
					"io:%p status:%d buf_id:%d n_buffers:%d", this,
 | 
			
		||||
				i, inport->valid, inio,
 | 
			
		||||
				i, PORT_VALID(inport), inio,
 | 
			
		||||
				inio ? inio->status : -1,
 | 
			
		||||
				inio ? inio->buffer_id : SPA_ID_INVALID,
 | 
			
		||||
				inport->n_buffers);
 | 
			
		||||
| 
						 | 
				
			
			@ -785,6 +793,15 @@ static int impl_get_interface(struct spa_handle *handle, const char *type, void
 | 
			
		|||
 | 
			
		||||
static int impl_clear(struct spa_handle *handle)
 | 
			
		||||
{
 | 
			
		||||
	struct impl *this;
 | 
			
		||||
	uint32_t i;
 | 
			
		||||
 | 
			
		||||
	spa_return_val_if_fail(handle != NULL, -EINVAL);
 | 
			
		||||
 | 
			
		||||
	this = (struct impl *) handle;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < MAX_PORTS; i++)
 | 
			
		||||
		free(this->in_ports[i]);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -86,7 +86,7 @@ struct impl {
 | 
			
		|||
 | 
			
		||||
	uint32_t port_count;
 | 
			
		||||
	uint32_t last_port;
 | 
			
		||||
	struct port in_ports[MAX_PORTS];
 | 
			
		||||
	struct port *in_ports[MAX_PORTS];
 | 
			
		||||
	struct port out_ports[1];
 | 
			
		||||
 | 
			
		||||
	int n_formats;
 | 
			
		||||
| 
						 | 
				
			
			@ -95,11 +95,12 @@ struct impl {
 | 
			
		|||
	unsigned int started:1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define CHECK_FREE_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && !this->in_ports[(p)].valid)
 | 
			
		||||
#define CHECK_IN_PORT(this,d,p)      ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && this->in_ports[(p)].valid)
 | 
			
		||||
#define PORT_VALID(p)                ((p) != NULL && (p)->valid)
 | 
			
		||||
#define CHECK_FREE_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && !PORT_VALID(this->in_ports[(p)]))
 | 
			
		||||
#define CHECK_IN_PORT(this,d,p)      ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && PORT_VALID(this->in_ports[(p)]))
 | 
			
		||||
#define CHECK_OUT_PORT(this,d,p)     ((d) == SPA_DIRECTION_OUTPUT && (p) == 0)
 | 
			
		||||
#define CHECK_PORT(this,d,p)         (CHECK_OUT_PORT(this,d,p) || CHECK_IN_PORT (this,d,p))
 | 
			
		||||
#define GET_IN_PORT(this,p)          (&this->in_ports[p])
 | 
			
		||||
#define GET_IN_PORT(this,p)          (this->in_ports[p])
 | 
			
		||||
#define GET_OUT_PORT(this,p)         (&this->out_ports[p])
 | 
			
		||||
#define GET_PORT(this,d,p)           (d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,p) : GET_OUT_PORT(this,p))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -180,7 +181,7 @@ static int impl_node_add_listener(void *object,
 | 
			
		|||
	emit_node_info(this, true);
 | 
			
		||||
	emit_port_info(this, GET_OUT_PORT(this, 0), true);
 | 
			
		||||
	for (i = 0; i < this->last_port; i++) {
 | 
			
		||||
		if (this->in_ports[i].valid)
 | 
			
		||||
		if (PORT_VALID(this->in_ports[i]))
 | 
			
		||||
			emit_port_info(this, GET_IN_PORT(this, i), true);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -207,6 +208,13 @@ static int impl_node_add_port(void *object, enum spa_direction direction, uint32
 | 
			
		|||
	spa_return_val_if_fail(CHECK_FREE_IN_PORT(this, direction, port_id), -EINVAL);
 | 
			
		||||
 | 
			
		||||
	port = GET_IN_PORT (this, port_id);
 | 
			
		||||
	if (port == NULL) {
 | 
			
		||||
		port = calloc(1, sizeof(struct port));
 | 
			
		||||
		if (port == NULL)
 | 
			
		||||
			return -errno;
 | 
			
		||||
		this->in_ports[port_id] = port;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	port->direction = direction;
 | 
			
		||||
	port->id = port_id;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -720,6 +728,15 @@ static int impl_get_interface(struct spa_handle *handle, const char *type, void
 | 
			
		|||
 | 
			
		||||
static int impl_clear(struct spa_handle *handle)
 | 
			
		||||
{
 | 
			
		||||
	struct impl *this;
 | 
			
		||||
	uint32_t i;
 | 
			
		||||
 | 
			
		||||
	spa_return_val_if_fail(handle != NULL, -EINVAL);
 | 
			
		||||
 | 
			
		||||
	this = (struct impl *) handle;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < MAX_PORTS; i++)
 | 
			
		||||
		free(this->in_ports[i]);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue