2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
5 * gst.c: Initialization and non-pipeline operations
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.
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.
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.
26 #include "gst_private.h"
27 #include "gst-i18n-lib.h"
28 #include <locale.h> /* for LC_ALL */
32 #ifndef GST_DISABLE_REGISTRY
33 #include "registries/gstxmlregistry.h"
34 #endif /* GST_DISABLE_REGISTRY */
35 #include "gstregistrypool.h"
37 #define GST_CAT_DEFAULT GST_CAT_GST_INIT
39 #define MAX_PATH_SPLIT 16
40 #define GST_PLUGIN_SEPARATOR ","
44 #ifndef GST_DISABLE_REGISTRY
45 gboolean _gst_registry_auto_load = TRUE;
46 static GstRegistry *_global_registry;
47 static GstRegistry *_user_registry;
48 static gboolean _gst_registry_fixed = FALSE;
51 static gboolean _gst_use_threads = TRUE;
53 static gboolean _gst_enable_cpu_opt = TRUE;
55 static gboolean gst_initialized = FALSE;
57 /* this will be set in popt callbacks when a problem has been encountered */
58 static gboolean _gst_initialization_failure = FALSE;
59 extern gint _gst_trace_on;
61 /* set to TRUE when segfaults need to be left as is */
62 gboolean _gst_disable_segtrap = FALSE;
64 extern GThreadFunctions gst_thread_dummy_functions;
67 static void load_plugin_func (gpointer data, gpointer user_data);
68 static void init_popt_callback (poptContext context,
69 enum poptCallbackReason reason,
70 const GstPoptOption * option, const char *arg, void *data);
71 static gboolean init_pre (void);
72 static gboolean init_post (void);
74 static GSList *preload_plugins = NULL;
76 const gchar *g_log_domain_gstreamer = "GStreamer";
79 debug_log_handler (const gchar * log_domain,
80 GLogLevelFlags log_level, const gchar * message, gpointer user_data)
82 g_log_default_handler (log_domain, log_level, message, user_data);
83 /* FIXME: do we still need this ? fatal errors these days are all
84 * other than core errors */
85 /* g_on_error_query (NULL); */
92 #ifndef GST_DISABLE_GST_DEBUG
112 /* default scheduler, can be changed in gstscheduler.h with
113 * the GST_SCHEDULER_DEFAULT_NAME define.
115 static const GstPoptOption gstreamer_options[] = {
116 {NULL, NUL, POPT_ARG_CALLBACK | POPT_CBFLAG_PRE | POPT_CBFLAG_POST,
117 (void *) &init_popt_callback, 0, NULL, NULL},
118 /* make sure we use our GETTEXT_PACKAGE as the domain for popt translations */
119 {NULL, NUL, POPT_ARG_INTL_DOMAIN, GETTEXT_PACKAGE, 0, NULL, NULL},
120 {"gst-version", NUL, POPT_ARG_NONE | POPT_ARGFLAG_STRIP, NULL, ARG_VERSION,
121 N_("Print the GStreamer version"), NULL},
122 {"gst-fatal-warnings", NUL, POPT_ARG_NONE | POPT_ARGFLAG_STRIP, NULL,
123 ARG_FATAL_WARNINGS, N_("Make all warnings fatal"), NULL},
125 #ifndef GST_DISABLE_GST_DEBUG
126 {"gst-debug-help", NUL, POPT_ARG_NONE | POPT_ARGFLAG_STRIP, NULL,
127 ARG_DEBUG_HELP, N_("Print available debug categories and exit"), NULL},
128 {"gst-debug-level", NUL, POPT_ARG_INT | POPT_ARGFLAG_STRIP, NULL,
131 ("Default debug level from 1 (only error) to 5 (anything) or 0 for no output"),
133 {"gst-debug", NUL, POPT_ARG_STRING | POPT_ARGFLAG_STRIP, NULL, ARG_DEBUG,
135 ("Comma-separated list of category_name:level pairs to set specific levels for the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3"),
137 {"gst-debug-no-color", NUL, POPT_ARG_NONE | POPT_ARGFLAG_STRIP, NULL,
138 ARG_DEBUG_NO_COLOR, N_("Disable colored debugging output"), NULL},
139 {"gst-debug-disable", NUL, POPT_ARG_NONE | POPT_ARGFLAG_STRIP, NULL,
140 ARG_DEBUG_DISABLE, N_("Disable debugging")},
143 {"gst-disable-cpu-opt", NUL, POPT_ARG_NONE | POPT_ARGFLAG_STRIP, NULL,
144 ARG_DISABLE_CPU_OPT, N_("Disable accelerated CPU instructions"), NULL},
145 {"gst-plugin-spew", NUL, POPT_ARG_NONE | POPT_ARGFLAG_STRIP, NULL,
146 ARG_PLUGIN_SPEW, N_("Enable verbose plugin loading diagnostics"), NULL},
147 {"gst-plugin-path", NUL, POPT_ARG_STRING | POPT_ARGFLAG_STRIP, NULL,
149 N_("path list for loading plugins (separated by '"
150 G_SEARCHPATH_SEPARATOR_S "')"), N_("PATHS")},
151 {"gst-plugin-load", NUL, POPT_ARG_STRING | POPT_ARGFLAG_STRIP, NULL,
154 ("Comma-separated list of plugins to preload in addition to the list stored in env variable GST_PLUGIN_PATH"),
156 {"gst-disable-segtrap", NUL, POPT_ARG_NONE | POPT_ARGFLAG_STRIP, NULL,
158 N_("Disable trapping of segmentation faults during plugin loading"),
160 {"gst-scheduler", NUL, POPT_ARG_STRING | POPT_ARGFLAG_STRIP, NULL,
162 N_("Scheduler to use ('" GST_SCHEDULER_DEFAULT_NAME
163 "' is the default)"), N_("SCHEDULER")},
164 {"gst-registry", NUL, POPT_ARG_STRING | POPT_ARGFLAG_STRIP, NULL,
165 ARG_REGISTRY, N_("Registry to use"), N_("REGISTRY")},
170 * gst_init_get_popt_table:
172 * Returns a popt option table with GStreamer's argument specifications. The
173 * table is set up to use popt's callback method, so whenever the parsing is
174 * actually performed (via poptGetContext), the GStreamer libraries will
177 * This function is useful if you want to integrate GStreamer with other
178 * libraries that use popt.
180 * Returns: a pointer to the static GStreamer option table.
181 * No free is necessary.
183 const GstPoptOption *
184 gst_init_get_popt_table (void)
186 return gstreamer_options;
191 * @argc: pointer to application's argc
192 * @argv: pointer to application's argv
194 * Initializes the GStreamer library, setting up internal path lists,
195 * registering built-in elements, and loading standard plugins.
197 * This function will return %FALSE if GStreamer could not be initialized
198 * for some reason. If you want your program to fail fatally,
199 * use gst_init() instead.
201 * Returns: %TRUE if GStreamer could be initialized.
204 gst_init_check (int *argc, char **argv[])
206 return gst_init_check_with_popt_table (argc, argv, NULL);
211 * @argc: pointer to application's argc
212 * @argv: pointer to application's argv
214 * Initializes the GStreamer library, setting up internal path lists,
215 * registering built-in elements, and loading standard plugins.
217 * This function will terminate your program if it was unable to initialize
218 * GStreamer for some reason. If you want your program to fall back,
219 * use gst_init_check() instead.
222 gst_init (int *argc, char **argv[])
224 gst_init_with_popt_table (argc, argv, NULL);
228 * gst_init_with_popt_table:
229 * @argc: pointer to application's argc
230 * @argv: pointer to application's argv
231 * @popt_options: pointer to a popt table to append
233 * Initializes the GStreamer library, parsing the options,
234 * setting up internal path lists,
235 * registering built-in elements, and loading standard plugins.
237 * This function will terminate your program if it was unable to initialize
238 * GStreamer for some reason. If you want your program to fall back,
239 * use gst_init_check_with_popt_table() instead.
242 gst_init_with_popt_table (int *argc, char **argv[],
243 const GstPoptOption * popt_options)
245 if (!gst_init_check_with_popt_table (argc, argv, popt_options)) {
246 g_print ("Could not initialize GStreamer !\n");
252 * gst_init_check_with_popt_table:
253 * @argc: pointer to application's argc
254 * @argv: pointer to application's argv
255 * @popt_options: pointer to a popt table to append
257 * Initializes the GStreamer library, parsing the options,
258 * setting up internal path lists,
259 * registering built-in elements, and loading standard plugins.
261 * Returns: %TRUE if GStreamer could be initialized.
264 gst_init_check_with_popt_table (int *argc, char **argv[],
265 const GstPoptOption * popt_options)
269 GstPoptOption *options;
270 GstPoptOption options_with[] = {
271 {NULL, NUL, POPT_ARG_INCLUDE_TABLE, poptHelpOptions, 0, "Help options:",
273 {NULL, NUL, POPT_ARG_INCLUDE_TABLE, (GstPoptOption *) gstreamer_options, 0,
274 "GStreamer options:", NULL},
275 {NULL, NUL, POPT_ARG_INCLUDE_TABLE, (GstPoptOption *) popt_options, 0,
276 "Application options:", NULL},
279 GstPoptOption options_without[] = {
280 {NULL, NUL, POPT_ARG_INCLUDE_TABLE, poptHelpOptions, 0, "Help options:",
282 {NULL, NUL, POPT_ARG_INCLUDE_TABLE, (GstPoptOption *) gstreamer_options, 0,
283 "GStreamer options:", NULL},
287 if (gst_initialized) {
288 GST_DEBUG ("already initialized gst");
292 if (!argc || !argv) {
294 g_warning ("gst_init: Only one of argc or argv was NULL");
300 gst_initialized = TRUE;
304 if (popt_options == NULL) {
305 options = options_without;
307 options = options_with;
309 context = poptGetContext ("GStreamer", *argc, (const char **) *argv,
312 while ((nextopt = poptGetNextOpt (context)) > 0) {
313 /* we only check for failures here, actual work is done in callbacks */
314 if (_gst_initialization_failure)
319 g_print ("Error on option %s: %s.\nRun '%s --help' "
320 "to see a full list of available command line options.\n",
321 poptBadOption (context, 0), poptStrerror (nextopt), (*argv)[0]);
323 poptFreeContext (context);
327 *argc = poptStrippedArgv (context, *argc, *argv);
329 poptFreeContext (context);
334 #ifndef GST_DISABLE_REGISTRY
336 add_path_func (gpointer data, gpointer user_data)
338 GstRegistry *registry = GST_REGISTRY (user_data);
340 GST_INFO ("Adding plugin path: \"%s\"", (gchar *) data);
341 gst_registry_add_path (registry, (gchar *) data);
346 prepare_for_load_plugin_func (gpointer data, gpointer user_data)
348 preload_plugins = g_slist_prepend (preload_plugins, data);
352 parse_debug_list (const gchar * list)
357 g_return_if_fail (list != NULL);
359 walk = split = g_strsplit (list, ",", 0);
362 gchar **values = g_strsplit (walk[0], ":", 2);
364 if (values[0] && values[1]) {
367 g_strstrip (values[0]);
368 g_strstrip (values[1]);
369 level = strtol (values[1], NULL, 0);
370 if (level >= 0 && level < GST_LEVEL_COUNT) {
371 GST_DEBUG ("setting debugging to level %d for name \"%s\"",
373 gst_debug_set_threshold_for_name (values[0], level);
382 load_plugin_func (gpointer data, gpointer user_data)
385 const gchar *filename;
387 filename = (const gchar *) data;
389 plugin = gst_plugin_load_file (filename, NULL);
392 GST_INFO ("Loaded plugin: \"%s\"", filename);
394 gst_registry_pool_add_plugin (plugin);
396 GST_WARNING ("Failed to load plugin: \"%s\"", filename);
403 split_and_iterate (const gchar * stringlist, gchar * separator, GFunc iterator,
408 gchar *lastlist = g_strdup (stringlist);
411 strings = g_strsplit (lastlist, separator, MAX_PATH_SPLIT);
416 iterator (strings[j], user_data);
417 if (++j == MAX_PATH_SPLIT) {
418 lastlist = g_strdup (strings[j]);
419 g_strfreev (strings);
427 /* we have no fail cases yet, but maybe in the future */
433 if (g_thread_supported ()) {
434 /* somebody already initialized threading */
435 _gst_use_threads = TRUE;
437 if (_gst_use_threads)
438 g_thread_init (NULL);
440 g_thread_init (&gst_thread_dummy_functions);
442 /* we need threading to be enabled right here */
446 setlocale (LC_ALL, "");
447 bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
448 #endif /* ENABLE_NLS */
450 #ifndef GST_DISABLE_REGISTRY
452 const gchar *debug_list;
454 debug_list = g_getenv ("GST_DEBUG");
456 parse_debug_list (debug_list);
460 #ifndef GST_DISABLE_REGISTRY
463 const gchar *homedir;
466 gst_xml_registry_new ("global_registry", GLOBAL_REGISTRY_FILE);
468 #ifdef PLUGINS_USE_BUILDDIR
469 /* location libgstelements.so */
470 gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/libs/gst");
471 gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/elements");
472 gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/types");
473 gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/autoplug");
474 gst_registry_add_path (_global_registry,
475 PLUGINS_BUILDDIR "/gst/schedulers");
476 gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/indexers");
478 /* add the main (installed) library path */
479 gst_registry_add_path (_global_registry, PLUGINS_DIR);
480 #endif /* PLUGINS_USE_BUILDDIR */
482 if (g_getenv ("GST_REGISTRY")) {
483 user_reg = g_strdup (g_getenv ("GST_REGISTRY"));
485 homedir = g_get_home_dir ();
486 user_reg = g_strjoin ("/", homedir, LOCAL_REGISTRY_FILE, NULL);
488 _user_registry = gst_xml_registry_new ("user_registry", user_reg);
492 #endif /* GST_DISABLE_REGISTRY */
498 gst_register_core_elements (GstPlugin * plugin)
500 /* register some standard builtin types */
501 g_assert (gst_element_register (plugin, "bin", GST_RANK_PRIMARY,
503 g_assert (gst_element_register (plugin, "pipeline", GST_RANK_PRIMARY,
505 g_assert (gst_element_register (plugin, "thread", GST_RANK_PRIMARY,
507 g_assert (gst_element_register (plugin, "queue", GST_RANK_PRIMARY,
513 static GstPluginDesc plugin_desc = {
517 "core elements of the GStreamer library",
518 gst_register_core_elements,
530 * - initalization of threads if we use them
533 * - initializes gst_format
534 * - registers a bunch of types for gst_objects
536 * - we don't have cases yet where this fails, but in the future
537 * we might and then it's nice to be able to return that
543 const gchar *plugin_path;
545 #ifndef GST_DISABLE_TRACE
547 #endif /* GST_DISABLE_TRACE */
549 llf = G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL;
550 g_log_set_handler (g_log_domain_gstreamer, llf, debug_log_handler, NULL);
552 GST_INFO ("Initializing GStreamer Core Library version %s %s",
553 VERSION, _gst_use_threads ? "" : "(no threads)");
555 _gst_format_initialize ();
556 _gst_query_type_initialize ();
557 gst_object_get_type ();
559 gst_real_pad_get_type ();
560 gst_ghost_pad_get_type ();
561 gst_element_factory_get_type ();
562 gst_element_get_type ();
563 gst_scheduler_factory_get_type ();
564 gst_type_find_factory_get_type ();
566 #ifndef GST_DISABLE_INDEX
567 gst_index_factory_get_type ();
568 #endif /* GST_DISABLE_INDEX */
569 #ifndef GST_DISABLE_URI
570 gst_uri_handler_get_type ();
571 #endif /* GST_DISABLE_URI */
573 plugin_path = g_getenv ("GST_PLUGIN_PATH");
574 #ifndef GST_DISABLE_REGISTRY
575 split_and_iterate (plugin_path, G_SEARCHPATH_SEPARATOR_S, add_path_func,
577 #endif /* GST_DISABLE_REGISTRY */
579 /* register core plugins */
580 _gst_plugin_register_static (&plugin_desc);
582 _gst_cpu_initialize (_gst_enable_cpu_opt);
583 gst_structure_get_type ();
584 _gst_value_initialize ();
585 gst_caps_get_type ();
586 _gst_plugin_initialize ();
587 _gst_event_initialize ();
588 _gst_buffer_initialize ();
589 _gst_tag_initialize ();
591 #ifndef GST_DISABLE_REGISTRY
592 if (!_gst_registry_fixed) {
593 /* don't override command-line options */
594 if (g_getenv ("GST_REGISTRY")) {
595 g_object_set (_global_registry, "location", g_getenv ("GST_REGISTRY"),
597 _gst_registry_fixed = TRUE;
601 if (!_gst_registry_fixed) {
602 gst_registry_pool_add (_global_registry, 100);
603 gst_registry_pool_add (_user_registry, 50);
605 gst_registry_pool_add (_global_registry, 100);
608 if (_gst_registry_auto_load) {
609 gst_registry_pool_load_all ();
611 #endif /* GST_DISABLE_REGISTRY */
613 /* if we need to preload plugins */
614 if (preload_plugins) {
615 g_slist_foreach (preload_plugins, load_plugin_func, NULL);
616 g_slist_free (preload_plugins);
617 preload_plugins = NULL;
619 #ifndef GST_DISABLE_TRACE
622 gst_trace = gst_trace_new ("gst.trace", 1024);
623 gst_trace_set_default (gst_trace);
625 #endif /* GST_DISABLE_TRACE */
626 if (_gst_progname == NULL) {
627 _gst_progname = g_strdup ("gstprog");
633 #ifndef GST_DISABLE_GST_DEBUG
635 sort_by_category_name (gconstpointer a, gconstpointer b)
637 return strcmp (gst_debug_category_get_name ((GstDebugCategory *) a),
638 gst_debug_category_get_name ((GstDebugCategory *) b));
641 gst_debug_help (void)
644 GList *list2, *walk2;
649 walk2 = list2 = gst_registry_pool_plugin_list ();
651 GstPlugin *plugin = GST_PLUGIN (walk2->data);
653 walk2 = g_list_next (walk2);
655 if (!gst_plugin_is_loaded (plugin)) {
656 #ifndef GST_DISABLE_REGISTRY
657 if (GST_IS_REGISTRY (plugin->manager)) {
658 GST_CAT_LOG (GST_CAT_PLUGIN_LOADING, "loading plugin %s",
660 if (gst_registry_load_plugin (GST_REGISTRY (plugin->manager),
661 plugin) != GST_REGISTRY_OK)
662 GST_CAT_WARNING (GST_CAT_PLUGIN_LOADING, "loading plugin %s failed",
665 #endif /* GST_DISABLE_REGISTRY */
670 list = gst_debug_get_all_categories ();
671 walk = list = g_slist_sort (list, sort_by_category_name);
674 g_print ("name level description\n");
675 g_print ("---------------------+--------+--------------------------------\n");
678 GstDebugCategory *cat = (GstDebugCategory *) walk->data;
680 if (gst_debug_is_colored ()) {
681 gchar *color = gst_debug_construct_term_color (cat->color);
683 g_print ("%s%-20s\033[00m %1d %s %s%s\033[00m\n",
685 gst_debug_category_get_name (cat),
686 gst_debug_category_get_threshold (cat),
687 gst_debug_level_get_name (gst_debug_category_get_threshold (cat)),
688 color, gst_debug_category_get_description (cat));
691 g_print ("%-20s %1d %s %s\n", gst_debug_category_get_name (cat),
692 gst_debug_category_get_threshold (cat),
693 gst_debug_level_get_name (gst_debug_category_get_threshold (cat)),
694 gst_debug_category_get_description (cat));
696 walk = g_slist_next (walk);
704 init_popt_callback (poptContext context, enum poptCallbackReason reason,
705 const GstPoptOption * option, const char *arg, void *data)
707 GLogLevelFlags fatal_mask;
712 case POPT_CALLBACK_REASON_PRE:
714 _gst_initialization_failure = TRUE;
716 case POPT_CALLBACK_REASON_OPTION:
717 switch (option->val) {
719 g_print ("GStreamer Core Library version %s\n", GST_VERSION);
721 case ARG_FATAL_WARNINGS:
722 fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
723 fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
724 g_log_set_always_fatal (fatal_mask);
726 #ifndef GST_DISABLE_GST_DEBUG
727 case ARG_DEBUG_LEVEL:{
730 tmp = strtol (arg, NULL, 0);
731 if (tmp >= 0 && tmp < GST_LEVEL_COUNT) {
732 gst_debug_set_default_threshold (tmp);
737 parse_debug_list (arg);
739 case ARG_DEBUG_NO_COLOR:
740 gst_debug_set_colored (FALSE);
742 case ARG_DEBUG_DISABLE:
743 gst_debug_set_active (FALSE);
749 case ARG_DISABLE_CPU_OPT:
750 _gst_enable_cpu_opt = FALSE;
752 case ARG_PLUGIN_SPEW:
754 case ARG_PLUGIN_PATH:
755 #ifndef GST_DISABLE_REGISTRY
756 split_and_iterate (arg, G_SEARCHPATH_SEPARATOR_S, add_path_func,
758 #endif /* GST_DISABLE_REGISTRY */
760 case ARG_PLUGIN_LOAD:
761 split_and_iterate (arg, ",", prepare_for_load_plugin_func, NULL);
763 case ARG_SEGTRAP_DISABLE:
764 _gst_disable_segtrap = TRUE;
767 gst_scheduler_factory_set_default_name (arg);
770 #ifndef GST_DISABLE_REGISTRY
771 g_object_set (G_OBJECT (_user_registry), "location", arg, NULL);
772 _gst_registry_fixed = TRUE;
773 #endif /* GST_DISABLE_REGISTRY */
776 g_warning ("option %d not recognized", option->val);
780 case POPT_CALLBACK_REASON_POST:
782 _gst_initialization_failure = TRUE;
783 gst_initialized = TRUE;
790 * @use_threads: a #gboolean indicating whether threads should be used
792 * Instructs the core to turn on/off threading. When threading
793 * is turned off, all thread operations such as mutexes and conditionals
794 * are turned into NOPs. use this if you want absolute minimal overhead
795 * and you don't use any threads in the pipeline.
797 * This function may only be called before threads are initialized. This
798 * usually happens when calling gst_init.
802 gst_use_threads (gboolean use_threads)
804 g_return_if_fail (!gst_initialized);
805 g_return_if_fail (g_thread_supported ());
807 _gst_use_threads = use_threads;
813 * Queries if GStreamer has threads enabled.
815 * Returns: %TRUE if threads are enabled.
818 gst_has_threads (void)
820 return _gst_use_threads;
824 static GSList *mainloops = NULL;
829 * Enters the main GStreamer processing loop.
836 loop = g_main_loop_new (NULL, FALSE);
837 mainloops = g_slist_prepend (mainloops, loop);
839 g_main_loop_run (loop);
845 * Exits the main GStreamer processing loop.
851 g_error ("Quit more loops than there are");
853 GMainLoop *loop = mainloops->data;
855 mainloops = g_slist_delete_link (mainloops, mainloops);
856 g_main_loop_quit (loop);
857 g_main_loop_unref (loop);
863 * @major: pointer to a guint to store the major version number
864 * @minor: pointer to a guint to store the minor version number
865 * @micro: pointer to a guint to store the micro version number
867 * Gets the version number of the GStreamer library.
870 gst_version (guint * major, guint * minor, guint * micro)
872 g_return_if_fail (major);
873 g_return_if_fail (minor);
874 g_return_if_fail (micro);
876 *major = GST_VERSION_MAJOR;
877 *minor = GST_VERSION_MINOR;
878 *micro = GST_VERSION_MICRO;