Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qpipewire_async_support.cpp
Go to the documentation of this file.
1
// Copyright (C) 2025 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4
#
include
"qpipewire_async_support_p.h"
5
6
#
include
<
QtMultimedia
/
private
/
qpipewire_instance_p
.
h
>
7
8
QT_BEGIN_NAMESPACE
9
10
namespace
QtPipeWire
{
11
12
namespace
{
13
14
template
<
typename
Closure>
15
auto
runWithEventLoopLock(Closure &&closure)
16
{
17
auto
instance = QPipeWireInstance::instance();
18
if
(instance)
19
return
instance->runWithEventLoopLock(
std
::forward<Closure>(closure));
20
else
21
return
closure();
22
}
23
24
}
// namespace
25
26
// SpaListenerBase
27
28
static
std
::
atomic_int
s_sequenceNumberAllocator
;
29
30
SpaListenerBase
::
SpaListenerBase
()
31
:
m_sequenceNumber
(s_sequenceNumberAllocator.fetch_add(1, std::memory_order_relaxed))
32
{
33
}
34
35
void
SpaListenerBase
::
removeHooks
()
36
{
37
spa_hook_remove(&
m_listenerHook
);
38
}
39
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41
42
// NodeEventListener
43
44
NodeEventListener
::
NodeEventListener
(PwNodeHandle node,
NodeHandler
handler)
45
:
m_node
(
std
::
move
(
node
)),
m_handler
(
std
::
move
(
handler
))
46
{
47
static
constexpr
struct
pw_node_events nodeEvents{
48
.version = PW_VERSION_NODE_EVENTS,
49
.info = NodeEventListener::onInfo,
50
.param = NodeEventListener::onParam,
51
};
52
53
int
status = pw_node_add_listener(m_node.get(), &m_listenerHook, &nodeEvents,
this
);
54
if
(status < 0)
55
qFatal() <<
"Failed to add listener: "
<< make_error_code(-status).message();
56
}
57
58
NodeEventListener
::~
NodeEventListener
()
59
{
60
removeHooks
();
61
runWithEventLoopLock([&] {
62
m_node = {};
63
});
64
}
65
66
void
NodeEventListener
::
enumParams
(spa_param_type type)
67
{
68
int
status = pw_node_enum_params(m_node.get(), m_sequenceNumber, type, 0, 0,
nullptr
);
69
if
(status < 0)
70
qCritical() <<
"pw_node_enum_params failed:"
<< make_error_code(-status).message();
71
}
72
73
void
NodeEventListener
::onInfo(
void
*data,
const
pw_node_info *info)
74
{
75
NodeEventListener
*self =
reinterpret_cast
<
NodeEventListener
*>(data);
76
if
(self->m_handler.infoHandler)
77
self->m_handler.infoHandler(info);
78
}
79
80
void
NodeEventListener
::onParam(
void
*data,
int
seq, uint32_t id, uint32_t index, uint32_t next,
81
const
spa_pod *param)
82
{
83
NodeEventListener
*self =
reinterpret_cast
<
NodeEventListener
*>(data);
84
if
(self->m_handler.paramHandler)
85
self->m_handler.paramHandler(seq, id, index, next, param);
86
}
87
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89
90
// CoreEventListener
91
92
CoreEventListener
::
CoreEventListener
()
93
{
94
coreEvents.version = PW_VERSION_CORE_EVENTS;
95
}
96
97
CoreEventListener
::~
CoreEventListener
()
98
{
99
runWithEventLoopLock([&] {
100
removeHooks
();
101
});
102
}
103
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105
106
// CoreEventDoneListener
107
108
CoreEventDoneListener
::
CoreEventDoneListener
()
109
{
110
coreEvents.done = [](
void
*self, uint32_t id,
int
seq) {
111
Q_ASSERT(QPipeWireInstance::instance()->isInPwThreadLoop());
112
CoreEventDoneListener *listener =
reinterpret_cast
<CoreEventDoneListener *>(self);
113
if
(id == PW_ID_CORE && listener->m_seqnum == seq) {
114
listener->m_seqnum = -1;
115
if
(
auto
handler = std::exchange(listener->m_handler, {}))
116
handler();
117
}
118
};
119
}
120
121
q23
::
expected
<
void
,
int
>
CoreEventDoneListener
::
asyncWait
(pw_core *coreConnection,
122
std
::function<
void
()> handler)
123
{
124
m_handler = std::move(handler);
125
126
return
runWithEventLoopLock([&]() -> q23::expected<
void
,
int
> {
127
int
status = pw_core_add_listener(coreConnection, &m_listenerHook, &coreEvents,
this
);
128
if
(status < 0) {
129
qFatal() <<
"pw_core_add_listener failed"
<< make_error_code(-status).message();
130
return
q23::unexpected(status);
131
}
132
133
Q_ASSERT(m_seqnum == -1);
134
status = pw_core_sync(coreConnection, PW_ID_CORE, 0);
135
if
(status < 0)
136
return
q23::unexpected(status);
137
m_seqnum = status;
138
return
{};
139
});
140
}
141
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143
144
CoreEventSyncHelper
::
CoreEventSyncHelper
() =
default
;
145
146
q23::expected<
bool
,
int
>
CoreEventSyncHelper
::sync(
pw_core
*
coreConnection
,
147
std
::
optional
<
std
::
chrono
::
nanoseconds
>
timeout
)
148
{
149
auto
voidOrError
=
CoreEventDoneListener
::
asyncWait
(
coreConnection
, [&] {
150
m_semaphore
.
release
();
151
});
152
if
(
voidOrError
) {
153
if
(
timeout
)
154
return
m_semaphore
.
try_acquire_for
(*
timeout
);
155
156
m_semaphore
.
acquire
();
157
return
true
;
158
}
159
return
voidOrError
.
error
();
160
}
161
162
}
// namespace QtPipeWire
163
164
QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
QtPipeWire
Definition
qpipewire_async_support.cpp:10
QtPipeWire::s_sequenceNumberAllocator
static std::atomic_int s_sequenceNumberAllocator
Definition
qpipewire_async_support.cpp:28
std
[33]
Definition
src_corelib_tools_qhash.cpp:421
QtPipeWire::CoreEventDoneListener
Definition
qpipewire_async_support_p.h:81
QtPipeWire::CoreEventDoneListener::asyncWait
q23::expected< void, int > asyncWait(pw_core *coreConnection, std::function< void()> handler)
Definition
qpipewire_async_support.cpp:121
QtPipeWire::CoreEventDoneListener::CoreEventDoneListener
CoreEventDoneListener()
Definition
qpipewire_async_support.cpp:108
QtPipeWire::CoreEventListener
Definition
qpipewire_async_support_p.h:72
QtPipeWire::CoreEventListener::~CoreEventListener
~CoreEventListener()
Definition
qpipewire_async_support.cpp:97
QtPipeWire::CoreEventListener::CoreEventListener
CoreEventListener()
Definition
qpipewire_async_support.cpp:92
QtPipeWire::CoreEventSyncHelper
Definition
qpipewire_async_support_p.h:91
QtPipeWire::CoreEventSyncHelper::CoreEventSyncHelper
CoreEventSyncHelper()
QtPipeWire::NodeEventListener::NodeHandler
Definition
qpipewire_async_support_p.h:52
QtPipeWire::NodeEventListener::NodeEventListener
NodeEventListener(PwNodeHandle, NodeHandler)
Definition
qpipewire_async_support.cpp:44
QtPipeWire::NodeEventListener::InfoHandler
std::function< void(const struct pw_node_info *)> InfoHandler
Definition
qpipewire_async_support_p.h:47
QtPipeWire::NodeEventListener::~NodeEventListener
~NodeEventListener()
Definition
qpipewire_async_support.cpp:58
QtPipeWire::NodeEventListener::enumParams
void enumParams(spa_param_type)
Definition
qpipewire_async_support.cpp:66
QtPipeWire::SpaListenerBase
Definition
qpipewire_async_support_p.h:32
QtPipeWire::SpaListenerBase::SpaListenerBase
SpaListenerBase()
Definition
qpipewire_async_support.cpp:30
QtPipeWire::SpaListenerBase::removeHooks
void removeHooks()
Definition
qpipewire_async_support.cpp:35
QtPipeWire::SpaListenerBase::m_listenerHook
spa_hook m_listenerHook
Definition
qpipewire_async_support_p.h:42
QtPipeWire::SpaListenerBase::m_sequenceNumber
int m_sequenceNumber
Definition
qpipewire_async_support_p.h:41
qtmultimedia
src
multimedia
pipewire
qpipewire_async_support.cpp
Generated on
for Qt by
1.18.0