diff --git a/src/gst/gstpipewireclock.c b/src/gst/gstpipewireclock.c index d8e6da6a0..0502a0a65 100644 --- a/src/gst/gstpipewireclock.c +++ b/src/gst/gstpipewireclock.c @@ -14,12 +14,12 @@ GST_DEBUG_CATEGORY_STATIC (gst_pipewire_clock_debug_category); G_DEFINE_TYPE (GstPipeWireClock, gst_pipewire_clock, GST_TYPE_SYSTEM_CLOCK); GstClock * -gst_pipewire_clock_new (struct pw_stream *stream, GstClockTime last_time) +gst_pipewire_clock_new (GstPipeWireStream *stream, GstClockTime last_time) { GstPipeWireClock *clock; clock = g_object_new (GST_TYPE_PIPEWIRE_CLOCK, NULL); - clock->stream = stream; + g_weak_ref_set (&clock->stream, stream); clock->last_time = last_time; clock->time_offset = last_time; @@ -30,14 +30,18 @@ static GstClockTime gst_pipewire_clock_get_internal_time (GstClock * clock) { GstPipeWireClock *pclock = (GstPipeWireClock *) clock; + g_autoptr (GstPipeWireStream) s = g_weak_ref_get (&pclock->stream); GstClockTime result; uint64_t now; - now = pw_stream_get_nsec(pclock->stream); + if (G_UNLIKELY (!s)) + return pclock->last_time; + + now = pw_stream_get_nsec(s->pwstream); #if 0 struct pw_time t; - if (pclock->stream == NULL || - pw_stream_get_time_n (pclock->stream, &t, sizeof(t)) < 0 || + if (s->pwstream == NULL || + pw_stream_get_time_n (s->pwstream, &t, sizeof(t)) < 0 || t.rate.denom == 0) return pclock->last_time; @@ -64,6 +68,8 @@ gst_pipewire_clock_finalize (GObject * object) GST_DEBUG_OBJECT (clock, "finalize"); + g_weak_ref_set (&clock->stream, NULL); + G_OBJECT_CLASS (gst_pipewire_clock_parent_class)->finalize (object); } diff --git a/src/gst/gstpipewireclock.h b/src/gst/gstpipewireclock.h index 91ae0306e..f6019dd55 100644 --- a/src/gst/gstpipewireclock.h +++ b/src/gst/gstpipewireclock.h @@ -5,8 +5,10 @@ #ifndef __GST_PIPEWIRE_CLOCK_H__ #define __GST_PIPEWIRE_CLOCK_H__ -#include +#include "config.h" +#include "gstpipewirestream.h" +#include #include G_BEGIN_DECLS @@ -30,7 +32,8 @@ typedef struct _GstPipeWireClockClass GstPipeWireClockClass; struct _GstPipeWireClock { GstSystemClock parent; - struct pw_stream *stream; + GWeakRef stream; + GstClockTime last_time; GstClockTimeDiff time_offset; }; @@ -41,7 +44,7 @@ struct _GstPipeWireClockClass { GType gst_pipewire_clock_get_type (void); -GstClock * gst_pipewire_clock_new (struct pw_stream *stream, +GstClock * gst_pipewire_clock_new (GstPipeWireStream *stream, GstClockTime last_time); void gst_pipewire_clock_reset (GstPipeWireClock *clock, GstClockTime time); diff --git a/src/gst/gstpipewirepool.c b/src/gst/gstpipewirepool.c index bc0219edf..10013080b 100644 --- a/src/gst/gstpipewirepool.c +++ b/src/gst/gstpipewirepool.c @@ -35,11 +35,12 @@ static guint pool_signals[LAST_SIGNAL] = { 0 }; static GQuark pool_data_quark; GstPipeWirePool * -gst_pipewire_pool_new (void) +gst_pipewire_pool_new (GstPipeWireStream *stream) { GstPipeWirePool *pool; pool = g_object_new (GST_TYPE_PIPEWIRE_POOL, NULL); + g_weak_ref_set (&pool->stream, stream); return pool; } @@ -148,15 +149,19 @@ acquire_buffer (GstBufferPool * pool, GstBuffer ** buffer, GstBufferPoolAcquireParams * params) { GstPipeWirePool *p = GST_PIPEWIRE_POOL (pool); + g_autoptr (GstPipeWireStream) s = g_weak_ref_get (&p->stream); GstPipeWirePoolData *data; struct pw_buffer *b; + if (G_UNLIKELY (!s)) + return GST_FLOW_ERROR; + GST_OBJECT_LOCK (pool); while (TRUE) { if (G_UNLIKELY (GST_BUFFER_POOL_IS_FLUSHING (pool))) goto flushing; - if ((b = pw_stream_dequeue_buffer(p->stream))) + if ((b = pw_stream_dequeue_buffer(s->pwstream))) break; if (params && (params->flags & GST_BUFFER_POOL_ACQUIRE_FLAG_DONTWAIT)) @@ -262,6 +267,7 @@ gst_pipewire_pool_finalize (GObject * object) GstPipeWirePool *pool = GST_PIPEWIRE_POOL (object); GST_DEBUG_OBJECT (pool, "finalize"); + g_weak_ref_set (&pool->stream, NULL); g_object_unref (pool->fd_allocator); g_object_unref (pool->dmabuf_allocator); diff --git a/src/gst/gstpipewirepool.h b/src/gst/gstpipewirepool.h index d05fa3abf..2c085f259 100644 --- a/src/gst/gstpipewirepool.h +++ b/src/gst/gstpipewirepool.h @@ -5,6 +5,8 @@ #ifndef __GST_PIPEWIRE_POOL_H__ #define __GST_PIPEWIRE_POOL_H__ +#include "gstpipewirestream.h" + #include #include @@ -45,7 +47,7 @@ struct _GstPipeWirePoolData { struct _GstPipeWirePool { GstBufferPool parent; - struct pw_stream *stream; + GWeakRef stream; guint n_buffers; gboolean add_metavideo; @@ -63,7 +65,7 @@ struct _GstPipeWirePoolClass { GType gst_pipewire_pool_get_type (void); -GstPipeWirePool * gst_pipewire_pool_new (void); +GstPipeWirePool * gst_pipewire_pool_new (GstPipeWireStream *stream); void gst_pipewire_pool_wrap_buffer (GstPipeWirePool *pool, struct pw_buffer *buffer); void gst_pipewire_pool_remove_buffer (GstPipeWirePool *pool, struct pw_buffer *buffer); diff --git a/src/gst/gstpipewirestream.c b/src/gst/gstpipewirestream.c index 7591d46c2..4cadcd5c8 100644 --- a/src/gst/gstpipewirestream.c +++ b/src/gst/gstpipewirestream.c @@ -5,6 +5,9 @@ #include "gstpipewirestream.h" +#include "gstpipewirepool.h" +#include "gstpipewireclock.h" + GST_DEBUG_CATEGORY_STATIC (pipewire_stream_debug); #define GST_CAT_DEFAULT pipewire_stream_debug @@ -15,7 +18,7 @@ gst_pipewire_stream_init (GstPipeWireStream * self) { self->fd = -1; self->client_name = g_strdup (pw_get_client_name()); - self->pool = gst_pipewire_pool_new (); + self->pool = gst_pipewire_pool_new (self); } static void @@ -120,9 +123,7 @@ gst_pipewire_stream_open (GstPipeWireStream * self, self->element); /* create clock */ - self->clock = gst_pipewire_clock_new (self->pwstream, 0); - - self->pool->stream = self->pwstream; + self->clock = gst_pipewire_clock_new (self, 0); pw_thread_loop_unlock (self->core->loop); @@ -149,13 +150,10 @@ gst_pipewire_stream_close (GstPipeWireStream * self) { GST_DEBUG_OBJECT (self, "close"); - self->pool->stream = NULL; - /* destroy the clock */ gst_element_post_message (GST_ELEMENT (self->element), gst_message_new_clock_lost (GST_OBJECT_CAST (self->element), self->clock)); - - GST_PIPEWIRE_CLOCK (self->clock)->stream = NULL; + g_weak_ref_set (&GST_PIPEWIRE_CLOCK (self->clock)->stream, NULL); g_clear_object (&self->clock); /* destroy the pw stream */ diff --git a/src/gst/gstpipewirestream.h b/src/gst/gstpipewirestream.h index a9626c0e7..ff8c8e2e6 100644 --- a/src/gst/gstpipewirestream.h +++ b/src/gst/gstpipewirestream.h @@ -9,14 +9,14 @@ #include "config.h" #include "gstpipewirecore.h" -#include "gstpipewirepool.h" -#include "gstpipewireclock.h" #include #include G_BEGIN_DECLS +typedef struct _GstPipeWirePool GstPipeWirePool; + #define GST_TYPE_PIPEWIRE_STREAM (gst_pipewire_stream_get_type()) G_DECLARE_FINAL_TYPE(GstPipeWireStream, gst_pipewire_stream, GST, PIPEWIRE_STREAM, GstObject)