GNOME Bugzilla – Bug 730697
GES Memory management problems when playing a list of files
Last modified: 2014-10-29 16:19:13 UTC
I faced problem with memory management with GES. I have a program which plays a list of video files. You can add files to the list and play it. User can replay the list without shutting the program down. Video files list elements are basic C strings and I build timeline from scratch whenever I start playing my videos list. The problem is that GES stores clips into the memory and does not release it after all the timeline is played. That is, after each time I play my timeline, the total consumption of the RAM my application uses just accumulates, for example after the first time I play my timeline my application RAM consumption is 100MB, after I play it second time it doubles and it uses 200mb. There must be a problem with memory management. I use assets, I unref them, I use static timeline and pipiline, maybe that is the cause? do I need to unref timeline and pipeline? I use g_object_unref (pipeline); g_object_unref (timeline); but it does not help The code below represents my problem: #include <ges/ges.h> #include <stdio.h> static GESTimeline *timeline; static GESPipeline *pipeline; int main (int argc, char **argv) { gchar *firstFileAddress = "C:/videoSamples/sample2.mkv"; gchar *secondFileAddress = "C:/videoSamples/sample2.mkv"; int a = 0; gst_init (NULL, NULL); ges_init (); printf ("check process memory consumption before playing video files(enter any number! and press enter) \n"); scanf("%d",&a); // lets play first playlist if(1){ GMainLoop *mainloop; timeline = ges_timeline_new_audio_video (); // Adding clips to the timeline if(1) { GESAsset *src_asset; GESLayer *layer; gchar *uri; GESUriClipAsset *asset; layer = ges_timeline_append_layer(timeline); uri = gst_filename_to_uri (firstFileAddress, NULL); asset = ges_uri_clip_asset_request_sync(uri,NULL); src_asset = GES_ASSET(asset); ges_layer_add_asset (layer, src_asset, 0*GST_SECOND, 5*GST_SECOND, 2*GST_SECOND, GES_TRACK_TYPE_UNKNOWN); gst_object_unref (src_asset); g_free(uri); } // Adding clips to the timeline if(1) { GESAsset *src_asset; GESLayer *layer; gchar *uri; GESUriClipAsset *asset; layer = ges_timeline_append_layer(timeline); uri = gst_filename_to_uri (secondFileAddress, NULL); asset = ges_uri_clip_asset_request_sync(uri,NULL); src_asset = GES_ASSET(asset); ges_layer_add_asset (layer, src_asset, 2*GST_SECOND, 5*GST_SECOND, 2*GST_SECOND, GES_TRACK_TYPE_UNKNOWN); gst_object_unref (src_asset); g_free(uri); } pipeline = ges_pipeline_new (); if (!ges_pipeline_set_timeline (pipeline, timeline)) return; ges_timeline_commit(timeline); gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); mainloop = g_main_loop_new (NULL, FALSE); g_timeout_add_seconds (4+1, (GSourceFunc) g_main_loop_quit, mainloop); g_main_loop_run (mainloop); gst_object_unref (timeline); gst_object_unref (pipeline); } printf ("+-------------------------------------------------------------------------------------+\n"); printf ("check memory consumption after playing first playlist (enter any number! and press enter)\n"); printf ("you can close video window\n"); scanf("%d",&a); if(1){ GMainLoop *mainloop; timeline = ges_timeline_new_audio_video (); // Adding clips to the timeline if(1) { GESAsset *src_asset; GESLayer *layer; gchar *uri; GESUriClipAsset *asset; layer = ges_timeline_append_layer(timeline); uri = gst_filename_to_uri (firstFileAddress, NULL); asset = ges_uri_clip_asset_request_sync(uri,NULL); src_asset = GES_ASSET(asset); ges_layer_add_asset (layer, src_asset, 0*GST_SECOND, 5*GST_SECOND, 2*GST_SECOND, GES_TRACK_TYPE_UNKNOWN); gst_object_unref (src_asset); g_free(uri); } // Adding clips to the timeline if(1) { GESAsset *src_asset; GESLayer *layer; gchar *uri; GESUriClipAsset *asset; layer = ges_timeline_append_layer(timeline); uri = gst_filename_to_uri (secondFileAddress, NULL); asset = ges_uri_clip_asset_request_sync(uri,NULL); src_asset = GES_ASSET(asset); ges_layer_add_asset (layer, src_asset, 2*GST_SECOND, 5*GST_SECOND, 2*GST_SECOND, GES_TRACK_TYPE_UNKNOWN); gst_object_unref (src_asset); g_free(uri); } pipeline = ges_pipeline_new (); if (!ges_pipeline_set_timeline (pipeline, timeline)) return; ges_timeline_commit(timeline); gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); mainloop = g_main_loop_new (NULL, FALSE); g_timeout_add_seconds (4+1, (GSourceFunc) g_main_loop_quit, mainloop); g_main_loop_run (mainloop); gst_object_unref (timeline); gst_object_unref (pipeline); } printf ("check process memory consumption after playing final playlist\n"); scanf("%d",&a); return 0; }
Going to NULL state will cleanup quite some memory. See https://bugzilla.gnome.org/show_bug.cgi?id=596849 about about 1 part of the problem. Though the memory should stop growing at some point, unless you keep adding new cip, of course.
I did like this after playing first playlist: // First playlist code g_main_loop_run (mainloop); // Now I add this gst_element_set_state (GST_ELEMENT (pipeline),GST_STATE_NULL); It actually reduces memory consumption to the minimum, however I can't play the second list. How can I fix that?
I think this is a duplicate of https://bugzilla.gnome.org/show_bug.cgi?id=596849 for which I just proposed a patch.
No other information has been provided and that bug should be FIXED now, closing.