Memory leaking after restarting pipelines

Hi, I have a simple application on C to decode and encode application. I need to restart pipelines a lot. Here is code example:

void pipeline_func() {
    GstElement* pipeline = NULL;
    gst_init(NULL, NULL);


    char command[2048]  =   " filesrc location=video.mp4 ! "
                            " qtdemux name=demux demux.video_0 ! "
                            " queue max-size-time=0 max-size-bytes=0 max-size-buffers=0 ! "
                            " decodebin ! "
                            " videoconvert ! "
                            " x264enc ! "
                            " mux. mp4mux name=mux ! "
                            " filesink location=out.mp4";

    pipeline = gst_parse_launch(command, NULL);
    if (pipeline == NULL) {
        return;
    }
    gst_element_set_state(pipeline, GST_STATE_PLAYING);

    //  Enough time for pipeline to work
    sleep(5);
    gst_element_set_state(pipeline, GST_STATE_NULL);
    gst_object_unref(pipeline);
    pipeline = NULL;
}

int main(int argc, char* argv[]) {
    int restart_times = 1;
    if (argc > 1) {
        restart_times = atoi(argv[1]);
    }

    for (int i = 0; i < restart_times; i++) {
        pipeline_func();
    }


    return 0;

}

But after restarting pipeline i see memory leak. I checked it with memusage:
After 1 pipeline:

Memory usage summary: heap total: 108818840, heap peak: 106002055, stack peak: 6015024
         total calls   total memory   failed calls
 malloc|      30644      107056986              0
realloc|       4434         316391              0  (nomove:832, dec:59, free:0)
 calloc|       4949        1445463              0
   free|      43004      106939574

After 2 pipelines:

Memory usage summary: heap total: 214608301, heap peak: 105970691, stack peak: 6015024
         total calls   total memory   failed calls
 malloc|      36461      212330969              0
realloc|       4999         390863              0  (nomove:865, dec:86, free:0)
 calloc|       6097        1886469              0
   free|      56735      212687644

After 3 pipelines

Memory usage summary: heap total: 320422903, heap peak: 105970691, stack peak: 6015024
         total calls   total memory   failed calls
 malloc|      42281      317630093              0
realloc|       5564         465335              0  (nomove:914, dec:113, free:0)
 calloc|       7245        2327475              0
   free|      70469      318460855

Every pipeline it holds 41391 bytes.
Do you know what the problem could be and how to solve it?

For debugging purposes, add a gst_deinit() call at the end of your application and then run the application with GST_TRACERS=leaks GST_DEBUG=*TRACE*:7.

If you’re lucky, it will show you what kind of (mini)object is leaked.

It could be that another kind of allocation is leaked of course, in which case you’d need to perhaps try valgrind --leak-check=yes or somesuch (there are suppression files in the GStreamer repo for GObject things etc which might be useful to cut through the noise).

With gst_deinit() the problem is till the same
1 pipeline

Memory usage summary: heap total: 108801136, heap peak: 105871618, stack peak: 15648
         total calls   total memory   failed calls
 malloc|      30633      107036836              0
realloc|       4418         316135              0  (nomove:826, dec:64, free:0)
 calloc|       4921        1448165              0
   free|      54806      107881086

2 pipelines

Memory usage summary: heap total: 214604599, heap peak: 105871682, stack peak: 15648
         total calls   total memory   failed calls
 malloc|      36493      212331557              0
realloc|       4985         390511              0  (nomove:866, dec:92, free:0)
 calloc|       6046        1882531              0
   free|      68552      213643127

And debug application with GST_TRACERS=leaks GST_DEBUG=*TRACE*:7. is not very informative.

With gst_deinit() the problem is till the same

I didn’t mean to suggest that it would fix the leak, but it’s required for the leak tracer to output any leaks on shutdown (unless you interact with it programmatically via the api).

Sounds like it’s something else that’s leaked then and you’ll have to investigate with valgrind or heaptrack or similar.

It might also be worth cutting down your pipeline to the bare minimum to narrow it down (remove elements at the end and replace with fakesink)

Interesting that i am using only basic elements and plugins.

And start pipeline with gst_parse_launch similar to this https://gstreamer.freedesktop.org/documentation/tutorials/basic/hello-world.html?gi-language=c

But I still got memory leaks.

Yes, that’s obviously unexpected, but hard to say more without some more info to see what actually leaks :slight_smile:

try to test restart in a loop(stop/start) for 20, 30 or 100 times and follow the memory usage. 1 run may not tell much.

Hi, @video_encoder . Do you find a cause of memory leak? I have the same problem

Hi @video_encoder we have exact the same problem.

We tested it on embeded boards, linux and windows, they all show the same issue.
We checked the GST_TRACERS=leaks and did not find leaks
We measured the memory usage over time. cycles of 30 - 180
Loading HD-Video and play it for 10 second .

And we tested it with 3 versions 1.18.6, 1.22.2 and 1.24.5.
The graphs show the memory consumption 30 times every time the
pipeline_func is called

The text on the graph

befparse is the memory just before gst_parse_launch(.,.)
afterready is the memory after the pipeline is set in READY state
afterplay is the memory after PLAYED is done
statnull is the memory after state NULL

We also checked what unref does do and gst_deinit. Even after those there is still a lot of memory.

We also noticed that after a long pause, after GST_STATE_NULL the memory usage is lower but we can\t wait for 8 seconds between 2 plays.

Hope anyone has a suggestion

Hi,

Do you have a small code example where you can reproduce this ? It may make sense to run it in valgrind, or even Valgrind’s massif tool to see where the memory is allocated.

Olivier

Hi Olivier,

I did send you an code example,

Thanks for your reply

Hi all,

Were there any further findings to this?

Many thanks

Hi all.
The same problem.