0

I am trying to write an application that will turn an MPEG4 into JPEG files. I have a pipeline working from the command line. But I'm getting unable to link errors from Gstreamer when running from my C application.

Here is my pipeline:

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

Here is the application source that builds the pipeline:

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);
...

And here is my output with 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.

Any ideas?

linsek
  • 3,334
  • 9
  • 42
  • 55
  • You may just need a videoconvert between decodebin and jpegenc. – mpr Jan 19 '15 at 21:33
  • I am using gstreamer-0.10.36 on a Beaglebone Black. I've only built a select group of plugins in. One of them was the `autoconvert` plugin which contains `autovideoconvert`. I tried that, but no luck. Still says couldn't link elements. – linsek Jan 19 '15 at 22:45
  • I also tried `ffmpegcolorspace` with no change in behavior. – linsek Jan 19 '15 at 22:48
  • It may be that gst_element_link_many doesn't handle the dynamic nature of the decodebin src pads. See this link for more details: http://stackoverflow.com/questions/17492757/gstreamer1-0-link-a-decodebin-to-videoconvert – mpr Jan 19 '15 at 22:53

1 Answers1

1

When using gstreamer one must verify which elements can be plugged together in the pipeline and how.

As a rough simplification all elements have a sink and a source in order to form a chain and sources plug to sinks. Many elements can just be plugged as the sink and source are "static" (they do not change). However, some element such as decodebin require a bit more attention since they source is not always present.

Checking the element description for decodebin online or running gstreamer-inspect-0.10 decodebin on a terminal, you will get some information about the decodebin element.

The interesting sections (in this case) are the "Pad templates" and "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 (...)

...

There you can read that the source pad is just "sometimes" available. This happens because this element can decode different input formats and the output won't be available until the input type has been detected. When decodebin has detected the input format it triggers the signal new-decoded-pad. You have to listen to this signal before linking the two decodebin to jpegenc (in your case).

Here you can find a similar implementation for listening to the "padd-added" signal: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-components-decodebin.html

Here some references to the use of decodebin and decodebin2:

Community
  • 1
  • 1
lebrush
  • 31
  • 3