I'm trying to add some processing logic to a program that chugs away on a local video file, but I'm having some trouble understanding how to translate the following (successfull) gst-launch command into code (and supply it with a "pad-added" callback):
gst-launch filesrc location=/path/to/my/video.avi ! decodebin2 ! autovideosink
I've tried my hand at gstreamer's basic-tutorial-3, using decodebin2
in place of audioconvert
:
data.source = gst_element_factory_make("filesrc", "source");
data.convert = gst_element_factory_make("decodebin2", "uridecoder");
data.sink = gst_element_factory_make("autovideosink", "autodetect");
However, I am never able to link data.convert
to data.sink
, as it is outlined in the example; the gst_element_link(data.convert, data.sink)
always fails. I suspect there's some special treatment for decodebin2
. Some gstreamer users have metioned using ghostpads and seperate bins, which after a swift attempt, also yielded no success:
data.bin = gst_bin_new("processing-bin");
gst_bin_add_many(GST_BIN(data.bin), data.decoder, data.sink, NULL);
gst_element_add_pad(data.bin,
gst_ghost_pad_new("bin_sink",
gst_element_get_static_pad(data.decoder,"sink")));
I'm a little confused as how to continue debugging. Does anyone else have any pointers?
Here is a boiled down gist of the current code: (gist)
====
Update: My callback is now firing, I think it was because I had an incorrect filename for the filesrc location (whoops)
Now, after following the advice below, I am able to confirm that I'm getting audio and video caps types and check against them in the pad-added callback. However, I'm now getting the following "not-linked" error after one frame of pad processing:
Debugging information: gstavidemux.c(5187): gst_avi_demux_loop (): /GstPipeline:gstreamer-test/GstBin:processing-bin/GstDecodeBin2:uridecoder/GstAviDemux:avidemux0:
streaming stopped, reason not-linked
I think the main issue I was running into is that I was listening to the decoder for new pads, when I should've been getting the static pad from the video sink. I've updated the gist with my callback function to illustrate the difference.
Basically, it boiled down to this change:
I changed
GstPad *sink_pad = gst_element_get_static_pad(data->decoder, "sink");
to the following
GstPad *sink_pad = gst_element_get_static_pad(data->sink, "sink");