libs/gst/net/Makefile
plugins/Makefile
plugins/elements/Makefile
+plugins/tracers/Makefile
po/Makefile.in
tests/Makefile
tests/benchmarks/Makefile
Certain GStreamer core function (such as gst_pad_push or gst_element_add_pad) will
call into the tracer. The tracer will dispatch into loaded tracing plugins.
Developers will be able to select a list of plugins by setting an environment
-variable, such as GST_TRACE="meminfo,dbus". When then plugins are loaded, they will
-add them to certain hooks. Another env var GST_TRACE_CHANNEL can be used to send
-the tracing to a file or a socket (Do the same for GST_DEBUG_CHANNEL). The syntax
-could be GST_XXX_CHANNEL=file:///path/to/file or GST_XXX_CHANNEL=tcp://<ip>:<port>.
+variable, such as GST_TRACE="meminfo,dbus". One can also pass parameters to
+plugins: GST_TRACE="log(events;buffers),stats(all)".
+When then plugins are loaded, we'll add them to certain hooks according to that
+they are interested in.
+
+Another env var GST_TRACE_CHANNEL can be used to send the tracing to a file or
+a socket (Do the same for GST_DEBUG_CHANNEL). The syntax could be
+GST_XXX_CHANNEL=file:///path/to/file or GST_XXX_CHANNEL=tcp://<ip>:<port>.
If no channel is set, the tracing goes to stderr like the debug logging.
-TODO(ensonic): we might want to have GST_{DEBUG|TRACE)_FORMAT envars as well. These
-could be raw, ansi-color, binary, ...
+TODO(ensonic): we might want to have GST_{DEBUG|TRACE)_FORMAT envars as well.
+These could be raw, ansi-color, binary, suitable for babeltrace (see lttng), ...
-Hooks
------
-e.g. gst_pad_push() will do add this line:
-GST_TRACER_PUSH_BUFFER (pad, buffer)
+With these we can deprecate GST_DEBUG_FILE and GST_DEBUG_NO_COLOR.
+
+Hook api
+--------
+e.g. gst_pad_push() would become:
+
+#ifndef GST_DISABLE_GST_DEBUG
+static inline GstFlowReturn __gst_pad_push (GstPad * pad, GstBuffer * buffer);
+#endif
+
+GstFlowReturn
+gst_pad_push (GstPad * pad, GstBuffer * buffer)
+#ifndef GST_DISABLE_GST_DEBUG
+{
+ if (__tracer_enabled && __tracer_hook_is_used)
+ gst_tracer_push_buffer_pre (pad, buffer);
+ GstFlowReturn res = __gst_pad_push (GstPad * pad, GstBuffer * buffer);
+ if (__tracer_enabled && __tracer_hook_is_used)
+ gst_tracer_push_buffer_post (pad, res);
+ return res;
+}
+
+static inline GstFlowReturn
+__gst_pad_push (GstPad * pad, GstBuffer * buffer)
+#endif
+{
+ g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
+ g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
+ g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
-If tracing is disable at compile time the macro will evaluate to nothing. Otherwise
-it will become something along the lines of:
-if (__tracer && __tracer_hook_is_used) {
- gst_tracer_push_buffer (pad, buffer);
+ return gst_pad_push_data (pad,
+ GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH, buffer);
}
+TODO(ensonic): gcc has some magic for wrapping functions
+- http://gcc.gnu.org/onlinedocs/gcc/Constructing-Calls.html
+- http://www.clifford.at/cfun/gccfeat/#gccfeat05.c
+
TODO(ensonic): we should eval if we can use something like jump_label in the kernel
- http://lwn.net/Articles/412072/ + http://lwn.net/Articles/435215/
- http://lxr.free-electrons.com/source/kernel/jump_label.c
- it is linux specific :/
In addition to api hooks we should also provide timer hooks. Interval timers are
-useful to get e.g. resource usage snapshots. Also absolute timers might make sense.
-
-Plugins can attach handlers to one or more hooks. When a hook such as
-gst_tracer_push_buffer () is called it will take a timestamp and call all attached
-handlers. Hooks will be called from misc threads. The trace plugins should only
-consume (=read) the provided data. Most trace plugins will log data to a trace
-channel.
+useful to get e.g. resource usage snapshots. Also absolute timers might make
+sense. All this could be implemented with a clock thread.
-TODO(ensonic): use GSignal for the hooks?
-
-Plugins
-=======
+Hooks
+-----
+ gst_bin_add
+ gst_bin_remove
+ gst_element_add_pad
+ gst_element_post_message
+ gst_element_query
+ gst_element_remove_pad
+ gst_pad_link
+ gst_pad_pull_range
+ gst_pad_push
+ gst_pad_push_list
+ gst_pad_push_event
+ gst_pad_unlink
+
+Plugin api
+----------
+
+TracerPlugins are plugin features. They have a simple api:
+
+GstTracerHookMask init(gchar *params);
+Plugins can attach handlers to one or more hooks. They use a HookMask to tell
+which events they are interested in. The params are the extra detail from the
+environment var.
+
+void invoke(GstStructure *s);
+Hooks marshall the parameters given to a trace hook into a GstStructure and also
+add some extra into such as a timestamp. The hooks will receive this structure.
+Hooks will be called from misc threads. The trace plugins should only consume
+(=read) the provided data. Most trace plugins will log data to a trace channel.
+
+void done(void);
+Plugins can output results and release data. This would ideally be done at the
+end of the applications, but gst_deinit() is not mandatory. gst_tracelib was
+using a gcc_destructor
+
+Plugins ideas
+=============
+
+We can have some under gstreamer/plugins/tracers/
meminfo
-------
----
- provide a dbus iface to announce applications that are traced
- tracing UIs can use the dbus iface to find the channels where logging and tracing
- is getting logged to, one would start the tracing UI first and when the
- application is started with tracing activated, the dbus plugin will announce the
- new application, upon which the tracing UI can start reading from the log channels
+ is getting logged to
+- one would start the tracing UI first and when the application is started with
+ tracing activated, the dbus plugin will announce the new application,
+ upon which the tracing UI can start reading from the log channels, this avoid
+ missing some data
topology
--------
- register to pipeline topology hooks
- tracing UIs can show a live pipeline graph
-communication
--------------
+stats
+-----
- register to buffer, event, message and query flow
- tracing apps can do e.g. statistics
is loaded) and read the log streams from the sockets/files that are configured for
the app.
-gst-trace-stats
----------------
-Such a tool could read a trace and summarize the content like gst-tracelib did for
-stats in 0.10.
+gst-tracer
+----------
+Counterpart of gst-tracelib-ui
Problems / Open items
=====================
+- when hooking into a timer, should we just have some predefined intervals?
+- how to trigger the shutdown processing?
- when connecting to a running app, we cant easily get the 'current' state if logging
is using a socket, as past events are not stored
+
+Try it
+======
+GST_DEBUG="GST_REG*:4,GST_TRACER:4,log:7" GST_TRACE=log gst-launch-1.0 fakesrc num-buffers=10 ! fakesink
+- traces for buffer flow in TRACE level and default category
+
gsttoc.c \
gsttocsetter.c \
$(GST_TRACE_SRC) \
+ gsttracer.c \
+ gsttracerfactory.c \
gsttypefind.c \
gsttypefindfactory.c \
gsturi.c \
gsttaskpool.h \
gsttoc.h \
gsttocsetter.h \
+ gsttracer.h \
+ gsttracerfactory.h \
gsttypefind.h \
gsttypefindfactory.h \
gsturi.h \
g_type_class_ref (gst_pad_get_type ());
g_type_class_ref (gst_element_factory_get_type ());
g_type_class_ref (gst_element_get_type ());
+ g_type_class_ref (gst_tracer_factory_get_type ());
g_type_class_ref (gst_type_find_factory_get_type ());
g_type_class_ref (gst_bin_get_type ());
g_type_class_ref (gst_bus_get_type ());
GLIB_MINOR_VERSION, GLIB_MICRO_VERSION);
GST_INFO ("initialized GStreamer successfully");
+#ifndef GST_DISABLE_GST_DEBUG
+ _priv_gst_tracer_init ();
+#endif
+
return TRUE;
}
GST_DEBUG ("already deinitialized");
return;
}
+#ifndef GST_DISABLE_GST_DEBUG
+ _priv_gst_tracer_deinit ();
+#endif
g_thread_pool_set_max_unused_threads (0);
bin_class = GST_BIN_CLASS (g_type_class_peek (gst_bin_get_type ()));
g_type_class_unref (g_type_class_peek (gst_pad_get_type ()));
g_type_class_unref (g_type_class_peek (gst_element_factory_get_type ()));
g_type_class_unref (g_type_class_peek (gst_element_get_type ()));
+ g_type_class_unref (g_type_class_peek (gst_tracer_factory_get_type ()));
g_type_class_unref (g_type_class_peek (gst_type_find_factory_get_type ()));
g_type_class_unref (g_type_class_peek (gst_bin_get_type ()));
g_type_class_unref (g_type_class_peek (gst_bus_get_type ()));
#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>
#include <gst/gsturi.h>
gpointer _gst_reserved[GST_PADDING];
};
+struct _GstTracerFactory {
+ GstPluginFeature feature;
+ /* <private> */
+
+ GType type;
+
+ /*
+ gpointer user_data;
+ GDestroyNotify user_data_notify;
+ */
+
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+struct _GstTracerFactoryClass {
+ GstPluginFeatureClass parent;
+ /* <private> */
+
+ gpointer _gst_reserved[GST_PADDING];
+};
+
struct _GstElementFactory {
GstPluginFeature parent;
#include "gstutils.h"
#include "gstinfo.h"
#include "gsterror.h"
+#include "gsttracer.h"
#include "gstvalue.h"
#include "glib-compat-private.h"
*
* MT safe.
*/
+#ifndef GST_DISABLE_GST_DEBUG
+static inline GstFlowReturn __gst_pad_push (GstPad * pad, GstBuffer * buffer);
+#endif
+
GstFlowReturn
gst_pad_push (GstPad * pad, GstBuffer * buffer)
+#ifndef GST_DISABLE_GST_DEBUG
+{
+ const gboolean trace = gst_tracer_is_enabled (GST_TRACER_HOOK_ID_BUFFERS);
+ GstFlowReturn res;
+
+ if (trace)
+ gst_tracer_push_buffer_pre (pad, buffer);
+ res = __gst_pad_push (pad, buffer);
+ if (trace)
+ gst_tracer_push_buffer_post (pad, res);
+ return res;
+}
+
+static inline GstFlowReturn
+__gst_pad_push (GstPad * pad, GstBuffer * buffer)
+#endif
{
g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
* This _must_ be updated whenever the registry format changes,
* we currently use the core version where this change happened.
*/
-#define GST_MAGIC_BINARY_VERSION_STR "1.0.0"
+#define GST_MAGIC_BINARY_VERSION_STR "1.3.0"
/*
* GST_MAGIC_BINARY_VERSION_LEN:
#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>
#include <gst/gstdeviceproviderfactory.h>
/* pack element metadata strings */
gst_registry_chunks_save_string (list,
gst_structure_to_string (factory->metadata));
+ } else if (GST_IS_TRACER_FACTORY (feature)) {
+ /* Initialize with zeroes because of struct padding and
+ * valgrind complaining about copying unitialized memory
+ */
+ pf = g_slice_new0 (GstRegistryChunkPluginFeature);
+ pf_size = sizeof (GstRegistryChunkPluginFeature);
+ chk = gst_registry_chunks_make_data (pf, pf_size);
} else {
GST_WARNING_OBJECT (feature, "unhandled feature type '%s'", type_name);
}
GST_DEBUG
("Reading/casting for GstRegistryChunkPluginFeature at address %p",
*in);
+
unpack_element (*in, dmf, GstRegistryChunkDeviceProviderFactory, end, fail);
pf = (GstRegistryChunkPluginFeature *) dmf;
goto fail;
}
}
+ } else if (GST_IS_TRACER_FACTORY (feature)) {
+ align (*in);
+ GST_DEBUG
+ ("Reading/casting for GstRegistryChunkPluginFeature at address %p",
+ *in);
+ unpack_element (*in, pf, GstRegistryChunkPluginFeature, end, fail);
} else {
GST_WARNING ("unhandled factory type : %s", G_OBJECT_TYPE_NAME (feature));
goto fail;
--- /dev/null
+/* GStreamer
+ * Copyright (C) 2013 Stefan Sauer <ensonic@users.sf.net>
+ *
+ * gsttracer.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.
+ */
+
+#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
+
+/* tracing plugins base class */
+
+enum
+{
+ PROP_0,
+ PROP_PARAMS,
+ PROP_MASK,
+ PROP_LAST
+};
+
+static GParamSpec *properties[PROP_LAST];
+
+static void gst_tracer_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec);
+static void gst_tracer_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
+struct _GstTracerPrivate
+{
+ const gchar *params;
+ GstTracerHook mask;
+};
+
+#define gst_tracer_parent_class parent_class
+G_DEFINE_ABSTRACT_TYPE (GstTracer, gst_tracer, GST_TYPE_OBJECT);
+
+static void
+gst_tracer_class_init (GstTracerClass * klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->set_property = gst_tracer_set_property;
+ gobject_class->get_property = gst_tracer_get_property;
+
+ properties[PROP_PARAMS] =
+ g_param_spec_string ("params", "Params", "Extra configuration parameters",
+ NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_MASK] =
+ g_param_spec_flags ("mask", "Mask", "Event mask", GST_TYPE_TRACER_HOOK,
+ GST_TRACER_HOOK_NONE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (gobject_class, PROP_LAST, properties);
+ g_type_class_add_private (klass, sizeof (GstTracerPrivate));
+}
+
+static void
+gst_tracer_init (GstTracer * tracer)
+{
+ tracer->priv = G_TYPE_INSTANCE_GET_PRIVATE (tracer, GST_TYPE_TRACER,
+ GstTracerPrivate);
+}
+
+static void
+gst_tracer_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstTracer *self = GST_TRACER_CAST (object);
+
+ switch (prop_id) {
+ case PROP_PARAMS:
+ self->priv->params = g_value_get_string (value);
+ break;
+ case PROP_MASK:
+ self->priv->mask = g_value_get_flags (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_tracer_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ GstTracer *self = GST_TRACER_CAST (object);
+
+ switch (prop_id) {
+ case PROP_PARAMS:
+ g_value_set_string (value, self->priv->params);
+ break;
+ case PROP_MASK:
+ g_value_set_flags (value, self->priv->mask);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_tracer_invoke (GstTracer * self, GstStructure * s)
+{
+ GstTracerClass *klass = GST_TRACER_GET_CLASS (self);
+
+ g_return_if_fail (klass->invoke);
+
+ klass->invoke (s);
+}
+
+/* tracing modules */
+
+gboolean
+gst_tracer_register (GstPlugin * plugin, const gchar * name, GType type)
+{
+ GstPluginFeature *existing_feature;
+ GstRegistry *registry;
+ GstTracerFactory *factory;
+
+ g_return_val_if_fail (name != NULL, FALSE);
+ g_return_val_if_fail (g_type_is_a (type, GST_TYPE_TRACER), FALSE);
+
+ registry = gst_registry_get ();
+ /* check if feature already exists, if it exists there is no need to update it
+ * when the registry is getting updated, outdated plugins and all their
+ * features are removed and readded.
+ */
+ existing_feature = gst_registry_lookup_feature (registry, name);
+ if (existing_feature) {
+ GST_DEBUG_OBJECT (registry, "update existing feature %p (%s)",
+ existing_feature, name);
+ factory = GST_TRACER_FACTORY_CAST (existing_feature);
+ factory->type = type;
+ existing_feature->loaded = TRUE;
+ //g_type_set_qdata (type, __gst_elementclass_factory, factory);
+ gst_object_unref (existing_feature);
+ return TRUE;
+ }
+
+ factory = g_object_newv (GST_TYPE_TRACER_FACTORY, 0, NULL);
+ GST_DEBUG_OBJECT (factory, "new tracer factory for %s", name);
+
+ gst_plugin_feature_set_name (GST_PLUGIN_FEATURE_CAST (factory), name);
+ gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE_CAST (factory),
+ GST_RANK_NONE);
+
+ factory->type = type;
+ GST_DEBUG_OBJECT (factory, "tracer factory for %u:%s",
+ (guint) type, g_type_name (type));
+
+ if (plugin && plugin->desc.name) {
+ GST_PLUGIN_FEATURE_CAST (factory)->plugin_name = plugin->desc.name; /* interned string */
+ GST_PLUGIN_FEATURE_CAST (factory)->plugin = plugin;
+ g_object_add_weak_pointer ((GObject *) plugin,
+ (gpointer *) & GST_PLUGIN_FEATURE_CAST (factory)->plugin);
+ } else {
+ GST_PLUGIN_FEATURE_CAST (factory)->plugin_name = "NULL";
+ GST_PLUGIN_FEATURE_CAST (factory)->plugin = NULL;
+ }
+ GST_PLUGIN_FEATURE_CAST (factory)->loaded = TRUE;
+
+ gst_registry_add_feature (gst_registry_get (),
+ GST_PLUGIN_FEATURE_CAST (factory));
+
+ return TRUE;
+}
+
+/* tracing helpers */
+
+static gboolean tracer_enabled = FALSE;
+
+static GList *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]) {
+ // TODO(ensonic): check t[i] for params
+ 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) {
+ tracers[j] = g_list_prepend (tracers[j],
+ gst_object_ref (tracer));
+ GST_WARNING_OBJECT (tracer, "added tracer to hook %d", j);
+ }
+ mask >>= 1;
+ j++;
+ }
+
+ 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 = tracers[i]; node; node = g_list_next (node)) {
+ gst_object_unref (node->data);
+ }
+ g_list_free (tracers[i]);
+ tracers[i] = NULL;
+ }
+}
+
+gboolean
+gst_tracer_is_enabled (GstTracerHookId id)
+{
+ return tracer_enabled && (tracers[id] != NULL);
+}
+
+static void
+dispatch (GstTracerHookId id, GstStructure * s)
+{
+ GList *node;
+ for (node = tracers[id]; node; node = g_list_next (node)) {
+ gst_tracer_invoke (node->data, s);
+ }
+}
+
+/* tracing hooks */
+void
+gst_tracer_push_buffer_pre (GstPad * pad, GstBuffer * buffer)
+{
+ // TODO(ensonic): gst_structure_new_id
+ dispatch (GST_TRACER_HOOK_ID_BUFFERS, gst_structure_new ("push_buffer::pre",
+ ".ts", G_TYPE_UINT64, gst_util_get_timestamp (),
+ "pad", GST_TYPE_PAD, pad, "buffer", GST_TYPE_BUFFER, buffer, NULL));
+}
+
+void
+gst_tracer_push_buffer_post (GstPad * pad, GstFlowReturn res)
+{
+ // TODO(ensonic): gst_structure_new_id
+ dispatch (GST_TRACER_HOOK_ID_BUFFERS, gst_structure_new ("push_buffer::post",
+ ".ts", G_TYPE_UINT64, gst_util_get_timestamp (),
+ "pad", GST_TYPE_PAD, pad, "return", G_TYPE_INT, res, NULL));
+}
+
+#endif /* GST_DISABLE_GST_DEBUG */
--- /dev/null
+/* GStreamer
+ * Copyright (C) 2013 Stefan Sauer <ensonic@users.sf.net>
+ *
+ * gsttracer.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_H__
+#define __GST_TRACER_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;
+
+/* tracing plugins */
+
+typedef struct _GstTracer GstTracer;
+typedef struct _GstTracerPrivate GstTracerPrivate;
+typedef struct _GstTracerClass GstTracerClass;
+
+#define GST_TYPE_TRACER (gst_tracer_get_type())
+#define GST_TRACER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TRACER,GstTracer))
+#define GST_TRACER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TRACER,GstTracerClass))
+#define GST_IS_TRACER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TRACER))
+#define GST_IS_TRACER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TRACER))
+#define GST_TRACER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_TRACER,GstTracerClass))
+#define GST_TRACER_CAST(obj) ((GstTracer *)(obj))
+
+struct _GstTracer {
+ GstObject parent;
+ /*< private >*/
+ GstTracerPrivate *priv;
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+typedef void (*GstTracerInvokeFunction) (GstStructure *s);
+
+struct _GstTracerClass {
+ GstObjectClass parent_class;
+
+ /* plugin vmethods */
+ GstTracerInvokeFunction invoke;
+
+ /*< private >*/
+ 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);
+
+gboolean gst_tracer_register (GstPlugin * plugin, const gchar * name, GType type);
+
+gboolean gst_tracer_is_enabled (GstTracerHookId id);
+void gst_tracer_push_buffer_pre (GstPad *pad, GstBuffer *buffer);
+void gst_tracer_push_buffer_post (GstPad *pad, GstFlowReturn res);
+
+
+#endif /* GST_DISABLE_GST_DEBUG */
+
+G_END_DECLS
+
+#endif /* __GST_TRACER_H__ */
+
--- /dev/null
+/* GStreamer
+ * Copyright (C) 2013 Stefan Sauer <ensonic@users.sf.net>
+ *
+ * gsttracerfactory.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:gsttracerfactory
+ * @short_description: Information about registered tracer functions
+ *
+ * Last reviewed on 2012-10-24 (1.2.X)
+ */
+
+#include "gst_private.h"
+#include "gstinfo.h"
+#include "gsttracer.h"
+#include "gsttracerfactory.h"
+#include "gstregistry.h"
+
+GST_DEBUG_CATEGORY (tracer_debug);
+#define GST_CAT_DEFAULT tracer_debug
+
+#define _do_init \
+{ \
+ GST_DEBUG_CATEGORY_INIT (tracer_debug, "GST_TRACER", \
+ GST_DEBUG_FG_BLUE, "tracing subsystem"); \
+}
+
+#define gst_tracer_factory_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstTracerFactory, gst_tracer_factory,
+ GST_TYPE_PLUGIN_FEATURE, _do_init);
+
+static void
+gst_tracer_factory_class_init (GstTracerFactoryClass * klass)
+{
+}
+
+static void
+gst_tracer_factory_init (GstTracerFactory * factory)
+{
+}
+
+/**
+ * gst_tracer_factory_get_list:
+ *
+ * Gets the list of all registered tracer factories. You must free the
+ * list using gst_plugin_feature_list_free().
+ *
+ * The returned factories are sorted by factory name.
+ *
+ * Free-function: gst_plugin_feature_list_free
+ *
+ * Returns: (transfer full) (element-type Gst.TracerFactory): the list of all
+ * registered #GstTracerFactory.
+ */
+GList *
+gst_tracer_factory_get_list (void)
+{
+ return gst_registry_get_feature_list (gst_registry_get (),
+ GST_TYPE_TRACER_FACTORY);
+}
--- /dev/null
+/* GStreamer
+ * Copyright (C) 2013 Stefan Sauer <ensonic@users.sf.net>
+ *
+ * gsttracerfactory.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_FACTORY_H__
+#define __GST_TRACER_FACTORY_H__
+
+#include <gst/gstcaps.h>
+#include <gst/gstplugin.h>
+#include <gst/gstpluginfeature.h>
+#include <gst/gsttracer.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_TRACER_FACTORY (gst_tracer_factory_get_type())
+#define GST_TRACER_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TRACER_FACTORY, GstTracerFactory))
+#define GST_IS_TRACER_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TRACER_FACTORY))
+#define GST_TRACER_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TRACER_FACTORY, GstTracerFactoryClass))
+#define GST_IS_TRACER_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TRACER_FACTORY))
+#define GST_TRACER_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_TRACER_FACTORY, GstTracerFactoryClass))
+#define GST_TRACER_FACTORY_CAST(obj) ((GstTracerFactory *)(obj))
+
+/**
+ * GstTracerFactory:
+ *
+ * Opaque object that stores information about a tracer function.
+ */
+typedef struct _GstTracerFactory GstTracerFactory;
+typedef struct _GstTracerFactoryClass GstTracerFactoryClass;
+
+/* tracering interface */
+
+GType gst_tracer_factory_get_type (void);
+GList * gst_tracer_factory_get_list (void);
+
+
+G_END_DECLS
+
+#endif /* __GST_TRACER_FACTORY_H__ */
-SUBDIRS = elements
+SUBDIRS = elements tracers
+
+DIST_SUBDIRS = elements tracers
-DIST_SUBDIRS = elements
--- /dev/null
+Makefile
+Makefile.in
+*.o
+*.lo
+*.la
+.deps
+.libs
+*.bb
+*.bbg
+*.da
+*.def
+*.gcno
--- /dev/null
+
+plugin_LTLIBRARIES = libgstcoretracers.la
+
+libgstcoretracers_la_DEPENDENCIES = $(top_builddir)/gst/libgstreamer-@GST_API_VERSION@.la
+libgstcoretracers_la_SOURCES = \
+ gstlog.c \
+ gsttracers.c
+
+libgstcoretracers_la_CFLAGS = $(GST_OBJ_CFLAGS)
+libgstcoretracers_la_LIBADD = \
+ $(top_builddir)/libs/gst/base/libgstbase-@GST_API_VERSION@.la \
+ $(GST_OBJ_LIBS)
+libgstcoretracers_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+libgstcoretracers_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
+
+noinst_HEADERS = \
+ gstlog.h
+
+CLEANFILES = *.gcno *.gcda *.gcov *.gcov.out
+
+%.c.gcov: .libs/libgstcoretracers_la-%.gcda %.c
+ $(GCOV) -b -f -o $^ > $@.out
+
+gcov: $(libgstcoretracers_la_SOURCES:=.gcov)
+
+Android.mk: Makefile.am
+ androgenizer -:PROJECT gstreamer -:SHARED libgstcoretracers -:TAGS eng debug \
+ -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
+ -:SOURCES $(libgstcoretracers_la_SOURCES) \
+ -:CFLAGS $(DEFS) $(libgstcoretracers_la_CFLAGS) \
+ -:LDFLAGS $(libgstcoretracers_la_LDFLAGS) \
+ $(libgstcoretracers_la_LIBADD) \
+ -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
+ LOCAL_MODULE_PATH:=$$\(TARGET_OUT\)/lib/gstreamer-@GST_API_VERSION@ \
+ > $@
--- /dev/null
+/* GStreamer
+ * Copyright (C) 2013 Stefan Sauer <ensonic@users.sf.net>
+ *
+ * gstlog.c: tracing module that logs events
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "gstlog.h"
+
+GST_DEBUG_CATEGORY_STATIC (gst_log_debug);
+#define GST_CAT_DEFAULT gst_log_debug
+
+#define _do_init \
+ GST_DEBUG_CATEGORY_INIT (gst_log_debug, "log", 0, "log tracer");
+#define gst_log_tracer_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstLogTracer, gst_log_tracer, GST_TYPE_TRACER,
+ _do_init);
+
+static void gst_log_tracer_invoke (GstStructure * s);
+
+static void
+gst_log_tracer_class_init (GstLogTracerClass * klass)
+{
+ GstTracerClass *gst_tracer_class = GST_TRACER_CLASS (klass);
+
+ gst_tracer_class->invoke = gst_log_tracer_invoke;
+}
+
+static void
+gst_log_tracer_init (GstLogTracer * self)
+{
+ g_object_set (self, "mask", GST_TRACER_HOOK_ALL, NULL);
+}
+
+static void
+gst_log_tracer_invoke (GstStructure * s)
+{
+ gchar *str = gst_structure_to_string (s);
+ /* TODO(ensonic): log to different categories depending on GstHookId */
+ GST_TRACE ("%s", str);
+ g_free (str);
+}
--- /dev/null
+/* GStreamer
+ * Copyright (C) 2013 Stefan Sauer <ensonic@users.sf.net>
+ *
+ * gstlog.h: tracing module that logs events
+ *
+ * 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_LOG_TRACER_H__
+#define __GST_LOG_TRACER_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_LOG_TRACER \
+ (gst_log_tracer_get_type())
+#define GST_LOG_TRACER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_LOG_TRACER,GstLogTracer))
+#define GST_LOG_TRACER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_LOG_TRACER,GstLogTracerClass))
+#define GST_IS_LOG_TRACER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_LOG_TRACER))
+#define GST_IS_LOG_TRACER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_LOG_TRACER))
+
+typedef struct _GstLogTracer GstLogTracer;
+typedef struct _GstLogTracerClass GstLogTracerClass;
+
+/**
+ * GstLogTracer:
+ *
+ * Opaque #GstLogTracer data structure
+ */
+struct _GstLogTracer {
+ GstTracer parent;
+
+ /*< private >*/
+};
+
+struct _GstLogTracerClass {
+ GstTracerClass parent_class;
+
+ /* signals */
+};
+
+G_GNUC_INTERNAL GType gst_log_tracer_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_LOG_TRACER_H__ */
--- /dev/null
+/* GStreamer
+ * Copyright (C) 2013 Stefan Sauer <ensonic@users.sf.net>
+ *
+ * gsttracers.c: tracing modules
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include "gstlog.h"
+
+static gboolean
+plugin_init (GstPlugin * plugin)
+{
+ if (!gst_tracer_register (plugin, "log", gst_log_tracer_get_type ()))
+ return FALSE;
+ return TRUE;
+}
+
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, coretracers,
+ "GStreamer core tracers", plugin_init, VERSION, GST_LICENSE,
+ GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);