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: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2044>
This commit is contained in:
Thibault Saunier 2021-02-26 15:31:29 -03:00 committed by GStreamer Merge Bot
parent b6038523c1
commit 8c2fd4fff7
6 changed files with 108 additions and 27 deletions

View file

@ -28,3 +28,16 @@
#define GST_TRANSCODER_MESSAGE_DATA_ERROR "error" #define GST_TRANSCODER_MESSAGE_DATA_ERROR "error"
#define GST_TRANSCODER_MESSAGE_DATA_WARNING "warning" #define GST_TRANSCODER_MESSAGE_DATA_WARNING "warning"
#define GST_TRANSCODER_MESSAGE_DATA_ISSUE_DETAILS "issue-details" #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);

View file

@ -26,7 +26,7 @@
#include "gsttranscoder.h" #include "gsttranscoder.h"
#include "gsttranscoder-signal-adapter.h" #include "gsttranscoder-signal-adapter.h"
#include "gsttranscoder-message-private.h" #include "gsttranscoder-private.h"
#include <gst/gst.h> #include <gst/gst.h>
@ -52,15 +52,6 @@ enum
static GParamSpec *param_specs[PROP_LAST] = { NULL, }; static GParamSpec *param_specs[PROP_LAST] = { NULL, };
struct _GstTranscoderSignalAdapter
{
GObject parent;
GstBus *bus;
GSource *source;
GstTranscoder *transcoder;
};
struct _GstTranscoderSignalAdapterClass struct _GstTranscoderSignalAdapterClass
{ {
GObjectClass parent_class; GObjectClass parent_class;
@ -189,10 +180,6 @@ gst_transcoder_signal_adapter_new (GstTranscoder * transcoder,
g_return_val_if_fail (GST_IS_TRANSCODER (transcoder), NULL); 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 = g_object_new (GST_TYPE_TRANSCODER_SIGNAL_ADAPTER, NULL);
self->bus = gst_transcoder_get_message_bus (transcoder); self->bus = gst_transcoder_get_message_bus (transcoder);
self->source = gst_bus_create_watch (self->bus); self->source = gst_bus_create_watch (self->bus);
@ -205,6 +192,7 @@ gst_transcoder_signal_adapter_new (GstTranscoder * transcoder,
return NULL; return NULL;
} }
g_weak_ref_set (&self->transcoder, transcoder);
g_source_attach (self->source, context); g_source_attach (self->source, context);
g_source_set_callback (self->source, g_source_set_callback (self->source,
(GSourceFunc) gst_transcoder_signal_adapter_on_message, self, NULL); (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->bus);
gst_clear_object (&self->transcoder);
G_OBJECT_CLASS (parent_class)->dispose (object); 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) { switch (prop_id) {
case PROP_TRANSCODER: case PROP_TRANSCODER:
g_value_set_object (value, self->transcoder); g_value_take_object (value, g_weak_ref_get (&self->transcoder));
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); 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: * gst_transcoder_signal_adapter_get_transcoder:
* @self: The #GstTranscoderSignalAdapter * @self: The #GstTranscoderSignalAdapter
* *
* Returns: (transfer full): The #GstTranscoder @self is tracking * Returns: (transfer full)(nullable): The #GstTranscoder @self is tracking
* *
* Since: 1.20 * Since: 1.20
*/ */
GstTranscoder * GstTranscoder *
gst_transcoder_signal_adapter_get_transcoder (GstTranscoderSignalAdapter * self) gst_transcoder_signal_adapter_get_transcoder (GstTranscoderSignalAdapter * self)
{ {
return gst_object_ref (self->transcoder); return g_weak_ref_get (&self->transcoder);
} }

View file

@ -48,12 +48,6 @@ GST_TRANSCODER_API
*/ */
G_DECLARE_FINAL_TYPE(GstTranscoderSignalAdapter, gst_transcoder_signal_adapter, GST, TRANSCODER_SIGNAL_ADAPTER, GObject) 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 GST_TRANSCODER_API
GstTranscoder * gst_transcoder_signal_adapter_get_transcoder (GstTranscoderSignalAdapter * self); GstTranscoder * gst_transcoder_signal_adapter_get_transcoder (GstTranscoderSignalAdapter * self);

View file

@ -28,7 +28,7 @@
*/ */
#include "gsttranscoder.h" #include "gsttranscoder.h"
#include "gsttranscoder-message-private.h" #include "gsttranscoder-private.h"
GST_DEBUG_CATEGORY_STATIC (gst_transcoder_debug); GST_DEBUG_CATEGORY_STATIC (gst_transcoder_debug);
#define GST_CAT_DEFAULT gst_transcoder_debug #define GST_CAT_DEFAULT gst_transcoder_debug
@ -89,6 +89,8 @@ struct _GstTranscoder
GstClockTime last_duration; GstClockTime last_duration;
GstBus *api_bus; GstBus *api_bus;
GstTranscoderSignalAdapter *signal_adapter;
GstTranscoderSignalAdapter *sync_signal_adapter;
}; };
struct _GstTranscoderClass struct _GstTranscoderClass
@ -220,10 +222,14 @@ gst_transcoder_dispose (GObject * object)
GST_TRACE_OBJECT (self, "Stopping main thread"); GST_TRACE_OBJECT (self, "Stopping main thread");
GST_OBJECT_LOCK (self);
if (self->loop) { if (self->loop) {
g_main_loop_quit (self->loop); g_main_loop_quit (self->loop);
GST_OBJECT_UNLOCK (self);
g_thread_join (self->thread); g_thread_join (self->thread);
GST_OBJECT_LOCK (self);
self->thread = NULL; self->thread = NULL;
g_main_loop_unref (self->loop); g_main_loop_unref (self->loop);
@ -232,6 +238,9 @@ gst_transcoder_dispose (GObject * object)
g_main_context_unref (self->context); g_main_context_unref (self->context);
self->context = NULL; 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); G_OBJECT_CLASS (parent_class)->dispose (object);
@ -927,7 +936,7 @@ gst_transcoder_run (GstTranscoder * self, GError ** error)
{ {
RunSyncData data = { 0, }; RunSyncData data = { 0, };
GstTranscoderSignalAdapter *signal_adapter = 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); data.loop = g_main_loop_new (NULL, FALSE);
g_signal_connect_swapped (signal_adapter, "error", G_CALLBACK (_error_cb), 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); 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: * gst_transcoder_message_get_name:
* @message: a #GstTranscoderMessage * @message: a #GstTranscoderMessage

View file

@ -138,6 +138,14 @@ void gst_transcoder_set_avoid_reencoding (GstTranscoder * self,
#include "gsttranscoder-signal-adapter.h" #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 G_END_DECLS
#endif #endif

View file

@ -376,7 +376,7 @@ main (int argc, char *argv[])
gst_transcoder_set_avoid_reencoding (transcoder, TRUE); gst_transcoder_set_avoid_reencoding (transcoder, TRUE);
gst_transcoder_set_cpu_usage (transcoder, settings.cpu_usage); 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_signal_connect_swapped (signal_adapter, "position-updated",
G_CALLBACK (position_updated_cb), transcoder); G_CALLBACK (position_updated_cb), transcoder);
g_signal_connect_swapped (signal_adapter, "warning", G_CALLBACK (_warning_cb), g_signal_connect_swapped (signal_adapter, "warning", G_CALLBACK (_warning_cb),