linux - 无法在应用程序中将 Gstreamer Decodebin 链接到 jpegenc

标签 linux gstreamer

我正在尝试编写一个将 MPEG4 转换为 JPEG 文件的应用程序。我有一个从命令行工作的管道。但从我的 C 应用程序运行时,我遇到了来自 Gstreamer 的无法链接错误。

这是我的管道:

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.

有什么想法吗?

最佳答案

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

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

检查 decodebin 的元素描述 online或者在终端上运行gstreamer-inspect-0.10decodebin,您将获得有关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。在将两个解码器链接到 jpegenc(在您的情况下)之前,您必须收听此信号。

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

这里有一些关于使用 decodebindecodebin2 的引用:

关于linux - 无法在应用程序中将 Gstreamer Decodebin 链接到 jpegenc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28033813/

相关文章:

linux - fhem界面未启动

c++ - GstBuffer 到颜色垫

stream - Gstreamer - appsrc 推送模型

c++ - 你如何在 Linux 上用 C++ 播放或录制音频(到 .WAV)?

linux - 我们如何通过总结进程占用的内存和 linux 中的可用内存来达到 RAM 大小?

c++ - linux系统找不到libexpat

linux - 查找超过 15 分钟的文件

linux - 使用 GIT 从 Windows 机器克隆到 Linux 网络服务器(内部)

php - 从 php 终止 gstreamer

c - 当仅向视频管道提供音频时,Gstreamer 管道卡在预滚动状态