Skip to content

Commit 6412fec

Browse files
committed
Improve pipewire members naming and deinitialization
1 parent ab3c72e commit 6412fec

2 files changed

Lines changed: 81 additions & 42 deletions

File tree

src/soundio/pipewireenumerator.cpp

Lines changed: 72 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ static std::optional<uint32_t> getPortIndexFromName(const char* name) {
6868

6969
PipewireEnumerator::PipewireEnumerator(UserSettingsPointer, SoundManager* pManager)
7070
: m_pSoundManager(pManager),
71+
m_pPwThreadLoop(nullptr),
72+
m_pPwContext(nullptr),
73+
m_pPwCore(nullptr),
74+
m_pPwRegistry(nullptr),
75+
m_pPwMetadata(nullptr),
76+
m_pPwFilter(nullptr),
7177
m_soundDevices(std::make_shared<SoundDeviceMap>()),
7278
m_openedDevices(std::make_shared<DeviceMap>()),
7379
m_initialized(false),
@@ -77,34 +83,72 @@ PipewireEnumerator::PipewireEnumerator(UserSettingsPointer, SoundManager* pManag
7783

7884
pw_init(nullptr, nullptr);
7985

80-
m_pThreadLoop = pw_thread_loop_new("mixxx_loop", nullptr);
81-
m_pContext = pw_context_new(pw_thread_loop_get_loop(m_pThreadLoop), nullptr, 0);
86+
m_pPwThreadLoop = pw_thread_loop_new("mixxx_loop", nullptr);
87+
spa_zero(m_pwRegistryListener);
88+
spa_zero(m_pwMetadataListener);
89+
spa_zero(m_pwFilterListener);
8290
}
8391

8492
PipewireEnumerator::~PipewireEnumerator() {
85-
pw_thread_loop_stop(m_pThreadLoop);
86-
spa_hook_remove(&m_registryListener);
87-
spa_hook_remove(&m_metadataListener);
88-
pw_proxy_destroy((struct pw_proxy*)m_pRegistry);
89-
pw_proxy_destroy((struct pw_proxy*)m_pMetadata);
90-
pw_core_disconnect(m_pCore);
91-
pw_context_destroy(m_pContext);
92-
pw_thread_loop_destroy(m_pThreadLoop);
93+
pw_thread_loop_stop(m_pPwThreadLoop);
94+
95+
if (m_pPwFilter) {
96+
pw_filter_destroy(m_pPwFilter);
97+
}
98+
99+
if (m_pPwMetadata) {
100+
spa_hook_remove(&m_pwMetadataListener);
101+
pw_proxy_destroy((struct pw_proxy*)m_pPwMetadata);
102+
}
103+
104+
if (m_pPwRegistry) {
105+
spa_hook_remove(&m_pwRegistryListener);
106+
pw_proxy_destroy((struct pw_proxy*)m_pPwRegistry);
107+
}
108+
109+
if (m_pPwCore) {
110+
pw_core_disconnect(m_pPwCore);
111+
}
112+
113+
if (m_pPwContext) {
114+
pw_context_destroy(m_pPwContext);
115+
}
116+
117+
pw_thread_loop_destroy(m_pPwThreadLoop);
93118
pw_deinit();
94119
}
95120

96121
void PipewireEnumerator::initialize() {
97-
m_pCore = pw_context_connect(m_pContext, nullptr, 0);
122+
if (m_initialized) {
123+
qWarning() << "PipewireEnumerator::initialize already initialized";
124+
return;
125+
}
98126

99-
if (!m_pCore) {
127+
if (!m_pPwContext) {
128+
m_pPwContext = pw_context_new(pw_thread_loop_get_loop(m_pPwThreadLoop), nullptr, 0);
129+
if (!m_pPwContext) {
130+
qWarning() << "PipewireEnumerator::initialize pw_context_new "
131+
"failed with error:"
132+
<< spa_strerror(errno);
133+
return;
134+
}
135+
}
136+
137+
m_pPwCore = pw_context_connect(m_pPwContext, nullptr, 0);
138+
139+
if (!m_pPwCore) {
140+
qWarning() << "PipewireEnumerator::initialize pw_context_connect "
141+
"failed with error:"
142+
<< spa_strerror(errno);
100143
return;
101144
}
102145

103-
m_pRegistry = pw_core_get_registry(m_pCore, PW_VERSION_REGISTRY, 0);
146+
m_pPwRegistry = pw_core_get_registry(m_pPwCore, PW_VERSION_REGISTRY, 0);
147+
pw_registry_add_listener(m_pPwRegistry, &m_pwRegistryListener, &registry_events, this);
104148

105149
// see https://docs.pipewire.org/page_man_pipewire-props_7.html
106150
// and pipewire/keys.h header
107-
m_pFilter = pw_filter_new(m_pCore,
151+
m_pPwFilter = pw_filter_new(m_pPwCore,
108152
"mixxx",
109153
pw_properties_new(PW_KEY_MEDIA_NAME,
110154
"Mixxx",
@@ -122,14 +166,9 @@ void PipewireEnumerator::initialize() {
122166
"Mixxx",
123167
nullptr));
124168

125-
spa_zero(m_registryListener);
126-
spa_zero(m_metadataListener);
127-
spa_zero(m_filterListener);
128-
129-
pw_registry_add_listener(m_pRegistry, &m_registryListener, &registry_events, this);
130-
pw_filter_add_listener(m_pFilter, &m_filterListener, &filter_events, this);
169+
pw_filter_add_listener(m_pPwFilter, &m_pwFilterListener, &filter_events, this);
131170

132-
int res = pw_filter_connect(m_pFilter,
171+
int res = pw_filter_connect(m_pPwFilter,
133172
PW_FILTER_FLAG_RT_PROCESS,
134173
nullptr,
135174
0);
@@ -138,7 +177,7 @@ void PipewireEnumerator::initialize() {
138177
qWarning() << "pw_filter_connect error:" << spa_strerror(res);
139178
}
140179

141-
pw_thread_loop_start(m_pThreadLoop);
180+
pw_thread_loop_start(m_pPwThreadLoop);
142181

143182
m_initialized = true;
144183
}
@@ -158,13 +197,13 @@ void PipewireEnumerator::registryEventGlobal(uint32_t id,
158197
return;
159198
}
160199

161-
void* data = pw_registry_bind(m_pRegistry,
200+
void* data = pw_registry_bind(m_pPwRegistry,
162201
id,
163202
PW_TYPE_INTERFACE_Metadata,
164203
PW_VERSION_METADATA,
165204
0);
166-
m_pMetadata = static_cast<pw_metadata*>(data);
167-
pw_metadata_add_listener(m_pMetadata, &m_metadataListener, &metadataEvents, this);
205+
m_pPwMetadata = static_cast<pw_metadata*>(data);
206+
pw_metadata_add_listener(m_pPwMetadata, &m_pwMetadataListener, &metadataEvents, this);
168207
} else if (strcmp(pType, PW_TYPE_INTERFACE_Node) == 0) {
169208
const char* media_class = spa_dict_lookup(pProps, PW_KEY_MEDIA_CLASS);
170209
const char* media_type = spa_dict_lookup(pProps, PW_KEY_MEDIA_TYPE);
@@ -346,7 +385,7 @@ void PipewireEnumerator::openDevice(uint32_t id,
346385
return;
347386
}
348387

349-
pw_thread_loop_lock(m_pThreadLoop);
388+
pw_thread_loop_lock(m_pPwThreadLoop);
350389

351390
if (rate != m_sampleRate.value() || framesPerBuffer != m_framesPerBuffer) {
352391
std::string rateStr = "1/" + std::to_string(rate);
@@ -358,7 +397,7 @@ void PipewireEnumerator::openDevice(uint32_t id,
358397
};
359398
spa_dict properties = SPA_DICT_INIT(items, 2);
360399

361-
int res = pw_filter_update_properties(m_pFilter, nullptr, &properties);
400+
int res = pw_filter_update_properties(m_pPwFilter, nullptr, &properties);
362401
if (res >= 0) {
363402
m_sampleRate = mixxx::audio::SampleRate(rate);
364403
m_framesPerBuffer = framesPerBuffer;
@@ -387,7 +426,7 @@ void PipewireEnumerator::openDevice(uint32_t id,
387426
"32 bit float mono audio",
388427
nullptr);
389428
pw_properties_setf(props, PW_KEY_PORT_NAME, "in:%zu", filterPortIndex);
390-
void* port_data = pw_filter_add_port(m_pFilter,
429+
void* port_data = pw_filter_add_port(m_ppwFilter,
391430
SPA_DIRECTION_INPUT,
392431
PW_FILTER_PORT_FLAG_MAP_BUFFERS,
393432
0,
@@ -404,7 +443,7 @@ void PipewireEnumerator::openDevice(uint32_t id,
404443
pw_properties* props = pw_properties_new(
405444
PW_KEY_FORMAT_DSP, "32 bit float mono audio", nullptr);
406445
pw_properties_setf(props, PW_KEY_PORT_NAME, "out:%zu", filterPortIndex);
407-
void* port_data = pw_filter_add_port(m_pFilter,
446+
void* port_data = pw_filter_add_port(m_ppwFilter,
408447
SPA_DIRECTION_OUTPUT,
409448
PW_FILTER_PORT_FLAG_MAP_BUFFERS,
410449
0,
@@ -413,7 +452,7 @@ void PipewireEnumerator::openDevice(uint32_t id,
413452
0);
414453
outputs.emplace_back(port_data, i, filterPortIndex);
415454
}
416-
pw_thread_loop_unlock(m_pThreadLoop);
455+
pw_thread_loop_unlock(m_pPwThreadLoop);
417456

418457
pOpenedDevices->emplace(id, Device{std::move(inputs), std::move(outputs)});
419458
m_openedDevices.store(pOpenedDevices);
@@ -434,15 +473,15 @@ void PipewireEnumerator::closeDevice(uint32_t id) {
434473

435474
auto& device = pOpenedDevices->at(id);
436475

437-
pw_thread_loop_lock(m_pThreadLoop);
476+
pw_thread_loop_lock(m_pPwThreadLoop);
438477
for (auto& port : device.inputs) {
439478
pw_filter_remove_port(port.pPortData);
440479
}
441480

442481
for (auto& port : device.outputs) {
443482
pw_filter_remove_port(port.pPortData);
444483
}
445-
pw_thread_loop_unlock(m_pThreadLoop);
484+
pw_thread_loop_unlock(m_pPwThreadLoop);
446485

447486
pOpenedDevices->erase(id);
448487
m_openedDevices.store(pOpenedDevices);
@@ -533,7 +572,7 @@ void PipewireEnumerator::createLink(uint32_t outNodeId,
533572
items[props.n_items++] = SPA_DICT_ITEM_INIT(PW_KEY_LINK_INPUT_PORT, strInPort.c_str());
534573
items[props.n_items++] = SPA_DICT_ITEM_INIT(PW_KEY_OBJECT_LINGER, "true");
535574

536-
struct pw_proxy* pProxy = static_cast<pw_proxy*>(pw_core_create_object(m_pCore,
575+
struct pw_proxy* pProxy = static_cast<pw_proxy*>(pw_core_create_object(m_pPwCore,
537576
"link-factory",
538577
PW_TYPE_INTERFACE_Link,
539578
PW_VERSION_LINK,

src/soundio/pipewireenumerator.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -127,15 +127,15 @@ class PipewireEnumerator : public SoundDeviceEnumerator {
127127
SoundManager* m_pSoundManager;
128128
UserSettingsPointer m_pConfig;
129129

130-
pw_core* m_pCore;
131-
pw_registry* m_pRegistry;
132-
pw_context* m_pContext;
133-
pw_metadata* m_pMetadata;
134-
pw_thread_loop* m_pThreadLoop;
135-
spa_hook m_registryListener;
136-
spa_hook m_metadataListener;
137-
spa_hook m_filterListener;
138-
pw_filter* m_pFilter;
130+
pw_thread_loop* m_pPwThreadLoop;
131+
pw_context* m_pPwContext;
132+
pw_core* m_pPwCore;
133+
pw_registry* m_pPwRegistry;
134+
pw_metadata* m_pPwMetadata;
135+
pw_filter* m_pPwFilter;
136+
spa_hook m_pwRegistryListener;
137+
spa_hook m_pwFilterListener;
138+
spa_hook m_pwMetadataListener;
139139

140140
struct Device {
141141
struct Port {

0 commit comments

Comments
 (0)