Проблема утечки памяти с конвейером gstreamer с оплатой / паузой на Jetson TK1 - PullRequest
0 голосов
/ 08 ноября 2018

В моем проекте (Jetson TK1 с ​​L4T 21.4) я должен воспроизвести / приостановить конвейер некоторых gstreamer.

Проблема в большой утечке памяти (около 100 МБ на каждую итерацию воспроизведения / паузы). Здесь у меня есть демонстрационная программа, которая воспроизводит утечки. Похоже, причиной утечки является omxh264enc. Если я удалю строку 11 из демонстрационной программы, утечка памяти исчезнет.

Можете ли вы предложить какое-нибудь решение или обходной путь для меня?

#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;
}

Компилировать с

g++ main.c -o demo_mem_leak `pkg-config --cflags --libs gstreamer-1.0` --std=c++11
...