mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
impl-link: make async link when on e of the nodes is async
We simply cannot schedule async nodes properly if we don't have the async link. This change was done to make sure that driver sources don't end up with async buffers and cause a unneccesary 1 cycle delay in async clients. But we can fix this in a better way, like this: Increment the cycle counter after we copy the output port buffers. This ensures the async clients immediately pick up the new buffers (or the output buffers from the previous cycle). Also remove some old compatibility code that is no longer useful. Fixes #4138 See #4133
This commit is contained in:
parent
b3688b163d
commit
e56939ac0f
2 changed files with 94 additions and 104 deletions
|
|
@ -1321,8 +1321,7 @@ struct pw_impl_link *pw_context_create_link(struct pw_context *context,
|
|||
if (this->passive && str == NULL)
|
||||
pw_properties_set(properties, PW_KEY_LINK_PASSIVE, "true");
|
||||
|
||||
impl->async = !output_node->driver &&
|
||||
(output_node->async || input_node->async) &&
|
||||
impl->async = (output_node->async || input_node->async) &&
|
||||
SPA_FLAG_IS_SET(output->flags, PW_IMPL_PORT_FLAG_ASYNC) &&
|
||||
SPA_FLAG_IS_SET(input->flags, PW_IMPL_PORT_FLAG_ASYNC);
|
||||
|
||||
|
|
|
|||
|
|
@ -2003,10 +2003,14 @@ static int node_ready(void *data, int status)
|
|||
struct pw_impl_node *node = data;
|
||||
struct pw_impl_node *driver = node->driver_node;
|
||||
struct pw_node_activation *a = node->rt.target.activation;
|
||||
struct pw_node_activation_state *state = &a->state[0];
|
||||
struct spa_system *data_system = node->rt.target.system;
|
||||
struct pw_node_target *t, *reposition_target = NULL;;
|
||||
struct pw_impl_port *p;
|
||||
uint64_t nsec;
|
||||
struct spa_io_clock *cl = &node->rt.position->clock;
|
||||
int sync_type, all_ready, update_sync, target_sync, old_status;
|
||||
uint32_t owner[2], reposition_owner, pending;
|
||||
uint64_t min_timeout = UINT64_MAX, nsec;
|
||||
|
||||
pw_log_trace_fp("%p: ready driver:%d exported:%d %p status:%d prepared:%d", node,
|
||||
node->driver, node->exported, driver, status, node->rt.prepared);
|
||||
|
|
@ -2019,18 +2023,13 @@ static int node_ready(void *data, int status)
|
|||
pw_log_info("%p: ready non-active node %s in state %d", node, node->name, node->info.state);
|
||||
return -EIO;
|
||||
}
|
||||
if (SPA_UNLIKELY(node != driver)) {
|
||||
pw_log_warn("%p: ready non-driver node %s", node, node->name);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
nsec = get_time_ns(data_system);
|
||||
|
||||
if (SPA_LIKELY(node == driver)) {
|
||||
struct pw_node_activation_state *state = &a->state[0];
|
||||
struct spa_io_clock *cl = &node->rt.position->clock;
|
||||
int sync_type, all_ready, update_sync, target_sync;
|
||||
uint32_t owner[2], reposition_owner;
|
||||
uint64_t min_timeout = UINT64_MAX;
|
||||
int32_t pending;
|
||||
int old_status;
|
||||
|
||||
if (SPA_UNLIKELY((pending = pw_node_activation_state_xchg(state)) > 0)) {
|
||||
pw_impl_node_rt_emit_incomplete(driver);
|
||||
old_status = SPA_ATOMIC_LOAD(a->status);
|
||||
|
|
@ -2126,24 +2125,16 @@ retry_status:
|
|||
|
||||
update_position(node, all_ready, nsec);
|
||||
|
||||
a->position.clock.cycle++;
|
||||
pw_impl_node_rt_emit_start(node);
|
||||
}
|
||||
/* this should not happen, driver nodes that are not currently driving
|
||||
* should not emit the ready callback */
|
||||
if (SPA_UNLIKELY(node->driver && !node->driving))
|
||||
return 0;
|
||||
|
||||
if (SPA_UNLIKELY(!node->driver)) {
|
||||
/* legacy, nodes should directly resume the graph by calling
|
||||
* the peer eventfd directly, node_ready is only for drivers */
|
||||
a->status = PW_NODE_ACTIVATION_FINISHED;
|
||||
a->finish_time = nsec;
|
||||
}
|
||||
/* move output with previous cycle, this makes the async nodes
|
||||
* pick up the new data immediately */
|
||||
if (status & SPA_STATUS_HAVE_DATA) {
|
||||
spa_list_for_each(p, &node->rt.output_mix, rt.node_link)
|
||||
spa_node_process_fast(p->mix);
|
||||
}
|
||||
|
||||
a->position.clock.cycle++;
|
||||
pw_impl_node_rt_emit_start(node);
|
||||
|
||||
/* now signal all the nodes we drive */
|
||||
trigger_targets(node, status, nsec);
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue