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"
31 #ifndef GST_DISABLE_REGISTRY
32 #include "registries/gstxmlregistry.h"
33 #endif /* GST_DISABLE_REGISTRY */
34 #include "gstregistrypool.h"
36 #define GST_CAT_DEFAULT GST_CAT_GST_INIT
38 #define MAX_PATH_SPLIT 16
39 #define GST_PLUGIN_SEPARATOR ","
43 #ifndef GST_DISABLE_REGISTRY
44 gboolean _gst_registry_auto_load = TRUE;
45 static GstRegistry *_global_registry;
46 static GstRegistry *_user_registry;
47 static gboolean _gst_registry_fixed = FALSE;
50 static gboolean _gst_use_threads = TRUE;
52 static gboolean _gst_enable_cpu_opt = TRUE;
54 static gboolean gst_initialized = FALSE;
55 /* this will be set in popt callbacks when a problem has been encountered */
56 static gboolean _gst_initialization_failure = FALSE;
57 extern gint _gst_trace_on;
59 /* set to TRUE when segfaults need to be left as is */
60 gboolean _gst_disable_segtrap = FALSE;
62 extern GThreadFunctions gst_thread_dummy_functions;
65 static void load_plugin_func (gpointer data, gpointer user_data);
66 static void init_popt_callback (poptContext context,
67 enum poptCallbackReason reason,
68 const struct poptOption *option,
69 const char *arg, void *data);
70 static gboolean init_pre (void);
71 static gboolean init_post (void);
73 static GSList *preload_plugins = NULL;
75 const gchar *g_log_domain_gstreamer = "GStreamer";
78 debug_log_handler (const gchar *log_domain,
79 GLogLevelFlags log_level,
83 g_log_default_handler (log_domain, log_level, message, user_data);
84 /* FIXME: do we still need this ? fatal errors these days are all
85 * other than core errors */
86 /* 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 struct poptOption gstreamer_options[] = {
116 {NULL, NUL, POPT_ARG_CALLBACK|POPT_CBFLAG_PRE|POPT_CBFLAG_POST, (void *) &init_popt_callback, 0, NULL, NULL},
117 {"gst-version", NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_VERSION, N_("Print the GStreamer version"), NULL},
118 {"gst-fatal-warnings", NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_FATAL_WARNINGS, N_("Make all warnings fatal"), NULL},
119 #ifndef GST_DISABLE_GST_DEBUG
120 {"gst-debug-level", NUL, POPT_ARG_INT|POPT_ARGFLAG_STRIP, NULL, ARG_DEBUG_LEVEL, N_("default debug level from 1 (only error) to 5 (anything) or 0 for no output"), "LEVEL"},
121 {"gst-debug", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_DEBUG, N_("colon-seperated list of category_name=level pairs to set specific levels for the individual categories.\nExample:GST_AUTOPLUG=5:GST_ELEMENT_*=3"), "CATEGORIES"},
122 {"gst-debug-no-color", NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_DEBUG_NO_COLOR, N_("disable color debugging output"), NULL},
123 {"gst-disable-debug", NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_DEBUG_DISABLE, N_("disable debugging")},
124 {"gst-debug-help", NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_DEBUG_HELP, N_("print available debug categories and exit"), NULL},
126 {"gst-disable-cpu-opt",NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_DISABLE_CPU_OPT,N_("Disable accelerated CPU instructions"), NULL},
127 {"gst-plugin-spew", NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_PLUGIN_SPEW, N_("enable verbose plugin loading diagnostics"), NULL},
128 {"gst-plugin-path", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_PLUGIN_PATH, N_("'" G_SEARCHPATH_SEPARATOR_S "'--separated path list for loading plugins"), "PATHS"},
129 {"gst-plugin-load", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_PLUGIN_LOAD, N_("comma-separated list of plugins to preload in addition to the list stored in env variable GST_PLUGIN_PATH"), "PLUGINS"},
130 {"gst-disable-segtrap",NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_SEGTRAP_DISABLE,N_("disable trapping of segmentation faults during plugin loading"), NULL},
131 {"gst-scheduler", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_SCHEDULER, N_("scheduler to use ('"GST_SCHEDULER_DEFAULT_NAME"' is the default)"), "SCHEDULER"},
132 {"gst-registry", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_REGISTRY, N_("registry to use") , "REGISTRY"},
137 * gst_init_get_popt_table:
139 * Returns a popt option table with GStreamer's argument specifications. The
140 * table is set up to use popt's callback method, so whenever the parsing is
141 * actually performed (via poptGetContext), the GStreamer libraries will
144 * Returns: a pointer to the static GStreamer option table.
145 * No free is necessary.
147 const struct poptOption *
148 gst_init_get_popt_table (void)
150 return gstreamer_options;
155 * @argc: pointer to application's argc
156 * @argv: pointer to application's argv
158 * Initializes the GStreamer library, setting up internal path lists,
159 * registering built-in elements, and loading standard plugins.
161 * This function will return %FALSE if GStreamer could not be initialized
162 * for some reason. If you want your program to fail fatally,
163 * use gst_init() instead.
165 * Returns: %TRUE if GStreamer could be initialized.
168 gst_init_check (int *argc, char **argv[])
170 return gst_init_check_with_popt_table (argc, argv, NULL);
175 * @argc: pointer to application's argc
176 * @argv: pointer to application's argv
178 * Initializes the GStreamer library, setting up internal path lists,
179 * registering built-in elements, and loading standard plugins.
181 * This function will terminate your program if it was unable to initialize
182 * GStreamer for some reason. If you want your program to fall back,
183 * use gst_init_check() instead.
186 gst_init (int *argc, char **argv[])
188 gst_init_with_popt_table (argc, argv, NULL);
192 * gst_init_with_popt_table:
193 * @argc: pointer to application's argc
194 * @argv: pointer to application's argv
195 * @popt_options: pointer to a popt table to append
197 * Initializes the GStreamer library, parsing the options,
198 * setting up internal path lists,
199 * registering built-in elements, and loading standard plugins.
201 * This function will terminate your program if it was unable to initialize
202 * GStreamer for some reason. If you want your program to fall back,
203 * use gst_init_check_with_popt_table() instead.
206 gst_init_with_popt_table (int *argc, char **argv[],
207 const struct poptOption *popt_options)
209 if (!gst_init_check_with_popt_table (argc, argv, popt_options)) {
210 g_print ("Could not initialize GStreamer !\n");
215 * gst_init_check_with_popt_table:
216 * @argc: pointer to application's argc
217 * @argv: pointer to application's argv
218 * @popt_options: pointer to a popt table to append
220 * Initializes the GStreamer library, parsing the options,
221 * setting up internal path lists,
222 * registering built-in elements, and loading standard plugins.
224 * Returns: %TRUE if GStreamer could be initialized.
227 gst_init_check_with_popt_table (int *argc, char **argv[],
228 const struct poptOption *popt_options)
232 struct poptOption *options;
233 struct poptOption options_with[] = {
234 {NULL, NUL, POPT_ARG_INCLUDE_TABLE, poptHelpOptions, 0, "Help options:", NULL},
235 {NULL, NUL, POPT_ARG_INCLUDE_TABLE, (struct poptOption *) gstreamer_options, 0, "GStreamer options:", NULL},
236 {NULL, NUL, POPT_ARG_INCLUDE_TABLE, (struct poptOption *) popt_options, 0, "Application options:", NULL},
239 struct poptOption options_without[] = {
240 {NULL, NUL, POPT_ARG_INCLUDE_TABLE, poptHelpOptions, 0, "Help options:", NULL},
241 {NULL, NUL, POPT_ARG_INCLUDE_TABLE, (struct poptOption *) gstreamer_options, 0, "GStreamer options:", NULL},
247 GST_DEBUG ("already initialized gst");
251 if (!argc || !argv) {
253 g_warning ("gst_init: Only one of argc or argv was NULL");
255 if (!init_pre ()) return FALSE;
256 if (!init_post ()) return FALSE;
257 gst_initialized = TRUE;
261 if (popt_options == NULL) {
262 options = options_without;
264 options = options_with;
266 context = poptGetContext ("GStreamer", *argc, (const char**)*argv,
269 while ((nextopt = poptGetNextOpt (context)) > 0)
271 /* we only check for failures here, actual work is done in callbacks */
272 if (_gst_initialization_failure) return FALSE;
276 g_print ("Error on option %s: %s.\nRun '%s --help' "
277 "to see a full list of available command line options.\n",
278 poptBadOption (context, 0),
279 poptStrerror (nextopt),
282 poptFreeContext (context);
286 *argc = poptStrippedArgv (context, *argc, *argv);
288 poptFreeContext (context);
293 #ifndef GST_DISABLE_REGISTRY
295 add_path_func (gpointer data, gpointer user_data)
297 GstRegistry *registry = GST_REGISTRY (user_data);
299 GST_INFO ("Adding plugin path: \"%s\"", (gchar *) data);
300 gst_registry_add_path (registry, (gchar *)data);
305 prepare_for_load_plugin_func (gpointer data, gpointer user_data)
307 preload_plugins = g_slist_prepend (preload_plugins, data);
311 parse_debug_list (const gchar *list)
316 g_return_if_fail (list != NULL);
318 walk = split = g_strsplit (list, ":", 0);
321 gchar **values = g_strsplit ( walk[0], "=", 2);
322 if (values[0] && values[1]) {
324 g_strstrip (values[0]);
325 g_strstrip (values[1]);
326 level = strtol (values[1], NULL, 0);
327 if (level >= 0 && level < GST_LEVEL_COUNT) {
328 GST_DEBUG ("setting debugging to level %d for name \"%s\"",
330 gst_debug_set_threshold_for_name (values[0], level);
339 load_plugin_func (gpointer data, gpointer user_data)
342 const gchar *filename;
344 filename = (const gchar *) data;
346 plugin = gst_plugin_load_file (filename, NULL);
349 GST_INFO ("Loaded plugin: \"%s\"", filename);
351 gst_registry_pool_add_plugin (plugin);
353 GST_WARNING ("Failed to load plugin: \"%s\"", filename);
360 split_and_iterate (const gchar *stringlist, gchar *separator, GFunc iterator, gpointer user_data)
364 gchar *lastlist = g_strdup (stringlist);
367 strings = g_strsplit (lastlist, separator, MAX_PATH_SPLIT);
372 iterator (strings[j], user_data);
373 if (++j == MAX_PATH_SPLIT) {
374 lastlist = g_strdup (strings[j]);
375 g_strfreev (strings);
383 /* we have no fail cases yet, but maybe in the future */
390 if (g_thread_supported ()) {
391 /* somebody already initialized threading */
392 _gst_use_threads = TRUE;
394 if (_gst_use_threads)
395 g_thread_init (NULL);
397 g_thread_init (&gst_thread_dummy_functions);
399 /* we need threading to be enabled right here */
403 setlocale (LC_ALL, "");
404 bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
405 textdomain (GETTEXT_PACKAGE);
406 #endif /* ENABLE_NLS */
408 #ifndef GST_DISABLE_REGISTRY
410 const gchar *debug_list;
412 debug_list = g_getenv ("GST_DEBUG");
414 parse_debug_list (debug_list);
418 #ifndef GST_DISABLE_REGISTRY
421 const gchar *homedir;
423 _global_registry = gst_xml_registry_new ("global_registry", GLOBAL_REGISTRY_FILE);
425 #ifdef PLUGINS_USE_BUILDDIR
426 /* location libgstelements.so */
427 gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/libs/gst");
428 gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/elements");
429 gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/types");
430 gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/autoplug");
431 gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/schedulers");
432 gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/indexers");
434 /* add the main (installed) library path */
435 gst_registry_add_path (_global_registry, PLUGINS_DIR);
436 #endif /* PLUGINS_USE_BUILDDIR */
438 if (g_getenv ("GST_REGISTRY"))
440 user_reg = g_strdup (g_getenv ("GST_REGISTRY"));
444 homedir = g_get_home_dir ();
445 user_reg = g_strjoin ("/", homedir, LOCAL_REGISTRY_FILE, NULL);
447 _user_registry = gst_xml_registry_new ("user_registry", user_reg);
451 #endif /* GST_DISABLE_REGISTRY */
457 gst_register_core_elements (GstPlugin *plugin)
459 /* register some standard builtin types */
460 g_assert (gst_element_register (plugin, "bin", GST_RANK_PRIMARY, GST_TYPE_BIN));
461 g_assert (gst_element_register (plugin, "pipeline", GST_RANK_PRIMARY, GST_TYPE_PIPELINE));
462 g_assert (gst_element_register (plugin, "thread", GST_RANK_PRIMARY, GST_TYPE_THREAD));
463 g_assert (gst_element_register (plugin, "queue", GST_RANK_PRIMARY, GST_TYPE_QUEUE));
468 static GstPluginDesc plugin_desc = {
472 "core elements of the GStreamer library",
473 gst_register_core_elements,
485 * - initalization of threads if we use them
488 * - initializes gst_format
489 * - registers a bunch of types for gst_objects
491 * - we don't have cases yet where this fails, but in the future
492 * we might and then it's nice to be able to return that
498 const gchar *plugin_path;
499 #ifndef GST_DISABLE_TRACE
501 #endif /* GST_DISABLE_TRACE */
503 llf = G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL;
504 g_log_set_handler (g_log_domain_gstreamer, llf, debug_log_handler, NULL);
506 GST_INFO ("Initializing GStreamer Core Library version %s %s",
507 VERSION, _gst_use_threads ? "" : "(no threads)");
509 _gst_format_initialize ();
510 _gst_query_type_initialize ();
511 gst_object_get_type ();
513 gst_real_pad_get_type ();
514 gst_ghost_pad_get_type ();
515 gst_element_factory_get_type ();
516 gst_element_get_type ();
517 gst_scheduler_factory_get_type ();
518 gst_type_find_factory_get_type ();
520 #ifndef GST_DISABLE_INDEX
521 gst_index_factory_get_type ();
522 #endif /* GST_DISABLE_INDEX */
523 #ifndef GST_DISABLE_URI
524 gst_uri_handler_get_type ();
525 #endif /* GST_DISABLE_URI */
527 plugin_path = g_getenv ("GST_PLUGIN_PATH");
528 #ifndef GST_DISABLE_REGISTRY
529 split_and_iterate (plugin_path, G_SEARCHPATH_SEPARATOR_S, add_path_func, _user_registry);
530 #endif /* GST_DISABLE_REGISTRY */
532 /* register core plugins */
533 _gst_plugin_register_static (&plugin_desc);
535 _gst_cpu_initialize (_gst_enable_cpu_opt);
536 _gst_structure_initialize ();
537 _gst_value_initialize ();
538 _gst_caps_initialize ();
539 _gst_plugin_initialize ();
540 _gst_event_initialize ();
541 _gst_buffer_initialize ();
542 _gst_tag_initialize ();
544 #ifndef GST_DISABLE_REGISTRY
545 if (!_gst_registry_fixed) {
546 /* don't override command-line options */
547 if (g_getenv ("GST_REGISTRY")) {
548 g_object_set (_user_registry, "location", g_getenv ("GST_REGISTRY"), NULL);
549 _gst_registry_fixed = TRUE;
553 if (!_gst_registry_fixed) {
554 gst_registry_pool_add (_global_registry, 100);
555 gst_registry_pool_add (_user_registry, 50);
557 gst_registry_pool_add (_user_registry, 50);
560 if (_gst_registry_auto_load) {
561 gst_registry_pool_load_all ();
563 #endif /* GST_DISABLE_REGISTRY */
565 /* if we need to preload plugins */
566 if (preload_plugins) {
567 g_slist_foreach (preload_plugins, load_plugin_func, NULL);
568 g_slist_free (preload_plugins);
569 preload_plugins = NULL;
572 #ifndef GST_DISABLE_TRACE
575 gst_trace = gst_trace_new ("gst.trace", 1024);
576 gst_trace_set_default (gst_trace);
578 #endif /* GST_DISABLE_TRACE */
579 if (_gst_progname == NULL) {
580 _gst_progname = g_strdup ("gstprog");
586 #ifndef GST_DISABLE_GST_DEBUG
588 sort_by_category_name (gconstpointer a, gconstpointer b)
590 return strcmp (gst_debug_category_get_name ((GstDebugCategory *) a),
591 gst_debug_category_get_name ((GstDebugCategory *) b));
594 gst_debug_help (void)
597 GList *list2, *walk2;
602 walk2 = list2 = gst_registry_pool_plugin_list ();
604 GstPlugin *plugin = GST_PLUGIN (walk2->data);
605 walk2 = g_list_next (walk2);
607 if (!gst_plugin_is_loaded (plugin)) {
608 #ifndef GST_DISABLE_REGISTRY
609 if (GST_IS_REGISTRY (plugin->manager)) {
610 GST_CAT_LOG (GST_CAT_PLUGIN_LOADING, "loading plugin %s", plugin->desc.name);
611 if (gst_registry_load_plugin (GST_REGISTRY (plugin->manager), plugin) != GST_REGISTRY_OK)
612 GST_CAT_WARNING (GST_CAT_PLUGIN_LOADING, "loading plugin %s failed", plugin->desc.name);
614 #endif /* GST_DISABLE_REGISTRY */
619 list = gst_debug_get_all_categories ();
620 walk = list = g_slist_sort (list, sort_by_category_name);
623 g_print ("name level description\n");
624 g_print ("---------------------+--------+--------------------------------\n");
627 GstDebugCategory *cat = (GstDebugCategory *) walk->data;
629 if (gst_debug_is_colored ()) {
630 gchar *color = gst_debug_construct_term_color (cat->color);
631 g_print ("%s%-20s\033[00m %1d %s %s%s\033[00m\n",
633 gst_debug_category_get_name (cat),
634 gst_debug_category_get_threshold (cat),
635 gst_debug_level_get_name (gst_debug_category_get_threshold (cat)),
637 gst_debug_category_get_description (cat));
640 g_print ("%-20s %1d %s %s\n", gst_debug_category_get_name (cat),
641 gst_debug_category_get_threshold (cat),
642 gst_debug_level_get_name (gst_debug_category_get_threshold (cat)),
643 gst_debug_category_get_description (cat));
645 walk = g_slist_next (walk);
653 init_popt_callback (poptContext context, enum poptCallbackReason reason,
654 const struct poptOption *option, const char *arg, void *data)
656 GLogLevelFlags fatal_mask;
661 case POPT_CALLBACK_REASON_PRE:
662 if (!init_pre ()) _gst_initialization_failure = TRUE;
664 case POPT_CALLBACK_REASON_OPTION:
665 switch (option->val) {
667 g_print ("GStreamer Core Library version %s\n", GST_VERSION);
669 case ARG_FATAL_WARNINGS:
670 fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
671 fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
672 g_log_set_always_fatal (fatal_mask);
674 #ifndef GST_DISABLE_GST_DEBUG
675 case ARG_DEBUG_LEVEL: {
677 tmp = strtol (arg, NULL, 0);
678 if (tmp >= 0 && tmp < GST_LEVEL_COUNT) {
679 gst_debug_set_default_threshold (tmp);
684 parse_debug_list (arg);
686 case ARG_DEBUG_NO_COLOR:
687 gst_debug_set_colored (FALSE);
689 case ARG_DEBUG_DISABLE:
690 gst_debug_set_active (FALSE);
696 case ARG_DISABLE_CPU_OPT:
697 _gst_enable_cpu_opt = FALSE;
699 case ARG_PLUGIN_SPEW:
701 case ARG_PLUGIN_PATH:
702 #ifndef GST_DISABLE_REGISTRY
703 split_and_iterate (arg, G_SEARCHPATH_SEPARATOR_S, add_path_func, _user_registry);
704 #endif /* GST_DISABLE_REGISTRY */
706 case ARG_PLUGIN_LOAD:
707 split_and_iterate (arg, ",", prepare_for_load_plugin_func, NULL);
709 case ARG_SEGTRAP_DISABLE:
710 _gst_disable_segtrap = TRUE;
713 gst_scheduler_factory_set_default_name (arg);
716 #ifndef GST_DISABLE_REGISTRY
717 g_object_set (G_OBJECT (_user_registry), "location", arg, NULL);
718 _gst_registry_fixed = TRUE;
719 #endif /* GST_DISABLE_REGISTRY */
722 g_warning ("option %d not recognized", option->val);
726 case POPT_CALLBACK_REASON_POST:
727 if (!init_post ()) _gst_initialization_failure = TRUE;
728 gst_initialized = TRUE;
735 * @use_threads: a #gboolean indicating whether threads should be used
737 * Instructs the core to turn on/off threading. When threading
738 * is turned off, all thread operations such as mutexes and conditionals
739 * are turned into NOPs. use this if you want absolute minimal overhead
740 * and you don't use any threads in the pipeline.
742 * This function may only be called before threads are initialized. This
743 * usually happens when calling gst_init.
747 gst_use_threads (gboolean use_threads)
749 g_return_if_fail (!gst_initialized);
750 g_return_if_fail (g_thread_supported ());
752 _gst_use_threads = use_threads;
758 * Queries if GStreamer has threads enabled.
760 * Returns: %TRUE if threads are enabled.
763 gst_has_threads (void)
765 return _gst_use_threads;
769 static GSList *mainloops = NULL;
774 * Enters the main GStreamer processing loop.
781 loop = g_main_loop_new (NULL, FALSE);
782 mainloops = g_slist_prepend (mainloops, loop);
784 g_main_loop_run (loop);
790 * Exits the main GStreamer processing loop.
796 g_error ("Quit more loops than there are");
798 GMainLoop *loop = mainloops->data;
799 mainloops = g_slist_delete_link (mainloops, mainloops);
800 g_main_loop_quit (loop);
801 g_main_loop_unref (loop);
807 * @major: pointer to a guint to store the major version number
808 * @minor: pointer to a guint to store the minor version number
809 * @micro: pointer to a guint to store the micro version number
811 * Gets the version number of the GStreamer library.
814 gst_version (guint *major, guint *minor, guint *micro)
816 g_return_if_fail (major);
817 g_return_if_fail (minor);
818 g_return_if_fail (micro);
820 *major = GST_VERSION_MAJOR;
821 *minor = GST_VERSION_MINOR;
822 *micro = GST_VERSION_MICRO;