media-session: add alsa-no-dsp module

Instruct the policy to not configure audio adapter nodes in DSP mode. Instead,
Device nodes will always be configured in passthrough mode, and client nodes
will be configured in convert or passthrough mode depending on whether the
client format matches the device format or not.
This commit is contained in:
Julian Bouzas 2021-08-19 12:14:37 -04:00 committed by Wim Taymans
parent 699bfbc095
commit 90371440b0
5 changed files with 72 additions and 2 deletions

View file

@ -84,6 +84,7 @@ session.modules = {
#default-profile # restore default profiles
#default-routes # restore default route
#streams-follow-default # move streams when default changes
#alsa-no-dsp # do not configure audio nodes in DSP mode
#alsa-seq # alsa seq midi support
#alsa-monitor # alsa udev detection
#bluez5 # bluetooth support

View file

@ -0,0 +1,51 @@
/* PipeWire
*
* Copyright © 2021 Collabora Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* Instruct policy-node to not configure audio adapter nodes in DSP mode.
* Device nodes will always be configured in passthrough mode. If a client node
* wants to be linked with a device node that has a different format, then the
* policy will configure the client node in convert mode so that both nodes
* have the same format.
*
* This is done by just setting a session property flag, and policy-node does the rest.
*/
#include "config.h"
#include "pipewire/pipewire.h"
#include "pipewire/extensions/metadata.h"
#include "media-session.h"
/** \page page_media_session_module_no_dsp Media Session Module: No DSP
*/
#define KEY_NAME "policy-node.alsa-no-dsp"
int sm_alsa_no_dsp_start(struct sm_media_session *session)
{
pw_properties_set(session->props, KEY_NAME, "true");
return 0;
}

View file

@ -90,6 +90,7 @@ int sm_default_profile_start(struct sm_media_session *sess);
int sm_default_routes_start(struct sm_media_session *sess);
int sm_restore_stream_start(struct sm_media_session *sess);
int sm_streams_follow_default_start(struct sm_media_session *sess);
int sm_alsa_no_dsp_start(struct sm_media_session *sess);
int sm_alsa_midi_start(struct sm_media_session *sess);
int sm_v4l2_monitor_start(struct sm_media_session *sess);
int sm_libcamera_monitor_start(struct sm_media_session *sess);
@ -2390,6 +2391,7 @@ static const struct {
{ "default-routes", "restore default route", sm_default_routes_start, NULL },
{ "restore-stream", "restore stream settings", sm_restore_stream_start, NULL },
{ "streams-follow-default", "move streams when default changes", sm_streams_follow_default_start, NULL },
{ "alsa-no-dsp", "do not configure audio nodes in DSP mode", sm_alsa_no_dsp_start, NULL },
{ "alsa-seq", "alsa seq midi support", sm_alsa_midi_start, NULL },
{ "alsa-monitor", "alsa card udev detection", sm_alsa_monitor_start, NULL },
{ "v4l2", "video for linux udev detection", sm_v4l2_monitor_start, NULL },

View file

@ -92,6 +92,7 @@ struct impl {
struct default_node defaults[4];
bool streams_follow_default;
bool alsa_no_dsp;
};
struct node {
@ -279,6 +280,7 @@ static int configure_node(struct node *node, struct spa_audio_info *info, bool f
struct spa_pod *param;
struct spa_audio_info format;
enum pw_direction direction;
uint32_t mode;
if (node->configured && !force) {
pw_log_debug("node %d is configured passthrough:%d", node->id, node->passthrough);
@ -292,7 +294,18 @@ static int configure_node(struct node *node, struct spa_audio_info *info, bool f
format = node->format;
if (info != NULL && info->info.raw.channels > 0) {
if (impl->alsa_no_dsp) {
if ((info != NULL && memcmp(&node->format, info, sizeof(node->format)) == 0) ||
node->type == NODE_TYPE_DEVICE)
mode = SPA_PARAM_PORT_CONFIG_MODE_passthrough;
else
mode = SPA_PARAM_PORT_CONFIG_MODE_convert;
} else {
mode = SPA_PARAM_PORT_CONFIG_MODE_dsp;
}
if (mode != SPA_PARAM_PORT_CONFIG_MODE_passthrough &&
info != NULL && info->info.raw.channels > 0) {
pw_log_info("node %d monitor:%d channelmix %d->%d",
node->id, node->monitor, format.info.raw.channels,
info->info.raw.channels);
@ -313,7 +326,7 @@ static int configure_node(struct node *node, struct spa_audio_info *info, bool f
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamPortConfig, SPA_PARAM_PortConfig,
SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(direction),
SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(SPA_PARAM_PORT_CONFIG_MODE_dsp),
SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(mode),
SPA_PARAM_PORT_CONFIG_monitor, SPA_POD_Bool(true),
SPA_PARAM_PORT_CONFIG_format, SPA_POD_Pod(param));
@ -1314,6 +1327,8 @@ int sm_policy_node_start(struct sm_media_session *session)
flag = pw_properties_get(session->props, NAME ".streams-follow-default");
impl->streams_follow_default = (flag != NULL && pw_properties_parse_bool(flag));
flag = pw_properties_get(session->props, NAME ".alsa-no-dsp");
impl->alsa_no_dsp = (flag != NULL && pw_properties_parse_bool(flag));
spa_list_init(&impl->node_list);

View file

@ -66,6 +66,7 @@ if get_option('session-managers').contains('media-session') and alsa_dep.found()
media_session_sources = [
'media-session/access-flatpak.c',
'media-session/access-portal.c',
'media-session/alsa-no-dsp.c',
'media-session/alsa-midi.c',
'media-session/alsa-monitor.c',
'media-session/alsa-endpoint.c',