diff --git a/gst-libs/gst/transcoder/gsttranscoder-message-private.h b/gst-libs/gst/transcoder/gsttranscoder-private.h similarity index 79% rename from gst-libs/gst/transcoder/gsttranscoder-message-private.h rename to gst-libs/gst/transcoder/gsttranscoder-private.h index 2c2ba213d8..edf8daf9ca 100644 --- a/gst-libs/gst/transcoder/gsttranscoder-message-private.h +++ b/gst-libs/gst/transcoder/gsttranscoder-private.h @@ -28,3 +28,16 @@ #define GST_TRANSCODER_MESSAGE_DATA_ERROR "error" #define GST_TRANSCODER_MESSAGE_DATA_WARNING "warning" #define GST_TRANSCODER_MESSAGE_DATA_ISSUE_DETAILS "issue-details" + +struct _GstTranscoderSignalAdapter +{ + GObject parent; + GstBus *bus; + GSource *source; + + GWeakRef transcoder; +}; + + +GstTranscoderSignalAdapter * gst_transcoder_signal_adapter_new_sync_emit (GstTranscoder * transcoder); +GstTranscoderSignalAdapter * gst_transcoder_signal_adapter_new (GstTranscoder * transcoder, GMainContext * context); \ No newline at end of file diff --git a/gst-libs/gst/transcoder/gsttranscoder-signal-adapter.c b/gst-libs/gst/transcoder/gsttranscoder-signal-adapter.c index ac41275986..9cad67c0d9 100644 --- a/gst-libs/gst/transcoder/gsttranscoder-signal-adapter.c +++ b/gst-libs/gst/transcoder/gsttranscoder-signal-adapter.c @@ -26,7 +26,7 @@ #include "gsttranscoder.h" #include "gsttranscoder-signal-adapter.h" -#include "gsttranscoder-message-private.h" +#include "gsttranscoder-private.h" #include @@ -52,15 +52,6 @@ enum static GParamSpec *param_specs[PROP_LAST] = { NULL, }; -struct _GstTranscoderSignalAdapter -{ - GObject parent; - GstBus *bus; - GSource *source; - - GstTranscoder *transcoder; -}; - struct _GstTranscoderSignalAdapterClass { GObjectClass parent_class; @@ -189,10 +180,6 @@ gst_transcoder_signal_adapter_new (GstTranscoder * transcoder, g_return_val_if_fail (GST_IS_TRANSCODER (transcoder), NULL); - if (!context) { - context = g_main_context_get_thread_default (); - } - self = g_object_new (GST_TYPE_TRANSCODER_SIGNAL_ADAPTER, NULL); self->bus = gst_transcoder_get_message_bus (transcoder); self->source = gst_bus_create_watch (self->bus); @@ -205,6 +192,7 @@ gst_transcoder_signal_adapter_new (GstTranscoder * transcoder, return NULL; } + g_weak_ref_set (&self->transcoder, transcoder); g_source_attach (self->source, context); g_source_set_callback (self->source, (GSourceFunc) gst_transcoder_signal_adapter_on_message, self, NULL); @@ -256,7 +244,6 @@ gst_transcoder_signal_adapter_dispose (GObject * object) } gst_clear_object (&self->bus); - gst_clear_object (&self->transcoder); G_OBJECT_CLASS (parent_class)->dispose (object); } @@ -269,7 +256,7 @@ gst_transcoder_signal_adapter_get_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_TRANSCODER: - g_value_set_object (value, self->transcoder); + g_value_take_object (value, g_weak_ref_get (&self->transcoder)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -331,12 +318,12 @@ gst_transcoder_signal_adapter_class_init (GstTranscoderSignalAdapterClass * * gst_transcoder_signal_adapter_get_transcoder: * @self: The #GstTranscoderSignalAdapter * - * Returns: (transfer full): The #GstTranscoder @self is tracking + * Returns: (transfer full)(nullable): The #GstTranscoder @self is tracking * * Since: 1.20 */ GstTranscoder * gst_transcoder_signal_adapter_get_transcoder (GstTranscoderSignalAdapter * self) { - return gst_object_ref (self->transcoder); + return g_weak_ref_get (&self->transcoder); } diff --git a/gst-libs/gst/transcoder/gsttranscoder-signal-adapter.h b/gst-libs/gst/transcoder/gsttranscoder-signal-adapter.h index 6dda124375..198efe073a 100644 --- a/gst-libs/gst/transcoder/gsttranscoder-signal-adapter.h +++ b/gst-libs/gst/transcoder/gsttranscoder-signal-adapter.h @@ -48,12 +48,6 @@ GST_TRANSCODER_API */ G_DECLARE_FINAL_TYPE(GstTranscoderSignalAdapter, gst_transcoder_signal_adapter, GST, TRANSCODER_SIGNAL_ADAPTER, GObject) -GST_TRANSCODER_API -GstTranscoderSignalAdapter * gst_transcoder_signal_adapter_new_sync_emit (GstTranscoder * transcoder); - -GST_TRANSCODER_API -GstTranscoderSignalAdapter * gst_transcoder_signal_adapter_new (GstTranscoder * transcoder, GMainContext * context); - GST_TRANSCODER_API GstTranscoder * gst_transcoder_signal_adapter_get_transcoder (GstTranscoderSignalAdapter * self); diff --git a/gst-libs/gst/transcoder/gsttranscoder.c b/gst-libs/gst/transcoder/gsttranscoder.c index 850129a835..c87cb8d04f 100644 --- a/gst-libs/gst/transcoder/gsttranscoder.c +++ b/gst-libs/gst/transcoder/gsttranscoder.c @@ -28,7 +28,7 @@ */ #include "gsttranscoder.h" -#include "gsttranscoder-message-private.h" +#include "gsttranscoder-private.h" GST_DEBUG_CATEGORY_STATIC (gst_transcoder_debug); #define GST_CAT_DEFAULT gst_transcoder_debug @@ -89,6 +89,8 @@ struct _GstTranscoder GstClockTime last_duration; GstBus *api_bus; + GstTranscoderSignalAdapter *signal_adapter; + GstTranscoderSignalAdapter *sync_signal_adapter; }; struct _GstTranscoderClass @@ -220,10 +222,14 @@ gst_transcoder_dispose (GObject * object) GST_TRACE_OBJECT (self, "Stopping main thread"); + GST_OBJECT_LOCK (self); if (self->loop) { g_main_loop_quit (self->loop); + GST_OBJECT_UNLOCK (self); g_thread_join (self->thread); + + GST_OBJECT_LOCK (self); self->thread = NULL; g_main_loop_unref (self->loop); @@ -232,6 +238,9 @@ gst_transcoder_dispose (GObject * object) g_main_context_unref (self->context); self->context = NULL; + gst_clear_object (&self->signal_adapter); + gst_clear_object (&self->sync_signal_adapter); + GST_OBJECT_UNLOCK (self); } G_OBJECT_CLASS (parent_class)->dispose (object); @@ -927,7 +936,7 @@ gst_transcoder_run (GstTranscoder * self, GError ** error) { RunSyncData data = { 0, }; GstTranscoderSignalAdapter *signal_adapter = - gst_transcoder_signal_adapter_new (self, NULL); + gst_transcoder_get_signal_adapter (self, NULL); data.loop = g_main_loop_new (NULL, FALSE); g_signal_connect_swapped (signal_adapter, "error", G_CALLBACK (_error_cb), @@ -1233,6 +1242,76 @@ gst_transcoder_get_message_bus (GstTranscoder * self) return g_object_ref (self->api_bus); } +/** + * gst_transcoder_get_sync_signal_adapter: + * @self: (transfer none): #GstTranscoder instance to emit signals synchronously + * for. + * + * Gets the #GstTranscoderSignalAdapter attached to @self to emit signals from + * its thread of emission. + * + * Returns: (transfer full): The #GstTranscoderSignalAdapter to connect signal + * handlers to. + * + * Since: 1.20 + */ +GstTranscoderSignalAdapter * +gst_transcoder_get_sync_signal_adapter (GstTranscoder * self) +{ + g_return_val_if_fail (GST_IS_TRANSCODER (self), NULL); + + GST_OBJECT_LOCK (self); + if (!self->sync_signal_adapter) + self->sync_signal_adapter = + gst_transcoder_signal_adapter_new_sync_emit (self); + GST_OBJECT_UNLOCK (self); + + return g_object_ref (self->sync_signal_adapter); +} + +/** + * gst_transcoder_get_signal_adapter: + * @self: (transfer none): #GstTranscoder instance to emit signals for. + * @context: (nullable): A #GMainContext on which the main-loop will process + * transcoder bus messages on. Can be NULL (thread-default + * context will be used then). + * + * Gets the #GstTranscoderSignalAdapter attached to @self if it is attached to + * the right #GMainContext. If no #GstTranscoderSignalAdapter has been created + * yet, it will be created and returned, other calls will return that same + * adapter until it is destroyed, at which point, a new one can be attached the + * same way. + * + * Returns: (transfer full)(nullable): The #GstTranscoderSignalAdapter to + * connect signal handlers to. + * + * Since: 1.20 + */ +GstTranscoderSignalAdapter * +gst_transcoder_get_signal_adapter (GstTranscoder * self, GMainContext * context) +{ + g_return_val_if_fail (GST_IS_TRANSCODER (self), NULL); + + if (!context) + context = g_main_context_get_thread_default (); + if (!context) + context = g_main_context_default (); + + GST_OBJECT_LOCK (self); + if (!self->signal_adapter) { + self->signal_adapter = gst_transcoder_signal_adapter_new (self, context); + } else if (g_source_get_context (self->signal_adapter->source) != context) { + GST_WARNING_OBJECT (self, "Trying to get an adapter for a different " + "GMainContext than the one attached, this is not possible"); + GST_OBJECT_UNLOCK (self); + + return NULL; + } + GST_OBJECT_UNLOCK (self); + + return g_object_ref (self->signal_adapter); +} + /** * gst_transcoder_message_get_name: * @message: a #GstTranscoderMessage diff --git a/gst-libs/gst/transcoder/gsttranscoder.h b/gst-libs/gst/transcoder/gsttranscoder.h index dcd22860d7..5f890c6385 100644 --- a/gst-libs/gst/transcoder/gsttranscoder.h +++ b/gst-libs/gst/transcoder/gsttranscoder.h @@ -138,6 +138,14 @@ void gst_transcoder_set_avoid_reencoding (GstTranscoder * self, #include "gsttranscoder-signal-adapter.h" +GST_TRANSCODER_API +GstTranscoderSignalAdapter* +gst_transcoder_get_signal_adapter (GstTranscoder * self, + GMainContext *context); +GST_TRANSCODER_API +GstTranscoderSignalAdapter* +gst_transcoder_get_sync_signal_adapter (GstTranscoder * self); + G_END_DECLS #endif diff --git a/tools/gst-transcoder.c b/tools/gst-transcoder.c index 3d1bc83d22..37bbe413fb 100644 --- a/tools/gst-transcoder.c +++ b/tools/gst-transcoder.c @@ -376,7 +376,7 @@ main (int argc, char *argv[]) gst_transcoder_set_avoid_reencoding (transcoder, TRUE); gst_transcoder_set_cpu_usage (transcoder, settings.cpu_usage); - signal_adapter = gst_transcoder_signal_adapter_new (transcoder, NULL); + signal_adapter = gst_transcoder_get_signal_adapter (transcoder, NULL); g_signal_connect_swapped (signal_adapter, "position-updated", G_CALLBACK (position_updated_cb), transcoder); g_signal_connect_swapped (signal_adapter, "warning", G_CALLBACK (_warning_cb),