]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/gstreamer0-10.git/blob - gst/gst.c
de123f6919293ce5ac51651f390c356993f20f55
[glsdk/gstreamer0-10.git] / gst / gst.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *
5  * gst.c: Initialization and non-pipeline operations
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  */
23 #include <stdlib.h>
24 #include <stdio.h>
26 #include "gst_private.h"
27 #include "gst-i18n-lib.h"
28 #include <locale.h>             /* for LC_ALL */
30 #include "gst.h"
31 #include "gstqueue.h"
32 #ifndef GST_DISABLE_REGISTRY
33 #include "registries/gstxmlregistry.h"
34 #endif /* GST_DISABLE_REGISTRY */
35 #include "gstregistrypool.h"
37 #define GST_CAT_DEFAULT GST_CAT_GST_INIT
39 #define MAX_PATH_SPLIT  16
40 #define GST_PLUGIN_SEPARATOR ","
42 gchar *_gst_progname;
44 #ifndef GST_DISABLE_REGISTRY
45 gboolean _gst_registry_auto_load = TRUE;
46 static GstRegistry *_global_registry;
47 static GstRegistry *_user_registry;
48 static gboolean _gst_registry_fixed = FALSE;
49 #endif
51 static gboolean _gst_use_threads = TRUE;
53 static gboolean _gst_enable_cpu_opt = TRUE;
55 static gboolean gst_initialized = FALSE;
56 /* this will be set in popt callbacks when a problem has been encountered */
57 static gboolean _gst_initialization_failure = FALSE;
58 extern gint _gst_trace_on;
60 /* set to TRUE when segfaults need to be left as is */
61 gboolean _gst_disable_segtrap = FALSE;
63 extern GThreadFunctions gst_thread_dummy_functions;
66 static void     load_plugin_func        (gpointer data, gpointer user_data);
67 static void     init_popt_callback      (poptContext context,
68                                          enum poptCallbackReason reason,
69                                          const GstPoptOption *option,
70                                          const char *arg, void *data);
71 static gboolean init_pre                (void);
72 static gboolean init_post               (void);
74 static GSList *preload_plugins = NULL;
76 const gchar *g_log_domain_gstreamer = "GStreamer";
78 static void
79 debug_log_handler (const gchar *log_domain,
80                    GLogLevelFlags log_level,
81                    const gchar *message,
82                    gpointer user_data)
83 {
84   g_log_default_handler (log_domain, log_level, message, user_data);
85   /* FIXME: do we still need this ? fatal errors these days are all
86    * other than core errors */
87   /* g_on_error_query (NULL); */
88 }
90 enum {
91   ARG_VERSION=1,
92   ARG_FATAL_WARNINGS,
93 #ifndef GST_DISABLE_GST_DEBUG
94   ARG_DEBUG_LEVEL,
95   ARG_DEBUG,
96   ARG_DEBUG_DISABLE,
97   ARG_DEBUG_NO_COLOR,
98   ARG_DEBUG_HELP,
99 #endif
100   ARG_DISABLE_CPU_OPT,
101   ARG_PLUGIN_SPEW,
102   ARG_PLUGIN_PATH,
103   ARG_PLUGIN_LOAD,
104   ARG_SEGTRAP_DISABLE,
105   ARG_SCHEDULER,
106   ARG_REGISTRY
107 };
109 #ifndef NUL
110 #define NUL '\0'
111 #endif
113 /* default scheduler, can be changed in gstscheduler.h with
114  * the GST_SCHEDULER_DEFAULT_NAME define.
115  */
116 static const GstPoptOption gstreamer_options[] = {
117   {NULL, NUL, POPT_ARG_CALLBACK|POPT_CBFLAG_PRE|POPT_CBFLAG_POST, (void *) &init_popt_callback, 0, NULL, NULL},
118   /* make sure we use our GETTEXT_PACKAGE as the domain for popt translations */
119   {NULL, NUL, POPT_ARG_INTL_DOMAIN, GETTEXT_PACKAGE, 0, NULL, NULL},
120   {"gst-version",        NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP,   NULL, ARG_VERSION,        N_("Print the GStreamer version"), NULL},
121   {"gst-fatal-warnings", NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP,   NULL, ARG_FATAL_WARNINGS, N_("Make all warnings fatal"), NULL},
123 #ifndef GST_DISABLE_GST_DEBUG
124   {"gst-debug-help",     NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP,   NULL, ARG_DEBUG_HELP,     N_("Print available debug categories and exit"), NULL},
125   {"gst-debug-level",    NUL, POPT_ARG_INT|POPT_ARGFLAG_STRIP,    NULL, ARG_DEBUG_LEVEL,  N_("Default debug level from 1 (only error) to 5 (anything) or 0 for no output"), N_("LEVEL")},
126   {"gst-debug",          NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_DEBUG,          N_("Comma-separated list of category_name:level pairs to set specific levels for the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3"), N_("LIST")},
127   {"gst-debug-no-color", NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP,   NULL, ARG_DEBUG_NO_COLOR, N_("Disable colored debugging output"), NULL},
128   {"gst-debug-disable",  NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP,   NULL, ARG_DEBUG_DISABLE,  N_("Disable debugging")},
129 #endif
131   {"gst-disable-cpu-opt",NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP,   NULL, ARG_DISABLE_CPU_OPT,N_("Disable accelerated CPU instructions"), NULL},
132   {"gst-plugin-spew",    NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP,   NULL, ARG_PLUGIN_SPEW,    N_("Enable verbose plugin loading diagnostics"), NULL},
133   {"gst-plugin-path",    NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_PLUGIN_PATH,    N_("path list for loading plugins (separated by '" G_SEARCHPATH_SEPARATOR_S "')"),N_("PATHS")},
134   {"gst-plugin-load",    NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_PLUGIN_LOAD,    N_("Comma-separated list of plugins to preload in addition to the list stored in env variable GST_PLUGIN_PATH"), N_("PLUGINS")},
135   {"gst-disable-segtrap",NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP,   NULL, ARG_SEGTRAP_DISABLE,N_("Disable trapping of segmentation faults during plugin loading"), NULL},
136   {"gst-scheduler",      NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_SCHEDULER,      N_("Scheduler to use ('"GST_SCHEDULER_DEFAULT_NAME"' is the default)"), N_("SCHEDULER")},
137   {"gst-registry",       NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_REGISTRY,       N_("Registry to use") , N_("REGISTRY")},
138   POPT_TABLEEND
139 };
141 /**
142  * gst_init_get_popt_table:
143  *
144  * Returns a popt option table with GStreamer's argument specifications. The
145  * table is set up to use popt's callback method, so whenever the parsing is
146  * actually performed (via poptGetContext), the GStreamer libraries will
147  * be initialized.
148  *
149  * This function is useful if you want to integrate GStreamer with other
150  * libraries that use popt.
151  *
152  * Returns: a pointer to the static GStreamer option table.
153  * No free is necessary.
154  */
155 const GstPoptOption *
156 gst_init_get_popt_table (void)
158   return gstreamer_options;
161 /**
162  * gst_init_check:
163  * @argc: pointer to application's argc
164  * @argv: pointer to application's argv
165  *
166  * Initializes the GStreamer library, setting up internal path lists,
167  * registering built-in elements, and loading standard plugins.
168  *
169  * This function will return %FALSE if GStreamer could not be initialized
170  * for some reason.  If you want your program to fail fatally,
171  * use gst_init() instead.
172  *
173  * Returns: %TRUE if GStreamer could be initialized.
174  */
175 gboolean
176 gst_init_check (int *argc, char **argv[])
178   return gst_init_check_with_popt_table (argc, argv, NULL);
181 /**
182  * gst_init:
183  * @argc: pointer to application's argc
184  * @argv: pointer to application's argv
185  *
186  * Initializes the GStreamer library, setting up internal path lists,
187  * registering built-in elements, and loading standard plugins.
188  *
189  * This function will terminate your program if it was unable to initialize
190  * GStreamer for some reason.  If you want your program to fall back,
191  * use gst_init_check() instead.
192  */
193 void
194 gst_init (int *argc, char **argv[])
196   gst_init_with_popt_table (argc, argv, NULL);
199 /**
200  * gst_init_with_popt_table:
201  * @argc: pointer to application's argc
202  * @argv: pointer to application's argv
203  * @popt_options: pointer to a popt table to append
204  *
205  * Initializes the GStreamer library, parsing the options,
206  * setting up internal path lists,
207  * registering built-in elements, and loading standard plugins.
208  *
209  * This function will terminate your program if it was unable to initialize
210  * GStreamer for some reason.  If you want your program to fall back,
211  * use gst_init_check_with_popt_table() instead.
212  */
213 void
214 gst_init_with_popt_table (int *argc, char **argv[],
215                           const GstPoptOption *popt_options)
217   if (!gst_init_check_with_popt_table (argc, argv, popt_options)) {
218     g_print ("Could not initialize GStreamer !\n");
219     exit (1);
220   }
222 /**
223  * gst_init_check_with_popt_table:
224  * @argc: pointer to application's argc
225  * @argv: pointer to application's argv
226  * @popt_options: pointer to a popt table to append
227  *
228  * Initializes the GStreamer library, parsing the options,
229  * setting up internal path lists,
230  * registering built-in elements, and loading standard plugins.
231  *
232  * Returns: %TRUE if GStreamer could be initialized.
233  */
234 gboolean
235 gst_init_check_with_popt_table (int *argc, char **argv[],
236                                 const GstPoptOption *popt_options)
238   poptContext context;
239   gint nextopt;
240   GstPoptOption *options;
241   GstPoptOption options_with[] = {
242     {NULL, NUL, POPT_ARG_INCLUDE_TABLE, poptHelpOptions,                                 0, "Help options:", NULL},
243     {NULL, NUL, POPT_ARG_INCLUDE_TABLE, (GstPoptOption *) gstreamer_options,     0, "GStreamer options:", NULL},
244     {NULL, NUL, POPT_ARG_INCLUDE_TABLE, (GstPoptOption *) popt_options,                  0, "Application options:", NULL},
245     POPT_TABLEEND
246   };
247   GstPoptOption options_without[] = {
248     {NULL, NUL, POPT_ARG_INCLUDE_TABLE, poptHelpOptions,                                 0, "Help options:", NULL},
249     {NULL, NUL, POPT_ARG_INCLUDE_TABLE, (GstPoptOption *) gstreamer_options,     0, "GStreamer options:", NULL},
250     POPT_TABLEEND
251   };
253   if (gst_initialized)
254   {
255     GST_DEBUG ("already initialized gst");
256     return TRUE;
257   }
259   if (!argc || !argv) {
260     if (argc || argv)
261       g_warning ("gst_init: Only one of argc or argv was NULL");
263     if (!init_pre ()) return FALSE;
264     if (!init_post ()) return FALSE;
265     gst_initialized = TRUE;
266     return TRUE;
267   }
269   if (popt_options == NULL) {
270     options = options_without;
271   } else {
272     options = options_with;
273   }
274   context = poptGetContext ("GStreamer", *argc, (const char**)*argv,
275                             options, 0);
277   while ((nextopt = poptGetNextOpt (context)) > 0)
278   {
279     /* we only check for failures here, actual work is done in callbacks */
280     if (_gst_initialization_failure) return FALSE;
281   }
283   if (nextopt != -1) {
284     g_print ("Error on option %s: %s.\nRun '%s --help' "
285              "to see a full list of available command line options.\n",
286              poptBadOption (context, 0),
287              poptStrerror (nextopt),
288              (*argv)[0]);
290     poptFreeContext (context);
291     return FALSE;
292   }
294   *argc = poptStrippedArgv (context, *argc, *argv);
296   poptFreeContext (context);
298   return TRUE;
301 #ifndef GST_DISABLE_REGISTRY
302 static void
303 add_path_func (gpointer data, gpointer user_data)
305   GstRegistry *registry = GST_REGISTRY (user_data);
307   GST_INFO ("Adding plugin path: \"%s\"", (gchar *) data);
308   gst_registry_add_path (registry, (gchar *)data);
310 #endif
312 static void
313 prepare_for_load_plugin_func (gpointer data, gpointer user_data)
315   preload_plugins = g_slist_prepend (preload_plugins, data);
318 static void
319 parse_debug_list (const gchar *list)
321   gchar **split;
322   gchar **walk;
324   g_return_if_fail (list != NULL);
326   walk = split = g_strsplit (list, ",", 0);
328   while (walk[0]) {
329     gchar **values = g_strsplit ( walk[0], ":", 2);
330     if (values[0] && values[1]) {
331       gint level = 0;
332       g_strstrip (values[0]);
333       g_strstrip (values[1]);
334       level = strtol (values[1], NULL, 0);
335       if (level >= 0 && level < GST_LEVEL_COUNT) {
336         GST_DEBUG ("setting debugging to level %d for name \"%s\"",
337                        level, values[0]);
338         gst_debug_set_threshold_for_name (values[0], level);
339       }
340     }
341     g_strfreev (values);
342     walk++;
343   }
344   g_strfreev (split);
346 static void
347 load_plugin_func (gpointer data, gpointer user_data)
349   GstPlugin *plugin;
350   const gchar *filename;
352   filename = (const gchar *) data;
354   plugin = gst_plugin_load_file (filename, NULL);
356   if (plugin) {
357     GST_INFO ("Loaded plugin: \"%s\"", filename);
359     gst_registry_pool_add_plugin (plugin);
360   } else {
361     GST_WARNING ("Failed to load plugin: \"%s\"", filename);
362   }
364   g_free (data);
367 static void
368 split_and_iterate (const gchar *stringlist, gchar *separator, GFunc iterator, gpointer user_data)
370   gchar **strings;
371   gint j = 0;
372   gchar *lastlist = g_strdup (stringlist);
374   while (lastlist) {
375     strings = g_strsplit (lastlist, separator, MAX_PATH_SPLIT);
376     g_free (lastlist);
377     lastlist = NULL;
379     while (strings[j]) {
380       iterator (strings[j], user_data);
381       if (++j == MAX_PATH_SPLIT) {
382         lastlist = g_strdup (strings[j]);
383         g_strfreev (strings);
384         j=0;
385         break;
386       }
387     }
388   }
391 /* we have no fail cases yet, but maybe in the future */
392 static gboolean
393 init_pre (void)
395   g_type_init ();
397   if (g_thread_supported ()) {
398     /* somebody already initialized threading */
399     _gst_use_threads = TRUE;
400   } else {
401     if (_gst_use_threads)
402       g_thread_init (NULL);
403     else
404       g_thread_init (&gst_thread_dummy_functions);
405   }
406   /* we need threading to be enabled right here */
407   _gst_debug_init();
409 #ifdef ENABLE_NLS
410   setlocale (LC_ALL, "");
411   bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
412 #endif /* ENABLE_NLS */
414 #ifndef GST_DISABLE_REGISTRY
415   {
416     const gchar *debug_list;
418     debug_list = g_getenv ("GST_DEBUG");
419     if (debug_list) {
420       parse_debug_list (debug_list);
421     }
422   }
423 #endif
424 #ifndef GST_DISABLE_REGISTRY
425   {
426     gchar *user_reg;
427     const gchar *homedir;
429     _global_registry = gst_xml_registry_new ("global_registry", GLOBAL_REGISTRY_FILE);
431 #ifdef PLUGINS_USE_BUILDDIR
432     /* location libgstelements.so */
433     gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/libs/gst");
434     gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/elements");
435     gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/types");
436     gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/autoplug");
437     gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/schedulers");
438     gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/indexers");
439 #else
440     /* add the main (installed) library path */
441     gst_registry_add_path (_global_registry, PLUGINS_DIR);
442 #endif /* PLUGINS_USE_BUILDDIR */
444     if (g_getenv ("GST_REGISTRY"))
445     {
446       user_reg = g_strdup (g_getenv ("GST_REGISTRY"));
447     }
448     else
449     {
450       homedir = g_get_home_dir ();
451       user_reg = g_strjoin ("/", homedir, LOCAL_REGISTRY_FILE, NULL);
452     }
453     _user_registry = gst_xml_registry_new ("user_registry", user_reg);
455     g_free (user_reg);
456   }
457 #endif /* GST_DISABLE_REGISTRY */
459   return TRUE;
462 static gboolean
463 gst_register_core_elements (GstPlugin *plugin)
465   /* register some standard builtin types */
466   g_assert (gst_element_register (plugin, "bin", GST_RANK_PRIMARY, GST_TYPE_BIN));
467   g_assert (gst_element_register (plugin, "pipeline", GST_RANK_PRIMARY, GST_TYPE_PIPELINE));
468   g_assert (gst_element_register (plugin, "thread", GST_RANK_PRIMARY, GST_TYPE_THREAD));
469   g_assert (gst_element_register (plugin, "queue", GST_RANK_PRIMARY, GST_TYPE_QUEUE));
471   return TRUE;
474 static GstPluginDesc plugin_desc = {
475   GST_VERSION_MAJOR,
476   GST_VERSION_MINOR,
477   "gstcoreelements",
478   "core elements of the GStreamer library",
479   gst_register_core_elements,
480   NULL,
481   VERSION,
482   GST_LICENSE,
483   GST_PACKAGE,
484   GST_ORIGIN,
486   GST_PADDING_INIT
487 };
489 /*
490  * this bit handles:
491  * - initalization of threads if we use them
492  * - log handler
493  * - initial output
494  * - initializes gst_format
495  * - registers a bunch of types for gst_objects
496  *
497  * - we don't have cases yet where this fails, but in the future
498  *   we might and then it's nice to be able to return that
499  */
500 static gboolean
501 init_post (void)
503   GLogLevelFlags llf;
504   const gchar *plugin_path;
505 #ifndef GST_DISABLE_TRACE
506   GstTrace *gst_trace;
507 #endif /* GST_DISABLE_TRACE */
509   llf = G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL;
510   g_log_set_handler (g_log_domain_gstreamer, llf, debug_log_handler, NULL);
512   GST_INFO ("Initializing GStreamer Core Library version %s %s",
513             VERSION, _gst_use_threads ? "" : "(no threads)");
515   _gst_format_initialize ();
516   _gst_query_type_initialize ();
517   gst_object_get_type ();
518   gst_pad_get_type ();
519   gst_real_pad_get_type ();
520   gst_ghost_pad_get_type ();
521   gst_element_factory_get_type ();
522   gst_element_get_type ();
523   gst_scheduler_factory_get_type ();
524   gst_type_find_factory_get_type ();
525   gst_bin_get_type ();
526 #ifndef GST_DISABLE_INDEX
527   gst_index_factory_get_type ();
528 #endif /* GST_DISABLE_INDEX */
529 #ifndef GST_DISABLE_URI
530   gst_uri_handler_get_type ();
531 #endif /* GST_DISABLE_URI */
533   plugin_path = g_getenv ("GST_PLUGIN_PATH");
534 #ifndef GST_DISABLE_REGISTRY
535   split_and_iterate (plugin_path, G_SEARCHPATH_SEPARATOR_S, add_path_func, _user_registry);
536 #endif /* GST_DISABLE_REGISTRY */
538   /* register core plugins */
539   _gst_plugin_register_static (&plugin_desc);
541   _gst_cpu_initialize (_gst_enable_cpu_opt);
542   _gst_structure_initialize ();
543   _gst_value_initialize ();
544   _gst_caps_initialize ();
545   _gst_plugin_initialize ();
546   _gst_event_initialize ();
547   _gst_buffer_initialize ();
548   _gst_tag_initialize ();
550 #ifndef GST_DISABLE_REGISTRY
551   if (!_gst_registry_fixed) {
552     /* don't override command-line options */
553     if (g_getenv ("GST_REGISTRY")) {
554       g_object_set (_user_registry, "location", g_getenv ("GST_REGISTRY"), NULL);
555       _gst_registry_fixed = TRUE;
556     }
557   }
559   if (!_gst_registry_fixed) {
560     gst_registry_pool_add (_global_registry, 100);
561     gst_registry_pool_add (_user_registry, 50);
562   } else {
563     gst_registry_pool_add (_user_registry, 50);
564   }
566   if (_gst_registry_auto_load) {
567     gst_registry_pool_load_all ();
568   }
569 #endif /* GST_DISABLE_REGISTRY */
571   /* if we need to preload plugins */
572   if (preload_plugins) {
573     g_slist_foreach (preload_plugins, load_plugin_func, NULL);
574     g_slist_free (preload_plugins);
575     preload_plugins = NULL;
576   }
578 #ifndef GST_DISABLE_TRACE
579   _gst_trace_on = 0;
580   if (_gst_trace_on) {
581     gst_trace = gst_trace_new ("gst.trace", 1024);
582     gst_trace_set_default (gst_trace);
583   }
584 #endif /* GST_DISABLE_TRACE */
585   if (_gst_progname == NULL) {
586     _gst_progname = g_strdup ("gstprog");
587   }
589   return TRUE;
592 #ifndef GST_DISABLE_GST_DEBUG
593 static gint
594 sort_by_category_name (gconstpointer a, gconstpointer b)
596   return strcmp (gst_debug_category_get_name ((GstDebugCategory *) a),
597                  gst_debug_category_get_name ((GstDebugCategory *) b));
599 static void
600 gst_debug_help (void)
602   GSList *list, *walk;
603   GList *list2, *walk2;
605   if (!init_post ())
606     exit (1);
608   walk2 = list2 = gst_registry_pool_plugin_list ();
609   while (walk2) {
610     GstPlugin *plugin = GST_PLUGIN (walk2->data);
611     walk2 = g_list_next (walk2);
613     if (!gst_plugin_is_loaded (plugin)) {
614 #ifndef GST_DISABLE_REGISTRY
615       if (GST_IS_REGISTRY (plugin->manager)) {
616         GST_CAT_LOG (GST_CAT_PLUGIN_LOADING, "loading plugin %s", plugin->desc.name);
617         if (gst_registry_load_plugin (GST_REGISTRY (plugin->manager), plugin) != GST_REGISTRY_OK)
618           GST_CAT_WARNING (GST_CAT_PLUGIN_LOADING, "loading plugin %s failed", plugin->desc.name);
619       }
620 #endif /* GST_DISABLE_REGISTRY */
621     }
622   }
623   g_list_free (list2);
625   list = gst_debug_get_all_categories ();
626   walk = list = g_slist_sort (list, sort_by_category_name);
628   g_print ("\n");
629   g_print ("name                  level    description\n");
630   g_print ("---------------------+--------+--------------------------------\n");
632   while (walk) {
633     GstDebugCategory *cat = (GstDebugCategory *) walk->data;
635     if (gst_debug_is_colored ()) {
636       gchar *color = gst_debug_construct_term_color (cat->color);
637       g_print ("%s%-20s\033[00m  %1d %s  %s%s\033[00m\n",
638                color,
639                gst_debug_category_get_name (cat),
640                gst_debug_category_get_threshold (cat),
641                gst_debug_level_get_name (gst_debug_category_get_threshold (cat)),
642                color,
643                gst_debug_category_get_description (cat));
644       g_free (color);
645     } else {
646       g_print ("%-20s  %1d %s  %s\n", gst_debug_category_get_name (cat),
647                gst_debug_category_get_threshold (cat),
648                gst_debug_level_get_name (gst_debug_category_get_threshold (cat)),
649                gst_debug_category_get_description (cat));
650     }
651     walk = g_slist_next (walk);
652   }
653   g_slist_free (list);
654   g_print ("\n");
656 #endif
658 static void
659 init_popt_callback (poptContext context, enum poptCallbackReason reason,
660                     const GstPoptOption *option, const char *arg, void *data)
662   GLogLevelFlags fatal_mask;
664   if (gst_initialized)
665     return;
666   switch (reason) {
667   case POPT_CALLBACK_REASON_PRE:
668     if (!init_pre ()) _gst_initialization_failure = TRUE;
669     break;
670   case POPT_CALLBACK_REASON_OPTION:
671     switch (option->val) {
672     case ARG_VERSION:
673       g_print ("GStreamer Core Library version %s\n", GST_VERSION);
674       exit (0);
675     case ARG_FATAL_WARNINGS:
676       fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
677       fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
678       g_log_set_always_fatal (fatal_mask);
679       break;
680 #ifndef GST_DISABLE_GST_DEBUG
681     case ARG_DEBUG_LEVEL: {
682       gint tmp = 0;
683       tmp = strtol (arg, NULL, 0);
684       if (tmp >= 0 && tmp < GST_LEVEL_COUNT) {
685         gst_debug_set_default_threshold (tmp);
686       }
687       break;
688     }
689     case ARG_DEBUG:
690       parse_debug_list (arg);
691       break;
692     case ARG_DEBUG_NO_COLOR:
693       gst_debug_set_colored (FALSE);
694       break;
695     case ARG_DEBUG_DISABLE:
696       gst_debug_set_active (FALSE);
697       break;
698     case ARG_DEBUG_HELP:
699       gst_debug_help ();
700       exit (0);
701 #endif
702     case ARG_DISABLE_CPU_OPT:
703       _gst_enable_cpu_opt = FALSE;
704       break;
705     case ARG_PLUGIN_SPEW:
706       break;
707     case ARG_PLUGIN_PATH:
708 #ifndef GST_DISABLE_REGISTRY
709       split_and_iterate (arg, G_SEARCHPATH_SEPARATOR_S, add_path_func, _user_registry);
710 #endif /* GST_DISABLE_REGISTRY */
711       break;
712     case ARG_PLUGIN_LOAD:
713       split_and_iterate (arg, ",", prepare_for_load_plugin_func, NULL);
714       break;
715     case ARG_SEGTRAP_DISABLE:
716       _gst_disable_segtrap = TRUE;
717       break;
718     case ARG_SCHEDULER:
719       gst_scheduler_factory_set_default_name (arg);
720       break;
721     case ARG_REGISTRY:
722 #ifndef GST_DISABLE_REGISTRY
723       g_object_set (G_OBJECT (_user_registry), "location", arg, NULL);
724       _gst_registry_fixed = TRUE;
725 #endif /* GST_DISABLE_REGISTRY */
726       break;
727     default:
728       g_warning ("option %d not recognized", option->val);
729       break;
730     }
731     break;
732   case POPT_CALLBACK_REASON_POST:
733     if (!init_post ()) _gst_initialization_failure = TRUE;
734     gst_initialized = TRUE;
735     break;
736   }
739 /**
740  * gst_use_threads:
741  * @use_threads: a #gboolean indicating whether threads should be used
742  *
743  * Instructs the core to turn on/off threading. When threading
744  * is turned off, all thread operations such as mutexes and conditionals
745  * are turned into NOPs. use this if you want absolute minimal overhead
746  * and you don't use any threads in the pipeline.
747  * <note><para>
748  * This function may only be called before threads are initialized. This
749  * usually happens when calling gst_init.
750  * </para></note>
751  */
752 void
753 gst_use_threads (gboolean use_threads)
755   g_return_if_fail (!gst_initialized);
756   g_return_if_fail (g_thread_supported ());
758   _gst_use_threads = use_threads;
761 /**
762  * gst_has_threads:
763  *
764  * Queries if GStreamer has threads enabled.
765  *
766  * Returns: %TRUE if threads are enabled.
767  */
768 gboolean
769 gst_has_threads (void)
771   return _gst_use_threads;
775 static GSList *mainloops = NULL;
777 /**
778  * gst_main:
779  *
780  * Enters the main GStreamer processing loop.
781  */
782 void
783 gst_main (void)
785   GMainLoop *loop;
787   loop = g_main_loop_new (NULL, FALSE);
788   mainloops = g_slist_prepend (mainloops, loop);
790   g_main_loop_run (loop);
793 /**
794  * gst_main_quit:
795  *
796  * Exits the main GStreamer processing loop.
797  */
798 void
799 gst_main_quit (void)
801   if (!mainloops)
802     g_error ("Quit more loops than there are");
803   else {
804     GMainLoop *loop = mainloops->data;
805     mainloops = g_slist_delete_link (mainloops, mainloops);
806     g_main_loop_quit (loop);
807     g_main_loop_unref (loop);
808   }
811 /**
812  * gst_version:
813  * @major: pointer to a guint to store the major version number
814  * @minor: pointer to a guint to store the minor version number
815  * @micro: pointer to a guint to store the micro version number
816  *
817  * Gets the version number of the GStreamer library.
818  */
819 void
820 gst_version (guint *major, guint *minor, guint *micro)
822   g_return_if_fail (major);
823   g_return_if_fail (minor);
824   g_return_if_fail (micro);
826   *major = GST_VERSION_MAJOR;
827   *minor = GST_VERSION_MINOR;
828   *micro = GST_VERSION_MICRO;