PipeWire 音頻設計與實現分析一——介紹

PipeWire 是一個基于圖的媒體處理引擎,一個可以運行多媒體節點圖的媒體服務器,是 Linux 的音頻/視頻總線,它管理 Linux 系統中,不同應用程序對音頻和視頻設備的共享訪問。它提供了一個本地客戶端音頻 API,但也提供兼容層來支持使用常見的音頻 API,包括 ALSA、PulseAudio 和 JACK。

在實現上,PipeWire 主要分為幾部分:

  • PipeWire 主守護進程 pipewire
  • PipeWire 的本地 API 客戶端庫
  • PipeWire 的 PulseAudio 兼容層,主要是 pipewire-pulse 守護進程
  • PipeWire 的 JACK 兼容層,主要是一個 shell 腳本和幾個 JACK 兼容客戶端庫
  • PipeWire 的 ALSA 兼容層,主要是 PipeWire 的 ALSA 插件
  • PipeWire 的媒體會話管理器,目前主要有兩個實現,一個是 pipewire-media-session,另一個是 wireplumber

PipeWire 在媒體節點圖的處理方面,采用機制與策略分離的設計。PipeWire 主守護進程運行媒體節點圖,是機制而不是策略。外部媒體會話管理器構建它們自己的音視頻流水線,然后讓 pipewire 守護進程執行最終的結果。這包括監聽系統中設備狀態的變化,并根據需要改變音視頻流水線。

媒體會話管理器不屬于 pipewire 項目本身,它們是單獨的項目,獨立的應用程序,它們通過 pipewire 的本地客戶端 API 庫與 PipeWire 主守護進程通信。媒體會話管理器目前的兩個實現中,pipewire-media-session 的源碼位于 media-session,WirePlumber 的源碼位于 wireplumber,在 GitHub 上有 wireplumber 項目的鏡像。PipeWire 社區有逐漸將媒體會話管理器從 pipewire-media-session 切換到 WirePlumber 的趨勢,pipewire-media-session 的代碼已經很少更新 (2025-03-09),甚至沒有做 GitHub 的鏡像。PipeWire 相關各部分結構如下圖:
PipeWire Architecture Overall
PipeWire 中,大部分功能通過模塊和插件實現,主守護進程 pipewire 和它的 PulseAudio 兼容層 pipewire-pulse 盡管運行在不同的進程中,但共用相同的可執行文件,這兩個守護進程通過加載不同的配置文件,進而加載不同的模塊和插件,來運行不同的邏輯,執行不同的功能,如:

$ ls -al /usr/bin/pipewire-pulse 
lrwxrwxrwx 1 root root 8 11月  9  2022 /usr/bin/pipewire-pulse -> pipewire

在 Ubuntu 操作系統平臺上,pipewire 守護進程的配置文件為 /usr/share/pipewire/pipewire.conf,pipewire-pulse 的配置文件為 /usr/share/pipewire/pipewire-pulse.conf。媒體會話管理器同樣有它的配置文件,pipewire-media-session 的配置文件為 /usr/share/pipewire/media-session.d/media-session.conf,此外,它還有用于監視 ALSA 音頻設備、藍牙音頻設備和 V4L2 視頻設備的配置文件 /usr/share/pipewire/media-session.d/alsa-monitor.conf/usr/share/pipewire/media-session.d/bluez-monitor.conf/usr/share/pipewire/media-session.d/v4l2-monitor.conf

本文分析應用程序接入 PulseAudio 本地 API 客戶端庫或 PipeWire 本地 API 客戶端庫的場景下,PipeWire 音頻部分的設計和實現,這主要包括 PipeWire 的本地 API 客戶端庫、PipeWire 主守護進程 pipewire、PipeWire 的 PulseAudio 兼容層 pipewire-pulse 和媒體會話管理器 pipewire-media-sessionpipewire-media-session 主要與比較老的 pipewire 版本一起使用,盡管它有逐漸被替代的趨勢,但它的實現邏輯更容易理解一點,這里仍然以它為例,來看 PipeWire 的會話管理器的實現。

代碼獲取及編譯調試運行

安裝 PipeWire 的首選方法是通過 Linux 系統發行版的包管理系統,比如通過 apt/dpkg 為 Debian/Ubuntu 等系統安裝,通過 yum/rpm 為 Fedora/CentOS 等系統安裝,然而,我們為了方便代碼分析調試,從代碼編譯運行。

獲取代碼的方法有多種,從 pipewire 和 pipewire-media-session 的源碼倉庫,自然可以通過 git 命令獲得源碼。

如果是 Ubuntu 系統,可以通過 apt 命令獲得源碼,具體方法如下:

  1. 編輯 /etc/apt/sources.list 文件,取消注釋那些 deb src 行,隨后執行 sudo apt-get update 命令更新包倉庫信息。
  2. 執行 sudo apt build-dep pipewiresudo apt build-dep pipewire-media-session 命令分別安裝編譯 pipewire 和 pipewire-media-session 所需的所有依賴包。
  3. 執行 apt source pipewireapt source pipewire-media-session 命令分別獲得 pipewire 和 pipewire-media-session 的源碼及其 debian 編譯配置文件。
  4. 執行 cd pipewire-0.3.48 && dpkg-buildpackage -b -uc -nc 命令以 dpkg-buildpackage 的方式編譯 pipewire 的源碼,這將生成多個 .deb 文件。可以以同樣的方式編譯 pipewire-media-session 的源碼。其中 dpkg-buildpackage-nc 參數表示不清理之前編譯結果 (或者 --no-clean)。

dpkg-buildpackage 構建工具,封裝 pipewire 本身的構建工具,編譯生成正式版的 deb 包。對于調試分析,更方便的是,直接使用 pipewire 本身的構建工具編譯生成 debug 版的二進制文件。PipeWire 使用稱為 Meson 的構建工具作為它的構建過程的基礎。這個工具與 Autotools 和 CMake 有點像。Meson 生成構建配置文件,喂給更底層的構建工具 Ninja,后者大概與我們更熟悉的 GNU Make 工作在相同的抽象層次上。

Meson 使用一個用戶指定的構建目錄,Meson 生成的所有文件都會放在這個目錄中。本文中,構建目錄稱為 builddir

對于構建依賴,可以通過各個發行版的包管理工具安裝。切換到 PipeWire 源碼目錄,并為 Ninja 生成構建配置文件:

$ cd pipewire-0.3.48
$ meson setup builddir

上面的命令完成之后,可以看一下配置的構建選項:

$ meson configure builddir 
Core properties:Source dir /media/data/develop/pipewire_0.3.48/pipewire-0.3.48Build dir  /media/data/develop/pipewire_0.3.48/pipewire-0.3.48/builddirMain project options:Core options                        Current Value                         Possible Values                       Description------------                        -------------                         ---------------                       -----------auto_features                       auto                                  [enabled, disabled, auto]             Override value of all 'auto' featuresbackend                             ninja                                 [ninja, vs, vs2010, vs2012, vs2013,   Backend to usevs2015, vs2017, vs2019,               vs2022, xcode]                       buildtype                           debugoptimized                        [plain, debug, debugoptimized,        Build type to userelease, minsize, custom]             cmake_prefix_path                   []                                                                          List of additional prefixes for cmake to searchdebug                               true                                  [true, false]                         Debugdefault_library                     shared                                [shared, static, both]                Default library typeforce_fallback_for                  []                                                                          Force fallback for those subprojectsinstall_umask                       0022                                  [preserve, 0000-0777]                 Default umask to apply on permissions of installed fileslayout                              mirror                                [mirror, flat]                        Build directory layoutoptimization                        2                                     [0, g, 1, 2, 3, s]                    Optimization levelpkg_config_path                     []                                                                          List of additional paths for pkg-config to searchstrip                               false                                 [true, false]                         Strip targets on installunity                               off                                   [on, off, subprojects]                Unity buildunity_size                          4                                     >=2                                   Unity block sizewarning_level                       3                                     [0, 1, 2, 3]                          Compiler warning level to usewerror                              false                                 [true, false]                         Treat warnings as errorswrap_mode                           default                               [default, nofallback, nodownload,     Wrap modeforcefallback, nopromote]             Backend options                     Current Value                         Possible Values                       Description---------------                     -------------                         ---------------                       -----------backend_max_links                   0                                     >=0                                   Maximum number of linker processes to run or 0 for no limitBase options                        Current Value                         Possible Values                       Description------------                        -------------                         ---------------                       -----------b_asneeded                          true                                  [true, false]                         Use -Wl,--as-needed when linkingb_colorout                          always                                [auto, always, never]                 Use colored outputb_coverage                          false                                 [true, false]                         Enable coverage tracking.b_lto                               false                                 [true, false]                         Use link time optimizationb_lto_threads                       0                                                                           Use multiple threads for Link Time Optimizationb_lundef                            true                                  [true, false]                         Use -Wl,--no-undefined when linkingb_ndebug                            false                                 [true, false, if-release]             Disable assertsb_pch                               true                                  [true, false]                         Use precompiled headersb_pgo                               off                                   [off, generate, use]                  Use profile guided optimizationb_pie                               true                                  [true, false]                         Build executables as position independentb_sanitize                          none                                  [none, address, thread, undefined,    Code sanitizer to usememory, address,undefined]            b_staticpic                         true                                  [true, false]                         Build static libraries as position independentCompiler options                    Current Value                         Possible Values                       Description----------------                    -------------                         ---------------                       -----------c_args                              []                                                                          Extra arguments passed to the c compilerc_link_args                         []                                                                          Extra arguments passed to the c linkerc_std                               gnu99                                 [none, c89, c99, c11, c17, c18, c2x,  C language standard to usegnu89, gnu99, gnu11,                  gnu17, gnu18, gnu2x]                 cpp_args                            []                                                                          Extra arguments passed to the cpp compilercpp_debugstl                        false                                 [true, false]                         STL debug modecpp_eh                              default                               [none, default, a, s, sc]             C++ exception handling type.cpp_link_args                       []                                                                          Extra arguments passed to the cpp linkercpp_rtti                            true                                  [true, false]                         Enable RTTIcpp_std                             c++17                                 [none, c++98, c++03, c++11, c++14,    C++ language standard to usec++17, c++1z, c++2a, c++20,           gnu++03, gnu++11, gnu++14, gnu++17,  gnu++1z, gnu++2a,                     gnu++20]                             Directories                         Current Value                         Possible Values                       Description-----------                         -------------                         ---------------                       -----------bindir                              bin                                                                         Executable directorydatadir                             share                                                                       Data file directoryincludedir                          include                                                                     Header file directoryinfodir                             share/info                                                                  Info page directorylibdir                              lib/aarch64-linux-gnu                                                       Library directorylibexecdir                          libexec                                                                     Library executable directorylocaledir                           share/locale                                                                Locale data directorylocalstatedir                       /var/local                                                                  Localstate data directorymandir                              share/man                                                                   Manual page directoryprefix                              /usr/local                                                                  Installation prefixsbindir                             sbin                                                                        System executable directorysharedstatedir                      /var/local/lib                                                              Architecture-independent data directorysysconfdir                          etc                                                                         Sysconf data directoryTesting options                     Current Value                         Possible Values                       Description---------------                     -------------                         ---------------                       -----------errorlogs                           true                                  [true, false]                         Whether to print the logs from failing testsstdsplit                            true                                  [true, false]                         Split stdout and stderr in test logsProject options                     Current Value                         Possible Values                       Description---------------                     -------------                         ---------------                       -----------alsa                                auto                                  [enabled, disabled, auto]             Enable alsa spa plugin integrationaudioconvert                        enabled                               [enabled, disabled, auto]             Enable audioconvert spa plugin integrationaudiomixer                          enabled                               [enabled, disabled, auto]             Enable audiomixer spa plugin integrationaudiotestsrc                        enabled                               [enabled, disabled, auto]             Enable audiotestsrc spa plugin integrationavahi                               auto                                  [enabled, disabled, auto]             Enable code that depends on avahibluez5                              auto                                  [enabled, disabled, auto]             Enable bluez5 spa plugin integrationbluez5-backend-hfp-native           enabled                               [enabled, disabled, auto]             Enable HFP in native backend in bluez5 spa pluginbluez5-backend-hsp-native           enabled                               [enabled, disabled, auto]             Enable HSP in native backend in bluez5 spa pluginbluez5-backend-hsphfpd              enabled                               [enabled, disabled, auto]             Enable hsphfpd backend in bluez5 spa plugin (no dependency on hsphfpd)bluez5-backend-ofono                enabled                               [enabled, disabled, auto]             Enable oFono HFP backend in bluez5 spa plugin (no dependency on oFono)bluez5-codec-aac                    auto                                  [enabled, disabled, auto]             Enable Fraunhofer FDK AAC open source codec implementationbluez5-codec-aptx                   auto                                  [enabled, disabled, auto]             Enable AptX Qualcomm open source codec implementationbluez5-codec-ldac                   auto                                  [enabled, disabled, auto]             Enable LDAC Sony open source codec implementationcontrol                             enabled                               [enabled, disabled, auto]             Enable control spa plugin integrationdbus                                enabled                               [enabled, disabled, auto]             Enable code that depends on dbusdocdir                                                                                                          Directory for installing documentation to (defaults topipewire_datadir/doc/meson.project_name() )docs                                disabled                              [enabled, disabled, auto]             Build documentationecho-cancel-webrtc                  auto                                  [enabled, disabled, auto]             Enable WebRTC-based echo cancellerevl                                 disabled                              [enabled, disabled, auto]             Enable EVL support spa plugin integrationexamples                            enabled                               [enabled, disabled, auto]             Build examplesffmpeg                              disabled                              [enabled, disabled, auto]             Enable ffmpeg spa plugin integrationgstreamer                           auto                                  [enabled, disabled, auto]             Build GStreamer pluginsgstreamer-device-provider           auto                                  [enabled, disabled, auto]             Build GStreamer device provider plugininstalled_tests                     disabled                              [enabled, disabled, auto]             Install manual and automated test executablesjack                                auto                                  [enabled, disabled, auto]             Enable jack spa plugin integrationjack-devel                          false                                 [true, false]                         Install jack development fileslibcamera                           auto                                  [enabled, disabled, auto]             Enable libcamera spa plugin integrationlibcanberra                         auto                                  [enabled, disabled, auto]             Enable code that depends on libcanberralibjack-path                                                                                                    Where to install the libjack.so librarylibpulse                            auto                                  [enabled, disabled, auto]             Enable code that depends on libpulselibusb                              auto                                  [enabled, disabled, auto]             Enable code that depends on libusblibv4l2-path                                                                                                    Where to install the libpw-v4l2.so librarylv2                                 auto                                  [enabled, disabled, auto]             Enable loading of LV2 pluginsman                                 auto                                  [enabled, disabled, auto]             Build manpagespipewire-alsa                       auto                                  [enabled, disabled, auto]             Enable pipewire-alsa integrationpipewire-jack                       enabled                               [enabled, disabled, auto]             Enable pipewire-jack integrationpipewire-v4l2                       enabled                               [enabled, disabled, auto]             Enable pipewire-v4l2 integrationpw-cat                              auto                                  [enabled, disabled, auto]             Build pw-cat/pw-play/pw-recordraop                                auto                                  [enabled, disabled, auto]             Enable module for Remote Audio Output Protocolroc                                 auto                                  [enabled, disabled, auto]             Enable code that depends on roc toolkitsdl2                                auto                                  [enabled, disabled, auto]             Enable code that depends on SDL 2session-managers                    [media-session]                                                             Session managers to build (can be [] for none or an absolute path)sndfile                             auto                                  [enabled, disabled, auto]             Enable code that depends on libsndfilespa-plugins                         enabled                               [enabled, disabled, auto]             Enable spa plugins integrationsupport                             enabled                               [enabled, disabled, auto]             Enable support spa plugin integrationsystemd                             auto                                  [enabled, disabled, auto]             Enable systemd integrationsystemd-system-service              disabled                              [enabled, disabled, auto]             Install systemd system service filesystemd-system-unit-dir                                                                                         Directory for system systemd units (defaults to /usr/lib/systemd/system)systemd-user-service                enabled                               [enabled, disabled, auto]             Install systemd user service file (ignored without systemd)systemd-user-unit-dir                                                                                           Directory for user systemd units (defaults to /usr/lib/systemd/user)test                                disabled                              [enabled, disabled, auto]             Enable test spa plugin integrationtests                               enabled                               [enabled, disabled, auto]             Build testsudev                                auto                                  [enabled, disabled, auto]             Enable Udev integrationudevrulesdir                                                                                                    Directory for udev rules (defaults to /lib/udev/rules.d)v4l2                                auto                                  [enabled, disabled, auto]             Enable v4l2 spa plugin integrationvideoconvert                        enabled                               [enabled, disabled, auto]             Enable videoconvert spa plugin integrationvideotestsrc                        enabled                               [enabled, disabled, auto]             Enable videotestsrc spa plugin integrationvolume                              enabled                               [enabled, disabled, auto]             Enable volume spa plugin integrationvulkan                              disabled                              [enabled, disabled, auto]             Enable vulkan spa plugin integrationx11                                 auto                                  [enabled, disabled, auto]             Enable code that depends on X11x11-xfixes                          auto                                  [enabled, disabled, auto]             Enable code that depends on XFixesSubproject media-session:Core options                        Current Value                         Possible Values                       Description------------                        -------------                         ---------------                       -----------default_library                     shared                                [shared, static, both]                Default library typewarning_level                       3                                     [0, 1, 2, 3]                          Compiler warning level to usewerror                              false                                 [true, false]                         Treat warnings as errorsProject options                     Current Value                         Possible Values                       Description---------------                     -------------                         ---------------                       -----------docdir                                                                                                          Directory for installing documentation to (defaults topipewire_datadir/doc/meson.project_name() )docs                                disabled                              [enabled, disabled, auto]             Build documentationinstalled_tests                     disabled                              [enabled, disabled, auto]             Install manual and automated test executablessystemd                             auto                                  [enabled, disabled, auto]             Enable systemd integrationsystemd-system-service              disabled                              [enabled, disabled, auto]             Install systemd system service filesystemd-user-service                enabled                               [enabled, disabled, auto]             Install systemd user service file (ignored without systemd)systemd-user-unit-dir                                                                                           Directory for user systemd units (defaults to /usr/lib/systemd/user)tests                               enabled                               [enabled, disabled, auto]             Build testswith-module-sets                    [jack, pulseaudio]                    [alsa, jack, pulseaudio]              Extra modules sets to enable on install (see media-session.conf)

定義安裝目錄前綴:

$ meson configure builddir -Dprefix=/usr # Default: /usr/local

PipeWire 特有的構建選項在 Project options 部分展示,它們在 meson_options.txt 文件中定義。

最后,調用如下命令構建 PipeWire:

$ ninja -C builddir

如果想要在不安裝 PipeWire 的情況運行它,可以先運行一個腳本,它會創建一個 PipeWire 可以從構建目錄運行的環境,其中 ALSA、PulseAudio 和 JACK 應用程序將自動地使用 PipeWire 仿真庫。這個腳本具體的執行方法如下:

$ ./pw-uninstalled.sh -b builddir

pw-uninstalled.sh 腳本內容如下:

#!/usr/bin/env bashset -eSCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"while getopts ":b:v:" opt; docase ${opt} inb)BUILDDIR=${OPTARG};;v)VERSION=${OPTARG}echo "Version: ${VERSION}";;\?)echo "Invalid option: -${OPTARG}"exit 1;;:)echo "Option -${OPTARG} requires an argument"exit 1;;esac
doneif [ -z "${BUILDDIR}" ]; thenBUILDDIR=${SCRIPT_DIR}/builddirecho "Using default build directory: ${BUILDDIR}"
fiif [ ! -d "${BUILDDIR}" ]; thenecho "Invalid build directory: ${BUILDDIR}"exit 1
fi# the config file read by the daemon
export PIPEWIRE_CONFIG_DIR="${BUILDDIR}/src/daemon"
# the directory with SPA plugins
export SPA_PLUGIN_DIR="${BUILDDIR}/spa/plugins"
export SPA_DATA_DIR="${SCRIPT_DIR}/spa/plugins"
# the directory with pipewire modules
export PIPEWIRE_MODULE_DIR="${BUILDDIR}/src/modules"
export PATH="${BUILDDIR}/src/daemon:${BUILDDIR}/src/tools:${BUILDDIR}/src/media-session:${BUILDDIR}/src/examples:${PATH}"
export LD_LIBRARY_PATH="${BUILDDIR}/src/pipewire/:${BUILDDIR}/pipewire-jack/src/${LD_LIBRARY_PATH+":$LD_LIBRARY_PATH"}"
export GST_PLUGIN_PATH="${BUILDDIR}/src/gst/${GST_PLUGIN_PATH+":${GST_PLUGIN_PATH}"}"
# the directory with card profiles and paths
export ACP_PATHS_DIR="${SCRIPT_DIR}/spa/plugins/alsa/mixer/paths"
export ACP_PROFILES_DIR="${SCRIPT_DIR}/spa/plugins/alsa/mixer/profile-sets"
# ALSA plugin directory
export ALSA_PLUGIN_DIR="${BUILDDIR}/pipewire-alsa/alsa-plugins"export PW_UNINSTALLED=1
export PKG_CONFIG_PATH="${BUILDDIR}/meson-uninstalled/:${PKG_CONFIG_PATH}"if [ -d "${BUILDDIR}/subprojects/wireplumber" ]; then# FIXME: find a nice, shell-neutral way to specify a prompt"${SCRIPT_DIR}"/subprojects/wireplumber/wp-uninstalled.sh -b"${BUILDDIR}"/subprojects/wireplumber "${SHELL}"
elif [ -d "${BUILDDIR}/subprojects/media-session" ]; then# FIXME: find a nice, shell-neutral way to specify a prompt"${SCRIPT_DIR}"/subprojects/media-session/media-session-uninstalled.sh -b"${BUILDDIR}"/subprojects/media-session "${SHELL}"
else# FIXME: find a nice, shell-neutral way to specify a prompt${SHELL}
fi

pw-uninstalled.sh 腳本接受構建目錄 builddir 作為參數,根據構建工具生成的二進制文件的目錄結構,導出 PipeWire 各守護進程或客戶端應用程序需要用到的環境變量,如 PIPEWIRE_CONFIG_DIRPIPEWIRE_MODULE_DIRSPA_PLUGIN_DIRLD_LIBRARY_PATHSPA_DATA_DIR 等。

pw-uninstalled.sh 腳本有個 bug:當傳入的構建目錄 builddir 是個相對路徑時,各環境變量也會以相對路徑的形式導出。在 PipeWire 的代碼倉庫根目錄執行pw-uninstalled.sh 腳本并檢查構建目錄的有效性,隨后基于構建目錄路徑導出環境變量,切換到構建目錄運行 PipeWire 系統音頻服務器,會發現各環境變量指向的路徑為無效路徑。

從構建目錄運行 pipewire 的方法如下:

$ cd builddir/
$ make run

這將會使用默認配置文件配置和啟動 pipewire 守護進程。默認的配置文件也將自動啟動 pipewire-media-session,一個默認的示例會話管理器,和 pipewire-pulse,一個 PulseAudio 兼容服務器。

正常安裝的 PipeWire,它的 pipewire 守護進程、pipewire-media-session 和 pipewire-pulse 是作為 3 個系統服務,各自由 systemd 獨立管理的。從構建目錄運行的 PipeWire,pipewire 守護進程的配置文件為 pipewire-0.3.48/builddir/src/daemon/pipewire-uninstalled.conf,其中有如下這樣一段配置:

context.exec = [#{ path = <program-name> [ args = "<arguments>" ] }## Execute the given program with arguments.## You can optionally start the session manager here,# but it is better to start it as a systemd service.# Run the session manager with -h for options.#{ path = "/media/data/develop/pipewire_0.3.48/pipewire-0.3.48/builddir/subprojects/media-session/media-session-uninstalled.sh" args = "pipewire-media-session" }## You can optionally start the pulseaudio-server here as well# but it is better to start it as a systemd service.# It can be interesting to start another daemon here that listens# on another address with the -a option (eg. -a tcp:4713).#{ path = "/media/data/develop/pipewire_0.3.48/pipewire-0.3.48/builddir/src/daemon/pipewire" args = "-c pipewire-pulse.conf" }
]

pipewire-media-session 和 pipewire-pulse 由 pipewire 守護進程啟動。

也可以通過 PIPEWIRE_DEBUG 環境變量啟用更多的調試日志,如:

$ cd builddir/
$ PIPEWIRE_DEBUG="D" make run

還可以啟動 gdb 來調試運行 pipewire,如:

$ cd builddir/
$ PIPEWIRE_DEBUG="D" make gdb

如果系統中已經安裝了 PipeWire,且以 pipewire-media-session 作為媒體會話管理器,則從構建目錄運行之前,可能需要先通過 systemd 停掉 pipewire service/socket,如:

$ systemctl --user stop pipewire.service \pipewire.socket \pipewire-media-session.service \pipewire-pulse.service \pipewire-pulse.socket

如果以 wireplumber 作為媒體會話管理器,需要將上面命令中的 pipewire-media-session.service 替換為 wireplumber.service

PipeWire 包含一些庫和工具,在 builddir 目錄中運行如下命令安裝所有這些東西到系統的指定目錄:

$ sudo meson install

完整安裝的 PipeWire 應該有一個 pipewire 進程,一個 pipewire-media-session (或 WirePlumber) 和一個 pipewire-pulse 進程。PipeWire 通常作為一個 systemd 系統服務來啟動。PipeWire 守護進程的配置文件位于 /usr/share/pipewire/pipewire.conf,可以參考這個配置文件中的注釋來了解更多關于配置選項的內容。通過 systemd 啟動 pipewire 守護進程的方法如下:

$ systemctl --user start pipewire.service pipewire.socket

如果沒有在 pipewire.conf 配置文件中啟動 media-session,也需要像下面這樣啟動它:

$ systemctl --user start pipewire-media-session.service

要使它在系統啟動時自動啟動可以執行如下命令:

$ systemctl --user enable pipewire-media-session.service

可以使用 enable --now 來立即啟動它。

對于 wireplumber,啟動它的方法與 media-session 類似,唯一的區別是 systemd 激活文件需要替換為 wireplumber.service

pipewire-pulse 進程是 PulseAudio 音頻服務器協議的重新實現,并作為一個系統服務在 PipeWire 之上運行。它的二進制可執行文件通常位于 /usr/bin/pipewire-pulse。pipewire-pulse 進程可以通過提供的 systemd 激活文件或 PipeWire 守護進程來啟動,可參考 /usr/share/pipewire/pipewire.conf 文件。

通過 systemd 啟動 pipewire-pulse 服務的方法如下:

$ systemctl --user start pipewire-pulse.service pipewire-pulse.socket

pipewire-pulse 的二進制可執行文件實際為 pipewire 守護進程二進制可執行文件的符號鏈接。

PipeWire 的 ALSA 插件在 Fedora 發行版中通常安裝在 /usr/lib64/alsa-lib/libasound_module_pcm_pipewire.so,在 Ubuntu 發行版中通常安裝在 /usr/lib/x86_64-linux-gnu/alsa-lib/libasound_module_pcm_pipewire.so,還有一個配置文件安裝在 /usr/share/alsa/alsa.conf.d/50-pipewire.conf,當以下文件位于 /etc/alsa/conf.d/ 目錄中時,插件將被 alsa 拾取:

/etc/alsa/conf.d/50-pipewire.conf -> /usr/share/alsa/alsa.conf.d/50-pipewire.conf
/etc/alsa/conf.d/99-pipewire-default.conf

通過這樣的設置,aplay -L 應該可以列出 pipewire: 設備,它們可以被用作普通的 alsa 設備來播放和錄音。

PipeWire 音頻服務器主程序

PipeWire 音頻服務器守護進程 pipewire 和它的 PulseAudio 兼容層 pipewire-pulse 守護進程共用同一個二進制可執行文件,它們的主程序定義 (位于 pipewire/src/daemon/pipewire.c) 如下:

int main(int argc, char *argv[])
{struct pw_context *context = NULL;struct pw_main_loop *loop = NULL;struct pw_properties *properties = NULL;static const struct option long_options[] = {{ "help",	no_argument,		NULL, 'h' },{ "version",	no_argument,		NULL, 'V' },{ "config",	required_argument,	NULL, 'c' },{ "verbose",	no_argument,		NULL, 'v' },{ NULL, 0, NULL, 0}};int c, res = 0;char path[PATH_MAX];const char *config_name;enum spa_log_level level = pw_log_level;if (setenv("PIPEWIRE_INTERNAL", "1", 1) < 0)fprintf(stderr, "can't set PIPEWIRE_INTERNAL env: %m");snprintf(path, sizeof(path), "%s.conf", argv[0]);config_name = basename(path);pw_init(&argc, &argv);while ((c = getopt_long(argc, argv, "hVc:v", long_options, NULL)) != -1) {switch (c) {case 'v':if (level < SPA_LOG_LEVEL_TRACE)pw_log_set_level(++level);break;case 'h':show_help(argv[0], config_name);return 0;case 'V':fprintf(stdout, "%s\n""Compiled with libpipewire %s\n""Linked with libpipewire %s\n",argv[0],pw_get_headers_version(),pw_get_library_version());return 0;case 'c':config_name = optarg;break;default:res = -EINVAL;goto done;}}properties = pw_properties_new(PW_KEY_CONFIG_NAME, config_name,NULL);loop = pw_main_loop_new(&properties->dict);if (loop == NULL) {pw_log_error("failed to create main-loop: %m");res = -errno;goto done;}pw_loop_add_signal(pw_main_loop_get_loop(loop), SIGINT, do_quit, loop);pw_loop_add_signal(pw_main_loop_get_loop(loop), SIGTERM, do_quit, loop);context = pw_context_new(pw_main_loop_get_loop(loop), properties, 0);properties = NULL;if (context == NULL) {pw_log_error("failed to create context: %m");res = -errno;goto done;}pw_log_info("start main loop");pw_main_loop_run(loop);pw_log_info("leave main loop");done:pw_properties_free(properties);if (context)pw_context_destroy(context);if (loop)pw_main_loop_destroy(loop);pw_deinit();return res;
}

pipewire 和 pipewire-pulse 主程序的執行過程如下:

  1. 傳入可執行程序執行時的命令行參數,調用 pw_init() 函數初始化 PipeWire,初始化一些基本配置和功能組件。pw_init() 函數在所有 PipeWire 程序中都會被調用,包括 PipeWire 守護進程及其 PulseAudio 兼容層,PipeWire 客戶端程序,PipeWire 媒體會話管理器 pipewire-media-session 和 wireplumber。初始化 PipeWire 的具體含義稍后會更細致地來看。
  2. 解析命令行參數。-v 參數指示 PipeWire 進程在執行時輸出更多日志,具體指輸出日志等級加 1,而不是輸出所有日志。-c 參數用來指定配置文件名,配置文件名默認為可執行文件名加上 .conf 后綴,如 pipewire 的為 pipewire.conf,pipewire-pulse 的為 pipewire-pulse.conf,這個參數指定的配置文件名替換默認配置文件名。
  3. 調用 pw_main_loop_new() 函數創建主循環。以 struct spa_dict 對象的形式傳遞參數,這里參數主要是配置文件名。為主循環添加 SIGINTSIGTERM 信號的處理程序,收到這兩個信號時,PipeWire 進程退出主循環。
  4. 基于主循環和配置信息創建上下文。
  5. 運行主循環。
  6. 主循環結束時清理上下文和主循環等對象。

pw_init() 函數初始化一些基本配置和功能組件,該函數定義 (位于 pipewire/src/pipewire/pipewire.c) 如下:

#define MAX_SUPPORT	32#define SUPPORTLIB	"support/libspa-support"PW_LOG_TOPIC_EXTERN(log_context);
#define PW_LOG_TOPIC_DEFAULT log_contextstatic char *prgname;static struct spa_i18n *_pipewire_i18n = NULL;struct plugin {struct spa_list link;char *filename;void *hnd;spa_handle_factory_enum_func_t enum_func;struct spa_list handles;int ref;
};struct handle {struct spa_list link;struct plugin *plugin;char *factory_name;int ref;struct spa_handle handle SPA_ALIGNED(8);
};struct registry {struct spa_list plugins;
};struct support {char **categories;const char *plugin_dir;const char *support_lib;struct registry registry;char *i18n_domain;struct spa_interface i18n_iface;struct spa_support support[MAX_SUPPORT];uint32_t n_support;unsigned int initialized:1;unsigned int in_valgrind:1;unsigned int no_color:1;unsigned int no_config:1;
};static pthread_mutex_t init_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t support_lock = PTHREAD_MUTEX_INITIALIZER;
static struct support global_support;. . . . . .static void init_i18n(struct support *support)
{/* Load locale from the environment. */setlocale(LC_ALL, "");/* Set LC_NUMERIC to C so that floating point strings are consistently* formatted and parsed across locales. */setlocale(LC_NUMERIC, "C");bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");pw_set_domain(GETTEXT_PACKAGE);
}. . . . . .
SPA_EXPORT
void pw_init(int *argc, char **argv[])
{const char *str;struct spa_dict_item items[6];uint32_t n_items;struct spa_dict info;struct support *support = &global_support;struct spa_log *log;char level[32];pthread_mutex_lock(&init_lock);if (support->initialized)goto done;pthread_mutex_lock(&support_lock);support->in_valgrind = RUNNING_ON_VALGRIND;if (getenv("NO_COLOR") != NULL)support->no_color = true;if ((str = getenv("PIPEWIRE_NO_CONFIG")) != NULL)support->no_config = pw_properties_parse_bool(str);init_i18n(support);if ((str = getenv("SPA_PLUGIN_DIR")) == NULL)str = PLUGINDIR;support->plugin_dir = str;if ((str = getenv("SPA_SUPPORT_LIB")) == NULL)str = SUPPORTLIB;support->support_lib = str;spa_list_init(&support->registry.plugins);if (pw_log_is_default()) {char *patterns = NULL;n_items = 0;if (!support->no_color)items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_LOG_COLORS, "true");items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_LOG_TIMESTAMP, "true");if ((str = getenv("PIPEWIRE_LOG_LINE")) == NULL || spa_atob(str))items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_LOG_LINE, "true");snprintf(level, sizeof(level), "%d", pw_log_level);items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_LOG_LEVEL, level);if ((str = getenv("PIPEWIRE_LOG")) != NULL)items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_LOG_FILE, str);if ((patterns = parse_pw_debug_env()) != NULL)items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_LOG_PATTERNS, patterns);info = SPA_DICT_INIT(items, n_items);log = add_interface(support, SPA_NAME_SUPPORT_LOG, SPA_TYPE_INTERFACE_Log, &info);if (log)pw_log_set(log);#ifdef HAVE_SYSTEMDif ((str = getenv("PIPEWIRE_LOG_SYSTEMD")) == NULL || spa_atob(str)) {log = load_journal_logger(support, &info);if (log)pw_log_set(log);}
#endiffree(patterns);} else {support->support[support->n_support++] =SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_Log, pw_log_get());}pw_log_init();n_items = 0;if ((str = getenv("PIPEWIRE_CPU")))items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_CPU_FORCE, str);if ((str = getenv("PIPEWIRE_VM")))items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_CPU_VM_TYPE, str);info = SPA_DICT_INIT(items, n_items);add_interface(support, SPA_NAME_SUPPORT_CPU, SPA_TYPE_INTERFACE_CPU, &info);add_i18n(support);pw_log_info("version %s", pw_get_library_version());support->initialized = true;pthread_mutex_unlock(&support_lock);
done:pthread_mutex_unlock(&init_lock);
}

PipeWire 程序用 struct support 類型的全局對象 global_support 維護一些基本配置和功能組件,如插件目錄、支持庫路徑、i18n、日志等,以及所有加載的插件,其中所有加載的插件用 struct registry 對象維護,基本功能組件用 struct spa_support 數組維護。

pw_init() 函數初始化 global_support 對象,具體過程如下:

  1. 從環境變量 NO_COLOR、 **PIPEWIRE_NO_CONFIG ** 中獲取對應配置,初始化 i18n。從環境變量 SPA_PLUGIN_DIR 獲取插件目錄,失敗時使用默認目錄路徑,如 /usr/lib/aarch64-linux-gnu/spa-0.2。從環境變量 SPA_SUPPORT_LIB 獲取支持庫路徑,失敗時使用默認路徑 support/libspa-support。初始化 struct registry

  2. 初始化并添加日志組件。如果全局日志組件為默認日志組件,構造日志組件初始化時的配置參數,除了前面獲取的 no_color,還有如下這些配置參數:

    • 是否打印時間戳配置 log.timestamp,為 true
    • 從環境變量 **PIPEWIRE_LOG_LINE ** 中獲取的是否打印行號配置 log.line;
    • 打印的最低日志等級配置 log.level
    • 從環境變量 **PIPEWIRE_LOG ** 中獲取的是否打印文件配置 log.file
    • 從環境變量 PIPEWIRE_DEBUG 中獲取的日志模式配置log.patterns

    之后調用 add_interface() 函數從支持庫插件中加載日志組件,并設置全局日志組件為該日志組件。如果環境變量 PIPEWIRE_LOG_SYSTEMD 指示使用 systemd 日志,則調用 load_journal_logger() 函數加載 journal 日志組件替換 支持庫插件中加載的日志組件。
    如果全局日志組件不是默認日志組件,則向 global_support 添加全局日志組件為。
    最后,調用 pw_log_init() 函數基于新的全局日志組件,初始化各個日志 topic。
    日志是 PipeWire 配置的第一個組件。

  3. 初始化并添加 CPU 組件。從環境變量 PIPEWIRE_CPUPIPEWIRE_VM 獲取配置參數,調用 add_interface() 函數從支持庫插件中加載 CPU 組件。

  4. 添加 i18n 組件。

  5. 結束初始化。

global_supportstruct spa_support 數組中維護的這些組件,提供十分基礎的全局功能,可以在其它一般插件的實現中使用。全局支持組件主要包括日志、CPU 和 i18n。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/75213.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/75213.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/75213.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用卷積神經網絡識別MNIST數據集

卷積神經網絡 卷積神經網絡本質是共享權重稀疏鏈接的全連接網絡 編寫步驟 構建一個神經網絡&#xff0c;步驟是幾乎不變的&#xff0c;大概有以下幾步 準備數據集 #更高級的CNN網絡 import torch import torch.nn as nn import torch.nn.functional as F import torchvisi…

力扣125.驗證回文串

如果在將所有大寫字符轉換為小寫字符、并移除所有非字母數字字符之后&#xff0c;短語正著讀和反著讀都一樣。則可以認為該短語是一個 回文串 。 字母和數字都屬于字母數字字符。 給你一個字符串 s&#xff0c;如果它是 回文串 &#xff0c;返回 true &#xff1b;否則&#…

UR機械臂sim2real推薦包

推薦一個和ur機械臂配套的interface&#xff1a; ur_rtde Universal Robots RTDE C Interface — ur_rtde 1.6.0 documentation 也歡迎大家提供新想法和bug

CST學習筆記(三)MATLAB與CST聯合仿真-遠場數據批量導出

CST學習筆記&#xff08;三&#xff09;MATLAB與CST聯合仿真-遠場數據批量導出 一、直接數據導出 &#xff08;1&#xff09;打開遠場&#xff0c;調至笛卡爾坐標系 &#xff08;2&#xff09;然后點擊post processing → Import/Export → Plot Data (ASCII) &#xff0c;即…

藍橋杯---BFS解決FloofFill算法1---圖像渲染

文章目錄 1.算法簡介2.題目概述3.算法原理4.代碼分析 1.算法簡介 這個算法是關于我們的floodfill的相關的問題&#xff0c;這個算法其實從名字就可以看出來&#xff1a;洪水灌溉&#xff0c;其實這個算法的過程就和他的名字非常相似&#xff0c;下面的這個圖就生動的展示了這個…

我與數學建模之啟程

下面的時間線就是從我的大二上開始 9月開學就迎來了本科階段最重要的數學建模競賽——國賽&#xff0c;這個比賽一般是在9月的第二周開始。 2021年國賽是我第一次參加國賽&#xff0c;在報名前我還在糾結隊友&#xff0c;后來經學長推薦找了另外兩個學長。其實第一次國賽沒啥…

利用 SSRF 和 Redis 未授權訪問進行內網滲透

目錄 環境搭建 ?編輯 發現內網存活主機 ?編輯 掃描內網端口 ?編輯 利用 Redis 未授權訪問進行 Webshell 寫入 步驟1&#xff1a;生成 payload 方式1&#xff1a;使用python生成 payload 方式二&#xff1a;使用 Gopher 工具 步驟 2&#xff1a;寫入 Webshell&#xf…

【Vue2插槽】

Vue2插槽 Vue2插槽默認插槽子組件代碼&#xff08;Child.vue&#xff09;父組件代碼&#xff08;Parent.vue&#xff09; 命名插槽子組件代碼&#xff08;ChildNamed.vue&#xff09;父組件代碼&#xff08;ParentNamed.vue&#xff09; 代碼解釋 Vue2插槽 Vue2插槽 下面為你詳…

ORB-SLAM學習感悟記錄

orb特征點的旋轉不變性 利用灰度質心法求出的質心后&#xff0c;與形心連線所形成的角度如下圖所示&#xff1a; 這里容易對上圖進行誤解&#xff1a; 為了保證旋轉不變性&#xff0c;這里注意ORB-slam是利用這個角度旋轉坐標系&#xff0c;以新坐標系為標準從圖像中采點進行…

搜索算法------深度優先搜索

1. 介紹 深度優先搜索&#xff08;Depth-First Search&#xff0c;DFS&#xff09;是一種用于遍歷或搜索樹或圖的算法。這種算法通過盡可能深地搜索圖的分支來探索解決方案空間&#xff0c;直到達到一個沒有分支的點&#xff0c;然后回溯 1.1 原理 選擇起始點&#xff1a;從…

4.2 單相機引導機器人放料-僅考慮角度變化

【案例說明】 本案例產品在托盤中,角度變化不大(<15度);抓取沒有問題,只是放的穴位只能容許3度的角度偏差,因此需要測量產品的角度。 思路是:機器人抓料后、去固定拍照位拍照(找到與標準照片的角度偏差),機器人在放料的位置上多旋轉這個角度偏差,把產品放進去。 …

六級詞匯量積累day13

commend 表揚 exhaust 耗盡&#xff0c;用盡 weary 疲憊的&#xff0c;勞累的 fatigue 疲憊&#xff0c;勞累 obese 臃腫的&#xff0c;肥胖的 adopt 采納&#xff0c;收養 adapt 適應 accomplish 完成&#xff0c;實現 accomplishment 成就 achieve 實現&#xff0c;完成 achi…

醫院信息系統與AI賦能的介紹

隨著醫療行業的不斷發展&#xff0c;醫院信息系統&#xff08;HIS&#xff0c;Hospital Information System&#xff09;已經成為現代醫療服務不可或缺的一部分。醫院信息系統通過數字化、信息化手段&#xff0c;有效地整合了醫院內部的醫療、財務、后勤等各個業務環節&#xf…

突發,國行 iPhone 17,支持 eSIM

古人云“無心生大用”&#xff0c;往往你感到絕望的時候&#xff0c;轉機就莫名其妙的來了。 根據供應鏈的最新消息&#xff0c;國行 iPhone 17 Air&#xff0c;有望用上 eSIM。 不僅如此&#xff0c;國產手機廠商&#xff0c;也計劃推出類似iPhone 17 Air的超薄機型&#xf…

【C++項目】從零實現RPC框架「三」:項?抽象層實現

?? 個人主頁:Zfox_ ?? 系列專欄:C++從入門到精通 目錄 一:?? 常?的零碎功能接?類實現?? 簡單?志宏實現?? Json 序列化/反序列化?? UUID ?成二:?? 項?消息類型字段信息定義 ?? 請求字段宏定義?? 消息類型定義?? 響應碼類型定義?? RPC 請求類型定…

Hadoop集群常用指令詳解

在大數據處理領域&#xff0c;Hadoop作為分布式計算和存儲的開源框架&#xff0c;已經成為不可或缺的工具。掌握Hadoop集群的常用指令對于集群的日常管理和操作至關重要。本文將詳細介紹Hadoop集群的常用指令&#xff0c;幫助讀者更好地理解和使用Hadoop。 一、Hadoop集群的啟…

幾種常見的.NET單元測試模擬框架介紹

目錄 1. Moq 2. NSubstitute 3. AutoFixture 4. FakeItEasy 總結對比 單元測試模擬框架是一種在軟件開發中用于輔助單元測試的工具。 它的主要作用是創建模擬對象來替代真實對象進行測試。在單元測試中&#xff0c;被測試的代碼可能依賴于其他組件或服務&#xff0c;如數…

藍橋杯備賽之枚舉

用循環等方式依次去枚舉所有的數字組合&#xff0c;一一驗證是否符合題目的要求 題目鏈接 0好數 - 藍橋云課 題目解析 好數的概念: 數的奇數位位奇數,偶數位為偶數,就是一個好數 求輸入n里面有多少個好數 題目原理 1> 遍歷每個數 2> 每次遍歷判斷是不是好數 把這…

9、tlm 事務交互通信

1、TLM&#xff08;Transaction-Level Modeling&#xff09; 是 SystemC 的高級建模方法&#xff0c;用于描述系統的通信行為&#xff0c;特別是在硬件設計和驗證中。TLM 是 SystemC 的一部分&#xff0c;用于提高仿真的效率和抽象性。以下是 TLM 的核心知識以及關鍵概念。 2、…

小白入門機器學習概述

文章目錄 一、引言二、機器學習的基礎概念1. 機器學習的定義2. 機器學習的類型&#xff08;1&#xff09;監督學習&#xff08;Supervised Learning&#xff09;&#xff08;2&#xff09;無監督學習&#xff08;Unsupervised Learning&#xff09;&#xff08;3&#xff09;半…