scheduler: prepare link before usage

A link might become unprepared because a node suspended. When we want
to make the nodes runnable, make sure the link is prepared again.
This commit is contained in:
Wim Taymans 2026-02-21 17:25:54 +01:00
parent 476220c18b
commit 846096d435
3 changed files with 22 additions and 17 deletions

View file

@ -204,27 +204,28 @@ static void check_runnable(struct pw_context *context, struct pw_impl_node *node
spa_list_for_each(p, &node->output_ports, link) {
spa_list_for_each(l, &p->links, output_link) {
n = l->input->node;
/* we can only check the peer when the link is ready and
* the peer is active */
if (!l->prepared || !n->active)
/* the peer needs to be active and we are linked to it
* with a non-passive link */
if (!n->active || p->passive)
continue;
if (!p->passive) {
make_runnable(context, node);
make_runnable(context, n);
}
/* explicitly prepare the link in case it was suspended */
pw_impl_link_prepare(l);
if (!l->prepared)
continue;
make_runnable(context, node);
make_runnable(context, n);
}
}
spa_list_for_each(p, &node->input_ports, link) {
spa_list_for_each(l, &p->links, input_link) {
n = l->output->node;
if (!l->prepared || !n->active)
if (!n->active || p->passive)
continue;
if (!p->passive) {
make_runnable(context, node);
make_runnable(context, n);
}
pw_impl_link_prepare(l);
if (!l->prepared)
continue;
make_runnable(context, node);
make_runnable(context, n);
}
}
}

View file

@ -969,7 +969,8 @@ static void output_remove(struct pw_impl_link *this)
this->output = NULL;
}
static int link_prepare(struct pw_impl_link *this)
SPA_EXPORT
int pw_impl_link_prepare(struct pw_impl_link *this)
{
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
@ -1088,7 +1089,7 @@ static void port_param_changed(struct pw_impl_link *this, uint32_t id,
pw_log_info("%p: format changed", this);
this->preparing = this->prepared = false;
link_update_state(this, PW_LINK_STATE_INIT, 0, NULL);
link_prepare(this);
pw_impl_link_prepare(this);
}
static void input_port_param_changed(void *data, uint32_t id)
@ -1708,7 +1709,7 @@ int pw_impl_link_register(struct pw_impl_link *link,
pw_global_add_listener(link->global, &link->global_listener, &global_events, link);
pw_global_register(link->global);
link_prepare(link);
pw_impl_link_prepare(link);
return 0;

View file

@ -1358,6 +1358,9 @@ int pw_impl_node_set_io(struct pw_impl_node *node, uint32_t id, void *data, size
int pw_impl_node_add_target(struct pw_impl_node *node, struct pw_node_target *t);
int pw_impl_node_remove_target(struct pw_impl_node *node, struct pw_node_target *t);
/** Prepare a link
* Starts the negotiation of formats and buffers on \a link */
int pw_impl_link_prepare(struct pw_impl_link *link);
/** starts streaming on a link */
int pw_impl_link_activate(struct pw_impl_link *link);