Утечка памяти в GStreamer после перезапуска конвейера - PullRequest
0 голосов
/ 26 апреля 2019

GStreamer версия: 1.14.4

В моем исходном приложении одновременно воспроизводилось несколько видео (началось с 300 МБ и увеличилось до 1 ГБ после нескольких перезапусков). Они должны быть перезапущены (разархивировать весь конвейер и создать заново) каждые N минут. После 3-го или 4-го перезапуска потребление памяти увеличилось до 6-7 ГБ и снова уменьшилось до 1 ГБ. Это случилось несколько раз. Так что это не типичная утечка памяти, но я не знаю, почему она началась с 300 МБ, увеличилась до 1 ГБ и колебалась между 6-7 и 1 ГБ.

Поэтому я решил создать 2 простых теста.

1-й тест:

То, что я тестировал: простое видео, длина 114,8 МБ и продолжительность почти 5 минут.

В чем была проблема: использование памяти начинается с 62,2 МБ и увеличивается до 88 МБ после 1-го воспроизведения. Когда видео было перезагружено и конвейер перезапущен (повторно обработан и создан заново), использование памяти осталось 88 МБ и продолжало увеличиваться до 105 МБ, где оно оставалось стабильным в течение оставшегося времени тестирования.

auto app = Gtk::Application::create("org.gtkmm.app");
Gtk::Window w;
gst_init(NULL, NULL);

Glib::signal_timeout().connect_seconds([]()
{
    auto pipeline = gst_parse_launch("playbin uri=file:///path/to/150.mp4", NULL);

    gst_element_set_state (pipeline, GST_STATE_PLAYING);

    auto bus = gst_element_get_bus (pipeline);
    auto msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, (GstMessageType)(GST_MESSAGE_ERROR | GST_MESSAGE_EOS));

    if (msg != NULL)
        gst_message_unref (msg);
    gst_object_unref (bus);
    gst_element_set_state (pipeline, GST_STATE_NULL);
    gst_object_unref (pipeline);

    return true;
}, 5);

return app->run(w);

2-й тест связан даже не с конвейером, а с GstDiscoverer, который я также использовал в своем исходном приложении.

Что я тестировал: простой плагин GstDiscoverer

В чем была проблема: объем памяти начался с 19,2 МБ и увеличился до 100 МБ после нескольких обнаружений, где оставался стабильным в течение оставшегося времени тестирования;

auto app = Gtk::Application::create("org.gtkmm.app");
Gtk::Window w;
gst_init(NULL, NULL);

Glib::signal_timeout().connect_seconds([](){
    auto discoverer = gst_discoverer_new(5 * GST_SECOND, nullptr);
    auto info = gst_discoverer_discover_uri(discoverer, "file:///path/to/150.mp4", nullptr);
    gst_discoverer_info_unref(info);
    g_object_unref(discoverer);

    return true;
}, 5);

return app->run(w);

Вывод: это не настоящая утечка памяти, но я хочу знать, почему она постоянно увеличивает память до некоторой "магической границы". В исходном приложении оно было еще более странным, поскольку оно колебалось между 1 ГБ и 6-7 ГБ, несмотря на то, что все ресурсы не были переброшены.

Возможно, GStreamer использует некоторый внутренний пул или кеш, который не освобождается даже после отмены конвейера. Есть предложения?

...