GStreamer 管道挂起 gst_element_get_state
GStreamer pipeline hangs on gst_element_get_state
我有以下使用 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
它不会挂起。
最好总是在管道中产生多个输出分支的元素之后添加队列(或多队列),例如解复用器。
原因是sinks会阻塞等待其他sinks接收第一个buffer(preroll)。使用单个线程作为您的代码,它将阻止唯一可用于将数据推送到接收器的线程。单个线程从多路分离器到两个接收器,一旦 1 阻塞,数据就无法到达第二个接收器。
使用队列会生成新线程,每个接收器都会有一个专用线程。
这是一个很旧的线程,但它可能会挂起,因为您有无限超时 (GST_CLOCK_TIME_NONE)。
我有以下使用 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
它不会挂起。
最好总是在管道中产生多个输出分支的元素之后添加队列(或多队列),例如解复用器。
原因是sinks会阻塞等待其他sinks接收第一个buffer(preroll)。使用单个线程作为您的代码,它将阻止唯一可用于将数据推送到接收器的线程。单个线程从多路分离器到两个接收器,一旦 1 阻塞,数据就无法到达第二个接收器。
使用队列会生成新线程,每个接收器都会有一个专用线程。
这是一个很旧的线程,但它可能会挂起,因为您有无限超时 (GST_CLOCK_TIME_NONE)。