8#include "pipewirecore_p.h"
10#include <KLocalizedString>
11#include <QSocketNotifier>
13#include <QThreadStorage>
15#include <spa/utils/result.h>
19using namespace Qt::StringLiterals;
21pw_core_events PipeWireCore::s_pwCoreEvents = {
22 .version = PW_VERSION_CORE_EVENTS,
23 .info = &PipeWireCore::onCoreInfo,
26 .error = &PipeWireCore::onCoreError,
30 .remove_mem =
nullptr,
33PipeWireCore::PipeWireCore()
35 static std::once_flag pwInitOnce;
36 std::call_once(pwInitOnce, [] { pw_init(
nullptr,
nullptr); });
39void PipeWireCore::onCoreError(
void *data, uint32_t
id,
int seq,
int res,
const char *message)
43 qCWarning(PIPEWIRE_LOGGING) <<
"PipeWire remote error: " << res << message;
44 if (
id == PW_ID_CORE) {
45 PipeWireCore *pw =
static_cast<PipeWireCore *
>(data);
51 Q_EMIT pw->pipeBroken();
52 spa_hook_remove(&pw->m_coreListener);
53 pw_core_disconnect(pw->m_pwCore);
60void PipeWireCore::onCoreInfo(
void *data,
const struct pw_core_info *info)
62 PipeWireCore *pw =
static_cast<PipeWireCore *
>(data);
66PipeWireCore::~PipeWireCore()
69 pw_loop_leave(m_pwMainLoop);
73 pw_core_disconnect(m_pwCore);
77 pw_context_destroy(m_pwContext);
81 pw_loop_destroy(m_pwMainLoop);
85bool PipeWireCore::init(
int fd)
87 m_pwMainLoop = pw_loop_new(
nullptr);
90 ki18n(
"Invalid PipeWire installation. See https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/3296 for more details.");
91 qCWarning(PIPEWIRE_LOGGING) <<
error.untranslatedText();
92 m_error =
error.toString();
95 pw_loop_enter(m_pwMainLoop);
99 int result = pw_loop_iterate(m_pwMainLoop, 0);
101 qCWarning(PIPEWIRE_LOGGING) <<
"pipewire_loop_iterate failed: " << spa_strerror(result);
104 m_pwContext = pw_context_new(m_pwMainLoop,
nullptr, 0);
106 qCWarning(PIPEWIRE_LOGGING) <<
"Failed to create PipeWire context";
107 m_error =
i18n(
"Failed to create PipeWire context");
116bool PipeWireCore::init_core()
119 m_pwCore = pw_context_connect_fd(m_pwContext, m_fd,
nullptr, 0);
121 m_pwCore = pw_context_connect(m_pwContext,
nullptr, 0);
124 m_error =
i18n(
"Failed to connect to PipeWire");
125 qCWarning(PIPEWIRE_LOGGING) <<
"error:" << m_error << m_fd;
129 if (pw_loop_iterate(m_pwMainLoop, 0) < 0) {
130 qCWarning(PIPEWIRE_LOGGING) <<
"Failed to start main PipeWire loop";
131 m_error =
i18n(
"Failed to start main PipeWire loop");
135 pw_core_add_listener(m_pwCore, &m_coreListener, &s_pwCoreEvents,
this);
144 ret.
reset(
new PipeWireCore);
152QString PipeWireCore::error()
const
KLocalizedString KI18N_EXPORT ki18n(const char *text)
QString i18n(const char *text, const TYPE &arg...)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
PHONON_EXPORT Notifier * notifier()
void activated(QSocketDescriptor socket, QSocketNotifier::Type type)
QString fromUtf8(QByteArrayView str)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QVersionNumber fromString(QAnyStringView string, qsizetype *suffixIndex)