tracer: add more hooks and handle it in the plugins

This commit is contained in:
Stefan Sauer 2014-07-16 09:22:14 +02:00
parent 37721fdc9d
commit ce7ce2d866
6 changed files with 308 additions and 20 deletions

View file

@ -90,6 +90,7 @@
#include "gstutils.h"
#include "gstinfo.h"
#include "gstquark.h"
#include "gsttracer.h"
#include "gstvalue.h"
#include "gst-i18n-lib.h"
#include "glib-compat-private.h"
@ -1656,18 +1657,22 @@ gboolean
gst_element_query (GstElement * element, GstQuery * query)
{
GstElementClass *klass;
gboolean res = FALSE;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
g_return_val_if_fail (query != NULL, FALSE);
GST_TRACER_ELEMENT_QUERY_PRE (element, query);
klass = GST_ELEMENT_GET_CLASS (element);
if (klass->query) {
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "send query on element %s",
GST_ELEMENT_NAME (element));
return klass->query (element, query);
res = klass->query (element, query);
}
return FALSE;
GST_TRACER_ELEMENT_QUERY_POST (element, res);
return res;
}
static gboolean
@ -1724,15 +1729,19 @@ gboolean
gst_element_post_message (GstElement * element, GstMessage * message)
{
GstElementClass *klass;
gboolean res = FALSE;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
g_return_val_if_fail (message != NULL, FALSE);
GST_TRACER_ELEMENT_POST_MESSAGE_PRE (element, message);
klass = GST_ELEMENT_GET_CLASS (element);
if (klass->post_message)
return klass->post_message (element, message);
res = klass->post_message (element, message);
return FALSE;
GST_TRACER_ELEMENT_POST_MESSAGE_POST (element, res);
return res;
}
/**

View file

@ -4760,6 +4760,8 @@ gst_pad_pull_range (GstPad * pad, guint64 offset, guint size,
g_return_val_if_fail (*buffer == NULL || (GST_IS_BUFFER (*buffer)
&& gst_buffer_get_size (*buffer) >= size), GST_FLOW_ERROR);
GST_TRACER_PAD_PULL_RANGE_PRE (pad, offset, size);
GST_OBJECT_LOCK (pad);
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushing;
@ -4806,6 +4808,7 @@ probed_data:
*buffer = res_buf;
GST_TRACER_PAD_PULL_RANGE_POST (pad, *buffer, ret);
return ret;
/* ERROR recovery here */
@ -4815,7 +4818,8 @@ flushing:
"pullrange, but pad was flushing");
pad->ABI.abi.last_flowret = GST_FLOW_FLUSHING;
GST_OBJECT_UNLOCK (pad);
return GST_FLOW_FLUSHING;
ret = GST_FLOW_FLUSHING;
goto done;
}
wrong_mode:
{
@ -4823,7 +4827,8 @@ wrong_mode:
GST_DEBUG_PAD_NAME (pad));
pad->ABI.abi.last_flowret = GST_FLOW_ERROR;
GST_OBJECT_UNLOCK (pad);
return GST_FLOW_ERROR;
ret = GST_FLOW_ERROR;
goto done;
}
probe_stopped:
{
@ -4844,7 +4849,7 @@ probe_stopped:
}
pad->ABI.abi.last_flowret = ret;
GST_OBJECT_UNLOCK (pad);
return ret;
goto done;
}
not_linked:
{
@ -4852,7 +4857,8 @@ not_linked:
"pulling range, but it was not linked");
pad->ABI.abi.last_flowret = GST_FLOW_NOT_LINKED;
GST_OBJECT_UNLOCK (pad);
return GST_FLOW_NOT_LINKED;
ret = GST_FLOW_NOT_LINKED;
goto done;
}
pull_range_failed:
{
@ -4861,7 +4867,7 @@ pull_range_failed:
GST_CAT_LEVEL_LOG (GST_CAT_SCHEDULING,
(ret >= GST_FLOW_EOS) ? GST_LEVEL_INFO : GST_LEVEL_WARNING,
pad, "pullrange failed, flow: %s", gst_flow_get_name (ret));
return ret;
goto done;
}
probe_stopped_unref:
{
@ -4877,8 +4883,11 @@ probe_stopped_unref:
if (*buffer == NULL)
gst_buffer_unref (res_buf);
return ret;
goto done;
}
done:
GST_TRACER_PAD_PULL_RANGE_POST (pad, NULL, ret);
return ret;
}
/* must be called with pad object lock */
@ -5227,6 +5236,8 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
GST_TRACER_PAD_PUSH_EVENT_PRE (pad, event);
if (GST_PAD_IS_SRC (pad)) {
if (G_UNLIKELY (!GST_EVENT_IS_DOWNSTREAM (event)))
goto wrong_direction;
@ -5281,6 +5292,7 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
}
GST_OBJECT_UNLOCK (pad);
GST_TRACER_PAD_PUSH_EVENT_POST (pad, res);
return res;
/* ERROR handling */
@ -5289,28 +5301,30 @@ wrong_direction:
g_warning ("pad %s:%s pushing %s event in wrong direction",
GST_DEBUG_PAD_NAME (pad), GST_EVENT_TYPE_NAME (event));
gst_event_unref (event);
return FALSE;
goto done;
}
unknown_direction:
{
g_warning ("pad %s:%s has invalid direction", GST_DEBUG_PAD_NAME (pad));
gst_event_unref (event);
return FALSE;
goto done;
}
flushed:
{
GST_DEBUG_OBJECT (pad, "We're flushing");
GST_OBJECT_UNLOCK (pad);
gst_event_unref (event);
return FALSE;
goto done;
}
eos:
{
GST_DEBUG_OBJECT (pad, "We're EOS");
GST_OBJECT_UNLOCK (pad);
gst_event_unref (event);
return FALSE;
goto done;
}
done:
GST_TRACER_PAD_PUSH_EVENT_POST (pad, FALSE);
return FALSE;
}
/* Check if we can call the event function with the given event */

View file

@ -66,6 +66,14 @@ typedef enum
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;
@ -153,12 +161,84 @@ extern GList *_priv_tracers[GST_TRACER_HOOK_ID_LAST];
} \
}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_util_get_timestamp (), \
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_util_get_timestamp (), \
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_util_get_timestamp (), \
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_util_get_timestamp (), \
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_util_get_timestamp (), \
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_util_get_timestamp (), \
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_util_get_timestamp (), \
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_util_get_timestamp (), \
element, res); \
} \
}G_STMT_END
#else /* !GST_DISABLE_GST_DEBUG */
#define GST_TRACER_PAD_PUSH_PRE(pad, buffer)
#define GST_TRACER_PAD_PUSH_POST(pad, res)
#define GST_TRACER_PAD_PUSH_LIST_PRE(pad, list)
#define GST_TRACER_PAD_PUSH_LIST_POST(pad, res)
#define GST_TRACER_PAD_PULL_RANGE_PRE(pad, offset, size)
#define GST_TRACER_PAD_PULL_RANGE_POST(pad, buffer, res)
#define GST_TRACER_PAD_PUSH_EVENT_PRE(pad, event)
#define GST_TRACER_PAD_PUSH_EVENT_POST(pad, res)
#define GST_TRACER_ELEMENT_POST_MESSAGE_PRE(element, message)
#define GST_TRACER_ELEMENT_POST_MESSAGE_POST(element, res)
#define GST_TRACER_ELEMENT_QUERY_PRE(element, query)
#define GST_TRACER_ELEMENT_QUERY_POST(element, res)
#endif /* GST_DISABLE_GST_DEBUG */

View file

@ -9,7 +9,7 @@ libgstcoretracers_la_SOURCES = \
libgstcoretracers_la_CFLAGS = $(GST_OBJ_CFLAGS)
libgstcoretracers_la_LIBADD = \
$(top_builddir)/libs/gst/base/libgstbase-@GST_API_VERSION@.la \
$(top_builddir)/gst/printf/libgstprintf.la \
$(GST_OBJ_LIBS)
libgstcoretracers_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstcoretracers_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)

View file

@ -25,15 +25,21 @@
#include "gstlog.h"
#include <gst/printf/printf.h>
GST_DEBUG_CATEGORY_STATIC (gst_log_debug);
#define GST_CAT_DEFAULT gst_log_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_BUFFER);
GST_DEBUG_CATEGORY_STATIC (GST_CAT_BUFFER_LIST);
GST_DEBUG_CATEGORY_STATIC (GST_CAT_EVENT);
GST_DEBUG_CATEGORY_STATIC (GST_CAT_MESSAGE);
#define _do_init \
GST_DEBUG_CATEGORY_INIT (gst_log_debug, "log", 0, "log tracer"); \
GST_DEBUG_CATEGORY_GET (GST_CAT_BUFFER, "GST_BUFFER"); \
GST_DEBUG_CATEGORY_GET (GST_CAT_BUFFER_LIST, "GST_BUFFER_LIST");
GST_DEBUG_CATEGORY_GET (GST_CAT_BUFFER_LIST, "GST_BUFFER_LIST"); \
GST_DEBUG_CATEGORY_GET (GST_CAT_EVENT, "GST_EVENT"); \
GST_DEBUG_CATEGORY_GET (GST_CAT_MESSAGE, "GST_MESSAGE");
#define gst_log_tracer_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstLogTracer, gst_log_tracer, GST_TYPE_TRACER,
_do_init);
@ -64,8 +70,6 @@ gst_log_tracer_invoke (GstTracer * self, GstTracerHookId hid,
guint64 ts = va_arg (var_args, guint64);
/* TODO(ensonic): log to different categories depending on 'mid'
* GST_TRACER_HOOK_ID_EVENTS -> GST_CAT_EVENT
* GST_TRACER_HOOK_ID_MESSAGES -> GST_CAT_MESSAGE
* GST_TRACER_HOOK_ID_QUERIES -> (static category)
* GST_TRACER_HOOK_ID_TOPLOGY -> ?
*/
@ -86,11 +90,43 @@ gst_log_tracer_invoke (GstTracer * self, GstTracerHookId hid,
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:
fmt = "element=%" GST_PTR_FORMAT ", query=%" GST_PTR_FORMAT;
break;
case GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_POST:
fmt = "element=%" GST_PTR_FORMAT ", res=%d";
break;
default:
break;
}
if (fmt) {
gchar *str = g_strdup_vprintf (fmt, var_args);
gchar *str;
__gst_vasprintf (&str, fmt, var_args);
GST_CAT_TRACE (cat, "[%d,%d] %" GST_TIME_FORMAT ", %s",
hid, mid, GST_TIME_ARGS (ts), str);
g_free (str);

View file

@ -435,6 +435,36 @@ do_element_stats (GstStatsTracer * self, GstPad * pad, GstClockTime elapsed1,
#endif
}
/* FIXME: this looks a bit weired, check that we really want to do this
*
* in: a normal pad
* out: the element
*
* in: a proxy pad
* out: the element that contains the peer of the proxy
*
* in: a ghost pad
* out: the bin owning the ghostpad
*/
static GstObject *
get_real_pad_parent (GstPad * pad)
{
GstObject *parent = GST_OBJECT_PARENT (pad);
/* if parent of pad is a ghost-pad, then pad is a proxy_pad */
if (parent && GST_IS_GHOST_PAD (parent)) {
pad = GST_PAD_CAST (parent);
parent = GST_OBJECT_PARENT (pad);
}
/* if pad is a ghost-pad, then parent is a bin and it is the parent of a
* proxy_pad */
while (parent && GST_IS_GHOST_PAD (pad)) {
pad = gst_ghost_pad_get_target (GST_GHOST_PAD (pad));
parent = pad ? GST_OBJECT_PARENT (pad) : NULL;
}
return parent;
}
/* tracer class */
static void gst_stats_tracer_finalize (GObject * obj);
@ -524,6 +554,101 @@ do_push_buffer_list_post (GstStatsTracer * self, va_list var_args)
do_element_stats (self, pad, stats->last_ts, ts);
}
static void
do_pull_range_list_pre (GstStatsTracer * self, va_list var_args)
{
guint64 ts = va_arg (var_args, guint64);
GstPad *pad = va_arg (var_args, GstPad *);
GstPadStats *stats = get_pad_stats (self, pad);
stats->last_ts = ts;
}
static void
do_pull_range_list_post (GstStatsTracer * self, va_list var_args)
{
guint64 ts = va_arg (var_args, guint64);
GstPad *pad = va_arg (var_args, GstPad *);
GstBuffer *buffer = va_arg (var_args, GstBuffer *);
GstPadStats *stats = get_pad_stats (self, pad);
guint64 last_ts = stats->last_ts;
if (buffer != NULL) {
do_pad_stats (self, pad, stats, buffer, ts);
do_transmission_stats (self, pad, buffer, ts);
}
do_element_stats (self, pad, last_ts, ts);
}
static void
do_push_event_pre (GstStatsTracer * self, va_list var_args)
{
guint64 ts = va_arg (var_args, guint64);
GstPad *pad = va_arg (var_args, GstPad *);
GstObject *parent;
GstElement *elem;
parent = get_real_pad_parent (pad);
if ((elem = GST_ELEMENT (parent))) {
GstElementStats *stats = get_element_stats (self, elem);
get_pad_stats (self, pad);
stats->last_ts = ts;
stats->num_events++;
self->num_events++;
}
}
static void
do_push_event_post (GstStatsTracer * self, va_list var_args)
{
#if 0
guint64 ts = va_arg (var_args, guint64);
GstPad *pad = va_arg (var_args, GstPad *);
#endif
}
static void
do_post_message_pre (GstStatsTracer * self, va_list var_args)
{
guint64 ts = va_arg (var_args, guint64);
GstElement *elem = va_arg (var_args, GstElement *);
GstElementStats *stats = get_element_stats (self, elem);
stats->last_ts = ts;
stats->num_messages++;
self->num_messages++;
}
static void
do_post_message_post (GstStatsTracer * self, va_list var_args)
{
#if 0
guint64 ts = va_arg (var_args, guint64);
GstElement *elem = va_arg (var_args, GstElement *);
#endif
}
static void
do_query_pre (GstStatsTracer * self, va_list var_args)
{
guint64 ts = va_arg (var_args, guint64);
GstElement *elem = va_arg (var_args, GstElement *);
GstElementStats *stats = get_element_stats (self, elem);
stats->last_ts = ts;
stats->num_queries++;
self->num_queries++;
}
static void
do_query_post (GstStatsTracer * self, va_list var_args)
{
#if 0
guint64 ts = va_arg (var_args, guint64);
GstElement *elem = va_arg (var_args, GstElement *);
#endif
}
static void
gst_stats_tracer_invoke (GstTracer * obj, GstTracerHookId hid,
GstTracerMessageId mid, va_list var_args)
@ -543,6 +668,30 @@ gst_stats_tracer_invoke (GstTracer * obj, GstTracerHookId hid,
case GST_TRACER_MESSAGE_ID_PAD_PUSH_LIST_POST:
do_push_buffer_list_post (self, var_args);
break;
case GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_PRE:
do_pull_range_list_pre (self, var_args);
break;
case GST_TRACER_MESSAGE_ID_PAD_PULL_RANGE_POST:
do_pull_range_list_post (self, var_args);
break;
case GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_PRE:
do_push_event_pre (self, var_args);
break;
case GST_TRACER_MESSAGE_ID_PAD_PUSH_EVENT_POST:
do_push_event_post (self, var_args);
break;
case GST_TRACER_MESSAGE_ID_ELEMENT_POST_MESSAGE_PRE:
do_post_message_pre (self, var_args);
break;
case GST_TRACER_MESSAGE_ID_ELEMENT_POST_MESSAGE_POST:
do_post_message_post (self, var_args);
break;
case GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_PRE:
do_query_pre (self, var_args);
break;
case GST_TRACER_MESSAGE_ID_ELEMENT_QUERY_POST:
do_query_post (self, var_args);
break;
default:
break;
}