GStreamer在第一帧冻结

时间:2017-12-05 12:09:27

标签: c gstreamer

我希望拆分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

有谁知道造成这种情况的原因是什么?

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);
相关问题