From 8364aaadad73875cdc580d332432c50ff329bc60 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 5 Mar 2025 21:20:51 +0100 Subject: Fix pipewire server breaking when pipewire connection is closed too quickly (--info) --- include/pipewire_audio.h | 1 + src/pipewire_audio.c | 37 ++++++++++++++++++------------------- src/pipewire_video.c | 7 ++++--- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/include/pipewire_audio.h b/include/pipewire_audio.h index 1cf6666..10d8c9b 100644 --- a/include/pipewire_audio.h +++ b/include/pipewire_audio.h @@ -80,6 +80,7 @@ typedef struct { struct pw_proxy *metadata_proxy; struct spa_hook metadata_listener; + struct spa_hook metadata_proxy_listener; char default_output_device_name[128]; char default_input_device_name[128]; diff --git a/src/pipewire_audio.c b/src/pipewire_audio.c index 1ab9681..b289106 100644 --- a/src/pipewire_audio.c +++ b/src/pipewire_audio.c @@ -329,22 +329,20 @@ static const struct pw_metadata_events metadata_events = { static void on_metadata_proxy_removed_cb(void *data) { gsr_pipewire_audio *self = data; if(self->metadata_proxy) { - // TODO: - //pw_proxy_destroy(self->metadata_proxy); - //self->metadata_proxy = NULL; + pw_proxy_destroy(self->metadata_proxy); + self->metadata_proxy = NULL; } } static void on_metadata_proxy_destroy_cb(void *data) { gsr_pipewire_audio *self = data; - // TODO: - //spa_hook_remove(&metadata->metadata_listener); - //spa_hook_remove(&metadata->proxy_listener); - //spa_zero(metadata->metadata_listener); - //spa_zero(metadata->proxy_listener); + spa_hook_remove(&self->metadata_listener); + spa_hook_remove(&self->metadata_proxy_listener); + spa_zero(self->metadata_listener); + spa_zero(self->metadata_proxy_listener); - //self->metadata_proxy = NULL; + self->metadata_proxy = NULL; } static const struct pw_proxy_events metadata_proxy_events = { @@ -365,11 +363,8 @@ static bool gsr_pipewire_audio_listen_on_metadata(gsr_pipewire_audio *self, uint return false; } - // TODO: - pw_metadata_add_listener((struct pw_metadata*)self->metadata_proxy, &self->metadata_listener, &metadata_events, self); - - //struct spa_hook proxy_listener; - //pw_proxy_add_listener(self->metadata_proxy, &proxy_listener, &metadata_proxy_events, self); + pw_proxy_add_object_listener(self->metadata_proxy, &self->metadata_listener, &metadata_events, self); + pw_proxy_add_listener(self->metadata_proxy, &self->metadata_proxy_listener, &metadata_proxy_events, self); return true; } @@ -549,15 +544,14 @@ bool gsr_pipewire_audio_init(gsr_pipewire_audio *self) { pw_context_load_module(self->context, "libpipewire-module-link-factory", NULL, NULL); - pw_thread_loop_lock(self->thread_loop); - if(pw_thread_loop_start(self->thread_loop) < 0) { fprintf(stderr, "gsr error: gsr_pipewire_audio_init: failed to start thread\n"); - pw_thread_loop_unlock(self->thread_loop); gsr_pipewire_audio_deinit(self); return false; } + pw_thread_loop_lock(self->thread_loop); + self->core = pw_context_connect(self->context, pw_properties_new(PW_KEY_REMOTE_NAME, NULL, NULL), 0); if(!self->core) { pw_thread_loop_unlock(self->thread_loop); @@ -568,11 +562,12 @@ bool gsr_pipewire_audio_init(gsr_pipewire_audio *self) { // TODO: Error check pw_core_add_listener(self->core, &self->core_listener, &core_events, self); + self->server_version_sync = pw_core_sync(self->core, PW_ID_CORE, 0); + pw_thread_loop_wait(self->thread_loop); + self->registry = pw_core_get_registry(self->core, PW_VERSION_REGISTRY, 0); pw_registry_add_listener(self->registry, &self->registry_listener, ®istry_events, self); - self->server_version_sync = pw_core_sync(self->core, PW_ID_CORE, 0); - pw_thread_loop_wait(self->thread_loop); pw_thread_loop_unlock(self->thread_loop); return true; } @@ -592,7 +587,11 @@ void gsr_pipewire_audio_deinit(gsr_pipewire_audio *self) { self->num_virtual_sink_proxies = 0; if(self->metadata_proxy) { + spa_hook_remove(&self->metadata_listener); + spa_hook_remove(&self->metadata_proxy_listener); pw_proxy_destroy(self->metadata_proxy); + spa_zero(self->metadata_listener); + spa_zero(self->metadata_proxy_listener); self->metadata_proxy = NULL; } diff --git a/src/pipewire_video.c b/src/pipewire_video.c index 023a2db..3f7b2df 100644 --- a/src/pipewire_video.c +++ b/src/pipewire_video.c @@ -413,6 +413,7 @@ static void renegotiate_format(void *data, uint64_t expirations) { uint8_t params_buffer[4096]; struct spa_pod_builder pod_builder = SPA_POD_BUILDER_INIT(params_buffer, sizeof(params_buffer)); if (!gsr_pipewire_video_build_format_params(self, &pod_builder, params, &num_video_formats)) { + fprintf(stderr, "gsr error: renegotiate_format: failed to build formats\n"); pw_thread_loop_unlock(self->thread_loop); return; } @@ -509,6 +510,9 @@ static bool gsr_pipewire_video_setup_stream(gsr_pipewire_video *self) { // TODO: Error check pw_core_add_listener(self->core, &self->core_listener, &core_events, self); + self->server_version_sync = pw_core_sync(self->core, PW_ID_CORE, 0); + pw_thread_loop_wait(self->thread_loop); + gsr_pipewire_video_init_modifiers(self); // TODO: Cleanup? @@ -519,9 +523,6 @@ static bool gsr_pipewire_video_setup_stream(gsr_pipewire_video *self) { goto error; } - self->server_version_sync = pw_core_sync(self->core, PW_ID_CORE, 0); - pw_thread_loop_wait(self->thread_loop); - self->stream = pw_stream_new(self->core, "com.dec05eba.gpu_screen_recorder", pw_properties_new(PW_KEY_MEDIA_TYPE, "Video", PW_KEY_MEDIA_CATEGORY, "Capture", -- cgit v1.2.3-70-g09d2