"Fossies" - the Fresh Open Source Software Archive

Member "gstreamer-1.16.1/gst/gst.c" (19 Apr 2019, 45889 Bytes) of package /linux/misc/gstreamer-1.16.1.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "gst.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes reports: 1.15.90_vs_1.16.0 or 1.14.4_vs_1.16.0.

    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., 51 Franklin St, Fifth Floor,
   20  * Boston, MA 02110-1301, USA.
   21  */
   22 
   23 /**
   24  * SECTION:gst
   25  * @title: GStreamer
   26  * @short_description: Media library supporting arbitrary formats and filter
   27  *                     graphs.
   28  *
   29  * GStreamer is a framework for constructing graphs of various filters
   30  * (termed elements here) that will handle streaming media.  Any discrete
   31  * (packetizable) media type is supported, with provisions for automatically
   32  * determining source type.  Formatting/framing information is provided with
   33  * a powerful negotiation framework.  Plugins are heavily used to provide for
   34  * all elements, allowing one to construct plugins outside of the GST
   35  * library, even released binary-only if license require (please don't).
   36  * GStreamer covers a wide range of use cases including: playback, recording,
   37  * editing, serving streams, voice over ip and video calls.
   38  *
   39  * The <application>GStreamer</application> library should be initialized with
   40  * gst_init() before it can be used. You should pass pointers to the main argc
   41  * and argv variables so that GStreamer can process its own command line
   42  * options, as shown in the following example.
   43  *
   44  * ## Initializing the gstreamer library
   45  *
   46  * |[ <!-- language="C" -->
   47  * int
   48  * main (int argc, char *argv[])
   49  * {
   50  *   // initialize the GStreamer library
   51  *   gst_init (&amp;argc, &amp;argv);
   52  *   ...
   53  * }
   54  * ]|
   55  *
   56  * It's allowed to pass two %NULL pointers to gst_init() in case you don't want
   57  * to pass the command line args to GStreamer.
   58  *
   59  * You can also use GOption to initialize your own parameters as shown in
   60  * the next code fragment:
   61  *
   62  * ## Initializing own parameters when initializing gstreamer
   63  * |[ <!-- language="C" -->
   64  * static gboolean stats = FALSE;
   65  * ...
   66  * int
   67  * main (int argc, char *argv[])
   68  * {
   69  *  GOptionEntry options[] = {
   70  *   {"tags", 't', 0, G_OPTION_ARG_NONE, &amp;tags,
   71  *       N_("Output tags (also known as metadata)"), NULL},
   72  *   {NULL}
   73  *  };
   74  *  ctx = g_option_context_new ("[ADDITIONAL ARGUMENTS]");
   75  *  g_option_context_add_main_entries (ctx, options, GETTEXT_PACKAGE);
   76  *  g_option_context_add_group (ctx, gst_init_get_option_group ());
   77  *  if (!g_option_context_parse (ctx, &amp;argc, &amp;argv, &amp;err)) {
   78  *    g_print ("Error initializing: &percnt;s\n", GST_STR_NULL (err->message));
   79  *    exit (1);
   80  *  }
   81  *  g_option_context_free (ctx);
   82  * ...
   83  * }
   84  * ]|
   85  *
   86  * Use gst_version() to query the library version at runtime or use the
   87  * GST_VERSION_* macros to find the version at compile time. Optionally
   88  * gst_version_string() returns a printable string.
   89  *
   90  * The gst_deinit() call is used to clean up all internal resources used
   91  * by GStreamer. It is mostly used in unit tests to check for leaks.
   92  */
   93 
   94 #include "gst_private.h"
   95 #include "gstconfig.h"
   96 #include <stdlib.h>
   97 #include <stdio.h>
   98 #include <sys/types.h>
   99 #ifdef HAVE_SYS_UTSNAME_H
  100 #include <sys/utsname.h>
  101 #endif
  102 #ifdef HAVE_UNISTD_H
  103 #include <unistd.h>
  104 #endif
  105 #ifdef G_OS_WIN32
  106 #define WIN32_LEAN_AND_MEAN     /* prevents from including too many things */
  107 #include <windows.h>            /* GetStdHandle, windows console */
  108 #endif
  109 #if defined (__APPLE__)
  110 #include "TargetConditionals.h"
  111 #if !TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR && !TARGET_OS_EMBEDDED
  112 #include <libproc.h>            /* proc_pidpath, PROC_PIDPATHINFO_MAXSIZE */
  113 #endif
  114 #endif
  115 
  116 #include "gst-i18n-lib.h"
  117 #include <locale.h>             /* for LC_ALL */
  118 
  119 #include "gst.h"
  120 
  121 #define GST_CAT_DEFAULT GST_CAT_GST_INIT
  122 
  123 #define MAX_PATH_SPLIT  16
  124 #define GST_PLUGIN_SEPARATOR ","
  125 
  126 static gboolean gst_initialized = FALSE;
  127 static gboolean gst_deinitialized = FALSE;
  128 
  129 GstClockTime _priv_gst_start_time;
  130 
  131 #ifdef G_OS_WIN32
  132 HMODULE _priv_gst_dll_handle = NULL;
  133 #endif
  134 
  135 #ifndef GST_DISABLE_REGISTRY
  136 GList *_priv_gst_plugin_paths = NULL;   /* for delayed processing in init_post */
  137 
  138 extern gboolean _priv_gst_disable_registry;
  139 extern gboolean _priv_gst_disable_registry_update;
  140 #endif
  141 
  142 gchar *_gst_executable_path = NULL;
  143 
  144 #ifndef GST_DISABLE_GST_DEBUG
  145 const gchar *priv_gst_dump_dot_dir;
  146 #endif
  147 
  148 /* defaults */
  149 
  150 /* set to TRUE when segfaults need to be left as is */
  151 static gboolean _gst_disable_segtrap = FALSE;
  152 
  153 static gboolean init_pre (GOptionContext * context, GOptionGroup * group,
  154     gpointer data, GError ** error);
  155 static gboolean init_post (GOptionContext * context, GOptionGroup * group,
  156     gpointer data, GError ** error);
  157 #ifndef GST_DISABLE_OPTION_PARSING
  158 static gboolean parse_goption_arg (const gchar * s_opt,
  159     const gchar * arg, gpointer data, GError ** err);
  160 #endif
  161 
  162 GSList *_priv_gst_preload_plugins = NULL;
  163 
  164 const gchar g_log_domain_gstreamer[] = "GStreamer";
  165 
  166 static void
  167 debug_log_handler (const gchar * log_domain,
  168     GLogLevelFlags log_level, const gchar * message, gpointer user_data)
  169 {
  170   g_log_default_handler (log_domain, log_level, message, user_data);
  171   /* FIXME: do we still need this ? fatal errors these days are all
  172    * other than core errors */
  173   /* g_on_error_query (NULL); */
  174 }
  175 
  176 enum
  177 {
  178   ARG_VERSION = 1,
  179   ARG_FATAL_WARNINGS,
  180 #ifndef GST_DISABLE_GST_DEBUG
  181   ARG_DEBUG_LEVEL,
  182   ARG_DEBUG,
  183   ARG_DEBUG_DISABLE,
  184   ARG_DEBUG_NO_COLOR,
  185   ARG_DEBUG_COLOR_MODE,
  186   ARG_DEBUG_HELP,
  187 #endif
  188   ARG_PLUGIN_SPEW,
  189   ARG_PLUGIN_PATH,
  190   ARG_PLUGIN_LOAD,
  191   ARG_SEGTRAP_DISABLE,
  192   ARG_REGISTRY_UPDATE_DISABLE,
  193   ARG_REGISTRY_FORK_DISABLE
  194 };
  195 
  196 /* debug-spec ::= category-spec [, category-spec]*
  197  * category-spec ::= category:val | val
  198  * category ::= [^:]+
  199  * val ::= [0-5]
  200  */
  201 
  202 #ifdef G_OS_WIN32
  203 /* Note: DllMain is only called when DLLs are loaded or unloaded, so this will
  204  * never be called if libgstreamer-1.0 is linked statically. Do not add any code
  205  * here to, say, initialize variables or set things up since that will only
  206  * happen for dynamically-built GStreamer.
  207  *
  208  * Also, ideally this should not be defined when GStreamer is built statically.
  209  * i.e., it should be conditional on #ifdef DLL_EXPORT. It will be ignored, but
  210  * if other libraries make the same mistake of defining it when building
  211  * statically, there will be a symbol collision during linking. Fixing this
  212  * requires one to build two object files: one for static linking and another
  213  * for dynamic linking. */
  214 BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);
  215 BOOL WINAPI
  216 DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
  217 {
  218   if (fdwReason == DLL_PROCESS_ATTACH)
  219     _priv_gst_dll_handle = (HMODULE) hinstDLL;
  220   return TRUE;
  221 }
  222 
  223 #endif
  224 
  225 /**
  226  * gst_init_get_option_group: (skip)
  227  *
  228  * Returns a #GOptionGroup with GStreamer's argument specifications. The
  229  * group is set up to use standard GOption callbacks, so when using this
  230  * group in combination with GOption parsing methods, all argument parsing
  231  * and initialization is automated.
  232  *
  233  * This function is useful if you want to integrate GStreamer with other
  234  * libraries that use GOption (see g_option_context_add_group() ).
  235  *
  236  * If you use this function, you should make sure you initialise the GLib
  237  * threading system as one of the very first things in your program
  238  * (see the example at the beginning of this section).
  239  *
  240  * Returns: (transfer full) (nullable): a pointer to GStreamer's option group.
  241  */
  242 
  243 GOptionGroup *
  244 gst_init_get_option_group (void)
  245 {
  246 #ifndef GST_DISABLE_OPTION_PARSING
  247   GOptionGroup *group;
  248   static const GOptionEntry gst_args[] = {
  249     {"gst-version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
  250         (gpointer) parse_goption_arg, N_("Print the GStreamer version"), NULL},
  251     {"gst-fatal-warnings", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
  252         (gpointer) parse_goption_arg, N_("Make all warnings fatal"), NULL},
  253 #ifndef GST_DISABLE_GST_DEBUG
  254     {"gst-debug-help", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
  255           (gpointer) parse_goption_arg,
  256           N_("Print available debug categories and exit"),
  257         NULL},
  258     {"gst-debug-level", 0, 0, G_OPTION_ARG_CALLBACK,
  259           (gpointer) parse_goption_arg,
  260           N_("Default debug level from 1 (only error) to 9 (anything) or "
  261               "0 for no output"),
  262         N_("LEVEL")},
  263     {"gst-debug", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) parse_goption_arg,
  264           N_("Comma-separated list of category_name:level pairs to set "
  265               "specific levels for the individual categories. Example: "
  266               "GST_AUTOPLUG:5,GST_ELEMENT_*:3"),
  267         N_("LIST")},
  268     {"gst-debug-no-color", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
  269           (gpointer) parse_goption_arg, N_("Disable colored debugging output"),
  270         NULL},
  271     {"gst-debug-color-mode", 0, 0, G_OPTION_ARG_CALLBACK,
  272           (gpointer) parse_goption_arg,
  273           N_("Changes coloring mode of the debug log. "
  274               "Possible modes: off, on, disable, auto, unix"),
  275         NULL},
  276     {"gst-debug-disable", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
  277         (gpointer) parse_goption_arg, N_("Disable debugging"), NULL},
  278 #endif
  279     {"gst-plugin-spew", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
  280           (gpointer) parse_goption_arg,
  281           N_("Enable verbose plugin loading diagnostics"),
  282         NULL},
  283     {"gst-plugin-path", 0, 0, G_OPTION_ARG_CALLBACK,
  284           (gpointer) parse_goption_arg,
  285         N_("Colon-separated paths containing plugins"), N_("PATHS")},
  286     {"gst-plugin-load", 0, 0, G_OPTION_ARG_CALLBACK,
  287           (gpointer) parse_goption_arg,
  288           N_("Comma-separated list of plugins to preload in addition to the "
  289               "list stored in environment variable GST_PLUGIN_PATH"),
  290         N_("PLUGINS")},
  291     {"gst-disable-segtrap", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
  292           (gpointer) parse_goption_arg,
  293           N_("Disable trapping of segmentation faults during plugin loading"),
  294         NULL},
  295     {"gst-disable-registry-update", 0, G_OPTION_FLAG_NO_ARG,
  296           G_OPTION_ARG_CALLBACK,
  297           (gpointer) parse_goption_arg,
  298           N_("Disable updating the registry"),
  299         NULL},
  300     {"gst-disable-registry-fork", 0, G_OPTION_FLAG_NO_ARG,
  301           G_OPTION_ARG_CALLBACK,
  302           (gpointer) parse_goption_arg,
  303           N_("Disable spawning a helper process while scanning the registry"),
  304         NULL},
  305     {NULL}
  306   };
  307 
  308   group = g_option_group_new ("gst", _("GStreamer Options"),
  309       _("Show GStreamer Options"), NULL, NULL);
  310   g_option_group_set_parse_hooks (group, (GOptionParseFunc) init_pre,
  311       (GOptionParseFunc) init_post);
  312 
  313   g_option_group_add_entries (group, gst_args);
  314   g_option_group_set_translation_domain (group, GETTEXT_PACKAGE);
  315 
  316   return group;
  317 #else
  318   return NULL;
  319 #endif
  320 }
  321 
  322 #if defined(__linux__)
  323 static void
  324 find_executable_path (void)
  325 {
  326   GError *error = NULL;
  327 
  328   if (_gst_executable_path)
  329     return;
  330 
  331   _gst_executable_path = g_file_read_link ("/proc/self/exe", &error);
  332   if (error)
  333     g_error_free (error);
  334 }
  335 #elif defined(G_OS_WIN32)
  336 static void
  337 find_executable_path (void)
  338 {
  339   char buffer[MAX_PATH];
  340 
  341   if (!GetModuleFileName (NULL, buffer, MAX_PATH))
  342     return;
  343 
  344   _gst_executable_path = g_strdup (buffer);
  345 }
  346 #elif defined(__APPLE__) && !TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR && !TARGET_OS_EMBEDDED
  347 static void
  348 find_executable_path (void)
  349 {
  350   int ret;
  351   pid_t pid;
  352   char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
  353 
  354   pid = getpid ();
  355   ret = proc_pidpath (pid, pathbuf, sizeof (pathbuf));
  356   if (ret > 0)
  357     _gst_executable_path = g_strdup (pathbuf);
  358 }
  359 #else
  360 static void
  361 find_executable_path (void)
  362 {
  363   GST_FIXME ("Couldn't look up executable path, add support for this platform");
  364 }
  365 #endif
  366 
  367 /**
  368  * gst_get_main_executable_path:
  369  *
  370  * This helper is mostly helpful for plugins that need to
  371  * inspect the folder of the main executable to determine
  372  * their set of features.
  373  *
  374  * When a plugin is initialized from the gst-plugin-scanner
  375  * external process, the returned path will be the same as from the
  376  * parent process.
  377  *
  378  * Returns: (transfer none) (nullable): The path of the executable that
  379  *   initialized GStreamer, or %NULL if it could not be determined.
  380  *
  381  * Since: 1.14
  382  */
  383 const gchar *
  384 gst_get_main_executable_path (void)
  385 {
  386   return _gst_executable_path;
  387 }
  388 
  389 /**
  390  * gst_init_check:
  391  * @argc: (inout) (allow-none): pointer to application's argc
  392  * @argv: (inout) (array length=argc) (allow-none): pointer to application's argv
  393  * @err: pointer to a #GError to which a message will be posted on error
  394  *
  395  * Initializes the GStreamer library, setting up internal path lists,
  396  * registering built-in elements, and loading standard plugins.
  397  *
  398  * This function will return %FALSE if GStreamer could not be initialized
  399  * for some reason.  If you want your program to fail fatally,
  400  * use gst_init() instead.
  401  *
  402  * Returns: %TRUE if GStreamer could be initialized.
  403  */
  404 gboolean
  405 gst_init_check (int *argc, char **argv[], GError ** err)
  406 {
  407   static GMutex init_lock;
  408 #ifndef GST_DISABLE_OPTION_PARSING
  409   GOptionGroup *group;
  410   GOptionContext *ctx;
  411 #endif
  412   gboolean res;
  413 
  414   g_mutex_lock (&init_lock);
  415 
  416   if (gst_initialized) {
  417     GST_DEBUG ("already initialized gst");
  418     g_mutex_unlock (&init_lock);
  419     return TRUE;
  420   }
  421 #ifndef GST_DISABLE_OPTION_PARSING
  422   ctx = g_option_context_new ("- GStreamer initialization");
  423   g_option_context_set_ignore_unknown_options (ctx, TRUE);
  424   g_option_context_set_help_enabled (ctx, FALSE);
  425   group = gst_init_get_option_group ();
  426   g_option_context_add_group (ctx, group);
  427   res = g_option_context_parse (ctx, argc, argv, err);
  428   g_option_context_free (ctx);
  429 #else
  430   init_pre (NULL, NULL, NULL, NULL);
  431   init_post (NULL, NULL, NULL, NULL);
  432   res = TRUE;
  433 #endif
  434 
  435   gst_initialized = res;
  436 
  437   g_mutex_unlock (&init_lock);
  438 
  439   return res;
  440 }
  441 
  442 /**
  443  * gst_init:
  444  * @argc: (inout) (allow-none): pointer to application's argc
  445  * @argv: (inout) (array length=argc) (allow-none): pointer to application's argv
  446  *
  447  * Initializes the GStreamer library, setting up internal path lists,
  448  * registering built-in elements, and loading standard plugins.
  449  *
  450  * Unless the plugin registry is disabled at compile time, the registry will be
  451  * loaded. By default this will also check if the registry cache needs to be
  452  * updated and rescan all plugins if needed. See gst_update_registry() for
  453  * details and section
  454  * <link linkend="gst-running">Running GStreamer Applications</link>
  455  * for how to disable automatic registry updates.
  456  *
  457  * > This function will terminate your program if it was unable to initialize
  458  * > GStreamer for some reason.  If you want your program to fall back,
  459  * > use gst_init_check() instead.
  460  *
  461  * WARNING: This function does not work in the same way as corresponding
  462  * functions in other glib-style libraries, such as gtk_init\(\). In
  463  * particular, unknown command line options cause this function to
  464  * abort program execution.
  465  */
  466 void
  467 gst_init (int *argc, char **argv[])
  468 {
  469   GError *err = NULL;
  470 
  471   if (!gst_init_check (argc, argv, &err)) {
  472     g_print ("Could not initialize GStreamer: %s\n",
  473         err ? err->message : "unknown error occurred");
  474     if (err) {
  475       g_error_free (err);
  476     }
  477     exit (1);
  478   }
  479 }
  480 
  481 /**
  482  * gst_is_initialized:
  483  *
  484  * Use this function to check if GStreamer has been initialized with gst_init()
  485  * or gst_init_check().
  486  *
  487  * Returns: %TRUE if initialization has been done, %FALSE otherwise.
  488  */
  489 gboolean
  490 gst_is_initialized (void)
  491 {
  492   return gst_initialized;
  493 }
  494 
  495 #ifndef GST_DISABLE_OPTION_PARSING
  496 #  ifndef GST_DISABLE_REGISTRY
  497 static void
  498 add_path_func (gpointer data, gpointer user_data)
  499 {
  500   GST_INFO ("Adding plugin path: \"%s\", will scan later", (gchar *) data);
  501   _priv_gst_plugin_paths =
  502       g_list_append (_priv_gst_plugin_paths, g_strdup (data));
  503 }
  504 #  endif
  505 #endif
  506 
  507 #ifndef GST_DISABLE_OPTION_PARSING
  508 static void
  509 prepare_for_load_plugin_func (gpointer data, gpointer user_data)
  510 {
  511   _priv_gst_preload_plugins =
  512       g_slist_prepend (_priv_gst_preload_plugins, g_strdup (data));
  513 }
  514 #endif
  515 
  516 #ifndef GST_DISABLE_OPTION_PARSING
  517 static void
  518 split_and_iterate (const gchar * stringlist, const gchar * separator,
  519     GFunc iterator, gpointer user_data)
  520 {
  521   gchar **strings;
  522   gint j = 0;
  523   gchar *lastlist = g_strdup (stringlist);
  524 
  525   while (lastlist) {
  526     strings = g_strsplit (lastlist, separator, MAX_PATH_SPLIT);
  527     g_free (lastlist);
  528     lastlist = NULL;
  529 
  530     while (strings[j]) {
  531       iterator (strings[j], user_data);
  532       if (++j == MAX_PATH_SPLIT) {
  533         lastlist = g_strdup (strings[j]);
  534         j = 0;
  535         break;
  536       }
  537     }
  538     g_strfreev (strings);
  539   }
  540 }
  541 #endif
  542 
  543 /* we have no fail cases yet, but maybe in the future */
  544 static gboolean
  545 init_pre (GOptionContext * context, GOptionGroup * group, gpointer data,
  546     GError ** error)
  547 {
  548   gchar *libdir;
  549   if (gst_initialized) {
  550     GST_DEBUG ("already initialized");
  551     return TRUE;
  552   }
  553 
  554   find_executable_path ();
  555 
  556   _priv_gst_start_time = gst_util_get_timestamp ();
  557 
  558 #ifndef GST_DISABLE_GST_DEBUG
  559   _priv_gst_debug_init ();
  560   priv_gst_dump_dot_dir = g_getenv ("GST_DEBUG_DUMP_DOT_DIR");
  561 #endif
  562 
  563 #ifdef ENABLE_NLS
  564   bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
  565   bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
  566 #endif /* ENABLE_NLS */
  567 
  568   /* This is the earliest we can make stuff show up in the logs.
  569    * So give some useful info about GStreamer here */
  570 #ifdef G_OS_WIN32
  571   {
  572     gchar *basedir =
  573         g_win32_get_package_installation_directory_of_module
  574         (_priv_gst_dll_handle);
  575 
  576     libdir = g_build_filename (basedir,
  577 #ifdef _DEBUG
  578         "debug"
  579 #endif
  580         "lib", NULL);
  581     g_free (basedir);
  582   }
  583 #else
  584   libdir = g_strdup (LIBDIR);
  585 #endif
  586   GST_INFO ("Initializing GStreamer Core Library version %s", VERSION);
  587   GST_INFO ("Using library installed in %s", libdir);
  588   g_free (libdir);
  589 
  590 #ifndef GST_DISABLE_REGISTRY
  591   {
  592     const gchar *disable_registry;
  593     if ((disable_registry = g_getenv ("GST_REGISTRY_DISABLE"))) {
  594       _priv_gst_disable_registry = (strcmp (disable_registry, "yes") == 0);
  595     }
  596   }
  597 #endif
  598 
  599   /* Print some basic system details if possible (OS/architecture) */
  600 #ifdef HAVE_SYS_UTSNAME_H
  601   {
  602     struct utsname sys_details;
  603 
  604     if (uname (&sys_details) == 0) {
  605       GST_INFO ("%s %s %s %s %s", sys_details.sysname,
  606           sys_details.nodename, sys_details.release, sys_details.version,
  607           sys_details.machine);
  608     }
  609   }
  610 #endif
  611 
  612 #ifndef G_ATOMIC_LOCK_FREE
  613   GST_CAT_WARNING (GST_CAT_PERFORMANCE, "GLib atomic operations are NOT "
  614       "implemented using real hardware atomic operations!");
  615 #endif
  616 
  617   return TRUE;
  618 }
  619 
  620 static gboolean
  621 gst_register_core_elements (GstPlugin * plugin)
  622 {
  623   /* register some standard builtin types */
  624   if (!gst_element_register (plugin, "bin", GST_RANK_PRIMARY,
  625           GST_TYPE_BIN) ||
  626       !gst_element_register (plugin, "pipeline", GST_RANK_PRIMARY,
  627           GST_TYPE_PIPELINE)
  628       )
  629     g_assert_not_reached ();
  630 
  631   return TRUE;
  632 }
  633 
  634 /*
  635  * this bit handles:
  636  * - initialization of threads if we use them
  637  * - log handler
  638  * - initial output
  639  * - initializes gst_format
  640  * - registers a bunch of types for gst_objects
  641  *
  642  * - we don't have cases yet where this fails, but in the future
  643  *   we might and then it's nice to be able to return that
  644  */
  645 static gboolean
  646 init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
  647     GError ** error)
  648 {
  649   GLogLevelFlags llf;
  650 
  651   if (gst_initialized) {
  652     GST_DEBUG ("already initialized");
  653     return TRUE;
  654   }
  655 
  656   llf = G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL;
  657   g_log_set_handler (g_log_domain_gstreamer, llf, debug_log_handler, NULL);
  658 
  659   _priv_gst_mini_object_initialize ();
  660   _priv_gst_quarks_initialize ();
  661   _priv_gst_allocator_initialize ();
  662   _priv_gst_memory_initialize ();
  663   _priv_gst_format_initialize ();
  664   _priv_gst_query_initialize ();
  665   _priv_gst_structure_initialize ();
  666   _priv_gst_caps_initialize ();
  667   _priv_gst_caps_features_initialize ();
  668   _priv_gst_meta_initialize ();
  669   _priv_gst_message_initialize ();
  670 
  671   g_type_class_ref (gst_object_get_type ());
  672   g_type_class_ref (gst_pad_get_type ());
  673   g_type_class_ref (gst_element_factory_get_type ());
  674   g_type_class_ref (gst_element_get_type ());
  675   g_type_class_ref (gst_tracer_factory_get_type ());
  676   g_type_class_ref (gst_type_find_factory_get_type ());
  677   g_type_class_ref (gst_bin_get_type ());
  678   g_type_class_ref (gst_bus_get_type ());
  679   g_type_class_ref (gst_task_get_type ());
  680   g_type_class_ref (gst_clock_get_type ());
  681   g_type_class_ref (gst_debug_color_mode_get_type ());
  682 
  683   gst_uri_handler_get_type ();
  684 
  685   g_type_class_ref (gst_object_flags_get_type ());
  686   g_type_class_ref (gst_bin_flags_get_type ());
  687   g_type_class_ref (gst_buffer_flags_get_type ());
  688   g_type_class_ref (gst_buffer_copy_flags_get_type ());
  689   g_type_class_ref (gst_bus_flags_get_type ());
  690   g_type_class_ref (gst_bus_sync_reply_get_type ());
  691   g_type_class_ref (gst_caps_flags_get_type ());
  692   g_type_class_ref (gst_clock_return_get_type ());
  693   g_type_class_ref (gst_clock_entry_type_get_type ());
  694   g_type_class_ref (gst_clock_flags_get_type ());
  695   g_type_class_ref (gst_clock_type_get_type ());
  696   g_type_class_ref (gst_debug_graph_details_get_type ());
  697   g_type_class_ref (gst_state_get_type ());
  698   g_type_class_ref (gst_state_change_return_get_type ());
  699   g_type_class_ref (gst_state_change_get_type ());
  700   g_type_class_ref (gst_element_flags_get_type ());
  701   g_type_class_ref (gst_tracer_value_scope_get_type ());
  702   g_type_class_ref (gst_tracer_value_flags_get_type ());
  703   g_type_class_ref (gst_core_error_get_type ());
  704   g_type_class_ref (gst_library_error_get_type ());
  705   g_type_class_ref (gst_resource_error_get_type ());
  706   g_type_class_ref (gst_stream_error_get_type ());
  707   g_type_class_ref (gst_event_type_flags_get_type ());
  708   g_type_class_ref (gst_event_type_get_type ());
  709   g_type_class_ref (gst_seek_type_get_type ());
  710   g_type_class_ref (gst_seek_flags_get_type ());
  711   g_type_class_ref (gst_qos_type_get_type ());
  712   g_type_class_ref (gst_format_get_type ());
  713   g_type_class_ref (gst_debug_level_get_type ());
  714   g_type_class_ref (gst_debug_color_flags_get_type ());
  715   g_type_class_ref (gst_iterator_result_get_type ());
  716   g_type_class_ref (gst_iterator_item_get_type ());
  717   g_type_class_ref (gst_message_type_get_type ());
  718   g_type_class_ref (gst_mini_object_flags_get_type ());
  719   g_type_class_ref (gst_pad_link_return_get_type ());
  720   g_type_class_ref (gst_pad_link_check_get_type ());
  721   g_type_class_ref (gst_flow_return_get_type ());
  722   g_type_class_ref (gst_pad_mode_get_type ());
  723   g_type_class_ref (gst_pad_direction_get_type ());
  724   g_type_class_ref (gst_pad_flags_get_type ());
  725   g_type_class_ref (gst_pad_presence_get_type ());
  726   g_type_class_ref (gst_pad_template_flags_get_type ());
  727   g_type_class_ref (gst_pipeline_flags_get_type ());
  728   g_type_class_ref (gst_plugin_error_get_type ());
  729   g_type_class_ref (gst_plugin_flags_get_type ());
  730   g_type_class_ref (gst_plugin_dependency_flags_get_type ());
  731   g_type_class_ref (gst_rank_get_type ());
  732   g_type_class_ref (gst_query_type_flags_get_type ());
  733   g_type_class_ref (gst_query_type_get_type ());
  734   g_type_class_ref (gst_buffering_mode_get_type ());
  735   g_type_class_ref (gst_stream_status_type_get_type ());
  736   g_type_class_ref (gst_structure_change_type_get_type ());
  737   g_type_class_ref (gst_tag_merge_mode_get_type ());
  738   g_type_class_ref (gst_tag_flag_get_type ());
  739   g_type_class_ref (gst_tag_scope_get_type ());
  740   g_type_class_ref (gst_task_pool_get_type ());
  741   g_type_class_ref (gst_task_state_get_type ());
  742   g_type_class_ref (gst_toc_entry_type_get_type ());
  743   g_type_class_ref (gst_type_find_probability_get_type ());
  744   g_type_class_ref (gst_uri_error_get_type ());
  745   g_type_class_ref (gst_uri_type_get_type ());
  746   g_type_class_ref (gst_parse_error_get_type ());
  747   g_type_class_ref (gst_parse_flags_get_type ());
  748   g_type_class_ref (gst_search_mode_get_type ());
  749   g_type_class_ref (gst_progress_type_get_type ());
  750   g_type_class_ref (gst_buffer_pool_acquire_flags_get_type ());
  751   g_type_class_ref (gst_memory_flags_get_type ());
  752   g_type_class_ref (gst_map_flags_get_type ());
  753   g_type_class_ref (gst_caps_intersect_mode_get_type ());
  754   g_type_class_ref (gst_pad_probe_type_get_type ());
  755   g_type_class_ref (gst_pad_probe_return_get_type ());
  756   g_type_class_ref (gst_segment_flags_get_type ());
  757   g_type_class_ref (gst_scheduling_flags_get_type ());
  758   g_type_class_ref (gst_meta_flags_get_type ());
  759   g_type_class_ref (gst_toc_entry_type_get_type ());
  760   g_type_class_ref (gst_toc_scope_get_type ());
  761   g_type_class_ref (gst_toc_loop_type_get_type ());
  762   g_type_class_ref (gst_control_binding_get_type ());
  763   g_type_class_ref (gst_control_source_get_type ());
  764   g_type_class_ref (gst_lock_flags_get_type ());
  765   g_type_class_ref (gst_allocator_flags_get_type ());
  766   g_type_class_ref (gst_stream_flags_get_type ());
  767   g_type_class_ref (gst_stream_type_get_type ());
  768   g_type_class_ref (gst_stack_trace_flags_get_type ());
  769   g_type_class_ref (gst_promise_result_get_type ());
  770 
  771   _priv_gst_event_initialize ();
  772   _priv_gst_buffer_initialize ();
  773   _priv_gst_buffer_list_initialize ();
  774   _priv_gst_sample_initialize ();
  775   _priv_gst_context_initialize ();
  776   _priv_gst_date_time_initialize ();
  777   _priv_gst_value_initialize ();
  778   _priv_gst_tag_initialize ();
  779   _priv_gst_toc_initialize ();
  780 
  781   g_type_class_ref (gst_param_spec_fraction_get_type ());
  782   gst_parse_context_get_type ();
  783 
  784   _priv_gst_plugin_initialize ();
  785 
  786   /* register core plugins */
  787   gst_plugin_register_static (GST_VERSION_MAJOR, GST_VERSION_MINOR,
  788       "staticelements", "core elements linked into the GStreamer library",
  789       gst_register_core_elements, VERSION, GST_LICENSE, PACKAGE,
  790       GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);
  791 
  792   /*
  793    * Any errors happening below this point are non-fatal, we therefore mark
  794    * gstreamer as being initialized, since it is the case from a plugin point of
  795    * view.
  796    *
  797    * If anything fails, it will be put back to %FALSE in gst_init_check().
  798    * This allows some special plugins that would call gst_init() to not cause a
  799    * looping effect (i.e. initializing GStreamer twice).
  800    */
  801   gst_initialized = TRUE;
  802 
  803   if (!gst_update_registry ())
  804     return FALSE;
  805 
  806   GST_INFO ("GLib runtime version: %d.%d.%d", glib_major_version,
  807       glib_minor_version, glib_micro_version);
  808   GST_INFO ("GLib headers version: %d.%d.%d", GLIB_MAJOR_VERSION,
  809       GLIB_MINOR_VERSION, GLIB_MICRO_VERSION);
  810   GST_INFO ("initialized GStreamer successfully");
  811 
  812 #ifndef GST_DISABLE_GST_DEBUG
  813   _priv_gst_tracing_init ();
  814 #endif
  815 
  816   return TRUE;
  817 }
  818 
  819 #ifndef GST_DISABLE_OPTION_PARSING
  820 #  ifndef GST_DISABLE_GST_DEBUG
  821 static gboolean
  822 select_all (GstPlugin * plugin, gpointer user_data)
  823 {
  824   return TRUE;
  825 }
  826 
  827 static gint
  828 sort_by_category_name (gconstpointer a, gconstpointer b)
  829 {
  830   return strcmp (gst_debug_category_get_name ((GstDebugCategory *) a),
  831       gst_debug_category_get_name ((GstDebugCategory *) b));
  832 }
  833 
  834 static void
  835 gst_debug_help (void)
  836 {
  837   GSList *list, *walk;
  838   GList *list2, *g;
  839 
  840   /* Need to ensure the registry is loaded to get debug categories */
  841   if (!init_post (NULL, NULL, NULL, NULL))
  842     exit (1);
  843 
  844   list2 = gst_registry_plugin_filter (gst_registry_get (),
  845       select_all, FALSE, NULL);
  846 
  847   /* FIXME this is gross.  why don't debug have categories PluginFeatures? */
  848   for (g = list2; g; g = g_list_next (g)) {
  849     GstPlugin *plugin = GST_PLUGIN_CAST (g->data);
  850     GList *features, *orig_features;
  851 
  852     if (GST_OBJECT_FLAG_IS_SET (plugin, GST_PLUGIN_FLAG_BLACKLISTED))
  853       continue;
  854 
  855     gst_plugin_load (plugin);
  856     /* Now create one of each feature so the class_init functions
  857      * are called, as that's where most debug categories are
  858      * registered. FIXME: If debug categories were a plugin feature,
  859      * this would be unneeded */
  860     orig_features = features =
  861         gst_registry_get_feature_list_by_plugin (gst_registry_get (),
  862         gst_plugin_get_name (plugin));
  863     while (features) {
  864       GstPluginFeature *feature;
  865 
  866       if (G_UNLIKELY (features->data == NULL))
  867         goto next;
  868 
  869       feature = GST_PLUGIN_FEATURE (features->data);
  870       if (GST_IS_ELEMENT_FACTORY (feature)) {
  871         GstElementFactory *factory;
  872         GstElement *e;
  873 
  874         factory = GST_ELEMENT_FACTORY (feature);
  875         e = gst_element_factory_create (factory, NULL);
  876         if (e)
  877           gst_object_unref (e);
  878       }
  879 
  880     next:
  881       features = g_list_next (features);
  882     }
  883 
  884     gst_plugin_feature_list_free (orig_features);
  885   }
  886   g_list_free (list2);
  887 
  888   list = gst_debug_get_all_categories ();
  889   walk = list = g_slist_sort (list, sort_by_category_name);
  890 
  891   g_print ("\n");
  892   g_print ("name                  level    description\n");
  893   g_print ("---------------------+--------+--------------------------------\n");
  894 
  895   while (walk) {
  896     gboolean on_unix;
  897     GstDebugCategory *cat = (GstDebugCategory *) walk->data;
  898     GstDebugColorMode coloring = gst_debug_get_color_mode ();
  899 #ifdef G_OS_UNIX
  900     on_unix = TRUE;
  901 #else
  902     on_unix = FALSE;
  903 #endif
  904 
  905     if (GST_DEBUG_COLOR_MODE_UNIX == coloring
  906         || (on_unix && GST_DEBUG_COLOR_MODE_ON == coloring)) {
  907       gchar *color = gst_debug_construct_term_color (cat->color);
  908 
  909       g_print ("%s%-20s\033[00m  %1d %s  %s%s\033[00m\n",
  910           color,
  911           gst_debug_category_get_name (cat),
  912           gst_debug_category_get_threshold (cat),
  913           gst_debug_level_get_name (gst_debug_category_get_threshold (cat)),
  914           color, gst_debug_category_get_description (cat));
  915       g_free (color);
  916     } else if (GST_DEBUG_COLOR_MODE_ON == coloring && !on_unix) {
  917 #ifdef G_OS_WIN32
  918       gint color = gst_debug_construct_win_color (cat->color);
  919       const gint clear = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
  920 
  921       SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), color);
  922       g_print ("%-20s", gst_debug_category_get_name (cat));
  923       SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), clear);
  924       g_print (" %1d %s ", gst_debug_category_get_threshold (cat),
  925           gst_debug_level_get_name (gst_debug_category_get_threshold (cat)));
  926       SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), color);
  927       g_print ("%s", gst_debug_category_get_description (cat));
  928       SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), clear);
  929       g_print ("\n");
  930 #endif /* G_OS_WIN32 */
  931     } else {
  932       g_print ("%-20s  %1d %s  %s\n", gst_debug_category_get_name (cat),
  933           gst_debug_category_get_threshold (cat),
  934           gst_debug_level_get_name (gst_debug_category_get_threshold (cat)),
  935           gst_debug_category_get_description (cat));
  936     }
  937     walk = g_slist_next (walk);
  938   }
  939   g_slist_free (list);
  940   g_print ("\n");
  941 }
  942 #  endif /* GST_DISABLE_OPTION_PARSING */
  943 #endif /* GST_DISABLE_GST_DEBUG */
  944 
  945 #ifndef GST_DISABLE_OPTION_PARSING
  946 static gboolean
  947 parse_one_option (gint opt, const gchar * arg, GError ** err)
  948 {
  949   switch (opt) {
  950     case ARG_VERSION:
  951       g_print ("GStreamer Core Library version %s\n", PACKAGE_VERSION);
  952       exit (0);
  953     case ARG_FATAL_WARNINGS:{
  954       GLogLevelFlags fatal_mask;
  955 
  956       fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
  957       fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
  958       g_log_set_always_fatal (fatal_mask);
  959       break;
  960     }
  961 #ifndef GST_DISABLE_GST_DEBUG
  962     case ARG_DEBUG_LEVEL:{
  963       GstDebugLevel tmp = GST_LEVEL_NONE;
  964 
  965       tmp = (GstDebugLevel) strtol (arg, NULL, 0);
  966       if (((guint) tmp) < GST_LEVEL_COUNT) {
  967         gst_debug_set_default_threshold (tmp);
  968       }
  969       break;
  970     }
  971     case ARG_DEBUG:
  972       gst_debug_set_threshold_from_string (arg, FALSE);
  973       break;
  974     case ARG_DEBUG_NO_COLOR:
  975       gst_debug_set_colored (FALSE);
  976       break;
  977     case ARG_DEBUG_COLOR_MODE:
  978       gst_debug_set_color_mode_from_string (arg);
  979       break;
  980     case ARG_DEBUG_DISABLE:
  981       gst_debug_set_active (FALSE);
  982       break;
  983     case ARG_DEBUG_HELP:
  984       gst_debug_help ();
  985       exit (0);
  986 #endif
  987     case ARG_PLUGIN_SPEW:
  988       break;
  989     case ARG_PLUGIN_PATH:
  990 #ifndef GST_DISABLE_REGISTRY
  991       if (!_priv_gst_disable_registry)
  992         split_and_iterate (arg, G_SEARCHPATH_SEPARATOR_S, add_path_func, NULL);
  993 #endif /* GST_DISABLE_REGISTRY */
  994       break;
  995     case ARG_PLUGIN_LOAD:
  996       split_and_iterate (arg, ",", prepare_for_load_plugin_func, NULL);
  997       break;
  998     case ARG_SEGTRAP_DISABLE:
  999       _gst_disable_segtrap = TRUE;
 1000       break;
 1001     case ARG_REGISTRY_UPDATE_DISABLE:
 1002 #ifndef GST_DISABLE_REGISTRY
 1003       if (!_priv_gst_disable_registry)
 1004         _priv_gst_disable_registry_update = TRUE;
 1005 #endif
 1006       break;
 1007     case ARG_REGISTRY_FORK_DISABLE:
 1008       gst_registry_fork_set_enabled (FALSE);
 1009       break;
 1010     default:
 1011       g_set_error (err, G_OPTION_ERROR, G_OPTION_ERROR_UNKNOWN_OPTION,
 1012           _("Unknown option"));
 1013       return FALSE;
 1014   }
 1015 
 1016   return TRUE;
 1017 }
 1018 
 1019 static gboolean
 1020 parse_goption_arg (const gchar * opt,
 1021     const gchar * arg, gpointer data, GError ** err)
 1022 {
 1023   static const struct
 1024   {
 1025     const gchar *opt;
 1026     int val;
 1027   } options[] = {
 1028     {
 1029     "--gst-version", ARG_VERSION}, {
 1030     "--gst-fatal-warnings", ARG_FATAL_WARNINGS},
 1031 #ifndef GST_DISABLE_GST_DEBUG
 1032     {
 1033     "--gst-debug-level", ARG_DEBUG_LEVEL}, {
 1034     "--gst-debug", ARG_DEBUG}, {
 1035     "--gst-debug-disable", ARG_DEBUG_DISABLE}, {
 1036     "--gst-debug-no-color", ARG_DEBUG_NO_COLOR}, {
 1037     "--gst-debug-color-mode", ARG_DEBUG_COLOR_MODE}, {
 1038     "--gst-debug-help", ARG_DEBUG_HELP},
 1039 #endif
 1040     {
 1041     "--gst-plugin-spew", ARG_PLUGIN_SPEW}, {
 1042     "--gst-plugin-path", ARG_PLUGIN_PATH}, {
 1043     "--gst-plugin-load", ARG_PLUGIN_LOAD}, {
 1044     "--gst-disable-segtrap", ARG_SEGTRAP_DISABLE}, {
 1045     "--gst-disable-registry-update", ARG_REGISTRY_UPDATE_DISABLE}, {
 1046     "--gst-disable-registry-fork", ARG_REGISTRY_FORK_DISABLE}, {
 1047     NULL}
 1048   };
 1049   gint val = 0, n;
 1050 
 1051   for (n = 0; options[n].opt; n++) {
 1052     if (!strcmp (opt, options[n].opt)) {
 1053       val = options[n].val;
 1054       break;
 1055     }
 1056   }
 1057 
 1058   return parse_one_option (val, arg, err);
 1059 }
 1060 #endif
 1061 
 1062 /**
 1063  * gst_deinit:
 1064  *
 1065  * Clean up any resources created by GStreamer in gst_init().
 1066  *
 1067  * It is normally not needed to call this function in a normal application
 1068  * as the resources will automatically be freed when the program terminates.
 1069  * This function is therefore mostly used by testsuites and other memory
 1070  * profiling tools.
 1071  *
 1072  * After this call GStreamer (including this method) should not be used anymore.
 1073  */
 1074 void
 1075 gst_deinit (void)
 1076 {
 1077   GstBinClass *bin_class;
 1078   GstClock *clock;
 1079 
 1080   if (!gst_initialized)
 1081     return;
 1082 
 1083   GST_INFO ("deinitializing GStreamer");
 1084 
 1085   if (gst_deinitialized) {
 1086     GST_DEBUG ("already deinitialized");
 1087     return;
 1088   }
 1089   g_thread_pool_set_max_unused_threads (0);
 1090   bin_class = (GstBinClass *) g_type_class_peek (gst_bin_get_type ());
 1091   if (bin_class && bin_class->pool != NULL) {
 1092     g_thread_pool_free (bin_class->pool, FALSE, TRUE);
 1093     bin_class->pool = NULL;
 1094   }
 1095   gst_task_cleanup_all ();
 1096 
 1097   g_slist_foreach (_priv_gst_preload_plugins, (GFunc) g_free, NULL);
 1098   g_slist_free (_priv_gst_preload_plugins);
 1099   _priv_gst_preload_plugins = NULL;
 1100 
 1101 #ifndef GST_DISABLE_REGISTRY
 1102   g_list_foreach (_priv_gst_plugin_paths, (GFunc) g_free, NULL);
 1103   g_list_free (_priv_gst_plugin_paths);
 1104   _priv_gst_plugin_paths = NULL;
 1105 #endif
 1106 
 1107   if (_gst_executable_path) {
 1108     g_free (_gst_executable_path);
 1109     _gst_executable_path = NULL;
 1110   }
 1111 
 1112   clock = gst_system_clock_obtain ();
 1113   gst_object_unref (clock);
 1114   gst_object_unref (clock);
 1115 
 1116   _priv_gst_registry_cleanup ();
 1117   _priv_gst_allocator_cleanup ();
 1118 
 1119   /* We want to destroy tracers as late as possible for the leaks tracer
 1120    * but still need to keep the caps system alive as it may have to use
 1121    * gst_caps_to_string() to display leaked caps. */
 1122 #ifndef GST_DISABLE_GST_DEBUG
 1123   _priv_gst_tracing_deinit ();
 1124 #endif
 1125 
 1126   _priv_gst_caps_features_cleanup ();
 1127   _priv_gst_caps_cleanup ();
 1128   _priv_gst_debug_cleanup ();
 1129 
 1130   g_type_class_unref (g_type_class_peek (gst_object_get_type ()));
 1131   g_type_class_unref (g_type_class_peek (gst_pad_get_type ()));
 1132   g_type_class_unref (g_type_class_peek (gst_element_factory_get_type ()));
 1133   g_type_class_unref (g_type_class_peek (gst_element_get_type ()));
 1134   g_type_class_unref (g_type_class_peek (gst_tracer_factory_get_type ()));
 1135   g_type_class_unref (g_type_class_peek (gst_type_find_factory_get_type ()));
 1136   g_type_class_unref (g_type_class_peek (gst_bin_get_type ()));
 1137   g_type_class_unref (g_type_class_peek (gst_bus_get_type ()));
 1138   g_type_class_unref (g_type_class_peek (gst_task_get_type ()));
 1139   g_type_class_unref (g_type_class_peek (gst_object_flags_get_type ()));
 1140   g_type_class_unref (g_type_class_peek (gst_bin_flags_get_type ()));
 1141   g_type_class_unref (g_type_class_peek (gst_buffer_flags_get_type ()));
 1142   g_type_class_unref (g_type_class_peek (gst_buffer_copy_flags_get_type ()));
 1143   g_type_class_unref (g_type_class_peek (gst_bus_flags_get_type ()));
 1144   g_type_class_unref (g_type_class_peek (gst_bus_sync_reply_get_type ()));
 1145   g_type_class_unref (g_type_class_peek (gst_caps_flags_get_type ()));
 1146   g_type_class_unref (g_type_class_peek (gst_clock_type_get_type ()));
 1147   g_type_class_unref (g_type_class_peek (gst_clock_return_get_type ()));
 1148   g_type_class_unref (g_type_class_peek (gst_clock_entry_type_get_type ()));
 1149   g_type_class_unref (g_type_class_peek (gst_clock_flags_get_type ()));
 1150   g_type_class_unref (g_type_class_peek (gst_debug_graph_details_get_type ()));
 1151   g_type_class_unref (g_type_class_peek (gst_state_get_type ()));
 1152   g_type_class_unref (g_type_class_peek (gst_state_change_return_get_type ()));
 1153   g_type_class_unref (g_type_class_peek (gst_state_change_get_type ()));
 1154   g_type_class_unref (g_type_class_peek (gst_element_flags_get_type ()));
 1155   g_type_class_unref (g_type_class_peek (gst_tracer_value_scope_get_type ()));
 1156   g_type_class_unref (g_type_class_peek (gst_tracer_value_flags_get_type ()));
 1157   g_type_class_unref (g_type_class_peek (gst_core_error_get_type ()));
 1158   g_type_class_unref (g_type_class_peek (gst_library_error_get_type ()));
 1159   g_type_class_unref (g_type_class_peek (gst_plugin_dependency_flags_get_type
 1160           ()));
 1161   g_type_class_unref (g_type_class_peek (gst_parse_flags_get_type ()));
 1162   g_type_class_unref (g_type_class_peek (gst_resource_error_get_type ()));
 1163   g_type_class_unref (g_type_class_peek (gst_search_mode_get_type ()));
 1164   g_type_class_unref (g_type_class_peek (gst_stream_error_get_type ()));
 1165   g_type_class_unref (g_type_class_peek (gst_stream_status_type_get_type ()));
 1166   g_type_class_unref (g_type_class_peek (gst_structure_change_type_get_type
 1167           ()));
 1168   g_type_class_unref (g_type_class_peek (gst_event_type_flags_get_type ()));
 1169   g_type_class_unref (g_type_class_peek (gst_event_type_get_type ()));
 1170   g_type_class_unref (g_type_class_peek (gst_seek_type_get_type ()));
 1171   g_type_class_unref (g_type_class_peek (gst_seek_flags_get_type ()));
 1172   g_type_class_unref (g_type_class_peek (gst_qos_type_get_type ()));
 1173   g_type_class_unref (g_type_class_peek (gst_format_get_type ()));
 1174   g_type_class_unref (g_type_class_peek (gst_debug_level_get_type ()));
 1175   g_type_class_unref (g_type_class_peek (gst_debug_color_flags_get_type ()));
 1176   g_type_class_unref (g_type_class_peek (gst_iterator_result_get_type ()));
 1177   g_type_class_unref (g_type_class_peek (gst_iterator_item_get_type ()));
 1178   g_type_class_unref (g_type_class_peek (gst_message_type_get_type ()));
 1179   g_type_class_unref (g_type_class_peek (gst_meta_flags_get_type ()));
 1180   g_type_class_unref (g_type_class_peek (gst_mini_object_flags_get_type ()));
 1181   g_type_class_unref (g_type_class_peek (gst_pad_link_return_get_type ()));
 1182   g_type_class_unref (g_type_class_peek (gst_pad_link_check_get_type ()));
 1183   g_type_class_unref (g_type_class_peek (gst_flow_return_get_type ()));
 1184   g_type_class_unref (g_type_class_peek (gst_pad_mode_get_type ()));
 1185   g_type_class_unref (g_type_class_peek (gst_pad_direction_get_type ()));
 1186   g_type_class_unref (g_type_class_peek (gst_pad_flags_get_type ()));
 1187   g_type_class_unref (g_type_class_peek (gst_pad_presence_get_type ()));
 1188   g_type_class_unref (g_type_class_peek (gst_pad_template_flags_get_type ()));
 1189   g_type_class_unref (g_type_class_peek (gst_pipeline_flags_get_type ()));
 1190   g_type_class_unref (g_type_class_peek (gst_plugin_error_get_type ()));
 1191   g_type_class_unref (g_type_class_peek (gst_plugin_flags_get_type ()));
 1192   g_type_class_unref (g_type_class_peek (gst_rank_get_type ()));
 1193   g_type_class_unref (g_type_class_peek (gst_query_type_flags_get_type ()));
 1194   g_type_class_unref (g_type_class_peek (gst_query_type_get_type ()));
 1195   g_type_class_unref (g_type_class_peek (gst_buffering_mode_get_type ()));
 1196   g_type_class_unref (g_type_class_peek (gst_tag_merge_mode_get_type ()));
 1197   g_type_class_unref (g_type_class_peek (gst_tag_flag_get_type ()));
 1198   g_type_class_unref (g_type_class_peek (gst_tag_scope_get_type ()));
 1199   g_type_class_unref (g_type_class_peek (gst_task_state_get_type ()));
 1200   g_type_class_unref (g_type_class_peek (gst_toc_entry_type_get_type ()));
 1201   g_type_class_unref (g_type_class_peek (gst_toc_scope_get_type ()));
 1202   g_type_class_unref (g_type_class_peek (gst_type_find_probability_get_type
 1203           ()));
 1204   g_type_class_unref (g_type_class_peek (gst_uri_type_get_type ()));
 1205   g_type_class_unref (g_type_class_peek (gst_uri_error_get_type ()));
 1206   g_type_class_unref (g_type_class_peek (gst_parse_error_get_type ()));
 1207   g_type_class_unref (g_type_class_peek (gst_param_spec_fraction_get_type ()));
 1208   g_type_class_unref (g_type_class_peek (gst_progress_type_get_type ()));
 1209   g_type_class_unref (g_type_class_peek (gst_buffer_pool_acquire_flags_get_type
 1210           ()));
 1211   g_type_class_unref (g_type_class_peek (gst_memory_flags_get_type ()));
 1212   g_type_class_unref (g_type_class_peek (gst_map_flags_get_type ()));
 1213   g_type_class_unref (g_type_class_peek (gst_caps_intersect_mode_get_type ()));
 1214   g_type_class_unref (g_type_class_peek (gst_pad_probe_type_get_type ()));
 1215   g_type_class_unref (g_type_class_peek (gst_pad_probe_return_get_type ()));
 1216   g_type_class_unref (g_type_class_peek (gst_segment_flags_get_type ()));
 1217   g_type_class_unref (g_type_class_peek (gst_scheduling_flags_get_type ()));
 1218   g_type_class_unref (g_type_class_peek (gst_stream_type_get_type ()));
 1219 
 1220   g_type_class_unref (g_type_class_peek (gst_control_binding_get_type ()));
 1221   g_type_class_unref (g_type_class_peek (gst_control_source_get_type ()));
 1222   g_type_class_unref (g_type_class_peek (gst_toc_entry_type_get_type ()));
 1223   g_type_class_unref (g_type_class_peek (gst_toc_loop_type_get_type ()));
 1224   g_type_class_unref (g_type_class_peek (gst_lock_flags_get_type ()));
 1225   g_type_class_unref (g_type_class_peek (gst_allocator_flags_get_type ()));
 1226   g_type_class_unref (g_type_class_peek (gst_stream_flags_get_type ()));
 1227   g_type_class_unref (g_type_class_peek (gst_debug_color_mode_get_type ()));
 1228   g_type_class_unref (g_type_class_peek (gst_stack_trace_flags_get_type ()));
 1229   g_type_class_unref (g_type_class_peek (gst_promise_result_get_type ()));
 1230 
 1231   gst_deinitialized = TRUE;
 1232   GST_INFO ("deinitialized GStreamer");
 1233 }
 1234 
 1235 /**
 1236  * gst_version:
 1237  * @major: (out): pointer to a guint to store the major version number
 1238  * @minor: (out): pointer to a guint to store the minor version number
 1239  * @micro: (out): pointer to a guint to store the micro version number
 1240  * @nano:  (out): pointer to a guint to store the nano version number
 1241  *
 1242  * Gets the version number of the GStreamer library.
 1243  */
 1244 void
 1245 gst_version (guint * major, guint * minor, guint * micro, guint * nano)
 1246 {
 1247   g_return_if_fail (major);
 1248   g_return_if_fail (minor);
 1249   g_return_if_fail (micro);
 1250   g_return_if_fail (nano);
 1251 
 1252   *major = GST_VERSION_MAJOR;
 1253   *minor = GST_VERSION_MINOR;
 1254   *micro = GST_VERSION_MICRO;
 1255   *nano = GST_VERSION_NANO;
 1256 }
 1257 
 1258 /**
 1259  * gst_version_string:
 1260  *
 1261  * This function returns a string that is useful for describing this version
 1262  * of GStreamer to the outside world: user agent strings, logging, ...
 1263  *
 1264  * Returns: (transfer full): a newly allocated string describing this version
 1265  *     of GStreamer.
 1266  */
 1267 
 1268 gchar *
 1269 gst_version_string (void)
 1270 {
 1271   guint major, minor, micro, nano;
 1272 
 1273   gst_version (&major, &minor, &micro, &nano);
 1274   if (nano == 0)
 1275     return g_strdup_printf ("GStreamer %d.%d.%d", major, minor, micro);
 1276   else if (nano == 1)
 1277     return g_strdup_printf ("GStreamer %d.%d.%d (GIT)", major, minor, micro);
 1278   else
 1279     return g_strdup_printf ("GStreamer %d.%d.%d (prerelease)", major, minor,
 1280         micro);
 1281 }
 1282 
 1283 /**
 1284  * gst_segtrap_is_enabled:
 1285  *
 1286  * Some functions in the GStreamer core might install a custom SIGSEGV handler
 1287  * to better catch and report errors to the application. Currently this feature
 1288  * is enabled by default when loading plugins.
 1289  *
 1290  * Applications might want to disable this behaviour with the
 1291  * gst_segtrap_set_enabled() function. This is typically done if the application
 1292  * wants to install its own handler without GStreamer interfering.
 1293  *
 1294  * Returns: %TRUE if GStreamer is allowed to install a custom SIGSEGV handler.
 1295  */
 1296 gboolean
 1297 gst_segtrap_is_enabled (void)
 1298 {
 1299   /* yeps, it's enabled when it's not disabled */
 1300   return !_gst_disable_segtrap;
 1301 }
 1302 
 1303 /**
 1304  * gst_segtrap_set_enabled:
 1305  * @enabled: whether a custom SIGSEGV handler should be installed.
 1306  *
 1307  * Applications might want to disable/enable the SIGSEGV handling of
 1308  * the GStreamer core. See gst_segtrap_is_enabled() for more information.
 1309  */
 1310 void
 1311 gst_segtrap_set_enabled (gboolean enabled)
 1312 {
 1313   _gst_disable_segtrap = !enabled;
 1314 }