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
|
libs/gst/net/Makefile
|
||||||
plugins/Makefile
|
plugins/Makefile
|
||||||
plugins/elements/Makefile
|
plugins/elements/Makefile
|
||||||
|
plugins/tracers/Makefile
|
||||||
po/Makefile.in
|
po/Makefile.in
|
||||||
tests/Makefile
|
tests/Makefile
|
||||||
tests/benchmarks/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
|
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.
|
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
|
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
|
variable, such as GST_TRACE="meminfo,dbus". One can also pass parameters to
|
||||||
add them to certain hooks. Another env var GST_TRACE_CHANNEL can be used to send
|
plugins: GST_TRACE="log(events;buffers),stats(all)".
|
||||||
the tracing to a file or a socket (Do the same for GST_DEBUG_CHANNEL). The syntax
|
When then plugins are loaded, we'll add them to certain hooks according to that
|
||||||
could be GST_XXX_CHANNEL=file:///path/to/file or GST_XXX_CHANNEL=tcp://<ip>:<port>.
|
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.
|
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
|
TODO(ensonic): we might want to have GST_{DEBUG|TRACE)_FORMAT envars as well.
|
||||||
could be raw, ansi-color, binary, ...
|
These could be raw, ansi-color, binary, suitable for babeltrace (see lttng), ...
|
||||||
|
|
||||||
Hooks
|
With these we can deprecate GST_DEBUG_FILE and GST_DEBUG_NO_COLOR.
|
||||||
-----
|
|
||||||
e.g. gst_pad_push() will do add this line:
|
|
||||||
GST_TRACER_PUSH_BUFFER (pad, buffer)
|
|
||||||
|
|
||||||
If tracing is disable at compile time the macro will evaluate to nothing. Otherwise
|
Hook api
|
||||||
it will become something along the lines of:
|
--------
|
||||||
if (__tracer && __tracer_hook_is_used) {
|
e.g. gst_pad_push() would become:
|
||||||
gst_tracer_push_buffer (pad, buffer);
|
|
||||||
|
#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
|
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://lwn.net/Articles/412072/ + http://lwn.net/Articles/435215/
|
||||||
- http://lxr.free-electrons.com/source/kernel/jump_label.c
|
- 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 :/
|
- it is linux specific :/
|
||||||
|
|
||||||
In addition to api hooks we should also provide timer hooks. Interval timers are
|
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
|
Hooks
|
||||||
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
|
gst_bin_add
|
||||||
consume (=read) the provided data. Most trace plugins will log data to a trace
|
gst_bin_remove
|
||||||
channel.
|
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
|
meminfo
|
||||||
-------
|
-------
|
||||||
|
@ -68,17 +130,19 @@ dbus
|
||||||
----
|
----
|
||||||
- provide a dbus iface to announce applications that are traced
|
- 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
|
- 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
|
is getting logged to
|
||||||
application is started with tracing activated, the dbus plugin will announce the
|
- one would start the tracing UI first and when the application is started with
|
||||||
new application, upon which the tracing UI can start reading from the log channels
|
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
|
topology
|
||||||
--------
|
--------
|
||||||
- register to pipeline topology hooks
|
- register to pipeline topology hooks
|
||||||
- tracing UIs can show a live pipeline graph
|
- tracing UIs can show a live pipeline graph
|
||||||
|
|
||||||
communication
|
stats
|
||||||
-------------
|
-----
|
||||||
- register to buffer, event, message and query flow
|
- register to buffer, event, message and query flow
|
||||||
- tracing apps can do e.g. statistics
|
- 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
|
is loaded) and read the log streams from the sockets/files that are configured for
|
||||||
the app.
|
the app.
|
||||||
|
|
||||||
gst-trace-stats
|
gst-tracer
|
||||||
---------------
|
----------
|
||||||
Such a tool could read a trace and summarize the content like gst-tracelib did for
|
Counterpart of gst-tracelib-ui
|
||||||
stats in 0.10.
|
|
||||||
|
|
||||||
|
|
||||||
Problems / Open items
|
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
|
- 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
|
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 \
|
gsttoc.c \
|
||||||
gsttocsetter.c \
|
gsttocsetter.c \
|
||||||
$(GST_TRACE_SRC) \
|
$(GST_TRACE_SRC) \
|
||||||
|
gsttracer.c \
|
||||||
|
gsttracerfactory.c \
|
||||||
gsttypefind.c \
|
gsttypefind.c \
|
||||||
gsttypefindfactory.c \
|
gsttypefindfactory.c \
|
||||||
gsturi.c \
|
gsturi.c \
|
||||||
|
@ -218,6 +220,8 @@ gst_headers = \
|
||||||
gsttaskpool.h \
|
gsttaskpool.h \
|
||||||
gsttoc.h \
|
gsttoc.h \
|
||||||
gsttocsetter.h \
|
gsttocsetter.h \
|
||||||
|
gsttracer.h \
|
||||||
|
gsttracerfactory.h \
|
||||||
gsttypefind.h \
|
gsttypefind.h \
|
||||||
gsttypefindfactory.h \
|
gsttypefindfactory.h \
|
||||||
gsturi.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_pad_get_type ());
|
||||||
g_type_class_ref (gst_element_factory_get_type ());
|
g_type_class_ref (gst_element_factory_get_type ());
|
||||||
g_type_class_ref (gst_element_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_type_find_factory_get_type ());
|
||||||
g_type_class_ref (gst_bin_get_type ());
|
g_type_class_ref (gst_bin_get_type ());
|
||||||
g_type_class_ref (gst_bus_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);
|
GLIB_MINOR_VERSION, GLIB_MICRO_VERSION);
|
||||||
GST_INFO ("initialized GStreamer successfully");
|
GST_INFO ("initialized GStreamer successfully");
|
||||||
|
|
||||||
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
_priv_gst_tracer_init ();
|
||||||
|
#endif
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -951,6 +956,9 @@ gst_deinit (void)
|
||||||
GST_DEBUG ("already deinitialized");
|
GST_DEBUG ("already deinitialized");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
_priv_gst_tracer_deinit ();
|
||||||
|
#endif
|
||||||
|
|
||||||
g_thread_pool_set_max_unused_threads (0);
|
g_thread_pool_set_max_unused_threads (0);
|
||||||
bin_class = GST_BIN_CLASS (g_type_class_peek (gst_bin_get_type ()));
|
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_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_factory_get_type ()));
|
||||||
g_type_class_unref (g_type_class_peek (gst_element_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_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_bin_get_type ()));
|
||||||
g_type_class_unref (g_type_class_peek (gst_bus_get_type ()));
|
g_type_class_unref (g_type_class_peek (gst_bus_get_type ()));
|
||||||
|
|
|
@ -77,6 +77,8 @@
|
||||||
#include <gst/gsttaskpool.h>
|
#include <gst/gsttaskpool.h>
|
||||||
#include <gst/gsttoc.h>
|
#include <gst/gsttoc.h>
|
||||||
#include <gst/gsttocsetter.h>
|
#include <gst/gsttocsetter.h>
|
||||||
|
#include <gst/gsttracer.h>
|
||||||
|
#include <gst/gsttracerfactory.h>
|
||||||
#include <gst/gsttypefind.h>
|
#include <gst/gsttypefind.h>
|
||||||
#include <gst/gsttypefindfactory.h>
|
#include <gst/gsttypefindfactory.h>
|
||||||
#include <gst/gsturi.h>
|
#include <gst/gsturi.h>
|
||||||
|
|
|
@ -393,6 +393,27 @@ struct _GstTypeFindFactoryClass {
|
||||||
gpointer _gst_reserved[GST_PADDING];
|
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 {
|
struct _GstElementFactory {
|
||||||
GstPluginFeature parent;
|
GstPluginFeature parent;
|
||||||
|
|
||||||
|
|
21
gst/gstpad.c
21
gst/gstpad.c
|
@ -94,6 +94,7 @@
|
||||||
#include "gstutils.h"
|
#include "gstutils.h"
|
||||||
#include "gstinfo.h"
|
#include "gstinfo.h"
|
||||||
#include "gsterror.h"
|
#include "gsterror.h"
|
||||||
|
#include "gsttracer.h"
|
||||||
#include "gstvalue.h"
|
#include "gstvalue.h"
|
||||||
#include "glib-compat-private.h"
|
#include "glib-compat-private.h"
|
||||||
|
|
||||||
|
@ -4442,8 +4443,28 @@ not_linked:
|
||||||
*
|
*
|
||||||
* MT safe.
|
* MT safe.
|
||||||
*/
|
*/
|
||||||
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
static inline GstFlowReturn __gst_pad_push (GstPad * pad, GstBuffer * buffer);
|
||||||
|
#endif
|
||||||
|
|
||||||
GstFlowReturn
|
GstFlowReturn
|
||||||
gst_pad_push (GstPad * pad, GstBuffer * buffer)
|
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_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_PAD_IS_SRC (pad), GST_FLOW_ERROR);
|
||||||
|
|
|
@ -55,7 +55,7 @@ G_BEGIN_DECLS
|
||||||
* This _must_ be updated whenever the registry format changes,
|
* This _must_ be updated whenever the registry format changes,
|
||||||
* we currently use the core version where this change happened.
|
* 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:
|
* GST_MAGIC_BINARY_VERSION_LEN:
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#include <gst/gst_private.h>
|
#include <gst/gst_private.h>
|
||||||
#include <gst/gstconfig.h>
|
#include <gst/gstconfig.h>
|
||||||
#include <gst/gstelement.h>
|
#include <gst/gstelement.h>
|
||||||
|
#include <gst/gsttracer.h>
|
||||||
|
#include <gst/gsttracerfactory.h>
|
||||||
#include <gst/gsttypefind.h>
|
#include <gst/gsttypefind.h>
|
||||||
#include <gst/gsttypefindfactory.h>
|
#include <gst/gsttypefindfactory.h>
|
||||||
#include <gst/gstdeviceproviderfactory.h>
|
#include <gst/gstdeviceproviderfactory.h>
|
||||||
|
@ -350,6 +352,13 @@ gst_registry_chunks_save_feature (GList ** list, GstPluginFeature * feature)
|
||||||
/* pack element metadata strings */
|
/* pack element metadata strings */
|
||||||
gst_registry_chunks_save_string (list,
|
gst_registry_chunks_save_string (list,
|
||||||
gst_structure_to_string (factory->metadata));
|
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 {
|
} else {
|
||||||
GST_WARNING_OBJECT (feature, "unhandled feature type '%s'", type_name);
|
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
|
GST_DEBUG
|
||||||
("Reading/casting for GstRegistryChunkPluginFeature at address %p",
|
("Reading/casting for GstRegistryChunkPluginFeature at address %p",
|
||||||
*in);
|
*in);
|
||||||
|
|
||||||
unpack_element (*in, dmf, GstRegistryChunkDeviceProviderFactory, end, fail);
|
unpack_element (*in, dmf, GstRegistryChunkDeviceProviderFactory, end, fail);
|
||||||
|
|
||||||
pf = (GstRegistryChunkPluginFeature *) dmf;
|
pf = (GstRegistryChunkPluginFeature *) dmf;
|
||||||
|
@ -692,6 +702,12 @@ gst_registry_chunks_load_feature (GstRegistry * registry, gchar ** in,
|
||||||
goto fail;
|
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 {
|
} else {
|
||||||
GST_WARNING ("unhandled factory type : %s", G_OBJECT_TYPE_NAME (feature));
|
GST_WARNING ("unhandled factory type : %s", G_OBJECT_TYPE_NAME (feature));
|
||||||
goto fail;
|
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