tee: Check for the removed pad flag also in the slow pushing path
[platform/upstream/gstreamer.git] / gst / gsttracerutils.c
index 5b61730..2522cbf 100644 (file)
  * Boston, MA 02110-1301, USA.
  */
 
-/**
- * SECTION:gsttracerutils
- * @short_description: Tracing subsystem
+/* Tracing subsystem:
  *
  * The tracing subsystem provides hooks in the core library and API for modules
  * to attach to them.
  *
  * The user can activate tracers by setting the environment variable GST_TRACE
  * to a ';' separated list of tracers.
+ *
+ * Note that instantiating tracers at runtime is possible but is not thread safe
+ * and needs to be done before any pipeline state is set to PAUSED.
  */
 
 #define GST_USE_UNSTABLE_API
@@ -37,7 +38,7 @@
 #include "gsttracerfactory.h"
 #include "gsttracerutils.h"
 
-#ifndef GST_DISABLE_GST_DEBUG
+#ifndef GST_DISABLE_GST_TRACER_HOOKS
 
 /* tracer quarks */
 
 static const gchar *_quark_strings[] = {
   "pad-push-pre", "pad-push-post", "pad-push-list-pre", "pad-push-list-post",
   "pad-pull-range-pre", "pad-pull-range-post", "pad-push-event-pre",
-  "pad-push-event-post", "element-post-message-pre",
-  "element-post-message-post", "element-query-pre", "element-query-post"
+  "pad-push-event-post", "pad-query-pre", "pad-query-post",
+  "element-post-message-pre",
+  "element-post-message-post", "element-query-pre", "element-query-post",
+  "element-new", "element-add-pad", "element-remove-pad",
+  "bin-add-pre", "bin-add-post", "bin-remove-pre", "bin-remove-post",
+  "pad-link-pre", "pad-link-post", "pad-unlink-pre", "pad-unlink-post",
+  "element-change-state-pre", "element-change-state-post",
+  "mini-object-created", "mini-object-destroyed", "object-created",
+  "object-destroyed", "mini-object-reffed", "mini-object-unreffed",
+  "object-reffed", "object-unreffed",
 };
 
 GQuark _priv_gst_tracer_quark_table[GST_TRACER_QUARK_MAX];
@@ -57,39 +66,36 @@ GQuark _priv_gst_tracer_quark_table[GST_TRACER_QUARK_MAX];
 gboolean _priv_tracer_enabled = FALSE;
 GHashTable *_priv_tracers = NULL;
 
-typedef struct
-{
-  GstTracer *tracer;
-  GstTracerHookFunction func;
-} GstTracerHook;
-
 /* Initialize the tracing system */
 void
-_priv_gst_tracer_init (void)
+_priv_gst_tracing_init (void)
 {
-  const gchar *env = g_getenv ("GST_TRACE");
+  gint i = 0;
+  const gchar *env = g_getenv ("GST_TRACERS");
+
+  /* We initialize the tracer sub system even if the end
+   * user did not activate it through the env variable
+   * so that external tools can use it anyway */
+  GST_DEBUG ("Initializing GstTracer");
+  _priv_tracers = g_hash_table_new (NULL, NULL);
+
+  if (G_N_ELEMENTS (_quark_strings) != GST_TRACER_QUARK_MAX)
+    g_warning ("the quark table is not consistent! %d != %d",
+        (gint) G_N_ELEMENTS (_quark_strings), GST_TRACER_QUARK_MAX);
+
+  for (i = 0; i < GST_TRACER_QUARK_MAX; i++) {
+    _priv_gst_tracer_quark_table[i] =
+        g_quark_from_static_string (_quark_strings[i]);
+  }
 
   if (env != NULL && *env != '\0') {
     GstRegistry *registry = gst_registry_get ();
     GstPluginFeature *feature;
     GstTracerFactory *factory;
     gchar **t = g_strsplit_set (env, ";", 0);
-    gint i = 0;
     gchar *params;
 
     GST_INFO ("enabling tracers: '%s'", env);
-
-    if (G_N_ELEMENTS (_quark_strings) != GST_TRACER_QUARK_MAX)
-      g_warning ("the quark table is not consistent! %d != %d",
-          (gint) G_N_ELEMENTS (_quark_strings), GST_TRACER_QUARK_MAX);
-
-    for (i = 0; i < GST_TRACER_QUARK_MAX; i++) {
-      _priv_gst_tracer_quark_table[i] =
-          g_quark_from_static_string (_quark_strings[i]);
-    }
-
-    _priv_tracers = g_hash_table_new (NULL, NULL);
-
     i = 0;
     while (t[i]) {
       // check t[i] for params
@@ -108,12 +114,18 @@ _priv_gst_tracer_init (void)
       if ((feature = gst_registry_lookup_feature (registry, t[i]))) {
         factory = GST_TRACER_FACTORY (gst_plugin_feature_load (feature));
         if (factory) {
+          GstTracer *tracer;
+
           GST_INFO_OBJECT (factory, "creating tracer: type-id=%u",
               (guint) factory->type);
 
+          tracer = g_object_new (factory->type, "params", params, NULL);
+
+          /* Clear floating flag */
+          gst_object_ref_sink (tracer);
+
           /* tracers register them self to the hooks */
-          gst_object_unref (g_object_new (factory->type, "params", params,
-                  NULL));
+          gst_object_unref (tracer);
         } else {
           GST_WARNING_OBJECT (feature,
               "loading plugin containing feature %s failed!", t[i]);
@@ -128,7 +140,7 @@ _priv_gst_tracer_init (void)
 }
 
 void
-_priv_gst_tracer_deinit (void)
+_priv_gst_tracing_deinit (void)
 {
   GList *h_list, *h_node, *t_node;
   GstTracerHook *hook;
@@ -152,9 +164,8 @@ _priv_gst_tracer_deinit (void)
   _priv_tracers = NULL;
 }
 
-void
-gst_tracer_register_hook_id (GstTracer * tracer, GQuark detail,
-    GstTracerHookFunction func)
+static void
+gst_tracing_register_hook_id (GstTracer * tracer, GQuark detail, GCallback func)
 {
   gpointer key = GINT_TO_POINTER (detail);
   GList *list = g_hash_table_lookup (_priv_tracers, key);
@@ -169,38 +180,28 @@ gst_tracer_register_hook_id (GstTracer * tracer, GQuark detail,
   _priv_tracer_enabled = TRUE;
 }
 
+/**
+ * gst_tracing_register_hook:
+ * @tracer: the tracer
+ * @detail: the detailed hook
+ * @func: (scope async): the callback
+ *
+ * Register @func to be called when the trace hook @detail is getting invoked.
+ * Use %NULL for @detail to register to all hooks.
+ */
 void
-gst_tracer_register_hook (GstTracer * tracer, const gchar * detail,
-    GstTracerHookFunction func)
+gst_tracing_register_hook (GstTracer * tracer, const gchar * detail,
+    GCallback func)
 {
-  gst_tracer_register_hook_id (tracer, g_quark_try_string (detail), func);
+  gst_tracing_register_hook_id (tracer, g_quark_try_string (detail), func);
 }
 
+#else /* !GST_DISABLE_GST_TRACER_HOOKS */
+
 void
-gst_tracer_dispatch (GQuark detail, ...)
+gst_tracing_register_hook (GstTracer * tracer, const gchar * detail,
+    GCallback func)
 {
-  va_list var_args;
-  gpointer key = GINT_TO_POINTER (detail);
-  GList *list, *node;
-  GstTracerHook *hook;
-
-  list = g_hash_table_lookup (_priv_tracers, key);
-  GST_DEBUG ("calling %d tracers for '%s'", g_list_length (list),
-      g_quark_to_string (detail));
-  for (node = list; node; node = g_list_next (node)) {
-    hook = (GstTracerHook *) node->data;
-    va_start (var_args, detail);
-    hook->func (hook->tracer, var_args);
-    va_end (var_args);
-  }
-  list = g_hash_table_lookup (_priv_tracers, NULL);
-  GST_DEBUG ("calling %d tracers for '*'", g_list_length (list));
-  for (node = list; node; node = g_list_next (node)) {
-    hook = (GstTracerHook *) node->data;
-    va_start (var_args, detail);
-    hook->func (hook->tracer, var_args);
-    va_end (var_args);
-  }
 }
 
-#endif /* GST_DISABLE_GST_DEBUG */
+#endif /* GST_DISABLE_GST_TRACER_HOOKS */