mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	port: delegate initialization of mix ports to port
This commit is contained in:
		
							parent
							
								
									319098b4c8
								
							
						
					
					
						commit
						2ea9addcf2
					
				
					 4 changed files with 163 additions and 95 deletions
				
			
		| 
						 | 
				
			
			@ -137,6 +137,7 @@ struct impl {
 | 
			
		|||
 | 
			
		||||
	struct pw_client_node_transport *transport;
 | 
			
		||||
 | 
			
		||||
	struct pw_map io_map;
 | 
			
		||||
	struct pw_memblock *io_areas;
 | 
			
		||||
	uint32_t io_memid;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -600,7 +601,12 @@ static int do_port_set_io(struct impl *impl,
 | 
			
		|||
	struct mem *m;
 | 
			
		||||
	uint32_t memid, mem_offset, mem_size;
 | 
			
		||||
 | 
			
		||||
	pw_log_debug("client-node %p: port %d.%d set io %p %zd", impl, port_id, mix_id, data, size);
 | 
			
		||||
	pw_log_debug("client-node %p: %s port %d.%d set io %p %zd", impl,
 | 
			
		||||
			direction == SPA_DIRECTION_INPUT ? "input" : "output",
 | 
			
		||||
			port_id, mix_id, data, size);
 | 
			
		||||
 | 
			
		||||
	if (!CHECK_PORT(this, direction, port_id))
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	if (this->resource == NULL)
 | 
			
		||||
		return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -643,9 +649,6 @@ impl_node_port_set_io(struct spa_node *node,
 | 
			
		|||
 | 
			
		||||
	this = SPA_CONTAINER_OF(node, struct node, node);
 | 
			
		||||
 | 
			
		||||
	if (!CHECK_PORT(this, direction, port_id))
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	return do_port_set_io(this->impl, direction, port_id, 0, id, data, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1215,6 +1218,7 @@ static void node_initialized(void *data)
 | 
			
		|||
 | 
			
		||||
	m = ensure_mem(impl, impl->io_areas->fd, t->data.MemFd, impl->io_areas->flags);
 | 
			
		||||
	impl->io_memid = m->id;
 | 
			
		||||
	pw_log_debug("client-node %p: io areas %p", node, impl->io_areas->ptr);
 | 
			
		||||
 | 
			
		||||
	pw_client_node_resource_transport(this->resource,
 | 
			
		||||
					  pw_global_get_id(pw_node_get_global(node)),
 | 
			
		||||
| 
						 | 
				
			
			@ -1246,16 +1250,35 @@ static void node_free(void *data)
 | 
			
		|||
	free(impl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *port_get_io(void *data, uint32_t id, size_t size)
 | 
			
		||||
static int port_init_mix(void *data, struct pw_port_mix *mix)
 | 
			
		||||
{
 | 
			
		||||
	struct impl *impl = data;
 | 
			
		||||
	uint32_t ioid;
 | 
			
		||||
 | 
			
		||||
	return impl->io_areas->ptr;
 | 
			
		||||
	ioid = pw_map_insert_new(&impl->io_map, NULL);
 | 
			
		||||
 | 
			
		||||
	mix->port.io = SPA_MEMBER(impl->io_areas->ptr, ioid * sizeof(struct spa_io_buffers), void);
 | 
			
		||||
 | 
			
		||||
	pw_log_debug("client-node %p: init mix io %d %p", impl, ioid, mix->port.io);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int port_release_mix(void *data, struct pw_port_mix *mix)
 | 
			
		||||
{
 | 
			
		||||
	struct impl *impl = data;
 | 
			
		||||
	uint32_t id;
 | 
			
		||||
 | 
			
		||||
	id = (mix->port.io - (struct spa_io_buffers*)impl->io_areas->ptr);
 | 
			
		||||
 | 
			
		||||
	pw_map_remove(&impl->io_map, id);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct pw_port_implementation port_impl = {
 | 
			
		||||
	PW_VERSION_PORT_IMPLEMENTATION,
 | 
			
		||||
	.get_io = port_get_io,
 | 
			
		||||
	.init_mix = port_init_mix,
 | 
			
		||||
	.release_mix = port_release_mix,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int mix_port_set_io(struct spa_node *node,
 | 
			
		||||
| 
						 | 
				
			
			@ -1264,16 +1287,12 @@ static int mix_port_set_io(struct spa_node *node,
 | 
			
		|||
{
 | 
			
		||||
	struct pw_port *p = SPA_CONTAINER_OF(node, struct pw_port, mix_node);
 | 
			
		||||
	struct impl *impl = p->owner_data;
 | 
			
		||||
	struct node *this = &impl->node;
 | 
			
		||||
 | 
			
		||||
	pw_log_debug("client-node %p: mix port %d set io %p, %zd", impl, port_id, data, size);
 | 
			
		||||
 | 
			
		||||
	p->rt.port.io = data;
 | 
			
		||||
	p->rt.mix_port.io = data;
 | 
			
		||||
 | 
			
		||||
	if (!CHECK_PORT(this, direction, port_id))
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	return do_port_set_io(impl,
 | 
			
		||||
			      direction, p->port_id, port_id,
 | 
			
		||||
			      id, data, size);
 | 
			
		||||
| 
						 | 
				
			
			@ -1355,6 +1374,7 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource,
 | 
			
		|||
	node_init(&impl->node, NULL, support, n_support);
 | 
			
		||||
	impl->node.impl = impl;
 | 
			
		||||
 | 
			
		||||
	pw_map_init(&impl->io_map, 64, 64);
 | 
			
		||||
	pw_array_init(&impl->mems, 64);
 | 
			
		||||
 | 
			
		||||
	if ((name = pw_properties_get(properties, "node.name")) == NULL)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,6 +40,7 @@ struct impl {
 | 
			
		|||
	struct pw_link this;
 | 
			
		||||
 | 
			
		||||
	bool active;
 | 
			
		||||
	bool have_io;
 | 
			
		||||
 | 
			
		||||
	struct pw_work_queue *work;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -480,14 +481,17 @@ param_filter(struct pw_link *this,
 | 
			
		|||
	return num;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void port_set_io(struct pw_link *this, struct pw_port *port, void *data, size_t size,
 | 
			
		||||
static int port_set_io(struct pw_link *this, struct pw_port *port, void *data, size_t size,
 | 
			
		||||
		struct spa_graph_port *p)
 | 
			
		||||
{
 | 
			
		||||
	struct pw_type *t = &this->core->type;
 | 
			
		||||
	int res;
 | 
			
		||||
	int res = 0;
 | 
			
		||||
 | 
			
		||||
	p->io = data;
 | 
			
		||||
	pw_log_debug("link %p: port %p %d.%d set io: %p", this, port, port->port_id, p->port_id, data);
 | 
			
		||||
	pw_log_debug("link %p: %s port %p %d.%d set io: %p", this,
 | 
			
		||||
			pw_direction_as_string(port->direction),
 | 
			
		||||
			port, port->port_id, p->port_id, data);
 | 
			
		||||
 | 
			
		||||
	if (port->mix_node.port_set_io) {
 | 
			
		||||
		if ((res = spa_node_port_set_io(&port->mix_node,
 | 
			
		||||
				     p->direction,
 | 
			
		||||
| 
						 | 
				
			
			@ -496,27 +500,33 @@ static void port_set_io(struct pw_link *this, struct pw_port *port, void *data,
 | 
			
		|||
				     data, size)) < 0)
 | 
			
		||||
			pw_log_warn("port %p: can't set io: %s", port, spa_strerror(res));
 | 
			
		||||
	}
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int select_io(struct pw_link *this)
 | 
			
		||||
{
 | 
			
		||||
	struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
 | 
			
		||||
	struct spa_io_buffers *io;
 | 
			
		||||
	struct pw_type *t = &this->core->type;
 | 
			
		||||
	int res;
 | 
			
		||||
 | 
			
		||||
	if (this->output->implementation && this->output->implementation->get_io)
 | 
			
		||||
		io = this->output->implementation->get_io(this->output->implementation_data,
 | 
			
		||||
				t->io.Buffers, sizeof(struct spa_io_buffers));
 | 
			
		||||
	else if (this->input->implementation && this->input->implementation->get_io)
 | 
			
		||||
		io = this->input->implementation->get_io(this->input->implementation_data,
 | 
			
		||||
				t->io.Buffers, sizeof(struct spa_io_buffers));
 | 
			
		||||
	else
 | 
			
		||||
		io = &this->io;
 | 
			
		||||
	if (impl->have_io)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	io = this->rt.in_port.port.io;
 | 
			
		||||
	if (io == NULL)
 | 
			
		||||
		io = this->rt.out_port.port.io;
 | 
			
		||||
	if (io == NULL)
 | 
			
		||||
		return -EIO;
 | 
			
		||||
 | 
			
		||||
	port_set_io(this, this->input, io, sizeof(struct spa_io_buffers), &this->rt.in_port);
 | 
			
		||||
	port_set_io(this, this->output, io, sizeof(struct spa_io_buffers), &this->rt.out_port);
 | 
			
		||||
	if ((res = port_set_io(this, this->input, io,
 | 
			
		||||
			sizeof(struct spa_io_buffers), &this->rt.in_port.port)) < 0)
 | 
			
		||||
		return res;
 | 
			
		||||
 | 
			
		||||
	if ((res = port_set_io(this, this->output, io,
 | 
			
		||||
			sizeof(struct spa_io_buffers), &this->rt.out_port.port)) < 0)
 | 
			
		||||
		return res;
 | 
			
		||||
 | 
			
		||||
	impl->have_io = true;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -714,7 +724,8 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s
 | 
			
		|||
		if ((res = pw_port_use_buffers(output,
 | 
			
		||||
					       allocation.buffers,
 | 
			
		||||
					       allocation.n_buffers)) < 0) {
 | 
			
		||||
			asprintf(&error, "error use output buffers: %d", res);
 | 
			
		||||
			asprintf(&error, "link %p: error use output buffers: %s", this,
 | 
			
		||||
					spa_strerror(res));
 | 
			
		||||
			goto error;
 | 
			
		||||
		}
 | 
			
		||||
		if (SPA_RESULT_IS_ASYNC(res))
 | 
			
		||||
| 
						 | 
				
			
			@ -728,7 +739,8 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s
 | 
			
		|||
		if ((res = pw_port_use_buffers(input,
 | 
			
		||||
					       allocation.buffers,
 | 
			
		||||
					       allocation.n_buffers)) < 0) {
 | 
			
		||||
			asprintf(&error, "error use input buffers: %d", res);
 | 
			
		||||
			asprintf(&error, "link %p: error use input buffers: %s", this,
 | 
			
		||||
					spa_strerror(res));
 | 
			
		||||
			goto error;
 | 
			
		||||
		}
 | 
			
		||||
		if (SPA_RESULT_IS_ASYNC(res))
 | 
			
		||||
| 
						 | 
				
			
			@ -739,8 +751,10 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s
 | 
			
		|||
		goto error;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	select_io(this);
 | 
			
		||||
 | 
			
		||||
	if ((res = select_io(this)) < 0) {
 | 
			
		||||
		asprintf(&error, "link %p: error can set io: %s", this, spa_strerror(res));
 | 
			
		||||
		goto error;
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
      error:
 | 
			
		||||
| 
						 | 
				
			
			@ -755,8 +769,8 @@ do_activate_link(struct spa_loop *loop,
 | 
			
		|||
		 bool async, uint32_t seq, const void *data, size_t size, void *user_data)
 | 
			
		||||
{
 | 
			
		||||
        struct pw_link *this = user_data;
 | 
			
		||||
	SPA_FLAG_UNSET(this->rt.out_port.flags, SPA_GRAPH_PORT_FLAG_DISABLED);
 | 
			
		||||
	SPA_FLAG_UNSET(this->rt.in_port.flags, SPA_GRAPH_PORT_FLAG_DISABLED);
 | 
			
		||||
	SPA_FLAG_UNSET(this->rt.out_port.port.flags, SPA_GRAPH_PORT_FLAG_DISABLED);
 | 
			
		||||
	SPA_FLAG_UNSET(this->rt.in_port.port.flags, SPA_GRAPH_PORT_FLAG_DISABLED);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -892,7 +906,7 @@ do_remove_input(struct spa_loop *loop,
 | 
			
		|||
	        bool async, uint32_t seq, const void *data, size_t size, void *user_data)
 | 
			
		||||
{
 | 
			
		||||
	struct pw_link *this = user_data;
 | 
			
		||||
	spa_graph_port_remove(&this->rt.in_port);
 | 
			
		||||
	spa_graph_port_remove(&this->rt.in_port.port);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -907,7 +921,7 @@ static void input_remove(struct pw_link *this, struct pw_port *port)
 | 
			
		|||
	pw_loop_invoke(port->node->data_loop,
 | 
			
		||||
		       do_remove_input, 1, NULL, 0, true, this);
 | 
			
		||||
 | 
			
		||||
	pw_map_remove(&port->mix_port_map, this->rt.in_port.port_id);
 | 
			
		||||
	pw_port_release_mix(port, &this->rt.in_port);
 | 
			
		||||
 | 
			
		||||
	spa_list_remove(&this->input_link);
 | 
			
		||||
	spa_hook_list_call(&this->input->listener_list, struct pw_port_events, link_removed, this);
 | 
			
		||||
| 
						 | 
				
			
			@ -921,7 +935,7 @@ do_remove_output(struct spa_loop *loop,
 | 
			
		|||
	         bool async, uint32_t seq, const void *data, size_t size, void *user_data)
 | 
			
		||||
{
 | 
			
		||||
	struct pw_link *this = user_data;
 | 
			
		||||
	spa_graph_port_remove(&this->rt.out_port);
 | 
			
		||||
	spa_graph_port_remove(&this->rt.out_port.port);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -936,7 +950,7 @@ static void output_remove(struct pw_link *this, struct pw_port *port)
 | 
			
		|||
	pw_loop_invoke(port->node->data_loop,
 | 
			
		||||
		       do_remove_output, 1, NULL, 0, true, this);
 | 
			
		||||
 | 
			
		||||
	pw_map_remove(&port->mix_port_map, this->rt.out_port.port_id);
 | 
			
		||||
	pw_port_release_mix(port, &this->rt.out_port);
 | 
			
		||||
 | 
			
		||||
	spa_list_remove(&this->output_link);
 | 
			
		||||
	spa_hook_list_call(&this->output->listener_list, struct pw_port_events, link_removed, this);
 | 
			
		||||
| 
						 | 
				
			
			@ -990,8 +1004,8 @@ do_deactivate_link(struct spa_loop *loop,
 | 
			
		|||
{
 | 
			
		||||
        struct pw_link *this = user_data;
 | 
			
		||||
	pw_log_trace("link %p: disable %p and %p", this, &this->rt.out_port, &this->rt.in_port);
 | 
			
		||||
	SPA_FLAG_SET(this->rt.out_port.flags, SPA_GRAPH_PORT_FLAG_DISABLED);
 | 
			
		||||
	SPA_FLAG_SET(this->rt.in_port.flags, SPA_GRAPH_PORT_FLAG_DISABLED);
 | 
			
		||||
	SPA_FLAG_SET(this->rt.out_port.port.flags, SPA_GRAPH_PORT_FLAG_DISABLED);
 | 
			
		||||
	SPA_FLAG_SET(this->rt.in_port.port.flags, SPA_GRAPH_PORT_FLAG_DISABLED);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1093,9 +1107,9 @@ do_add_link(struct spa_loop *loop,
 | 
			
		|||
        struct pw_port *port = ((struct pw_port **) data)[0];
 | 
			
		||||
 | 
			
		||||
        if (port->direction == PW_DIRECTION_OUTPUT) {
 | 
			
		||||
                spa_graph_port_add(&port->rt.mix_node, &this->rt.out_port);
 | 
			
		||||
                spa_graph_port_add(&port->rt.mix_node, &this->rt.out_port.port);
 | 
			
		||||
        } else {
 | 
			
		||||
                spa_graph_port_add(&port->rt.mix_node, &this->rt.in_port);
 | 
			
		||||
                spa_graph_port_add(&port->rt.mix_node, &this->rt.in_port.port);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -1197,27 +1211,14 @@ struct pw_link *pw_link_new(struct pw_core *core,
 | 
			
		|||
 | 
			
		||||
	this->io = SPA_IO_BUFFERS_INIT;
 | 
			
		||||
 | 
			
		||||
	this->rt.out_port.port_id = pw_map_insert_new(&output->mix_port_map, NULL);
 | 
			
		||||
	this->rt.in_port.port_id = pw_map_insert_new(&input->mix_port_map, NULL);
 | 
			
		||||
	pw_port_init_mix(output, &this->rt.out_port);
 | 
			
		||||
	pw_port_init_mix(input, &this->rt.in_port);
 | 
			
		||||
 | 
			
		||||
	pw_log_debug("link %p: constructed %p:%d.%d -> %p:%d.%d", impl,
 | 
			
		||||
		     output_node, output->port_id, this->rt.out_port.port_id,
 | 
			
		||||
		     input_node, input->port_id, this->rt.in_port.port_id);
 | 
			
		||||
		     output_node, output->port_id, this->rt.out_port.port.port_id,
 | 
			
		||||
		     input_node, input->port_id, this->rt.in_port.port.port_id);
 | 
			
		||||
 | 
			
		||||
	spa_graph_port_init(&this->rt.out_port,
 | 
			
		||||
			    PW_DIRECTION_OUTPUT,
 | 
			
		||||
			    this->rt.out_port.port_id,
 | 
			
		||||
			    SPA_GRAPH_PORT_FLAG_DISABLED,
 | 
			
		||||
			    &this->io);
 | 
			
		||||
	spa_graph_port_init(&this->rt.in_port,
 | 
			
		||||
			    PW_DIRECTION_INPUT,
 | 
			
		||||
			    this->rt.in_port.port_id,
 | 
			
		||||
			    SPA_GRAPH_PORT_FLAG_DISABLED,
 | 
			
		||||
			    &this->io);
 | 
			
		||||
	spa_graph_port_link(&this->rt.out_port, &this->rt.in_port);
 | 
			
		||||
 | 
			
		||||
	this->rt.in_port.scheduler_data = this;
 | 
			
		||||
	this->rt.out_port.scheduler_data = this;
 | 
			
		||||
	spa_graph_port_link(&this->rt.out_port.port, &this->rt.in_port.port);
 | 
			
		||||
 | 
			
		||||
	/* nodes can be in different data loops so we do this twice */
 | 
			
		||||
	pw_loop_invoke(output_node->data_loop, do_add_link,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -160,6 +160,45 @@ static const struct spa_node schedule_mix_node = {
 | 
			
		|||
	.port_reuse_buffer = schedule_mix_reuse_buffer,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int pw_port_init_mix(struct pw_port *port, struct pw_port_mix *mix)
 | 
			
		||||
{
 | 
			
		||||
	uint32_t id;
 | 
			
		||||
	int res = 0;
 | 
			
		||||
	const struct pw_port_implementation *pi = port->implementation;
 | 
			
		||||
 | 
			
		||||
	id = pw_map_insert_new(&port->mix_port_map, NULL);
 | 
			
		||||
 | 
			
		||||
	spa_graph_port_init(&mix->port,
 | 
			
		||||
			    port->direction, id,
 | 
			
		||||
			    SPA_GRAPH_PORT_FLAG_DISABLED,
 | 
			
		||||
			    NULL);
 | 
			
		||||
 | 
			
		||||
	mix->port.scheduler_data = port;
 | 
			
		||||
 | 
			
		||||
	if (pi && pi->init_mix)
 | 
			
		||||
		res = pi->init_mix(port->implementation_data, mix);
 | 
			
		||||
 | 
			
		||||
	pw_log_debug("port %p: init mix %d.%d io %p", port,
 | 
			
		||||
			port->port_id, mix->port.port_id, mix->port.io);
 | 
			
		||||
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
int pw_port_release_mix(struct pw_port *port, struct pw_port_mix *mix)
 | 
			
		||||
{
 | 
			
		||||
	int res = 0;
 | 
			
		||||
	const struct pw_port_implementation *pi = port->implementation;
 | 
			
		||||
 | 
			
		||||
	pw_map_remove(&port->mix_port_map, mix->port.port_id);
 | 
			
		||||
 | 
			
		||||
	if (pi && pi->release_mix)
 | 
			
		||||
		res = pi->release_mix(port->implementation_data, mix);
 | 
			
		||||
 | 
			
		||||
	pw_log_debug("port %p: release mix %d.%d", port,
 | 
			
		||||
			port->port_id, mix->port.port_id);
 | 
			
		||||
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct pw_port *pw_port_new(enum pw_direction direction,
 | 
			
		||||
			    uint32_t port_id,
 | 
			
		||||
			    struct pw_properties *properties,
 | 
			
		||||
| 
						 | 
				
			
			@ -185,7 +224,7 @@ struct pw_port *pw_port_new(enum pw_direction direction,
 | 
			
		|||
	this->port_id = port_id;
 | 
			
		||||
	this->properties = properties;
 | 
			
		||||
	this->state = PW_PORT_STATE_INIT;
 | 
			
		||||
	this->io = SPA_IO_BUFFERS_INIT;
 | 
			
		||||
	this->rt.io = SPA_IO_BUFFERS_INIT;
 | 
			
		||||
 | 
			
		||||
        if (user_data_size > 0)
 | 
			
		||||
		this->user_data = SPA_MEMBER(impl, sizeof(struct impl), void);
 | 
			
		||||
| 
						 | 
				
			
			@ -204,7 +243,7 @@ struct pw_port *pw_port_new(enum pw_direction direction,
 | 
			
		|||
			    this->direction,
 | 
			
		||||
			    this->port_id,
 | 
			
		||||
			    0,
 | 
			
		||||
			    &this->io);
 | 
			
		||||
			    &this->rt.io);
 | 
			
		||||
	spa_graph_node_init(&this->rt.mix_node);
 | 
			
		||||
 | 
			
		||||
	this->mix_node = this->direction == PW_DIRECTION_INPUT ?
 | 
			
		||||
| 
						 | 
				
			
			@ -217,7 +256,7 @@ struct pw_port *pw_port_new(enum pw_direction direction,
 | 
			
		|||
			    pw_direction_reverse(this->direction),
 | 
			
		||||
			    0,
 | 
			
		||||
			    0,
 | 
			
		||||
			    &this->io);
 | 
			
		||||
			    &this->rt.io);
 | 
			
		||||
 | 
			
		||||
	this->rt.mix_port.scheduler_data = this;
 | 
			
		||||
	this->rt.port.scheduler_data = this;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -212,38 +212,6 @@ static inline void free_allocation(struct allocation *alloc)
 | 
			
		|||
	alloc->n_buffers = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct pw_link {
 | 
			
		||||
	struct pw_core *core;		/**< core object */
 | 
			
		||||
	struct spa_list link;		/**< link in core link_list */
 | 
			
		||||
	struct pw_global *global;	/**< global for this link */
 | 
			
		||||
	struct spa_hook global_listener;
 | 
			
		||||
	bool registered;
 | 
			
		||||
 | 
			
		||||
        struct pw_link_info info;		/**< introspectable link info */
 | 
			
		||||
	struct pw_properties *properties;	/**< extra link properties */
 | 
			
		||||
 | 
			
		||||
	enum pw_link_state state;	/**< link state */
 | 
			
		||||
	char *error;			/**< error message when state error */
 | 
			
		||||
 | 
			
		||||
	struct spa_list resource_list;	/**< list of bound resources */
 | 
			
		||||
 | 
			
		||||
	struct spa_io_buffers io;	/**< link io area */
 | 
			
		||||
 | 
			
		||||
	struct pw_port *output;		/**< output port */
 | 
			
		||||
	struct spa_list output_link;	/**< link in output port links */
 | 
			
		||||
	struct pw_port *input;		/**< input port */
 | 
			
		||||
	struct spa_list input_link;	/**< link in input port links */
 | 
			
		||||
 | 
			
		||||
	struct spa_hook_list listener_list;
 | 
			
		||||
 | 
			
		||||
	struct {
 | 
			
		||||
		struct spa_graph_port out_port;
 | 
			
		||||
		struct spa_graph_port in_port;
 | 
			
		||||
	} rt;
 | 
			
		||||
 | 
			
		||||
	void *user_data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct pw_module {
 | 
			
		||||
	struct pw_core *core;           /**< the core object */
 | 
			
		||||
	struct spa_list link;           /**< link in the core module_list */
 | 
			
		||||
| 
						 | 
				
			
			@ -300,11 +268,18 @@ struct pw_node {
 | 
			
		|||
        void *user_data;                /**< extra user data */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct pw_port_mix {
 | 
			
		||||
	struct spa_graph_port port;
 | 
			
		||||
	struct spa_buffer *buffers;
 | 
			
		||||
	uint32_t n_buffers;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct pw_port_implementation {
 | 
			
		||||
#define PW_VERSION_PORT_IMPLEMENTATION       0
 | 
			
		||||
	uint32_t version;
 | 
			
		||||
 | 
			
		||||
	void *(*get_io) (void *data, uint32_t id, size_t size);
 | 
			
		||||
	int (*init_mix) (void *data, struct pw_port_mix *mix);
 | 
			
		||||
	int (*release_mix) (void *data, struct pw_port_mix *mix);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct pw_port {
 | 
			
		||||
| 
						 | 
				
			
			@ -326,8 +301,6 @@ struct pw_port {
 | 
			
		|||
 | 
			
		||||
	enum pw_port_state state;	/**< state of the port */
 | 
			
		||||
 | 
			
		||||
	struct spa_io_buffers io;	/**< io area of the port */
 | 
			
		||||
 | 
			
		||||
	bool allocated;			/**< if buffers are allocated */
 | 
			
		||||
	struct allocation allocation;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -346,6 +319,7 @@ struct pw_port {
 | 
			
		|||
 | 
			
		||||
	struct {
 | 
			
		||||
		struct spa_graph *graph;
 | 
			
		||||
		struct spa_io_buffers io;	/**< io area of the port */
 | 
			
		||||
		struct spa_graph_port port;	/**< this graph port, linked to mix_port */
 | 
			
		||||
		struct spa_graph_port mix_port;	/**< port from the mixer */
 | 
			
		||||
		struct spa_graph_node mix_node;	/**< mixer node */
 | 
			
		||||
| 
						 | 
				
			
			@ -355,6 +329,37 @@ struct pw_port {
 | 
			
		|||
        void *user_data;                /**< extra user data */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct pw_link {
 | 
			
		||||
	struct pw_core *core;		/**< core object */
 | 
			
		||||
	struct spa_list link;		/**< link in core link_list */
 | 
			
		||||
	struct pw_global *global;	/**< global for this link */
 | 
			
		||||
	struct spa_hook global_listener;
 | 
			
		||||
	bool registered;
 | 
			
		||||
 | 
			
		||||
        struct pw_link_info info;		/**< introspectable link info */
 | 
			
		||||
	struct pw_properties *properties;	/**< extra link properties */
 | 
			
		||||
 | 
			
		||||
	enum pw_link_state state;	/**< link state */
 | 
			
		||||
	char *error;			/**< error message when state error */
 | 
			
		||||
 | 
			
		||||
	struct spa_list resource_list;	/**< list of bound resources */
 | 
			
		||||
 | 
			
		||||
	struct spa_io_buffers io;	/**< link io area if not provided by ports */
 | 
			
		||||
 | 
			
		||||
	struct pw_port *output;		/**< output port */
 | 
			
		||||
	struct spa_list output_link;	/**< link in output port links */
 | 
			
		||||
	struct pw_port *input;		/**< input port */
 | 
			
		||||
	struct spa_list input_link;	/**< link in input port links */
 | 
			
		||||
 | 
			
		||||
	struct spa_hook_list listener_list;
 | 
			
		||||
 | 
			
		||||
	struct {
 | 
			
		||||
		struct pw_port_mix out_port;
 | 
			
		||||
		struct pw_port_mix in_port;
 | 
			
		||||
	} rt;
 | 
			
		||||
 | 
			
		||||
	void *user_data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct pw_resource {
 | 
			
		||||
	struct pw_core *core;		/**< the core object */
 | 
			
		||||
| 
						 | 
				
			
			@ -520,6 +525,9 @@ void * pw_port_get_user_data(struct pw_port *port);
 | 
			
		|||
/** Add a port to a node \memberof pw_port */
 | 
			
		||||
int pw_port_add(struct pw_port *port, struct pw_node *node);
 | 
			
		||||
 | 
			
		||||
int pw_port_init_mix(struct pw_port *port, struct pw_port_mix *mix);
 | 
			
		||||
int pw_port_release_mix(struct pw_port *port, struct pw_port_mix *mix);
 | 
			
		||||
 | 
			
		||||
/** Unlink a port \memberof pw_port */
 | 
			
		||||
void pw_port_unlink(struct pw_port *port);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue