GStreamer管道挂起在gst_element_get_state上

时间:2016-07-01 14:21:28

标签: c++ c gstreamer

我使用GStreamer库遵循非常基本的代码(如果重要的话,在Xubuntu 16.04上使用GStreamer v1.8.1)

#include <gst/gst.h>

int main(int argc, char *argv[])
{
    gst_init(&argc, &argv);

    const gchar* pd =
        "filesrc location=some.mp4 ! qtdemux name=d "
        "d.video_0 ! fakesink "
        "d.audio_0 ! fakesink ";

    GError* error = nullptr;
    GstElement *pipeline = gst_parse_launch(pd, &error);

    GstState state; GstState pending;
    switch(gst_element_set_state(pipeline, GST_STATE_PAUSED)) {
        case GST_STATE_CHANGE_FAILURE:
        case GST_STATE_CHANGE_NO_PREROLL:
            return -1;
        case GST_STATE_CHANGE_ASYNC: {
            gst_element_get_state(pipeline, &state, &pending, GST_CLOCK_TIME_NONE);
        }
        case GST_STATE_CHANGE_SUCCESS:
            break;
    }

    GMainLoop* loop = g_main_loop_new(nullptr, false);
    g_main_loop_run(loop);

    gst_object_unref(pipeline);

    return 0;
}

问题是,当我尝试运行此代码时,它会挂起

gst_element_get_state(pipeline, &state, &pending, GST_CLOCK_TIME_NONE);

问题是 - 它为什么会挂起?特别是如果考虑到,如果我从管道描述中删除d.audio_0 ! fakesink,它就不会挂起。

1 个答案:

答案 0 :(得分:3)

优良作法是始终在管道中生成多个输出分支的元素之后添加队列(或多队列),例如分流器。

原因是接收器将阻止等待其他接收器接收第一个缓冲区(预卷)。使用单个线程作为代码,它将阻止可用于将数据推入接收器的唯一线程。单个线程从解复用器进入两个接收器,一旦1个阻塞,数据无法到达第二个接收器。

使用队列将产生新线程,每个接收器将有一个专用线程。