gstreamer 管道设置为 GST_STATE_NULL 后未释放内存

问题描述 投票:0回答:2

我的应用程序需要多次重新启动 gstreamer 管道。 但是将管道设置为 GST_STATE_NULL 并在管道上调用 unref 后,内存似乎未释放。 每次重新启动后,与进程相关的内存都会不断增加。

我能够仅使用 videotestsrc-fakesink 元素重现问题,如下所示:

//g++ -Wall testpage_Simple.cpp -o testpage_Simple $(pkg-config --cflags --libs gstreamer-1.0)

#include <gst/gst.h> 
GstElement *pipeline;
GstElement *src;
GstElement *sink;
void clearPipeline () {
    // g_print ("clearPipeline    ");
    gst_element_set_state (pipeline, GST_STATE_NULL); 
    gst_object_unref (pipeline); 
}
void createPipeline () {
    pipeline = gst_pipeline_new ("pipelinePlay");
    src = gst_element_factory_make ("videotestsrc", "source");
    sink = gst_element_factory_make ("fakesink", "sink");

    gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);

    if (gst_element_link (src, sink)!= TRUE) {
        g_printerr ("src, sink could not be linked.\n");
    }
    gst_element_set_state (pipeline, GST_STATE_PLAYING);
}

gint main (gint argc, gchar * argv[]) 
{ 
    gst_init (NULL, NULL);
    system("gst-launch-1.0 --gst-version");
    g_print ("Start Test - ");
 //   for (int i=1; i<=10; i++) {
        system ("top -b -n 1 | grep testpage | awk '{print $6}'");
        createPipeline();
        clearPipeline(); 
 //   }
    g_print ("End of test !! ");
    system ("top -b -n 1 | grep testpage | awk '{print $6}'");
    gst_deinit();
    return 0; 
}

Ubuntu 19.04 上的示例输出(仅显示此过程中 top 命令的 RES 列值):
GStreamer 核心库版本 1.16.1
开始测试 - 7140
测试结束!! 8504

我们在使用 gstreamer 1.12.4 的 Ubuntu 18.04 上也观察到了类似的内存趋势。

这是预期的行为还是我在清理管道时遗漏了一些东西??

我检查了下面的链接。这似乎是一个类似的问题,但这个问题没有答案
管道重启后GStreamer内存泄漏

我尝试了下面链接中的磁盘缓存建议,也遇到了类似的问题。但这也没有帮助。
http://gstreamer-devel.966125.n4.nabble.com/Properly-freeing-resources-td4658631.html

c++ c video gstreamer gstreamer-1.0
2个回答
0
投票

只是猜测,也许问题与元素可能的状态转换有关

根据 https://gstreamer.freedesktop.org/documentation/additional/design/states.html?gi-language=c# 可能发生以下状态变化:

NULL -> READY:
    The element must check if the resources it needs are available. Device sinks and sources typically try to probe the device to constrain their caps.
    The element opens the device, this is needed if the previous step requires the device to be opened.

READY -> PAUSED:
    The element pads are activated in order to receive data in PAUSED. Streaming threads are started.
    Some elements might need to return ASYNC and complete the state change when they have enough information. It is a requirement for sinks to return ASYNC and complete the state change when they receive the first buffer or EOS event (preroll). Sinks also block the dataflow when in PAUSED.
    A pipeline resets the running_time to 0.
    Live sources return NO_PREROLL and don't generate data.

PAUSED -> PLAYING:
    Most elements ignore this state change.
    The pipeline selects a clock and distributes this to all the children before setting them to PLAYING. This means that it is only allowed to synchronize on the clock in the PLAYING state.
    The pipeline uses the clock and the running_time to calculate the base_time. This base_time is distributed to all children when performing the state change.
    Sink elements stop blocking on the preroll buffer or event and start rendering the data.
    Sinks can post the EOS message in the PLAYING state. It is not allowed to post EOS when not in the PLAYING state.
    While streaming in PAUSED or PLAYING elements can create and remove sometimes pads.
    Live sources start generating data and return SUCCESS.

PLAYING -> PAUSED:
    Most elements ignore this state change.
    The pipeline calculates the running_time based on the last selected clock and the base_time. It stores this information to continue playback when going back to the PLAYING state.
    Sinks unblock any clock wait calls.
    When a sink does not have a pending buffer to play, it returns ASYNC from this state change and completes the state change when it receives a new buffer or an EOS event.
    Any queued EOS messages are removed since they will be reposted when going back to the PLAYING state. The EOS messages are queued in GstBins.
    Live sources stop generating data and return NO_PREROLL.

PAUSED -> READY:
    Sinks unblock any waits in the preroll.
    Elements unblock any waits on devices
    Chain or get_range() functions return FLUSHING.
    The element pads are deactivated so that streaming becomes impossible and all streaming threads are stopped.
    The sink forgets all negotiated formats
    Elements remove all sometimes pads

READY -> NULL:
    Elements close devices
    Elements reset any internal state.

如果当前状态正在播放,则 st。喜欢

gst_element_set_state (pipeline, GST_STATE_PAUSED);
gst_element_set_state (pipeline, GST_STATE_READY);
gst_element_set_state (pipeline, GST_STATE_NULL);

可能有帮助

检查 gst_element_set_state(...) 的返回值也可能不是一个坏主意:)


0
投票

您找到解决此问题的方法了吗? 我看到非常相似的行为..

© www.soinside.com 2019 - 2024. All rights reserved.