diff --git a/src/modules/module-client-node/remote-node.c b/src/modules/module-client-node/remote-node.c index 5d7342ffe..eeafa1543 100644 --- a/src/modules/module-client-node/remote-node.c +++ b/src/modules/module-client-node/remote-node.c @@ -317,9 +317,9 @@ static int add_port_update(struct node_data *data, struct pw_impl_port *port, ui for (idx = 0;;) { spa_pod_dynamic_builder_init(&b, buf, sizeof(buf), 4096); - res = spa_node_port_enum_params_sync(port->node->node, - port->direction, port->port_id, - id, &idx, NULL, ¶m, &b.b); + res = spa_node_port_enum_params_sync(port->mix, + port->direction, SPA_ID_INVALID, + id, &idx, NULL, ¶m, &b.b); if (res == 1) { void *p; p = pw_reallocarray(params, n_params + 1, sizeof(struct spa_pod*)); diff --git a/src/pipewire/context.c b/src/pipewire/context.c index e2e8d2fc9..c3618c6be 100644 --- a/src/pipewire/context.c +++ b/src/pipewire/context.c @@ -670,7 +670,9 @@ SPA_PRINTF_FUNC(7, 8) int pw_context_debug_port_params(struct pw_context *this, */ int pw_context_find_format(struct pw_context *context, struct pw_impl_port *output, + uint32_t output_mix, struct pw_impl_port *input, + uint32_t input_mix, struct pw_properties *props, uint32_t n_format_filters, struct spa_pod **format_filters, @@ -684,10 +686,27 @@ int pw_context_find_format(struct pw_context *context, struct spa_pod_builder fb = { 0 }; uint8_t fbuf[4096]; struct spa_pod *filter; + struct spa_node *in_node, *out_node; + uint32_t in_port, out_port; out_state = output->state; in_state = input->state; + if (output_mix == SPA_ID_INVALID) { + out_node = output->node->node; + out_port = output->port_id; + } else { + out_node = output->mix; + out_port = output_mix; + } + if (input_mix == SPA_ID_INVALID) { + in_node = input->node->node; + in_port = input->port_id; + } else { + in_node = input->mix; + in_port = input_mix; + } + pw_log_debug("%p: finding best format %d %d", context, out_state, in_state); /* when a port is configured but the node is idle, we can reconfigure with a different format */ @@ -701,8 +720,8 @@ int pw_context_find_format(struct pw_context *context, if (in_state == PW_IMPL_PORT_STATE_CONFIGURE && out_state > PW_IMPL_PORT_STATE_CONFIGURE) { /* only input needs format */ spa_pod_builder_init(&fb, fbuf, sizeof(fbuf)); - if ((res = spa_node_port_enum_params_sync(output->node->node, - output->direction, output->port_id, + if ((res = spa_node_port_enum_params_sync(out_node, + output->direction, out_port, SPA_PARAM_Format, &oidx, NULL, &filter, &fb)) != 1) { if (res < 0) @@ -714,8 +733,8 @@ int pw_context_find_format(struct pw_context *context, pw_log_debug("%p: Got output format:", context); pw_log_format(SPA_LOG_LEVEL_DEBUG, filter); - if ((res = spa_node_port_enum_params_sync(input->node->node, - input->direction, input->port_id, + if ((res = spa_node_port_enum_params_sync(in_node, + input->direction, in_port, SPA_PARAM_EnumFormat, &iidx, filter, format, builder)) <= 0) { if (res == -ENOENT || res == 0) { @@ -730,8 +749,8 @@ int pw_context_find_format(struct pw_context *context, } else if (out_state >= PW_IMPL_PORT_STATE_CONFIGURE && in_state > PW_IMPL_PORT_STATE_CONFIGURE) { /* only output needs format */ spa_pod_builder_init(&fb, fbuf, sizeof(fbuf)); - if ((res = spa_node_port_enum_params_sync(input->node->node, - input->direction, input->port_id, + if ((res = spa_node_port_enum_params_sync(in_node, + input->direction, in_port, SPA_PARAM_Format, &iidx, NULL, &filter, &fb)) != 1) { if (res < 0) @@ -743,8 +762,8 @@ int pw_context_find_format(struct pw_context *context, pw_log_debug("%p: Got input format:", context); pw_log_format(SPA_LOG_LEVEL_DEBUG, filter); - if ((res = spa_node_port_enum_params_sync(output->node->node, - output->direction, output->port_id, + if ((res = spa_node_port_enum_params_sync(out_node, + output->direction, out_port, SPA_PARAM_EnumFormat, &oidx, filter, format, builder)) <= 0) { if (res == -ENOENT || res == 0) { @@ -761,8 +780,8 @@ int pw_context_find_format(struct pw_context *context, /* both ports need a format */ pw_log_debug("%p: do enum input %d", context, iidx); spa_pod_builder_init(&fb, fbuf, sizeof(fbuf)); - if ((res = spa_node_port_enum_params_sync(input->node->node, - input->direction, input->port_id, + if ((res = spa_node_port_enum_params_sync(in_node, + input->direction, in_port, SPA_PARAM_EnumFormat, &iidx, NULL, &filter, &fb)) != 1) { if (res == -ENOENT) { @@ -779,8 +798,8 @@ int pw_context_find_format(struct pw_context *context, pw_log_debug("%p: enum output %d with filter: %p", context, oidx, filter); pw_log_format(SPA_LOG_LEVEL_DEBUG, filter); - if ((res = spa_node_port_enum_params_sync(output->node->node, - output->direction, output->port_id, + if ((res = spa_node_port_enum_params_sync(out_node, + output->direction, out_port, SPA_PARAM_EnumFormat, &oidx, filter, format, builder)) != 1) { if (res == 0 && filter != NULL) { diff --git a/src/pipewire/impl-link.c b/src/pipewire/impl-link.c index 76eae1242..dab97df47 100644 --- a/src/pipewire/impl-link.c +++ b/src/pipewire/impl-link.c @@ -355,7 +355,9 @@ static int do_negotiate(struct pw_impl_link *this) /* find a common format for the ports */ if ((res = pw_context_find_format(context, - output, input, NULL, 0, NULL, + output, this->rt.out_mix.port.port_id, + input, this->rt.in_mix.port.port_id, + NULL, 0, NULL, &format, &b, &error)) < 0) { format = NULL; goto error; @@ -369,8 +371,8 @@ static int do_negotiate(struct pw_impl_link *this) /* if output port had format and is idle, check if it changed. If so, renegotiate */ if (out_state > PW_IMPL_PORT_STATE_CONFIGURE && output->node->info.state == PW_NODE_STATE_IDLE) { index = 0; - res = spa_node_port_enum_params_sync(output->node->node, - output->direction, output->port_id, + res = spa_node_port_enum_params_sync(output->mix, + this->rt.out_mix.port.direction, this->rt.out_mix.port.port_id, SPA_PARAM_Format, &index, NULL, ¤t, &b); switch (res) { @@ -403,8 +405,8 @@ static int do_negotiate(struct pw_impl_link *this) /* if input port had format and is idle, check if it changed. If so, renegotiate */ if (in_state > PW_IMPL_PORT_STATE_CONFIGURE && input->node->info.state == PW_NODE_STATE_IDLE) { index = 0; - res = spa_node_port_enum_params_sync(input->node->node, - input->direction, input->port_id, + res = spa_node_port_enum_params_sync(input->mix, + this->rt.in_mix.port.direction, this->rt.in_mix.port.port_id, SPA_PARAM_Format, &index, NULL, ¤t, &b); switch (res) { @@ -492,12 +494,12 @@ static int do_negotiate(struct pw_impl_link *this) return res; error: - pw_context_debug_port_params(context, input->node->node, input->direction, - input->port_id, SPA_PARAM_EnumFormat, res, - "input format (%s)", error); - pw_context_debug_port_params(context, output->node->node, output->direction, - output->port_id, SPA_PARAM_EnumFormat, res, - "output format (%s)", error); + pw_context_debug_port_params(context, input->mix, + this->rt.in_mix.port.direction, this->rt.in_mix.port.port_id, + SPA_PARAM_EnumFormat, res, "input format (%s)", error); + pw_context_debug_port_params(context, output->mix, + this->rt.out_mix.port.direction, this->rt.out_mix.port.port_id, + SPA_PARAM_EnumFormat, res, "output format (%s)", error); link_update_state(this, PW_LINK_STATE_ERROR, res, error); free(format); return res; @@ -604,8 +606,8 @@ static int do_allocation(struct pw_impl_link *this) } if ((res = pw_buffers_negotiate(this->context, alloc_flags, - output->node->node, output->port_id, - input->node->node, input->port_id, + output->mix, this->rt.out_mix.port.port_id, + input->mix, this->rt.in_mix.port.port_id, &output->buffers)) < 0) { error = spa_aprintf("error alloc buffers: %s", spa_strerror(res)); goto error; diff --git a/src/pipewire/impl-port.c b/src/pipewire/impl-port.c index bf2ddb2c3..14f2217e0 100644 --- a/src/pipewire/impl-port.c +++ b/src/pipewire/impl-port.c @@ -853,11 +853,13 @@ int pw_impl_port_set_mix(struct pw_impl_port *port, struct spa_node *node, uint3 SPA_IO_Buffers, &port->rt.io, sizeof(port->rt.io)); - if (port->node && port->node->rt.position) + if (port->node && port->node->rt.position) { spa_node_set_io(port->mix, SPA_IO_Position, port->node->rt.position, sizeof(struct spa_io_position)); + } + check_params(port); } return 0; } @@ -1530,7 +1532,6 @@ int pw_impl_port_for_each_param(struct pw_impl_port *port, { int res; struct impl *impl = SPA_CONTAINER_OF(port, struct impl, this); - struct pw_impl_node *node = port->node; struct result_port_params_data user_data = { impl, data, callback, seq, false }; struct spa_hook listener; struct spa_param_info *pi; @@ -1589,11 +1590,10 @@ int pw_impl_port_for_each_param(struct pw_impl_port *port, pw_param_add(&impl->pending_list, seq, param_id, NULL); spa_zero(listener); - spa_node_add_listener(node->node, &listener, &node_events, &user_data); - res = spa_node_port_enum_params(node->node, seq, - port->direction, port->port_id, - param_id, index, max, - filter); + spa_node_add_listener(port->mix, &listener, &node_events, &user_data); + res = spa_node_port_enum_params(port->mix, seq, + port->direction, SPA_ID_INVALID, + param_id, index, max, filter); spa_hook_remove(&listener); if (user_data.cache) { diff --git a/src/pipewire/private.h b/src/pipewire/private.h index 0d82014ce..d3de73c73 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -1158,7 +1158,9 @@ struct pw_control { /** Find a good format between 2 ports */ int pw_context_find_format(struct pw_context *context, struct pw_impl_port *output, + uint32_t output_mix, struct pw_impl_port *input, + uint32_t input_mix, struct pw_properties *props, uint32_t n_format_filters, struct spa_pod **format_filters,