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

Linux 无法将Gstreamer decodebin链接到应用程序中的jpegenc,linux,gstreamer,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 *conve

我正在尝试编写一个应用程序,将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-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.
0:00:07.460292251 870 0x73600信息GST_元素_工厂gstelementfactory.c:374:GST_元素_工厂_创建:创建名为“接收器到框架文件”的元素“多文件接收器”
0:00:07.461766792 870 0x73600信息GST\u元素\u焊盘gstelement.c:728:GST\u元素\u添加\u焊盘:添加焊盘“水槽”
0:00:07.463330792 870 0x73600信息GST_元素_PADS gstutils.c:1698:GST_元素_链接_PADS_full:尝试链接元素转换文件源:(任意)到元素转换解码库:(任意)
0:00:07.464368584 870 0x73600信息GST_pad gstutils.c:1032:GST_pad_check_链接:尝试链接转换文件源:src和转换解码器bin:sink
0:00:07.465330126 870 0x73600信息GST_PADS gstutils.c:1596:准备链接可能重影:在同一个文件箱中转换文件源和转换解码箱,无需重影板
0:00:07.466026334 870 0x73600信息GST_pad gstpad.c:1978:GST_pad_link_prepare:尝试链接转换文件源:src和转换解码器bin:sink
0:00:07.466664876 870 0x73600信息GST_pad gstpad.c:2161:GST_pad_link_full:链接转换文件源:src和convert decodebin:sink,成功
0:00:07.467401751 870 0x73600信息GST_元素_PADS gstutils.c:1698:GST_元素_链接_PADS_full:尝试链接元素转换decodebin:(任意)到元素jpeg编码器:(任意)
0:00:07.468785959 870 0x73600信息GST_元素_PADS gstelement.c:972:GST_元素_get_static_pad:元素“convert decodebin”中没有此类pad“src%d”
0:00:07.470078917 870 0x73600信息GST\u元素\u焊盘gstutils.c:1216:GST\u元素\u获取\u兼容\u焊盘:找不到可链接到jpeg编码器的兼容焊盘:接收器
1999年12月31日星期五23:41:45:错误:[ProcessCapture]元素无法链接。

有什么想法吗?

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

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

检查
decodebin
的元素描述或在终端上运行
gstreamer-inspect-0.10 decodebin
,您将获得有关
decodebin
元素的一些信息

有趣的部分(在本例中)是“焊盘模板”和“元件信号”:

在那里你可以看到,源板只是“有时”可用。这是因为该元素可以解码不同的输入格式,并且在检测到输入类型之前,输出将不可用。当
decodebin
检测到输入格式时,它会触发信号
新解码键盘
。在将两个decodebin链接到JPEG ENC(在您的情况下)之前,您必须先收听此信号

在这里,您可以找到一个类似的监听“padd添加”信号的实现:

这里有一些关于使用
decodebin
decodebin2
的参考:


您可能只需要在decodebin和JPEG之间进行视频转换。我正在Beaglebone Black上使用gstreamer-0.10.36。我只在中构建了一组精选的插件。其中之一是
autoconvert
插件,它包含
autovideoconvert
。我试过了,但是运气不好。仍然说无法链接元素。我也尝试了
ffmpegcolorspace
,但行为没有改变。可能是gst\u元素\u链接\u很多无法处理decodebin src pad的动态特性。有关更多详细信息,请参阅此链接: