• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  * Copyright (C) 2013 Stefan Sauer <ensonic@users.sf.net>
3  *
4  * gsttracerutils.h: tracing subsystem
5  *
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.
10  *
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.
15  *
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.
20  */
21 
22 
23 #ifndef __GST_TRACER_UTILS_H__
24 #define __GST_TRACER_UTILS_H__
25 
26 #include <glib.h>
27 #include <glib-object.h>
28 #include <gst/gstconfig.h>
29 #include <gst/gstbin.h>
30 #include <gst/gstutils.h>
31 
32 G_BEGIN_DECLS
33 
34 #ifndef GST_DISABLE_GST_TRACER_HOOKS
35 
36 /* tracing hooks */
37 
38 void _priv_gst_tracing_init (void);
39 void _priv_gst_tracing_deinit (void);
40 
41 /* tracer quarks */
42 
43 /* These enums need to match the number and order
44  * of strings declared in _quark_table, in gsttracerutils.c */
45 typedef enum /*< skip >*/
46 {
47   GST_TRACER_QUARK_HOOK_PAD_PUSH_PRE = 0,
48   GST_TRACER_QUARK_HOOK_PAD_PUSH_POST,
49   GST_TRACER_QUARK_HOOK_PAD_PUSH_LIST_PRE,
50   GST_TRACER_QUARK_HOOK_PAD_PUSH_LIST_POST,
51   GST_TRACER_QUARK_HOOK_PAD_PULL_RANGE_PRE,
52   GST_TRACER_QUARK_HOOK_PAD_PULL_RANGE_POST,
53   GST_TRACER_QUARK_HOOK_PAD_PUSH_EVENT_PRE ,
54   GST_TRACER_QUARK_HOOK_PAD_PUSH_EVENT_POST,
55   GST_TRACER_QUARK_HOOK_PAD_QUERY_PRE ,
56   GST_TRACER_QUARK_HOOK_PAD_QUERY_POST,
57   GST_TRACER_QUARK_HOOK_ELEMENT_POST_MESSAGE_PRE,
58   GST_TRACER_QUARK_HOOK_ELEMENT_POST_MESSAGE_POST,
59   GST_TRACER_QUARK_HOOK_ELEMENT_QUERY_PRE,
60   GST_TRACER_QUARK_HOOK_ELEMENT_QUERY_POST,
61   GST_TRACER_QUARK_HOOK_ELEMENT_NEW,
62   GST_TRACER_QUARK_HOOK_ELEMENT_ADD_PAD,
63   GST_TRACER_QUARK_HOOK_ELEMENT_REMOVE_PAD,
64   GST_TRACER_QUARK_HOOK_BIN_ADD_PRE,
65   GST_TRACER_QUARK_HOOK_BIN_ADD_POST,
66   GST_TRACER_QUARK_HOOK_BIN_REMOVE_PRE,
67   GST_TRACER_QUARK_HOOK_BIN_REMOVE_POST,
68   GST_TRACER_QUARK_HOOK_PAD_LINK_PRE,
69   GST_TRACER_QUARK_HOOK_PAD_LINK_POST,
70   GST_TRACER_QUARK_HOOK_PAD_UNLINK_PRE,
71   GST_TRACER_QUARK_HOOK_PAD_UNLINK_POST,
72   GST_TRACER_QUARK_HOOK_ELEMENT_CHANGE_STATE_PRE,
73   GST_TRACER_QUARK_HOOK_ELEMENT_CHANGE_STATE_POST,
74   GST_TRACER_QUARK_HOOK_MINI_OBJECT_CREATED,
75   GST_TRACER_QUARK_HOOK_MINI_OBJECT_DESTROYED,
76   GST_TRACER_QUARK_HOOK_OBJECT_CREATED,
77   GST_TRACER_QUARK_HOOK_OBJECT_DESTROYED,
78   GST_TRACER_QUARK_HOOK_MINI_OBJECT_REFFED,
79   GST_TRACER_QUARK_HOOK_MINI_OBJECT_UNREFFED,
80   GST_TRACER_QUARK_HOOK_OBJECT_REFFED,
81   GST_TRACER_QUARK_HOOK_OBJECT_UNREFFED,
82   GST_TRACER_QUARK_HOOK_PLUGIN_FEATURE_LOADED,
83   GST_TRACER_QUARK_MAX
84 } GstTracerQuarkId;
85 
86 extern GQuark _priv_gst_tracer_quark_table[GST_TRACER_QUARK_MAX];
87 
88 #define GST_TRACER_QUARK(q) _priv_gst_tracer_quark_table[GST_TRACER_QUARK_##q]
89 
90 /* tracing module helpers */
91 
92 typedef struct {
93   GObject *tracer;
94   GCallback func;
95 } GstTracerHook;
96 
97 extern gboolean _priv_tracer_enabled;
98 /* key are hook-id quarks, values are GstTracerHook */
99 extern GHashTable *_priv_tracers;
100 
101 #define GST_TRACER_IS_ENABLED (_priv_tracer_enabled)
102 
103 #define GST_TRACER_TS \
104   GST_CLOCK_DIFF (_priv_gst_start_time, gst_util_get_timestamp ())
105 
106 /* tracing hooks */
107 
108 #define GST_TRACER_ARGS h->tracer, ts
109 #define GST_TRACER_DISPATCH(key,type,args) G_STMT_START{ \
110   if (GST_TRACER_IS_ENABLED) {                                         \
111     GstClockTime ts = GST_TRACER_TS;                                   \
112     GList *__l, *__n;                                                  \
113     GstTracerHook *h;                                                  \
114     __l = g_hash_table_lookup (_priv_tracers, GINT_TO_POINTER (key));  \
115     for (__n = __l; __n; __n = g_list_next (__n)) {                    \
116       h = (GstTracerHook *) __n->data;                                 \
117       ((type)(h->func)) args;                                          \
118     }                                                                  \
119     __l = g_hash_table_lookup (_priv_tracers, NULL);                   \
120     for (__n = __l; __n; __n = g_list_next (__n)) {                    \
121       h = (GstTracerHook *) __n->data;                                 \
122       ((type)(h->func)) args;                                          \
123     }                                                                  \
124   }                                                                    \
125 }G_STMT_END
126 
127 /**
128  * GstTracerHookPadPushPre:
129  * @self: the tracer instance
130  * @ts: the current timestamp
131  * @pad: the pad
132  * @buffer: the buffer
133  *
134  * Pre-hook for gst_pad_push() named "pad-push-pre".
135  */
136 typedef void (*GstTracerHookPadPushPre) (GObject *self, GstClockTime ts,
137     GstPad *pad, GstBuffer *buffer);
138 #define GST_TRACER_PAD_PUSH_PRE(pad, buffer) G_STMT_START{ \
139   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_PAD_PUSH_PRE), \
140     GstTracerHookPadPushPre, (GST_TRACER_ARGS, pad, buffer)); \
141 }G_STMT_END
142 
143 /**
144  * GstTracerHookPadPushPost:
145  * @self: the tracer instance
146  * @ts: the current timestamp
147  * @pad: the pad
148  * @res: the result of gst_pad_push()
149  *
150  * Post-hook for gst_pad_push() named "pad-push-post".
151  */
152 typedef void (*GstTracerHookPadPushPost) (GObject * self, GstClockTime ts,
153     GstPad *pad, GstFlowReturn res);
154 #define GST_TRACER_PAD_PUSH_POST(pad, res) G_STMT_START{ \
155   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_PAD_PUSH_POST), \
156     GstTracerHookPadPushPost, (GST_TRACER_ARGS, pad, res)); \
157 }G_STMT_END
158 
159 /**
160  * GstTracerHookPadPushListPre:
161  * @self: the tracer instance
162  * @ts: the current timestamp
163  * @pad: the pad
164  * @list: the buffer-list
165  *
166  * Pre-hook for gst_pad_push_list() named "pad-push-list-pre".
167  */
168 typedef void (*GstTracerHookPadPushListPre) (GObject *self, GstClockTime ts,
169     GstPad *pad, GstBufferList *list);
170 #define GST_TRACER_PAD_PUSH_LIST_PRE(pad, list) G_STMT_START{ \
171   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_PAD_PUSH_LIST_PRE), \
172     GstTracerHookPadPushListPre, (GST_TRACER_ARGS, pad, list)); \
173 }G_STMT_END
174 
175 /**
176  * GstTracerHookPadPushListPost:
177  * @self: the tracer instance
178  * @ts: the current timestamp
179  * @pad: the pad
180  * @res: the result of gst_pad_push_list()
181  *
182  * Post-hook for gst_pad_push_list() named "pad-push-list-post".
183  */
184 typedef void (*GstTracerHookPadPushListPost) (GObject *self, GstClockTime ts,
185     GstPad *pad,
186     GstFlowReturn res);
187 #define GST_TRACER_PAD_PUSH_LIST_POST(pad, res) G_STMT_START{ \
188   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_PAD_PUSH_LIST_POST), \
189     GstTracerHookPadPushListPost, (GST_TRACER_ARGS, pad, res)); \
190 }G_STMT_END
191 
192 /**
193  * GstTracerHookPadPullRangePre:
194  * @self: the tracer instance
195  * @ts: the current timestamp
196  * @pad: the pad
197  * @offset: the stream offset
198  * @size: the requested size
199  *
200  * Pre-hook for gst_pad_pull_range() named "pad-pull-range-pre".
201  */
202 typedef void (*GstTracerHookPadPullRangePre) (GObject *self, GstClockTime ts,
203     GstPad *pad, guint64 offset, guint size);
204 #define GST_TRACER_PAD_PULL_RANGE_PRE(pad, offset, size) G_STMT_START{ \
205   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_PAD_PULL_RANGE_PRE), \
206     GstTracerHookPadPullRangePre, (GST_TRACER_ARGS, pad, offset, size)); \
207 }G_STMT_END
208 
209 /**
210  * GstTracerHookPadPullRangePost:
211  * @self: the tracer instance
212  * @ts: the current timestamp
213  * @pad: the pad
214  * @buffer: the buffer
215  * @res: the result of gst_pad_pull_range()
216  *
217  * Post-hook for gst_pad_pull_range() named "pad-pull-range-post".
218  */
219 typedef void (*GstTracerHookPadPullRangePost) (GObject *self, GstClockTime ts,
220     GstPad *pad, GstBuffer *buffer, GstFlowReturn res);
221 #define GST_TRACER_PAD_PULL_RANGE_POST(pad, buffer, res) G_STMT_START{ \
222   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_PAD_PULL_RANGE_POST), \
223     GstTracerHookPadPullRangePost, (GST_TRACER_ARGS, pad, buffer, res)); \
224 }G_STMT_END
225 
226 /**
227  * GstTracerHookPadPushEventPre:
228  * @self: the tracer instance
229  * @ts: the current timestamp
230  * @pad: the pad
231  * @event: the event
232  *
233  * Pre-hook for gst_pad_push_event() named "pad-push-event-pre".
234  */
235 typedef void (*GstTracerHookPadPushEventPre) (GObject *self, GstClockTime ts,
236     GstPad *pad, GstEvent *event);
237 #define GST_TRACER_PAD_PUSH_EVENT_PRE(pad, event) G_STMT_START{ \
238   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_PAD_PUSH_EVENT_PRE), \
239     GstTracerHookPadPushEventPre, (GST_TRACER_ARGS, pad, event)); \
240 }G_STMT_END
241 
242 /**
243  * GstTracerHookPadPushEventPost:
244  * @self: the tracer instance
245  * @ts: the current timestamp
246  * @pad: the pad
247  * @res: the result of gst_pad_push_event()
248  *
249  * Post-hook for gst_pad_push_event() named "pad-push-event-post".
250  */
251 typedef void (*GstTracerHookPadPushEventPost) (GObject *self, GstClockTime ts,
252     GstPad *pad, gboolean res);
253 #define GST_TRACER_PAD_PUSH_EVENT_POST(pad, res) G_STMT_START{ \
254   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_PAD_PUSH_EVENT_POST), \
255     GstTracerHookPadPushEventPost, (GST_TRACER_ARGS, pad, res)); \
256 }G_STMT_END
257 
258 /**
259  * GstTracerHookPadQueryPre:
260  * @self: the tracer instance
261  * @ts: the current timestamp
262  * @pad: the pad
263  * @query: the query
264  *
265  * Pre-hook for gst_pad_query() named "pad-query-pre".
266  */
267 typedef void (*GstTracerHookPadQueryPre) (GObject *self, GstClockTime ts,
268     GstPad *pad, GstQuery *query);
269 #define GST_TRACER_PAD_QUERY_PRE(pad, query) G_STMT_START{ \
270   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_PAD_QUERY_PRE), \
271     GstTracerHookPadQueryPre, (GST_TRACER_ARGS, pad, query)); \
272 }G_STMT_END
273 
274 /**
275  * GstTracerHookPadQueryPost:
276  * @self: the tracer instance
277  * @ts: the current timestamp
278  * @pad: the pad
279  * @query: the query
280  * @res: the result of gst_pad_query()
281  *
282  * Post-hook for gst_pad_query() named "pad-query-post".
283  */
284 typedef void (*GstTracerHookPadQueryPost) (GObject *self, GstClockTime ts,
285     GstPad *pad, GstQuery *query, gboolean res);
286 #define GST_TRACER_PAD_QUERY_POST(pad, query, res) G_STMT_START{ \
287   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_PAD_QUERY_POST), \
288     GstTracerHookPadQueryPost, (GST_TRACER_ARGS, pad, query, res)); \
289 }G_STMT_END
290 
291 /**
292  * GstTracerHookElementPostMessagePre:
293  * @self: the tracer instance
294  * @ts: the current timestamp
295  * @element: the element
296  * @message: the message
297  *
298  * Pre-hook for gst_element_post_message() named "element-post-message-pre".
299  */
300 typedef void (*GstTracerHookElementPostMessagePre) (GObject *self,
301     GstClockTime ts, GstElement *element, GstMessage *message);
302 #define GST_TRACER_ELEMENT_POST_MESSAGE_PRE(element, message) G_STMT_START{ \
303   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_ELEMENT_POST_MESSAGE_PRE), \
304     GstTracerHookElementPostMessagePre, (GST_TRACER_ARGS, element, message)); \
305 }G_STMT_END
306 
307 /**
308  * GstTracerHookElementPostMessagePost:
309  * @self: the tracer instance
310  * @ts: the current timestamp
311  * @element: the element
312  * @res: the result of gst_element_post_message()
313  *
314  * Pre-hook for gst_element_post_message() named "element-post-message-post".
315  */
316 typedef void (*GstTracerHookElementPostMessagePost) (GObject *self,
317     GstClockTime ts, GstElement *element, gboolean res);
318 #define GST_TRACER_ELEMENT_POST_MESSAGE_POST(element, res) G_STMT_START{ \
319   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_ELEMENT_POST_MESSAGE_POST), \
320     GstTracerHookElementPostMessagePost, (GST_TRACER_ARGS, element, res)); \
321 }G_STMT_END
322 
323 /**
324  * GstTracerHookElementQueryPre:
325  * @self: the tracer instance
326  * @ts: the current timestamp
327  * @element: the element
328  * @query: the query
329  *
330  * Pre-hook for gst_element_query() named "element-query-pre".
331  */
332 typedef void (*GstTracerHookElementQueryPre) (GObject *self, GstClockTime ts,
333     GstElement *element, GstQuery *query);
334 #define GST_TRACER_ELEMENT_QUERY_PRE(element, query) G_STMT_START{ \
335   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_ELEMENT_QUERY_PRE), \
336     GstTracerHookElementQueryPre, (GST_TRACER_ARGS, element, query)); \
337 }G_STMT_END
338 
339 /**
340  * GstTracerHookElementQueryPost:
341  * @self: the tracer instance
342  * @ts: the current timestamp
343  * @element: the element
344  * @query: the query
345  * @res: the result of gst_element_query()
346  *
347  * Post-hook for gst_element_query() named "element-query-post".
348  */
349 typedef void (*GstTracerHookElementQueryPost) (GObject *self, GstClockTime ts,
350     GstElement *element, GstQuery *query, gboolean res);
351 #define GST_TRACER_ELEMENT_QUERY_POST(element, query, res) G_STMT_START{ \
352   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_ELEMENT_QUERY_POST), \
353     GstTracerHookElementQueryPost, (GST_TRACER_ARGS, element, query, res)); \
354 }G_STMT_END
355 
356 /**
357  * GstTracerHookElementNew:
358  * @self: the tracer instance
359  * @ts: the current timestamp
360  * @element: the element
361  *
362  * Hook for whenever a new element is created, named "element-new".
363  */
364 typedef void (*GstTracerHookElementNew) (GObject *self, GstClockTime ts,
365     GstElement *element);
366 #define GST_TRACER_ELEMENT_NEW(element) G_STMT_START{ \
367   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_ELEMENT_NEW), \
368     GstTracerHookElementNew, (GST_TRACER_ARGS, element)); \
369 }G_STMT_END
370 
371 /**
372  * GstTracerHookElementAddPad:
373  * @self: the tracer instance
374  * @ts: the current timestamp
375  * @element: the element
376  * @pad: the pad
377  *
378  * Hook for gst_element_add_pad() named "element-add-pad".
379  */
380 typedef void (*GstTracerHookElementAddPad) (GObject *self, GstClockTime ts,
381     GstElement *element, GstPad *pad);
382 #define GST_TRACER_ELEMENT_ADD_PAD(element, pad) G_STMT_START{ \
383   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_ELEMENT_ADD_PAD), \
384     GstTracerHookElementAddPad, (GST_TRACER_ARGS, element, pad)); \
385 }G_STMT_END
386 
387 /**
388  * GstTracerHookElementRemovePad:
389  * @self: the tracer instance
390  * @ts: the current timestamp
391  * @element: the element
392  * @pad: the pad
393  *
394  * Hook for gst_element_remove_pad() named "element-remove-pad".
395  */
396 typedef void (*GstTracerHookElementRemovePad) (GObject *self, GstClockTime ts,
397     GstElement *element, GstPad *pad);
398 #define GST_TRACER_ELEMENT_REMOVE_PAD(element, pad) G_STMT_START{ \
399   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_ELEMENT_REMOVE_PAD), \
400     GstTracerHookElementRemovePad, (GST_TRACER_ARGS, element, pad)); \
401 }G_STMT_END
402 
403 /**
404  * GstTracerHookElementChangeStatePre:
405  * @self: the tracer instance
406  * @ts: the current timestamp
407  * @element: the element
408  * @transition: the transition
409  *
410  * Pre-hook for gst_element_change_state() named "element-change-state-pre".
411  */
412 typedef void (*GstTracerHookElementChangeStatePre) (GObject *self,
413     GstClockTime ts, GstElement *element, GstStateChange transition);
414 #define GST_TRACER_ELEMENT_CHANGE_STATE_PRE(element, transition) G_STMT_START{ \
415   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_ELEMENT_CHANGE_STATE_PRE), \
416     GstTracerHookElementChangeStatePre, (GST_TRACER_ARGS, element, transition)); \
417 }G_STMT_END
418 
419 /**
420  * GstTracerHookElementChangeStatePost:
421  * @self: the tracer instance
422  * @ts: the current timestamp
423  * @element: the element
424  * @transition: the transition
425  * @result: the result of gst_pad_push()
426  *
427  * Post-hook for gst_element_change_state() named "element-change-state-post".
428  */
429 typedef void (*GstTracerHookElementChangeStatePost) (GObject *self,
430     GstClockTime ts, GstElement *element, GstStateChange transition,
431     GstStateChangeReturn result);
432 #define GST_TRACER_ELEMENT_CHANGE_STATE_POST(element, transition, result) G_STMT_START{ \
433   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_ELEMENT_CHANGE_STATE_POST), \
434     GstTracerHookElementChangeStatePost, (GST_TRACER_ARGS, element, transition, result)); \
435 }G_STMT_END
436 
437 /**
438  * GstTracerHookBinAddPre:
439  * @self: the tracer instance
440  * @ts: the current timestamp
441  * @bin: the bin
442  * @element: the element
443  *
444  * Pre-hook for gst_bin_add() named "bin-add-pre".
445  */
446 typedef void (*GstTracerHookBinAddPre) (GObject *self, GstClockTime ts,
447     GstBin *bin, GstElement *element);
448 #define GST_TRACER_BIN_ADD_PRE(bin, element) G_STMT_START{ \
449   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_BIN_ADD_PRE), \
450     GstTracerHookBinAddPre, (GST_TRACER_ARGS, bin, element)); \
451 }G_STMT_END
452 
453 /**
454  * GstTracerHookBinAddPost:
455  * @self: the tracer instance
456  * @ts: the current timestamp
457  * @bin: the bin
458  * @element: the element
459  * @result: the result of gst_bin_add()
460  *
461  * Post-hook for gst_bin_add() named "bin-add-post".
462  */
463 typedef void (*GstTracerHookBinAddPost) (GObject *self, GstClockTime ts,
464     GstBin *bin, GstElement *element, gboolean result);
465 #define GST_TRACER_BIN_ADD_POST(bin, element, result) G_STMT_START{ \
466   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_BIN_ADD_POST), \
467     GstTracerHookBinAddPost, (GST_TRACER_ARGS, bin, element, result)); \
468 }G_STMT_END
469 
470 /**
471  * GstTracerHookBinRemovePre:
472  * @self: the tracer instance
473  * @ts: the current timestamp
474  * @bin: the bin
475  * @element: the element
476  *
477  * Pre-hook for gst_bin_remove() named "bin-remove-pre".
478  */
479 typedef void (*GstTracerHookBinRemovePre) (GObject *self, GstClockTime ts,
480     GstBin *bin, GstElement *element);
481 #define GST_TRACER_BIN_REMOVE_PRE(bin, element) G_STMT_START{ \
482   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_BIN_REMOVE_PRE), \
483     GstTracerHookBinRemovePre, (GST_TRACER_ARGS, bin, element)); \
484 }G_STMT_END
485 
486 /**
487  * GstTracerHookBinRemovePost:
488  * @self: the tracer instance
489  * @ts: the current timestamp
490  * @bin: the bin
491  * @result: the result of gst_bin_remove()
492  *
493  * Post-hook for gst_bin_remove() named "bin-remove-post".
494  */
495 typedef void (*GstTracerHookBinRemovePost) (GObject *self, GstClockTime ts,
496     GstBin *bin, gboolean result);
497 #define GST_TRACER_BIN_REMOVE_POST(bin, result) G_STMT_START{ \
498   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_BIN_REMOVE_POST), \
499     GstTracerHookBinRemovePost, (GST_TRACER_ARGS, bin, result)); \
500 }G_STMT_END
501 
502 /**
503  * GstTracerHookPadLinkPre:
504  * @self: the tracer instance
505  * @ts: the current timestamp
506  * @srcpad: the srcpad
507  * @sinkpad: the sinkpad
508  *
509  * Pre-hook for gst_pad_link() named "pad-link-pre".
510  */
511 typedef void (*GstTracerHookPadLinkPre) (GObject *self, GstClockTime ts,
512     GstPad *srcpad, GstPad *sinkpad);
513 #define GST_TRACER_PAD_LINK_PRE(srcpad, sinkpad) G_STMT_START{ \
514   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_PAD_LINK_PRE), \
515     GstTracerHookPadLinkPre, (GST_TRACER_ARGS, srcpad, sinkpad)); \
516 }G_STMT_END
517 
518 /**
519  * GstTracerHookPadLinkPost:
520  * @self: the tracer instance
521  * @ts: the current timestamp
522  * @srcpad: the srcpad
523  * @sinkpad: the sinkpad
524  * @result: the result of gst_pad_link()
525  *
526  * Post-hook for gst_pad_link() named "pad-link-post".
527  */
528 typedef void (*GstTracerHookPadLinkPost) (GObject *self, GstClockTime ts,
529     GstPad *srcpad, GstPad *sinkpad, GstPadLinkReturn result);
530 #define GST_TRACER_PAD_LINK_POST(srcpad, sinkpad, result) G_STMT_START{ \
531   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_PAD_LINK_POST), \
532     GstTracerHookPadLinkPost, (GST_TRACER_ARGS, srcpad, sinkpad, result)); \
533 }G_STMT_END
534 
535 /**
536  * GstTracerHookPadUnlinkPre:
537  * @self: the tracer instance
538  * @ts: the current timestamp
539  * @srcpad: the srcpad
540  * @sinkpad: the sinkpad
541  *
542  * Pre-hook for gst_pad_unlink() named "pad-unlink-pre".
543  */
544 typedef void (*GstTracerHookPadUnlinkPre) (GObject *self, GstClockTime ts,
545     GstPad *srcpad, GstPad *sinkpad);
546 #define GST_TRACER_PAD_UNLINK_PRE(srcpad, sinkpad) G_STMT_START{ \
547   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_PAD_UNLINK_PRE), \
548     GstTracerHookPadUnlinkPre, (GST_TRACER_ARGS, srcpad, sinkpad)); \
549 }G_STMT_END
550 
551 /**
552  * GstTracerHookPadUnlinkPost:
553  * @self: the tracer instance
554  * @ts: the current timestamp
555  * @srcpad: the srcpad
556  * @sinkpad: the sinkpad
557  * @result: the result of gst_pad_push()
558  *
559  * Post-hook for gst_pad_unlink() named "pad-unlink-post".
560  */
561 typedef void (*GstTracerHookPadUnlinkPost) (GObject *self, GstClockTime ts,
562     GstPad *srcpad, GstPad *sinkpad, gboolean result);
563 #define GST_TRACER_PAD_UNLINK_POST(srcpad, sinkpad, result) G_STMT_START{ \
564   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_PAD_UNLINK_POST), \
565     GstTracerHookPadUnlinkPost, (GST_TRACER_ARGS, srcpad, sinkpad, result)); \
566 }G_STMT_END
567 
568 /**
569  * GstTracerHookMiniObjectCreated:
570  * @self: the tracer instance
571  * @ts: the current timestamp
572  * @object: the mini object being created
573  *
574  * Hook called when a #GstMiniObject is created named "mini-object-created".
575  */
576 typedef void (*GstTracerHookMiniObjectCreated) (GObject *self, GstClockTime ts,
577     GstMiniObject *object);
578 #define GST_TRACER_MINI_OBJECT_CREATED(object) G_STMT_START{ \
579   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_MINI_OBJECT_CREATED), \
580     GstTracerHookMiniObjectCreated, (GST_TRACER_ARGS, object)); \
581 }G_STMT_END
582 
583 /**
584  * GstTracerHookMiniObjectDestroyed:
585  * @self: the tracer instance
586  * @ts: the current timestamp
587  * @object: the mini object being destroyed
588  *
589  * Hook called when a #GstMiniObject is being destroyed named
590  * "mini-object-destroyed".
591  */
592 typedef void (*GstTracerHookMiniObjectDestroyed) (GObject *self, GstClockTime ts,
593     GstMiniObject *object);
594 #define GST_TRACER_MINI_OBJECT_DESTROYED(object) G_STMT_START{ \
595   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_MINI_OBJECT_DESTROYED), \
596     GstTracerHookMiniObjectDestroyed, (GST_TRACER_ARGS, object)); \
597 }G_STMT_END
598 
599 /**
600  * GstTracerHookObjectUnreffed:
601  * @self: the tracer instance
602  * @ts: the current timestamp
603  * @object: the object being unreffed
604  * @new_refcount: the new refcount after unrefing @object
605  *
606  * Hook called when a #GstObject is being unreffed named
607  * "object-unreffed"
608  */
609 typedef void (*GstTracerHookObjectUnreffed) (GObject *self, GstClockTime ts,
610     GstObject *object, gint new_refcount);
611 #define GST_TRACER_OBJECT_UNREFFED(object, new_refcount) G_STMT_START{ \
612   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_OBJECT_UNREFFED), \
613     GstTracerHookObjectUnreffed, (GST_TRACER_ARGS, object, new_refcount)); \
614 }G_STMT_END
615 
616 /**
617  * GstTracerHookObjectReffed:
618  * @self: the tracer instance
619  * @ts: the current timestamp
620  * @object: the object being reffed
621  * @new_refcount: the new refcount after refing @object
622  *
623  * Hook called when a #GstObject is being reffed named
624  * "object-reffed".
625  */
626 typedef void (*GstTracerHookObjectReffed) (GObject *self, GstClockTime ts,
627     GstObject *object, gint new_refcount);
628 #define GST_TRACER_OBJECT_REFFED(object, new_refcount) G_STMT_START{ \
629   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_OBJECT_REFFED), \
630     GstTracerHookObjectReffed, (GST_TRACER_ARGS, object, new_refcount)); \
631 }G_STMT_END
632 
633 /**
634  * GstTracerHookMiniObjectUnreffed:
635  * @self: the tracer instance
636  * @ts: the current timestamp
637  * @object: the mini object being unreffed
638  * @new_refcount: the new refcount after unrefing @object
639  *
640  * Hook called when a #GstMiniObject is being unreffed named
641  * "mini-object-unreffed".
642  */
643 typedef void (*GstTracerHookMiniObjectUnreffed) (GObject *self, GstClockTime ts,
644     GstMiniObject *object, gint new_refcount);
645 #define GST_TRACER_MINI_OBJECT_UNREFFED(object, new_refcount) G_STMT_START{ \
646   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_MINI_OBJECT_UNREFFED), \
647     GstTracerHookMiniObjectUnreffed, (GST_TRACER_ARGS, object, new_refcount)); \
648 }G_STMT_END
649 
650 /**
651  * GstTracerHookMiniObjectReffed:
652  * @self: the tracer instance
653  * @ts: the current timestamp
654  * @object: the mini object being reffed
655  * @new_refcount: the new refcount after refing @object
656  *
657  * Hook called when a #GstMiniObject is being reffed named
658  * "mini-object-reffed".
659  */
660 typedef void (*GstTracerHookMiniObjectReffed) (GObject *self, GstClockTime ts,
661     GstMiniObject *object, gint new_refcount);
662 #define GST_TRACER_MINI_OBJECT_REFFED(object, new_refcount) G_STMT_START{ \
663   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_MINI_OBJECT_REFFED), \
664     GstTracerHookMiniObjectReffed, (GST_TRACER_ARGS, object, new_refcount)); \
665 }G_STMT_END
666 
667 /**
668  * GstTracerHookObjectCreated:
669  * @self: the tracer instance
670  * @ts: the current timestamp
671  * @object: the object being created
672  *
673  * Hook called when a #GstObject is created named "object-created".
674  */
675 typedef void (*GstTracerHookObjectCreated) (GObject *self, GstClockTime ts,
676     GstObject *object);
677 #define GST_TRACER_OBJECT_CREATED(object) G_STMT_START{ \
678   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_OBJECT_CREATED), \
679     GstTracerHookObjectCreated, (GST_TRACER_ARGS, object)); \
680 }G_STMT_END
681 
682 /**
683  * GstTracerHookObjectDestroyed:
684  * @self: the tracer instance
685  * @ts: the current timestamp
686  * @object: the object being destroyed
687  *
688  * Hook called when a #GstObject is being destroyed named
689  * "object-destroyed".
690  */
691 typedef void (*GstTracerHookObjectDestroyed) (GObject *self, GstClockTime ts,
692     GstObject *object);
693 
694 #define GST_TRACER_OBJECT_DESTROYED(object) G_STMT_START{ \
695   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_OBJECT_DESTROYED), \
696     GstTracerHookObjectDestroyed, (GST_TRACER_ARGS, object)); \
697 }G_STMT_END
698 
699 /**
700  * GstTracerHookPluginFeatureLoaded:
701  * @self: the tracer instance
702  * @ts: the current timestamp
703  * @feature: the plugin feature that was loaded
704  *
705  * Hook called when a GstPluginFeature is loaded named
706  * "plugin-feature-loaded".
707  *
708  * Since: 1.20
709  */
710 typedef void (*GstTracerHookPluginFeatureLoaded) (GObject *self, GstClockTime ts,
711     GstPluginFeature *feature);
712 /**
713  * GST_TRACER_PLUGIN_FEATURE_LOADED:
714  * @feature: The feature that this tracer is called for
715  *
716  * Add a tracepoint when a plugin feature is loaded.
717  *
718  * Since: 1.20
719  */
720 #define GST_TRACER_PLUGIN_FEATURE_LOADED(feature) G_STMT_START{ \
721   GST_TRACER_DISPATCH(GST_TRACER_QUARK(HOOK_PLUGIN_FEATURE_LOADED), \
722     GstTracerHookPluginFeatureLoaded, (GST_TRACER_ARGS, feature)); \
723 }G_STMT_END
724 
725 
726 #else /* !GST_DISABLE_GST_TRACER_HOOKS */
727 
728 static inline void
729 _priv_gst_tracing_init (void)
730 {
731   GST_DEBUG ("Tracing hooks are disabled");
732 }
733 
734 static inline void
735 _priv_gst_tracing_deinit (void)
736 {
737 }
738 
739 #define GST_TRACER_PAD_PUSH_PRE(pad, buffer)
740 #define GST_TRACER_PAD_PUSH_POST(pad, res)
741 #define GST_TRACER_PAD_PUSH_LIST_PRE(pad, list)
742 #define GST_TRACER_PAD_PUSH_LIST_POST(pad, res)
743 #define GST_TRACER_PAD_PULL_RANGE_PRE(pad, offset, size)
744 #define GST_TRACER_PAD_PULL_RANGE_POST(pad, buffer, res)
745 #define GST_TRACER_PAD_PUSH_EVENT_PRE(pad, event)
746 #define GST_TRACER_PAD_PUSH_EVENT_POST(pad, res)
747 #define GST_TRACER_PAD_QUERY_PRE(pad, query)
748 #define GST_TRACER_PAD_QUERY_POST(pad, query, res)
749 #define GST_TRACER_ELEMENT_POST_MESSAGE_PRE(element, message)
750 #define GST_TRACER_ELEMENT_POST_MESSAGE_POST(element, res)
751 #define GST_TRACER_ELEMENT_QUERY_PRE(element, query)
752 #define GST_TRACER_ELEMENT_QUERY_POST(element, query, res)
753 #define GST_TRACER_ELEMENT_NEW(element)
754 #define GST_TRACER_ELEMENT_ADD_PAD(element, pad)
755 #define GST_TRACER_ELEMENT_REMOVE_PAD(element, pad)
756 #define GST_TRACER_ELEMENT_CHANGE_STATE_PRE(element, transition)
757 #define GST_TRACER_ELEMENT_CHANGE_STATE_POST(element, transition, res)
758 #define GST_TRACER_BIN_ADD_PRE(bin, element)
759 #define GST_TRACER_BIN_ADD_POST(bin, element, res)
760 #define GST_TRACER_BIN_REMOVE_PRE(bin, element)
761 #define GST_TRACER_BIN_REMOVE_POST(bin, res)
762 #define GST_TRACER_PAD_LINK_PRE(srcpad, sinkpad)
763 #define GST_TRACER_PAD_LINK_POST(srcpad, sinkpad, res)
764 #define GST_TRACER_PAD_UNLINK_PRE(srcpad, sinkpad)
765 #define GST_TRACER_PAD_UNLINK_POST(srcpad, sinkpad, res)
766 #define GST_TRACER_MINI_OBJECT_CREATED(object)
767 #define GST_TRACER_MINI_OBJECT_DESTROYED(object)
768 #define GST_TRACER_MINI_OBJECT_REFFED(object, new_refcount)
769 #define GST_TRACER_MINI_OBJECT_UNREFFED(object, new_refcount)
770 #define GST_TRACER_OBJECT_CREATED(object)
771 #define GST_TRACER_OBJECT_DESTROYED(object)
772 #define GST_TRACER_OBJECT_REFFED(object, new_refcount)
773 #define GST_TRACER_OBJECT_UNREFFED(object, new_refcount)
774 #define GST_TRACER_PLUGIN_FEATURE_LOADED(feature)
775 
776 #endif /* GST_DISABLE_GST_TRACER_HOOKS */
777 
778 G_END_DECLS
779 
780 #endif /* __GST_TRACER_UTILS_H__ */
781 
782