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