summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2019-12-13 11:34:25 +0100
committerWim Taymans <wtaymans@redhat.com>2019-12-13 11:34:25 +0100
commit698ab911c348b9c937c0b90445efce9f7e653bb1 (patch)
treed47512a8dd1dcc4a87bb741756dd232176fbf6b0
parent828bd30879ec2d63c8477b85e9d946ac653c8bf3 (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.c22
-rw-r--r--pipewire-jack/src/pipewire-jack.c5
-rw-r--r--pipewire-pulseaudio/src/thread-mainloop.c2
-rw-r--r--src/daemon/main.c2
-rw-r--r--src/daemon/pipewire.conf.in2
-rw-r--r--src/gst/gstpipewiredeviceprovider.c35
-rw-r--r--src/gst/gstpipewiredeviceprovider.h3
-rw-r--r--src/gst/gstpipewiresink.c56
-rw-r--r--src/gst/gstpipewiresink.h3
-rw-r--r--src/gst/gstpipewiresrc.c81
-rw-r--r--src/gst/gstpipewiresrc.h3
-rw-r--r--src/pipewire/context.c3
-rw-r--r--src/pipewire/data-loop.c37
-rw-r--r--src/pipewire/data-loop.h4
-rw-r--r--src/pipewire/loop.c22
-rw-r--r--src/pipewire/loop.h5
-rw-r--r--src/pipewire/main-loop.c36
-rw-r--r--src/pipewire/main-loop.h5
-rw-r--r--src/pipewire/private.h2
-rw-r--r--src/pipewire/thread-loop.c70
-rw-r--r--src/pipewire/thread-loop.h9
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);