introduce ges_deinit()
authorGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>
Mon, 6 Feb 2017 11:07:26 +0000 (12:07 +0100)
committerThibault Saunier <thibault.saunier@osg.samsung.com>
Mon, 6 Feb 2017 12:49:20 +0000 (09:49 -0300)
GstDiscoverer objects were leaked by tests making the leaks detector
unusable.
Introduce ges_deinit(), similiar to gst_deinit(), doing some cleanup
before exiting the process.

https://bugzilla.gnome.org/show_bug.cgi?id=776805

26 files changed:
docs/libs/ges-sections.txt
ges/ges-uri-asset.c
ges/ges-uri-asset.h
ges/ges.c
ges/ges.h
tests/check/ges/asset.c
tests/check/ges/backgroundsource.c
tests/check/ges/basic.c
tests/check/ges/clip.c
tests/check/ges/effects.c
tests/check/ges/group.c
tests/check/ges/layer.c
tests/check/ges/mixers.c
tests/check/ges/overlays.c
tests/check/ges/project.c
tests/check/ges/tempochange.c
tests/check/ges/timelineedition.c
tests/check/ges/titles.c
tests/check/ges/track.c
tests/check/ges/transition.c
tests/check/ges/uriclip.c
tests/check/nle/complex.c
tests/check/nle/nlecomposition.c
tests/check/nle/nleoperation.c
tests/check/nle/simple.c
tests/check/nle/tempochange.c

index 5a59846..96bf442 100644 (file)
@@ -5,6 +5,7 @@
 <TITLE>Initialization</TITLE>
 ges_init
 ges_init_check
+ges_deinit
 ges_version
 ges_init_get_option_group
 GES_VERSION_MAJOR
index 0a78a3a..170dc8a 100644 (file)
@@ -37,6 +37,9 @@
 
 static GHashTable *parent_newparent_table = NULL;
 
+static GstDiscoverer *discoverer = NULL;
+static GstDiscoverer *sync_discoverer = NULL;
+
 static void
 initable_iface_init (GInitableIface * initable_iface)
 {
@@ -220,18 +223,37 @@ ges_uri_clip_asset_class_init (GESUriClipAssetClass * klass)
   if (errno)
     timeout = DEFAULT_DISCOVERY_TIMEOUT;
 
-  klass->discoverer = gst_discoverer_new (timeout, &err);
+  if (!discoverer) {
+    discoverer = gst_discoverer_new (timeout, &err);
+    if (!discoverer) {
+      GST_ERROR ("Could not create discoverer: %s", err->message);
+      g_error_free (err);
+      return;
+    }
+  }
+
+  /* The class structure keeps weak pointers on the discoverers so they
+   * can be properly cleaned up in _ges_uri_asset_cleanup(). */
   if (!klass->discoverer) {
-    GST_ERROR ("Could not create discoverer: %s", err->message);
-    g_error_free (err);
-    return;
+    klass->discoverer = discoverer;
+    g_object_add_weak_pointer (G_OBJECT (discoverer),
+        (gpointer *) & klass->discoverer);
+  }
+
+  if (!sync_discoverer) {
+    sync_discoverer = gst_discoverer_new (timeout, &err);
+
+    if (!sync_discoverer) {
+      GST_ERROR ("Could not create discoverer: %s", err->message);
+      g_error_free (err);
+      return;
+    }
   }
 
-  klass->sync_discoverer = gst_discoverer_new (timeout, NULL);
   if (!klass->sync_discoverer) {
-    GST_ERROR ("Could not create discoverer: %s", err->message);
-    g_error_free (err);
-    return;
+    klass->sync_discoverer = sync_discoverer;
+    g_object_add_weak_pointer (G_OBJECT (sync_discoverer),
+        (gpointer *) & klass->sync_discoverer);
   }
 
   g_signal_connect (klass->discoverer, "discovered",
@@ -735,3 +757,10 @@ ges_uri_source_asset_get_filesource_asset (GESUriSourceAsset * asset)
 
   return asset->priv->parent_asset;
 }
+
+void
+_ges_uri_asset_cleanup (void)
+{
+  g_clear_object (&discoverer);
+  g_clear_object (&sync_discoverer);
+}
index 8fe053f..b1a0ca4 100644 (file)
@@ -116,5 +116,7 @@ GstDiscovererStreamInfo * ges_uri_source_asset_get_stream_info     (GESUriSource
 const gchar * ges_uri_source_asset_get_stream_uri                  (GESUriSourceAsset *asset);
 const GESUriClipAsset *ges_uri_source_asset_get_filesource_asset   (GESUriSourceAsset *asset);
 
+void _ges_uri_asset_cleanup (void);
+
 G_END_DECLS
 #endif /* _GES_URI_CLIP_ASSET */
index 3f8f645..46ebf1d 100644 (file)
--- a/ges/ges.c
+++ b/ges/ges.c
@@ -134,6 +134,23 @@ ges_init (void)
   return ges_init_post (NULL, NULL, NULL, NULL);
 }
 
+/**
+ * ges_deinit:
+ *
+ * Clean up any resources created by GES in ges_init().
+ *
+ * It is normally not needed to call this function in a normal application as the
+ * resources will automatically be freed when the program terminates.
+ * This function is therefore mostly used by testsuites and other memory profiling tools.
+ *
+ * After this call GES (including this method) should not be used anymore.
+ */
+void
+ges_deinit (void)
+{
+  _ges_uri_asset_cleanup ();
+}
+
 #ifndef GST_DISABLE_OPTION_PARSING
 static gboolean
 parse_goption_arg (const gchar * s_opt,
index 0b3141b..670d473 100644 (file)
--- a/ges/ges.h
+++ b/ges/ges.h
@@ -87,6 +87,7 @@ G_BEGIN_DECLS
 
 gboolean ges_init         (void);
 gboolean ges_init_check (int *argc, char **argv[], GError ** err);
+void     ges_deinit       (void);
 void     ges_version      (guint * major, guint * minor, guint * micro,
                            guint * nano);
 GOptionGroup *
index e1fcefb..d15d75a 100644 (file)
@@ -201,6 +201,10 @@ ges_suite (void)
   Suite *s = suite_create ("ges");
   TCase *tc_chain = tcase_create ("a");
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   suite_add_tcase (s, tc_chain);
   ges_init ();
 
index 5edb149..d32448d 100644 (file)
@@ -405,6 +405,10 @@ ges_suite (void)
   Suite *s = suite_create ("ges-backgroundsource");
   TCase *tc_chain = tcase_create ("backgroundsource");
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   suite_add_tcase (s, tc_chain);
 
   tcase_add_test (tc_chain, test_test_source_basic);
index 039190d..6b8340c 100644 (file)
@@ -776,6 +776,10 @@ ges_suite (void)
   Suite *s = suite_create ("ges-basic");
   TCase *tc_chain = tcase_create ("basic");
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   suite_add_tcase (s, tc_chain);
 
   tcase_add_test (tc_chain, test_ges_init);
index 0be8832..7820e0b 100644 (file)
@@ -699,6 +699,10 @@ ges_suite (void)
   Suite *s = suite_create ("ges-clip");
   TCase *tc_chain = tcase_create ("clip");
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   suite_add_tcase (s, tc_chain);
 
   tcase_add_test (tc_chain, test_object_properties);
index 0a40f55..fc1c10d 100644 (file)
@@ -561,6 +561,10 @@ ges_suite (void)
   Suite *s = suite_create ("ges");
   TCase *tc_chain = tcase_create ("effect");
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   suite_add_tcase (s, tc_chain);
 
   tcase_add_test (tc_chain, test_effect_basic);
index 3526d02..2884252 100644 (file)
@@ -764,6 +764,10 @@ ges_suite (void)
   Suite *s = suite_create ("ges-group");
   TCase *tc_chain = tcase_create ("group");
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   suite_add_tcase (s, tc_chain);
 
   tcase_add_test (tc_chain, test_move_group);
index 3b8f19e..dad061f 100644 (file)
@@ -1759,6 +1759,10 @@ ges_suite (void)
   Suite *s = suite_create ("ges-layer");
   TCase *tc_chain = tcase_create ("timeline-layer");
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   suite_add_tcase (s, tc_chain);
 
   tcase_add_test (tc_chain, test_layer_properties);
index 167cd32..08b4efb 100644 (file)
@@ -200,6 +200,10 @@ ges_suite (void)
   Suite *s = suite_create ("Smart mixers");
   TCase *tc_chain = tcase_create ("smart-mixers");
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   ges_init ();
   suite_add_tcase (s, tc_chain);
 
index be44fc9..e83fcdf 100644 (file)
@@ -207,6 +207,10 @@ ges_suite (void)
   Suite *s = suite_create ("ges-overlays");
   TCase *tc_chain = tcase_create ("overlays");
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   suite_add_tcase (s, tc_chain);
 
   tcase_add_test (tc_chain, test_overlay_basic);
index 1e151c8..384733e 100644 (file)
@@ -734,6 +734,10 @@ ges_suite (void)
   Suite *s = suite_create ("ges-project");
   TCase *tc_chain = tcase_create ("project");
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   suite_add_tcase (s, tc_chain);
   ges_init ();
 
index 42b48ec..faaee02 100644 (file)
@@ -134,6 +134,10 @@ ges_suite (void)
   GstPluginFeature *pitch = gst_registry_find_feature (gst_registry_get (),
       "pitch", GST_TYPE_ELEMENT_FACTORY);
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   if (pitch) {
     gst_object_unref (pitch);
 
index 841914e..1861639 100644 (file)
@@ -1501,6 +1501,10 @@ ges_suite (void)
   Suite *s = suite_create ("ges-timeline-edition");
   TCase *tc_chain = tcase_create ("timeline-edition");
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   ges_init ();
 
   suite_add_tcase (s, tc_chain);
index 90467a0..98a4a0a 100644 (file)
@@ -211,6 +211,10 @@ ges_suite (void)
   Suite *s = suite_create ("ges-titles");
   TCase *tc_chain = tcase_create ("titles");
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   suite_add_tcase (s, tc_chain);
 
   tcase_add_test (tc_chain, test_title_source_basic);
index da8ddb2..96e41e7 100644 (file)
@@ -94,6 +94,10 @@ ges_suite (void)
   Suite *s = suite_create ("ges-track");
   TCase *tc_chain = tcase_create ("track");
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   suite_add_tcase (s, tc_chain);
 
   tcase_add_test (tc_chain, test_update_restriction_caps);
index b245f23..b6c916a 100644 (file)
@@ -178,6 +178,10 @@ ges_suite (void)
   Suite *s = suite_create ("ges-transition");
   TCase *tc_chain = tcase_create ("transition");
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   suite_add_tcase (s, tc_chain);
 
   tcase_add_test (tc_chain, test_transition_basic);
index 7531508..c329809 100644 (file)
@@ -290,6 +290,10 @@ main (int argc, char **argv)
 
   gst_check_init (&argc, &argv);
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   s = ges_suite ();
 
   av_uri = ges_test_get_audio_video_uri ();
index 588dd8b..a5ca7da 100644 (file)
@@ -824,6 +824,10 @@ gnonlin_suite (void)
   Suite *s = suite_create ("gnonlin-complex");
   TCase *tc_chain = tcase_create ("complex");
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   ges_init ();
   suite_add_tcase (s, tc_chain);
 
index be727d2..aec78c1 100644 (file)
@@ -437,6 +437,10 @@ gnonlin_suite (void)
   Suite *s = suite_create ("nlecomposition");
   TCase *tc_chain = tcase_create ("nlecomposition");
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   ges_init ();
   suite_add_tcase (s, tc_chain);
 
index a1d106c..2825e12 100644 (file)
@@ -688,6 +688,10 @@ gnonlin_suite (void)
   Suite *s = suite_create ("nleoperation");
   TCase *tc_chain = tcase_create ("nleoperation");
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   ges_init ();
   suite_add_tcase (s, tc_chain);
 
index 86ca917..df8d215 100644 (file)
@@ -763,6 +763,10 @@ gnonlin_suite (void)
   Suite *s = suite_create ("gnonlin-simple");
   TCase *tc_chain = tcase_create ("general");
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   suite_add_tcase (s, tc_chain);
 
   ges_init ();
index a313c90..cd6d714 100644 (file)
@@ -160,6 +160,10 @@ gnonlin_suite (void)
   Suite *s = suite_create ("nle");
   TCase *tc_chain = tcase_create ("tempochange");
 
+  if (atexit (ges_deinit) != 0) {
+    GST_ERROR ("failed to set ges_deinit as exit function");
+  }
+
   ges_init ();
   suite_add_tcase (s, tc_chain);