diff options
author | Wim Taymans <wtaymans@redhat.com> | 2019-12-13 11:34:25 +0100 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2019-12-13 11:34:25 +0100 |
commit | 698ab911c348b9c937c0b90445efce9f7e653bb1 (patch) | |
tree | d47512a8dd1dcc4a87bb741756dd232176fbf6b0 | |
parent | 828bd30879ec2d63c8477b85e9d946ac653c8bf3 (diff) |
loop: pass spa_dict to *_loop_new
Make the thread_loop alloc its own loop by default to simplify
some core. Add extra new_full method to pass a custom pw_loop.
Make other loop implementations ready to support custom loops
if we want that later.
-rw-r--r-- | pipewire-alsa/alsa-plugins/pcm_pipewire.c | 22 | ||||
-rw-r--r-- | pipewire-jack/src/pipewire-jack.c | 5 | ||||
-rw-r--r-- | pipewire-pulseaudio/src/thread-mainloop.c | 2 | ||||
-rw-r--r-- | src/daemon/main.c | 2 | ||||
-rw-r--r-- | src/daemon/pipewire.conf.in | 2 | ||||
-rw-r--r-- | src/gst/gstpipewiredeviceprovider.c | 35 | ||||
-rw-r--r-- | src/gst/gstpipewiredeviceprovider.h | 3 | ||||
-rw-r--r-- | src/gst/gstpipewiresink.c | 56 | ||||
-rw-r--r-- | src/gst/gstpipewiresink.h | 3 | ||||
-rw-r--r-- | src/gst/gstpipewiresrc.c | 81 | ||||
-rw-r--r-- | src/gst/gstpipewiresrc.h | 3 | ||||
-rw-r--r-- | src/pipewire/context.c | 3 | ||||
-rw-r--r-- | src/pipewire/data-loop.c | 37 | ||||
-rw-r--r-- | src/pipewire/data-loop.h | 4 | ||||
-rw-r--r-- | src/pipewire/loop.c | 22 | ||||
-rw-r--r-- | src/pipewire/loop.h | 5 | ||||
-rw-r--r-- | src/pipewire/main-loop.c | 36 | ||||
-rw-r--r-- | src/pipewire/main-loop.h | 5 | ||||
-rw-r--r-- | src/pipewire/private.h | 2 | ||||
-rw-r--r-- | src/pipewire/thread-loop.c | 70 | ||||
-rw-r--r-- | src/pipewire/thread-loop.h | 9 |
21 files changed, 215 insertions, 192 deletions
diff --git a/pipewire-alsa/alsa-plugins/pcm_pipewire.c b/pipewire-alsa/alsa-plugins/pcm_pipewire.c index a5d2eb32..4e39059c 100644 --- a/pipewire-alsa/alsa-plugins/pcm_pipewire.c +++ b/pipewire-alsa/alsa-plugins/pcm_pipewire.c @@ -65,7 +65,7 @@ typedef struct { unsigned int sample_bits; snd_pcm_uframes_t min_avail; - struct pw_loop *loop; + struct spa_system *system; struct pw_thread_loop *main_loop; struct pw_context *context; @@ -93,7 +93,7 @@ static int pcm_poll_block_check(snd_pcm_ioplug_t *io) (io->state == SND_PCM_STATE_PREPARED && io->stream == SND_PCM_STREAM_CAPTURE)) { avail = snd_pcm_avail_update(io->pcm); if (avail >= 0 && avail < (snd_pcm_sframes_t)pw->min_avail) { - spa_system_eventfd_read(pw->loop->system, io->poll_fd, &val); + spa_system_eventfd_read(pw->system, io->poll_fd, &val); return 1; } } @@ -104,7 +104,7 @@ static int pcm_poll_block_check(snd_pcm_ioplug_t *io) static inline int pcm_poll_unblock_check(snd_pcm_ioplug_t *io) { snd_pcm_pipewire_t *pw = io->private_data; - spa_system_eventfd_write(pw->loop->system, pw->fd, 1); + spa_system_eventfd_write(pw->system, pw->fd, 1); return 1; } @@ -115,12 +115,10 @@ static void snd_pcm_pipewire_free(snd_pcm_pipewire_t *pw) pw_thread_loop_stop(pw->main_loop); if (pw->context) pw_context_destroy(pw->context); + if (pw->fd >= 0) + spa_system_close(pw->system, pw->fd); if (pw->main_loop) pw_thread_loop_destroy(pw->main_loop); - if (pw->fd >= 0) - spa_system_close(pw->loop->system, pw->fd); - if (pw->loop) - pw_loop_destroy(pw->loop); free(pw); } } @@ -782,6 +780,7 @@ static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name, int err; const char *str; struct pw_properties *props; + struct pw_loop *loop; assert(pcmp); pw = calloc(1, sizeof(*pw)); @@ -812,9 +811,10 @@ static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name, pw->target = capture_node ? (uint32_t)atoi(capture_node) : SPA_ID_INVALID; } - pw->loop = pw_loop_new(NULL); - pw->main_loop = pw_thread_loop_new(pw->loop, "alsa-pipewire"); - pw->context = pw_context_new(pw->loop, NULL, 0); + pw->main_loop = pw_thread_loop_new("alsa-pipewire", NULL); + loop = pw_thread_loop_get_loop(pw->main_loop); + pw->system = loop->system; + pw->context = pw_context_new(loop, NULL, 0); props = pw_properties_new(NULL, NULL); str = pw_get_prgname(); @@ -836,7 +836,7 @@ static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name, pw_core_add_listener(pw->core, &pw->core_listener, &core_events, pw); pw_thread_loop_unlock(pw->main_loop); - pw->fd = spa_system_eventfd_create(pw->loop->system, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK); + pw->fd = spa_system_eventfd_create(pw->system, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK); pw->io.version = SND_PCM_IOPLUG_VERSION; pw->io.name = "ALSA <-> PipeWire PCM I/O Plugin"; diff --git a/pipewire-jack/src/pipewire-jack.c b/pipewire-jack/src/pipewire-jack.c index 7b375f87..8f503958 100644 --- a/pipewire-jack/src/pipewire-jack.c +++ b/pipewire-jack/src/pipewire-jack.c @@ -201,7 +201,6 @@ struct port { }; struct context { - struct pw_main_loop *main; struct pw_thread_loop *loop; struct pw_context *context; @@ -2100,8 +2099,7 @@ jack_client_t * jack_client_open (const char *client_name, client->node_id = SPA_ID_INVALID; strncpy(client->name, client_name, JACK_CLIENT_NAME_SIZE); - client->context.main = pw_main_loop_new(NULL); - client->context.loop = pw_thread_loop_new(pw_main_loop_get_loop(client->context.main), client_name); + client->context.loop = pw_thread_loop_new(client_name, NULL); client->context.context = pw_context_new(pw_thread_loop_get_loop(client->context.loop), NULL, 0); spa_list_init(&client->context.free_objects); spa_list_init(&client->context.nodes); @@ -2252,7 +2250,6 @@ int jack_client_close (jack_client_t *client) c->destroyed = true; pw_context_destroy(c->context.context); pw_thread_loop_destroy(c->context.loop); - pw_main_loop_destroy(c->context.main); pw_log_debug(NAME" %p: free", client); free(c); diff --git a/pipewire-pulseaudio/src/thread-mainloop.c b/pipewire-pulseaudio/src/thread-mainloop.c index 266625f8..8884b809 100644 --- a/pipewire-pulseaudio/src/thread-mainloop.c +++ b/pipewire-pulseaudio/src/thread-mainloop.c @@ -44,7 +44,7 @@ pa_threaded_mainloop *pa_threaded_mainloop_new(void) if (m->loop == NULL) goto no_mem; - m->tloop = pw_thread_loop_new(m->loop->loop, NULL); + m->tloop = pw_thread_loop_new_full(m->loop->loop, "pipewire-pulse", NULL); if (m->tloop == NULL) goto no_mem; diff --git a/src/daemon/main.c b/src/daemon/main.c index c2a1a877..58f2aab9 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -103,7 +103,7 @@ int main(int argc, char *argv[]) } - loop = pw_main_loop_new(pw_properties_copy(properties)); + loop = pw_main_loop_new(&properties->dict); if (loop == NULL) { pw_log_error("failed to create main-loop: %m"); return -1; diff --git a/src/daemon/pipewire.conf.in b/src/daemon/pipewire.conf.in index 93a6809b..00f383c0 100644 --- a/src/daemon/pipewire.conf.in +++ b/src/daemon/pipewire.conf.in @@ -1,7 +1,7 @@ #daemon config file for PipeWire version @VERSION@ #set-prop library.name.system support/libspa-support -#set-prop core.data-loop.library.name.system support/libspa-support +#set-prop context.data-loop.library.name.system support/libspa-support #set-prop link.max-buffers 64 add-spa-lib audio.convert* audioconvert/libspa-audioconvert diff --git a/src/gst/gstpipewiredeviceprovider.c b/src/gst/gstpipewiredeviceprovider.c index 4ca4c744..e3179cdb 100644 --- a/src/gst/gstpipewiredeviceprovider.c +++ b/src/gst/gstpipewiredeviceprovider.c @@ -340,8 +340,8 @@ on_core_done (void *data, uint32_t id, int seq) pw_log_debug("check %d %d", seq, self->seq); if (seq == self->seq) { self->end = true; - if (self->main_loop) - pw_thread_loop_signal (self->main_loop, FALSE); + if (self->loop) + pw_thread_loop_signal (self->loop, FALSE); } } @@ -357,7 +357,7 @@ on_core_error(void *data, uint32_t id, int seq, int res, const char *message) if (id == 0) { self->error = res; } - pw_thread_loop_signal(self->main_loop, FALSE); + pw_thread_loop_signal(self->loop, FALSE); } static const struct pw_core_events core_events = { @@ -585,26 +585,25 @@ gst_pipewire_device_provider_start (GstDeviceProvider * provider) GST_DEBUG_OBJECT (self, "starting provider"); - self->loop = pw_loop_new (NULL); self->list_only = FALSE; spa_list_init(&self->pending); - if (!(self->main_loop = pw_thread_loop_new (self->loop, "pipewire-device-monitor"))) { + if (!(self->loop = pw_thread_loop_new ("pipewire-device-monitor", NULL))) { GST_ERROR_OBJECT (self, "Could not create PipeWire mainloop"); - goto failed_main_loop; + goto failed_loop; } - if (!(self->context = pw_context_new (self->loop, NULL, sizeof(*data)))) { + if (!(self->context = pw_context_new (pw_thread_loop_get_loop(self->loop), NULL, sizeof(*data)))) { GST_ERROR_OBJECT (self, "Could not create PipeWire context"); goto failed_context; } - if (pw_thread_loop_start (self->main_loop) < 0) { + if (pw_thread_loop_start (self->loop) < 0) { GST_ERROR_OBJECT (self, "Could not start PipeWire mainloop"); goto failed_start; } - pw_thread_loop_lock (self->main_loop); + pw_thread_loop_lock (self->loop); if ((self->core = pw_context_connect (self->context, NULL, 0)) == NULL) { GST_ERROR_OBJECT (self, "Failed to connect"); @@ -631,26 +630,24 @@ gst_pipewire_device_provider_start (GstDeviceProvider * provider) break; if (self->end) break; - pw_thread_loop_wait (self->main_loop); + pw_thread_loop_wait (self->loop); } GST_DEBUG_OBJECT (self, "started"); - pw_thread_loop_unlock (self->main_loop); + pw_thread_loop_unlock (self->loop); return TRUE; failed_connect: - pw_thread_loop_unlock (self->main_loop); + pw_thread_loop_unlock (self->loop); failed_start: pw_context_destroy (self->context); self->context = NULL; failed_context: - pw_thread_loop_destroy (self->main_loop); - self->main_loop = NULL; -failed_main_loop: - pw_loop_destroy (self->loop); + pw_thread_loop_destroy (self->loop); self->loop = NULL; +failed_loop: return TRUE; } @@ -669,12 +666,8 @@ gst_pipewire_device_provider_stop (GstDeviceProvider * provider) pw_context_destroy (self->context); self->context = NULL; } - if (self->main_loop) { - pw_thread_loop_destroy (self->main_loop); - self->main_loop = NULL; - } if (self->loop) { - pw_loop_destroy (self->loop); + pw_thread_loop_destroy (self->loop); self->loop = NULL; } } diff --git a/src/gst/gstpipewiredeviceprovider.h b/src/gst/gstpipewiredeviceprovider.h index 8aad8795..e0268355 100644 --- a/src/gst/gstpipewiredeviceprovider.h +++ b/src/gst/gstpipewiredeviceprovider.h @@ -83,8 +83,7 @@ struct _GstPipeWireDeviceProvider { gchar *client_name; - struct pw_loop *loop; - struct pw_thread_loop *main_loop; + struct pw_thread_loop *loop; struct pw_context *context; diff --git a/src/gst/gstpipewiresink.c b/src/gst/gstpipewiresink.c index 4bd9b518..77e16ee8 100644 --- a/src/gst/gstpipewiresink.c +++ b/src/gst/gstpipewiresink.c @@ -119,10 +119,7 @@ gst_pipewire_sink_finalize (GObject * object) g_object_unref (pwsink->pool); - pw_thread_loop_destroy (pwsink->main_loop); - pwsink->main_loop = NULL; - - pw_loop_destroy (pwsink->loop); + pw_thread_loop_destroy (pwsink->loop); pwsink->loop = NULL; if (pwsink->properties) @@ -264,9 +261,9 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink) SPA_PARAM_META_size, SPA_POD_Int(sizeof (struct spa_meta_header))); - pw_thread_loop_lock (sink->main_loop); + pw_thread_loop_lock (sink->loop); pw_stream_update_params (sink->stream, port_params, 2); - pw_thread_loop_unlock (sink->main_loop); + pw_thread_loop_unlock (sink->loop); } static void @@ -281,10 +278,9 @@ gst_pipewire_sink_init (GstPipeWireSink * sink) g_queue_init (&sink->queue); - sink->loop = pw_loop_new (NULL); - sink->main_loop = pw_thread_loop_new (sink->loop, "pipewire-sink-loop"); - sink->context = pw_context_new (sink->loop, NULL, 0); - GST_DEBUG ("loop %p %p", sink->loop, sink->main_loop); + sink->loop = pw_thread_loop_new ("pipewire-sink-loop", NULL); + sink->context = pw_context_new (pw_thread_loop_get_loop(sink->loop), NULL, 0); + GST_DEBUG ("loop %p context %p", sink->loop, sink->context); } static GstCaps * @@ -406,7 +402,7 @@ on_add_buffer (void *_data, struct pw_buffer *b) { GstPipeWireSink *pwsink = _data; gst_pipewire_pool_wrap_buffer (pwsink->pool, b); - pw_thread_loop_signal (pwsink->main_loop, FALSE); + pw_thread_loop_signal (pwsink->loop, FALSE); } static void @@ -455,7 +451,7 @@ do_send_buffer (GstPipeWireSink *pwsink) if ((res = pw_stream_queue_buffer (pwsink->stream, data->b)) < 0) { g_warning ("can't send buffer %s", spa_strerror(res)); - pw_thread_loop_signal (pwsink->main_loop, FALSE); + pw_thread_loop_signal (pwsink->loop, FALSE); } else pwsink->need_ready--; } @@ -496,7 +492,7 @@ on_state_changed (void *data, enum pw_stream_state old, enum pw_stream_state sta ("stream error: %s", error), (NULL)); break; } - pw_thread_loop_signal (pwsink->main_loop, FALSE); + pw_thread_loop_signal (pwsink->loop, FALSE); } static void @@ -524,7 +520,7 @@ gst_pipewire_sink_setcaps (GstBaseSink * bsink, GstCaps * caps) possible = gst_caps_to_format_all (caps, SPA_PARAM_EnumFormat); - pw_thread_loop_lock (pwsink->main_loop); + pw_thread_loop_lock (pwsink->loop); state = pw_stream_get_state (pwsink->stream, &error); if (state == PW_STREAM_STATE_ERROR) @@ -554,12 +550,12 @@ gst_pipewire_sink_setcaps (GstBaseSink * bsink, GstCaps * caps) if (state == PW_STREAM_STATE_ERROR) goto start_error; - pw_thread_loop_wait (pwsink->main_loop); + pw_thread_loop_wait (pwsink->loop); } } res = TRUE; - pw_thread_loop_unlock (pwsink->main_loop); + pw_thread_loop_unlock (pwsink->loop); pwsink->negotiated = res; @@ -568,7 +564,7 @@ gst_pipewire_sink_setcaps (GstBaseSink * bsink, GstCaps * caps) start_error: { GST_ERROR ("could not start stream: %s", error); - pw_thread_loop_unlock (pwsink->main_loop); + pw_thread_loop_unlock (pwsink->loop); g_ptr_array_unref (possible); return FALSE; } @@ -586,7 +582,7 @@ gst_pipewire_sink_render (GstBaseSink * bsink, GstBuffer * buffer) if (!pwsink->negotiated) goto not_negotiated; - pw_thread_loop_lock (pwsink->main_loop); + pw_thread_loop_lock (pwsink->loop); if (pw_stream_get_state (pwsink->stream, &error) != PW_STREAM_STATE_STREAMING) goto done; @@ -616,7 +612,7 @@ gst_pipewire_sink_render (GstBaseSink * bsink, GstBuffer * buffer) do_send_buffer (pwsink); done: - pw_thread_loop_unlock (pwsink->main_loop); + pw_thread_loop_unlock (pwsink->loop); return res; @@ -664,7 +660,7 @@ gst_pipewire_sink_start (GstBaseSink * basesink) props = NULL; } - pw_thread_loop_lock (pwsink->main_loop); + pw_thread_loop_lock (pwsink->loop); pwsink->stream = pw_stream_new (pwsink->core, pwsink->client_name, props); pwsink->pool->stream = pwsink->stream; @@ -673,7 +669,7 @@ gst_pipewire_sink_start (GstBaseSink * basesink) &stream_events, pwsink); - pw_thread_loop_unlock (pwsink->main_loop); + pw_thread_loop_unlock (pwsink->loop); return TRUE; } @@ -683,14 +679,14 @@ gst_pipewire_sink_stop (GstBaseSink * basesink) { GstPipeWireSink *pwsink = GST_PIPEWIRE_SINK (basesink); - pw_thread_loop_lock (pwsink->main_loop); + pw_thread_loop_lock (pwsink->loop); if (pwsink->stream) { pw_stream_disconnect (pwsink->stream); pw_stream_destroy (pwsink->stream); pwsink->stream = NULL; pwsink->pool->stream = NULL; } - pw_thread_loop_unlock (pwsink->main_loop); + pw_thread_loop_unlock (pwsink->loop); pwsink->negotiated = FALSE; @@ -700,10 +696,10 @@ gst_pipewire_sink_stop (GstBaseSink * basesink) static gboolean gst_pipewire_sink_open (GstPipeWireSink * pwsink) { - if (pw_thread_loop_start (pwsink->main_loop) < 0) + if (pw_thread_loop_start (pwsink->loop) < 0) goto mainloop_error; - pw_thread_loop_lock (pwsink->main_loop); + pw_thread_loop_lock (pwsink->loop); if (pwsink->fd == -1) pwsink->core = pw_context_connect (pwsink->context, NULL, 0); @@ -713,7 +709,7 @@ gst_pipewire_sink_open (GstPipeWireSink * pwsink) if (pwsink->core == NULL) goto connect_error; - pw_thread_loop_unlock (pwsink->main_loop); + pw_thread_loop_unlock (pwsink->loop); return TRUE; @@ -728,7 +724,7 @@ connect_error: { GST_ELEMENT_ERROR (pwsink, RESOURCE, FAILED, ("Failed to connect"), (NULL)); - pw_thread_loop_unlock (pwsink->main_loop); + pw_thread_loop_unlock (pwsink->loop); return FALSE; } } @@ -736,7 +732,7 @@ connect_error: static gboolean gst_pipewire_sink_close (GstPipeWireSink * pwsink) { - pw_thread_loop_lock (pwsink->main_loop); + pw_thread_loop_lock (pwsink->loop); if (pwsink->stream) { pw_stream_disconnect (pwsink->stream); } @@ -744,9 +740,9 @@ gst_pipewire_sink_close (GstPipeWireSink * pwsink) pw_core_disconnect (pwsink->core); pwsink->core = NULL; } - pw_thread_loop_unlock (pwsink->main_loop); + pw_thread_loop_unlock (pwsink->loop); - pw_thread_loop_stop (pwsink->main_loop); + pw_thread_loop_stop (pwsink->loop); if (pwsink->stream) { pw_stream_destroy (pwsink->stream); diff --git a/src/gst/gstpipewiresink.h b/src/gst/gstpipewiresink.h index 91c80f48..79959e2f 100644 --- a/src/gst/gstpipewiresink.h +++ b/src/gst/gstpipewiresink.h @@ -83,8 +83,7 @@ struct _GstPipeWireSink { /* video state */ gboolean negotiated; - struct pw_loop *loop; - struct pw_thread_loop *main_loop; + struct pw_thread_loop *loop; struct pw_context *context; struct pw_core *core; diff --git a/src/gst/gstpipewiresrc.c b/src/gst/gstpipewiresrc.c index 7a984ada..75128eab 100644 --- a/src/gst/gstpipewiresrc.c +++ b/src/gst/gstpipewiresrc.c @@ -210,9 +210,7 @@ gst_pipewire_src_finalize (GObject * object) pw_context_destroy (pwsrc->context); pwsrc->context = NULL; - pw_thread_loop_destroy (pwsrc->main_loop); - pwsrc->main_loop = NULL; - pw_loop_destroy (pwsrc->loop); + pw_thread_loop_destroy (pwsrc->loop); pwsrc->loop = NULL; if (pwsrc->properties) @@ -329,10 +327,9 @@ gst_pipewire_src_init (GstPipeWireSrc * src) src->client_name = g_strdup(pw_get_client_name ()); src->pool = gst_pipewire_pool_new (); - src->loop = pw_loop_new (NULL); - src->main_loop = pw_thread_loop_new (src->loop, "pipewire-main-loop"); - src->context = pw_context_new (src->loop, NULL, 0); - GST_DEBUG ("loop %p, mainloop %p", src->loop, src->main_loop); + src->loop = pw_thread_loop_new ("pipewire-main-loop", NULL); + src->context = pw_context_new (pw_thread_loop_get_loop(src->loop), NULL, 0); + GST_DEBUG ("loop %p context %p", src->loop, src->context); } @@ -349,9 +346,9 @@ buffer_recycle (GstMiniObject *obj) src = data->owner; GST_LOG_OBJECT (obj, "recycle buffer"); - pw_thread_loop_lock (src->main_loop); + pw_thread_loop_lock (src->loop); pw_stream_queue_buffer (src->stream, data->b); - pw_thread_loop_unlock (src->main_loop); + pw_thread_loop_unlock (src->loop); return FALSE; } @@ -438,7 +435,7 @@ on_process (void *_data) gst_buffer_ref (buf); g_queue_push_tail (&pwsrc->queue, buf); - pw_thread_loop_signal (pwsrc->main_loop, FALSE); + pw_thread_loop_signal (pwsrc->loop, FALSE); return; } @@ -462,7 +459,7 @@ on_state_changed (void *data, ("stream error: %s", error), (NULL)); break; } - pw_thread_loop_signal (pwsrc->main_loop, FALSE); + pw_thread_loop_signal (pwsrc->loop, FALSE); } static void @@ -492,7 +489,7 @@ static gboolean gst_pipewire_src_stream_start (GstPipeWireSrc *pwsrc) { const char *error = NULL; - pw_thread_loop_lock (pwsrc->main_loop); + pw_thread_loop_lock (pwsrc->loop); GST_DEBUG_OBJECT (pwsrc, "doing stream start"); while (TRUE) { enum pw_stream_state state = pw_stream_get_state (pwsrc->stream, &error); @@ -504,21 +501,21 @@ gst_pipewire_src_stream_start (GstPipeWireSrc *pwsrc) if (state == PW_STREAM_STATE_ERROR) goto start_error; - pw_thread_loop_wait (pwsrc->main_loop); + pw_thread_loop_wait (pwsrc->loop); } parse_stream_properties (pwsrc, pw_stream_get_properties (pwsrc->stream)); GST_DEBUG_OBJECT (pwsrc, "signal started"); pwsrc->started = TRUE; - pw_thread_loop_signal (pwsrc->main_loop, FALSE); - pw_thread_loop_unlock (pwsrc->main_loop); + pw_thread_loop_signal (pwsrc->loop, FALSE); + pw_thread_loop_unlock (pwsrc->loop); return TRUE; start_error: { GST_DEBUG_OBJECT (pwsrc, "error starting stream: %s", error); - pw_thread_loop_unlock (pwsrc->main_loop); + pw_thread_loop_unlock (pwsrc->loop); return FALSE; } } @@ -529,7 +526,7 @@ wait_negotiated (GstPipeWireSrc *this) enum pw_stream_state state; const char *error = NULL; - pw_thread_loop_lock (this->main_loop); + pw_thread_loop_lock (this->loop); while (TRUE) { state = pw_stream_get_state (this->stream, &error); @@ -542,10 +539,10 @@ wait_negotiated (GstPipeWireSrc *this) if (this->started) break; - pw_thread_loop_wait (this->main_loop); + pw_thread_loop_wait (this->loop); } GST_DEBUG_OBJECT (this, "got started signal"); - pw_thread_loop_unlock (this->main_loop); + pw_thread_loop_unlock (this->loop); return state; } @@ -592,7 +589,7 @@ gst_pipewire_src_negotiate (GstBaseSrc * basesrc) gst_caps_unref (caps); /* first disconnect */ - pw_thread_loop_lock (pwsrc->main_loop); + pw_thread_loop_lock (pwsrc->loop); if (pw_stream_get_state(pwsrc->stream, &error) != PW_STREAM_STATE_UNCONNECTED) { GST_DEBUG_OBJECT (basesrc, "disconnect capture"); pw_stream_disconnect (pwsrc->stream); @@ -608,7 +605,7 @@ gst_pipewire_src_negotiate (GstBaseSrc * basesrc) goto connect_error; } - pw_thread_loop_wait (pwsrc->main_loop); + pw_thread_loop_wait (pwsrc->loop); } } @@ -632,9 +629,9 @@ gst_pipewire_src_negotiate (GstBaseSrc * basesrc) if (state == PW_STREAM_STATE_ERROR) goto connect_error; - pw_thread_loop_wait (pwsrc->main_loop); + pw_thread_loop_wait (pwsrc->loop); } - pw_thread_loop_unlock (pwsrc->main_loop); + pw_thread_loop_unlock (pwsrc->loop); result = gst_pipewire_src_stream_start (pwsrc); @@ -669,7 +666,7 @@ no_common_caps: } connect_error: { - pw_thread_loop_unlock (pwsrc->main_loop); + pw_thread_loop_unlock (pwsrc->loop); return FALSE; } } @@ -726,11 +723,11 @@ gst_pipewire_src_unlock (GstBaseSrc * basesrc) { GstPipeWireSrc *pwsrc = GST_PIPEWIRE_SRC (basesrc); - pw_thread_loop_lock (pwsrc->main_loop); + pw_thread_loop_lock (pwsrc->loop); GST_DEBUG_OBJECT (pwsrc, "setting flushing"); pwsrc->flushing = TRUE; - pw_thread_loop_signal (pwsrc->main_loop, FALSE); - pw_thread_loop_unlock (pwsrc->main_loop); + pw_thread_loop_signal (pwsrc->loop, FALSE); + pw_thread_loop_unlock (pwsrc->loop); return TRUE; } @@ -740,10 +737,10 @@ gst_pipewire_src_unlock_stop (GstBaseSrc * basesrc) { GstPipeWireSrc *pwsrc = GST_PIPEWIRE_SRC (basesrc); - pw_thread_loop_lock (pwsrc->main_loop); + pw_thread_loop_lock (pwsrc->loop); GST_DEBUG_OBJECT (pwsrc, "unsetting flushing"); pwsrc->flushing = FALSE; - pw_thread_loop_unlock (pwsrc->main_loop); + pw_thread_loop_unlock (pwsrc->loop); return TRUE; } @@ -812,7 +809,7 @@ gst_pipewire_src_create (GstPushSrc * psrc, GstBuffer ** buffer) if (!pwsrc->negotiated) goto not_negotiated; - pw_thread_loop_lock (pwsrc->main_loop); + pw_thread_loop_lock (pwsrc->loop); while (TRUE) { enum pw_stream_state state; @@ -834,9 +831,9 @@ gst_pipewire_src_create (GstPushSrc * psrc, GstBuffer ** buffer) if (buf != NULL) break; - pw_thread_loop_wait (pwsrc->main_loop); + pw_thread_loop_wait (pwsrc->loop); } - pw_thread_loop_unlock (pwsrc->main_loop); + pw_thread_loop_unlock (pwsrc->loop); gst_buffer_unref (buf); @@ -876,12 +873,12 @@ not_negotiated: } streaming_error: { - pw_thread_loop_unlock (pwsrc->main_loop); + pw_thread_loop_unlock (pwsrc->loop); return GST_FLOW_ERROR; } streaming_stopped: { - pw_thread_loop_unlock (pwsrc->main_loop); + pw_thread_loop_unlock (pwsrc->loop); return GST_FLOW_FLUSHING; } } @@ -899,9 +896,9 @@ gst_pipewire_src_stop (GstBaseSrc * basesrc) pwsrc = GST_PIPEWIRE_SRC (basesrc); - pw_thread_loop_lock (pwsrc->main_loop); + pw_thread_loop_lock (pwsrc->loop); clear_queue (pwsrc); - pw_thread_loop_unlock (pwsrc->main_loop); + pw_thread_loop_unlock (pwsrc->loop); return TRUE; } @@ -934,10 +931,10 @@ gst_pipewire_src_open (GstPipeWireSrc * pwsrc) { struct pw_properties *props; - if (pw_thread_loop_start (pwsrc->main_loop) < 0) + if (pw_thread_loop_start (pwsrc->loop) < 0) goto mainloop_failed; - pw_thread_loop_lock (pwsrc->main_loop); + pw_thread_loop_lock (pwsrc->loop); if (pwsrc->fd == -1) pwsrc->core = pw_context_connect (pwsrc->context, NULL, 0); @@ -966,7 +963,7 @@ gst_pipewire_src_open (GstPipeWireSrc * pwsrc) pwsrc->clock = gst_pipewire_clock_new (pwsrc->stream, pwsrc->last_time); - pw_thread_loop_unlock (pwsrc->main_loop); + pw_thread_loop_unlock (pwsrc->loop); return TRUE; @@ -979,13 +976,13 @@ mainloop_failed: connect_error: { GST_ELEMENT_ERROR (pwsrc, RESOURCE, FAILED, ("can't connect"), (NULL)); - pw_thread_loop_unlock (pwsrc->main_loop); + pw_thread_loop_unlock (pwsrc->loop); return FALSE; } no_stream: { GST_ELEMENT_ERROR (pwsrc, RESOURCE, FAILED, ("can't create stream"), (NULL)); - pw_thread_loop_unlock (pwsrc->main_loop); + pw_thread_loop_unlock (pwsrc->loop); return FALSE; } } @@ -995,7 +992,7 @@ gst_pipewire_src_close (GstPipeWireSrc * pwsrc) { clear_queue (pwsrc); - pw_thread_loop_stop (pwsrc->main_loop); + pw_thread_loop_stop (pwsrc->loop); pwsrc->last_time = gst_clock_get_time (pwsrc->clock); diff --git a/src/gst/gstpipewiresrc.h b/src/gst/gstpipewiresrc.h index effb3a85..02374f6d 100644 --- a/src/gst/gstpipewiresrc.h +++ b/src/gst/gstpipewiresrc.h @@ -71,8 +71,7 @@ struct _GstPipeWireSrc { GstClockTime min_latency; GstClockTime max_latency; - struct pw_loop *loop; - struct pw_thread_loop *main_loop; + struct pw_thread_loop *loop; struct pw_context *context; struct pw_core *core; diff --git a/src/pipewire/context.c b/src/pipewire/context.c index b1828063..90497090 100644 --- a/src/pipewire/context.c +++ b/src/pipewire/context.c @@ -158,7 +158,8 @@ struct pw_context *pw_context_new(struct pw_loop *main_loop, if ((str = pw_properties_get(pr, "context.data-loop." PW_KEY_LIBRARY_NAME_SYSTEM))) pw_properties_set(pr, PW_KEY_LIBRARY_NAME_SYSTEM, str); - this->data_loop_impl = pw_data_loop_new(pr); + this->data_loop_impl = pw_data_loop_new(&pr->dict); + pw_properties_free(pr); if (this->data_loop_impl == NULL) { res = -errno; goto error_free; diff --git a/src/pipewire/data-loop.c b/src/pipewire/data-loop.c index 50adb327..ad146048 100644 --- a/src/pipewire/data-loop.c +++ b/src/pipewire/data-loop.c @@ -86,13 +86,7 @@ static void do_stop(void *data, uint64_t count) this->running = false; } -/** Create a new \ref pw_data_loop. - * \return a newly allocated data loop - * - * \memberof pw_data_loop - */ -SPA_EXPORT -struct pw_data_loop *pw_data_loop_new(struct pw_properties *properties) +static struct pw_data_loop *loop_new(struct pw_loop *loop, const struct spa_dict *props) { struct pw_data_loop *this; int res; @@ -105,13 +99,16 @@ struct pw_data_loop *pw_data_loop_new(struct pw_properties *properties) pw_log_debug(NAME" %p: new", this); - this->loop = pw_loop_new(properties); - properties = NULL; - if (this->loop == NULL) { + if (loop == NULL) { + loop = pw_loop_new(props); + this->created = true; + } + if (loop == NULL) { res = -errno; pw_log_error(NAME" %p: can't create loop: %m", this); goto error_free; } + this->loop = loop; this->event = pw_loop_add_event(this->loop, do_stop, this); if (this->event == NULL) { @@ -125,16 +122,27 @@ struct pw_data_loop *pw_data_loop_new(struct pw_properties *properties) return this; error_loop_destroy: - pw_loop_destroy(this->loop); + if (this->created && this->loop) + pw_loop_destroy(this->loop); error_free: free(this); error_cleanup: - if (properties) - pw_properties_free(properties); errno = -res; return NULL; } +/** Create a new \ref pw_data_loop. + * \return a newly allocated data loop + * + * \memberof pw_data_loop + */ +SPA_EXPORT +struct pw_data_loop *pw_data_loop_new(const struct spa_dict *props) +{ + return loop_new(NULL, props); +} + + /** Destroy a data loop * \param loop the data loop to destroy * \memberof pw_data_loop @@ -149,7 +157,8 @@ void pw_data_loop_destroy(struct pw_data_loop *loop) pw_data_loop_stop(loop); pw_loop_destroy_source(loop->loop, loop->event); - pw_loop_destroy(loop->loop); + if (loop->created) + pw_loop_destroy(loop->loop); free(loop); } diff --git a/src/pipewire/data-loop.h b/src/pipewire/data-loop.h index f85b7151..f736f8e4 100644 --- a/src/pipewire/data-loop.h +++ b/src/pipewire/data-loop.h @@ -49,9 +49,9 @@ struct pw_data_loop_events { void (*destroy) (void *data); }; -/** Make a new loop */ +/** Make a new loop. */ struct pw_data_loop * -pw_data_loop_new(struct pw_properties *properties); +pw_data_loop_new(const struct spa_dict *props); /** Add an event listener to loop */ void pw_data_loop_add_listener(struct pw_data_loop *loop, diff --git a/src/pipewire/loop.c b/src/pipewire/loop.c index af6ccf4e..53a86ed1 100644 --- a/src/pipewire/loop.c +++ b/src/pipewire/loop.c @@ -44,7 +44,6 @@ struct impl { struct spa_handle *system_handle; struct spa_handle *loop_handle; - struct pw_properties *properties; }; /** \endcond */ @@ -53,7 +52,7 @@ struct impl { * \memberof pw_loop */ SPA_EXPORT -struct pw_loop *pw_loop_new(struct pw_properties *properties) +struct pw_loop *pw_loop_new(const struct spa_dict *props) { int res; struct impl *impl; @@ -72,17 +71,15 @@ struct pw_loop *pw_loop_new(struct pw_properties *properties) } this = &impl->this; - impl->properties = properties; - if (properties) - lib = pw_properties_get(properties, PW_KEY_LIBRARY_NAME_SYSTEM); + if (props) + lib = spa_dict_lookup(props, PW_KEY_LIBRARY_NAME_SYSTEM); else lib = NULL; impl->system_handle = pw_load_spa_handle(lib, SPA_NAME_SUPPORT_SYSTEM, - properties ? &properties->dict : NULL, - n_support, support); + props, n_support, support); if (impl->system_handle == NULL) { res = -errno; pw_log_error(NAME" %p: can't make "SPA_NAME_SUPPORT_SYSTEM" handle: %m", this); @@ -99,14 +96,13 @@ struct pw_loop *pw_loop_new(struct pw_properties *properties) support[n_support++] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_System, iface); - if (properties) - lib = pw_properties_get(properties, PW_KEY_LIBRARY_NAME_LOOP); + if (props) + lib = spa_dict_lookup(props, PW_KEY_LIBRARY_NAME_LOOP); else lib = NULL; impl->loop_handle = pw_load_spa_handle(lib, - SPA_NAME_SUPPORT_LOOP, - properties ? &properties->dict : NULL, + SPA_NAME_SUPPORT_LOOP, props, n_support, support); if (impl->loop_handle == NULL) { res = -errno; @@ -150,8 +146,6 @@ error_unload_system: error_free: free(impl); error_cleanup: - if (properties) - pw_properties_free(properties); errno = -res; return NULL; } @@ -165,8 +159,6 @@ void pw_loop_destroy(struct pw_loop *loop) { struct impl *impl = SPA_CONTAINER_OF(loop, struct impl, this); - if (impl->properties) - pw_properties_free(impl->properties); pw_unload_spa_handle(impl->loop_handle); pw_unload_spa_handle(impl->system_handle); free(impl); diff --git a/src/pipewire/loop.h b/src/pipewire/loop.h index 6f4a7614..8b02d1d7 100644 --- a/src/pipewire/loop.h +++ b/src/pipewire/loop.h @@ -30,8 +30,7 @@ extern "C" { #endif #include <spa/support/loop.h> - -#include <pipewire/properties.h> +#include <spa/utils/dict.h> /** \class pw_loop * @@ -47,7 +46,7 @@ struct pw_loop { }; struct pw_loop * -pw_loop_new(struct pw_properties *properties); +pw_loop_new(const struct spa_dict *props); void pw_loop_destroy(struct pw_loop *loop); diff --git a/src/pipewire/main-loop.c b/src/pipewire/main-loop.c index 0cc17367..b46fb1f4 100644 --- a/src/pipewire/main-loop.c +++ b/src/pipewire/main-loop.c @@ -35,13 +35,7 @@ static void do_stop(void *data, uint64_t count) this->running = false; } -/** Create a new new main loop - * \return a newly allocated \ref pw_main_loop - * - * \memberof pw_main_loop - */ -SPA_EXPORT -struct pw_main_loop *pw_main_loop_new(struct pw_properties *properties) +static struct pw_main_loop *loop_new(struct pw_loop *loop, const struct spa_dict *props) { struct pw_main_loop *this; int res; @@ -54,12 +48,15 @@ struct pw_main_loop *pw_main_loop_new(struct pw_properties *properties) pw_log_debug(NAME" %p: new", this); - this->loop = pw_loop_new(properties); - properties = NULL; - if (this->loop == NULL) { + if (loop == NULL) { + loop = pw_loop_new(props); + this->created = true; + } + if (loop == NULL) { res = -errno; goto error_free; } + this->loop = loop; this->event = pw_loop_add_event(this->loop, do_stop, this); if (this->event == NULL) { @@ -72,16 +69,26 @@ struct pw_main_loop *pw_main_loop_new(struct pw_properties *properties) return this; error_free_loop: - pw_loop_destroy(this->loop); + if (this->created && this->loop) + pw_loop_destroy(this->loop); error_free: free(this); error_cleanup: - if (properties) - pw_properties_free(properties); errno = -res; return NULL; } +/** Create a new new main loop + * \return a newly allocated \ref pw_main_loop + * + * \memberof pw_main_loop + */ +SPA_EXPORT +struct pw_main_loop *pw_main_loop_new(const struct spa_dict *props) +{ + return loop_new(NULL, props); +} + /** Destroy a main loop * \param loop the main loop to destroy * @@ -93,7 +100,8 @@ void pw_main_loop_destroy(struct pw_main_loop *loop) pw_log_debug(NAME" %p: destroy", loop); pw_main_loop_emit_destroy(loop); - pw_loop_destroy(loop->loop); + if (loop->created) + pw_loop_destroy(loop->loop); free(loop); } diff --git a/src/pipewire/main-loop.h b/src/pipewire/main-loop.h index b3976742..0ae3079d 100644 --- a/src/pipewire/main-loop.h +++ b/src/pipewire/main-loop.h @@ -39,7 +39,6 @@ extern "C" { struct pw_main_loop; #include <pipewire/loop.h> -#include <pipewire/properties.h> /** Events of the main loop */ struct pw_main_loop_events { @@ -50,9 +49,9 @@ struct pw_main_loop_events { void (*destroy) (void *data); }; -/** Create a new main loop */ +/** Create a new main loop. */ struct pw_main_loop * -pw_main_loop_new(struct pw_properties *properties); +pw_main_loop_new(const struct spa_dict *props); /** Add an event listener */ void pw_main_loop_add_listener(struct pw_main_loop *loop, diff --git a/src/pipewire/private.h b/src/pipewire/private.h index 63c48d8e..407f5c55 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -276,6 +276,7 @@ struct pw_data_loop { struct spa_source *event; pthread_t thread; + unsigned int created:1; unsigned int running:1; }; @@ -288,6 +289,7 @@ struct pw_main_loop { struct spa_hook_list listener_list; struct spa_source *event; + unsigned int created:1; unsigned int running:1; }; diff --git a/src/pipewire/thread-loop.c b/src/pipewire/thread-loop.c index 25a23c4d..36b05ffb 100644 --- a/src/pipewire/thread-loop.c +++ b/src/pipewire/thread-loop.c @@ -59,6 +59,7 @@ struct pw_thread_loop { int n_waiting; int n_waiting_for_accept; + unsigned int created:1; unsigned int running:1; }; /** \endcond */ @@ -96,23 +97,9 @@ do { \ } \ } while(false); -/** Create a new \ref pw_thread_loop - * - * \param loop the loop to wrap - * \param name the name of the thread or NULL - * \return a newly allocated \ref pw_thread_loop - * - * Make a new \ref pw_thread_loop that will run \a loop in - * a thread with \a name. - * - * After this function you should probably call pw_thread_loop_start() to - * actually start the thread - * - * \memberof pw_thread_loop - */ -SPA_EXPORT -struct pw_thread_loop *pw_thread_loop_new(struct pw_loop *loop, - const char *name) +static struct pw_thread_loop *loop_new(struct pw_loop *loop, + const char *name, + const struct spa_dict *props) { struct pw_thread_loop *this; pthread_mutexattr_t attr; @@ -125,6 +112,14 @@ struct pw_thread_loop *pw_thread_loop_new(struct pw_loop *loop, pw_log_debug(NAME" %p: new", this); + if (loop == NULL) { + loop = pw_loop_new(props); + this->created = true; + } + if (loop == NULL) { + res = -errno; + goto clean_this; + } this->loop = loop; this->name = name ? strdup(name) : NULL; @@ -149,19 +144,49 @@ struct pw_thread_loop *pw_thread_loop_new(struct pw_loop *loop, return this; - clean_acceptcond: +clean_acceptcond: pthread_cond_destroy(&this->accept_cond); - clean_cond: +clean_cond: pthread_cond_destroy(&this->cond); - clean_lock: +clean_lock: pthread_mutex_destroy(&this->lock); - clean_this: +clean_this: + if (this->created && this->loop) + pw_loop_destroy(this->loop); free(this->name); free(this); errno = -res; return NULL; } +/** Create a new \ref pw_thread_loop + * + * \param loop the loop to wrap + * \param name the name of the thread or NULL + * \return a newly allocated \ref pw_thread_loop + * + * Make a new \ref pw_thread_loop that will run \a loop in + * a thread with \a name. + * + * After this function you should probably call pw_thread_loop_start() to + * actually start the thread + * + * \memberof pw_thread_loop + */ +SPA_EXPORT +struct pw_thread_loop *pw_thread_loop_new(const char *name, + const struct spa_dict *props) +{ + return loop_new(NULL, name, props); +} + +SPA_EXPORT +struct pw_thread_loop *pw_thread_loop_new_full(struct pw_loop *loop, + const char *name, const struct spa_dict *props) +{ + return loop_new(loop, name, props); +} + /** Destroy a threaded loop \memberof pw_thread_loop */ SPA_EXPORT void pw_thread_loop_destroy(struct pw_thread_loop *loop) @@ -174,6 +199,9 @@ void pw_thread_loop_destroy(struct pw_thread_loop *loop) pw_loop_destroy_source(loop->loop, loop->event); + if (loop->created && loop->loop) + pw_loop_destroy(loop->loop); + pthread_cond_destroy(&loop->accept_cond); pthread_cond_destroy(&loop->cond); pthread_mutex_destroy(&loop->lock); diff --git a/src/pipewire/thread-loop.h b/src/pipewire/thread-loop.h index 00c71b83..c26c523a 100644 --- a/src/pipewire/thread-loop.h +++ b/src/pipewire/thread-loop.h @@ -103,9 +103,14 @@ struct pw_thread_loop_events { void (*destroy) (void *data); }; -/** Make a new thread loop with the given name */ +/** Make a new thread loop with the given name and optional properties. */ struct pw_thread_loop * -pw_thread_loop_new(struct pw_loop *loop, const char *name); +pw_thread_loop_new(const char *name, const struct spa_dict *props); + +/** Make a new thread loop with the given loop, name and optional properties. + * When \a loop is NULL, a new loop will be created. */ +struct pw_thread_loop * +pw_thread_loop_new_full(struct pw_loop *loop, const char *name, const struct spa_dict *props); /** Destroy a thread loop */ void pw_thread_loop_destroy(struct pw_thread_loop *loop); |