无法在应用程序中将Gstreamer decodebin链接到jpegenc

时间:2015-01-19 21:31:21

标签: linux gstreamer

我正在尝试编写一个将MPEG4转换为JPEG文件的应用程序。我有一个从命令行工作的管道。但是当我从C应用程序运行时,我从Gstreamer收到unable to link错误。

这是我的管道:

gst-launch-0.10 filesrc location=/tmp/capture.m4v ! decodebin ! jpegenc ! multifilesink location=/tmp/img%d.jpg

以下是构建管道的应用程序源:

GstElement  *convert_pipeline;
GstElement  *convert_src;
GstElement  *convert_sink;
GstElement  *demuxer;
GstElement  *decoder;
GstElement  *jpeg_encoder;

convert_pipeline = gst_pipeline_new ("convert-pipeline");
g_assert(convert_pipeline);

#define CAPTURE_FILE            "/tmp/capture.m4v"
convert_src = gst_element_factory_make("filesrc", "convert file source");
g_object_set(G_OBJECT (convert_src), "location", CAPTURE_FILE, NULL);
g_assert(convert_src);

decoder = gst_element_factory_make("decodebin", "MPEG4 decoder");
g_assert(decoder);

jpeg_encoder = gst_element_factory_make ("jpegenc", "jpeg encoder");
g_assert(jpeg_encoder);

convert_sink = gst_element_factory_make("multifilesink", "sink to frame file");
g_object_set(G_OBJECT (convert_sink), "location", CAPTURE_FRAME_FILES, NULL);
g_assert(convert_sink);

gst_bin_add_many(GST_BIN(convert_pipeline), convert_src, decoder, jpeg_encoder, convert_sink, NULL);

if (gst_element_link_many(convert_src, decoder, jpeg_encoder, convert_sink, NULL) != TRUE)
{
    logme(LEVEL_ERROR, "[%s] Elements could not be linked.", __METHOD_NAME__.c_str());
    gst_object_unref(convert_pipeline);
    return;
}

ret = gst_element_set_state (convert_pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE) {
  logme(LEVEL_ERROR, "[%s] Unable to set the frame capture pipeline to the playing state", __METHOD_NAME__.c_str());
  gst_object_unref (convert_pipeline);
  return;
}

HandleGstEvent(convert_pipeline);
...

这是我的输出GST_DEBUG = *:3

0:00:07.460292251   870    0x73600 INFO     GST_ELEMENT_FACTORY gstelementfactory.c:374:gst_element_factory_create: creating element "multifilesink" named "sink to frame file"
0:00:07.461766792   870    0x73600 INFO        GST_ELEMENT_PADS gstelement.c:728:gst_element_add_pad:<GstBaseSink@0x29c1d8> adding pad 'sink'
0:00:07.463330792   870    0x73600 INFO        GST_ELEMENT_PADS gstutils.c:1698:gst_element_link_pads_full: trying to link element convert file source:(any) to element convert decodebin:(any)
0:00:07.464368584   870    0x73600 INFO                GST_PADS gstutils.c:1032:gst_pad_check_link: trying to link convert file source:src and convert decodebin:sink
0:00:07.465330126   870    0x73600 INFO                GST_PADS gstutils.c:1596:prepare_link_maybe_ghosting: convert file source and convert decodebin in same bin, no need for ghost pads
0:00:07.466026334   870    0x73600 INFO                GST_PADS gstpad.c:1978:gst_pad_link_prepare: trying to link convert file source:src and convert decodebin:sink
0:00:07.466664876   870    0x73600 INFO                GST_PADS gstpad.c:2161:gst_pad_link_full: linked convert file source:src and convert decodebin:sink, successful
0:00:07.467401751   870    0x73600 INFO        GST_ELEMENT_PADS gstutils.c:1698:gst_element_link_pads_full: trying to link element convert decodebin:(any) to element jpeg encoder:(any)
0:00:07.468785959   870    0x73600 INFO        GST_ELEMENT_PADS gstelement.c:972:gst_element_get_static_pad: no such pad 'src%d' in element "convert decodebin"
0:00:07.470078917   870    0x73600 INFO        GST_ELEMENT_PADS gstutils.c:1216:gst_element_get_compatible_pad:<convert decodebin> Could not find a compatible pad to link to jpeg encoder:sink
Fri Dec 31 23:41:45 1999: ERROR:[ProcessCapture] Elements could not be linked.

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

使用gstreamer时,必须验证哪些元素可以在管道中插入,以及如何。

作为粗略的简化,所有元素都有一个接收器和一个源,以便形成链和源插头到接收器。可以插入许多元素,因为接收器和源是“静态的”(它们不会改变)。但是,某些元素如decodebin需要更多关注,因为它们并不总是存在。

检查终端上decodebin online或运行gstreamer-inspect-0.10 decodebin的元素说明,您将获得有关decodebin元素的一些信息。

有趣的部分(在本例中)是“Pad templates”和“Element Signals”:

...

Pad Templates:
  SINK template: 'sink'
    Availability: Always
    Capabilities:
    ANY

SRC template: 'src%d'
  Availability: Sometimes
  Capabilities:
   ANY

...

Element Signals:
 "new-decoded-pad" :  void user_function (...)

...

在那里你可以看到源垫只是“有时”可用。发生这种情况是因为此元素可以解码不同的输入格式,并且在检测到输入类型之前输出将不可用。当decodebin检测到输入格式时,它会触发信号new-decoded-pad。在将两个decodebin链接到jpegenc(在您的情况下)之前,您必须先听取此信号。

在这里你可以找到一个类似的实现,用于收听“padd-added”信号: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-components-decodebin.html

这里有一些使用decodebindecodebin2的参考: