summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Sauer <ensonic@users.sf.net>2014-07-18 07:49:38 +0200
committerStefan Sauer <ensonic@users.sf.net>2015-08-26 22:33:58 +0200
commit850554dcc16924339a6e47423a405ed25db04a5e (patch)
treeea7b3338f41ded31bac40d38300a56a24c346314
parentee5534abd39b2613201a14a1cd9466ee75b9ff3d (diff)
tracer: split into tracer and tracerutils
Keep tracer base class in tracer and move core support into the utils module. Add a unstable-api guard to the tracer.h so that external modules would need to acknowledge the status by setting GST_USE_UNSTABLE_API.
-rw-r--r--gst/Makefile.am2
-rw-r--r--gst/gst.h1
-rw-r--r--gst/gst_private.h2
-rw-r--r--gst/gstelement.c2
-rw-r--r--gst/gstpad.c2
-rw-r--r--gst/gstregistrychunks.c1
-rw-r--r--gst/gsttracer.c129
-rw-r--r--gst/gsttracer.h204
-rw-r--r--gst/gsttracerfactory.c1
-rw-r--r--gst/gsttracerfactory.h1
-rw-r--r--gst/gsttracerutils.c151
-rw-r--r--gst/gsttracerutils.h225
-rw-r--r--plugins/tracers/Makefile.am3
-rw-r--r--plugins/tracers/gstlatency.h1
-rw-r--r--plugins/tracers/gstlog.h1
-rw-r--r--plugins/tracers/gstrusage.h1
-rw-r--r--plugins/tracers/gststats.h1
17 files changed, 403 insertions, 325 deletions
diff --git a/gst/Makefile.am b/gst/Makefile.am
index 68203da52..1fadb97e4 100644
--- a/gst/Makefile.am
+++ b/gst/Makefile.am
@@ -117,6 +117,7 @@ libgstreamer_@GST_API_VERSION@_la_SOURCES = \
$(GST_TRACE_SRC) \
gsttracer.c \
gsttracerfactory.c \
+ gsttracerutils.c \
gsttypefind.c \
gsttypefindfactory.c \
gsturi.c \
@@ -221,6 +222,7 @@ gst_headers = \
gsttocsetter.h \
gsttracer.h \
gsttracerfactory.h \
+ gsttracerutils.h \
gsttypefind.h \
gsttypefindfactory.h \
gsturi.h \
diff --git a/gst/gst.h b/gst/gst.h
index c9ffed55b..a9c7dc4b7 100644
--- a/gst/gst.h
+++ b/gst/gst.h
@@ -77,7 +77,6 @@
#include <gst/gsttaskpool.h>
#include <gst/gsttoc.h>
#include <gst/gsttocsetter.h>
-#include <gst/gsttracer.h>
#include <gst/gsttracerfactory.h>
#include <gst/gsttypefind.h>
#include <gst/gsttypefindfactory.h>
diff --git a/gst/gst_private.h b/gst/gst_private.h
index 39e224587..384dc7b43 100644
--- a/gst/gst_private.h
+++ b/gst/gst_private.h
@@ -62,6 +62,8 @@ extern const char g_log_domain_gstreamer[];
#include "gstdatetime.h"
+#include "gsttracerutils.h"
+
G_BEGIN_DECLS
/* used by gstparse.c and grammar.y */
diff --git a/gst/gstelement.c b/gst/gstelement.c
index bed709bdc..e6d1e3d8c 100644
--- a/gst/gstelement.c
+++ b/gst/gstelement.c
@@ -90,7 +90,7 @@
#include "gstutils.h"
#include "gstinfo.h"
#include "gstquark.h"
-#include "gsttracer.h"
+#include "gsttracerutils.h"
#include "gstvalue.h"
#include "gst-i18n-lib.h"
#include "glib-compat-private.h"
diff --git a/gst/gstpad.c b/gst/gstpad.c
index 5c4ad4485..5ba5b3253 100644
--- a/gst/gstpad.c
+++ b/gst/gstpad.c
@@ -94,7 +94,7 @@
#include "gstutils.h"
#include "gstinfo.h"
#include "gsterror.h"
-#include "gsttracer.h"
+#include "gsttracerutils.h"
#include "gstvalue.h"
#include "glib-compat-private.h"
diff --git a/gst/gstregistrychunks.c b/gst/gstregistrychunks.c
index c88152d12..7712fcf60 100644
--- a/gst/gstregistrychunks.c
+++ b/gst/gstregistrychunks.c
@@ -31,7 +31,6 @@
#include <gst/gst_private.h>
#include <gst/gstconfig.h>
#include <gst/gstelement.h>
-#include <gst/gsttracer.h>
#include <gst/gsttracerfactory.h>
#include <gst/gsttypefind.h>
#include <gst/gsttypefindfactory.h>
diff --git a/gst/gsttracer.c b/gst/gsttracer.c
index 065ca3abb..42ec2b66c 100644
--- a/gst/gsttracer.c
+++ b/gst/gsttracer.c
@@ -1,7 +1,7 @@
/* GStreamer
* Copyright (C) 2013 Stefan Sauer <ensonic@users.sf.net>
*
- * gsttracer.h: tracing subsystem
+ * gsttracer.c: tracer base class
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -21,28 +21,20 @@
/**
* SECTION:gsttracer
- * @short_description: Tracing subsystem
- *
- * The tracing subsystem provides hooks in the core library and API for modules
- * to attach to them.
+ * @short_description: Tracing base class
*
* Tracing modules will subclass #GstTracer and register through
* gst_tracer_register(). Modules can attach to various hook-types - see
* #GstTracerHook. When invoked they receive hook specific contextual data,
* which they must not modify.
- *
- * The user can activate tracers by setting the environment variable GST_TRACE
- * to a ';' separated list of tracers.
*/
+#define GST_USE_UNSTABLE_API
+
#include "gst_private.h"
#include "gstenumtypes.h"
-#include "gstregistry.h"
#include "gsttracer.h"
#include "gsttracerfactory.h"
-#include "gstutils.h"
-
-#ifndef GST_DISABLE_GST_DEBUG
GST_DEBUG_CATEGORY_EXTERN (tracer_debug);
#define GST_CAT_DEFAULT tracer_debug
@@ -138,7 +130,7 @@ gst_tracer_get_property (GObject * object, guint prop_id,
}
}
-static void
+void
gst_tracer_invoke (GstTracer * self, GstTracerHookId hid,
GstTracerMessageId mid, va_list var_args)
{
@@ -206,115 +198,6 @@ gst_tracer_register (GstPlugin * plugin, const gchar * name, GType type)
return TRUE;
}
-/* tracing helpers */
-
-gboolean _priv_tracer_enabled = FALSE;
-/* TODO(ensonic): use GPtrArray ? */
-GList *_priv_tracers[GST_TRACER_HOOK_ID_LAST] = { NULL, };
-
-/* Initialize the debugging system */
-void
-_priv_gst_tracer_init (void)
-{
- const gchar *env = g_getenv ("GST_TRACE");
-
- if (env != NULL && *env != '\0') {
- GstRegistry *registry = gst_registry_get ();
- GstPluginFeature *feature;
- GstTracerFactory *factory;
- GstTracerHook mask;
- GstTracer *tracer;
- gchar **t = g_strsplit_set (env, ";", 0);
- gint i = 0, j;
- gchar *params;
-
- GST_INFO ("enabling tracers: '%s'", env);
-
- while (t[i]) {
- // check t[i] for params
- if ((params = strchr (t[i], '('))) {
- gchar *end = strchr (&params[1], ')');
- *params = '\0';
- params++;
- if (end)
- *end = '\0';
- } else {
- params = NULL;
- }
-
- GST_INFO ("checking tracer: '%s'", t[i]);
-
- if ((feature = gst_registry_lookup_feature (registry, t[i]))) {
- factory = GST_TRACER_FACTORY (gst_plugin_feature_load (feature));
- if (factory) {
- GST_INFO_OBJECT (factory, "creating tracer: type-id=%u",
- (guint) factory->type);
-
- tracer = g_object_new (factory->type, "params", params, NULL);
- g_object_get (tracer, "mask", &mask, NULL);
-
- if (mask) {
- /* add to lists according to mask */
- j = 0;
- while (mask && (j < GST_TRACER_HOOK_ID_LAST)) {
- if (mask & 1) {
- _priv_tracers[j] = g_list_prepend (_priv_tracers[j],
- gst_object_ref (tracer));
- GST_WARNING_OBJECT (tracer, "added tracer to hook %d", j);
- }
- mask >>= 1;
- j++;
- }
-
- _priv_tracer_enabled = TRUE;
- } else {
- GST_WARNING_OBJECT (tracer,
- "tracer with zero mask won't have any effect");
- }
- gst_object_unref (tracer);
- } else {
- GST_WARNING_OBJECT (feature,
- "loading plugin containing feature %s failed!", t[i]);
- }
- } else {
- GST_WARNING ("no tracer named '%s'", t[i]);
- }
- i++;
- }
- g_strfreev (t);
- }
-}
-
-void
-_priv_gst_tracer_deinit (void)
-{
- gint i;
- GList *node;
-
- /* shutdown tracers for final reports */
- for (i = 0; i < GST_TRACER_HOOK_ID_LAST; i++) {
- for (node = _priv_tracers[i]; node; node = g_list_next (node)) {
- gst_object_unref (node->data);
- }
- g_list_free (_priv_tracers[i]);
- _priv_tracers[i] = NULL;
- }
- _priv_tracer_enabled = FALSE;
-}
-
-void
-gst_tracer_dispatch (GstTracerHookId hid, GstTracerMessageId mid, ...)
-{
- va_list var_args;
- GList *node;
-
- for (node = _priv_tracers[hid]; node; node = g_list_next (node)) {
- va_start (var_args, mid);
- gst_tracer_invoke (node->data, hid, mid, var_args);
- va_end (var_args);
- }
-}
-
/* tracing module helpers */
void
@@ -328,5 +211,3 @@ gst_tracer_log_trace (GstStructure * s)
g_free (data);
gst_structure_free (s);
}
-
-#endif /* GST_DISABLE_GST_DEBUG */
diff --git a/gst/gsttracer.h b/gst/gsttracer.h
index 99f1982de..02e2ec0a1 100644
--- a/gst/gsttracer.h
+++ b/gst/gsttracer.h
@@ -1,7 +1,7 @@
/* GStreamer
* Copyright (C) 2013 Stefan Sauer <ensonic@users.sf.net>
*
- * gsttracer.h: tracing subsystem
+ * gsttracer.h: tracer base class
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -22,63 +22,18 @@
#ifndef __GST_TRACER_H__
#define __GST_TRACER_H__
+#ifndef GST_USE_UNSTABLE_API
+#warning "The tracer subsystem is unstable API and may change in future."
+#warning "You can define GST_USE_UNSTABLE_API to avoid this warning."
+#endif
+
#include <glib.h>
#include <glib-object.h>
#include <gst/gstconfig.h>
-#include <gst/gstbin.h>
+#include <gst/gsttracerutils.h>
G_BEGIN_DECLS
-#ifndef GST_DISABLE_GST_DEBUG
-
-/* hook flags and ids */
-
-typedef enum
-{
- GST_TRACER_HOOK_NONE = 0,
- GST_TRACER_HOOK_BUFFERS = (1 << 0),
- GST_TRACER_HOOK_EVENTS = (1 << 1),
- GST_TRACER_HOOK_MESSAGES = (1 << 2),
- GST_TRACER_HOOK_QUERIES = (1 << 3),
- GST_TRACER_HOOK_TOPOLOGY = (1 << 4),
- /*
- GST_TRACER_HOOK_TIMER
- */
- GST_TRACER_HOOK_ALL = (1 << 5) - 1
-} GstTracerHook;
-
-typedef enum
-{
- GST_TRACER_HOOK_ID_BUFFERS = 0,
- GST_TRACER_HOOK_ID_EVENTS,
- GST_TRACER_HOOK_ID_MESSAGES,
- GST_TRACER_HOOK_ID_QUERIES,
- GST_TRACER_HOOK_ID_TOPLOGY,
- /*
- GST_TRACER_HOOK_ID_TIMER
- */
- GST_TRACER_HOOK_ID_LAST
-} GstTracerHookId;
-
-typedef enum
-{
- GST_TRACER_MESSAGE_ID_PAD_PUSH_PRE = 0,
- GST_TRACER_MESSAGE_ID_PAD_PUSH_POST,
- GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_PRE,
- GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_POST,
- GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_PRE,
- GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_POST,
- GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_PRE,
- GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_POST,
- GST_TRACER_MESSAGE_ID_ELEMENT_POST_MESSAGE_PRE,
- GST_TRACER_MESSAGE_ID_ELEMENT_POST_MESSAGE_POST,
- GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_PRE,
- GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_POST,
- GST_TRACER_MESSAGE_ID_LAST
-} GstTracerMessageId;
-
-/* tracing plugins */
-
typedef struct _GstTracer GstTracer;
typedef struct _GstTracerPrivate GstTracerPrivate;
typedef struct _GstTracerClass GstTracerClass;
@@ -111,149 +66,10 @@ struct _GstTracerClass {
gpointer _gst_reserved[GST_PADDING];
};
-GType gst_tracer_get_type (void);
-
-/* tracing hooks */
-
-void _priv_gst_tracer_init (void);
-void _priv_gst_tracer_deinit (void);
-
-/* tracing modules */
-
-gboolean gst_tracer_register (GstPlugin * plugin, const gchar * name, GType type);
-
-/* tracing helpers */
-
-void gst_tracer_dispatch (GstTracerHookId hid, GstTracerMessageId mid, ...);
-
-/* tracing module helpers */
-
-void gst_tracer_log_trace (GstStructure * s);
-
-extern gboolean _priv_tracer_enabled;
-extern GList *_priv_tracers[GST_TRACER_HOOK_ID_LAST];
-
-extern GstClockTime _priv_gst_info_start_time;
-#define GST_TRACER_IS_ENABLED(id) \
- (_priv_tracer_enabled && (_priv_tracers[id] != NULL))
-
-#define GST_TRACER_TS \
- GST_CLOCK_DIFF (_priv_gst_info_start_time, gst_util_get_timestamp ())
-
-/* tracing hooks */
-
-#define GST_TRACER_PAD_PUSH_PRE(pad, buffer) G_STMT_START{ \
- if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \
- gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \
- GST_TRACER_MESSAGE_ID_PAD_PUSH_PRE, GST_TRACER_TS, \
- pad, buffer); \
- } \
-}G_STMT_END
-
-#define GST_TRACER_PAD_PUSH_POST(pad, res) G_STMT_START{ \
- if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \
- gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \
- GST_TRACER_MESSAGE_ID_PAD_PUSH_POST, GST_TRACER_TS, \
- pad, res); \
- } \
-}G_STMT_END
-
-#define GST_TRACER_PAD_PUSH_LIST_PRE(pad, list) G_STMT_START{ \
- if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \
- gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \
- GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_PRE, GST_TRACER_TS, \
- pad, list); \
- } \
-}G_STMT_END
-
-#define GST_TRACER_PAD_PUSH_LIST_POST(pad, res) G_STMT_START{ \
- if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \
- gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \
- GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_POST, GST_TRACER_TS, \
- pad, res); \
- } \
-}G_STMT_END
-
-#define GST_TRACER_PAD_PULL_RANGE_PRE(pad, offset, size) G_STMT_START{ \
- if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \
- gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \
- GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_PRE, GST_TRACER_TS, \
- pad, offset, size); \
- } \
-}G_STMT_END
-
-#define GST_TRACER_PAD_PULL_RANGE_POST(pad, buffer, res) G_STMT_START{ \
- if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \
- gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \
- GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_POST, GST_TRACER_TS, \
- pad, buffer, res); \
- } \
-}G_STMT_END
-
-#define GST_TRACER_PAD_PUSH_EVENT_PRE(pad, event) G_STMT_START{ \
- if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_EVENTS)) { \
- gst_tracer_dispatch (GST_TRACER_HOOK_ID_EVENTS, \
- GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_PRE, GST_TRACER_TS, \
- pad, event); \
- } \
-}G_STMT_END
-
-#define GST_TRACER_PAD_PUSH_EVENT_POST(pad, res) G_STMT_START{ \
- if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_EVENTS)) { \
- gst_tracer_dispatch (GST_TRACER_HOOK_ID_EVENTS, \
- GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_POST, GST_TRACER_TS, \
- pad, res); \
- } \
-}G_STMT_END
-
-#define GST_TRACER_ELEMENT_POST_MESSAGE_PRE(element, message) G_STMT_START{ \
- if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_MESSAGES)) { \
- gst_tracer_dispatch (GST_TRACER_HOOK_ID_MESSAGES, \
- GST_TRACER_MESSAGE_ID_ELEMENT_POST_MESSAGE_PRE, GST_TRACER_TS, \
- element, message); \
- } \
-}G_STMT_END
-
-#define GST_TRACER_ELEMENT_POST_MESSAGE_POST(element, res) G_STMT_START{ \
- if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_MESSAGES)) { \
- gst_tracer_dispatch (GST_TRACER_HOOK_ID_MESSAGES, \
- GST_TRACER_MESSAGE_ID_ELEMENT_POST_MESSAGE_POST, GST_TRACER_TS, \
- element, res); \
- } \
-}G_STMT_END
-
-#define GST_TRACER_ELEMENT_QUERY_PRE(element, query) G_STMT_START{ \
- if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_QUERIES)) { \
- gst_tracer_dispatch (GST_TRACER_HOOK_ID_QUERIES, \
- GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_PRE, GST_TRACER_TS, \
- element, query); \
- } \
-}G_STMT_END
-
-#define GST_TRACER_ELEMENT_QUERY_POST(element, res) G_STMT_START{ \
- if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_QUERIES)) { \
- gst_tracer_dispatch (GST_TRACER_HOOK_ID_QUERIES, \
- GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_POST, GST_TRACER_TS, \
- element, res); \
- } \
-}G_STMT_END
-
-#else /* !GST_DISABLE_GST_DEBUG */
-
-#define GST_TRACER_PAD_PUSH_PRE(pad, buffer)
-#define GST_TRACER_PAD_PUSH_POST(pad, res)
-#define GST_TRACER_PAD_PUSH_LIST_PRE(pad, list)
-#define GST_TRACER_PAD_PUSH_LIST_POST(pad, res)
-#define GST_TRACER_PAD_PULL_RANGE_PRE(pad, offset, size)
-#define GST_TRACER_PAD_PULL_RANGE_POST(pad, buffer, res)
-#define GST_TRACER_PAD_PUSH_EVENT_PRE(pad, event)
-#define GST_TRACER_PAD_PUSH_EVENT_POST(pad, res)
-#define GST_TRACER_ELEMENT_POST_MESSAGE_PRE(element, message)
-#define GST_TRACER_ELEMENT_POST_MESSAGE_POST(element, res)
-#define GST_TRACER_ELEMENT_QUERY_PRE(element, query)
-#define GST_TRACER_ELEMENT_QUERY_POST(element, res)
+void gst_tracer_invoke (GstTracer * self, GstTracerHookId hid,
+ GstTracerMessageId mid, va_list var_args);
-#endif /* GST_DISABLE_GST_DEBUG */
+GType gst_tracer_get_type (void);
G_END_DECLS
diff --git a/gst/gsttracerfactory.c b/gst/gsttracerfactory.c
index 9cdbb86f1..ec7ba5387 100644
--- a/gst/gsttracerfactory.c
+++ b/gst/gsttracerfactory.c
@@ -29,7 +29,6 @@
#include "gst_private.h"
#include "gstinfo.h"
-#include "gsttracer.h"
#include "gsttracerfactory.h"
#include "gstregistry.h"
diff --git a/gst/gsttracerfactory.h b/gst/gsttracerfactory.h
index 2bfe481b1..8e9370c39 100644
--- a/gst/gsttracerfactory.h
+++ b/gst/gsttracerfactory.h
@@ -25,7 +25,6 @@
#include <gst/gstcaps.h>
#include <gst/gstplugin.h>
#include <gst/gstpluginfeature.h>
-#include <gst/gsttracer.h>
G_BEGIN_DECLS
diff --git a/gst/gsttracerutils.c b/gst/gsttracerutils.c
new file mode 100644
index 000000000..ed83f8290
--- /dev/null
+++ b/gst/gsttracerutils.c
@@ -0,0 +1,151 @@
+/* GStreamer
+ * Copyright (C) 2013 Stefan Sauer <ensonic@users.sf.net>
+ *
+ * gsttracerutils.c: tracing subsystem
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * SECTION:gsttracerutils
+ * @short_description: 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.
+ */
+
+#define GST_USE_UNSTABLE_API
+
+#include "gst_private.h"
+#include "gsttracer.h"
+#include "gsttracerfactory.h"
+#include "gsttracerutils.h"
+
+#ifndef GST_DISABLE_GST_DEBUG
+
+/* tracing helpers */
+
+gboolean _priv_tracer_enabled = FALSE;
+/* TODO(ensonic): use array of GPtrArray* ? */
+GList *_priv_tracers[GST_TRACER_HOOK_ID_LAST] = { NULL, };
+
+/* Initialize the tracing system */
+void
+_priv_gst_tracer_init (void)
+{
+ const gchar *env = g_getenv ("GST_TRACE");
+
+ if (env != NULL && *env != '\0') {
+ GstRegistry *registry = gst_registry_get ();
+ GstPluginFeature *feature;
+ GstTracerFactory *factory;
+ GstTracerHook mask;
+ GstObject *tracer;
+ gchar **t = g_strsplit_set (env, ";", 0);
+ gint i = 0, j;
+ gchar *params;
+
+ GST_INFO ("enabling tracers: '%s'", env);
+
+ while (t[i]) {
+ // check t[i] for params
+ if ((params = strchr (t[i], '('))) {
+ gchar *end = strchr (&params[1], ')');
+ *params = '\0';
+ params++;
+ if (end)
+ *end = '\0';
+ } else {
+ params = NULL;
+ }
+
+ GST_INFO ("checking tracer: '%s'", t[i]);
+
+ if ((feature = gst_registry_lookup_feature (registry, t[i]))) {
+ factory = GST_TRACER_FACTORY (gst_plugin_feature_load (feature));
+ if (factory) {
+ GST_INFO_OBJECT (factory, "creating tracer: type-id=%u",
+ (guint) factory->type);
+
+ tracer = g_object_new (factory->type, "params", params, NULL);
+ g_object_get (tracer, "mask", &mask, NULL);
+
+ if (mask) {
+ /* add to lists according to mask */
+ j = 0;
+ while (mask && (j < GST_TRACER_HOOK_ID_LAST)) {
+ if (mask & 1) {
+ _priv_tracers[j] = g_list_prepend (_priv_tracers[j],
+ gst_object_ref (tracer));
+ GST_WARNING_OBJECT (tracer, "added tracer to hook %d", j);
+ }
+ mask >>= 1;
+ j++;
+ }
+
+ _priv_tracer_enabled = TRUE;
+ } else {
+ GST_WARNING_OBJECT (tracer,
+ "tracer with zero mask won't have any effect");
+ }
+ gst_object_unref (tracer);
+ } else {
+ GST_WARNING_OBJECT (feature,
+ "loading plugin containing feature %s failed!", t[i]);
+ }
+ } else {
+ GST_WARNING ("no tracer named '%s'", t[i]);
+ }
+ i++;
+ }
+ g_strfreev (t);
+ }
+}
+
+void
+_priv_gst_tracer_deinit (void)
+{
+ gint i;
+ GList *node;
+
+ /* shutdown tracers for final reports */
+ for (i = 0; i < GST_TRACER_HOOK_ID_LAST; i++) {
+ for (node = _priv_tracers[i]; node; node = g_list_next (node)) {
+ gst_object_unref (node->data);
+ }
+ g_list_free (_priv_tracers[i]);
+ _priv_tracers[i] = NULL;
+ }
+ _priv_tracer_enabled = FALSE;
+}
+
+void
+gst_tracer_dispatch (GstTracerHookId hid, GstTracerMessageId mid, ...)
+{
+ va_list var_args;
+ GList *node;
+
+ for (node = _priv_tracers[hid]; node; node = g_list_next (node)) {
+ va_start (var_args, mid);
+ gst_tracer_invoke (node->data, hid, mid, var_args);
+ va_end (var_args);
+ }
+}
+
+#endif /* GST_DISABLE_GST_DEBUG */
diff --git a/gst/gsttracerutils.h b/gst/gsttracerutils.h
new file mode 100644
index 000000000..c3bd5f35a
--- /dev/null
+++ b/gst/gsttracerutils.h
@@ -0,0 +1,225 @@
+/* GStreamer
+ * Copyright (C) 2013 Stefan Sauer <ensonic@users.sf.net>
+ *
+ * gsttracerutils.h: tracing subsystem
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __GST_TRACER_UTILS_H__
+#define __GST_TRACER_UTILS_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gst/gstconfig.h>
+#include <gst/gstbin.h>
+
+G_BEGIN_DECLS
+
+#ifndef GST_DISABLE_GST_DEBUG
+
+/* hook flags and ids */
+
+typedef enum
+{
+ GST_TRACER_HOOK_NONE = 0,
+ GST_TRACER_HOOK_BUFFERS = (1 << 0),
+ GST_TRACER_HOOK_EVENTS = (1 << 1),
+ GST_TRACER_HOOK_MESSAGES = (1 << 2),
+ GST_TRACER_HOOK_QUERIES = (1 << 3),
+ GST_TRACER_HOOK_TOPOLOGY = (1 << 4),
+ /*
+ GST_TRACER_HOOK_TIMER
+ */
+ GST_TRACER_HOOK_ALL = (1 << 5) - 1
+} GstTracerHook;
+
+typedef enum
+{
+ GST_TRACER_HOOK_ID_BUFFERS = 0,
+ GST_TRACER_HOOK_ID_EVENTS,
+ GST_TRACER_HOOK_ID_MESSAGES,
+ GST_TRACER_HOOK_ID_QUERIES,
+ GST_TRACER_HOOK_ID_TOPLOGY,
+ /*
+ GST_TRACER_HOOK_ID_TIMER
+ */
+ GST_TRACER_HOOK_ID_LAST
+} GstTracerHookId;
+
+typedef enum
+{
+ GST_TRACER_MESSAGE_ID_PAD_PUSH_PRE = 0,
+ GST_TRACER_MESSAGE_ID_PAD_PUSH_POST,
+ GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_PRE,
+ GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_POST,
+ GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_PRE,
+ GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_POST,
+ GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_PRE,
+ GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_POST,
+ GST_TRACER_MESSAGE_ID_ELEMENT_POST_MESSAGE_PRE,
+ GST_TRACER_MESSAGE_ID_ELEMENT_POST_MESSAGE_POST,
+ GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_PRE,
+ GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_POST,
+ GST_TRACER_MESSAGE_ID_LAST
+} GstTracerMessageId;
+
+/* tracing hooks */
+
+void _priv_gst_tracer_init (void);
+void _priv_gst_tracer_deinit (void);
+
+/* tracing modules */
+
+gboolean gst_tracer_register (GstPlugin * plugin, const gchar * name, GType type);
+
+/* tracing helpers */
+
+void gst_tracer_dispatch (GstTracerHookId hid, GstTracerMessageId mid, ...);
+
+/* tracing module helpers */
+
+void gst_tracer_log_trace (GstStructure * s);
+
+extern gboolean _priv_tracer_enabled;
+extern GList *_priv_tracers[GST_TRACER_HOOK_ID_LAST];
+
+#define GST_TRACER_IS_ENABLED(id) \
+ (_priv_tracer_enabled && (_priv_tracers[id] != NULL))
+
+#define GST_TRACER_TS \
+ GST_CLOCK_DIFF (_priv_gst_info_start_time, gst_util_get_timestamp ())
+
+/* tracing hooks */
+
+#define GST_TRACER_PAD_PUSH_PRE(pad, buffer) G_STMT_START{ \
+ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \
+ gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \
+ GST_TRACER_MESSAGE_ID_PAD_PUSH_PRE, GST_TRACER_TS, \
+ pad, buffer); \
+ } \
+}G_STMT_END
+
+#define GST_TRACER_PAD_PUSH_POST(pad, res) G_STMT_START{ \
+ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \
+ gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \
+ GST_TRACER_MESSAGE_ID_PAD_PUSH_POST, GST_TRACER_TS, \
+ pad, res); \
+ } \
+}G_STMT_END
+
+#define GST_TRACER_PAD_PUSH_LIST_PRE(pad, list) G_STMT_START{ \
+ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \
+ gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \
+ GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_PRE, GST_TRACER_TS, \
+ pad, list); \
+ } \
+}G_STMT_END
+
+#define GST_TRACER_PAD_PUSH_LIST_POST(pad, res) G_STMT_START{ \
+ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \
+ gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \
+ GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_POST, GST_TRACER_TS, \
+ pad, res); \
+ } \
+}G_STMT_END
+
+#define GST_TRACER_PAD_PULL_RANGE_PRE(pad, offset, size) G_STMT_START{ \
+ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \
+ gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \
+ GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_PRE, GST_TRACER_TS, \
+ pad, offset, size); \
+ } \
+}G_STMT_END
+
+#define GST_TRACER_PAD_PULL_RANGE_POST(pad, buffer, res) G_STMT_START{ \
+ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \
+ gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \
+ GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_POST, GST_TRACER_TS, \
+ pad, buffer, res); \
+ } \
+}G_STMT_END
+
+#define GST_TRACER_PAD_PUSH_EVENT_PRE(pad, event) G_STMT_START{ \
+ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_EVENTS)) { \
+ gst_tracer_dispatch (GST_TRACER_HOOK_ID_EVENTS, \
+ GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_PRE, GST_TRACER_TS, \
+ pad, event); \
+ } \
+}G_STMT_END
+
+#define GST_TRACER_PAD_PUSH_EVENT_POST(pad, res) G_STMT_START{ \
+ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_EVENTS)) { \
+ gst_tracer_dispatch (GST_TRACER_HOOK_ID_EVENTS, \
+ GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_POST, GST_TRACER_TS, \
+ pad, res); \
+ } \
+}G_STMT_END
+
+#define GST_TRACER_ELEMENT_POST_MESSAGE_PRE(element, message) G_STMT_START{ \
+ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_MESSAGES)) { \
+ gst_tracer_dispatch (GST_TRACER_HOOK_ID_MESSAGES, \
+ GST_TRACER_MESSAGE_ID_ELEMENT_POST_MESSAGE_PRE, GST_TRACER_TS, \
+ element, message); \
+ } \
+}G_STMT_END
+
+#define GST_TRACER_ELEMENT_POST_MESSAGE_POST(element, res) G_STMT_START{ \
+ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_MESSAGES)) { \
+ gst_tracer_dispatch (GST_TRACER_HOOK_ID_MESSAGES, \
+ GST_TRACER_MESSAGE_ID_ELEMENT_POST_MESSAGE_POST, GST_TRACER_TS, \
+ element, res); \
+ } \
+}G_STMT_END
+
+#define GST_TRACER_ELEMENT_QUERY_PRE(element, query) G_STMT_START{ \
+ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_QUERIES)) { \
+ gst_tracer_dispatch (GST_TRACER_HOOK_ID_QUERIES, \
+ GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_PRE, GST_TRACER_TS, \
+ element, query); \
+ } \
+}G_STMT_END
+
+#define GST_TRACER_ELEMENT_QUERY_POST(element, res) G_STMT_START{ \
+ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_QUERIES)) { \
+ gst_tracer_dispatch (GST_TRACER_HOOK_ID_QUERIES, \
+ GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_POST, GST_TRACER_TS, \
+ element, res); \
+ } \
+}G_STMT_END
+
+#else /* !GST_DISABLE_GST_DEBUG */
+
+#define GST_TRACER_PAD_PUSH_PRE(pad, buffer)
+#define GST_TRACER_PAD_PUSH_POST(pad, res)
+#define GST_TRACER_PAD_PUSH_LIST_PRE(pad, list)
+#define GST_TRACER_PAD_PUSH_LIST_POST(pad, res)
+#define GST_TRACER_PAD_PULL_RANGE_PRE(pad, offset, size)
+#define GST_TRACER_PAD_PULL_RANGE_POST(pad, buffer, res)
+#define GST_TRACER_PAD_PUSH_EVENT_PRE(pad, event)
+#define GST_TRACER_PAD_PUSH_EVENT_POST(pad, res)
+#define GST_TRACER_ELEMENT_POST_MESSAGE_PRE(element, message)
+#define GST_TRACER_ELEMENT_POST_MESSAGE_POST(element, res)
+#define GST_TRACER_ELEMENT_QUERY_PRE(element, query)
+#define GST_TRACER_ELEMENT_QUERY_POST(element, res)
+
+#endif /* GST_DISABLE_GST_DEBUG */
+
+G_END_DECLS
+
+#endif /* __GST_TRACER_UTILS_H__ */
+
diff --git a/plugins/tracers/Makefile.am b/plugins/tracers/Makefile.am
index 87db74cac..07c510a77 100644
--- a/plugins/tracers/Makefile.am
+++ b/plugins/tracers/Makefile.am
@@ -15,7 +15,8 @@ libgstcoretracers_la_SOURCES = \
gststats.c \
gsttracers.c
-libgstcoretracers_la_CFLAGS = $(GST_OBJ_CFLAGS)
+libgstcoretracers_la_CFLAGS = $(GST_OBJ_CFLAGS) \
+ -DGST_USE_UNSTABLE_API
libgstcoretracers_la_LIBADD = \
$(top_builddir)/gst/printf/libgstprintf.la \
$(GST_OBJ_LIBS)
diff --git a/plugins/tracers/gstlatency.h b/plugins/tracers/gstlatency.h
index efcab6b6f..e23430333 100644
--- a/plugins/tracers/gstlatency.h
+++ b/plugins/tracers/gstlatency.h
@@ -23,6 +23,7 @@
#define __GST_LATENCY_TRACER_H__
#include <gst/gst.h>
+#include <gst/gsttracer.h>
G_BEGIN_DECLS
diff --git a/plugins/tracers/gstlog.h b/plugins/tracers/gstlog.h
index 827f2aaf2..6f0dd7fdc 100644
--- a/plugins/tracers/gstlog.h
+++ b/plugins/tracers/gstlog.h
@@ -23,6 +23,7 @@
#define __GST_LOG_TRACER_H__
#include <gst/gst.h>
+#include <gst/gsttracer.h>
G_BEGIN_DECLS
diff --git a/plugins/tracers/gstrusage.h b/plugins/tracers/gstrusage.h
index e73515df0..b13fb85ff 100644
--- a/plugins/tracers/gstrusage.h
+++ b/plugins/tracers/gstrusage.h
@@ -23,6 +23,7 @@
#define __GST_RUSAGE_TRACER_H__
#include <gst/gst.h>
+#include <gst/gsttracer.h>
G_BEGIN_DECLS
diff --git a/plugins/tracers/gststats.h b/plugins/tracers/gststats.h
index 97ae17652..a5f2d6787 100644
--- a/plugins/tracers/gststats.h
+++ b/plugins/tracers/gststats.h
@@ -23,6 +23,7 @@
#define __GST_STATS_TRACER_H__
#include <gst/gst.h>
+#include <gst/gsttracer.h>
G_BEGIN_DECLS