我希望拆分GStreamer管道,以便显示和录制视频。我使用以下管道使用gst-launch工作:
gst-launch-1.0 -v videotestsrc! video / x-raw,width = 640,height = 480 tee 名称=" T" !排队! glupload! glimagesink t。 !排队! jpegenc! avimux! filesink location = output.avi
我试图在我的C ++应用程序中实现这一点,但遇到了一个对我没有意义的问题。下面是整个流水线设置,但只有最后几行相关/有趣。
gst_init (NULL, NULL);
GstElement *pipeline = gst_pipeline_new(NULL);
GstElement *sink = NULL;
GstElement *src = gst_element_factory_make("videotestsrc", NULL);
g_assert(src);
GstElement *filter = gst_element_factory_make("capsfilter", "filter");
g_assert(filter);
g_object_set(G_OBJECT (filter), "caps", gst_caps_new_simple("video/x-raw",
"width", G_TYPE_INT, 640,
"height", G_TYPE_INT, 480,
NULL),
NULL);
GstElement *convert = gst_element_factory_make("videoconvert", NULL);
g_assert(convert);
// Tee
GstElement *tee = gst_element_factory_make("tee", "videotee");
g_assert(GstElement *tee);
// Display queue
GstElement *displayQueue = gst_element_factory_make("queue", "displayQueue");
g_assert(displayQueue);
GstElement *upload = gst_element_factory_make("glupload", NULL);
g_assert(upload);
sink = gst_element_factory_make("qmlglsink", NULL);
g_assert(sink);
// Record queue
GstElement *recordQueue = gst_element_factory_make("queue", "recordQueue");
g_assert(recordQueue);
GstElement *encode = gst_element_factory_make("jpegenc", NULL);
g_assert(encode);
GstElement *mux = gst_element_factory_make("avimux", NULL);
g_assert(mux);
GstElement *filesink = gst_element_factory_make("filesink", NULL);
g_assert(filesink);
g_object_set(G_OBJECT(filesink), "location", "output.avi", NULL);
// The above is not interesting, just included it for completeness
// Add elements to bin
gst_bin_add_many(GST_BIN (pipeline), src, filter, convert, tee, displayQueue, upload, sink, recordQueue, encode, mux, filesink, NULL);
// Link elements
gst_element_link_many(src, filter, convert, tee, NULL);
gst_element_link_many(tee, displayQueue, upload, sink, NULL);
//gst_element_link_many(tee, recordQueue, encode, mux, filesink, NULL);
如果我没有将 filesink 添加到bin中,则测试视频会按预期显示。如果我将 filesink 添加到bin中,则视频会显示第一帧然后冻结。我不明白为什么会这样,因为我还没有将 filesink 链接到管道(该行被注释掉)。
有谁知道这是为什么?
(如果我取消注释记录队列链接到管道的行,则不显示任何内容。但这可能是以后的问题。)
更新
我尝试使用gst_parse_launch()运行管道,它显示了相同的行为。
GError *error = NULL;
GstPipeline *pipeline;
pipeline = GST_PIPELINE(gst_parse_launch("videotestsrc ! video/x-raw,width=640,height=480 tee name='t' ! queue ! glupload ! glimagesink t. ! queue ! jpegenc ! avimux ! filesink location=output.avi", &error));
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
上面的代码在第一帧冻结,并且创建了output.avi文件但是大小为0字节。如果我删除filesink队列,则视频显示正常。
使用:
videotestsrc! video / x-raw,width = 640,height = 480 tee name =" t" !排队! glupload! glimagesink
不能工作:
videotestsrc! video / x-raw,width = 640,height = 480 tee name =" t" !排队! glupload! glimagesink t。 !排队! jpegenc! avimux!文件接收 位置= output.avi
所以我想我的filesink插件有问题。我试图使用绝对路径来提交,但这并没有帮助。 (当我从终端使用gst-launch时它仍能正常工作)
我还尝试使用环境变量GST_DEBUG="filesink:9"
打印一些调试信息,但它不打印任何错误,只有以下信息:
0:00:00.116304411 3331 0x7f92b4002f60 INFO filesink gstfilesink.c:301:gst_file_sink_set_location:filename: /some/path/output.avi
0:00:00.116345776 3331 0x7f92b4002f60 INFO filesink gstfilesink.c:302:gst_file_sink_set_location:uri: file:///some/path/output.avi
0:00:00.118291875 3331 0x7f92b4002f60 DEBUG filesink gstfilesink.c:523:gst_file_sink_do_seek:寻求抵消 0使用fseeko
0:00:00.118320893 3331 0x7f92b4002f60 DEBUG filesink gstfilesink.c:423:gst_file_sink_open_file:已打开 文件/some/path/output.avi,可搜索1
有谁知道造成这种情况的原因是什么?
答案 0 :(得分:0)
您可以先选择使用gst_parse_launch()的简单选项,而不是创建元素并连接打击垫。
来到你冻结的问题,元素的链接是不正确的 它需要遵循:
// Link elements
gst_element_link_many(src, filter, convert, tee, NULL);
/* Manually link the Tee, which has "Request" pads */
GstPad *tee_display_pad = gst_element_get_request_pad (tee, "src_%u");
GstPad *queue_display_pad = gst_element_get_static_pad (displayQueue, "sink");
GstPad *tee_video_pad = gst_element_get_request_pad (tee, "src_%u");
GstPad *queue_video_pad = gst_element_get_static_pad (recordQueue, "sink");
if (gst_pad_link (tee_display_pad, queue_display_pad) != GST_PAD_LINK_OK ||
gst_pad_link (tee_video_pad, queue_video_pad) != GST_PAD_LINK_OK)
return -1;
gst_object_unref (tee_display_pad);
gst_object_unref (queue_display_pad);
gst_object_unref (tee_video_pad);
gst_object_unref (queue_video_pad);
gst_element_link_many(displayQueue, upload, sink, NULL);
gst_element_link_many(recordQueue, encode, mux, filesink, NULL);