mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 16:26:39 +00:00
tracer: initial prototype for the tracing subsystem
This commit is contained in:
parent
456ef2aa1d
commit
4e5d586c7d
19 changed files with 951 additions and 35 deletions
|
@ -990,6 +990,7 @@ libs/gst/helpers/Makefile
|
|||
libs/gst/net/Makefile
|
||||
plugins/Makefile
|
||||
plugins/elements/Makefile
|
||||
plugins/tracers/Makefile
|
||||
po/Makefile.in
|
||||
tests/Makefile
|
||||
tests/benchmarks/Makefile
|
||||
|
|
|
@ -11,26 +11,57 @@ per process or none if tracing is off (not enabled via envvar or compiled out).
|
|||
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.
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
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
|
||||
|
@ -41,18 +72,49 @@ TODO(ensonic): liblttng-ust provides such a mechanism for user-space
|
|||
- 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.
|
||||
useful to get e.g. resource usage snapshots. Also absolute timers might make
|
||||
sense. All this could be implemented with a clock thread.
|
||||
|
||||
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.
|
||||
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
|
||||
|
||||
TODO(ensonic): use GSignal for the hooks?
|
||||
Plugin api
|
||||
----------
|
||||
|
||||
Plugins
|
||||
=======
|
||||
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
|
||||
-------
|
||||
|
@ -68,17 +130,19 @@ dbus
|
|||
----
|
||||
- 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
|
||||
|
||||
|
@ -92,14 +156,21 @@ Alternatively it would show a dialog that shows all local apps (if the dbus plug
|
|||
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
|
||||
|
||||
|
|
|
@ -115,6 +115,8 @@ libgstreamer_@GST_API_VERSION@_la_SOURCES = \
|
|||
gsttoc.c \
|
||||
gsttocsetter.c \
|
||||
$(GST_TRACE_SRC) \
|
||||
gsttracer.c \
|
||||
gsttracerfactory.c \
|
||||
gsttypefind.c \
|
||||
gsttypefindfactory.c \
|
||||
gsturi.c \
|
||||
|
@ -218,6 +220,8 @@ gst_headers = \
|
|||
gsttaskpool.h \
|
||||
gsttoc.h \
|
||||
gsttocsetter.h \
|
||||
gsttracer.h \
|
||||
gsttracerfactory.h \
|
||||
gsttypefind.h \
|
||||
gsttypefindfactory.h \
|
||||
gsturi.h \
|
||||
|
|
|
@ -587,6 +587,7 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
|
|||
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 ());
|
||||
|
@ -718,6 +719,10 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
|
|||
GLIB_MINOR_VERSION, GLIB_MICRO_VERSION);
|
||||
GST_INFO ("initialized GStreamer successfully");
|
||||
|
||||
#ifndef GST_DISABLE_GST_DEBUG
|
||||
_priv_gst_tracer_init ();
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -951,6 +956,9 @@ gst_deinit (void)
|
|||
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 ()));
|
||||
|
@ -984,6 +992,7 @@ gst_deinit (void)
|
|||
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 ()));
|
||||
|
|
|
@ -77,6 +77,8 @@
|
|||
#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>
|
||||
|
|
|
@ -393,6 +393,27 @@ struct _GstTypeFindFactoryClass {
|
|||
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;
|
||||
|
||||
|
|
21
gst/gstpad.c
21
gst/gstpad.c
|
@ -94,6 +94,7 @@
|
|||
#include "gstutils.h"
|
||||
#include "gstinfo.h"
|
||||
#include "gsterror.h"
|
||||
#include "gsttracer.h"
|
||||
#include "gstvalue.h"
|
||||
#include "glib-compat-private.h"
|
||||
|
||||
|
@ -4442,8 +4443,28 @@ not_linked:
|
|||
*
|
||||
* 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);
|
||||
|
|
|
@ -55,7 +55,7 @@ G_BEGIN_DECLS
|
|||
* 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:
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#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>
|
||||
|
@ -350,6 +352,13 @@ gst_registry_chunks_save_feature (GList ** list, GstPluginFeature * feature)
|
|||
/* 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);
|
||||
}
|
||||
|
@ -677,6 +686,7 @@ gst_registry_chunks_load_feature (GstRegistry * registry, gchar ** in,
|
|||
GST_DEBUG
|
||||
("Reading/casting for GstRegistryChunkPluginFeature at address %p",
|
||||
*in);
|
||||
|
||||
unpack_element (*in, dmf, GstRegistryChunkDeviceProviderFactory, end, fail);
|
||||
|
||||
pf = (GstRegistryChunkPluginFeature *) dmf;
|
||||
|
@ -692,6 +702,12 @@ gst_registry_chunks_load_feature (GstRegistry * registry, gchar ** in,
|
|||
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;
|
||||
|
|
313
gst/gsttracer.c
Normal file
313
gst/gsttracer.c
Normal file
|
@ -0,0 +1,313 @@
|
|||
/* 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 */
|
115
gst/gsttracer.h
Normal file
115
gst/gsttracer.h
Normal file
|
@ -0,0 +1,115 @@
|
|||
/* 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__ */
|
||||
|
76
gst/gsttracerfactory.c
Normal file
76
gst/gsttracerfactory.c
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* 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);
|
||||
}
|
56
gst/gsttracerfactory.h
Normal file
56
gst/gsttracerfactory.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* 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__ */
|
|
@ -1,3 +1,4 @@
|
|||
SUBDIRS = elements
|
||||
SUBDIRS = elements tracers
|
||||
|
||||
DIST_SUBDIRS = elements tracers
|
||||
|
||||
DIST_SUBDIRS = elements
|
||||
|
|
12
plugins/tracers/.gitignore
vendored
Normal file
12
plugins/tracers/.gitignore
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
Makefile
|
||||
Makefile.in
|
||||
*.o
|
||||
*.lo
|
||||
*.la
|
||||
.deps
|
||||
.libs
|
||||
*.bb
|
||||
*.bbg
|
||||
*.da
|
||||
*.def
|
||||
*.gcno
|
35
plugins/tracers/Makefile.am
Normal file
35
plugins/tracers/Makefile.am
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
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@ \
|
||||
> $@
|
60
plugins/tracers/gstlog.c
Normal file
60
plugins/tracers/gstlog.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* 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);
|
||||
}
|
64
plugins/tracers/gstlog.h
Normal file
64
plugins/tracers/gstlog.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* 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__ */
|
39
plugins/tracers/gsttracers.c
Normal file
39
plugins/tracers/gsttracers.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/* 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);
|
Loading…
Reference in a new issue