From e3fe89aba8915a1bac345bb6769f76e55cd13bcd Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Tue, 16 Jan 2024 02:52:49 +1100 Subject: [PATCH] timecodestamper: Don't do finalizing in dispose Add a finalize method and release locks and things in there, instead of in the dispose method. Dispose may be called multiple times, at any time, and should just safely release references to other memory that might reference it back. In this case, timecodestamper would later crash in the element dispose method trying to take the freed mutex from gst_timecodestamper_release_pad(). Part-of: --- .../gst/timecode/gsttimecodestamper.c | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/subprojects/gst-plugins-bad/gst/timecode/gsttimecodestamper.c b/subprojects/gst-plugins-bad/gst/timecode/gsttimecodestamper.c index c616058de9..3f118bdb72 100644 --- a/subprojects/gst-plugins-bad/gst/timecode/gsttimecodestamper.c +++ b/subprojects/gst-plugins-bad/gst/timecode/gsttimecodestamper.c @@ -116,6 +116,7 @@ GST_STATIC_PAD_TEMPLATE ("ltc_sink", GST_STATIC_CAPS ("audio/x-raw,format=U8,rate=[1,max],channels=1") ); +static void gst_timecodestamper_finalize (GObject * object); static void gst_timecodestamper_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_timecodestamper_get_property (GObject * object, guint prop_id, @@ -232,6 +233,7 @@ gst_timecodestamper_class_init (GstTimeCodeStamperClass * klass) gobject_class->set_property = gst_timecodestamper_set_property; gobject_class->get_property = gst_timecodestamper_get_property; + gobject_class->finalize = gst_timecodestamper_finalize; gobject_class->dispose = gst_timecodestamper_dispose; g_object_class_install_property (gobject_class, PROP_SOURCE, @@ -402,6 +404,20 @@ gst_timecodestamper_init (GstTimeCodeStamper * timecodestamper) #endif } +static void +gst_timecodestamper_finalize (GObject * object) +{ +#if HAVE_LTC + GstTimeCodeStamper *timecodestamper = GST_TIME_CODE_STAMPER (object); + + g_cond_clear (&timecodestamper->ltc_cond_video); + g_cond_clear (&timecodestamper->ltc_cond_audio); + g_mutex_clear (&timecodestamper->mutex); +#endif + + G_OBJECT_CLASS (gst_timecodestamper_parent_class)->finalize (object); +} + static void gst_timecodestamper_dispose (GObject * object) { @@ -433,9 +449,7 @@ gst_timecodestamper_dispose (GObject * object) timecodestamper->rtc_tc = NULL; } #if HAVE_LTC - g_cond_clear (&timecodestamper->ltc_cond_video); - g_cond_clear (&timecodestamper->ltc_cond_audio); - g_mutex_clear (&timecodestamper->mutex); + g_mutex_lock (&timecodestamper->mutex); { TimestampedTimecode *tc; while ((tc = g_queue_pop_tail (&timecodestamper->ltc_current_tcs))) { @@ -458,6 +472,7 @@ gst_timecodestamper_dispose (GObject * object) gst_audio_stream_align_free (timecodestamper->stream_align); timecodestamper->stream_align = NULL; } + g_mutex_unlock (&timecodestamper->mutex); #endif G_OBJECT_CLASS (gst_timecodestamper_parent_class)->dispose (object);