1 /* GStreamer Editing Services
2 * Copyright (C) 2009 Edward Hervey <edward.hervey@collabora.co.uk>
3 * 2009 Nokia Corporation
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
23 * @title: Initialization
24 * @short_description: GStreamer editing services initialization functions
26 * GES needs to be initialized after GStreamer itself. This section
27 * contains the various functions to do so.
36 #include "ges/gstframepositioner.h"
37 #include "ges-internal.h"
40 #include <ges/ges-pitivi-formatter.h>
43 #define GES_GNONLIN_VERSION_NEEDED_MAJOR 1
44 #define GES_GNONLIN_VERSION_NEEDED_MINOR 2
45 #define GES_GNONLIN_VERSION_NEEDED_MICRO 0
47 GST_DEBUG_CATEGORY (_ges_debug);
49 G_LOCK_DEFINE_STATIC (init_lock);
51 /* (without holding ref) thread object for thread_self() validation
54 static GThread *initialized_thread = NULL;
57 ges_init_pre (GOptionContext * context, GOptionGroup * group, gpointer data,
60 if (initialized_thread) {
61 GST_DEBUG ("already initialized");
65 /* initialize debugging category */
66 GST_DEBUG_CATEGORY_INIT (_ges_debug, "ges", GST_DEBUG_FG_YELLOW,
67 "GStreamer Editing Services");
73 ges_init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
76 GESUriClipAssetClass *uriasset_klass = NULL;
77 GstElementFactory *nlecomposition_factory = NULL;
79 if (initialized_thread) {
80 GST_DEBUG ("already initialized ges");
84 uriasset_klass = g_type_class_ref (GES_TYPE_URI_CLIP_ASSET);
86 _init_formatter_assets ();
87 if (!_ges_uri_asset_ensure_setup (uriasset_klass)) {
88 GST_ERROR ("cannot setup uri asset");
92 nlecomposition_factory = gst_element_factory_find ("nlecomposition");
93 if (!nlecomposition_factory) {
94 GST_ERROR ("The `nlecomposition` object was not found.");
96 *error = g_error_new (GST_CORE_ERROR, GST_CORE_ERROR_MISSING_PLUGIN,
97 "The `nle` plugin is missing.");
101 gst_object_unref (nlecomposition_factory);
103 /* register clip classes with the system */
105 g_type_class_ref (GES_TYPE_TEST_CLIP);
106 g_type_class_ref (GES_TYPE_URI_CLIP);
107 g_type_class_ref (GES_TYPE_TITLE_CLIP);
108 g_type_class_ref (GES_TYPE_TRANSITION_CLIP);
109 g_type_class_ref (GES_TYPE_OVERLAY_CLIP);
110 g_type_class_ref (GES_TYPE_OVERLAY_TEXT_CLIP);
112 g_type_class_ref (GES_TYPE_GROUP);
114 /* Register track elements */
115 g_type_class_ref (GES_TYPE_EFFECT);
117 ges_asset_cache_init ();
119 gst_element_register (NULL, "framepositioner", 0, GST_TYPE_FRAME_POSITIONNER);
120 gst_element_register (NULL, "gespipeline", 0, GES_TYPE_PIPELINE);
122 /* TODO: user-defined types? */
123 initialized_thread = g_thread_self ();
124 g_type_class_unref (uriasset_klass);
126 GST_DEBUG ("GStreamer Editing Services initialized");
132 g_type_class_unref (uriasset_klass);
134 GST_ERROR ("Could not initialize GES.");
142 * Initialize the GStreamer Editing Service. Call this before any usage of
143 * GES. You should take care of initilizing GStreamer before calling this
147 * GStreamer Editing Services do not guarantee MT safety.
148 * An application is required to use GES APIs (including ges_deinit())
149 * in the thread where ges_init() was called.
158 ges_init_pre (NULL, NULL, NULL, NULL);
160 ret = ges_init_post (NULL, NULL, NULL, NULL);
161 G_UNLOCK (init_lock);
169 * Clean up any resources created by GES in ges_init().
171 * It is normally not needed to call this function in a normal application as the
172 * resources will automatically be freed when the program terminates.
173 * This function is therefore mostly used by testsuites and other memory profiling tools.
174 * This function should be called from the thread where ges_init() was called.
176 * After this call GES should not be used until another ges_init() call.
183 GST_INFO ("deinitializing GES");
185 if (!initialized_thread) {
186 GST_DEBUG ("nothing to deinitialize");
187 G_UNLOCK (init_lock);
191 /* Allow deinit only from a thread where ges_init() was called */
192 g_assert (initialized_thread == g_thread_self ());
194 _ges_uri_asset_cleanup ();
196 g_type_class_unref (g_type_class_peek (GES_TYPE_TEST_CLIP));
197 g_type_class_unref (g_type_class_peek (GES_TYPE_URI_CLIP));
198 g_type_class_unref (g_type_class_peek (GES_TYPE_TITLE_CLIP));
199 g_type_class_unref (g_type_class_peek (GES_TYPE_TRANSITION_CLIP));
200 g_type_class_unref (g_type_class_peek (GES_TYPE_OVERLAY_CLIP));
201 g_type_class_unref (g_type_class_peek (GES_TYPE_OVERLAY_TEXT_CLIP));
203 g_type_class_unref (g_type_class_peek (GES_TYPE_GROUP));
204 /* Register track elements */
205 g_type_class_unref (g_type_class_peek (GES_TYPE_EFFECT));
207 ges_asset_cache_deinit ();
208 ges_xml_formatter_deinit ();
210 initialized_thread = NULL;
211 G_UNLOCK (init_lock);
213 GST_INFO ("deinitialized GES");
218 #ifndef GST_DISABLE_OPTION_PARSING
220 parse_goption_arg (const gchar * s_opt,
221 const gchar * arg, gpointer data, GError ** err)
223 if (g_strcmp0 (s_opt, "--ges-version") == 0) {
224 g_print ("GStreamer Editing Services version %s\n", PACKAGE_VERSION);
226 } else if (g_strcmp0 (s_opt, "--ges-sample-paths") == 0) {
227 ges_add_missing_uri_relocation_uri (arg, FALSE);
228 } else if (g_strcmp0 (s_opt, "--ges-sample-path-recurse") == 0) {
229 ges_add_missing_uri_relocation_uri (arg, TRUE);
237 * ges_init_get_option_group: (skip)
239 * Returns a #GOptionGroup with GES's argument specifications. The
240 * group is set up to use standard GOption callbacks, so when using this
241 * group in combination with GOption parsing methods, all argument parsing
242 * and initialization is automated.
244 * This function is useful if you want to integrate GES with other
245 * libraries that use GOption (see g_option_context_add_group() ).
247 * If you use this function, you should make sure you initialise the GStreamer
248 * as one of the very first things in your program. That means you need to
249 * use gst_init_get_option_group() and add it to the option context before
250 * using the ges_init_get_option_group() result.
252 * Returns: (transfer full): a pointer to GES's option group.
255 ges_init_get_option_group (void)
257 #ifndef GST_DISABLE_OPTION_PARSING
260 static const GOptionEntry ges_args[] = {
261 {"ges-version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
262 (gpointer) parse_goption_arg,
263 "Print the GStreamer Editing Services version",
265 {"ges-sample-paths", 0, 0, G_OPTION_ARG_CALLBACK,
266 (gpointer) parse_goption_arg,
267 "List of pathes to look assets in if they were moved"},
268 {"ges-sample-path-recurse", 0, 0, G_OPTION_ARG_CALLBACK,
269 (gpointer) parse_goption_arg,
270 "Same as above, but recursing into the folder"},
274 group = g_option_group_new ("GES", "GStreamer Editing Services Options",
275 "Show GES Options", NULL, NULL);
276 g_option_group_set_parse_hooks (group, (GOptionParseFunc) ges_init_pre,
277 (GOptionParseFunc) ges_init_post);
278 g_option_group_add_entries (group, ges_args);
289 * @major: (out): pointer to a guint to store the major version number
290 * @minor: (out): pointer to a guint to store the minor version number
291 * @micro: (out): pointer to a guint to store the micro version number
292 * @nano: (out): pointer to a guint to store the nano version number
294 * Gets the version number of the GStreamer Editing Services library.
297 ges_version (guint * major, guint * minor, guint * micro, guint * nano)
299 g_return_if_fail (major);
300 g_return_if_fail (minor);
301 g_return_if_fail (micro);
302 g_return_if_fail (nano);
304 *major = GES_VERSION_MAJOR;
305 *minor = GES_VERSION_MINOR;
306 *micro = GES_VERSION_MICRO;
307 *nano = GES_VERSION_NANO;
312 * @argc: (inout) (allow-none): pointer to application's argc
313 * @argv: (inout) (array length=argc) (allow-none): pointer to application's argv
314 * @err: pointer to a #GError to which a message will be posted on error
316 * Initializes the GStreamer Editing Services library, setting up internal path lists,
317 * and loading evrything needed.
319 * This function will return %FALSE if GES could not be initialized
322 * Returns: %TRUE if GES could be initialized.
325 ges_init_check (int *argc, char **argv[], GError ** err)
327 #ifndef GST_DISABLE_OPTION_PARSING
335 if (initialized_thread) {
336 GST_DEBUG ("already initialized ges");
337 G_UNLOCK (init_lock);
340 #ifndef GST_DISABLE_OPTION_PARSING
341 ctx = g_option_context_new ("- GStreamer Editing Services initialization");
342 g_option_context_set_ignore_unknown_options (ctx, TRUE);
343 g_option_context_set_help_enabled (ctx, FALSE);
344 group = ges_init_get_option_group ();
345 g_option_context_add_group (ctx, group);
346 res = g_option_context_parse (ctx, argc, argv, err);
347 g_option_context_free (ctx);
351 G_UNLOCK (init_lock);
355 ges_init_pre (NULL, NULL, NULL, NULL);
356 res = ges_init_post (NULL, NULL, NULL, NULL);
358 G_UNLOCK (init_lock);
364 * ges_is_initialized:
366 * Use this function to check if GES has been initialized with ges_init()
367 * or ges_init_check().
369 * Returns: %TRUE if initialization has been done, %FALSE otherwise.
374 ges_is_initialized (void)
376 return initialized_thread ? TRUE : FALSE;