client-node: rework mix_info

Use the port_set_mix_info to add and remove mix info information to the
client.

Previously it was impossible to clean up mix_info.

With this change we can also simplify the jack peer port detection.
Because the mix info is always sent before the link appears we can
simply look up the info when the link appears.
This commit is contained in:
Wim Taymans 2023-06-20 20:09:29 +02:00
parent a6ebcc62db
commit 1ce94628ee
3 changed files with 90 additions and 67 deletions

View file

@ -1408,6 +1408,11 @@ static int port_init_mix(void *data, struct pw_impl_port_mix *mix)
m->peer_id = mix->peer_id;
if (impl->resource && impl->resource->version >= 4)
pw_client_node_resource_port_set_mix_info(impl->resource,
mix->port.direction, mix->p->port_id,
mix->port.port_id, mix->peer_id, NULL);
pw_log_debug("%p: init mix id:%d io:%p base:%p", impl,
mix->id, mix->io, area->map->ptr);
@ -1430,6 +1435,11 @@ static int port_release_mix(void *data, struct pw_impl_port_mix *mix)
if ((m = find_mix(port, mix->port.port_id)) == NULL || !m->valid)
return -EINVAL;
if (impl->resource && impl->resource->version >= 4)
pw_client_node_resource_port_set_mix_info(impl->resource,
mix->port.direction, mix->p->port_id,
mix->port.port_id, SPA_ID_INVALID, NULL);
pw_map_remove(&impl->io_map, mix->id);
m->valid = false;
@ -1515,13 +1525,7 @@ static int impl_mix_port_set_io(void *object,
mix->io = data;
else
mix->io = NULL;
if (mix->io != NULL && impl->resource && impl->resource->version >= 4)
pw_client_node_resource_port_set_mix_info(impl->resource,
direction, port->port_id,
mix->port.port_id, mix->peer_id, NULL);
}
return do_port_set_io(impl,
direction, port->port_id, mix->port.port_id,
id, data, size);

View file

@ -896,6 +896,47 @@ error_exit:
return res;
}
static void clear_mix(struct node_data *data, struct mix *mix)
{
pw_log_debug("port %p: mix clear %d.%d", mix->port, mix->port->port_id, mix->mix_id);
spa_node_port_set_io(mix->port->mix, mix->mix.port.direction,
mix->mix.port.port_id, SPA_IO_Buffers, NULL, 0);
spa_list_remove(&mix->link);
clear_buffers(data, mix);
pw_array_clear(&mix->buffers);
spa_list_append(&data->free_mix, &mix->link);
pw_impl_port_release_mix(mix->port, &mix->mix);
}
static int client_node_port_set_mix_info(void *_data,
enum spa_direction direction, uint32_t port_id,
uint32_t mix_id, uint32_t peer_id, const struct spa_dict *props)
{
struct node_data *data = _data;
struct mix *mix;
pw_log_debug("%p: %d:%d:%d peer:%d", data, direction, port_id, mix_id, peer_id);
mix = find_mix(data, direction, port_id, mix_id);
if (peer_id == SPA_ID_INVALID) {
if (mix == NULL)
return -EINVAL;
clear_mix(data, mix);
} else {
if (mix != NULL)
return -EEXIST;
mix = create_mix(data, direction, port_id, mix_id, peer_id);
if (mix == NULL)
return -errno;
}
return 0;
}
static const struct pw_client_node_events client_node_events = {
PW_VERSION_CLIENT_NODE_EVENTS,
.transport = client_node_transport,
@ -909,6 +950,7 @@ static const struct pw_client_node_events client_node_events = {
.port_use_buffers = client_node_port_use_buffers,
.port_set_io = client_node_port_set_io,
.set_activation = client_node_set_activation,
.port_set_mix_info = client_node_port_set_mix_info,
};
static void do_node_init(struct node_data *data)
@ -934,22 +976,6 @@ static void do_node_init(struct node_data *data)
}
}
static void clear_mix(struct node_data *data, struct mix *mix)
{
pw_log_debug("port %p: mix clear %d.%d", mix->port, mix->port->port_id, mix->mix_id);
spa_node_port_set_io(mix->port->mix, mix->mix.port.direction,
mix->mix.port.port_id, SPA_IO_Buffers, NULL, 0);
spa_list_remove(&mix->link);
clear_buffers(data, mix);
pw_array_clear(&mix->buffers);
spa_list_append(&data->free_mix, &mix->link);
pw_impl_port_release_mix(mix->port, &mix->mix);
}
static void clean_node(struct node_data *d)
{
struct mix *mix;