Search code examples
cvideogstreamerdecoder

Gstreamer linking decodebin2 to autovideosink


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

Solution

  • 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");