tracer: simplify hook api

Instead of a single invoke() function and a 'mask', register to individual
hooks. This avoids one level of indirection and allows us to remove the
hook enums. The message enms are now renamed to hook enums.
This commit is contained in:
Stefan Sauer 2014-09-15 13:15:17 +02:00
parent 7b24d76260
commit 1a3e218b89
8 changed files with 470 additions and 534 deletions

View file

@ -45,7 +45,6 @@ enum
{ {
PROP_0, PROP_0,
PROP_PARAMS, PROP_PARAMS,
PROP_MASK,
PROP_LAST PROP_LAST
}; };
@ -59,7 +58,6 @@ static void gst_tracer_get_property (GObject * object, guint prop_id,
struct _GstTracerPrivate struct _GstTracerPrivate
{ {
const gchar *params; const gchar *params;
GstTracerHook mask;
}; };
#define gst_tracer_parent_class parent_class #define gst_tracer_parent_class parent_class
@ -77,10 +75,6 @@ gst_tracer_class_init (GstTracerClass * klass)
g_param_spec_string ("params", "Params", "Extra configuration parameters", g_param_spec_string ("params", "Params", "Extra configuration parameters",
NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); 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_object_class_install_properties (gobject_class, PROP_LAST, properties);
g_type_class_add_private (klass, sizeof (GstTracerPrivate)); g_type_class_add_private (klass, sizeof (GstTracerPrivate));
} }
@ -102,9 +96,6 @@ gst_tracer_set_property (GObject * object, guint prop_id,
case PROP_PARAMS: case PROP_PARAMS:
self->priv->params = g_value_get_string (value); self->priv->params = g_value_get_string (value);
break; break;
case PROP_MASK:
self->priv->mask = g_value_get_flags (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -121,25 +112,12 @@ gst_tracer_get_property (GObject * object, guint prop_id,
case PROP_PARAMS: case PROP_PARAMS:
g_value_set_string (value, self->priv->params); g_value_set_string (value, self->priv->params);
break; break;
case PROP_MASK:
g_value_set_flags (value, self->priv->mask);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
} }
} }
void
gst_tracer_invoke (GstTracer * self, GstTracerMessageId mid, va_list var_args)
{
GstTracerClass *klass = GST_TRACER_GET_CLASS (self);
g_return_if_fail (klass->invoke);
klass->invoke (self, mid, var_args);
}
/* tracing modules */ /* tracing modules */
gboolean gboolean

View file

@ -53,24 +53,20 @@ struct _GstTracer {
gpointer _gst_reserved[GST_PADDING]; gpointer _gst_reserved[GST_PADDING];
}; };
typedef void (*GstTracerInvokeFunction) (GstTracer * self, typedef void (*GstTracerHookFunction) (GstTracer * self, va_list var_args);
GstTracerMessageId mid, va_list var_args);
struct _GstTracerClass { struct _GstTracerClass {
GstObjectClass parent_class; GstObjectClass parent_class;
/* plugin vmethods */
GstTracerInvokeFunction invoke;
/*< private >*/ /*< private >*/
gpointer _gst_reserved[GST_PADDING]; gpointer _gst_reserved[GST_PADDING];
}; };
void gst_tracer_invoke (GstTracer * self, GstTracerMessageId mid,
va_list var_args);
GType gst_tracer_get_type (void); GType gst_tracer_get_type (void);
void gst_tracer_register_hook (GstTracer *tracer, GstTracerHookId id,
GstTracerHookFunction func);
G_END_DECLS G_END_DECLS
#endif /* __GST_TRACER_H__ */ #endif /* __GST_TRACER_H__ */

View file

@ -45,6 +45,12 @@ gboolean _priv_tracer_enabled = FALSE;
/* TODO(ensonic): use array of GPtrArray* ? */ /* TODO(ensonic): use array of GPtrArray* ? */
GList *_priv_tracers[GST_TRACER_HOOK_ID_LAST] = { NULL, }; GList *_priv_tracers[GST_TRACER_HOOK_ID_LAST] = { NULL, };
typedef struct
{
GstTracer *tracer;
GstTracerHookFunction func;
} GstTracerHook;
/* Initialize the tracing system */ /* Initialize the tracing system */
void void
_priv_gst_tracer_init (void) _priv_gst_tracer_init (void)
@ -55,10 +61,8 @@ _priv_gst_tracer_init (void)
GstRegistry *registry = gst_registry_get (); GstRegistry *registry = gst_registry_get ();
GstPluginFeature *feature; GstPluginFeature *feature;
GstTracerFactory *factory; GstTracerFactory *factory;
GstTracerHook mask;
GstObject *tracer;
gchar **t = g_strsplit_set (env, ";", 0); gchar **t = g_strsplit_set (env, ";", 0);
gint i = 0, j; gint i = 0;
gchar *params; gchar *params;
GST_INFO ("enabling tracers: '%s'", env); GST_INFO ("enabling tracers: '%s'", env);
@ -83,28 +87,9 @@ _priv_gst_tracer_init (void)
GST_INFO_OBJECT (factory, "creating tracer: type-id=%u", GST_INFO_OBJECT (factory, "creating tracer: type-id=%u",
(guint) factory->type); (guint) factory->type);
tracer = g_object_new (factory->type, "params", params, NULL); /* tracers register them self to the hooks */
g_object_get (tracer, "mask", &mask, NULL); gst_object_unref (g_object_new (factory->type, "params", params,
NULL));
if (mask) {
/* add to lists according to mask */
j = 0;
while (mask && (j < GST_TRACER_HOOK_ID_LAST)) {
if (mask & 1) {
_priv_tracers[j] = g_list_prepend (_priv_tracers[j],
gst_object_ref (tracer));
GST_WARNING_OBJECT (tracer, "added tracer to hook %d", j);
}
mask >>= 1;
j++;
}
_priv_tracer_enabled = TRUE;
} else {
GST_WARNING_OBJECT (tracer,
"tracer with zero mask won't have any effect");
}
gst_object_unref (tracer);
} else { } else {
GST_WARNING_OBJECT (feature, GST_WARNING_OBJECT (feature,
"loading plugin containing feature %s failed!", t[i]); "loading plugin containing feature %s failed!", t[i]);
@ -123,11 +108,14 @@ _priv_gst_tracer_deinit (void)
{ {
gint i; gint i;
GList *node; GList *node;
GstTracerHook *hook;
/* shutdown tracers for final reports */ /* shutdown tracers for final reports */
for (i = 0; i < GST_TRACER_HOOK_ID_LAST; i++) { for (i = 0; i < GST_TRACER_HOOK_ID_LAST; i++) {
for (node = _priv_tracers[i]; node; node = g_list_next (node)) { for (node = _priv_tracers[i]; node; node = g_list_next (node)) {
gst_object_unref (node->data); hook = (GstTracerHook *) node->data;
gst_object_unref (hook->tracer);
g_slice_free (GstTracerHook, hook);
} }
g_list_free (_priv_tracers[i]); g_list_free (_priv_tracers[i]);
_priv_tracers[i] = NULL; _priv_tracers[i] = NULL;
@ -136,14 +124,28 @@ _priv_gst_tracer_deinit (void)
} }
void void
gst_tracer_dispatch (GstTracerHookId hid, GstTracerMessageId mid, ...) gst_tracer_register_hook (GstTracer * tracer, GstTracerHookId id,
GstTracerHookFunction func)
{
GstTracerHook *hook = g_slice_new0 (GstTracerHook);
hook->tracer = gst_object_ref (tracer);
hook->func = func;
_priv_tracers[id] = g_list_prepend (_priv_tracers[id], hook);
GST_DEBUG_OBJECT (tracer, "added tracer to hook %d", id);
_priv_tracer_enabled = TRUE;
}
void
gst_tracer_dispatch (GstTracerHookId id, ...)
{ {
va_list var_args; va_list var_args;
GList *node; GList *node;
GstTracerHook *hook;
for (node = _priv_tracers[hid]; node; node = g_list_next (node)) { for (node = _priv_tracers[id]; node; node = g_list_next (node)) {
va_start (var_args, mid); hook = (GstTracerHook *) node->data;
gst_tracer_invoke (node->data, mid, var_args); va_start (var_args, id);
hook->func (hook->tracer, var_args);
va_end (var_args); va_end (var_args);
} }
} }

View file

@ -32,52 +32,25 @@ G_BEGIN_DECLS
#ifndef GST_DISABLE_GST_DEBUG #ifndef GST_DISABLE_GST_DEBUG
/* hook flags and ids */ /* tracer hook message ids */
typedef enum typedef enum
{ {
GST_TRACER_HOOK_NONE = 0, GST_TRACER_HOOK_ID_PAD_PUSH_PRE = 0,
GST_TRACER_HOOK_BUFFERS = (1 << 0), GST_TRACER_HOOK_ID_PAD_PUSH_POST,
GST_TRACER_HOOK_EVENTS = (1 << 1), GST_TRACER_HOOK_ID_PAD_PUSH_LIST_PRE,
GST_TRACER_HOOK_MESSAGES = (1 << 2), GST_TRACER_HOOK_ID_PAD_PUSH_LIST_POST,
GST_TRACER_HOOK_QUERIES = (1 << 3), GST_TRACER_HOOK_ID_PAD_PULL_RANGE_PRE,
GST_TRACER_HOOK_TOPOLOGY = (1 << 4), GST_TRACER_HOOK_ID_PAD_PULL_RANGE_POST,
/* GST_TRACER_HOOK_ID_PAD_PUSH_EVENT_PRE,
GST_TRACER_HOOK_TIMER GST_TRACER_HOOK_ID_PAD_PUSH_EVENT_POST,
*/ GST_TRACER_HOOK_ID_ELEMENT_POST_MESSAGE_PRE,
GST_TRACER_HOOK_ALL = (1 << 5) - 1 GST_TRACER_HOOK_ID_ELEMENT_POST_MESSAGE_POST,
} GstTracerHook; GST_TRACER_HOOK_ID_ELEMENT_QUERY_PRE,
GST_TRACER_HOOK_ID_ELEMENT_QUERY_POST,
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 GST_TRACER_HOOK_ID_LAST
} GstTracerHookId; } GstTracerHookId;
typedef enum
{
GST_TRACER_MESSAGE_ID_PAD_PUSH_PRE = 0,
GST_TRACER_MESSAGE_ID_PAD_PUSH_POST,
GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_PRE,
GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_POST,
GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_PRE,
GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_POST,
GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_PRE,
GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_POST,
GST_TRACER_MESSAGE_ID_ELEMENT_POST_MESSAGE_PRE,
GST_TRACER_MESSAGE_ID_ELEMENT_POST_MESSAGE_POST,
GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_PRE,
GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_POST,
GST_TRACER_MESSAGE_ID_LAST
} GstTracerMessageId;
/* tracing hooks */ /* tracing hooks */
void _priv_gst_tracer_init (void); void _priv_gst_tracer_init (void);
@ -89,7 +62,7 @@ gboolean gst_tracer_register (GstPlugin * plugin, const gchar * name, GType type
/* tracing helpers */ /* tracing helpers */
void gst_tracer_dispatch (GstTracerHookId hid, GstTracerMessageId mid, ...); void gst_tracer_dispatch (GstTracerHookId id, ...);
/* tracing module helpers */ /* tracing module helpers */
@ -107,97 +80,97 @@ extern GList *_priv_tracers[GST_TRACER_HOOK_ID_LAST];
/* tracing hooks */ /* tracing hooks */
#define GST_TRACER_PAD_PUSH_PRE(pad, buffer) G_STMT_START{ \ #define GST_TRACER_PAD_PUSH_PRE(pad, buffer) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_PAD_PUSH_PRE)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \ gst_tracer_dispatch (GST_TRACER_HOOK_ID_PAD_PUSH_PRE, \
GST_TRACER_MESSAGE_ID_PAD_PUSH_PRE, GST_TRACER_TS, \ GST_TRACER_TS, \
pad, buffer); \ pad, buffer); \
} \ } \
}G_STMT_END }G_STMT_END
#define GST_TRACER_PAD_PUSH_POST(pad, res) G_STMT_START{ \ #define GST_TRACER_PAD_PUSH_POST(pad, res) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_PAD_PUSH_POST)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \ gst_tracer_dispatch (GST_TRACER_HOOK_ID_PAD_PUSH_POST, \
GST_TRACER_MESSAGE_ID_PAD_PUSH_POST, GST_TRACER_TS, \ GST_TRACER_TS, \
pad, res); \ pad, res); \
} \ } \
}G_STMT_END }G_STMT_END
#define GST_TRACER_PAD_PUSH_LIST_PRE(pad, list) G_STMT_START{ \ #define GST_TRACER_PAD_PUSH_LIST_PRE(pad, list) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_PAD_PUSH_LIST_PRE)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \ gst_tracer_dispatch (GST_TRACER_HOOK_ID_PAD_PUSH_LIST_PRE, \
GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_PRE, GST_TRACER_TS, \ GST_TRACER_TS, \
pad, list); \ pad, list); \
} \ } \
}G_STMT_END }G_STMT_END
#define GST_TRACER_PAD_PUSH_LIST_POST(pad, res) G_STMT_START{ \ #define GST_TRACER_PAD_PUSH_LIST_POST(pad, res) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_PAD_PUSH_LIST_POST)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \ gst_tracer_dispatch (GST_TRACER_HOOK_ID_PAD_PUSH_LIST_POST, \
GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_POST, GST_TRACER_TS, \ GST_TRACER_TS, \
pad, res); \ pad, res); \
} \ } \
}G_STMT_END }G_STMT_END
#define GST_TRACER_PAD_PULL_RANGE_PRE(pad, offset, size) G_STMT_START{ \ #define GST_TRACER_PAD_PULL_RANGE_PRE(pad, offset, size) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_PAD_PULL_RANGE_PRE)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \ gst_tracer_dispatch (GST_TRACER_HOOK_ID_PAD_PULL_RANGE_PRE, \
GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_PRE, GST_TRACER_TS, \ GST_TRACER_TS, \
pad, offset, size); \ pad, offset, size); \
} \ } \
}G_STMT_END }G_STMT_END
#define GST_TRACER_PAD_PULL_RANGE_POST(pad, buffer, res) G_STMT_START{ \ #define GST_TRACER_PAD_PULL_RANGE_POST(pad, buffer, res) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_PAD_PULL_RANGE_POST)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \ gst_tracer_dispatch (GST_TRACER_HOOK_ID_PAD_PULL_RANGE_POST, \
GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_POST, GST_TRACER_TS, \ GST_TRACER_TS, \
pad, buffer, res); \ pad, buffer, res); \
} \ } \
}G_STMT_END }G_STMT_END
#define GST_TRACER_PAD_PUSH_EVENT_PRE(pad, event) G_STMT_START{ \ #define GST_TRACER_PAD_PUSH_EVENT_PRE(pad, event) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_EVENTS)) { \ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_PAD_PUSH_EVENT_PRE)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_EVENTS, \ gst_tracer_dispatch (GST_TRACER_HOOK_ID_PAD_PUSH_EVENT_PRE, \
GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_PRE, GST_TRACER_TS, \ GST_TRACER_TS, \
pad, event); \ pad, event); \
} \ } \
}G_STMT_END }G_STMT_END
#define GST_TRACER_PAD_PUSH_EVENT_POST(pad, res) G_STMT_START{ \ #define GST_TRACER_PAD_PUSH_EVENT_POST(pad, res) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_EVENTS)) { \ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_PAD_PUSH_EVENT_POST)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_EVENTS, \ gst_tracer_dispatch (GST_TRACER_HOOK_ID_PAD_PUSH_EVENT_POST, \
GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_POST, GST_TRACER_TS, \ GST_TRACER_TS, \
pad, res); \ pad, res); \
} \ } \
}G_STMT_END }G_STMT_END
#define GST_TRACER_ELEMENT_POST_MESSAGE_PRE(element, message) G_STMT_START{ \ #define GST_TRACER_ELEMENT_POST_MESSAGE_PRE(element, message) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_MESSAGES)) { \ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_ELEMENT_POST_MESSAGE_PRE)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_MESSAGES, \ gst_tracer_dispatch (GST_TRACER_HOOK_ID_ELEMENT_POST_MESSAGE_PRE, \
GST_TRACER_MESSAGE_ID_ELEMENT_POST_MESSAGE_PRE, GST_TRACER_TS, \ GST_TRACER_TS, \
element, message); \ element, message); \
} \ } \
}G_STMT_END }G_STMT_END
#define GST_TRACER_ELEMENT_POST_MESSAGE_POST(element, res) G_STMT_START{ \ #define GST_TRACER_ELEMENT_POST_MESSAGE_POST(element, res) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_MESSAGES)) { \ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_ELEMENT_POST_MESSAGE_POST)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_MESSAGES, \ gst_tracer_dispatch (GST_TRACER_HOOK_ID_ELEMENT_POST_MESSAGE_POST, \
GST_TRACER_MESSAGE_ID_ELEMENT_POST_MESSAGE_POST, GST_TRACER_TS, \ GST_TRACER_TS, \
element, res); \ element, res); \
} \ } \
}G_STMT_END }G_STMT_END
#define GST_TRACER_ELEMENT_QUERY_PRE(element, query) G_STMT_START{ \ #define GST_TRACER_ELEMENT_QUERY_PRE(element, query) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_QUERIES)) { \ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_ELEMENT_QUERY_PRE)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_QUERIES, \ gst_tracer_dispatch (GST_TRACER_HOOK_ID_ELEMENT_QUERY_PRE, \
GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_PRE, GST_TRACER_TS, \ GST_TRACER_TS, \
element, query); \ element, query); \
} \ } \
}G_STMT_END }G_STMT_END
#define GST_TRACER_ELEMENT_QUERY_POST(element, res) G_STMT_START{ \ #define GST_TRACER_ELEMENT_QUERY_POST(element, res) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_QUERIES)) { \ if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_ELEMENT_QUERY_POST)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_QUERIES, \ gst_tracer_dispatch (GST_TRACER_HOOK_ID_ELEMENT_QUERY_POST, \
GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_POST, GST_TRACER_TS, \ GST_TRACER_TS, \
element, res); \ element, res); \
} \ } \
}G_STMT_END }G_STMT_END

View file

@ -87,50 +87,6 @@ get_real_pad_parent (GstPad * pad)
return GST_ELEMENT_CAST (parent); return GST_ELEMENT_CAST (parent);
} }
/* tracer class */
static void gst_latency_tracer_invoke (GstTracer * obj, GstTracerMessageId mid,
va_list var_args);
static void
gst_latency_tracer_class_init (GstLatencyTracerClass * klass)
{
GstTracerClass *gst_tracer_class = GST_TRACER_CLASS (klass);
gst_tracer_class->invoke = gst_latency_tracer_invoke;
latency_probe_id = g_quark_from_static_string ("latency_probe.id");
latency_probe_pad = g_quark_from_static_string ("latency_probe.pad");
latency_probe_ts = g_quark_from_static_string ("latency_probe.ts");
/* announce trace formats */
/* *INDENT-OFF* */
gst_tracer_log_trace (gst_structure_new ("latency.class",
"src", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
"related-to", G_TYPE_STRING, "pad", /* TODO: use genum */
NULL),
"sink", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
"related-to", G_TYPE_STRING, "pad", /* TODO: use genum */
NULL),
"time", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_UINT64,
"description", G_TYPE_STRING,
"time it took for the buffer to go from src to sink ns",
"flags", G_TYPE_STRING, "aggregated", /* TODO: use gflags */
"min", G_TYPE_UINT64, G_GUINT64_CONSTANT (0),
"max", G_TYPE_UINT64, G_MAXUINT64,
NULL),
NULL));
/* *INDENT-ON* */
}
static void
gst_latency_tracer_init (GstLatencyTracer * self)
{
g_object_set (self, "mask", GST_TRACER_HOOK_BUFFERS | GST_TRACER_HOOK_EVENTS,
NULL);
}
/* hooks */ /* hooks */
static void static void
@ -172,24 +128,24 @@ send_latency_probe (GstLatencyTracer * self, GstElement * parent, GstPad * pad,
} }
static void static void
do_push_buffer_pre (GstLatencyTracer * self, va_list var_args) do_push_buffer_pre (GstTracer * self, va_list var_args)
{ {
guint64 ts = va_arg (var_args, guint64); guint64 ts = va_arg (var_args, guint64);
GstPad *pad = va_arg (var_args, GstPad *); GstPad *pad = va_arg (var_args, GstPad *);
GstElement *parent = get_real_pad_parent (pad); GstElement *parent = get_real_pad_parent (pad);
send_latency_probe (self, parent, pad, ts); send_latency_probe ((GstLatencyTracer *) self, parent, pad, ts);
} }
static void static void
do_pull_buffer_pre (GstLatencyTracer * self, va_list var_args) do_pull_range_pre (GstTracer * self, va_list var_args)
{ {
guint64 ts = va_arg (var_args, guint64); guint64 ts = va_arg (var_args, guint64);
GstPad *pad = va_arg (var_args, GstPad *); GstPad *pad = va_arg (var_args, GstPad *);
GstPad *peer_pad = GST_PAD_PEER (pad); GstPad *peer_pad = GST_PAD_PEER (pad);
GstElement *parent = get_real_pad_parent (peer_pad); GstElement *parent = get_real_pad_parent (peer_pad);
send_latency_probe (self, parent, peer_pad, ts); send_latency_probe ((GstLatencyTracer *) self, parent, peer_pad, ts);
} }
static void static void
@ -206,28 +162,28 @@ calculate_latency (GstLatencyTracer * self, GstElement * parent, GstPad * pad,
} }
static void static void
do_push_buffer_post (GstLatencyTracer * self, va_list var_args) do_push_buffer_post (GstTracer * self, va_list var_args)
{ {
guint64 ts = va_arg (var_args, guint64); guint64 ts = va_arg (var_args, guint64);
GstPad *pad = va_arg (var_args, GstPad *); GstPad *pad = va_arg (var_args, GstPad *);
GstPad *peer_pad = GST_PAD_PEER (pad); GstPad *peer_pad = GST_PAD_PEER (pad);
GstElement *parent = get_real_pad_parent (peer_pad); GstElement *parent = get_real_pad_parent (peer_pad);
calculate_latency (self, parent, peer_pad, ts); calculate_latency ((GstLatencyTracer *) self, parent, peer_pad, ts);
} }
static void static void
do_pull_range_post (GstLatencyTracer * self, va_list var_args) do_pull_range_post (GstTracer * self, va_list var_args)
{ {
guint64 ts = va_arg (var_args, guint64); guint64 ts = va_arg (var_args, guint64);
GstPad *pad = va_arg (var_args, GstPad *); GstPad *pad = va_arg (var_args, GstPad *);
GstElement *parent = get_real_pad_parent (pad); GstElement *parent = get_real_pad_parent (pad);
calculate_latency (self, parent, pad, ts); calculate_latency ((GstLatencyTracer *) self, parent, pad, ts);
} }
static void static void
do_push_event_pre (GstLatencyTracer * self, va_list var_args) do_push_event_pre (GstTracer * self, va_list var_args)
{ {
G_GNUC_UNUSED guint64 ts = va_arg (var_args, guint64); G_GNUC_UNUSED guint64 ts = va_arg (var_args, guint64);
GstPad *pad = va_arg (var_args, GstPad *); GstPad *pad = va_arg (var_args, GstPad *);
@ -250,31 +206,59 @@ do_push_event_pre (GstLatencyTracer * self, va_list var_args)
} }
} }
static void /* tracer class */
gst_latency_tracer_invoke (GstTracer * obj, GstTracerMessageId mid,
va_list var_args)
{
GstLatencyTracer *self = GST_LATENCY_TRACER_CAST (obj);
switch (mid) { static void
case GST_TRACER_MESSAGE_ID_PAD_PUSH_PRE: gst_latency_tracer_class_init (GstLatencyTracerClass * klass)
case GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_PRE: {
do_push_buffer_pre (self, var_args); latency_probe_id = g_quark_from_static_string ("latency_probe.id");
break; latency_probe_pad = g_quark_from_static_string ("latency_probe.pad");
case GST_TRACER_MESSAGE_ID_PAD_PUSH_POST: latency_probe_ts = g_quark_from_static_string ("latency_probe.ts");
case GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_POST:
do_push_buffer_post (self, var_args); /* announce trace formats */
break; /* *INDENT-OFF* */
case GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_PRE: gst_tracer_log_trace (gst_structure_new ("latency.class",
do_pull_buffer_pre (self, var_args); "src", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
break; "related-to", G_TYPE_STRING, "pad", /* TODO: use genum */
case GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_POST: NULL),
do_pull_range_post (self, var_args); "sink", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
break; "related-to", G_TYPE_STRING, "pad", /* TODO: use genum */
case GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_PRE: NULL),
do_push_event_pre (self, var_args); "time", GST_TYPE_STRUCTURE, gst_structure_new ("value",
break; "type", G_TYPE_GTYPE, G_TYPE_UINT64,
default: "description", G_TYPE_STRING,
break; "time it took for the buffer to go from src to sink ns",
} "flags", G_TYPE_STRING, "aggregated", /* TODO: use gflags */
"min", G_TYPE_UINT64, G_GUINT64_CONSTANT (0),
"max", G_TYPE_UINT64, G_MAXUINT64,
NULL),
NULL));
/* *INDENT-ON* */
}
static void
gst_latency_tracer_init (GstLatencyTracer * self)
{
GstTracer *tracer = GST_TRACER (self);
gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PUSH_PRE,
do_push_buffer_pre);
gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PUSH_LIST_PRE,
do_push_buffer_pre);
gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PUSH_POST,
do_push_buffer_post);
gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PUSH_LIST_POST,
do_push_buffer_post);
gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PULL_RANGE_PRE,
do_pull_range_pre);
gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PULL_RANGE_POST,
do_pull_range_post);
gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PUSH_EVENT_PRE,
do_push_event_pre);
/*
- we should also replace GstTracerHookId with a 'detail' string like in
signals
- then we can attach to *all* hooks with 'null' as detail
gst_tracer_register_hook (self, gchar *detail, func);
gst_tracer_register_hook_id (self, GQuark detail, func);
*/
} }

View file

@ -52,95 +52,138 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_QUERY);
G_DEFINE_TYPE_WITH_CODE (GstLogTracer, gst_log_tracer, GST_TYPE_TRACER, G_DEFINE_TYPE_WITH_CODE (GstLogTracer, gst_log_tracer, GST_TYPE_TRACER,
_do_init); _do_init);
static void gst_log_tracer_invoke (GstTracer * self, GstTracerMessageId mid, static void
va_list var_args); do_log (GstDebugCategory * cat, const char *format, va_list var_args)
{
gst_debug_log_valist (cat, GST_LEVEL_TRACE, "", "", 0, NULL,
format, var_args);
}
static void
do_push_buffer_pre (GstTracer * self, va_list var_args)
{
do_log (GST_CAT_BUFFER,
"%" GST_TIME_FORMAT ", pad=%" GST_PTR_FORMAT ", buffer=%" GST_PTR_FORMAT,
var_args);
}
static void
do_push_buffer_post (GstTracer * self, va_list var_args)
{
do_log (GST_CAT_BUFFER,
"%" GST_TIME_FORMAT ", pad=%" GST_PTR_FORMAT ", res=%d", var_args);
}
static void
do_push_buffer_list_pre (GstTracer * self, va_list var_args)
{
do_log (GST_CAT_BUFFER_LIST,
"%" GST_TIME_FORMAT ", pad=%" GST_PTR_FORMAT ", list=%p", var_args);
}
static void
do_push_buffer_list_post (GstTracer * self, va_list var_args)
{
do_log (GST_CAT_BUFFER_LIST,
"%" GST_TIME_FORMAT ", pad=%" GST_PTR_FORMAT ", res=%d", var_args);
}
static void
do_pull_range_pre (GstTracer * self, va_list var_args)
{
do_log (GST_CAT_BUFFER,
"%" GST_TIME_FORMAT ", pad=%" GST_PTR_FORMAT ", offset=%" G_GUINT64_FORMAT
", size=%u", var_args);
}
static void
do_pull_range_post (GstTracer * self, va_list var_args)
{
do_log (GST_CAT_BUFFER,
"%" GST_TIME_FORMAT ", pad=%" GST_PTR_FORMAT ", buffer=%" GST_PTR_FORMAT
", res=%d", var_args);
}
static void
do_push_event_pre (GstTracer * self, va_list var_args)
{
do_log (GST_CAT_EVENT,
"%" GST_TIME_FORMAT ", pad=%" GST_PTR_FORMAT ", event=%" GST_PTR_FORMAT,
var_args);
}
static void
do_push_event_post (GstTracer * self, va_list var_args)
{
do_log (GST_CAT_EVENT,
"%" GST_TIME_FORMAT ", pad=%" GST_PTR_FORMAT ", res=%d", var_args);
}
static void
do_post_message_pre (GstTracer * self, va_list var_args)
{
do_log (GST_CAT_EVENT,
"%" GST_TIME_FORMAT ", element=%" GST_PTR_FORMAT ", message=%"
GST_PTR_FORMAT, var_args);
}
static void
do_post_message_post (GstTracer * self, va_list var_args)
{
do_log (GST_CAT_EVENT,
"%" GST_TIME_FORMAT ", element=%" GST_PTR_FORMAT ", res=%d", var_args);
}
static void
do_query_pre (GstTracer * self, va_list var_args)
{
do_log (GST_CAT_QUERY,
"%" GST_TIME_FORMAT ", element=%" GST_PTR_FORMAT ", query=%"
GST_PTR_FORMAT, var_args);
}
static void
do_query_post (GstTracer * self, va_list var_args)
{
do_log (GST_CAT_QUERY,
"%" GST_TIME_FORMAT ", element=%" GST_PTR_FORMAT ", res=%d", var_args);
}
/* tracer class */
static void static void
gst_log_tracer_class_init (GstLogTracerClass * klass) 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 static void
gst_log_tracer_init (GstLogTracer * self) gst_log_tracer_init (GstLogTracer * self)
{ {
g_object_set (self, "mask", GST_TRACER_HOOK_ALL, NULL); GstTracer *tracer = GST_TRACER (self);
}
gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PUSH_PRE,
static void do_push_buffer_pre);
gst_log_tracer_invoke (GstTracer * self, GstTracerMessageId mid, gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PUSH_POST,
va_list var_args) do_push_buffer_post);
{ gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PUSH_LIST_PRE,
const gchar *fmt = NULL; do_push_buffer_list_pre);
GstDebugCategory *cat = GST_CAT_DEFAULT; gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PUSH_LIST_POST,
guint64 ts = va_arg (var_args, guint64); do_push_buffer_list_post);
gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PULL_RANGE_PRE,
/* TODO(ensonic): log to different categories depending on 'mid' do_pull_range_pre);
* GST_TRACER_HOOK_ID_QUERIES -> (static category) gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PULL_RANGE_POST,
* GST_TRACER_HOOK_ID_TOPLOGY -> ? do_pull_range_post);
*/ gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PUSH_EVENT_PRE,
switch (mid) { do_push_event_pre);
case GST_TRACER_MESSAGE_ID_PAD_PUSH_PRE: gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PUSH_EVENT_POST,
cat = GST_CAT_BUFFER; do_push_event_post);
fmt = "pad=%" GST_PTR_FORMAT ", buffer=%" GST_PTR_FORMAT; gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_ELEMENT_POST_MESSAGE_PRE,
break; do_post_message_pre);
case GST_TRACER_MESSAGE_ID_PAD_PUSH_POST: gst_tracer_register_hook (tracer,
cat = GST_CAT_BUFFER; GST_TRACER_HOOK_ID_ELEMENT_POST_MESSAGE_POST, do_post_message_post);
fmt = "pad=%" GST_PTR_FORMAT ", res=%d"; gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_ELEMENT_QUERY_PRE,
break; do_query_pre);
case GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_PRE: gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_ELEMENT_QUERY_POST,
cat = GST_CAT_BUFFER_LIST; do_query_post);
fmt = "pad=%" GST_PTR_FORMAT ", list=%p";
break;
case GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_POST:
cat = GST_CAT_BUFFER_LIST;
fmt = "pad=%" GST_PTR_FORMAT ", res=%d";
break;
case GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_PRE:
cat = GST_CAT_BUFFER;
fmt = "pad=%" GST_PTR_FORMAT ", offset=%" G_GUINT64_FORMAT ", size=%u";
break;
case GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_POST:
cat = GST_CAT_BUFFER;
fmt = "pad=%" GST_PTR_FORMAT ", buffer=%" GST_PTR_FORMAT ", res=%d";
break;
case GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_PRE:
cat = GST_CAT_EVENT;
fmt = "pad=%" GST_PTR_FORMAT ", event=%" GST_PTR_FORMAT;
break;
case GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_POST:
cat = GST_CAT_EVENT;
fmt = "pad=%" GST_PTR_FORMAT ", res=%d";
break;
case GST_TRACER_MESSAGE_ID_ELEMENT_POST_MESSAGE_PRE:
cat = GST_CAT_MESSAGE;
fmt = "element=%" GST_PTR_FORMAT ", message=%" GST_PTR_FORMAT;
break;
case GST_TRACER_MESSAGE_ID_ELEMENT_POST_MESSAGE_POST:
cat = GST_CAT_MESSAGE;
fmt = "element=%" GST_PTR_FORMAT ", res=%d";
break;
case GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_PRE:
cat = GST_CAT_QUERY;
fmt = "element=%" GST_PTR_FORMAT ", query=%" GST_PTR_FORMAT;
break;
case GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_POST:
cat = GST_CAT_QUERY;
fmt = "element=%" GST_PTR_FORMAT ", res=%d";
break;
default:
break;
}
if (fmt) {
gchar *str;
__gst_vasprintf (&str, fmt, var_args);
GST_CAT_TRACE (cat, "[%d] %" GST_TIME_FORMAT ", %s",
mid, GST_TIME_ARGS (ts), str);
g_free (str);
} else {
GST_CAT_TRACE (cat, "[%d] %" GST_TIME_FORMAT, mid, GST_TIME_ARGS (ts));
}
} }

View file

@ -78,9 +78,6 @@ typedef struct
static GstTraceValues *tvs_proc; static GstTraceValues *tvs_proc;
static void gst_rusage_tracer_invoke (GstTracer * self, GstTracerMessageId mid,
va_list var_args);
/* data helper */ /* data helper */
static void static void
@ -166,91 +163,7 @@ free_thread_stats (gpointer data)
} }
static void static void
gst_rusage_tracer_class_init (GstRUsageTracerClass * klass) do_stats (GstTracer * obj, va_list var_args)
{
GstTracerClass *gst_tracer_class = GST_TRACER_CLASS (klass);
gst_tracer_class->invoke = gst_rusage_tracer_invoke;
}
static void
gst_rusage_tracer_init (GstRUsageTracer * self)
{
g_object_set (self, "mask", GST_TRACER_HOOK_ALL, NULL);
self->threads = g_hash_table_new_full (NULL, NULL, NULL, free_thread_stats);
main_thread_id = g_thread_self ();
tvs_proc = make_trace_values (GST_SECOND);
if ((num_cpus = sysconf (_SC_NPROCESSORS_ONLN)) == -1) {
GST_WARNING_OBJECT (self, "failed to get number of cpus online");
if ((num_cpus = sysconf (_SC_NPROCESSORS_CONF)) == -1) {
GST_WARNING_OBJECT (self, "failed to get number of cpus, assuming 1");
num_cpus = 1;
}
}
GST_DEBUG ("rusage: main thread=%p, num_cpus=%ld", main_thread_id, num_cpus);
/* announce trace formats */
/* *INDENT-OFF* */
gst_tracer_log_trace (gst_structure_new ("thread-rusage.class",
"thread-id", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
"related-to", G_TYPE_STRING, "thread", /* TODO: use genum */
NULL),
"average-cpuload", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_UINT,
"description", G_TYPE_STRING, "average cpu usage per thread in ‰",
"flags", G_TYPE_STRING, "aggregated", /* TODO: use gflags */
"min", G_TYPE_UINT, 0,
"max", G_TYPE_UINT, 1000,
NULL),
"current-cpuload", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_UINT,
"description", G_TYPE_STRING, "current cpu usage per thread in ‰",
"flags", G_TYPE_STRING, "windowed", /* TODO: use gflags */
"min", G_TYPE_UINT, 0,
"max", G_TYPE_UINT, 1000,
NULL),
"time", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_UINT64,
"description", G_TYPE_STRING, "time spent in thread in ns",
"flags", G_TYPE_STRING, "aggregated", /* TODO: use gflags */
"min", G_TYPE_UINT64, G_GUINT64_CONSTANT (0),
"max", G_TYPE_UINT64, G_MAXUINT64,
NULL),
NULL));
gst_tracer_log_trace (gst_structure_new ("proc-rusage.class",
"thread-id", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
"related-to", G_TYPE_STRING, "process", /* TODO: use genum */
NULL),
"average-cpuload", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_UINT,
"description", G_TYPE_STRING, "average cpu usage per process in ‰",
"flags", G_TYPE_STRING, "aggregated", /* TODO: use gflags */
"min", G_TYPE_UINT, 0,
"max", G_TYPE_UINT, 1000,
NULL),
"current-cpuload", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_UINT,
"description", G_TYPE_STRING, "current cpu usage per process in ‰",
"flags", G_TYPE_STRING, "windowed", /* TODO: use gflags */
"min", G_TYPE_UINT, 0,
"max", G_TYPE_UINT, 1000,
NULL),
"time", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_UINT64,
"description", G_TYPE_STRING, "time spent in process in ns",
"flags", G_TYPE_STRING, "aggregated", /* TODO: use gflags */
"min", G_TYPE_UINT64, G_GUINT64_CONSTANT (0),
"max", G_TYPE_UINT64, G_MAXUINT64,
NULL),
NULL));
/* *INDENT-ON* */
}
static void
gst_rusage_tracer_invoke (GstTracer * obj, GstTracerMessageId mid,
va_list var_args)
{ {
GstRUsageTracer *self = GST_RUSAGE_TRACER_CAST (obj); GstRUsageTracer *self = GST_RUSAGE_TRACER_CAST (obj);
guint64 ts = va_arg (var_args, guint64); guint64 ts = va_arg (var_args, guint64);
@ -360,3 +273,89 @@ gst_rusage_tracer_invoke (GstTracer * obj, GstTracerMessageId mid,
NULL)); NULL));
/* *INDENT-ON* */ /* *INDENT-ON* */
} }
/* tracer class */
static void
gst_rusage_tracer_class_init (GstRUsageTracerClass * klass)
{
/* announce trace formats */
/* *INDENT-OFF* */
gst_tracer_log_trace (gst_structure_new ("thread-rusage.class",
"thread-id", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
"related-to", G_TYPE_STRING, "thread", /* TODO: use genum */
NULL),
"average-cpuload", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_UINT,
"description", G_TYPE_STRING, "average cpu usage per thread in ‰",
"flags", G_TYPE_STRING, "aggregated", /* TODO: use gflags */
"min", G_TYPE_UINT, 0,
"max", G_TYPE_UINT, 1000,
NULL),
"current-cpuload", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_UINT,
"description", G_TYPE_STRING, "current cpu usage per thread in ‰",
"flags", G_TYPE_STRING, "windowed", /* TODO: use gflags */
"min", G_TYPE_UINT, 0,
"max", G_TYPE_UINT, 1000,
NULL),
"time", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_UINT64,
"description", G_TYPE_STRING, "time spent in thread in ns",
"flags", G_TYPE_STRING, "aggregated", /* TODO: use gflags */
"min", G_TYPE_UINT64, G_GUINT64_CONSTANT (0),
"max", G_TYPE_UINT64, G_MAXUINT64,
NULL),
NULL));
gst_tracer_log_trace (gst_structure_new ("proc-rusage.class",
"thread-id", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
"related-to", G_TYPE_STRING, "process", /* TODO: use genum */
NULL),
"average-cpuload", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_UINT,
"description", G_TYPE_STRING, "average cpu usage per process in ‰",
"flags", G_TYPE_STRING, "aggregated", /* TODO: use gflags */
"min", G_TYPE_UINT, 0,
"max", G_TYPE_UINT, 1000,
NULL),
"current-cpuload", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_UINT,
"description", G_TYPE_STRING, "current cpu usage per process in ‰",
"flags", G_TYPE_STRING, "windowed", /* TODO: use gflags */
"min", G_TYPE_UINT, 0,
"max", G_TYPE_UINT, 1000,
NULL),
"time", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_UINT64,
"description", G_TYPE_STRING, "time spent in process in ns",
"flags", G_TYPE_STRING, "aggregated", /* TODO: use gflags */
"min", G_TYPE_UINT64, G_GUINT64_CONSTANT (0),
"max", G_TYPE_UINT64, G_MAXUINT64,
NULL),
NULL));
/* *INDENT-ON* */
}
static void
gst_rusage_tracer_init (GstRUsageTracer * self)
{
GstTracer *tracer = GST_TRACER (self);
gint i;
for (i = 0; i < GST_TRACER_HOOK_ID_LAST; i++) {
gst_tracer_register_hook (tracer, i, do_stats);
}
self->threads = g_hash_table_new_full (NULL, NULL, NULL, free_thread_stats);
main_thread_id = g_thread_self ();
tvs_proc = make_trace_values (GST_SECOND);
if ((num_cpus = sysconf (_SC_NPROCESSORS_ONLN)) == -1) {
GST_WARNING_OBJECT (self, "failed to get number of cpus online");
if ((num_cpus = sysconf (_SC_NPROCESSORS_CONF)) == -1) {
GST_WARNING_OBJECT (self, "failed to get number of cpus, assuming 1");
num_cpus = 1;
}
}
GST_DEBUG ("rusage: main thread=%p, num_cpus=%ld", main_thread_id, num_cpus);
}

View file

@ -336,106 +336,6 @@ do_element_stats (GstStatsTracer * self, GstPad * pad, GstClockTime elapsed1,
#endif #endif
} }
/* tracer class */
static void gst_stats_tracer_finalize (GObject * obj);
static void gst_stats_tracer_invoke (GstTracer * obj, GstTracerMessageId mid,
va_list var_args);
static void
gst_stats_tracer_class_init (GstStatsTracerClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstTracerClass *gst_tracer_class = GST_TRACER_CLASS (klass);
gobject_class->finalize = gst_stats_tracer_finalize;
gst_tracer_class->invoke = gst_stats_tracer_invoke;
}
static void
gst_stats_tracer_init (GstStatsTracer * self)
{
g_object_set (self, "mask",
GST_TRACER_HOOK_BUFFERS | GST_TRACER_HOOK_EVENTS |
GST_TRACER_HOOK_MESSAGES | GST_TRACER_HOOK_QUERIES, NULL);
self->elements = g_ptr_array_new_with_free_func (free_element_stats);
self->pads = g_ptr_array_new_with_free_func (free_pad_stats);
/* announce trace formats */
/* *INDENT-OFF* */
gst_tracer_log_trace (gst_structure_new ("buffer.class",
"pad-ix", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
"related-to", G_TYPE_STRING, "pad", /* TODO: use genum */
NULL),
"element-ix", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
"related-to", G_TYPE_STRING, "element", /* TODO: use genum */
NULL),
"peer-pad-ix", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
"related-to", G_TYPE_STRING, "pad", /* TODO: use genum */
NULL),
"peer-element-ix", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
"related-to", G_TYPE_STRING, "element", /* TODO: use genum */
NULL),
"buffer-size", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_UINT,
"description", G_TYPE_STRING, "size of buffer in bytes",
"flags", G_TYPE_STRING, "", /* TODO: use gflags */
"min", G_TYPE_UINT, 0,
"max", G_TYPE_UINT, G_MAXUINT,
NULL),
"buffer-ts", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_UINT64,
"description", G_TYPE_STRING, "timestamp of the buffer in ns",
"flags", G_TYPE_STRING, "", /* TODO: use gflags */
"min", G_TYPE_UINT64, G_GUINT64_CONSTANT (0),
"max", G_TYPE_UINT64, G_MAXUINT64,
NULL),
"buffer-duration", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_UINT64,
"description", G_TYPE_STRING, "duration of the buffer in ns",
"flags", G_TYPE_STRING, "", /* TODO: use gflags */
"min", G_TYPE_UINT64, G_GUINT64_CONSTANT (0),
"max", G_TYPE_UINT64, G_MAXUINT64,
NULL),
/* TODO(ensonic): "buffer-flags" */
NULL));
gst_tracer_log_trace (gst_structure_new ("event.class",
"pad-ix", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
"related-to", G_TYPE_STRING, "pad", /* TODO: use genum */
NULL),
"element-ix", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
"related-to", G_TYPE_STRING, "element", /* TODO: use genum */
NULL),
"name", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_STRING,
"description", G_TYPE_STRING, "name of the event",
"flags", G_TYPE_STRING, "", /* TODO: use gflags */
NULL),
NULL));
gst_tracer_log_trace (gst_structure_new ("message.class",
"element-ix", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
"related-to", G_TYPE_STRING, "element", /* TODO: use genum */
NULL),
"name", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_STRING,
"description", G_TYPE_STRING, "name of the message",
"flags", G_TYPE_STRING, "", /* TODO: use gflags */
NULL),
NULL));
gst_tracer_log_trace (gst_structure_new ("query.class",
"element-ix", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
"related-to", G_TYPE_STRING, "element", /* TODO: use genum */
NULL),
"name", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_STRING,
"description", G_TYPE_STRING, "name of the query",
"flags", G_TYPE_STRING, "", /* TODO: use gflags */
NULL),
NULL));
/* *INDENT-ON* */
}
/* hooks */ /* hooks */
static void static void
@ -610,56 +510,117 @@ do_query_post (GstStatsTracer * self, va_list var_args)
#endif #endif
} }
static void /* tracer class */
gst_stats_tracer_invoke (GstTracer * obj, GstTracerMessageId mid,
va_list var_args)
{
GstStatsTracer *self = GST_STATS_TRACER_CAST (obj);
switch (mid) { static void
case GST_TRACER_MESSAGE_ID_PAD_PUSH_PRE: gst_stats_tracer_class_init (GstStatsTracerClass * klass)
do_push_buffer_pre (self, var_args); {
break; /* announce trace formats */
case GST_TRACER_MESSAGE_ID_PAD_PUSH_POST: /* *INDENT-OFF* */
do_push_buffer_post (self, var_args); gst_tracer_log_trace (gst_structure_new ("buffer.class",
break; "pad-ix", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
case GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_PRE: "related-to", G_TYPE_STRING, "pad", /* TODO: use genum */
do_push_buffer_list_pre (self, var_args); NULL),
break; "element-ix", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
case GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_POST: "related-to", G_TYPE_STRING, "element", /* TODO: use genum */
do_push_buffer_list_post (self, var_args); NULL),
break; "peer-pad-ix", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
case GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_PRE: "related-to", G_TYPE_STRING, "pad", /* TODO: use genum */
do_pull_range_pre (self, var_args); NULL),
break; "peer-element-ix", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
case GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_POST: "related-to", G_TYPE_STRING, "element", /* TODO: use genum */
do_pull_range_post (self, var_args); NULL),
break; "buffer-size", GST_TYPE_STRUCTURE, gst_structure_new ("value",
case GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_PRE: "type", G_TYPE_GTYPE, G_TYPE_UINT,
do_push_event_pre (self, var_args); "description", G_TYPE_STRING, "size of buffer in bytes",
break; "flags", G_TYPE_STRING, "", /* TODO: use gflags */
case GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_POST: "min", G_TYPE_UINT, 0,
do_push_event_post (self, var_args); "max", G_TYPE_UINT, G_MAXUINT,
break; NULL),
case GST_TRACER_MESSAGE_ID_ELEMENT_POST_MESSAGE_PRE: "buffer-ts", GST_TYPE_STRUCTURE, gst_structure_new ("value",
do_post_message_pre (self, var_args); "type", G_TYPE_GTYPE, G_TYPE_UINT64,
break; "description", G_TYPE_STRING, "timestamp of the buffer in ns",
case GST_TRACER_MESSAGE_ID_ELEMENT_POST_MESSAGE_POST: "flags", G_TYPE_STRING, "", /* TODO: use gflags */
do_post_message_post (self, var_args); "min", G_TYPE_UINT64, G_GUINT64_CONSTANT (0),
break; "max", G_TYPE_UINT64, G_MAXUINT64,
case GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_PRE: NULL),
do_query_pre (self, var_args); "buffer-duration", GST_TYPE_STRUCTURE, gst_structure_new ("value",
break; "type", G_TYPE_GTYPE, G_TYPE_UINT64,
case GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_POST: "description", G_TYPE_STRING, "duration of the buffer in ns",
do_query_post (self, var_args); "flags", G_TYPE_STRING, "", /* TODO: use gflags */
break; "min", G_TYPE_UINT64, G_GUINT64_CONSTANT (0),
default: "max", G_TYPE_UINT64, G_MAXUINT64,
break; NULL),
} /* TODO(ensonic): "buffer-flags" */
NULL));
gst_tracer_log_trace (gst_structure_new ("event.class",
"pad-ix", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
"related-to", G_TYPE_STRING, "pad", /* TODO: use genum */
NULL),
"element-ix", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
"related-to", G_TYPE_STRING, "element", /* TODO: use genum */
NULL),
"name", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_STRING,
"description", G_TYPE_STRING, "name of the event",
"flags", G_TYPE_STRING, "", /* TODO: use gflags */
NULL),
NULL));
gst_tracer_log_trace (gst_structure_new ("message.class",
"element-ix", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
"related-to", G_TYPE_STRING, "element", /* TODO: use genum */
NULL),
"name", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_STRING,
"description", G_TYPE_STRING, "name of the message",
"flags", G_TYPE_STRING, "", /* TODO: use gflags */
NULL),
NULL));
gst_tracer_log_trace (gst_structure_new ("query.class",
"element-ix", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
"related-to", G_TYPE_STRING, "element", /* TODO: use genum */
NULL),
"name", GST_TYPE_STRUCTURE, gst_structure_new ("value",
"type", G_TYPE_GTYPE, G_TYPE_STRING,
"description", G_TYPE_STRING, "name of the query",
"flags", G_TYPE_STRING, "", /* TODO: use gflags */
NULL),
NULL));
/* *INDENT-ON* */
} }
static void static void
gst_stats_tracer_finalize (GObject * obj) gst_stats_tracer_init (GstStatsTracer * self)
{ {
G_OBJECT_CLASS (parent_class)->finalize (obj); GstTracer *tracer = GST_TRACER (self);
gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PUSH_PRE,
(GstTracerHookFunction) do_push_buffer_pre);
gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PUSH_POST,
(GstTracerHookFunction) do_push_buffer_post);
gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PUSH_LIST_PRE,
(GstTracerHookFunction) do_push_buffer_list_pre);
gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PUSH_LIST_POST,
(GstTracerHookFunction) do_push_buffer_list_post);
gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PULL_RANGE_PRE,
(GstTracerHookFunction) do_pull_range_pre);
gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PULL_RANGE_POST,
(GstTracerHookFunction) do_pull_range_post);
gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PUSH_EVENT_PRE,
(GstTracerHookFunction) do_push_event_pre);
gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_PAD_PUSH_EVENT_POST,
(GstTracerHookFunction) do_push_event_post);
gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_ELEMENT_POST_MESSAGE_PRE,
(GstTracerHookFunction) do_post_message_pre);
gst_tracer_register_hook (tracer,
GST_TRACER_HOOK_ID_ELEMENT_POST_MESSAGE_POST,
(GstTracerHookFunction) do_post_message_post);
gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_ELEMENT_QUERY_PRE,
(GstTracerHookFunction) do_query_pre);
gst_tracer_register_hook (tracer, GST_TRACER_HOOK_ID_ELEMENT_QUERY_POST,
(GstTracerHookFunction) do_query_post);
self->elements = g_ptr_array_new_with_free_func (free_element_stats);
self->pads = g_ptr_array_new_with_free_func (free_pad_stats);
} }