From b418b876e43a1f16072b5a9926741189f918ac94 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 1 Oct 2021 16:17:24 +0200 Subject: [PATCH] media-session: don't try to remap to unpositioned formats check if a node has AUX channels and mark it as unpositioned in that case. If the peer node we need to link to has unpositioned channels, don't try to configure the node for the unpositioned layout but instead configure it to its default format and link the ports one by one, as many as there are. This is mostly for Pro-audio devices. It does not make sense to try to remix a stereo stream to 18 channels. Most likely the pro-audio card does not have 18 speakers connected and we would not known how to remix anyway because the channels don't have a position. So, just take the 2 channels and link them to the 2 first AUX inputs, which is usually more correct and mimics what other players do when outputting to JACK. If a specific remapping needs to be done for the pro-audio card, it needs to be configured with a virtual device. --- src/media-session/policy-node.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/media-session/policy-node.c b/src/media-session/policy-node.c index 129b41560..69423ec89 100644 --- a/src/media-session/policy-node.c +++ b/src/media-session/policy-node.c @@ -139,8 +139,21 @@ struct node { unsigned int passthrough_only:1; unsigned int passthrough:1; unsigned int want_passthrough:1; + unsigned int unpositioned:1; }; +static bool is_unpositioned(struct spa_audio_info *info) +{ + uint32_t i; + if (SPA_FLAG_IS_SET(info->info.raw.flags, SPA_AUDIO_FLAG_UNPOSITIONED)) + return true; + for (i = 0; i < info->info.raw.channels; i++) + if (info->info.raw.position[i] >= SPA_AUDIO_CHANNEL_START_Aux && + info->info.raw.position[i] <= SPA_AUDIO_CHANNEL_LAST_Aux) + return true; + return false; +} + static bool find_format(struct node *node) { struct impl *impl = node->impl; @@ -190,9 +203,11 @@ static bool find_format(struct node *node) if (n_position == 0 || n_position != info.info.raw.channels) SPA_FLAG_SET(info.info.raw.flags, SPA_AUDIO_FLAG_UNPOSITIONED); - if (node->format.info.raw.channels < info.info.raw.channels) + if (node->format.info.raw.channels < info.info.raw.channels) { node->format = info; - + if (is_unpositioned(&info)) + node->unpositioned = true; + } have_format = true; break; @@ -926,11 +941,10 @@ static int link_nodes(struct node *node, struct node *peer) configure_passthrough(node); configure_passthrough(peer); } else { - if (node->dont_remix) - configure_node(node, NULL, false); - else { + if (node->dont_remix || peer->unpositioned) + configure_node(node, NULL, peer->unpositioned); + else configure_node(node, &peer->format, true); - } } if (node->direction == PW_DIRECTION_INPUT) {