From 1c8daa4a507e1580dd0a931febd64895e7aa4376 Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Thu, 9 May 2019 09:24:21 +0200 Subject: [PATCH] core: fix pw_core_find_format() for active ports pw_core_find_format() is currently broken when one of the ports is already active: The format of the active port is used and the other port is completely ignored. As a result, the autolink module may try to link a new port to the first already active port even if the formats do not match. To fix this, use the format of the active port as a filter and enumerate the formats of the other port. --- src/pipewire/core.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/pipewire/core.c b/src/pipewire/core.c index dcf0def6d..c0ae3f936 100644 --- a/src/pipewire/core.c +++ b/src/pipewire/core.c @@ -773,27 +773,51 @@ int pw_core_find_format(struct pw_core *core, in_state = PW_PORT_STATE_CONFIGURE; if (in_state == PW_PORT_STATE_CONFIGURE && out_state > PW_PORT_STATE_CONFIGURE) { - /* only input needs format */ + struct spa_pod_builder fb = { 0 }; + uint8_t fbuf[4096]; + struct spa_pod *dummy; + spa_pod_builder_init(&fb, fbuf, sizeof(fbuf)); if ((res = spa_node_port_enum_params(output->node->node, output->spa_direction, output->port_id, t->param.idFormat, &oidx, - NULL, format, builder)) <= 0) { - if (res == 0) - res = -EBADF; + NULL, format, &fb)) <= 0) { asprintf(error, "error get output format: %s", spa_strerror(res)); goto error; } + pw_log_debug("Got output %d format:", oidx); + if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG)) + spa_debug_format(2, core->type.map, *format); + + if ((res = spa_node_port_enum_params(input->node->node, + input->spa_direction, input->port_id, + t->param.idEnumFormat, &iidx, + *format, &dummy, builder)) <= 0) { + asprintf(error, "error input enum formats: %d", res); + goto error; + } } else if (out_state == PW_PORT_STATE_CONFIGURE && in_state > PW_PORT_STATE_CONFIGURE) { - /* only output needs format */ + struct spa_pod_builder fb = { 0 }; + uint8_t fbuf[4096]; + struct spa_pod *dummy; + spa_pod_builder_init(&fb, fbuf, sizeof(fbuf)); if ((res = spa_node_port_enum_params(input->node->node, input->spa_direction, input->port_id, t->param.idFormat, &iidx, - NULL, format, builder)) <= 0) { - if (res == 0) - res = -EBADF; + NULL, format, &fb)) <= 0) { asprintf(error, "error get input format: %s", spa_strerror(res)); goto error; } + pw_log_debug("Got input %d format:", oidx); + if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG)) + spa_debug_format(2, core->type.map, *format); + + if ((res = spa_node_port_enum_params(output->node->node, + output->spa_direction, output->port_id, + t->param.idEnumFormat, &oidx, + *format, &dummy, builder)) <= 0) { + asprintf(error, "error output enum formats: %d", res); + goto error; + } } else if (in_state == PW_PORT_STATE_CONFIGURE && out_state == PW_PORT_STATE_CONFIGURE) { struct spa_pod_builder fb = { 0 }; uint8_t fbuf[4096];