状态切换时 Gstreamer 内存泄漏

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

我一直在尝试制作一个通过 gstreamer 运行一些相机的程序。程序首先设置管道,然后根据用户输入在“播放”或“暂停”状态之间切换。 我注意到运行该程序一段时间后,该程序的内存使用量会随着时间的推移慢慢增加。在尝试了很多不同的事情之后,我能够用一个非常小的示例程序重现该问题:

#include <gst/gst.h>
#include <stdio.h>
#include <unistd.h>
#include <string>
#include <iostream>

int main(int argc, char* argv[])
{
    gst_init(&argc, &argv);
    GError* err = NULL;

    std::string pipeline_str = "fakesrc ! fakesink sync = false ";

    GstElement* pipeline = gst_parse_launch(pipeline_str.c_str(), &err);
    gst_element_set_state(pipeline, GST_STATE_READY);
    gst_element_get_state(pipeline, NULL, NULL, 4000000000ll);

    for (;;)
    {
        gst_element_set_state(pipeline, GST_STATE_PAUSED);
        GstStateChangeReturn result = gst_element_get_state(pipeline, NULL, NULL, 4000000000ll);
        if (result != GST_STATE_CHANGE_SUCCESS){
            std::cout << "error" << std::endl;
            break;
        }      
        usleep(100);

        gst_element_set_state(pipeline, GST_STATE_PLAYING);
        result = gst_element_get_state(pipeline, NULL, NULL, 4000000000ll);
        if (result != GST_STATE_CHANGE_SUCCESS){
            std::cout << "error" << std::endl;
            break;
        }
        usleep(100);
    }

    gst_element_set_state(pipeline, GST_STATE_NULL);

    gst_object_unref(pipeline);

    return 0;
}

运行此程序,我可以看到使用 htop 时内存使用量增加得相当快。所以在我看来问题是在状态切换时发生的?有人遇到过类似问题吗

c++ c memory-leaks gstreamer
1个回答
0
投票

状态更改是异步的。您生成的状态更改请求多于管道可以处理的数量,因此很可能您的消息队列是由这些请求建立的。

等待状态更改完成,然后再尝试再次更改。检查总线以了解从管道发出的状态更改。

编辑,示例:

#include <gst/gst.h>
#include <stdio.h>
#include <unistd.h>
#include <string>
#include <iostream>

int main(int argc, char* argv[])
{
    gst_init(&argc, &argv);
    GError* err = NULL;

    std::string pipeline_str = "videotestsrc ! fakesink sync=false";

    GstElement* pipeline = gst_parse_launch(pipeline_str.c_str(), &err);

    GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));

    gst_element_set_state(pipeline, GST_STATE_READY);

    for (;;)
    {
        GstMessage* msg = gst_bus_timed_pop_filtered(bus, -1, GST_MESSAGE_STATE_CHANGED);
        if (msg->src == GST_OBJECT(pipeline))
        {
            gst_message_unref(msg);
            break;
        }
        gst_message_unref(msg);
    }

    for (;;)
    {
        gst_element_set_state(pipeline, GST_STATE_PAUSED);

        for (;;)
        {
            GstMessage* msg = gst_bus_timed_pop_filtered(bus, -1, GST_MESSAGE_STATE_CHANGED);
            if (msg->src == GST_OBJECT(pipeline))
            {
                gst_message_unref(msg);
                break;
            }
            gst_message_unref(msg);
        }

        gst_element_set_state(pipeline, GST_STATE_PLAYING);

        for (;;)
        {
            GstMessage* msg = gst_bus_timed_pop_filtered(bus, -1, GST_MESSAGE_STATE_CHANGED);
            if (msg->src == GST_OBJECT(pipeline))
            {
                gst_message_unref(msg);
                break;
            }
            gst_message_unref(msg);
        }
    }

    gst_element_set_state(pipeline, GST_STATE_NULL);

    gst_object_unref(bus);
    gst_object_unref(pipeline);

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.