From 8c2fd4fff7ea08f750f8139fc0616c476077d0ba Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Fri, 26 Feb 2021 15:31:29 -0300 Subject: [PATCH] transcoder: Rework the API to create/get SignalAdapter We can only have 1 single GstTranscoderSignalAdapter object for a given GstTranscoder object, this enforces that by avoiding to expose a constructor and instead add a method to GstTranscoder to get the signal adapter (internally creating it when needed). We can still cleanly ensure that the signal adapter is running for the requested GMainContext and return NULL if it is not the case. Part-of: --- ...sage-private.h => gsttranscoder-private.h} | 13 +++ .../transcoder/gsttranscoder-signal-adapter.c | 23 ++--- .../transcoder/gsttranscoder-signal-adapter.h | 6 -- gst-libs/gst/transcoder/gsttranscoder.c | 83 ++++++++++++++++++- gst-libs/gst/transcoder/gsttranscoder.h | 8 ++ tools/gst-transcoder.c | 2 +- 6 files changed, 108 insertions(+), 27 deletions(-) rename gst-libs/gst/transcoder/{gsttranscoder-message-private.h => gsttranscoder-private.h} (79%) 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),