wireplumber: update to master as of Dec 5th 2019 63/23263/1
authorGeorge Kiagiadakis <george.kiagiadakis@collabora.com>
Thu, 5 Dec 2019 15:08:12 +0000 (17:08 +0200)
committerGeorge Kiagiadakis <george.kiagiadakis@collabora.com>
Thu, 5 Dec 2019 16:42:36 +0000 (18:42 +0200)
This update introduces a new TOML configuration file based
policy engine, which behaves the same as the previous static
engine, except that we now can:
 * link different apps to different devices
 * finetune how the device is configured with a lot of properties
   that we can match against
 * force a specific role to a specific app, by overriding
   it in the configuration file
 * make a specific app remain linked to the output even if
   another app comes in to play something; this is useful
   for the bluez-alsa gstreamer helper at this moment

In addition, the code is cleaner and easier to work with, and
we can easily add more properties to force a specific behavior
per app.

Bug-AGL: SPEC-2837

Change-Id: If0ecd468592b78cb2f2a5a8c3db16f655e4927f9
Signed-off-by: George Kiagiadakis <george.kiagiadakis@collabora.com>
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/bluealsa-input-audio.endpoint-link.in [new file with mode: 0644]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/bluealsa-output-audio.endpoint-link.in [new file with mode: 0644]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/default-input-audio.endpoint-link.in [new file with mode: 0644]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/default-output-audio.endpoint-link.in [new file with mode: 0644]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/default.streams [new file with mode: 0644]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/wireplumber.conf [moved from meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/wireplumber.conf.in with 65% similarity]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl_git.bb
meta-pipewire/recipes-multimedia/wireplumber/wireplumber/0001-Build-cpptoml-without-a-cmake-subproject.patch [new file with mode: 0644]
meta-pipewire/recipes-multimedia/wireplumber/wireplumber_git.bb

diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/bluealsa-input-audio.endpoint-link.in b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/bluealsa-input-audio.endpoint-link.in
new file mode 100644 (file)
index 0000000..818ac6b
--- /dev/null
@@ -0,0 +1,16 @@
+[match-endpoint]
+priority = 75
+direction = "input"
+name = "bluealsa*"
+media_class = "Stream/Input/Audio"
+
+[target-endpoint]
+media_class = "Audio/Source"
+streams = "default.streams"
+stream = "Multimedia"
+properties = [
+  CAPTURE_DEV_PROPERTIES
+]
+
+[endpoint-link]
+keep = true
diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/bluealsa-output-audio.endpoint-link.in b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/bluealsa-output-audio.endpoint-link.in
new file mode 100644 (file)
index 0000000..1ba7afe
--- /dev/null
@@ -0,0 +1,16 @@
+[match-endpoint]
+priority = 75
+direction = "output"
+name = "bluealsa*"
+media_class = "Stream/Output/Audio"
+
+[target-endpoint]
+media_class = "Audio/Sink"
+streams = "default.streams"
+stream = "Multimedia"
+properties = [
+  PLAYBACK_DEV_PROPERTIES
+]
+
+[endpoint-link]
+keep = true
diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/default-input-audio.endpoint-link.in b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/default-input-audio.endpoint-link.in
new file mode 100644 (file)
index 0000000..adb142c
--- /dev/null
@@ -0,0 +1,14 @@
+[match-endpoint]
+priority = 50
+direction = "input"
+media_class = "Stream/Input/Audio"
+
+[target-endpoint]
+media_class = "Audio/Source"
+streams = "default.streams"
+properties = [
+  CAPTURE_DEV_PROPERTIES
+]
+
+[endpoint-link]
+keep = false
diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/default-output-audio.endpoint-link.in b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/default-output-audio.endpoint-link.in
new file mode 100644 (file)
index 0000000..16af915
--- /dev/null
@@ -0,0 +1,14 @@
+[match-endpoint]
+priority = 50
+direction = "output"
+media_class = "Stream/Output/Audio"
+
+[target-endpoint]
+media_class = "Audio/Sink"
+streams = "default.streams"
+properties = [
+  PLAYBACK_DEV_PROPERTIES
+]
+
+[endpoint-link]
+keep = false
diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/default.streams b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/default.streams
new file mode 100644 (file)
index 0000000..c645416
--- /dev/null
@@ -0,0 +1,31 @@
+[[streams]]
+name = "Multimedia"
+priority = 25
+
+[[streams]]
+name = "Speech-Low"
+priority = 30
+
+[[streams]]
+name = "Custom-Low"
+priority = 35
+
+[[streams]]
+name = "Navigation"
+priority = 50
+
+[[streams]]
+name = "Speech-High"
+priority = 60
+
+[[streams]]
+name = "Custom-High"
+priority = 65
+
+[[streams]]
+name = "Communication"
+priority = 75
+
+[[streams]]
+name = "Emergency"
+priority = 99
@@ -33,24 +33,5 @@ load-module C libwireplumber-module-pw-alsa-udev {
 # and creates simple-endpoints for each one of them
 load-module C libwireplumber-module-pw-audio-client
 
-# Implements linking clients to devices and maintains
-# information about the devices to be used.
-# Notes:
-# - Devices must be specified in hw:X,Y format, where X and Y are integers.
-#   Things like hw:Intel,0 or paths are not understood.
-# - Roles and priorities can be arbitrary strings and arbitrary numbers
-# - Roles are matched against the stream names specified in the modules above.
-load-module C libwireplumber-module-simple-policy {
-  "default-playback-device": <"PLAYBACK">,
-  "default-capture-device": <"CAPTURE">,
-  "role-priorities": <{
-    "Multimedia": 1,
-    "Speech-Low": 2,
-    "Custom-Low": 3,
-    "Navigation": 5,
-    "Speech-High:": 7,
-    "Custom-High": 8,
-    "Communication": 9,
-    "Emergency": 10
-  }>
-}
+# Implements linking clients to devices based on TOML configuration files
+load-module C libwireplumber-module-config-policy
index 7ed9ea1..d569a23 100644 (file)
@@ -7,7 +7,14 @@ SECTION     = "multimedia"
 LICENSE = "MIT"
 LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
 
-SRC_URI = "file://wireplumber.conf.in"
+SRC_URI = "\
+    file://wireplumber.conf \
+    file://default.streams \
+    file://default-output-audio.endpoint-link.in \
+    file://default-input-audio.endpoint-link.in \
+    file://bluealsa-output-audio.endpoint-link.in \
+    file://bluealsa-input-audio.endpoint-link.in \
+"
 
 PACKAGE_ARCH = "${MACHINE_ARCH}"
 
@@ -15,48 +22,54 @@ do_configure[noexec] = "1"
 do_compile[noexec] = "1"
 
 #
-# For device names, any unique substring of the "endpoint" name is valid.
-# To list all endpoints:
+# Device preferences are configured by listing a subset of the properties
+# that the device node has on pipewire.
+#
+# Every property match needs to have a property name and an expected value.
+# The values support shell-like pattern matching using the * and ? characters.
+# The syntax adheres to the rules of TOML v0.5 table array.
+#
+# To list all device node properties, you can run (on the target):
 #  export XDG_RUNTIME_DIR=/run/user/1001
-#  pipewire-cli
-#  > connect pipewire-0
-#  > list-objects
-# ... and look for objects of type "PipeWire:Interface:Endpoint/0"
+#  wireplumber-cli
 #
-# For instance:
-#   id 269, parent 40, type PipeWire:Interface:Endpoint/0
-#           media.name = "USB Audio on WD15 Dock (hw:1,0 / node 5)"
-#           media.class = "Audio/Sink"
-#   id 270, parent 40, type PipeWire:Interface:Endpoint/0
-#           media.name = "USB Audio on WD15 Dock (hw:1,0 / node 7)"
-#           media.class = "Audio/Source"
+# Another way to figure out some of these properties is by parsing the
+# aplay/arecord output. For example, this line is interpreted as follows:
 #
-# Audio/Sink endpoints are valid for playback
-# Audio/Source endpoints are valid for capture
+#  card 0: PCH [HDA Intel PCH], device 2: ALC3246 [ALC3246 Analog]
 #
-# Wireplumber will first filter endpoints based on the media.class, depending
-# on whether the client is doing playback or capture and then it will look
-# for a sub-string match in the media.name
+# api.alsa.path = "hw:0,2"
+# api.alsa.card = "0"
+# api.alsa.card.id = "PCH"
+# api.alsa.card.name = "HDA Intel PCH"
+# api.alsa.pcm.device = "2"
+# api.alsa.pcm.id = "ALC3246"
+# api.alsa.pcm.name = "ALC3246 Analog"
 #
-DEV_PLAYBACK = "hw:0,0"
-DEV_CAPTURE = "hw:0,0"
+DEV_PLAYBACK = '{ name = \"api.alsa.path\", value = \"hw:0,0\" }'
+DEV_CAPTURE = '{ name = \"api.alsa.path\", value = \"hw:0,0\" }'
 
-DEV_PLAYBACK_dra7xx-evm = "DRA7xx-EVM"
-DEV_CAPTURE_dra7xx-evm = "DRA7xx-EVM"
+DEV_PLAYBACK_dra7xx-evm = '{ name = \"api.alsa.card.name\", value = \"DRA7xx-EVM\" }'
+DEV_CAPTURE_dra7xx-evm = '{ name = \"api.alsa.card.name\", value = \"DRA7xx-EVM\" }'
 
-DEV_PLAYBACK_m3ulcb = "ak4613"
-DEV_CAPTURE_m3ulcb = "ak4613"
+DEV_PLAYBACK_m3ulcb = '{ name = \"api.alsa.card.name\", value = \"ak4613\" }'
+DEV_CAPTURE_m3ulcb = '{ name = \"api.alsa.card.name\", value = \"ak4613\" }'
 
-DEV_PLAYBACK_h3ulcb = "ak4613"
-DEV_CAPTURE_h3ulcb = "ak4613"
+DEV_PLAYBACK_h3ulcb = '{ name = \"api.alsa.card.name\", value = \"ak4613\" }'
+DEV_CAPTURE_h3ulcb = '{ name = \"api.alsa.card.name\", value = \"ak4613\" }'
 
-DEV_PLAYBACK_raspberrypi3 = "bcm2835 ALSA on bcm2835 ALSA"
-DEV_CAPTURE_raspberrypi3 = "hw:0,0"
+DEV_PLAYBACK_raspberrypi3 = '{ name = \"api.alsa.pcm.name\", value = \"bcm2835 ALSA\" }, { name = \"api.alsa.card.name\", value = \"bcm2835 ALSA\" }'
+DEV_CAPTURE_raspberrypi3 = '{ name = \"api.alsa.path\", value = \"hw:0,0\" }'
 
 do_install_append() {
-    sed -e "s/PLAYBACK/${DEV_PLAYBACK}/" -e "s/CAPTURE/${DEV_CAPTURE}/" ${WORKDIR}/wireplumber.conf.in > ${WORKDIR}/wireplumber.conf
+    sed -e "s/PLAYBACK_DEV_PROPERTIES/${DEV_PLAYBACK}/" -e "s/CAPTURE_DEV_PROPERTIES/${DEV_CAPTURE}/" ${WORKDIR}/default-output-audio.endpoint-link.in > ${WORKDIR}/default-output-audio.endpoint-link
+    sed -e "s/PLAYBACK_DEV_PROPERTIES/${DEV_PLAYBACK}/" -e "s/CAPTURE_DEV_PROPERTIES/${DEV_CAPTURE}/" ${WORKDIR}/default-input-audio.endpoint-link.in > ${WORKDIR}/default-input-audio.endpoint-link
+    sed -e "s/PLAYBACK_DEV_PROPERTIES/${DEV_PLAYBACK}/" -e "s/CAPTURE_DEV_PROPERTIES/${DEV_CAPTURE}/" ${WORKDIR}/bluealsa-output-audio.endpoint-link.in > ${WORKDIR}/bluealsa-output-audio.endpoint-link
+    sed -e "s/PLAYBACK_DEV_PROPERTIES/${DEV_PLAYBACK}/" -e "s/CAPTURE_DEV_PROPERTIES/${DEV_CAPTURE}/" ${WORKDIR}/bluealsa-input-audio.endpoint-link.in > ${WORKDIR}/bluealsa-input-audio.endpoint-link
     install -d ${D}/${sysconfdir}/wireplumber/
     install -m 644 ${WORKDIR}/wireplumber.conf ${D}/${sysconfdir}/wireplumber/wireplumber.conf
+    install -m 644 ${WORKDIR}/default.streams ${D}/${sysconfdir}/wireplumber/default.streams
+    install -m 644 ${WORKDIR}/*.endpoint-link ${D}/${sysconfdir}/wireplumber/
 }
 
 FILES_${PN} += "\
diff --git a/meta-pipewire/recipes-multimedia/wireplumber/wireplumber/0001-Build-cpptoml-without-a-cmake-subproject.patch b/meta-pipewire/recipes-multimedia/wireplumber/wireplumber/0001-Build-cpptoml-without-a-cmake-subproject.patch
new file mode 100644 (file)
index 0000000..726b35e
--- /dev/null
@@ -0,0 +1,28 @@
+From e5efe3d4f0abc28251dac245ce0cf4124e7e2a12 Mon Sep 17 00:00:00 2001
+From: George Kiagiadakis <george.kiagiadakis@collabora.com>
+Date: Thu, 5 Dec 2019 17:59:44 +0200
+Subject: [PATCH] Build cpptoml without a cmake subproject
+
+Upstream-Status: Inappropriate
+---
+ meson.build | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/meson.build b/meson.build
+index 5a75d96..0b21377 100644
+--- a/meson.build
++++ b/meson.build
+@@ -24,9 +24,7 @@ else
+   wireplumber_config_dir = join_paths(get_option('prefix'), get_option('sysconfdir'), 'wireplumber')
+ endif
+-cmake = import('cmake')
+-cpptoml = cmake.subproject('cpptoml')
+-cpptoml_dep = cpptoml.dependency('cpptoml')
++cpptoml_dep = declare_dependency(include_directories: include_directories('subprojects/cpptoml'))
+ gobject_dep = dependency('gobject-2.0')
+ gmodule_dep = dependency('gmodule-2.0')
+-- 
+2.24.0
+
index 0ea2975..d89ca5c 100644 (file)
@@ -11,12 +11,22 @@ inherit meson pkgconfig gobject-introspection
 
 DEPENDS = "glib-2.0 glib-2.0-native pipewire"
 
-SRC_URI = "git://gitlab.freedesktop.org/pipewire/wireplumber.git;protocol=https;branch=master"
-SRCREV = "59ab08ff0c9ff8b80dba93b8928db99f1a222ac4"
+SRC_URI = "\
+    git://gitlab.freedesktop.org/pipewire/wireplumber.git;protocol=https;branch=master \
+    https://raw.githubusercontent.com/skystrife/cpptoml/fededad7169e538ca47e11a9ee9251bc361a9a65/include/cpptoml.h \
+    file://0001-Build-cpptoml-without-a-cmake-subproject.patch \
+"
+SRCREV = "8bdadd5a71510afce3254976605a2860fedc2a0b"
+SRC_URI[sha256sum] = "3e4e1d315fa1229921c7a4297ead08775b5bb1220c18a7eac62db9ca7e79df0d"
 
 PV = "0.1.90+git${SRCPV}"
 S  = "${WORKDIR}/git"
 
+do_configure_prepend() {
+    mkdir -p ${WORKDIR}/git/subprojects/cpptoml/include
+    cp -f ${WORKDIR}/cpptoml.h ${WORKDIR}/git/subprojects/cpptoml/include/
+}
+
 PACKAGES =+ "${PN}-config"
 
 FILES_${PN} += "\