Commit 1a3e218b authored by Stefan Sauer's avatar Stefan Sauer

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.
parent 7b24d762
......@@ -45,7 +45,6 @@ enum
{
PROP_0,
PROP_PARAMS,
PROP_MASK,
PROP_LAST
};
......@@ -59,7 +58,6 @@ static void gst_tracer_get_property (GObject * object, guint prop_id,
struct _GstTracerPrivate
{
const gchar *params;
GstTracerHook mask;
};
#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",
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));
}
......@@ -102,9 +96,6 @@ gst_tracer_set_property (GObject * object, guint 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;
......@@ -121,25 +112,12 @@ gst_tracer_get_property (GObject * object, guint 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;
}
}
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 */
gboolean
......
......@@ -53,24 +53,20 @@ struct _GstTracer {
gpointer _gst_reserved[GST_PADDING];
};
typedef void (*GstTracerInvokeFunction) (GstTracer * self,
GstTracerMessageId mid, va_list var_args);
typedef void (*GstTracerHookFunction) (GstTracer * self, va_list var_args);
struct _GstTracerClass {
GstObjectClass parent_class;
/* plugin vmethods */
GstTracerInvokeFunction invoke;
/*< private >*/
gpointer _gst_reserved[GST_PADDING];
};
void gst_tracer_invoke (GstTracer * self, GstTracerMessageId mid,
va_list var_args);
GType gst_tracer_get_type (void);
void gst_tracer_register_hook (GstTracer *tracer, GstTracerHookId id,
GstTracerHookFunction func);
G_END_DECLS
#endif /* __GST_TRACER_H__ */
......
......@@ -45,6 +45,12 @@ gboolean _priv_tracer_enabled = FALSE;
/* TODO(ensonic): use array of GPtrArray* ? */
GList *_priv_tracers[GST_TRACER_HOOK_ID_LAST] = { NULL, };
typedef struct
{
GstTracer *tracer;
GstTracerHookFunction func;
} GstTracerHook;
/* Initialize the tracing system */
void
_priv_gst_tracer_init (void)
......@@ -55,10 +61,8 @@ _priv_gst_tracer_init (void)
GstRegistry *registry = gst_registry_get ();
GstPluginFeature *feature;
GstTracerFactory *factory;
GstTracerHook mask;
GstObject *tracer;
gchar **t = g_strsplit_set (env, ";", 0);
gint i = 0, j;
gint i = 0;
gchar *params;
GST_INFO ("enabling tracers: '%s'", env);
......@@ -83,28 +87,9 @@ _priv_gst_tracer_init (void)
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) {
_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);
/* tracers register them self to the hooks */
gst_object_unref (g_object_new (factory->type, "params", params,
NULL));
} else {
GST_WARNING_OBJECT (feature,
"loading plugin containing feature %s failed!", t[i]);
......@@ -123,11 +108,14 @@ _priv_gst_tracer_deinit (void)
{
gint i;
GList *node;
GstTracerHook *hook;
/* shutdown tracers for final reports */
for (i = 0; i < GST_TRACER_HOOK_ID_LAST; i++) {
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]);
_priv_tracers[i] = NULL;
......@@ -136,14 +124,28 @@ _priv_gst_tracer_deinit (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;
GList *node;
GstTracerHook *hook;
for (node = _priv_tracers[hid]; node; node = g_list_next (node)) {
va_start (var_args, mid);
gst_tracer_invoke (node->data, mid, var_args);
for (node = _priv_tracers[id]; node; node = g_list_next (node)) {
hook = (GstTracerHook *) node->data;
va_start (var_args, id);
hook->func (hook->tracer, var_args);
va_end (var_args);
}
}
......
......@@ -32,52 +32,25 @@ G_BEGIN_DECLS
#ifndef GST_DISABLE_GST_DEBUG
/* hook flags and ids */
/* tracer hook message 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_PAD_PUSH_PRE = 0,
GST_TRACER_HOOK_ID_PAD_PUSH_POST,
GST_TRACER_HOOK_ID_PAD_PUSH_LIST_PRE,
GST_TRACER_HOOK_ID_PAD_PUSH_LIST_POST,
GST_TRACER_HOOK_ID_PAD_PULL_RANGE_PRE,
GST_TRACER_HOOK_ID_PAD_PULL_RANGE_POST,
GST_TRACER_HOOK_ID_PAD_PUSH_EVENT_PRE,
GST_TRACER_HOOK_ID_PAD_PUSH_EVENT_POST,
GST_TRACER_HOOK_ID_ELEMENT_POST_MESSAGE_PRE,
GST_TRACER_HOOK_ID_ELEMENT_POST_MESSAGE_POST,
GST_TRACER_HOOK_ID_ELEMENT_QUERY_PRE,
GST_TRACER_HOOK_ID_ELEMENT_QUERY_POST,
GST_TRACER_HOOK_ID_LAST
} 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 */
void _priv_gst_tracer_init (void);
......@@ -89,7 +62,7 @@ gboolean gst_tracer_register (GstPlugin * plugin, const gchar * name, GType type
/* tracing helpers */
void gst_tracer_dispatch (GstTracerHookId hid, GstTracerMessageId mid, ...);
void gst_tracer_dispatch (GstTracerHookId id, ...);
/* tracing module helpers */
......@@ -107,97 +80,97 @@ extern GList *_priv_tracers[GST_TRACER_HOOK_ID_LAST];
/* tracing hooks */
#define GST_TRACER_PAD_PUSH_PRE(pad, buffer) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \
GST_TRACER_MESSAGE_ID_PAD_PUSH_PRE, GST_TRACER_TS, \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_PAD_PUSH_PRE)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_PAD_PUSH_PRE, \
GST_TRACER_TS, \
pad, buffer); \
} \
}G_STMT_END
#define GST_TRACER_PAD_PUSH_POST(pad, res) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \
GST_TRACER_MESSAGE_ID_PAD_PUSH_POST, GST_TRACER_TS, \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_PAD_PUSH_POST)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_PAD_PUSH_POST, \
GST_TRACER_TS, \
pad, res); \
} \
}G_STMT_END
#define GST_TRACER_PAD_PUSH_LIST_PRE(pad, list) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \
GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_PRE, GST_TRACER_TS, \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_PAD_PUSH_LIST_PRE)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_PAD_PUSH_LIST_PRE, \
GST_TRACER_TS, \
pad, list); \
} \
}G_STMT_END
#define GST_TRACER_PAD_PUSH_LIST_POST(pad, res) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \
GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_POST, GST_TRACER_TS, \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_PAD_PUSH_LIST_POST)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_PAD_PUSH_LIST_POST, \
GST_TRACER_TS, \
pad, res); \
} \
}G_STMT_END
#define GST_TRACER_PAD_PULL_RANGE_PRE(pad, offset, size) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \
GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_PRE, GST_TRACER_TS, \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_PAD_PULL_RANGE_PRE)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_PAD_PULL_RANGE_PRE, \
GST_TRACER_TS, \
pad, offset, size); \
} \
}G_STMT_END
#define GST_TRACER_PAD_PULL_RANGE_POST(pad, buffer, res) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_BUFFERS)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_BUFFERS, \
GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_POST, GST_TRACER_TS, \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_PAD_PULL_RANGE_POST)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_PAD_PULL_RANGE_POST, \
GST_TRACER_TS, \
pad, buffer, res); \
} \
}G_STMT_END
#define GST_TRACER_PAD_PUSH_EVENT_PRE(pad, event) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_EVENTS)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_EVENTS, \
GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_PRE, GST_TRACER_TS, \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_PAD_PUSH_EVENT_PRE)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_PAD_PUSH_EVENT_PRE, \
GST_TRACER_TS, \
pad, event); \
} \
}G_STMT_END
#define GST_TRACER_PAD_PUSH_EVENT_POST(pad, res) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_EVENTS)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_EVENTS, \
GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_POST, GST_TRACER_TS, \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_PAD_PUSH_EVENT_POST)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_PAD_PUSH_EVENT_POST, \
GST_TRACER_TS, \
pad, res); \
} \
}G_STMT_END
#define GST_TRACER_ELEMENT_POST_MESSAGE_PRE(element, message) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_MESSAGES)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_MESSAGES, \
GST_TRACER_MESSAGE_ID_ELEMENT_POST_MESSAGE_PRE, GST_TRACER_TS, \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_ELEMENT_POST_MESSAGE_PRE)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_ELEMENT_POST_MESSAGE_PRE, \
GST_TRACER_TS, \
element, message); \
} \
}G_STMT_END
#define GST_TRACER_ELEMENT_POST_MESSAGE_POST(element, res) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_MESSAGES)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_MESSAGES, \
GST_TRACER_MESSAGE_ID_ELEMENT_POST_MESSAGE_POST, GST_TRACER_TS, \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_ELEMENT_POST_MESSAGE_POST)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_ELEMENT_POST_MESSAGE_POST, \
GST_TRACER_TS, \
element, res); \
} \
}G_STMT_END
#define GST_TRACER_ELEMENT_QUERY_PRE(element, query) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_QUERIES)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_QUERIES, \
GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_PRE, GST_TRACER_TS, \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_ELEMENT_QUERY_PRE)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_ELEMENT_QUERY_PRE, \
GST_TRACER_TS, \
element, query); \
} \
}G_STMT_END
#define GST_TRACER_ELEMENT_QUERY_POST(element, res) G_STMT_START{ \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_QUERIES)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_QUERIES, \
GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_POST, GST_TRACER_TS, \
if (GST_TRACER_IS_ENABLED(GST_TRACER_HOOK_ID_ELEMENT_QUERY_POST)) { \
gst_tracer_dispatch (GST_TRACER_HOOK_ID_ELEMENT_QUERY_POST, \
GST_TRACER_TS, \
element, res); \
} \
}G_STMT_END
......
......@@ -87,50 +87,6 @@ get_real_pad_parent (GstPad * pad)
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 */
static void
......@@ -172,24 +128,24 @@ send_latency_probe (GstLatencyTracer * self, GstElement * parent, GstPad * pad,
}
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);
GstPad *pad = va_arg (var_args, GstPad *);
GstElement *parent = get_real_pad_parent (pad);
send_latency_probe (self, parent, pad, ts);
send_latency_probe ((GstLatencyTracer *) self, parent, pad, ts);
}
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);
GstPad *pad = va_arg (var_args, GstPad *);
GstPad *peer_pad = GST_PAD_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
......@@ -206,28 +162,28 @@ calculate_latency (GstLatencyTracer * self, GstElement * parent, GstPad * pad,
}
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);
GstPad *pad = va_arg (var_args, GstPad *);
GstPad *peer_pad = GST_PAD_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
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);
GstPad *pad = va_arg (var_args, GstPad *);
GstElement *parent = get_real_pad_parent (pad);
calculate_latency (self, parent, pad, ts);
calculate_latency ((GstLatencyTracer *) self, parent, pad, ts);
}
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);
GstPad *pad = va_arg (var_args, GstPad *);
......@@ -250,31 +206,59 @@ do_push_event_pre (GstLatencyTracer * self, va_list var_args)
}
}
/* tracer class */
static void
gst_latency_tracer_invoke (GstTracer * obj, GstTracerMessageId mid,
va_list var_args)
gst_latency_tracer_class_init (GstLatencyTracerClass * klass)
{
GstLatencyTracer *self = GST_LATENCY_TRACER_CAST (obj);
switch (mid) {
case GST_TRACER_MESSAGE_ID_PAD_PUSH_PRE:
case GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_PRE:
do_push_buffer_pre (self, var_args);
break;
case GST_TRACER_MESSAGE_ID_PAD_PUSH_POST:
case GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_POST:
do_push_buffer_post (self, var_args);
break;
case GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_PRE:
do_pull_buffer_pre (self, var_args);
break;
case GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_POST:
do_pull_range_post (self, var_args);
break;
case GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_PRE:
do_push_event_pre (self, var_args);
break;
default:
break;
}
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)
{
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);
*/
}
......@@ -52,95 +52,138 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_QUERY);
G_DEFINE_TYPE_WITH_CODE (GstLogTracer, gst_log_tracer, GST_TYPE_TRACER,
_do_init);
static void gst_log_tracer_invoke (GstTracer * self, GstTracerMessageId mid,
va_list var_args);
static void
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
gst_log_tracer_class_init (GstLogTracerClass * klass)
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)
{
GstTracerClass *gst_tracer_class = GST_TRACER_CLASS (klass);
do_log (GST_CAT_BUFFER,
"%" GST_TIME_FORMAT ", pad=%" GST_PTR_FORMAT ", res=%d", var_args);
}
gst_tracer_class->invoke = gst_log_tracer_invoke;
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
gst_log_tracer_init (GstLogTracer * self)
do_push_buffer_list_post (GstTracer * self, va_list var_args)
{
g_object_set (self, "mask", GST_TRACER_HOOK_ALL, NULL);
do_log (GST_CAT_BUFFER_LIST,
"%" GST_TIME_FORMAT ", pad=%" GST_PTR_FORMAT ", res=%d", var_args);
}
static void
gst_log_tracer_invoke (GstTracer * self, GstTracerMessageId mid,
va_list var_args)
do_pull_range_pre (GstTracer * self, va_list var_args)
{
const gchar *fmt = NULL;
GstDebugCategory *cat = GST_CAT_DEFAULT;
guint64 ts = va_arg (var_args, guint64);
/* TODO(ensonic): log to different categories depending on 'mid'
* GST_TRACER_HOOK_ID_QUERIES -> (static category)
* GST_TRACER_HOOK_ID_TOPLOGY -> ?
*/
switch (mid) {
case GST_TRACER_MESSAGE_ID_PAD_PUSH_PRE:
cat = GST_CAT_BUFFER;
fmt = "pad=%" GST_PTR_FORMAT ", buffer=%" GST_PTR_FORMAT;
break;
case GST_TRACER_MESSAGE_ID_PAD_PUSH_POST:
cat = GST_CAT_BUFFER;
fmt = "pad=%" GST_PTR_FORMAT ", res=%d";
break;
case GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_PRE:
cat = GST_CAT_BUFFER_LIST;
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));
}
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)
{