introduce ges_deinit()

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
This commit is contained in:
Guillaume Desmottes 2017-02-06 12:07:26 +01:00 committed by Thibault Saunier
parent 7ba2c22ccb
commit 53c5bc069c
26 changed files with 143 additions and 9 deletions

View file

@ -5,6 +5,7 @@
<TITLE>Initialization</TITLE> <TITLE>Initialization</TITLE>
ges_init ges_init
ges_init_check ges_init_check
ges_deinit
ges_version ges_version
ges_init_get_option_group ges_init_get_option_group
GES_VERSION_MAJOR GES_VERSION_MAJOR

View file

@ -37,6 +37,9 @@
static GHashTable *parent_newparent_table = NULL; static GHashTable *parent_newparent_table = NULL;
static GstDiscoverer *discoverer = NULL;
static GstDiscoverer *sync_discoverer = NULL;
static void static void
initable_iface_init (GInitableIface * initable_iface) initable_iface_init (GInitableIface * initable_iface)
{ {
@ -220,18 +223,37 @@ ges_uri_clip_asset_class_init (GESUriClipAssetClass * klass)
if (errno) if (errno)
timeout = DEFAULT_DISCOVERY_TIMEOUT; timeout = DEFAULT_DISCOVERY_TIMEOUT;
klass->discoverer = gst_discoverer_new (timeout, &err); if (!discoverer) {
if (!klass->discoverer) { discoverer = gst_discoverer_new (timeout, &err);
GST_ERROR ("Could not create discoverer: %s", err->message); if (!discoverer) {
g_error_free (err); GST_ERROR ("Could not create discoverer: %s", err->message);
return; 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) {
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) { if (!klass->sync_discoverer) {
GST_ERROR ("Could not create discoverer: %s", err->message); klass->sync_discoverer = sync_discoverer;
g_error_free (err); g_object_add_weak_pointer (G_OBJECT (sync_discoverer),
return; (gpointer *) & klass->sync_discoverer);
} }
g_signal_connect (klass->discoverer, "discovered", g_signal_connect (klass->discoverer, "discovered",
@ -735,3 +757,10 @@ ges_uri_source_asset_get_filesource_asset (GESUriSourceAsset * asset)
return asset->priv->parent_asset; return asset->priv->parent_asset;
} }
void
_ges_uri_asset_cleanup (void)
{
g_clear_object (&discoverer);
g_clear_object (&sync_discoverer);
}

View 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 gchar * ges_uri_source_asset_get_stream_uri (GESUriSourceAsset *asset);
const GESUriClipAsset *ges_uri_source_asset_get_filesource_asset (GESUriSourceAsset *asset); const GESUriClipAsset *ges_uri_source_asset_get_filesource_asset (GESUriSourceAsset *asset);
void _ges_uri_asset_cleanup (void);
G_END_DECLS G_END_DECLS
#endif /* _GES_URI_CLIP_ASSET */ #endif /* _GES_URI_CLIP_ASSET */

View file

@ -134,6 +134,23 @@ ges_init (void)
return ges_init_post (NULL, NULL, NULL, NULL); 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 #ifndef GST_DISABLE_OPTION_PARSING
static gboolean static gboolean
parse_goption_arg (const gchar * s_opt, parse_goption_arg (const gchar * s_opt,

View file

@ -87,6 +87,7 @@ G_BEGIN_DECLS
gboolean ges_init (void); gboolean ges_init (void);
gboolean ges_init_check (int *argc, char **argv[], GError ** err); gboolean ges_init_check (int *argc, char **argv[], GError ** err);
void ges_deinit (void);
void ges_version (guint * major, guint * minor, guint * micro, void ges_version (guint * major, guint * minor, guint * micro,
guint * nano); guint * nano);
GOptionGroup * GOptionGroup *

View file

@ -201,6 +201,10 @@ ges_suite (void)
Suite *s = suite_create ("ges"); Suite *s = suite_create ("ges");
TCase *tc_chain = tcase_create ("a"); 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); suite_add_tcase (s, tc_chain);
ges_init (); ges_init ();

View file

@ -405,6 +405,10 @@ ges_suite (void)
Suite *s = suite_create ("ges-backgroundsource"); Suite *s = suite_create ("ges-backgroundsource");
TCase *tc_chain = tcase_create ("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); suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_test_source_basic); tcase_add_test (tc_chain, test_test_source_basic);

View file

@ -776,6 +776,10 @@ ges_suite (void)
Suite *s = suite_create ("ges-basic"); Suite *s = suite_create ("ges-basic");
TCase *tc_chain = tcase_create ("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); suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_ges_init); tcase_add_test (tc_chain, test_ges_init);

View file

@ -699,6 +699,10 @@ ges_suite (void)
Suite *s = suite_create ("ges-clip"); Suite *s = suite_create ("ges-clip");
TCase *tc_chain = tcase_create ("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); suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_object_properties); tcase_add_test (tc_chain, test_object_properties);

View file

@ -561,6 +561,10 @@ ges_suite (void)
Suite *s = suite_create ("ges"); Suite *s = suite_create ("ges");
TCase *tc_chain = tcase_create ("effect"); 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); suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_effect_basic); tcase_add_test (tc_chain, test_effect_basic);

View file

@ -764,6 +764,10 @@ ges_suite (void)
Suite *s = suite_create ("ges-group"); Suite *s = suite_create ("ges-group");
TCase *tc_chain = tcase_create ("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); suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_move_group); tcase_add_test (tc_chain, test_move_group);

View file

@ -1759,6 +1759,10 @@ ges_suite (void)
Suite *s = suite_create ("ges-layer"); Suite *s = suite_create ("ges-layer");
TCase *tc_chain = tcase_create ("timeline-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); suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_layer_properties); tcase_add_test (tc_chain, test_layer_properties);

View file

@ -200,6 +200,10 @@ ges_suite (void)
Suite *s = suite_create ("Smart mixers"); Suite *s = suite_create ("Smart mixers");
TCase *tc_chain = tcase_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 (); ges_init ();
suite_add_tcase (s, tc_chain); suite_add_tcase (s, tc_chain);

View file

@ -207,6 +207,10 @@ ges_suite (void)
Suite *s = suite_create ("ges-overlays"); Suite *s = suite_create ("ges-overlays");
TCase *tc_chain = tcase_create ("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); suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_overlay_basic); tcase_add_test (tc_chain, test_overlay_basic);

View file

@ -734,6 +734,10 @@ ges_suite (void)
Suite *s = suite_create ("ges-project"); Suite *s = suite_create ("ges-project");
TCase *tc_chain = tcase_create ("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); suite_add_tcase (s, tc_chain);
ges_init (); ges_init ();

View file

@ -134,6 +134,10 @@ ges_suite (void)
GstPluginFeature *pitch = gst_registry_find_feature (gst_registry_get (), GstPluginFeature *pitch = gst_registry_find_feature (gst_registry_get (),
"pitch", GST_TYPE_ELEMENT_FACTORY); "pitch", GST_TYPE_ELEMENT_FACTORY);
if (atexit (ges_deinit) != 0) {
GST_ERROR ("failed to set ges_deinit as exit function");
}
if (pitch) { if (pitch) {
gst_object_unref (pitch); gst_object_unref (pitch);

View file

@ -1501,6 +1501,10 @@ ges_suite (void)
Suite *s = suite_create ("ges-timeline-edition"); Suite *s = suite_create ("ges-timeline-edition");
TCase *tc_chain = tcase_create ("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 (); ges_init ();
suite_add_tcase (s, tc_chain); suite_add_tcase (s, tc_chain);

View file

@ -211,6 +211,10 @@ ges_suite (void)
Suite *s = suite_create ("ges-titles"); Suite *s = suite_create ("ges-titles");
TCase *tc_chain = tcase_create ("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); suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_title_source_basic); tcase_add_test (tc_chain, test_title_source_basic);

View file

@ -94,6 +94,10 @@ ges_suite (void)
Suite *s = suite_create ("ges-track"); Suite *s = suite_create ("ges-track");
TCase *tc_chain = tcase_create ("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); suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_update_restriction_caps); tcase_add_test (tc_chain, test_update_restriction_caps);

View file

@ -178,6 +178,10 @@ ges_suite (void)
Suite *s = suite_create ("ges-transition"); Suite *s = suite_create ("ges-transition");
TCase *tc_chain = tcase_create ("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); suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_transition_basic); tcase_add_test (tc_chain, test_transition_basic);

View file

@ -290,6 +290,10 @@ main (int argc, char **argv)
gst_check_init (&argc, &argv); gst_check_init (&argc, &argv);
if (atexit (ges_deinit) != 0) {
GST_ERROR ("failed to set ges_deinit as exit function");
}
s = ges_suite (); s = ges_suite ();
av_uri = ges_test_get_audio_video_uri (); av_uri = ges_test_get_audio_video_uri ();

View file

@ -824,6 +824,10 @@ gnonlin_suite (void)
Suite *s = suite_create ("gnonlin-complex"); Suite *s = suite_create ("gnonlin-complex");
TCase *tc_chain = tcase_create ("complex"); TCase *tc_chain = tcase_create ("complex");
if (atexit (ges_deinit) != 0) {
GST_ERROR ("failed to set ges_deinit as exit function");
}
ges_init (); ges_init ();
suite_add_tcase (s, tc_chain); suite_add_tcase (s, tc_chain);

View file

@ -437,6 +437,10 @@ gnonlin_suite (void)
Suite *s = suite_create ("nlecomposition"); Suite *s = suite_create ("nlecomposition");
TCase *tc_chain = tcase_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 (); ges_init ();
suite_add_tcase (s, tc_chain); suite_add_tcase (s, tc_chain);

View file

@ -688,6 +688,10 @@ gnonlin_suite (void)
Suite *s = suite_create ("nleoperation"); Suite *s = suite_create ("nleoperation");
TCase *tc_chain = tcase_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 (); ges_init ();
suite_add_tcase (s, tc_chain); suite_add_tcase (s, tc_chain);

View file

@ -763,6 +763,10 @@ gnonlin_suite (void)
Suite *s = suite_create ("gnonlin-simple"); Suite *s = suite_create ("gnonlin-simple");
TCase *tc_chain = tcase_create ("general"); 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); suite_add_tcase (s, tc_chain);
ges_init (); ges_init ();

View file

@ -160,6 +160,10 @@ gnonlin_suite (void)
Suite *s = suite_create ("nle"); Suite *s = suite_create ("nle");
TCase *tc_chain = tcase_create ("tempochange"); TCase *tc_chain = tcase_create ("tempochange");
if (atexit (ges_deinit) != 0) {
GST_ERROR ("failed to set ges_deinit as exit function");
}
ges_init (); ges_init ();
suite_add_tcase (s, tc_chain); suite_add_tcase (s, tc_chain);