/* GStreamer * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * * gst.c: Initialization and non-pipeline operations * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include #include "gst_private.h" #include "gst.h" #include "gstqueue.h" #ifndef GST_DISABLE_TYPEFIND #include "gsttypefind.h" #endif #define MAX_PATH_SPLIT 16 #define GST_PLUGIN_SEPARATOR "," gchar *_gst_progname; extern gint _gst_trace_on; extern gboolean _gst_plugin_spew; static gboolean gst_init_check (int *argc, gchar ***argv); static void load_plugin_func (gpointer data, gpointer user_data); static GSList *preload_plugins = NULL; const gchar *g_log_domain_gstreamer = "GStreamer"; static void debug_log_handler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) { g_log_default_handler(log_domain, log_level, message, user_data); g_on_error_query(NULL); } /** * gst_init: * @argc: pointer to application's argc * @argv: pointer to application's argv * * Initializes the GStreamer library, setting up internal path lists, * registering built-in elements, and loading standard plugins. */ void gst_init (int *argc, char **argv[]) { GLogLevelFlags llf; #ifndef GST_DISABLE_TRACE GstTrace *gst_trace; #endif if (!g_thread_supported ()) g_thread_init (NULL); g_type_init(); if (!gst_init_check (argc,argv)) { exit (0); /* FIXME! */ } llf = G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL; g_log_set_handler(g_log_domain_gstreamer, llf, debug_log_handler, NULL); GST_INFO (GST_CAT_GST_INIT, "Initializing GStreamer Core Library"); gst_object_get_type (); gst_pad_get_type (); gst_real_pad_get_type (); gst_ghost_pad_get_type (); gst_elementfactory_get_type (); gst_element_get_type (); gst_typefactory_get_type (); gst_schedulerfactory_get_type (); gst_bin_get_type (); #ifndef GST_DISABLE_AUTOPLUG gst_autoplugfactory_get_type (); #endif _gst_cpu_initialize (); _gst_props_initialize (); _gst_caps_initialize (); _gst_plugin_initialize (); _gst_event_initialize (); _gst_buffer_initialize (); _gst_buffer_pool_initialize (); /* if we need to preload plugins */ if (preload_plugins) { g_slist_foreach (preload_plugins, load_plugin_func, NULL); g_slist_free (preload_plugins); preload_plugins = NULL; } /* register some standard builtin types */ gst_elementfactory_new ("bin", gst_bin_get_type (), &gst_bin_details); gst_elementfactory_new ("pipeline", gst_pipeline_get_type (), &gst_pipeline_details); gst_elementfactory_new ("thread", gst_thread_get_type (), &gst_thread_details); gst_elementfactory_new ("queue", gst_queue_get_type (), &gst_queue_details); #ifndef GST_DISABLE_TYPEFIND gst_elementfactory_new ("typefind", gst_typefind_get_type (), &gst_typefind_details); #endif #ifndef GST_DISABLE_TRACE _gst_trace_on = 0; if (_gst_trace_on) { gst_trace = gst_trace_new ("gst.trace",1024); gst_trace_set_default (gst_trace); } #endif /* GST_DISABLE_TRACE */ } static void split_and_iterate (const gchar *stringlist, gchar *separator, GFunc iterator) { gchar **strings; gint j = 0; gchar *lastlist = g_strdup (stringlist); while (lastlist) { strings = g_strsplit (lastlist, separator, MAX_PATH_SPLIT); g_free (lastlist); lastlist = NULL; while (strings[j]) { iterator (strings[j], NULL); if (++j == MAX_PATH_SPLIT) { lastlist = g_strdup (strings[j]); g_strfreev (strings); j=0; break; } } } } static void add_path_func (gpointer data, gpointer user_data) { GST_INFO (GST_CAT_GST_INIT, "Adding plugin path: \"%s\"", (gchar *)data); gst_plugin_add_path ((gchar *)data); } static void prepare_for_load_plugin_func (gpointer data, gpointer user_data) { preload_plugins = g_slist_prepend (preload_plugins, data); } static void load_plugin_func (gpointer data, gpointer user_data) { gboolean ret; ret = gst_plugin_load ((gchar *)data); if (ret) GST_INFO (GST_CAT_GST_INIT, "Loaded plugin: \"%s\"", (gchar *)data); else GST_INFO (GST_CAT_GST_INIT, "Failed to load plugin: \"%s\"", (gchar *)data); g_free (data); } static void parse_number (gchar *number, guint32 *val) { /* handle either 0xHEX or dec */ if (*(number+1) == 'x') { sscanf (number+2, "%08x", val); } else { sscanf (number, "%d", val); } } /* returns FALSE if the program can be aborted */ static gboolean gst_init_check (int *argc, gchar ***argv) { gboolean ret = TRUE; gboolean showhelp = FALSE; _gst_progname = NULL; if (argc && argv) { gint i, j, k; _gst_progname = g_strdup(*argv[0]); for (i=1; i< *argc; i++) { if (!strncmp ("--gst-info-mask=", (*argv)[i], 16)) { guint32 val; parse_number ((*argv)[i]+16, &val); gst_info_set_categories (val); (*argv)[i] = NULL; } else if (!strncmp ("--gst-debug-mask=", (*argv)[i], 17)) { guint32 val; parse_number ((*argv)[i]+17, &val); gst_debug_set_categories (val); (*argv)[i] = NULL; } else if (!strncmp ("--gst-mask=", (*argv)[i], 11)) { guint32 val; parse_number ((*argv)[i]+11, &val); gst_debug_set_categories (val); gst_info_set_categories (val); (*argv)[i] = NULL; } else if (!strncmp ("--gst-plugin-spew", (*argv)[i], 17)) { _gst_plugin_spew = TRUE; (*argv)[i] = NULL; } else if (!strncmp ("--gst-plugin-path=", (*argv)[i], 17)) { split_and_iterate ((*argv)[i]+18, G_SEARCHPATH_SEPARATOR_S, add_path_func); (*argv)[i] = NULL; } else if (!strncmp ("--gst-plugin-load=", (*argv)[i], 17)) { split_and_iterate ((*argv)[i]+18, ",", prepare_for_load_plugin_func); (*argv)[i] = NULL; } else if (!strncmp ("--help", (*argv)[i], 6)) { showhelp = TRUE; (*argv)[i] = NULL; } } for (i = 1; i < *argc; i++) { for (k = i; k < *argc; k++) if ((*argv)[k] != NULL) break; if (k > i) { k -= i; for (j = i + k; j < *argc; j++) (*argv)[j-k] = (*argv)[j]; *argc -= k; } } } if (_gst_progname == NULL) { _gst_progname = g_strdup("gstprog"); } /* check for ENV variables */ { const gchar *plugin_path = g_getenv("GST_PLUGIN_PATH"); split_and_iterate (plugin_path, G_SEARCHPATH_SEPARATOR_S, add_path_func); } if (showhelp) { guint i; g_print ("usage %s [OPTION...]\n", _gst_progname); g_print ("\nGStreamer options\n"); g_print (" --gst-info-mask=FLAGS GST info flags to set (current %08x)\n", gst_info_get_categories()); g_print (" --gst-debug-mask=FLAGS GST debugging flags to set\n"); g_print (" --gst-mask=FLAGS GST info *and* debug flags to set\n"); g_print (" --gst-plugin-spew Enable printout of errors while loading GST plugins\n"); g_print (" --gst-plugin-path=PATH Add directories separated with '%s' to the plugin search path\n", G_SEARCHPATH_SEPARATOR_S); g_print (" --gst-plugin-load=PLUGINS Load plugins separated with '%s'\n", GST_PLUGIN_SEPARATOR); g_print ("\n Mask (to be OR'ed) info/debug FLAGS \n"); g_print ("--------------------------------------------------------\n"); for (i = 0; idata; mainloops = g_slist_delete_link (mainloops, mainloops); g_main_loop_quit (loop); } } /** * gst_version: * @major: pointer to a guint to store the major version number * @minor: pointer to a guint to store the minor version number * @micro: pointer to a guint to store the micro version number * * Gets the version number of the GStreamer library */ void gst_version (guint *major, guint *minor, guint *micro) { g_return_if_fail (major); g_return_if_fail (minor); g_return_if_fail (micro); *major = GST_VERSION_MAJOR; *minor = GST_VERSION_MINOR; *micro = GST_VERSION_MICRO; }