gst/gst.c: Make _gst_disable_segtrap static, it's only used in gstplugin.c and we...
[platform/upstream/gstreamer.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  */
22
23 /**
24  * SECTION:gst
25  * @short_description: Media library supporting arbitrary formats and filter
26  *                     graphs.
27  * @see_also: Check out both <ulink url="http://www.cse.ogi.edu/sysl/">OGI's
28  *            pipeline</ulink> and Microsoft's DirectShow for some background.
29  *
30  * GStreamer is a framework for constructing graphs of various filters
31  * (termed elements here) that will handle streaming media.  Any discreet
32  * (packetizable) media type is supported, with provisions for automatically
33  * determining source type.  Formatting/framing information is provided with
34  * a powerful negotiation framework.  Plugins are heavily used to provide for
35  * all elements, allowing one to construct plugins outside of the GST
36  * library, even released binary-only if license require (please don't).
37  *
38  * GStreamer borrows heavily from both the <ulink
39  * url="http://www.cse.ogi.edu/sysl/">OGI media pipeline</ulink> and
40  * Microsoft's DirectShow, hopefully taking the best of both and leaving the
41  * cruft behind. Its interface is slowly getting stable.
42  *
43  * The <application>GStreamer</application> library should be initialized with
44  * gst_init() before it can be used. You should pass pointers to the main argc
45  * and argv variables so that GStreamer can process its own command line
46  * options, as shown in the following example.
47  *
48  * <example>
49  * <title>Initializing the gstreamer library</title>
50  * <programlisting language="c">
51  * int
52  * main (int argc, char *argv[])
53  * {
54  *   // initialize the GStreamer library
55  *   gst_init (&amp;argc, &amp;argv);
56  *   ...
57  * }
58  * </programlisting>
59  * </example>
60  *
61  * It's allowed to pass two NULL pointers to gst_init() in case you don't want
62  * to pass the command line args to GStreamer.
63  *
64  * You can also use GOption to initialize your own parameters as shown in
65  * the next code fragment:
66  * <example>
67  * <title>Initializing own parameters when initializing gstreamer</title>
68  * <programlisting>
69  * static gboolean stats = FALSE;
70  * ...
71  * int
72  * main (int argc, char *argv[])
73  * {
74  *  GOptionEntry options[] = {
75  *   {"tags", 't', 0, G_OPTION_ARG_NONE, &amp;tags,
76  *       N_("Output tags (also known as metadata)"), NULL},
77  *   {NULL}
78  *  };
79  *  // must initialise the threading system before using any other GLib funtion
80  *  if (!g_thread_supported ())
81  *    g_thread_init (NULL);
82  *  ctx = g_option_context_new ("[ADDITIONAL ARGUMENTS]");
83  *  g_option_context_add_main_entries (ctx, options, GETTEXT_PACKAGE);
84  *  g_option_context_add_group (ctx, gst_init_get_option_group ());
85  *  if (!g_option_context_parse (ctx, &amp;argc, &amp;argv, &amp;err)) {
86  *    g_print ("Error initializing: &percnt;s\n", GST_STR_NULL (err->message));
87  *    exit (1);
88  *  }
89  *  g_option_context_free (ctx);
90  * ...
91  * }
92  * </programlisting>
93  * </example>
94  *
95  * Use gst_version() to query the library version at runtime or use the
96  * GST_VERSION_* macros to find the version at compile time. Optionally
97  * gst_version_string() returns a printable string.
98  *
99  * The gst_deinit() call is used to clean up all internal resources used
100  * by <application>GStreamer</application>. It is mostly used in unit tests 
101  * to check for leaks.
102  *
103  * Last reviewed on 2006-08-11 (0.10.10)
104  */
105
106 #include "gst_private.h"
107 #include <stdlib.h>
108 #include <stdio.h>
109 #include <sys/types.h>
110 #ifdef HAVE_FORK
111 #include <sys/wait.h>
112 #endif /* HAVE_FORK */
113 #ifdef HAVE_SYS_UTSNAME_H
114 #include <sys/utsname.h>
115 #endif
116 #ifdef HAVE_UNISTD_H
117 #include <unistd.h>
118 #endif
119
120 #include "gst-i18n-lib.h"
121 #include <locale.h>             /* for LC_ALL */
122
123 #include "gst.h"
124
125 #define GST_CAT_DEFAULT GST_CAT_GST_INIT
126
127 #define MAX_PATH_SPLIT  16
128 #define GST_PLUGIN_SEPARATOR ","
129
130 static gboolean gst_initialized = FALSE;
131
132 #ifndef GST_DISABLE_REGISTRY
133 static GList *plugin_paths = NULL;      /* for delayed processing in post_init */
134 #endif
135
136 extern gint _gst_trace_on;
137
138 /* defaults */
139 #ifdef HAVE_FORK
140 #define DEFAULT_FORK TRUE
141 #else
142 #define DEFAULT_FORK FALSE
143 #endif /* HAVE_FORK */
144
145 /* set to TRUE when segfaults need to be left as is */
146 static gboolean _gst_disable_segtrap = FALSE;
147
148 /* control the behaviour of registry rebuild */
149 static gboolean _gst_enable_registry_fork = DEFAULT_FORK;
150
151 static void load_plugin_func (gpointer data, gpointer user_data);
152 static gboolean init_pre (GOptionContext * context, GOptionGroup * group,
153     gpointer data, GError ** error);
154 static gboolean init_post (GOptionContext * context, GOptionGroup * group,
155     gpointer data, GError ** error);
156 #ifndef GST_DISABLE_OPTION_PARSING
157 static gboolean parse_goption_arg (const gchar * s_opt,
158     const gchar * arg, gpointer data, GError ** err);
159 #endif
160
161 static GSList *preload_plugins = NULL;
162
163 const gchar g_log_domain_gstreamer[] = "GStreamer";
164
165 static void
166 debug_log_handler (const gchar * log_domain,
167     GLogLevelFlags log_level, const gchar * message, gpointer user_data)
168 {
169   g_log_default_handler (log_domain, log_level, message, user_data);
170   /* FIXME: do we still need this ? fatal errors these days are all
171    * other than core errors */
172   /* g_on_error_query (NULL); */
173 }
174
175 enum
176 {
177   ARG_VERSION = 1,
178   ARG_FATAL_WARNINGS,
179 #ifndef GST_DISABLE_GST_DEBUG
180   ARG_DEBUG_LEVEL,
181   ARG_DEBUG,
182   ARG_DEBUG_DISABLE,
183   ARG_DEBUG_NO_COLOR,
184   ARG_DEBUG_HELP,
185 #endif
186   ARG_PLUGIN_SPEW,
187   ARG_PLUGIN_PATH,
188   ARG_PLUGIN_LOAD,
189   ARG_SEGTRAP_DISABLE,
190   ARG_REGISTRY_FORK_DISABLE
191 };
192
193 /* debug-spec ::= category-spec [, category-spec]*
194  * category-spec ::= category:val | val
195  * category ::= [^:]+
196  * val ::= [0-5]
197  */
198
199 #ifndef NUL
200 #define NUL '\0'
201 #endif
202
203 #ifndef GST_DISABLE_GST_DEBUG
204 static gboolean
205 parse_debug_category (gchar * str, const gchar ** category)
206 {
207   if (!str)
208     return FALSE;
209
210   /* works in place */
211   g_strstrip (str);
212
213   if (str[0] != NUL) {
214     *category = str;
215     return TRUE;
216   }
217
218   return FALSE;
219 }
220
221 static gboolean
222 parse_debug_level (gchar * str, gint * level)
223 {
224   if (!str)
225     return FALSE;
226
227   /* works in place */
228   g_strstrip (str);
229
230   if (str[0] != NUL && str[1] == NUL
231       && str[0] >= '0' && str[0] < '0' + GST_LEVEL_COUNT) {
232     *level = str[0] - '0';
233     return TRUE;
234   }
235
236   return FALSE;
237 }
238
239 static void
240 parse_debug_list (const gchar * list)
241 {
242   gchar **split;
243   gchar **walk;
244
245   g_return_if_fail (list != NULL);
246
247   split = g_strsplit (list, ",", 0);
248
249   for (walk = split; *walk; walk++) {
250     if (strchr (*walk, ':')) {
251       gchar **values = g_strsplit (*walk, ":", 2);
252
253       if (values[0] && values[1]) {
254         gint level;
255         const gchar *category;
256
257         if (parse_debug_category (values[0], &category)
258             && parse_debug_level (values[1], &level))
259           gst_debug_set_threshold_for_name (category, level);
260       }
261
262       g_strfreev (values);
263     } else {
264       gint level;
265
266       if (parse_debug_level (*walk, &level))
267         gst_debug_set_default_threshold (level);
268     }
269   }
270
271   g_strfreev (split);
272 }
273 #endif
274
275 /**
276  * gst_init_get_option_group:
277  *
278  * Returns a #GOptionGroup with GStreamer's argument specifications. The
279  * group is set up to use standard GOption callbacks, so when using this
280  * group in combination with GOption parsing methods, all argument parsing
281  * and initialization is automated.
282  *
283  * This function is useful if you want to integrate GStreamer with other
284  * libraries that use GOption (see g_option_context_add_group() ).
285  *
286  * If you use this function, you should make sure you initialise the GLib
287  * threading system as one of the very first things in your program
288  * (see the example at the beginning of this section).
289  *
290  * Returns: a pointer to GStreamer's option group.
291  */
292
293 GOptionGroup *
294 gst_init_get_option_group (void)
295 {
296 #ifndef GST_DISABLE_OPTION_PARSING
297   GOptionGroup *group;
298   const static GOptionEntry gst_args[] = {
299     {"gst-version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
300         (gpointer) parse_goption_arg, N_("Print the GStreamer version"), NULL},
301     {"gst-fatal-warnings", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
302         (gpointer) parse_goption_arg, N_("Make all warnings fatal"), NULL},
303 #ifndef GST_DISABLE_GST_DEBUG
304     {"gst-debug-help", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
305           (gpointer) parse_goption_arg,
306           N_("Print available debug categories and exit"),
307         NULL},
308     {"gst-debug-level", 0, 0, G_OPTION_ARG_CALLBACK,
309           (gpointer) parse_goption_arg,
310           N_("Default debug level from 1 (only error) to 5 (anything) or "
311               "0 for no output"),
312         N_("LEVEL")},
313     {"gst-debug", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) parse_goption_arg,
314           N_("Comma-separated list of category_name:level pairs to set "
315               "specific levels for the individual categories. Example: "
316               "GST_AUTOPLUG:5,GST_ELEMENT_*:3"),
317         N_("LIST")},
318     {"gst-debug-no-color", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
319           (gpointer) parse_goption_arg, N_("Disable colored debugging output"),
320         NULL},
321     {"gst-debug-disable", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
322         (gpointer) parse_goption_arg, N_("Disable debugging"), NULL},
323 #endif
324     {"gst-plugin-spew", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
325           (gpointer) parse_goption_arg,
326           N_("Enable verbose plugin loading diagnostics"),
327         NULL},
328     {"gst-plugin-path", 0, 0, G_OPTION_ARG_CALLBACK,
329           (gpointer) parse_goption_arg,
330         N_("Colon-separated paths containing plugins"), N_("PATHS")},
331     {"gst-plugin-load", 0, 0, G_OPTION_ARG_CALLBACK,
332           (gpointer) parse_goption_arg,
333           N_("Comma-separated list of plugins to preload in addition to the "
334               "list stored in environment variable GST_PLUGIN_PATH"),
335         N_("PLUGINS")},
336     {"gst-disable-segtrap", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
337           (gpointer) parse_goption_arg,
338           N_("Disable trapping of segmentation faults during plugin loading"),
339         NULL},
340     {"gst-disable-registry-fork", 0, G_OPTION_FLAG_NO_ARG,
341           G_OPTION_ARG_CALLBACK,
342           (gpointer) parse_goption_arg,
343           N_("Disable the use of fork() while scanning the registry"),
344         NULL},
345     {NULL}
346   };
347
348   /* The GLib threading system must be initialised before calling any other
349    * GLib function according to the documentation; if the application hasn't
350    * called gst_init() yet or initialised the threading system otherwise, we
351    * better issue a warning here (since chances are high that the application
352    * has already called other GLib functions such as g_option_context_new() */
353   if (!g_thread_supported ()) {
354     g_warning ("The GStreamer function gst_init_get_option_group() was\n"
355         "\tcalled, but the GLib threading system has not been initialised\n"
356         "\tyet, something that must happen before any other GLib function\n"
357         "\tis called. The application needs to be fixed so that it calls\n"
358         "\t   if (!g_thread_supported ()) g_thread_init(NULL);\n"
359         "\tas very first thing in its main() function. Please file a bug\n"
360         "\tagainst this application.");
361     g_thread_init (NULL);
362   }
363
364   group = g_option_group_new ("gst", _("GStreamer Options"),
365       _("Show GStreamer Options"), NULL, NULL);
366   g_option_group_set_parse_hooks (group, (GOptionParseFunc) init_pre,
367       (GOptionParseFunc) init_post);
368
369   g_option_group_add_entries (group, gst_args);
370   g_option_group_set_translation_domain (group, GETTEXT_PACKAGE);
371
372   return group;
373 #else
374   return NULL;
375 #endif
376 }
377
378 /**
379  * gst_init_check:
380  * @argc: pointer to application's argc
381  * @argv: pointer to application's argv
382  * @err: pointer to a #GError to which a message will be posted on error
383  *
384  * Initializes the GStreamer library, setting up internal path lists,
385  * registering built-in elements, and loading standard plugins.
386  *
387  * This function will return %FALSE if GStreamer could not be initialized
388  * for some reason.  If you want your program to fail fatally,
389  * use gst_init() instead.
390  *
391  * This function should be called before calling any other GLib functions. If
392  * this is not an option, your program must initialise the GLib thread system
393  * using g_thread_init() before any other GLib functions are called.
394  *
395  * Returns: %TRUE if GStreamer could be initialized.
396  */
397 gboolean
398 gst_init_check (int *argc, char **argv[], GError ** err)
399 {
400 #ifndef GST_DISABLE_OPTION_PARSING
401   GOptionGroup *group;
402   GOptionContext *ctx;
403 #endif
404   gboolean res;
405
406   if (!g_thread_supported ())
407     g_thread_init (NULL);
408
409   if (gst_initialized) {
410     GST_DEBUG ("already initialized gst");
411     return TRUE;
412   }
413 #ifndef GST_DISABLE_OPTION_PARSING
414   ctx = g_option_context_new ("- GStreamer initialization");
415   g_option_context_set_ignore_unknown_options (ctx, TRUE);
416   group = gst_init_get_option_group ();
417   g_option_context_add_group (ctx, group);
418   res = g_option_context_parse (ctx, argc, argv, err);
419   g_option_context_free (ctx);
420 #else
421   init_pre (NULL, NULL, NULL, NULL);
422   init_post (NULL, NULL, NULL, NULL);
423   res = TRUE;
424 #endif
425
426   gst_initialized = res;
427
428   if (res) {
429     GST_INFO ("initialized GStreamer successfully");
430   } else {
431     GST_INFO ("failed to initialize GStreamer");
432   }
433
434   return res;
435 }
436
437 /**
438  * gst_init:
439  * @argc: pointer to application's argc
440  * @argv: pointer to application's argv
441  *
442  * Initializes the GStreamer library, setting up internal path lists,
443  * registering built-in elements, and loading standard plugins.
444  *
445  * This function should be called before calling any other GLib functions. If
446  * this is not an option, your program must initialise the GLib thread system
447  * using g_thread_init() before any other GLib functions are called.
448  *
449  * <note><para>
450  * This function will terminate your program if it was unable to initialize
451  * GStreamer for some reason.  If you want your program to fall back,
452  * use gst_init_check() instead.
453  * </para></note>
454  *
455  * WARNING: This function does not work in the same way as corresponding
456  * functions in other glib-style libraries, such as gtk_init().  In
457  * particular, unknown command line options cause this function to
458  * abort program execution.
459  */
460 void
461 gst_init (int *argc, char **argv[])
462 {
463   GError *err = NULL;
464
465   if (!gst_init_check (argc, argv, &err)) {
466     g_print ("Could not initialize GStreamer: %s\n",
467         err ? err->message : "unknown error occurred");
468     if (err) {
469       g_error_free (err);
470     }
471     exit (1);
472   }
473 }
474
475 #ifndef GST_DISABLE_REGISTRY
476 static void
477 add_path_func (gpointer data, gpointer user_data)
478 {
479   GST_INFO ("Adding plugin path: \"%s\", will scan later", (gchar *) data);
480   plugin_paths = g_list_append (plugin_paths, g_strdup (data));
481 }
482 #endif
483
484 #ifndef GST_DISABLE_OPTION_PARSING
485 static void
486 prepare_for_load_plugin_func (gpointer data, gpointer user_data)
487 {
488   preload_plugins = g_slist_prepend (preload_plugins, g_strdup (data));
489 }
490 #endif
491
492 static void
493 load_plugin_func (gpointer data, gpointer user_data)
494 {
495   GstPlugin *plugin;
496   const gchar *filename;
497   GError *err = NULL;
498
499   filename = (const gchar *) data;
500
501   plugin = gst_plugin_load_file (filename, &err);
502
503   if (plugin) {
504     GST_INFO ("Loaded plugin: \"%s\"", filename);
505
506     gst_default_registry_add_plugin (plugin);
507   } else {
508     if (err) {
509       /* Report error to user, and free error */
510       GST_ERROR ("Failed to load plugin: %s", err->message);
511       g_error_free (err);
512     } else {
513       GST_WARNING ("Failed to load plugin: \"%s\"", filename);
514     }
515   }
516 }
517
518 #ifndef GST_DISABLE_OPTION_PARSING
519 static void
520 split_and_iterate (const gchar * stringlist, gchar * separator, GFunc iterator,
521     gpointer user_data)
522 {
523   gchar **strings;
524   gint j = 0;
525   gchar *lastlist = g_strdup (stringlist);
526
527   while (lastlist) {
528     strings = g_strsplit (lastlist, separator, MAX_PATH_SPLIT);
529     g_free (lastlist);
530     lastlist = NULL;
531
532     while (strings[j]) {
533       iterator (strings[j], user_data);
534       if (++j == MAX_PATH_SPLIT) {
535         lastlist = g_strdup (strings[j]);
536         j = 0;
537         break;
538       }
539     }
540     g_strfreev (strings);
541   }
542 }
543 #endif
544
545 /* we have no fail cases yet, but maybe in the future */
546 static gboolean
547 init_pre (GOptionContext * context, GOptionGroup * group, gpointer data,
548     GError ** error)
549 {
550   if (gst_initialized) {
551     GST_DEBUG ("already initialized");
552     return TRUE;
553   }
554
555   /* GStreamer was built against a GLib >= 2.8 and is therefore not doing
556    * the refcount hack. Check that it isn't being run against an older GLib */
557   if (glib_major_version < 2 ||
558       (glib_major_version == 2 && glib_minor_version < 8)) {
559     g_warning ("GStreamer was compiled against GLib %d.%d.%d but is running"
560         " against %d.%d.%d. This will cause reference counting issues",
561         GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION,
562         glib_major_version, glib_minor_version, glib_micro_version);
563   }
564
565   g_type_init ();
566
567   /* we need threading to be enabled right here */
568   g_assert (g_thread_supported ());
569   _gst_debug_init ();
570
571 #ifdef ENABLE_NLS
572   setlocale (LC_ALL, "");
573   bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
574 #endif /* ENABLE_NLS */
575
576 #ifndef GST_DISABLE_GST_DEBUG
577   {
578     const gchar *debug_list;
579
580     if (g_getenv ("GST_DEBUG_NO_COLOR") != NULL)
581       gst_debug_set_colored (FALSE);
582
583     debug_list = g_getenv ("GST_DEBUG");
584     if (debug_list) {
585       parse_debug_list (debug_list);
586     }
587   }
588 #endif
589   /* This is the earliest we can make stuff show up in the logs.
590    * So give some useful info about GStreamer here */
591   GST_INFO ("Initializing GStreamer Core Library version %s", VERSION);
592   GST_INFO ("Using library installed in %s", LIBDIR);
593
594   /* Print some basic system details if possible (OS/architecture) */
595 #ifdef HAVE_SYS_UTSNAME_H
596   {
597     struct utsname sys_details;
598
599     if (uname (&sys_details) == 0) {
600       GST_INFO ("%s %s %s %s %s", sys_details.sysname,
601           sys_details.nodename, sys_details.release, sys_details.version,
602           sys_details.machine);
603     }
604   }
605 #endif
606
607   return TRUE;
608 }
609
610 static gboolean
611 gst_register_core_elements (GstPlugin * plugin)
612 {
613   /* register some standard builtin types */
614   if (!gst_element_register (plugin, "bin", GST_RANK_PRIMARY,
615           GST_TYPE_BIN) ||
616       !gst_element_register (plugin, "pipeline", GST_RANK_PRIMARY,
617           GST_TYPE_PIPELINE)
618       )
619     g_assert_not_reached ();
620
621   return TRUE;
622 }
623
624 static GstPluginDesc plugin_desc = {
625   GST_VERSION_MAJOR,
626   GST_VERSION_MINOR,
627   "staticelements",
628   "core elements linked into the GStreamer library",
629   gst_register_core_elements,
630   VERSION,
631   GST_LICENSE,
632   PACKAGE,
633   GST_PACKAGE_NAME,
634   GST_PACKAGE_ORIGIN,
635
636   GST_PADDING_INIT
637 };
638
639 #ifndef GST_DISABLE_REGISTRY
640
641 typedef enum
642 {
643   REGISTRY_SCAN_AND_UPDATE_FAILURE = 0,
644   REGISTRY_SCAN_AND_UPDATE_SUCCESS_NOT_CHANGED,
645   REGISTRY_SCAN_AND_UPDATE_SUCCESS_UPDATED
646 } GstRegistryScanAndUpdateResult;
647
648 /*
649  * scan_and_update_registry:
650  * @default_registry: the #GstRegistry
651  * @registry_file: registry filename
652  * @write_changes: write registry if it has changed?
653  *
654  * Scans for registry changes and eventually updates the registry cache. 
655  *
656  * Return: %REGISTRY_SCAN_AND_UPDATE_FAILURE if the registry could not scanned
657  *         or updated, %REGISTRY_SCAN_AND_UPDATE_SUCCESS_NOT_CHANGED if the
658  *         registry is clean and %REGISTRY_SCAN_AND_UPDATE_SUCCESS_UPDATED if
659  *         it has been updated and the cache needs to be re-read.
660  */
661 static GstRegistryScanAndUpdateResult
662 scan_and_update_registry (GstRegistry * default_registry,
663     const gchar * registry_file, gboolean write_changes, GError ** error)
664 {
665   const gchar *plugin_path;
666   gboolean changed = FALSE;
667   GList *l;
668
669   /* scan paths specified via --gst-plugin-path */
670   GST_DEBUG ("scanning paths added via --gst-plugin-path");
671   for (l = plugin_paths; l != NULL; l = l->next) {
672     GST_INFO ("Scanning plugin path: \"%s\"", (gchar *) l->data);
673     /* CHECKME: add changed |= here as well? */
674     gst_registry_scan_path (default_registry, (gchar *) l->data);
675   }
676   /* keep plugin_paths around in case a re-scan is forced later on */
677
678   /* GST_PLUGIN_PATH specifies a list of directories to scan for
679    * additional plugins.  These take precedence over the system plugins */
680   plugin_path = g_getenv ("GST_PLUGIN_PATH");
681   if (plugin_path) {
682     char **list;
683     int i;
684
685     GST_DEBUG ("GST_PLUGIN_PATH set to %s", plugin_path);
686     list = g_strsplit (plugin_path, G_SEARCHPATH_SEPARATOR_S, 0);
687     for (i = 0; list[i]; i++) {
688       changed |= gst_registry_scan_path (default_registry, list[i]);
689     }
690     g_strfreev (list);
691   } else {
692     GST_DEBUG ("GST_PLUGIN_PATH not set");
693   }
694
695   /* GST_PLUGIN_SYSTEM_PATH specifies a list of plugins that are always
696    * loaded by default.  If not set, this defaults to the system-installed
697    * path, and the plugins installed in the user's home directory */
698   plugin_path = g_getenv ("GST_PLUGIN_SYSTEM_PATH");
699   if (plugin_path == NULL) {
700     char *home_plugins;
701
702     GST_DEBUG ("GST_PLUGIN_SYSTEM_PATH not set");
703
704     /* plugins in the user's home directory take precedence over
705      * system-installed ones */
706     home_plugins = g_build_filename (g_get_home_dir (),
707         ".gstreamer-" GST_MAJORMINOR, "plugins", NULL);
708     GST_DEBUG ("scanning home plugins %s", home_plugins);
709     changed |= gst_registry_scan_path (default_registry, home_plugins);
710     g_free (home_plugins);
711
712     /* add the main (installed) library path */
713     GST_DEBUG ("scanning main plugins %s", PLUGINDIR);
714     changed |= gst_registry_scan_path (default_registry, PLUGINDIR);
715   } else {
716     gchar **list;
717     gint i;
718
719     GST_DEBUG ("GST_PLUGIN_SYSTEM_PATH set to %s", plugin_path);
720     list = g_strsplit (plugin_path, G_SEARCHPATH_SEPARATOR_S, 0);
721     for (i = 0; list[i]; i++) {
722       changed |= gst_registry_scan_path (default_registry, list[i]);
723     }
724     g_strfreev (list);
725   }
726
727   /* Remove cached plugins so stale info is cleared. */
728   changed |= _priv_gst_registry_remove_cache_plugins (default_registry);
729
730   if (!changed) {
731     GST_INFO ("Registry cache has not changed");
732     return REGISTRY_SCAN_AND_UPDATE_SUCCESS_NOT_CHANGED;
733   }
734
735   if (!write_changes) {
736     GST_INFO ("Registry cached changed, but writing is disabled. Not writing.");
737     return REGISTRY_SCAN_AND_UPDATE_FAILURE;
738   }
739
740   GST_INFO ("Registry cache changed. Writing new registry cache");
741 #ifdef USE_BINARY_REGISTRY
742   if (!gst_registry_binary_write_cache (default_registry, registry_file)) {
743 #else
744   if (!gst_registry_xml_write_cache (default_registry, registry_file)) {
745 #endif
746     g_set_error (error, GST_CORE_ERROR, GST_CORE_ERROR_FAILED,
747         _("Error writing registry cache to %s: %s"),
748         registry_file, g_strerror (errno));
749     return REGISTRY_SCAN_AND_UPDATE_FAILURE;
750   }
751
752   GST_INFO ("Registry cache written successfully");
753   return REGISTRY_SCAN_AND_UPDATE_SUCCESS_UPDATED;
754 }
755
756 static gboolean
757 ensure_current_registry_nonforking (GstRegistry * default_registry,
758     const gchar * registry_file, GError ** error)
759 {
760   /* fork() not available */
761   GST_INFO ("reading registry cache: %s", registry_file);
762 #ifdef USE_BINARY_REGISTRY
763   gst_registry_binary_read_cache (default_registry, registry_file);
764 #else
765   gst_registry_xml_read_cache (default_registry, registry_file);
766 #endif
767   GST_DEBUG ("Updating registry cache in-process");
768   scan_and_update_registry (default_registry, registry_file, TRUE, error);
769   return TRUE;
770 }
771
772 /* when forking is not available this function always does nothing but return
773  * TRUE immediatly */
774 static gboolean
775 ensure_current_registry_forking (GstRegistry * default_registry,
776     const gchar * registry_file, GError ** error)
777 {
778 #ifdef HAVE_FORK
779   pid_t pid;
780   int pfd[2];
781   int ret;
782
783   /* We fork here, and let the child read and possibly rebuild the registry.
784    * After that, the parent will re-read the freshly generated registry. */
785   GST_DEBUG ("forking to update registry");
786
787   if (pipe (pfd) == -1) {
788     g_set_error (error, GST_CORE_ERROR, GST_CORE_ERROR_FAILED,
789         _("Error re-scanning registry %s: %s"),
790         ", could not create pipes. Error", g_strerror (errno));
791     return FALSE;
792   }
793
794   GST_INFO ("reading registry cache: %s", registry_file);
795 #ifdef USE_BINARY_REGISTRY
796   gst_registry_binary_read_cache (default_registry, registry_file);
797 #else
798   gst_registry_xml_read_cache (default_registry, registry_file);
799 #endif
800
801   pid = fork ();
802   if (pid == -1) {
803     GST_ERROR ("Failed to fork()");
804     g_set_error (error, GST_CORE_ERROR, GST_CORE_ERROR_FAILED,
805         _("Error re-scanning registry %s: %s"),
806         ", failed to fork. Error", g_strerror (errno));
807     return FALSE;
808   }
809
810   if (pid == 0) {
811     gint result_code;
812
813     /* this is the child. Close the read pipe */
814     (void) close (pfd[0]);
815
816     GST_DEBUG ("child reading registry cache");
817     result_code =
818         scan_and_update_registry (default_registry, registry_file, TRUE, NULL);
819
820     /* need to use _exit, so that any exit handlers registered don't
821      * bring down the main program */
822     GST_DEBUG ("child exiting: %d", result_code);
823
824     /* make valgrind happy (yes, you can call it insane) */
825     g_free ((char *) registry_file);
826
827     /* write a result byte to the pipe */
828     do {
829       ret = write (pfd[1], &result_code, sizeof (result_code));
830     } while (ret == -1 && errno == EINTR);
831     /* if ret == -1 now, we could not write to pipe, probably 
832      * means parent has exited before us */
833     (void) close (pfd[1]);
834
835     _exit (0);
836   } else {
837     gint result_code;
838
839     /* parent. Close write pipe */
840     (void) close (pfd[1]);
841
842     /* Wait for result from the pipe */
843     GST_DEBUG ("Waiting for data from child");
844     do {
845       ret = read (pfd[0], &result_code, sizeof (result_code));
846     } while (ret == -1 && errno == EINTR);
847
848     if (ret == -1) {
849       g_set_error (error, GST_CORE_ERROR, GST_CORE_ERROR_FAILED,
850           _("Error re-scanning registry %s: %s"),
851           ", read returned error", g_strerror (errno));
852       close (pfd[0]);
853       return FALSE;
854     }
855     (void) close (pfd[0]);
856
857     /* Wait to ensure the child is reaped, but ignore the result */
858     GST_DEBUG ("parent waiting on child");
859     waitpid (pid, NULL, 0);
860     GST_DEBUG ("parent done waiting on child");
861
862     if (ret == 0) {
863       GST_ERROR ("child did not exit normally, terminated by signal");
864       g_set_error (error, GST_CORE_ERROR, GST_CORE_ERROR_FAILED,
865           _("Error re-scanning registry %s"), ", child terminated by signal");
866       return FALSE;
867     }
868
869     if (result_code == REGISTRY_SCAN_AND_UPDATE_SUCCESS_UPDATED) {
870       GST_DEBUG ("Child succeeded. Parent reading registry cache");
871       _priv_gst_registry_remove_cache_plugins (default_registry);
872 #ifdef USE_BINARY_REGISTRY
873       gst_registry_binary_read_cache (default_registry, registry_file);
874 #else
875       gst_registry_xml_read_cache (default_registry, registry_file);
876 #endif
877     } else if (result_code == REGISTRY_SCAN_AND_UPDATE_FAILURE) {
878       GST_DEBUG ("Child failed. Parent re-scanning registry, ignoring errors.");
879       scan_and_update_registry (default_registry, registry_file, FALSE, NULL);
880     }
881   }
882 #endif /* HAVE_FORK */
883   return TRUE;
884 }
885
886 static gboolean
887 ensure_current_registry (GError ** error)
888 {
889   char *registry_file;
890   GstRegistry *default_registry;
891   gboolean ret;
892   gboolean do_fork;
893
894   default_registry = gst_registry_get_default ();
895   registry_file = g_strdup (g_getenv ("GST_REGISTRY"));
896   if (registry_file == NULL) {
897 #ifdef USE_BINARY_REGISTRY
898     registry_file = g_build_filename (g_get_home_dir (),
899         ".gstreamer-" GST_MAJORMINOR, "registry." HOST_CPU ".bin", NULL);
900 #else
901     registry_file = g_build_filename (g_get_home_dir (),
902         ".gstreamer-" GST_MAJORMINOR, "registry." HOST_CPU ".xml", NULL);
903 #endif
904   }
905
906   /* first see if forking is enabled */
907   do_fork = _gst_enable_registry_fork;
908   if (do_fork) {
909     const gchar *fork_env;
910
911     /* forking enabled, see if it is disabled with an env var */
912     if ((fork_env = g_getenv ("GST_REGISTRY_FORK"))) {
913       /* fork enabled for any value different from "no" */
914       do_fork = strcmp (fork_env, "no") != 0;
915     }
916   }
917
918   /* now check registry with or without forking */
919   if (do_fork) {
920     GST_DEBUG ("forking for registry rebuild");
921     ret = ensure_current_registry_forking (default_registry, registry_file,
922         error);
923   } else {
924     GST_DEBUG ("requested not to fork for registry rebuild");
925     ret = ensure_current_registry_nonforking (default_registry, registry_file,
926         error);
927   }
928
929   g_free (registry_file);
930
931   return ret;
932 }
933 #endif /* GST_DISABLE_REGISTRY */
934
935 /*
936  * this bit handles:
937  * - initalization of threads if we use them
938  * - log handler
939  * - initial output
940  * - initializes gst_format
941  * - registers a bunch of types for gst_objects
942  *
943  * - we don't have cases yet where this fails, but in the future
944  *   we might and then it's nice to be able to return that
945  */
946 static gboolean
947 init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
948     GError ** error)
949 {
950   GLogLevelFlags llf;
951
952 #ifndef GST_DISABLE_TRACE
953   GstTrace *gst_trace;
954 #endif /* GST_DISABLE_TRACE */
955
956   if (gst_initialized) {
957     GST_DEBUG ("already initialized");
958     return TRUE;
959   }
960
961   llf = G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL;
962   g_log_set_handler (g_log_domain_gstreamer, llf, debug_log_handler, NULL);
963
964   _priv_gst_quarks_initialize ();
965   _gst_format_initialize ();
966   _gst_query_initialize ();
967   g_type_class_ref (gst_object_get_type ());
968   g_type_class_ref (gst_pad_get_type ());
969   g_type_class_ref (gst_element_factory_get_type ());
970   g_type_class_ref (gst_element_get_type ());
971   g_type_class_ref (gst_type_find_factory_get_type ());
972   g_type_class_ref (gst_bin_get_type ());
973
974 #ifndef GST_DISABLE_INDEX
975   g_type_class_ref (gst_index_factory_get_type ());
976 #endif /* GST_DISABLE_INDEX */
977 #ifndef GST_DISABLE_URI
978   gst_uri_handler_get_type ();
979 #endif /* GST_DISABLE_URI */
980
981   gst_structure_get_type ();
982   _gst_value_initialize ();
983   g_type_class_ref (gst_param_spec_fraction_get_type ());
984   gst_caps_get_type ();
985   _gst_event_initialize ();
986   _gst_buffer_initialize ();
987   _gst_message_initialize ();
988   _gst_tag_initialize ();
989
990   /* register core plugins */
991   _gst_plugin_register_static (&plugin_desc);
992
993   _gst_plugin_initialize ();
994
995   /*
996    * Any errors happening below this point are non-fatal, we therefore mark
997    * gstreamer as being initialized, since it is the case from a plugin point of
998    * view.
999    *
1000    * If anything fails, it will be put back to FALSE in gst_init_check().
1001    * This allows some special plugins that would call gst_init() to not cause a
1002    * looping effect (i.e. initializing GStreamer twice).
1003    */
1004   gst_initialized = TRUE;
1005
1006 #ifndef GST_DISABLE_REGISTRY
1007   if (!ensure_current_registry (error))
1008     return FALSE;
1009 #endif /* GST_DISABLE_REGISTRY */
1010
1011   /* if we need to preload plugins, do so now */
1012   g_slist_foreach (preload_plugins, load_plugin_func, NULL);
1013   /* keep preload_plugins around in case a re-scan is forced later on */
1014
1015 #ifndef GST_DISABLE_TRACE
1016   _gst_trace_on = 0;
1017   if (_gst_trace_on) {
1018     gst_trace = gst_trace_new ("gst.trace", 1024);
1019     gst_trace_set_default (gst_trace);
1020   }
1021 #endif /* GST_DISABLE_TRACE */
1022
1023   return TRUE;
1024 }
1025
1026 #ifndef GST_DISABLE_GST_DEBUG
1027 static gboolean
1028 select_all (GstPlugin * plugin, gpointer user_data)
1029 {
1030   return TRUE;
1031 }
1032
1033 static gint
1034 sort_by_category_name (gconstpointer a, gconstpointer b)
1035 {
1036   return strcmp (gst_debug_category_get_name ((GstDebugCategory *) a),
1037       gst_debug_category_get_name ((GstDebugCategory *) b));
1038 }
1039
1040 static void
1041 gst_debug_help (void)
1042 {
1043   GSList *list, *walk;
1044   GList *list2, *g;
1045
1046   /* Need to ensure the registry is loaded to get debug categories */
1047   if (!init_post (NULL, NULL, NULL, NULL))
1048     exit (1);
1049
1050   list2 = gst_registry_plugin_filter (gst_registry_get_default (),
1051       select_all, FALSE, NULL);
1052
1053   /* FIXME this is gross.  why don't debug have categories PluginFeatures? */
1054   for (g = list2; g; g = g_list_next (g)) {
1055     GstPlugin *plugin = GST_PLUGIN_CAST (g->data);
1056
1057     gst_plugin_load (plugin);
1058   }
1059   g_list_free (list2);
1060
1061   list = gst_debug_get_all_categories ();
1062   walk = list = g_slist_sort (list, sort_by_category_name);
1063
1064   g_print ("\n");
1065   g_print ("name                  level    description\n");
1066   g_print ("---------------------+--------+--------------------------------\n");
1067
1068   while (walk) {
1069     GstDebugCategory *cat = (GstDebugCategory *) walk->data;
1070
1071     if (gst_debug_is_colored ()) {
1072       gchar *color = gst_debug_construct_term_color (cat->color);
1073
1074       g_print ("%s%-20s\033[00m  %1d %s  %s%s\033[00m\n",
1075           color,
1076           gst_debug_category_get_name (cat),
1077           gst_debug_category_get_threshold (cat),
1078           gst_debug_level_get_name (gst_debug_category_get_threshold (cat)),
1079           color, gst_debug_category_get_description (cat));
1080       g_free (color);
1081     } else {
1082       g_print ("%-20s  %1d %s  %s\n", gst_debug_category_get_name (cat),
1083           gst_debug_category_get_threshold (cat),
1084           gst_debug_level_get_name (gst_debug_category_get_threshold (cat)),
1085           gst_debug_category_get_description (cat));
1086     }
1087     walk = g_slist_next (walk);
1088   }
1089   g_slist_free (list);
1090   g_print ("\n");
1091 }
1092 #endif
1093
1094 #ifndef GST_DISABLE_OPTION_PARSING
1095 static gboolean
1096 parse_one_option (gint opt, const gchar * arg, GError ** err)
1097 {
1098   switch (opt) {
1099     case ARG_VERSION:
1100       g_print ("GStreamer Core Library version %s\n", PACKAGE_VERSION);
1101       exit (0);
1102     case ARG_FATAL_WARNINGS:{
1103       GLogLevelFlags fatal_mask;
1104
1105       fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
1106       fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
1107       g_log_set_always_fatal (fatal_mask);
1108       break;
1109     }
1110 #ifndef GST_DISABLE_GST_DEBUG
1111     case ARG_DEBUG_LEVEL:{
1112       gint tmp = 0;
1113
1114       tmp = strtol (arg, NULL, 0);
1115       if (tmp >= 0 && tmp < GST_LEVEL_COUNT) {
1116         gst_debug_set_default_threshold (tmp);
1117       }
1118       break;
1119     }
1120     case ARG_DEBUG:
1121       parse_debug_list (arg);
1122       break;
1123     case ARG_DEBUG_NO_COLOR:
1124       gst_debug_set_colored (FALSE);
1125       break;
1126     case ARG_DEBUG_DISABLE:
1127       gst_debug_set_active (FALSE);
1128       break;
1129     case ARG_DEBUG_HELP:
1130       gst_debug_help ();
1131       exit (0);
1132 #endif
1133     case ARG_PLUGIN_SPEW:
1134       break;
1135     case ARG_PLUGIN_PATH:
1136 #ifndef GST_DISABLE_REGISTRY
1137       split_and_iterate (arg, G_SEARCHPATH_SEPARATOR_S, add_path_func, NULL);
1138 #endif /* GST_DISABLE_REGISTRY */
1139       break;
1140     case ARG_PLUGIN_LOAD:
1141       split_and_iterate (arg, ",", prepare_for_load_plugin_func, NULL);
1142       break;
1143     case ARG_SEGTRAP_DISABLE:
1144       _gst_disable_segtrap = TRUE;
1145       break;
1146     case ARG_REGISTRY_FORK_DISABLE:
1147       _gst_enable_registry_fork = FALSE;
1148       break;
1149     default:
1150       g_set_error (err, G_OPTION_ERROR, G_OPTION_ERROR_UNKNOWN_OPTION,
1151           _("Unknown option"));
1152       return FALSE;
1153   }
1154
1155   return TRUE;
1156 }
1157
1158 static gboolean
1159 parse_goption_arg (const gchar * opt,
1160     const gchar * arg, gpointer data, GError ** err)
1161 {
1162   static const struct
1163   {
1164     gchar *opt;
1165     int val;
1166   } options[] = {
1167     {
1168     "--gst-version", ARG_VERSION}, {
1169     "--gst-fatal-warnings", ARG_FATAL_WARNINGS},
1170 #ifndef GST_DISABLE_GST_DEBUG
1171     {
1172     "--gst-debug-level", ARG_DEBUG_LEVEL}, {
1173     "--gst-debug", ARG_DEBUG}, {
1174     "--gst-debug-disable", ARG_DEBUG_DISABLE}, {
1175     "--gst-debug-no-color", ARG_DEBUG_NO_COLOR}, {
1176     "--gst-debug-help", ARG_DEBUG_HELP},
1177 #endif
1178     {
1179     "--gst-plugin-spew", ARG_PLUGIN_SPEW}, {
1180     "--gst-plugin-path", ARG_PLUGIN_PATH}, {
1181     "--gst-plugin-load", ARG_PLUGIN_LOAD}, {
1182     "--gst-disable-segtrap", ARG_SEGTRAP_DISABLE}, {
1183     "--gst-disable-registry-fork", ARG_REGISTRY_FORK_DISABLE}, {
1184     NULL}
1185   };
1186   gint val = 0, n;
1187
1188   for (n = 0; options[n].opt; n++) {
1189     if (!strcmp (opt, options[n].opt)) {
1190       val = options[n].val;
1191       break;
1192     }
1193   }
1194
1195   return parse_one_option (val, arg, err);
1196 }
1197 #endif
1198
1199 extern GstRegistry *_gst_registry_default;
1200
1201 /**
1202  * gst_deinit:
1203  *
1204  * Clean up any resources created by GStreamer in gst_init().
1205  *
1206  * It is normally not needed to call this function in a normal application
1207  * as the resources will automatically be freed when the program terminates.
1208  * This function is therefore mostly used by testsuites and other memory
1209  * profiling tools.
1210  *
1211  * After this call GStreamer (including this method) should not be used anymore. 
1212  */
1213 void
1214 gst_deinit (void)
1215 {
1216   GstClock *clock;
1217
1218   GST_INFO ("deinitializing GStreamer");
1219
1220   if (!gst_initialized) {
1221     GST_DEBUG ("already deinitialized");
1222     return;
1223   }
1224
1225   g_slist_foreach (preload_plugins, (GFunc) g_free, NULL);
1226   g_slist_free (preload_plugins);
1227   preload_plugins = NULL;
1228
1229 #ifndef GST_DISABLE_REGISTRY
1230   g_list_foreach (plugin_paths, (GFunc) g_free, NULL);
1231   g_list_free (plugin_paths);
1232   plugin_paths = NULL;
1233 #endif
1234
1235   clock = gst_system_clock_obtain ();
1236   gst_object_unref (clock);
1237   gst_object_unref (clock);
1238
1239   _priv_gst_registry_cleanup ();
1240
1241   g_type_class_unref (g_type_class_peek (gst_object_get_type ()));
1242   g_type_class_unref (g_type_class_peek (gst_pad_get_type ()));
1243   g_type_class_unref (g_type_class_peek (gst_element_factory_get_type ()));
1244   g_type_class_unref (g_type_class_peek (gst_element_get_type ()));
1245   g_type_class_unref (g_type_class_peek (gst_type_find_factory_get_type ()));
1246   g_type_class_unref (g_type_class_peek (gst_bin_get_type ()));
1247 #ifndef GST_DISABLE_INDEX
1248   g_type_class_unref (g_type_class_peek (gst_index_factory_get_type ()));
1249 #endif /* GST_DISABLE_INDEX */
1250   g_type_class_unref (g_type_class_peek (gst_param_spec_fraction_get_type ()));
1251
1252   gst_initialized = FALSE;
1253   GST_INFO ("deinitialized GStreamer");
1254 }
1255
1256 /**
1257  * gst_version:
1258  * @major: pointer to a guint to store the major version number
1259  * @minor: pointer to a guint to store the minor version number
1260  * @micro: pointer to a guint to store the micro version number
1261  * @nano:  pointer to a guint to store the nano version number
1262  *
1263  * Gets the version number of the GStreamer library.
1264  */
1265 void
1266 gst_version (guint * major, guint * minor, guint * micro, guint * nano)
1267 {
1268   g_return_if_fail (major);
1269   g_return_if_fail (minor);
1270   g_return_if_fail (micro);
1271   g_return_if_fail (nano);
1272
1273   *major = GST_VERSION_MAJOR;
1274   *minor = GST_VERSION_MINOR;
1275   *micro = GST_VERSION_MICRO;
1276   *nano = GST_VERSION_NANO;
1277 }
1278
1279 /**
1280  * gst_version_string:
1281  *
1282  * This function returns a string that is useful for describing this version
1283  * of GStreamer to the outside world: user agent strings, logging, ...
1284  *
1285  * Returns: a newly allocated string describing this version of GStreamer.
1286  */
1287
1288 gchar *
1289 gst_version_string ()
1290 {
1291   guint major, minor, micro, nano;
1292
1293   gst_version (&major, &minor, &micro, &nano);
1294   if (nano == 0)
1295     return g_strdup_printf ("GStreamer %d.%d.%d", major, minor, micro);
1296   else if (nano == 1)
1297     return g_strdup_printf ("GStreamer %d.%d.%d (CVS)", major, minor, micro);
1298   else
1299     return g_strdup_printf ("GStreamer %d.%d.%d (prerelease)", major, minor,
1300         micro);
1301 }
1302
1303 /**
1304  * gst_segtrap_is_enabled:
1305  *
1306  * Some functions in the GStreamer core might install a custom SIGSEGV handler
1307  * to better catch and report errors to the application. Currently this feature
1308  * is enabled by default when loading plugins.
1309  *
1310  * Applications might want to disable this behaviour with the
1311  * gst_segtrap_set_enabled() function. This is typically done if the application
1312  * wants to install its own handler without GStreamer interfering.
1313  *
1314  * Returns: %TRUE if GStreamer is allowed to install a custom SIGSEGV handler.
1315  *
1316  * Since: 0.10.10
1317  */
1318 gboolean
1319 gst_segtrap_is_enabled (void)
1320 {
1321   /* yeps, it's enabled when it's not disabled */
1322   return !_gst_disable_segtrap;
1323 }
1324
1325 /**
1326  * gst_segtrap_set_enabled:
1327  * @enabled: whether a custom SIGSEGV handler should be installed.
1328  *
1329  * Applications might want to disable/enable the SIGSEGV handling of
1330  * the GStreamer core. See gst_segtrap_is_enabled() for more information.
1331  *
1332  * Since: 0.10.10
1333  */
1334 void
1335 gst_segtrap_set_enabled (gboolean enabled)
1336 {
1337   _gst_disable_segtrap = !enabled;
1338 }
1339
1340 /**
1341  * gst_registry_fork_is_enabled:
1342  *
1343  * By default GStreamer will perform a fork() when scanning and rebuilding the
1344  * registry file. 
1345  *
1346  * Applications might want to disable this behaviour with the
1347  * gst_registry_fork_set_enabled() function. 
1348  *
1349  * Returns: %TRUE if GStreamer will use fork() when rebuilding the registry. On
1350  * platforms without fork(), this function will always return %FALSE.
1351  *
1352  * Since: 0.10.10
1353  */
1354 gboolean
1355 gst_registry_fork_is_enabled (void)
1356 {
1357   return _gst_enable_registry_fork;
1358 }
1359
1360 /**
1361  * gst_registry_fork_set_enabled:
1362  * @enabled: whether rebuilding the registry may fork
1363  *
1364  * Applications might want to disable/enable the usage of fork() when rebuilding
1365  * the registry. See gst_registry_fork_is_enabled() for more information.
1366  *
1367  * On platforms without fork(), this function will have no effect on the return
1368  * value of gst_registry_fork_is_enabled().
1369  *
1370  * Since: 0.10.10
1371  */
1372 void
1373 gst_registry_fork_set_enabled (gboolean enabled)
1374 {
1375 #ifdef HAVE_FORK
1376   _gst_enable_registry_fork = enabled;
1377 #endif /* HAVE_FORK */
1378 }
1379
1380
1381 /**
1382  * gst_update_registry:
1383  *
1384  * Forces GStreamer to re-scan its plugin paths and update the default
1385  * plugin registry.
1386  *
1387  * Applications will almost never need to call this function, it is only
1388  * useful if the application knows new plugins have been installed (or old
1389  * ones removed) since the start of the application (or, to be precise, the
1390  * first call to gst_init()) and the application wants to make use of any
1391  * newly-installed plugins without restarting the application.
1392  *
1393  * Applications should assume that the registry update is neither atomic nor
1394  * thread-safe and should therefore not have any dynamic pipelines running
1395  * (including the playbin and decodebin elements) and should also not create
1396  * any elements or access the GStreamer registry while the update is in
1397  * progress.
1398  *
1399  * Note that this function may block for a significant amount of time.
1400  *
1401  * Returns: %TRUE if the registry has been updated successfully (does not
1402  *          imply that there were changes), otherwise %FALSE.
1403  *
1404  * Since: 0.10.12
1405  */
1406 gboolean
1407 gst_update_registry (void)
1408 {
1409   gboolean res = FALSE;
1410
1411 #ifndef GST_DISABLE_REGISTRY
1412   GError *err = NULL;
1413
1414   res = ensure_current_registry (&err);
1415   if (err) {
1416     GST_WARNING ("registry update failed: %s", err->message);
1417     g_error_free (err);
1418   } else {
1419     GST_LOG ("registry update succeeded");
1420   }
1421
1422   if (preload_plugins) {
1423     g_slist_foreach (preload_plugins, load_plugin_func, NULL);
1424   }
1425 #else
1426   GST_WARNING ("registry update failed: %s", "registry disabled");
1427 #endif /* GST_DISABLE_REGISTRY */
1428
1429   return res;
1430 }