【发布时间】:2017-12-05 12:09:26
【问题描述】:
我希望拆分 GStreamer 管道,以便显示和录制视频。我使用以下管道与 gst-launch 一起工作:
gst-launch-1.0 -v videotestsrc !视频/x-raw,宽度=640,高度=480 tee 名称=“t”!队列 !下载! glimagesink t。 !队列 !杰佩根! ! 文件接收器位置=输出.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 字节。如果我删除文件接收器队列,则视频显示正常。
作品:
videotestsrc !视频/x-raw,width=640,height=480 tee name="t" !队列 ! 下载! glimagesink
不起作用:
videotestsrc !视频/x-raw,width=640,height=480 tee name="t" !队列 ! 下载! glimagesink t。 !队列 !杰佩根! !文件接收器 位置=输出.avi
所以我想我的文件接收器插件有问题。我尝试使用文件的绝对路径,但这没有帮助。 (当我从终端使用 gst-launch 时它仍然可以正常工作)
我也试过用环境变量GST_DEBUG="filesink:9"打印一些调试信息,但它没有打印任何错误,只有这个信息:
0:00:00.116304411 3331 0x7f92b4002f60 INFO 文件接收器 gstfilesink.c:301:gst_file_sink_set_location: 文件名: /some/path/output.avi
0:00:00.116345776 3331 0x7f92b4002f60 INFO 文件接收器 gstfilesink.c:302:gst_file_sink_set_location: uri: file:///some/path/output.avi
0:00:00.118291875 3331 0x7f92b4002f60 调试文件接收器 gstfilesink.c:523:gst_file_sink_do_seek:寻求抵消 0 使用 fseeko
0:00:00.118320893 3331 0x7f92b4002f60 调试文件接收器 gstfilesink.c:423:gst_file_sink_open_file: 打开 文件 /some/path/output.avi,可查找 1
有人知道是什么原因造成的吗?
【问题讨论】:
-
为什么是 C 和 C++ 标签?这与编写代码的编程语言无关。
-
代码是用 C/C++ 编写的。我正在使用 C 的 GStreamer 库并在我的 C++ 应用程序中使用它。可能有其他语言的 GStreamer 库,但只有 C/C++ 的 GStreamer 是相关的,因此我添加了标签。
-
与 Qt 也没有太大关系。我怀疑可以从上面的例子中给出答案。除了所有这些代码对于组成 GStreamer 管道可能不正确之外,我不能添加太多。最好尝试查找有关如何使用
gst_parse_launch()gist.github.com/nzjrs/725122/… 的信息以及其他示例。至少你会将该任务委派给 GStreamer 本身。 -
@KMK,这仍然与 C 或 C++ 作为编程语言无关。您也没有用“英语”标记您的问题。
-
随着你的最新更新,你有一个管道 "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));"它需要是 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 位置=output.avi", &error));你错过了一个“!”在 caps 过滤器之后和 tee 元素之前