This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM5728: Gstreamer plugin ducatih264dec memory leak

Part Number: AM5728

Hi,

I have a pipeline with ducatih264dec that decodes a rtp video stream. I need to restart it many times. I do this using the start and stop functions (the code is presented below). The problem is that every time you restart the pipeline, ~10 MB of memory is allocated. And it is cleared only if the application is completely closed. Maybe I'm cleaning the pipeline incorrectly? Also i tried to  NULLed and unref every element of the pipeline and send a flush event to the pipeline, but the result is always the same.

//-------------RUN PIPELINE--------------------

int makePipelineUdpSrc(char *iface, char *addr, int port, int videoWidth, int videoHeight){

printf("makePipelineUdpSrc: Creating pipeline\n");

streamData.videoHeight = videoHeight;
streamData.videoWidth = videoWidth;

streamData.pipeline = gst_pipeline_new("pipeline");
if(streamData.pipeline == NULL){
printf("makePipelineUdpSrc error: can't create pipeline\n");
return -1;
}

streamData.udpcaps = gst_caps_from_string("application/x-rtp, media=video, clock-rate=90000, payload=96");

if(streamData.udpcaps == NULL){
printf("makePipelineUdpSrc error: can't create udpcaps\n");
return -1;
}
if(streamData.udpsrcVideo == NULL){
printf("makePipelineUdpSrc error: can't create udpsrcVideo\n");
return -1;
}
streamData.udpsrcVideo = gst_element_factory_make("udpsrc", "udpsrcVideo");
g_object_set(G_OBJECT(streamData.udpsrcVideo), "caps", streamData.udpcaps,
"multicast-iface", iface, "multicast-group", addr,
"auto-multicast", true, "port", port, NULL);
gst_caps_unref(streamData.udpcaps);

streamData.depayerVideo = gst_element_factory_make("rtph264depay", "depayerVideo");
if(streamData.depayerVideo == NULL){
printf("makePipelineUdpSrc error: can't create depayerVideo\n");
return -1;
}

streamData.parserVideo = gst_element_factory_make("h264parse", "parse");
if(streamData.parserVideo == NULL){
printf("makePipelineUdpSrc error: can't create parserVideo\n");
return -1;
}

streamData.decoderVideo = gst_element_factory_make("ducatih264dec", "dec");
if(streamData.decoderVideo == NULL){
printf("makePipelineUdpSrc error: can't create decoderVideo\n");
return -1;
}

streamData.capsVpeIn = gst_caps_new_simple("video/x-raw", NULL , NULL);
if(streamData.capsVpeIn == NULL){
printf("makePipelineUdpSrc error: can't create capsVpeIn\n");
return -1;
}

streamData.capsVpeOut = gst_caps_new_simple("video/x-raw", "format",
G_TYPE_STRING, "RGB", "width",
G_TYPE_INT, streamData.videoWidth,
"height", G_TYPE_INT,
streamData.videoHeight, NULL);
if(streamData.capsVpeOut == NULL){
printf("makePipelineUdpSrc error: can't create capsVpeOut\n");
return -1;
}

streamData.capsFilterVpeIn = gst_element_factory_make("capsfilter", "capsFilterVpeIn");
if(streamData.capsFilterVpeIn == NULL){
printf("makePipelineUdpSrc error: can't create capsFilterVpeIn\n");
return -1;
}
g_object_set(G_OBJECT(streamData.capsFilterVpeIn), "caps", streamData.capsVpeIn, NULL);
gst_caps_unref(streamData.capsVpeIn);

streamData.vpe = gst_element_factory_make("vpe", "vpe");
if(streamData.vpe == NULL){
printf("makePipelineUdpSrc error: can't create vpe\n");
return -1;
}

streamData.capsFilterVpeOut = gst_element_factory_make("capsfilter", "capsFilterVpeOut");
if(streamData.capsFilterVpeOut == NULL){
printf("makePipelineUdpSrc error: can't create capsFilterVpeOut\n");
return -1;
}
g_object_set(G_OBJECT(streamData.capsFilterVpeOut), "caps", streamData.capsVpeOut, NULL);
gst_caps_unref(streamData.capsVpeOut);

streamData.videosink = gst_element_factory_make("fakesink", "videosink");
if(streamData.videosink == NULL){
printf("makePipelineUdpSrc error: can't create videosink\n");
return -1;
}
g_object_set(G_OBJECT(streamData.videosink), "async", false, NULL);
g_object_set(G_OBJECT(streamData.videosink), "sync", false, NULL);

gst_bin_add_many(GST_BIN(streamData.pipeline),
streamData.udpsrcVideo, streamData.depayerVideo,
streamData.parserVideo, streamData.decoderVideo, streamData.capsFilterVpeIn,
streamData.vpe, streamData.capsFilterVpeOut, streamData.videosink, NULL);

if(gst_element_link_many(streamData.udpsrcVideo, streamData.depayerVideo,
streamData.parserVideo, streamData.decoderVideo,
streamData.capsFilterVpeIn, streamData.vpe,
streamData.capsFilterVpeOut, streamData.videosink, NULL) != TRUE){
printf("makePipelineUdpSrc error: can't link video elements\n");
return -1;
}


g_object_set(streamData.pipeline, "message-forward", TRUE, NULL);

streamData.bus = gst_pipeline_get_bus(GST_PIPELINE(streamData.pipeline));
gst_bus_set_sync_handler(streamData.bus, (catchBusMessageCb), NULL, (GDestroyNotify) g_free);
gst_object_unref(GST_OBJECT(streamData.bus));

gst_element_set_state(streamData.pipeline, GST_STATE_PLAYING);

streamData.streamLive = true;

printf("makePipelineUdpSrc: pipeline created\n");

return 0;
}

//-------------STOP PIPELINE--------------------

int deletePipelineUdpSrc(){

if(!streamData.streamLive){
printf("deletePipelineUdpSrc: nothing to delete. No pipeline exist");
return -1;
}

printf("deletePipelineUdpSrc: delete pipeline\n");

gst_element_set_state (streamData.pipeline, GST_STATE_NULL);
gst_object_unref (streamData.pipeline);

memset(&streamData,0,sizeof(StreamData));

printf("deletePipelineUdpSrc: pipeline deleted\n");

return 0;
}

  • Hi Nikolayy,

    Is there a gstreamer pipeline which reproduces the issue? please share if you have one.

    Which SDK is used here?

    Can you check this sysfs entry and confirm if the gem objects are growing every time?

    cat /sys/kernel/debug/dri/0/gem

    Thanks

    RamPrasad

  • Hi Ramprasad,

    SDK Version is 6.01.00.81.

    Gstreamer pipeline which reproduces the issue included in compex software. I will try to do small version for you today.

    I checked gem objects. Statistic are presented below.

    No pipeline started -> 0 objects, 0 bytes.

    Pipeline started -> 36 objects, 24371200 bytes.

    Pipeline stoped -> 21 objects, 14020608 bytes.

    Pipeline started -> 57 objects, 38391808 bytes.

    Pipeline stoped -> 42 objects, 28041216 bytes.

    As you can see 36 objects are added every time. But when it stops every time 21 objects are not released.

  • Hi RamPrasad,

    i found error in my code. I forgot to do unref message from gstreamer pipeline bus. For some reason, this problem appeared exactly when ducati was included in the pipeline.

    Anyway that solved my issue.

    Thanks :)