mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
link: update graph on activate/deactivate
Add the mixer ports to the graph when activating and remove in deactivate.
This commit is contained in:
parent
05b3c666d9
commit
f2edfacf09
1 changed files with 12 additions and 46 deletions
|
|
@ -786,6 +786,8 @@ do_activate_link(struct spa_loop *loop,
|
||||||
|
|
||||||
pw_log_trace("link %p: activate", this);
|
pw_log_trace("link %p: activate", this);
|
||||||
|
|
||||||
|
spa_graph_port_add(&this->output->rt.mix_node, &this->rt.mix[SPA_DIRECTION_OUTPUT].port);
|
||||||
|
spa_graph_port_add(&this->input->rt.mix_node, &this->rt.mix[SPA_DIRECTION_INPUT].port);
|
||||||
spa_graph_port_link(&this->rt.mix[SPA_DIRECTION_OUTPUT].port,
|
spa_graph_port_link(&this->rt.mix[SPA_DIRECTION_OUTPUT].port,
|
||||||
&this->rt.mix[SPA_DIRECTION_INPUT].port);
|
&this->rt.mix[SPA_DIRECTION_INPUT].port);
|
||||||
|
|
||||||
|
|
@ -931,63 +933,43 @@ static void clear_port_buffers(struct pw_link *link, struct pw_port *port)
|
||||||
pw_log_warn("link %p: port %p clear error %s", link, port, spa_strerror(res));
|
pw_log_warn("link %p: port %p clear error %s", link, port, spa_strerror(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
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_unlink(&this->rt.mix[SPA_DIRECTION_INPUT].port);
|
|
||||||
spa_graph_port_remove(&this->rt.mix[SPA_DIRECTION_INPUT].port);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void input_remove(struct pw_link *this, struct pw_port *port)
|
static void input_remove(struct pw_link *this, struct pw_port *port)
|
||||||
{
|
{
|
||||||
struct impl *impl = (struct impl *) this;
|
struct impl *impl = (struct impl *) this;
|
||||||
|
struct pw_port_mix *mix = &this->rt.mix[SPA_DIRECTION_INPUT];
|
||||||
|
struct spa_graph_port *p = &mix->port;
|
||||||
|
|
||||||
pw_log_debug("link %p: remove input port %p", this, port);
|
pw_log_debug("link %p: remove input port %p", this, port);
|
||||||
spa_hook_remove(&impl->input_port_listener);
|
spa_hook_remove(&impl->input_port_listener);
|
||||||
spa_hook_remove(&impl->input_node_listener);
|
spa_hook_remove(&impl->input_node_listener);
|
||||||
|
|
||||||
pw_loop_invoke(port->node->data_loop,
|
|
||||||
do_remove_input, 1, NULL, 0, true, this);
|
|
||||||
|
|
||||||
spa_list_remove(&this->input_link);
|
spa_list_remove(&this->input_link);
|
||||||
spa_hook_list_call(&this->input->listener_list, struct pw_port_events, link_removed, this);
|
spa_hook_list_call(&this->input->listener_list, struct pw_port_events, link_removed, this);
|
||||||
|
|
||||||
clear_port_buffers(this, port);
|
clear_port_buffers(this, port);
|
||||||
|
|
||||||
pw_port_release_mix(port, &this->rt.mix[SPA_DIRECTION_INPUT]);
|
port_set_io(this, this->input, NULL, 0, p);
|
||||||
|
pw_port_release_mix(port, mix);
|
||||||
this->input = NULL;
|
this->input = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
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_unlink(&this->rt.mix[SPA_DIRECTION_OUTPUT].port);
|
|
||||||
spa_graph_port_remove(&this->rt.mix[SPA_DIRECTION_OUTPUT].port);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void output_remove(struct pw_link *this, struct pw_port *port)
|
static void output_remove(struct pw_link *this, struct pw_port *port)
|
||||||
{
|
{
|
||||||
struct impl *impl = (struct impl *) this;
|
struct impl *impl = (struct impl *) this;
|
||||||
|
struct pw_port_mix *mix = &this->rt.mix[SPA_DIRECTION_OUTPUT];
|
||||||
|
struct spa_graph_port *p = &mix->port;
|
||||||
|
|
||||||
pw_log_debug("link %p: remove output port %p", this, port);
|
pw_log_debug("link %p: remove output port %p", this, port);
|
||||||
spa_hook_remove(&impl->output_port_listener);
|
spa_hook_remove(&impl->output_port_listener);
|
||||||
spa_hook_remove(&impl->output_node_listener);
|
spa_hook_remove(&impl->output_node_listener);
|
||||||
|
|
||||||
pw_loop_invoke(port->node->data_loop,
|
|
||||||
do_remove_output, 1, NULL, 0, true, this);
|
|
||||||
|
|
||||||
spa_list_remove(&this->output_link);
|
spa_list_remove(&this->output_link);
|
||||||
spa_hook_list_call(&this->output->listener_list, struct pw_port_events, link_removed, this);
|
spa_hook_list_call(&this->output->listener_list, struct pw_port_events, link_removed, this);
|
||||||
|
|
||||||
clear_port_buffers(this, port);
|
clear_port_buffers(this, port);
|
||||||
|
|
||||||
pw_port_release_mix(port, &this->rt.mix[SPA_DIRECTION_OUTPUT]);
|
port_set_io(this, this->output, NULL, 0, p);
|
||||||
|
pw_port_release_mix(port, mix);
|
||||||
this->output = NULL;
|
this->output = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1046,6 +1028,8 @@ do_deactivate_link(struct spa_loop *loop,
|
||||||
this->io->status);
|
this->io->status);
|
||||||
|
|
||||||
spa_graph_port_unlink(&this->rt.mix[SPA_DIRECTION_OUTPUT].port);
|
spa_graph_port_unlink(&this->rt.mix[SPA_DIRECTION_OUTPUT].port);
|
||||||
|
spa_graph_port_remove(&this->rt.mix[SPA_DIRECTION_OUTPUT].port);
|
||||||
|
spa_graph_port_remove(&this->rt.mix[SPA_DIRECTION_INPUT].port);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1149,18 +1133,6 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
do_add_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;
|
|
||||||
struct pw_port *port = ((struct pw_port **) data)[0];
|
|
||||||
|
|
||||||
spa_graph_port_add(&port->rt.mix_node, &this->rt.mix[port->direction].port);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct pw_port_events input_port_events = {
|
static const struct pw_port_events input_port_events = {
|
||||||
PW_VERSION_PORT_EVENTS,
|
PW_VERSION_PORT_EVENTS,
|
||||||
.destroy = input_port_destroy,
|
.destroy = input_port_destroy,
|
||||||
|
|
@ -1263,12 +1235,6 @@ struct pw_link *pw_link_new(struct pw_core *core,
|
||||||
output_node, output->port_id, this->rt.mix[SPA_DIRECTION_OUTPUT].port.port_id,
|
output_node, output->port_id, this->rt.mix[SPA_DIRECTION_OUTPUT].port.port_id,
|
||||||
input_node, input->port_id, this->rt.mix[SPA_DIRECTION_INPUT].port.port_id);
|
input_node, input->port_id, this->rt.mix[SPA_DIRECTION_INPUT].port.port_id);
|
||||||
|
|
||||||
/* nodes can be in different data loops so we do this twice */
|
|
||||||
pw_loop_invoke(output_node->data_loop, do_add_link,
|
|
||||||
SPA_ID_INVALID, &output, sizeof(struct pw_port *), false, this);
|
|
||||||
pw_loop_invoke(input_node->data_loop, do_add_link,
|
|
||||||
SPA_ID_INVALID, &input, sizeof(struct pw_port *), true, this);
|
|
||||||
|
|
||||||
spa_hook_list_call(&output->listener_list, struct pw_port_events, link_added, this);
|
spa_hook_list_call(&output->listener_list, struct pw_port_events, link_added, this);
|
||||||
spa_hook_list_call(&input->listener_list, struct pw_port_events, link_added, this);
|
spa_hook_list_call(&input->listener_list, struct pw_port_events, link_added, this);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue