2000-12-29 10:02:17 +00:00
|
|
|
/* GStreamer
|
|
|
|
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
|
|
|
|
* 2000 Wim Taymans <wtay@chello.be>
|
|
|
|
*
|
|
|
|
* gstinfo.c: INFO, ERROR, and DEBUG systems
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this library; if not, write to the
|
|
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
* Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
2000-12-30 02:41:15 +00:00
|
|
|
#include "gst_private.h"
|
2001-01-29 00:06:02 +00:00
|
|
|
#include "gstelement.h"
|
|
|
|
#include "gstpad.h"
|
2000-12-29 10:02:17 +00:00
|
|
|
|
|
|
|
extern gchar *_gst_progname;
|
|
|
|
|
|
|
|
|
|
|
|
/***** DEBUG system *****/
|
|
|
|
GHashTable *__gst_function_pointers = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/***** INFO system *****/
|
|
|
|
GstInfoHandler _gst_info_handler = gst_default_info_handler;
|
2001-01-01 01:56:16 +00:00
|
|
|
#ifdef GST_INFO_ENABLED_VERBOSE
|
|
|
|
guint32 _gst_info_categories = 0xffffffff;
|
|
|
|
#else
|
2001-01-01 00:17:21 +00:00
|
|
|
guint32 _gst_info_categories = 0x00000001;
|
2001-01-01 01:56:16 +00:00
|
|
|
#endif
|
2000-12-30 02:41:15 +00:00
|
|
|
|
|
|
|
static gchar *_gst_info_category_strings[] = {
|
|
|
|
"GST_INIT",
|
|
|
|
"COTHREADS",
|
|
|
|
"COTHREAD_SWITCH",
|
|
|
|
"AUTOPLUG",
|
|
|
|
"AUTOPLUG_ATTEMPT",
|
|
|
|
"PARENTAGE",
|
|
|
|
"STATES",
|
|
|
|
"PLANING",
|
|
|
|
"SCHEDULING",
|
|
|
|
"OPERATION",
|
|
|
|
"BUFFER",
|
|
|
|
"CAPS",
|
|
|
|
"CLOCK",
|
|
|
|
"ELEMENT_PADS",
|
|
|
|
"ELEMENTFACTORY",
|
|
|
|
"PADS",
|
|
|
|
"PIPELINE",
|
|
|
|
"PLUGIN_LOADING",
|
|
|
|
"PLUGIN_ERRORS",
|
|
|
|
"PROPERTIES",
|
|
|
|
"THREAD",
|
|
|
|
"TYPES",
|
|
|
|
"XML",
|
|
|
|
};
|
2000-12-29 10:02:17 +00:00
|
|
|
|
2001-01-04 22:16:06 +00:00
|
|
|
/**
|
|
|
|
* gst_default_info_handler:
|
|
|
|
* @category: category of the INFO message
|
|
|
|
* @file: the file the INFO occurs in
|
|
|
|
* @function: the function the INFO occurs in
|
|
|
|
* @line: the line number in the file
|
|
|
|
* @debug_string: the current debug_string in the function, if any
|
|
|
|
* @element: pointer to the #GstElement in question
|
|
|
|
* @string: the actual INFO string
|
|
|
|
*
|
|
|
|
* Prints out the INFO mesage in a variant of the following form:
|
|
|
|
*
|
|
|
|
* INFO:gst_function:542(args): [elementname] something neat happened
|
|
|
|
*/
|
2000-12-29 10:02:17 +00:00
|
|
|
void
|
2000-12-30 02:41:15 +00:00
|
|
|
gst_default_info_handler (gint category, gchar *file, gchar *function,
|
2000-12-29 10:02:17 +00:00
|
|
|
gint line, gchar *debug_string,
|
|
|
|
void *element, gchar *string)
|
|
|
|
{
|
2001-01-01 00:17:21 +00:00
|
|
|
gchar *empty = "";
|
|
|
|
gchar *elementname = empty,*location = empty;
|
|
|
|
|
|
|
|
if (debug_string == NULL) debug_string = "";
|
2001-01-01 03:14:40 +00:00
|
|
|
if (category != GST_CAT_GST_INIT)
|
2001-01-01 00:17:21 +00:00
|
|
|
location = g_strdup_printf("%s:%d%s:",function,line,debug_string);
|
|
|
|
if (element && GST_IS_ELEMENT (element))
|
2001-01-29 00:06:02 +00:00
|
|
|
elementname = g_strdup_printf (" [%s]", GST_OBJECT_NAME (element));
|
2001-01-01 00:17:21 +00:00
|
|
|
|
|
|
|
fprintf(stderr,"INFO:%s%s %s\n",location,elementname,string);
|
|
|
|
|
|
|
|
if (location != empty) g_free(location);
|
|
|
|
if (elementname != empty) g_free(elementname);
|
2000-12-29 10:02:17 +00:00
|
|
|
|
|
|
|
g_free(string);
|
|
|
|
}
|
|
|
|
|
2001-01-04 22:16:06 +00:00
|
|
|
/**
|
|
|
|
* gst_info_set_categories:
|
|
|
|
* @categories: bitmask of INFO categories to enable
|
|
|
|
*
|
|
|
|
* Enable the output of INFO categories based on the given bitmask.
|
|
|
|
* The bit for any given category is (1 << GST_CAT_...).
|
|
|
|
*/
|
2001-01-01 00:17:21 +00:00
|
|
|
void
|
|
|
|
gst_info_set_categories (guint32 categories) {
|
|
|
|
_gst_info_categories = categories;
|
2001-01-01 05:18:07 +00:00
|
|
|
if (categories)
|
2001-01-11 00:33:51 +00:00
|
|
|
GST_INFO (0, "setting INFO categories to 0x%08X",categories);
|
2001-01-01 00:17:21 +00:00
|
|
|
}
|
2000-12-29 10:02:17 +00:00
|
|
|
|
2001-01-04 22:16:06 +00:00
|
|
|
/**
|
|
|
|
* gst_info_get_categories:
|
|
|
|
*
|
|
|
|
* Returns: the current bitmask of enabled INFO categories
|
|
|
|
* The bit for any given category is (1 << GST_CAT_...).
|
|
|
|
*/
|
2001-01-01 00:17:21 +00:00
|
|
|
guint32
|
|
|
|
gst_info_get_categories () {
|
|
|
|
return _gst_info_categories;
|
|
|
|
}
|
2000-12-29 10:02:17 +00:00
|
|
|
|
2001-01-04 22:16:06 +00:00
|
|
|
/**
|
|
|
|
* gst_info_enable_category:
|
|
|
|
* @category: the category to enable
|
|
|
|
*
|
|
|
|
* Enables the given GST_CAT_... INFO category.
|
|
|
|
*/
|
2001-01-01 00:17:21 +00:00
|
|
|
void
|
|
|
|
gst_info_enable_category (gint category) {
|
|
|
|
_gst_info_categories |= (1 << category);
|
2001-01-01 05:18:07 +00:00
|
|
|
if (_gst_info_categories)
|
2001-01-11 00:33:51 +00:00
|
|
|
GST_INFO (0, "setting INFO categories to 0x%08X",_gst_info_categories);
|
2001-01-01 00:17:21 +00:00
|
|
|
}
|
|
|
|
|
2001-01-04 22:16:06 +00:00
|
|
|
/**
|
|
|
|
* gst_info_disable_category:
|
|
|
|
* @category: the category to disable
|
|
|
|
*
|
|
|
|
* Disables the given GST_CAT_... INFO category.
|
|
|
|
*/
|
2001-01-01 00:17:21 +00:00
|
|
|
void
|
|
|
|
gst_info_disable_category (gint category) {
|
|
|
|
_gst_info_categories &= ~ (1 << category);
|
2001-01-01 05:18:07 +00:00
|
|
|
if (_gst_info_categories)
|
2001-01-11 00:33:51 +00:00
|
|
|
GST_INFO (0, "setting INFO categories to 0x%08X",_gst_info_categories);
|
2001-01-01 00:17:21 +00:00
|
|
|
}
|
|
|
|
|
2001-01-01 05:18:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
/***** DEBUG system *****/
|
|
|
|
guint32 _gst_debug_categories = 0x00000000;
|
|
|
|
|
|
|
|
|
2001-01-04 22:16:06 +00:00
|
|
|
/**
|
|
|
|
* gst_debug_set_categories:
|
|
|
|
* @categories: bitmask of DEBUG categories to enable
|
|
|
|
*
|
|
|
|
* Enable the output of DEBUG categories based on the given bitmask.
|
|
|
|
* The bit for any given category is (1 << GST_CAT_...).
|
|
|
|
*/
|
2001-01-01 04:53:26 +00:00
|
|
|
void
|
|
|
|
gst_debug_set_categories (guint32 categories) {
|
|
|
|
_gst_debug_categories = categories;
|
2001-01-01 05:18:07 +00:00
|
|
|
if (categories)
|
2001-01-11 00:33:51 +00:00
|
|
|
GST_INFO (0, "setting DEBUG categories to 0x%08X",categories);
|
2001-01-01 04:53:26 +00:00
|
|
|
}
|
|
|
|
|
2001-01-04 22:16:06 +00:00
|
|
|
/**
|
|
|
|
* gst_debug_get_categories:
|
|
|
|
*
|
|
|
|
* Returns: the current bitmask of enabled DEBUG categories
|
|
|
|
* The bit for any given category is (1 << GST_CAT_...).
|
|
|
|
*/
|
2001-01-01 04:53:26 +00:00
|
|
|
guint32
|
|
|
|
gst_debug_get_categories () {
|
|
|
|
return _gst_debug_categories;
|
|
|
|
}
|
|
|
|
|
2001-01-04 22:16:06 +00:00
|
|
|
/**
|
|
|
|
* gst_debug_enable_category:
|
|
|
|
* @category: the category to enable
|
|
|
|
*
|
|
|
|
* Enables the given GST_CAT_... DEBUG category.
|
|
|
|
*/
|
2001-01-01 04:53:26 +00:00
|
|
|
void
|
|
|
|
gst_debug_enable_category (gint category) {
|
|
|
|
_gst_debug_categories |= (1 << category);
|
2001-01-01 05:18:07 +00:00
|
|
|
if (_gst_debug_categories)
|
2001-01-11 00:33:51 +00:00
|
|
|
GST_INFO (0, "setting DEBUG categories to 0x%08X",_gst_debug_categories);
|
2001-01-01 04:53:26 +00:00
|
|
|
}
|
|
|
|
|
2001-01-04 22:16:06 +00:00
|
|
|
/**
|
|
|
|
* gst_debug_disable_category:
|
|
|
|
* @category: the category to disable
|
|
|
|
*
|
|
|
|
* Disables the given GST_CAT_... DEBUG category.
|
|
|
|
*/
|
2001-01-01 04:53:26 +00:00
|
|
|
void
|
|
|
|
gst_debug_disable_category (gint category) {
|
|
|
|
_gst_debug_categories &= ~ (1 << category);
|
2001-01-01 05:18:07 +00:00
|
|
|
if (_gst_debug_categories)
|
2001-01-11 00:33:51 +00:00
|
|
|
GST_INFO (0, "setting DEBUG categories to 0x%08X",_gst_debug_categories);
|
2001-01-01 04:53:26 +00:00
|
|
|
}
|
|
|
|
|
2001-01-04 22:16:06 +00:00
|
|
|
/**
|
|
|
|
* gst_get_category_name:
|
|
|
|
* @category: the category to return the name of
|
|
|
|
*
|
|
|
|
* Returns: string containing the name of the category
|
|
|
|
*/
|
2001-01-01 04:53:26 +00:00
|
|
|
const gchar *
|
|
|
|
gst_get_category_name (gint category) {
|
|
|
|
if ((category >= 0) && (category < GST_CAT_MAX_CATEGORY))
|
|
|
|
return _gst_info_category_strings[category];
|
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2001-01-01 00:17:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
/***** ERROR system *****/
|
|
|
|
GstErrorHandler _gst_error_handler = gst_default_error_handler;
|
2000-12-29 10:02:17 +00:00
|
|
|
|
2001-01-04 22:16:06 +00:00
|
|
|
/**
|
|
|
|
* gst_default_error_handler:
|
|
|
|
* @file: the file the ERROR occurs in
|
|
|
|
* @function: the function the INFO occurs in
|
|
|
|
* @line: the line number in the file
|
|
|
|
* @debug_string: the current debug_string in the function, if any
|
|
|
|
* @element: pointer to the #GstElement in question
|
|
|
|
* @object: pointer to a related object
|
|
|
|
* @string: the actual ERROR string
|
|
|
|
*
|
|
|
|
* Prints out the given ERROR string in a variant of the following format:
|
|
|
|
*
|
|
|
|
* ***** GStreamer ERROR ***** in file gstsomething.c at gst_function:399(arg)
|
|
|
|
* Element: /pipeline/thread/element.src
|
|
|
|
* Error: peer is null!
|
|
|
|
* ***** attempting to stack trace.... *****
|
|
|
|
*
|
|
|
|
* At the end, it attempts to print the stack trace via GDB.
|
|
|
|
*/
|
2000-12-29 10:02:17 +00:00
|
|
|
void
|
|
|
|
gst_default_error_handler (gchar *file, gchar *function,
|
|
|
|
gint line, gchar *debug_string,
|
|
|
|
void *element, void *object, gchar *string)
|
|
|
|
{
|
|
|
|
int chars = 0;
|
|
|
|
gchar *path;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
// if there are NULL pointers, point them to null strings to clean up output
|
|
|
|
if (!debug_string) debug_string = "";
|
|
|
|
if (!string) string = "";
|
|
|
|
|
|
|
|
// print out a preamble
|
|
|
|
fprintf(stderr,"***** GStreamer ERROR ***** in file %s at %s:%d%s\n",
|
|
|
|
file,function,line,debug_string);
|
|
|
|
|
|
|
|
// if there's an element, print out the pertinent information
|
|
|
|
if (element) {
|
2000-12-31 22:18:05 +00:00
|
|
|
if (GST_IS_OBJECT(element)) {
|
2000-12-29 10:02:17 +00:00
|
|
|
path = gst_object_get_path_string(element);
|
|
|
|
fprintf(stderr,"Element: %s",path);
|
|
|
|
chars = 9 + strlen(path);
|
|
|
|
g_free(path);
|
|
|
|
} else {
|
|
|
|
fprintf(stderr,"Element ptr: %p",element);
|
|
|
|
chars = 15 + sizeof(void*)*2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if there's an object, print it out as well
|
|
|
|
if (object) {
|
|
|
|
// attempt to pad the line, or create a new one
|
|
|
|
if (chars < 40)
|
|
|
|
for (i=0;i<(40-chars)/8+1;i++) fprintf(stderr,"\t");
|
|
|
|
else
|
|
|
|
fprintf(stderr,"\n");
|
|
|
|
|
|
|
|
if (GST_IS_OBJECT(object)) {
|
|
|
|
path = gst_object_get_path_string(object);
|
|
|
|
fprintf(stderr,"Object: %s",path);
|
|
|
|
g_free(path);
|
|
|
|
} else {
|
|
|
|
fprintf(stderr,"Object ptr: %p",object);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(stderr,"\n");
|
|
|
|
fprintf(stderr,"Error: %s\n",string);
|
|
|
|
|
|
|
|
g_free(string);
|
|
|
|
|
|
|
|
fprintf(stderr,"***** attempting to stack trace.... *****\n");
|
|
|
|
|
|
|
|
g_on_error_stack_trace (_gst_progname);
|
|
|
|
|
|
|
|
exit(1);
|
|
|
|
}
|