2 * Copyright (C) 2013 Stefan Sauer <ensonic@users.sf.net>
4 * gsttracerutils.c: tracing subsystem
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
23 * SECTION:gsttracerutils
24 * @short_description: Tracing subsystem
26 * The tracing subsystem provides hooks in the core library and API for modules
29 * The user can activate tracers by setting the environment variable GST_TRACE
30 * to a ';' separated list of tracers.
33 #define GST_USE_UNSTABLE_API
35 #include "gst_private.h"
36 #include "gsttracer.h"
37 #include "gsttracerfactory.h"
38 #include "gsttracerutils.h"
40 #ifndef GST_DISABLE_GST_DEBUG
44 /* These strings must match order and number declared in the GstTracerQuarkId
45 * enum in gsttracerutils.h! */
46 static const gchar *_quark_strings[] = {
47 "pad-push-pre", "pad-push-post", "pad-push-list-pre", "pad-push-list-post",
48 "pad-pull-range-pre", "pad-pull-range-post", "pad-push-event-pre",
49 "pad-push-event-post", "pad-query-pre", "pad-query-post",
50 "element-post-message-pre",
51 "element-post-message-post", "element-query-pre", "element-query-post",
52 "element-new", "element-add-pad", "element-remove-pad", "bin-add-pre",
53 "bin-add-post", "bin-remove-pre", "bin-remove-post", "pad-link-pre",
54 "pad-link-post", "pad-unlink-pre", "pad-unlink-post"
57 GQuark _priv_gst_tracer_quark_table[GST_TRACER_QUARK_MAX];
61 gboolean _priv_tracer_enabled = FALSE;
62 GHashTable *_priv_tracers = NULL;
64 /* Initialize the tracing system */
66 _priv_gst_tracing_init (void)
68 const gchar *env = g_getenv ("GST_TRACER_PLUGINS");
70 if (env != NULL && *env != '\0') {
71 GstRegistry *registry = gst_registry_get ();
72 GstPluginFeature *feature;
73 GstTracerFactory *factory;
74 gchar **t = g_strsplit_set (env, ";", 0);
78 GST_INFO ("enabling tracers: '%s'", env);
80 if (G_N_ELEMENTS (_quark_strings) != GST_TRACER_QUARK_MAX)
81 g_warning ("the quark table is not consistent! %d != %d",
82 (gint) G_N_ELEMENTS (_quark_strings), GST_TRACER_QUARK_MAX);
84 for (i = 0; i < GST_TRACER_QUARK_MAX; i++) {
85 _priv_gst_tracer_quark_table[i] =
86 g_quark_from_static_string (_quark_strings[i]);
89 _priv_tracers = g_hash_table_new (NULL, NULL);
93 // check t[i] for params
94 if ((params = strchr (t[i], '('))) {
95 gchar *end = strchr (¶ms[1], ')');
104 GST_INFO ("checking tracer: '%s'", t[i]);
106 if ((feature = gst_registry_lookup_feature (registry, t[i]))) {
107 factory = GST_TRACER_FACTORY (gst_plugin_feature_load (feature));
109 GST_INFO_OBJECT (factory, "creating tracer: type-id=%u",
110 (guint) factory->type);
112 /* tracers register them self to the hooks */
113 gst_object_unref (g_object_new (factory->type, "params", params,
116 GST_WARNING_OBJECT (feature,
117 "loading plugin containing feature %s failed!", t[i]);
120 GST_WARNING ("no tracer named '%s'", t[i]);
129 _priv_gst_tracing_deinit (void)
131 GList *h_list, *h_node, *t_node;
134 _priv_tracer_enabled = FALSE;
138 /* shutdown tracers for final reports */
139 h_list = g_hash_table_get_values (_priv_tracers);
140 for (h_node = h_list; h_node; h_node = g_list_next (h_node)) {
141 for (t_node = h_node->data; t_node; t_node = g_list_next (t_node)) {
142 hook = (GstTracerHook *) t_node->data;
143 gst_object_unref (hook->tracer);
144 g_slice_free (GstTracerHook, hook);
146 g_list_free (h_node->data);
148 g_list_free (h_list);
149 g_hash_table_destroy (_priv_tracers);
150 _priv_tracers = NULL;
154 * gst_tracing_register_hook_id:
155 * @tracer: the tracer
156 * @detail: the detailed hook
157 * @func: (scope async): the callback
159 * Register @func to be called when the trace hook @detail is getting invoked.
162 gst_tracing_register_hook_id (GstTracer * tracer, GQuark detail, GCallback func)
164 gpointer key = GINT_TO_POINTER (detail);
165 GList *list = g_hash_table_lookup (_priv_tracers, key);
166 GstTracerHook *hook = g_slice_new0 (GstTracerHook);
167 hook->tracer = gst_object_ref (tracer);
170 list = g_list_prepend (list, hook);
171 g_hash_table_replace (_priv_tracers, key, list);
172 GST_DEBUG ("registering tracer for '%s', list.len=%d",
173 (detail ? g_quark_to_string (detail) : "*"), g_list_length (list));
174 _priv_tracer_enabled = TRUE;
178 * gst_tracing_register_hook:
179 * @tracer: the tracer
180 * @detail: the detailed hook
181 * @func: (scope async): the callback
183 * Register @func to be called when the trace hook @detail is getting invoked.
186 gst_tracing_register_hook (GstTracer * tracer, const gchar * detail,
189 gst_tracing_register_hook_id (tracer, g_quark_try_string (detail), func);
192 #endif /* GST_DISABLE_GST_DEBUG */