commit Brian's patch with AC fix from thomas
[platform/upstream/gstreamer.git] / gst / gstinfo.h
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *
5  * gstinfo.h: 
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #ifndef __GSTINFO_H__
24 #define __GSTINFO_H__
25
26 #include <stdio.h>
27 #include <gmodule.h>
28 #include <unistd.h>
29
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33
34 #ifdef HAVE_FUNC
35 #define FUNCTION __func__
36 #elif HAVE_PRETTY_FUNCTION
37 #define FUNCTION __PRETTY_FUNCTION__
38 #elif HAVE_FUNCTION
39 #define FUNCTION __FUNCTION__
40 #else
41 #define FUNCTION ""
42 #endif
43
44 /***** are we in the core or not? *****/
45 #ifdef __GST_PRIVATE_H__
46   #define _GST_DEBUG_INCORE TRUE
47 #else
48   #define _GST_DEBUG_INCORE FALSE
49 #endif
50
51
52 /* colorization stuff */
53 #ifdef GST_DEBUG_COLOR
54   #ifdef __GST_PRIVATE_H__   /* FIXME this should be some libgst.la -specific thing */
55     #define GST_DEBUG_CHAR_MODE "00"
56   #else
57     #define GST_DEBUG_CHAR_MODE "01"
58   #endif
59 #endif
60
61 gint _gst_debug_stringhash_color(gchar *file);
62
63
64
65 /**********************************************************************
66  * Categories
67  **********************************************************************/
68
69 const gchar *   gst_get_category_name   (gint category);
70
71 enum {
72   GST_CAT_GST_INIT = 0,         /* Library initialization */
73   GST_CAT_COTHREADS,            /* Cothread creation, etc. */
74   GST_CAT_COTHREAD_SWITCH,      /* Cothread switching */
75   GST_CAT_AUTOPLUG,             /* Successful autoplug results */
76   GST_CAT_AUTOPLUG_ATTEMPT,     /* Attempted autoplug operations */
77   GST_CAT_PARENTAGE,            /* GstBin parentage issues */
78   GST_CAT_STATES,               /* State changes and such */
79   GST_CAT_PLANNING,             /* Plan generation */
80   GST_CAT_SCHEDULING,           /* Schedule construction */
81   GST_CAT_DATAFLOW,             /* Events during actual data movement */
82   GST_CAT_BUFFER,               /* Buffer creation/destruction */
83   GST_CAT_CAPS,                 /* Capabilities matching */
84   GST_CAT_CLOCK,                /* Clocking */
85   GST_CAT_ELEMENT_PADS,         /* Element pad management */
86   GST_CAT_ELEMENT_FACTORY,      /* Elementfactory stuff */
87   GST_CAT_PADS,                 /* Pad creation/connection */
88   GST_CAT_PIPELINE,             /* Pipeline stuff */
89   GST_CAT_PLUGIN_LOADING,       /* Plugin loading */
90   GST_CAT_PLUGIN_ERRORS,        /* Errors during plugin loading */
91   GST_CAT_PLUGIN_INFO,          /* Plugin state information */
92   GST_CAT_PROPERTIES,           /* Properties */
93   GST_CAT_THREAD,               /* Thread creation/management */
94   GST_CAT_TYPES,                /* Typing */
95   GST_CAT_XML,                  /* XML load/save of everything */
96   GST_CAT_NEGOTIATION,          /* Caps Negotiation stuff */
97   GST_CAT_REFCOUNTING,          /* Ref Counting stuff */
98   GST_CAT_EVENT,                /* Event system */
99   GST_CAT_PARAMS,               /* Dynamic parameters */
100
101   GST_CAT_CALL_TRACE = 30,      /* Call tracing */
102
103   GST_CAT_MAX_CATEGORY = 31
104 };
105
106 extern const gchar *_gst_category_colors[32];
107
108
109
110 /**********************************************************************
111  * DEBUG system
112  **********************************************************************/
113
114 /* for include files that make too much noise normally */
115 #ifdef GST_DEBUG_FORCE_DISABLE
116 #undef GST_DEBUG_ENABLED
117 #endif
118 /* for applications that really really want all the noise */
119 #ifdef GST_DEBUG_FORCE_ENABLE
120 #define GST_DEBUG_ENABLED
121 #endif
122
123 /*#ifdef GST_DEBUG_ENABLED */
124 #define GST_DEBUG_ENABLE_CATEGORIES 0xffffffff
125 /*#else */
126 /*#define GST_DEBUG_ENABLE_CATEGORIES 0x00000000 */
127 /*#endif */
128
129
130 typedef void (*GstDebugHandler) (gint category,gboolean core,
131                                  const gchar *file,const gchar *function,
132                                  gint line,const gchar *debug_string,
133                                  void *element,gchar *string);
134
135 void gst_default_debug_handler (gint category,gboolean incore,
136                                 const gchar *file, const gchar *function,
137                                 gint line,const gchar *debug_string,
138                                 void *element,gchar *string);
139
140 extern guint32 _gst_debug_categories;
141 extern GstDebugHandler _gst_debug_handler;
142
143 /* fallback, this should probably be a 'weak' symbol or something */
144 G_GNUC_UNUSED static gchar *_debug_string = NULL;
145
146
147
148 #ifdef G_HAVE_ISO_VARARGS
149
150 #ifdef GST_DEBUG_ENABLED
151 #define GST_DEBUG(cat, ...) G_STMT_START{ \
152   if ((1<<cat) & _gst_debug_categories) \
153     _gst_debug_handler(cat,_GST_DEBUG_INCORE,__FILE__,FUNCTION,__LINE__,_debug_string, \
154                        NULL,g_strdup_printf( __VA_ARGS__ )); \
155 }G_STMT_END
156
157 #define GST_DEBUG_ELEMENT(cat, element, ...) G_STMT_START{ \
158   if ((1<<cat) & _gst_debug_categories) \
159     _gst_debug_handler(cat,_GST_DEBUG_INCORE,__FILE__,FUNCTION,__LINE__,_debug_string, \
160                        element,g_strdup_printf( __VA_ARGS__ )); \
161 }G_STMT_END
162
163 #else
164 #define GST_DEBUG(cat, ...)
165 #define GST_DEBUG_ELEMENT(cat,element, ...)
166 #endif
167
168 #elif defined(G_HAVE_GNUC_VARARGS)
169
170 #ifdef GST_DEBUG_ENABLED
171 #define GST_DEBUG(cat,format,args...) G_STMT_START{ \
172   if ((1<<cat) & _gst_debug_categories) \
173     _gst_debug_handler(cat,_GST_DEBUG_INCORE,__FILE__,FUNCTION,__LINE__,_debug_string, \
174                        NULL,g_strdup_printf( format , ## args )); \
175 }G_STMT_END
176
177 #define GST_DEBUG_ELEMENT(cat,element,format,args...) G_STMT_START{ \
178   if ((1<<cat) & _gst_debug_categories) \
179     _gst_debug_handler(cat,_GST_DEBUG_INCORE,__FILE__,FUNCTION,__LINE__,_debug_string, \
180                        element,g_strdup_printf( format , ## args )); \
181 }G_STMT_END
182
183 #else
184 #define GST_DEBUG(cat,format,args...)
185 #define GST_DEBUG_ELEMENT(cat,element,format,args...)
186 #endif
187
188 #endif
189
190
191
192
193 /********** some convenience macros for debugging **********/
194 #define GST_DEBUG_PAD_NAME(pad) \
195   (GST_OBJECT_PARENT(pad) != NULL) ? \
196   GST_OBJECT_NAME (GST_OBJECT_PARENT(pad)) : \
197   "''", GST_OBJECT_NAME (pad)
198
199 #ifdef G_HAVE_ISO_VARARGS
200
201 #ifdef GST_DEBUG_COLOR
202   #define GST_DEBUG_ENTER(...) GST_DEBUG( 31 , "\033[00;37mentering\033[00m :" __VA_ARGS__ )
203   #define GST_DEBUG_LEAVE(...) GST_DEBUG( 31 , "\033[00;37mleaving\033[00m :" , __VA_ARGS__ )
204 #else
205   #define GST_DEBUG_ENTER(...) GST_DEBUG( 31 , "entering :" __VA_ARGS__ )
206   #define GST_DEBUG_LEAVE(...) GST_DEBUG( 31 , "leaving :" __VA_ARGS__ )
207 #endif
208
209 #elif defined(G_HAVE_GNUC_VARARGS)
210
211 #ifdef GST_DEBUG_COLOR
212   #define GST_DEBUG_ENTER(format, args...) GST_DEBUG( 31 , format ": \033[00;37mentering\033[00m" , ##args )
213   #define GST_DEBUG_LEAVE(format, args...) GST_DEBUG( 31 , format ": \033[00;37mleaving\033[00m" , ##args )
214 #else
215   #define GST_DEBUG_ENTER(format, args...) GST_DEBUG( 31 , format ": entering" , ##args )
216   #define GST_DEBUG_LEAVE(format, args...) GST_DEBUG( 31 , format ": leaving" , ##args )
217 #endif
218
219 #endif
220
221
222 /***** Colorized debug for thread ids *****/
223 #ifdef GST_DEBUG_COLOR
224   #define GST_DEBUG_THREAD_FORMAT "\033[00;%dm%d\033[00m"
225   #define GST_DEBUG_THREAD_ARGS(id) ( ((id) < 0) ? 37 : ((id) % 6 + 31) ), (id)
226 #else
227   #define GST_DEBUG_THREAD_FORMAT "%d"
228   #define GST_DEBUG_THREAD_ARGS(id) (id)
229 #endif
230
231
232
233 /**********************************************************************
234  * The following is a DEBUG_ENTER implementation that will wrap the
235  * function it sits at the head of.  It removes the need for a
236  * DEBUG_LEAVE call.  However, it segfaults whenever it gets anywhere
237  * near cothreads.  We will not use it for the moment.
238  *
239 typedef void (*_debug_function_f)();
240 G_GNUC_UNUSED static gchar *_debug_string_pointer = NULL;
241 G_GNUC_UNUSED static GModule *_debug_self_module = NULL;
242
243 #ifdef G_HAVE_ISO_VARARGS
244
245 #define _DEBUG_ENTER_BUILTIN(...)                                                       \
246   static int _debug_in_wrapper = 0;                                                     \
247   gchar *_debug_string = ({                                                             \
248     if (!_debug_in_wrapper) {                                                           \
249       void *_return_value;                                                              \
250       gchar *_debug_string;                                                             \
251       _debug_function_f function;                                                       \
252       void *_function_args = __builtin_apply_args();                                    \
253       _debug_in_wrapper = 1;                                                            \
254       _debug_string = g_strdup_printf(GST_DEBUG_PREFIX(""));                            \
255       _debug_string_pointer = _debug_string;                                            \
256       fprintf(stderr,"%s: entered " FUNCTION, _debug_string);                           \ 
257       fprintf(stderr, __VA_ARGS__ );                                                    \
258       fprintf(stderr,"\n");                                                             \
259       if (_debug_self_module == NULL) _debug_self_module = g_module_open(NULL,0);       \
260       g_module_symbol(_debug_self_module,FUNCTION,(gpointer *)&function);               \
261       _return_value = __builtin_apply(function,_function_args,64);                      \
262       fprintf(stderr,"%s: left " FUNCTION, _debug_string);                              \
263       fprintf(stderr, __VA_ARGS__);                                                     \
264       fprintf(stderr,"\n");                                                             \
265       g_free(_debug_string);                                                            \
266       __builtin_return(_return_value);                                                  \
267     } else {                                                                            \
268       _debug_in_wrapper = 0;                                                            \
269     }                                                                                   \
270     _debug_string_pointer;                                                              \
271   });
272
273 #elif defined(G_HAVE_GNUC_VARARGS)
274
275 #define _DEBUG_ENTER_BUILTIN(format,args...)                                            \
276   static int _debug_in_wrapper = 0;                                                     \
277   gchar *_debug_string = ({                                                             \
278     if (!_debug_in_wrapper) {                                                           \
279       void *_return_value;                                                              \
280       gchar *_debug_string;                                                             \
281       _debug_function_f function;                                                       \
282       void *_function_args = __builtin_apply_args();                                    \
283       _debug_in_wrapper = 1;                                                            \
284       _debug_string = g_strdup_printf(GST_DEBUG_PREFIX(""));                            \
285       _debug_string_pointer = _debug_string;                                            \
286       fprintf(stderr,"%s: entered " FUNCTION format "\n" , _debug_string , ## args );   \
287       if (_debug_self_module == NULL) _debug_self_module = g_module_open(NULL,0);       \
288       g_module_symbol(_debug_self_module,FUNCTION,(gpointer *)&function);               \
289       _return_value = __builtin_apply(function,_function_args,64);                      \
290       fprintf(stderr,"%s: left " FUNCTION format "\n" , _debug_string , ## args ); \
291       g_free(_debug_string);                                                            \
292       __builtin_return(_return_value);                                                  \
293     } else {                                                                            \
294       _debug_in_wrapper = 0;                                                            \
295     }                                                                                   \
296     _debug_string_pointer;                                                              \
297   });
298
299 #endif
300
301 * WARNING: there's a gcc CPP bug lurking in here.  The extra space before the ##args    *
302  * somehow make the preprocessor leave the _debug_string. If it's removed, the          *
303  * _debug_string somehow gets stripped along with the ##args, and that's all she wrote. *
304
305 #ifdef G_HAVE_ISO_VARARGS
306
307 #define _DEBUG_BUILTIN(...)                                     \
308   if (_debug_string != (void *)-1) {                            \
309     if (_debug_string) {                                        \
310       fprintf(stderr, "%s: " _debug_string);                    \
311       fprintf(stderr, __VA_ARGS__);                             \
312     } else {                                                    \
313       fprintf(stderr,GST_DEBUG_PREFIX(": " __VA_ARGS__));       \
314     }                                                           \
315   }
316
317 #elif defined(G_HAVE_GNUC_VARARGS)
318
319 #define _DEBUG_BUILTIN(format,args...)                          \
320   if (_debug_string != (void *)-1) {                            \
321     if (_debug_string)                                          \
322       fprintf(stderr,"%s: " format , _debug_string , ## args);  \
323     else                                                        \
324       fprintf(stderr,GST_DEBUG_PREFIX(": " format , ## args));  \
325   }
326
327 #endif
328
329 */
330
331
332
333 /**********************************************************************
334  * INFO system
335  **********************************************************************/
336
337 typedef void (*GstInfoHandler) (gint category,gboolean incore,
338                                 const gchar *file,const gchar *function,
339                                 gint line,const gchar *debug_string,
340                                 void *element,gchar *string);
341
342 void gst_default_info_handler (gint category,gboolean incore,
343                                const gchar *file,const gchar *function,
344                                gint line,const gchar *debug_string,
345                                void *element,gchar *string);
346
347 extern GstInfoHandler _gst_info_handler;
348 extern guint32 _gst_info_categories;
349
350 /* for include files that make too much noise normally */
351 #ifdef GST_INFO_FORCE_DISABLE
352 #undef GST_INFO_ENABLED
353 #endif
354 /* for applications that really really want all the noise */
355 #ifdef GST_INFO_FORCE_ENABLE
356 #define GST_INFO_ENABLED
357 #endif
358
359 #ifdef G_HAVE_ISO_VARARGS
360
361 #ifdef GST_INFO_ENABLED
362 #define GST_INFO(cat,...) G_STMT_START{ \
363   if ((1<<cat) & _gst_info_categories) \
364     _gst_info_handler(cat,_GST_DEBUG_INCORE,__FILE__,FUNCTION,__LINE__,_debug_string, \
365                       NULL,g_strdup_printf( __VA_ARGS__ )); \
366 }G_STMT_END
367
368 #define GST_INFO_ELEMENT(cat,element,...) G_STMT_START{ \
369   if ((1<<cat) & _gst_info_categories) \
370     _gst_info_handler(cat,_GST_DEBUG_INCORE,__FILE__,FUNCTION,__LINE__,_debug_string, \
371                       element,g_strdup_printf( __VA_ARGS__ )); \
372 }G_STMT_END
373
374 #else
375 #define GST_INFO(cat,...) 
376 #define GST_INFO_ELEMENT(cat,element,...)
377 #endif
378
379 #elif defined(G_HAVE_GNUC_VARARGS)
380
381 #ifdef GST_INFO_ENABLED
382 #define GST_INFO(cat,format,args...) G_STMT_START{ \
383   if ((1<<cat) & _gst_info_categories) \
384     _gst_info_handler(cat,_GST_DEBUG_INCORE,__FILE__,FUNCTION,__LINE__,_debug_string, \
385                       NULL,g_strdup_printf( format , ## args )); \
386 }G_STMT_END
387
388 #define GST_INFO_ELEMENT(cat,element,format,args...) G_STMT_START{ \
389   if ((1<<cat) & _gst_info_categories) \
390     _gst_info_handler(cat,_GST_DEBUG_INCORE,__FILE__,FUNCTION,__LINE__,_debug_string, \
391                       element,g_strdup_printf( format , ## args )); \
392 }G_STMT_END
393
394 #else
395 #define GST_INFO(cat,format,args...) 
396 #define GST_INFO_ELEMENT(cat,element,format,args...)
397 #endif
398
399 #endif
400
401
402 void            gst_info_set_categories         (guint32 categories);
403 guint32         gst_info_get_categories         (void);
404 void            gst_info_enable_category        (gint category);
405 void            gst_info_disable_category       (gint category);
406
407 void            gst_debug_set_categories        (guint32 categories);
408 guint32         gst_debug_get_categories        (void);
409 void            gst_debug_enable_category       (gint category);
410 void            gst_debug_disable_category      (gint category);
411
412
413
414
415 /**********************************************************************
416  * ERROR system
417  **********************************************************************/
418
419 typedef void (*GstErrorHandler) (gchar *file,gchar *function,
420                                  gint line,gchar *debug_string,
421                                  void *element,void *object,gchar *string);
422
423 void gst_default_error_handler (gchar *file,gchar *function,
424                                 gint line,gchar *debug_string,
425                                 void *element,void *object,gchar *string);
426
427 extern GstErrorHandler _gst_error_handler;
428
429 #ifdef G_HAVE_ISO_VARARGS
430
431 #define GST_ERROR(element,...) \
432   _gst_error_handler(__FILE__,FUNCTION,__LINE__,_debug_string, \
433                      element,NULL,g_strdup_printf( __VA_ARGS__ ))
434
435 #define GST_ERROR_OBJECT(element,object,...) \
436   _gst_error_handler(__FILE__,FUNCTION,__LINE__,_debug_string, \
437                      element,object,g_strdup_printf( __VA_ARGS__ ))
438
439 #elif defined(G_HAVE_GNUC_VARARGS)
440
441 #define GST_ERROR(element,format,args...) \
442   _gst_error_handler(__FILE__,FUNCTION,__LINE__,_debug_string, \
443                      element,NULL,g_strdup_printf( format , ## args ))
444
445 #define GST_ERROR_OBJECT(element,object,format,args...) \
446   _gst_error_handler(__FILE__,FUNCTION,__LINE__,_debug_string, \
447                      element,object,g_strdup_printf( format , ## args ))
448
449 #endif
450
451
452
453
454 /********** function pointer stuff **********/
455 extern GHashTable *__gst_function_pointers;
456
457
458 #if GST_DEBUG_ENABLED
459 #define GST_DEBUG_FUNCPTR(ptr) _gst_debug_register_funcptr((void *)(ptr), #ptr)
460 #define GST_DEBUG_FUNCPTR_NAME(ptr) _gst_debug_nameof_funcptr((void *)ptr)
461 #else
462 #define GST_DEBUG_FUNCPTR(ptr) (ptr)
463 #define GST_DEBUG_FUNCPTR_NAME(ptr) ""
464 #endif
465
466 static inline void *
467 _gst_debug_register_funcptr (void *ptr, gchar *ptrname) 
468 {
469   if (!__gst_function_pointers) __gst_function_pointers = g_hash_table_new(g_direct_hash,g_direct_equal);
470   if (!g_hash_table_lookup(__gst_function_pointers,ptr))
471     g_hash_table_insert(__gst_function_pointers,ptr,ptrname);
472   return ptr;
473 }
474
475 gchar *_gst_debug_nameof_funcptr (void *ptr);
476
477 void gst_debug_print_stack_trace (void);
478
479
480
481 #endif /* __GSTINFO_H__ */