Hello!
In my project i have to play/pause some gstreamer’s pipeline.
The problem is huge memory leak (around 100 MB per each play/pause iteration).
Here i have demo program, that reproduce the leak. Looks like the reason of the leak is omxh264enc. If i delete line 11 from the demo program, memory leak disappears.
May you suggest some decision or workaround for me?
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <thread>
#include <gst/gst.h>
std::string strWeb
{
"appsrc name=source !"
"video/x-raw, format=I420, width=3840, height=2160, framerate=2/1 !"
"omxh264enc ! " // looks like memory leak reason is in this line !!!!!
"fakesink"
};
bool white = true;
GstClockTime g_timestamp;
static void cb_need_data( GstElement * appsrc, guint unused_size, gpointer data )
{
GstBuffer *buffer;
guint size;
GstFlowReturn ret;
size = 3840 * 2160 * 2;
buffer = gst_buffer_new_allocate (NULL, size, NULL);
gst_buffer_memset (buffer, 0, white ? 0xff : 0x0, size);
white = !white;
/* increment the g_timestamp every 1/2 second */
GST_BUFFER_PTS (buffer) = g_timestamp;
GST_BUFFER_DURATION (buffer) = gst_util_uint64_scale_int (1, GST_SECOND, 2);
g_timestamp += GST_BUFFER_DURATION (buffer);
g_signal_emit_by_name (appsrc, "push-buffer", buffer, &ret);
gst_buffer_unref(buffer);
printf("need data\n");
}
int main()
{
GstElement *appsrc;
GMainLoop *g_loop;
GError *err = NULL;
g_timestamp = 0;
g_loop = g_main_loop_new(NULL, FALSE);
gst_init(NULL, NULL);
GstElement *element = gst_parse_launch(strWeb.c_str(), &err);
if (!element)
{
printf("appsrc error - %s\n", err->message);
return 1;
}
appsrc = gst_bin_get_by_name(GST_BIN(element), "source");
if (!appsrc)
{
printf("appsrc error\n");
return 1;
}
g_signal_connect (appsrc, "need-data", G_CALLBACK(cb_need_data), NULL);
std::thread thread([&]()
{
while(true)
{
sleep(5);
g_main_loop_quit(g_loop);
}
});
for (int i = 0; i < 100; i++)
{
gst_element_set_state (element, GST_STATE_PLAYING);
sleep(1);
g_main_loop_run(g_loop);
sleep(1);
gst_element_set_state (element, GST_STATE_NULL);
printf("rerun %d\n", i);
sleep(1);
}
gst_object_unref(element);
gst_deinit();
return 0;
}