aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Härer <markus.haerer@gmx.net>2024-04-26 18:20:29 +0200
committerGitHub <noreply@github.com>2024-04-26 18:20:29 +0200
commit85519a64d77b754d100a0e498c1d65e19a4a549b (patch)
treec154fc5e4e63a7fb4dc731052c23d590ca6af77a
parent4ee6643c16e8a92f494a41b592123ec926ad2216 (diff)
parent6cad37352412345c3d1868b97a4a8a19fe4769c0 (diff)
downloadxbmc-85519a64d77b754d100a0e498c1d65e19a4a549b.tar.xz
Merge pull request #25043 from neo1973/pipewire_pulse
[AudioEngine] Make a smarter choice between PulseAudio and PipeWire
-rw-r--r--xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp54
-rw-r--r--xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h2
-rw-r--r--xbmc/platform/freebsd/PlatformFreebsd.cpp6
-rw-r--r--xbmc/platform/linux/OptionalsReg.cpp6
-rw-r--r--xbmc/platform/linux/OptionalsReg.h2
-rw-r--r--xbmc/platform/linux/PlatformLinux.cpp8
6 files changed, 62 insertions, 16 deletions
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp
index c6763bae13..5ec64fe9f0 100644
--- a/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp
+++ b/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp
@@ -19,6 +19,9 @@
#include <memory>
#include <mutex>
+#include <pulse/context.h>
+#include <pulse/introspect.h>
+
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
@@ -27,7 +30,7 @@ class CDriverMonitor
public:
CDriverMonitor() = default;
virtual ~CDriverMonitor();
- bool Start();
+ bool Start(bool allowPipeWireCompatServer);
bool IsInitialized();
CCriticalSection m_sec;
@@ -315,6 +318,21 @@ static void SinkChangedCallback(pa_context *c, pa_subscription_event_type_t t, u
}
}
+struct ServerInfoStruct
+{
+ pa_threaded_mainloop* m_mainloop;
+ bool m_isInfoSet{false};
+ std::string m_serverName;
+};
+
+static void ServerInfoCallback(pa_context* c, const pa_server_info* i, void* userdata)
+{
+ auto serverInfo = reinterpret_cast<ServerInfoStruct*>(userdata);
+ serverInfo->m_serverName = i->server_name;
+ serverInfo->m_isInfoSet = true;
+ pa_threaded_mainloop_signal(serverInfo->m_mainloop, 0);
+}
+
struct SinkInfoStruct
{
AEDeviceInfoList *list;
@@ -656,7 +674,7 @@ bool CDriverMonitor::IsInitialized()
return m_isInit;
}
-bool CDriverMonitor::Start()
+bool CDriverMonitor::Start(bool allowPipeWireCompatServer)
{
if (!SetupContext(nullptr, "KodiDriver", &m_pContext, &m_pMainLoop))
{
@@ -666,6 +684,30 @@ bool CDriverMonitor::Start()
pa_threaded_mainloop_lock(m_pMainLoop);
+ ServerInfoStruct serverInfo;
+ serverInfo.m_mainloop = m_pMainLoop;
+ pa_context_get_server_info(m_pContext, ServerInfoCallback, &serverInfo);
+ while (!serverInfo.m_isInfoSet)
+ pa_threaded_mainloop_wait(m_pMainLoop);
+
+ CLog::Log(LOGINFO, "PulseAudio: Server name: {}", serverInfo.m_serverName);
+
+#ifdef HAS_PIPEWIRE
+ // If Kodi is build with PipeWire support we prefer native PipeWire over the
+ // PulseAudio compatibility layer IF NOT PulseAudio is explicitly selected
+ if (!allowPipeWireCompatServer)
+ {
+ // Check the PulseAudio server name. If it contains PipeWire in any form
+ // it is the compatibility layer provided by PipeWire
+ if (StringUtils::Contains(serverInfo.m_serverName, "pipewire", true))
+ {
+ CLog::Log(LOGINFO, "PulseAudio: Server is PipeWire, bail and use native PipeWire interface");
+ pa_threaded_mainloop_unlock(m_pMainLoop);
+ return false;
+ }
+ }
+#endif
+
m_isInit = true;
std::unique_lock<CCriticalSection> lock(m_sec);
@@ -687,7 +729,7 @@ bool CDriverMonitor::Start()
std::unique_ptr<CDriverMonitor> CAESinkPULSE::m_pMonitor;
-bool CAESinkPULSE::Register()
+bool CAESinkPULSE::Register(bool allowPipeWireCompatServer)
{
// check if pulseaudio is actually available
pa_simple *s;
@@ -708,7 +750,11 @@ bool CAESinkPULSE::Register()
}
m_pMonitor = std::make_unique<CDriverMonitor>();
- m_pMonitor->Start();
+ if (!m_pMonitor->Start(allowPipeWireCompatServer))
+ {
+ m_pMonitor.reset();
+ return false;
+ }
AE::AESinkRegEntry entry;
entry.sinkName = "PULSE";
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h b/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h
index 3606a0b4f5..48f73f9a10 100644
--- a/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h
+++ b/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h
@@ -31,7 +31,7 @@ public:
CAESinkPULSE();
~CAESinkPULSE() override;
- static bool Register();
+ static bool Register(bool allowPipeWireCompatServer);
static std::unique_ptr<IAESink> Create(std::string& device, AEAudioFormat& desiredFormat);
static void EnumerateDevicesEx(AEDeviceInfoList &list, bool force = false);
static void Cleanup();
diff --git a/xbmc/platform/freebsd/PlatformFreebsd.cpp b/xbmc/platform/freebsd/PlatformFreebsd.cpp
index c949a339cb..6ab3f46ed2 100644
--- a/xbmc/platform/freebsd/PlatformFreebsd.cpp
+++ b/xbmc/platform/freebsd/PlatformFreebsd.cpp
@@ -89,7 +89,7 @@ bool CPlatformFreebsd::InitStageOne()
}
else if (sink == "pulseaudio")
{
- OPTIONALS::PulseAudioRegister();
+ OPTIONALS::PulseAudioRegister(true);
}
else if (sink == "oss")
{
@@ -102,11 +102,11 @@ bool CPlatformFreebsd::InitStageOne()
else if (sink == "alsa+pulseaudio")
{
OPTIONALS::ALSARegister();
- OPTIONALS::PulseAudioRegister();
+ OPTIONALS::PulseAudioRegister(true);
}
else
{
- if (!OPTIONALS::PulseAudioRegister())
+ if (!OPTIONALS::PulseAudioRegister(false))
{
if (!OPTIONALS::ALSARegister())
{
diff --git a/xbmc/platform/linux/OptionalsReg.cpp b/xbmc/platform/linux/OptionalsReg.cpp
index 82fb176d1d..3992f2a0d0 100644
--- a/xbmc/platform/linux/OptionalsReg.cpp
+++ b/xbmc/platform/linux/OptionalsReg.cpp
@@ -33,13 +33,13 @@ bool OPTIONALS::ALSARegister()
#ifdef HAS_PULSEAUDIO
#include "cores/AudioEngine/Sinks/AESinkPULSE.h"
-bool OPTIONALS::PulseAudioRegister()
+bool OPTIONALS::PulseAudioRegister(bool allowPipeWireCompatServer)
{
- bool ret = CAESinkPULSE::Register();
+ bool ret = CAESinkPULSE::Register(allowPipeWireCompatServer);
return ret;
}
#else
-bool OPTIONALS::PulseAudioRegister()
+bool OPTIONALS::PulseAudioRegister(bool)
{
return false;
}
diff --git a/xbmc/platform/linux/OptionalsReg.h b/xbmc/platform/linux/OptionalsReg.h
index 75fdb6ae62..3a777b7003 100644
--- a/xbmc/platform/linux/OptionalsReg.h
+++ b/xbmc/platform/linux/OptionalsReg.h
@@ -23,7 +23,7 @@ bool ALSARegister();
namespace OPTIONALS
{
-bool PulseAudioRegister();
+bool PulseAudioRegister(bool allowPipeWireCompatServer);
}
//-----------------------------------------------------------------------------
diff --git a/xbmc/platform/linux/PlatformLinux.cpp b/xbmc/platform/linux/PlatformLinux.cpp
index 6be5163883..e01f8216bf 100644
--- a/xbmc/platform/linux/PlatformLinux.cpp
+++ b/xbmc/platform/linux/PlatformLinux.cpp
@@ -101,7 +101,7 @@ bool CPlatformLinux::InitStageOne()
}
else if (sink == "pulseaudio")
{
- OPTIONALS::PulseAudioRegister();
+ OPTIONALS::PulseAudioRegister(true);
}
else if (sink == "pipewire")
{
@@ -114,13 +114,13 @@ bool CPlatformLinux::InitStageOne()
else if (sink == "alsa+pulseaudio")
{
OPTIONALS::ALSARegister();
- OPTIONALS::PulseAudioRegister();
+ OPTIONALS::PulseAudioRegister(true);
}
else
{
- if (!OPTIONALS::PipewireRegister())
+ if (!OPTIONALS::PulseAudioRegister(false))
{
- if (!OPTIONALS::PulseAudioRegister())
+ if (!OPTIONALS::PipewireRegister())
{
if (!OPTIONALS::ALSARegister())
{