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;
78 static GstValueTable gstvtable = {
80 (GstValueCompareFunc) NULL,
81 (GstValueSerializeFunc) ges_marker_list_serialize,
82 (GstValueDeserializeFunc) ges_marker_list_deserialize
84 static gboolean marker_list_registered = FALSE;
86 if (initialized_thread) {
87 GST_DEBUG ("already initialized ges");
91 uriasset_klass = g_type_class_ref (GES_TYPE_URI_CLIP_ASSET);
93 _init_formatter_assets ();
94 if (!_ges_uri_asset_ensure_setup (uriasset_klass)) {
95 GST_ERROR ("cannot setup uri asset");
99 nlecomposition_factory = gst_element_factory_find ("nlecomposition");
100 if (!nlecomposition_factory) {
101 GST_ERROR ("The `nlecomposition` object was not found.");
103 *error = g_error_new (GST_CORE_ERROR, GST_CORE_ERROR_MISSING_PLUGIN,
104 "The `nle` plugin is missing.");
108 gst_object_unref (nlecomposition_factory);
110 /* register clip classes with the system */
112 g_type_class_ref (GES_TYPE_TEST_CLIP);
113 g_type_class_ref (GES_TYPE_URI_CLIP);
114 g_type_class_ref (GES_TYPE_TITLE_CLIP);
115 g_type_class_ref (GES_TYPE_TRANSITION_CLIP);
116 g_type_class_ref (GES_TYPE_OVERLAY_CLIP);
117 g_type_class_ref (GES_TYPE_OVERLAY_TEXT_CLIP);
119 g_type_class_ref (GES_TYPE_GROUP);
121 /* Register track elements */
122 g_type_class_ref (GES_TYPE_EFFECT);
124 ges_asset_cache_init ();
126 gst_element_register (NULL, "framepositioner", 0, GST_TYPE_FRAME_POSITIONNER);
127 gst_element_register (NULL, "gespipeline", 0, GES_TYPE_PIPELINE);
129 /* TODO: user-defined types? */
130 initialized_thread = g_thread_self ();
131 g_type_class_unref (uriasset_klass);
133 if (!marker_list_registered) {
134 gstvtable.type = GES_TYPE_MARKER_LIST;
135 gst_value_register (&gstvtable);
136 marker_list_registered = TRUE;
139 GST_DEBUG ("GStreamer Editing Services initialized");
145 g_type_class_unref (uriasset_klass);
147 GST_ERROR ("Could not initialize GES.");
155 * Initialize the GStreamer Editing Service. Call this before any usage of
156 * GES. You should take care of initilizing GStreamer before calling this
160 * GStreamer Editing Services do not guarantee MT safety.
161 * An application is required to use GES APIs (including ges_deinit())
162 * in the thread where ges_init() was called.
171 ges_init_pre (NULL, NULL, NULL, NULL);
173 ret = ges_init_post (NULL, NULL, NULL, NULL);
174 G_UNLOCK (init_lock);
182 * Clean up any resources created by GES in ges_init().
184 * It is normally not needed to call this function in a normal application as the
185 * resources will automatically be freed when the program terminates.
186 * This function is therefore mostly used by testsuites and other memory profiling tools.
187 * This function should be called from the thread where ges_init() was called.
189 * After this call GES should not be used until another ges_init() call.
196 GST_INFO ("deinitializing GES");
198 if (!initialized_thread) {
199 GST_DEBUG ("nothing to deinitialize");
200 G_UNLOCK (init_lock);
204 /* Allow deinit only from a thread where ges_init() was called */
205 g_assert (initialized_thread == g_thread_self ());
207 _ges_uri_asset_cleanup ();
209 g_type_class_unref (g_type_class_peek (GES_TYPE_TEST_CLIP));
210 g_type_class_unref (g_type_class_peek (GES_TYPE_URI_CLIP));
211 g_type_class_unref (g_type_class_peek (GES_TYPE_TITLE_CLIP));
212 g_type_class_unref (g_type_class_peek (GES_TYPE_TRANSITION_CLIP));
213 g_type_class_unref (g_type_class_peek (GES_TYPE_OVERLAY_CLIP));
214 g_type_class_unref (g_type_class_peek (GES_TYPE_OVERLAY_TEXT_CLIP));
216 g_type_class_unref (g_type_class_peek (GES_TYPE_GROUP));
217 /* Register track elements */
218 g_type_class_unref (g_type_class_peek (GES_TYPE_EFFECT));
220 ges_asset_cache_deinit ();
221 ges_xml_formatter_deinit ();
223 initialized_thread = NULL;
224 G_UNLOCK (init_lock);
226 GST_INFO ("deinitialized GES");
231 #ifndef GST_DISABLE_OPTION_PARSING
233 parse_goption_arg (const gchar * s_opt,
234 const gchar * arg, gpointer data, GError ** err)
236 if (g_strcmp0 (s_opt, "--ges-version") == 0) {
237 g_print ("GStreamer Editing Services version %s\n", PACKAGE_VERSION);
239 } else if (g_strcmp0 (s_opt, "--ges-sample-paths") == 0) {
240 ges_add_missing_uri_relocation_uri (arg, FALSE);
241 } else if (g_strcmp0 (s_opt, "--ges-sample-path-recurse") == 0) {
242 ges_add_missing_uri_relocation_uri (arg, TRUE);
250 * ges_init_get_option_group: (skip)
252 * Returns a #GOptionGroup with GES's argument specifications. The
253 * group is set up to use standard GOption callbacks, so when using this
254 * group in combination with GOption parsing methods, all argument parsing
255 * and initialization is automated.
257 * This function is useful if you want to integrate GES with other
258 * libraries that use GOption (see g_option_context_add_group() ).
260 * If you use this function, you should make sure you initialise the GStreamer
261 * as one of the very first things in your program. That means you need to
262 * use gst_init_get_option_group() and add it to the option context before
263 * using the ges_init_get_option_group() result.
265 * Returns: (transfer full): a pointer to GES's option group.
268 ges_init_get_option_group (void)
270 #ifndef GST_DISABLE_OPTION_PARSING
273 static const GOptionEntry ges_args[] = {
274 {"ges-version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
275 (gpointer) parse_goption_arg,
276 "Print the GStreamer Editing Services version",
278 {"ges-sample-paths", 0, 0, G_OPTION_ARG_CALLBACK,
279 (gpointer) parse_goption_arg,
280 "List of pathes to look assets in if they were moved"},
281 {"ges-sample-path-recurse", 0, 0, G_OPTION_ARG_CALLBACK,
282 (gpointer) parse_goption_arg,
283 "Same as above, but recursing into the folder"},
287 group = g_option_group_new ("GES", "GStreamer Editing Services Options",
288 "Show GES Options", NULL, NULL);
289 g_option_group_set_parse_hooks (group, (GOptionParseFunc) ges_init_pre,
290 (GOptionParseFunc) ges_init_post);
291 g_option_group_add_entries (group, ges_args);
302 * @major: (out): pointer to a guint to store the major version number
303 * @minor: (out): pointer to a guint to store the minor version number
304 * @micro: (out): pointer to a guint to store the micro version number
305 * @nano: (out): pointer to a guint to store the nano version number
307 * Gets the version number of the GStreamer Editing Services library.
310 ges_version (guint * major, guint * minor, guint * micro, guint * nano)
312 g_return_if_fail (major);
313 g_return_if_fail (minor);
314 g_return_if_fail (micro);
315 g_return_if_fail (nano);
317 *major = GES_VERSION_MAJOR;
318 *minor = GES_VERSION_MINOR;
319 *micro = GES_VERSION_MICRO;
320 *nano = GES_VERSION_NANO;
325 * @argc: (inout) (allow-none): pointer to application's argc
326 * @argv: (inout) (array length=argc) (allow-none): pointer to application's argv
327 * @err: pointer to a #GError to which a message will be posted on error
329 * Initializes the GStreamer Editing Services library, setting up internal path lists,
330 * and loading evrything needed.
332 * This function will return %FALSE if GES could not be initialized
335 * Returns: %TRUE if GES could be initialized.
338 ges_init_check (int *argc, char **argv[], GError ** err)
340 #ifndef GST_DISABLE_OPTION_PARSING
348 if (initialized_thread) {
349 GST_DEBUG ("already initialized ges");
350 G_UNLOCK (init_lock);
353 #ifndef GST_DISABLE_OPTION_PARSING
354 ctx = g_option_context_new ("- GStreamer Editing Services initialization");
355 g_option_context_set_ignore_unknown_options (ctx, TRUE);
356 g_option_context_set_help_enabled (ctx, FALSE);
357 group = ges_init_get_option_group ();
358 g_option_context_add_group (ctx, group);
359 res = g_option_context_parse (ctx, argc, argv, err);
360 g_option_context_free (ctx);
364 G_UNLOCK (init_lock);
368 ges_init_pre (NULL, NULL, NULL, NULL);
369 res = ges_init_post (NULL, NULL, NULL, NULL);
371 G_UNLOCK (init_lock);
377 * ges_is_initialized:
379 * Use this function to check if GES has been initialized with ges_init()
380 * or ges_init_check().
382 * Returns: %TRUE if initialization has been done, %FALSE otherwise.
387 ges_is_initialized (void)
389 return initialized_thread ? TRUE : FALSE;