This is a megapatch with the following changes:
[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 #include "cothreads.h"
35
36
37 /**********************************************************************
38  * DEBUG system
39  **********************************************************************/
40
41 extern guint32 _gst_debug_categories;
42
43 /* for include files that make too much noise normally */
44 #ifdef GST_DEBUG_FORCE_DISABLE
45 #undef GST_DEBUG_ENABLED
46 #endif
47 /* for applications that really really want all the noise */
48 #ifdef GST_DEBUG_FORCE_ENABLE
49 #define GST_DEBUG_ENABLED
50 #endif
51
52 //#ifdef GST_DEBUG_ENABLED
53 #define GST_DEBUG_ENABLE_CATEGORIES 0xffffffff
54 //#else
55 //#define GST_DEBUG_ENABLE_CATEGORIES 0x00000000
56 //#endif
57
58 /* fallback, this should probably be a 'weak' symbol or something */
59 G_GNUC_UNUSED static gchar *_debug_string = NULL;
60
61 #define GST_DEBUG_PREFIX(format,args...) \
62 "DEBUG(%d:%d)" __PRETTY_FUNCTION__ ":%d" format , getpid() , cothread_getcurrent() , __LINE__ , ## args
63
64 #ifdef GST_DEBUG_ENABLED
65 #define GST_DEBUG(cat,format,args...) G_STMT_START{ \
66   if (((1<<cat) & GST_DEBUG_ENABLE_CATEGORIES) && \
67       ((1<<cat) & _gst_debug_categories)) \
68     (_debug_string != NULL) ? \
69       fprintf(stderr,GST_DEBUG_PREFIX("%s: "format , _debug_string , ## args )) : \
70       fprintf(stderr,GST_DEBUG_PREFIX(": "format , ## args )); \
71 }G_STMT_END
72
73 #define GST_DEBUG_NOPREFIX(cat,format,args...) G_STMT_START{ \
74   if (((1<<cat) & GST_DEBUG_ENABLE_CATEGORIES) && \
75       ((1<<cat) & _gst_debug_categories)) \
76     fprintf(stderr,format , ## args ); \
77 }G_STMT_END
78
79 #define GST_DEBUG_ENTER(format, args...) G_STMT_START{ \
80   if (((1<<31) & GST_DEBUG_ENABLE_CATEGORIES) && \
81       ((1<<31) & _gst_debug_categories)) \
82     fprintf(stderr,GST_DEBUG_PREFIX(format": entering\n" , ## args )); \
83 }G_STMT_END
84
85 // FIXME FIXME FIXME this leaks like crazy
86 #define GST_DEBUG_SET_STRING(format, args...) \
87   gchar *_debug_string = g_strdup_printf(format , ## args )
88
89 #define GST_DEBUG_ENTER_STRING GST_DEBUG_ENTER("%s",_debug_string)
90
91 #define GST_DEBUG_LEAVE(format, args...) G_STMT_START{ \
92   if (((1<<31) & GST_DEBUG_ENABLE_CATEGORIES) && \
93       ((1<<31) & _gst_debug_categories)) \
94     if (_debug_string != NULL) g_free(_debug_string),\
95       fprintf(stderr,GST_DEBUG_PREFIX(format": leaving\n" , ## args )); \
96 }G_STMT_END
97
98 #define GST_DEBUG_LEAVE_STRING GST_DEBUG_LEAVE("%s",_debug_string)
99
100 #else
101 #define GST_DEBUG(format, args...)
102 #define GST_DEBUG_NOPREFIX(format, args...)
103 #define GST_DEBUG_ENTER(format, args...)
104 #define GST_DEBUG_LEAVE(format, args...)
105 #define GST_DEBUG_SET_STRING(format, args...)
106 #define GST_DEBUG_ENTER_STRING
107 #endif
108
109
110
111 /********** some convenience macros for debugging **********/
112 #define GST_DEBUG_PAD_NAME(pad) \
113   (GST_OBJECT_PARENT(pad) != NULL) ? \
114   GST_OBJECT_NAME (GST_OBJECT_PARENT(pad)) : \
115   "''", GST_OBJECT_NAME (pad)
116
117
118
119 /********** function pointer stuff **********/
120 extern GHashTable *__gst_function_pointers;
121
122 #ifdef GST_DEBUG_ENABLED
123 #define GST_DEBUG_FUNCPTR(ptr) _gst_debug_register_funcptr((void *)(ptr), #ptr)
124 #define GST_DEBUG_FUNCPTR_NAME(ptr) _gst_debug_nameof_funcptr((void *)ptr)
125 #else
126 #define GST_DEBUG_FUNCPTR(ptr) (ptr)
127 #define GST_DEBUG_FUNCPTR_NAME(ptr) ""
128 #endif
129
130 static inline void *
131 _gst_debug_register_funcptr (void *ptr, gchar *ptrname) 
132 {
133   if (!__gst_function_pointers) __gst_function_pointers = g_hash_table_new(g_direct_hash,g_direct_equal);
134   if (!g_hash_table_lookup(__gst_function_pointers,ptr))
135     g_hash_table_insert(__gst_function_pointers,ptr,ptrname);
136   return ptr;
137 }
138
139 static inline gchar *
140 _gst_debug_nameof_funcptr (void *ptr) 
141 {
142   gchar *ptrname = __gst_function_pointers ? g_hash_table_lookup(__gst_function_pointers,ptr) : NULL;
143 // FIXME this must go away, it's a major leak
144   if (!ptrname) return g_strdup_printf("%p",ptr);
145   else return ptrname;
146 }
147
148
149 /**********************************************************************
150  * The following is a DEBUG_ENTER implementation that will wrap the
151  * function it sits at the head of.  It removes the need for a
152  * DEBUG_LEAVE call.  However, it segfaults whenever it gets anywhere
153  * near cothreads.  We will not use it for the moment.
154  *
155 typedef void (*_debug_function_f)();
156 G_GNUC_UNUSED static gchar *_debug_string_pointer = NULL;
157 G_GNUC_UNUSED static GModule *_debug_self_module = NULL;
158
159 #define _DEBUG_ENTER_BUILTIN(format,args...)                                            \
160   static int _debug_in_wrapper = 0;                                                     \
161   gchar *_debug_string = ({                                                             \
162     if (!_debug_in_wrapper) {                                                           \
163       void *_return_value;                                                              \
164       gchar *_debug_string;                                                             \
165       _debug_function_f function;                                                       \
166       void *_function_args = __builtin_apply_args();                                    \
167       _debug_in_wrapper = 1;                                                            \
168       _debug_string = g_strdup_printf(GST_DEBUG_PREFIX(""));                            \
169       _debug_string_pointer = _debug_string;                                            \
170       fprintf(stderr,"%s: entered " __PRETTY_FUNCTION__ format "\n" , _debug_string , ## args ); \
171       if (_debug_self_module == NULL) _debug_self_module = g_module_open(NULL,0);       \
172       g_module_symbol(_debug_self_module,__FUNCTION__,(gpointer *)&function);           \
173       _return_value = __builtin_apply(function,_function_args,64);                      \
174       fprintf(stderr,"%s: left " __PRETTY_FUNCTION__ format "\n" , _debug_string , ## args ); \
175       g_free(_debug_string);                                                            \
176       __builtin_return(_return_value);                                                  \
177     } else {                                                                            \
178       _debug_in_wrapper = 0;                                                            \
179     }                                                                                   \
180     _debug_string_pointer;                                                              \
181   });
182
183 * WARNING: there's a gcc CPP bug lurking in here.  The extra space before the ##args    *
184  * somehow make the preprocessor leave the _debug_string. If it's removed, the          *
185  * _debug_string somehow gets stripped along with the ##args, and that's all she wrote. *
186 #define _DEBUG_BUILTIN(format,args...)                          \
187   if (_debug_string != (void *)-1) {                            \
188     if (_debug_string)                                          \
189       fprintf(stderr,"%s: " format , _debug_string , ## args);  \
190     else                                                        \
191       fprintf(stderr,GST_DEBUG_PREFIX(": " format , ## args));  \
192   }
193
194 */
195
196
197
198 /**********************************************************************
199  * INFO system
200  **********************************************************************/
201
202 typedef void (*GstInfoHandler) (gint category,gchar *file,gchar *function,
203                                 gint line,gchar *debug_string,
204                                 void *element,gchar *string);
205
206 void gst_default_info_handler (gint category,gchar *file,gchar *function,
207                                gint line,gchar *debug_string,
208                                void *element,gchar *string);
209
210 extern GstInfoHandler _gst_info_handler;
211 extern guint32 _gst_info_categories;
212
213 /* for include files that make too much noise normally */
214 #ifdef GST_INFO_FORCE_DISABLE
215 #undef GST_INFO_ENABLED
216 #endif
217 /* for applications that really really want all the noise */
218 #ifdef GST_INFO_FORCE_ENABLE
219 #define GST_INFO_ENABLED
220 #endif
221
222 #ifdef GST_INFO_ENABLED
223 #define GST_INFO(cat,format,args...) G_STMT_START{ \
224   if ((1<<cat) & _gst_info_categories) \
225     _gst_info_handler(cat,__FILE__,__PRETTY_FUNCTION__,__LINE__,_debug_string, \
226                       NULL,g_strdup_printf( format , ## args )); \
227 }G_STMT_END
228
229 #define GST_INFO_ELEMENT(cat,element,format,args...) G_STMT_START{ \
230   if ((1<<cat) & _gst_info_categories) \
231     _gst_info_handler(cat,__FILE__,__PRETTY_FUNCTION__,__LINE__,_debug_string, \
232                       element,g_strdup_printf( format , ## args )); \
233 }G_STMT_END
234
235 #else
236 #define GST_INFO(cat,format,args...) 
237 #define GST_INFO_ELEMENT(cat,element,format,args...)
238 #endif
239
240
241 void            gst_info_set_categories         (guint32 categories);
242 guint32         gst_info_get_categories         (void);
243 void            gst_info_enable_category        (gint category);
244 void            gst_info_disable_category       (gint category);
245
246 void            gst_debug_set_categories        (guint32 categories);
247 guint32         gst_debug_get_categories        (void);
248 void            gst_debug_enable_category       (gint category);
249 void            gst_debug_disable_category      (gint category);
250
251 const gchar *   gst_get_category_name   (gint category);
252
253
254 enum {
255   GST_CAT_GST_INIT = 0,         // Library initialization
256   GST_CAT_COTHREADS,            // Cothread creation, etc.
257   GST_CAT_COTHREAD_SWITCH,      // Cothread switching
258   GST_CAT_AUTOPLUG,             // Successful autoplug results
259   GST_CAT_AUTOPLUG_ATTEMPT,     // Attempted autoplug operations
260   GST_CAT_PARENTAGE,            // GstBin parentage issues
261   GST_CAT_STATES,               // State changes and such
262   GST_CAT_PLANNING,             // Plan generation
263   GST_CAT_SCHEDULING,           // Schedule construction
264   GST_CAT_OPERATION,            // Events during actual data movement
265   GST_CAT_BUFFER,               // Buffer creation/destruction
266   GST_CAT_CAPS,                 // Capabilities matching
267   GST_CAT_CLOCK,                // Clocking
268   GST_CAT_ELEMENT_PADS,         // Element pad management
269   GST_CAT_ELEMENTFACTORY,       // Elementfactory stuff
270   GST_CAT_PADS,                 // Pad creation/connection
271   GST_CAT_PIPELINE,             // Pipeline stuff
272   GST_CAT_PLUGIN_LOADING,       // Plugin loading
273   GST_CAT_PLUGIN_ERRORS,        // Errors during plugin loading
274   GST_CAT_PROPERTIES,           // Properties
275   GST_CAT_THREAD,               // Thread creation/management
276   GST_CAT_TYPES,                // Typing
277   GST_CAT_XML,                  // XML load/save of everything
278
279   GST_CAT_MAX_CATEGORY,
280 };
281
282
283
284
285 /**********************************************************************
286  * ERROR system
287  **********************************************************************/
288
289 typedef void (*GstErrorHandler) (gchar *file,gchar *function,
290                                  gint line,gchar *debug_string,
291                                  void *element,void *object,gchar *string);
292
293 void gst_default_error_handler (gchar *file,gchar *function,
294                                 gint line,gchar *debug_string,
295                                 void *element,void *object,gchar *string);
296
297 extern GstErrorHandler _gst_error_handler;
298
299 #define GST_ERROR(element,format,args...) \
300   _gst_error_handler(__FILE__,__PRETTY_FUNCTION__,__LINE__,_debug_string, \
301                      element,NULL,g_strdup_printf( format , ## args ))
302
303 #define GST_ERROR_OBJECT(element,object,format,args...) \
304   _gst_error_handler(__FILE__,__PRETTY_FUNCTION__,__LINE__,_debug_string, \
305                      element,object,g_strdup_printf( format , ## args ))
306
307
308
309 #endif /* __GSTINFO_H__ */