Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GStreamer: how to connect dynamic pads

I'm trying to use GStreamer to play MP4 video from a file. I have managed to play the file using playbin2 and from the command prompt using:

gst-launch filesrc location=bbb.mp4 ! decodebin2 ! autovideosink

I am expecting in the future that I will need to create more complicated pipelines and hence why I'm attempting to 'program' the pipeline. In my program I am attempting to replicate the pipeline above, however I have an issue which I suspect is related to connecting the dynamic or "sometimes" source pad of decodebin2 to the autovideo sink. I am using these elements only to keep things as simple as possible.

static void on_new_decoded_pad(GstElement* object,
                           GstPad* arg0,
                           gboolean arg1,
                           gpointer user_data)
{
    // dynamically connect decoderbin2 src pad to autovideosink sink pad
}

static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
{
    // handle bus messages
}

int main(int argc, char *argv[])
{
    GMainLoop *loop;
    GstElement *pipeline, *source, *decodebin, *videosink;
    GstBus *bus;

    gst_init (&argc, &argv);
    loop = g_main_loop_new (NULL, FALSE);

    pipeline  = gst_pipeline_new ("pipeline");
    source    = gst_element_factory_make("filesrc",       "source");
    decodebin = gst_element_factory_make("decodebin2",    "decodebin");
    videosink = gst_element_factory_make("autovideosink", "videosink");

    /* check elements were created successfully */
    if (!pipeline || !source || !decodebin || !videosink) {
        // Failed to create element. Exit Program
        return -1;
    }

    /* apply properties to elements before adding to pipeline */
    gchar * filename = "bbb.mp4";
    g_object_set(G_OBJECT(source), "location", filename, NULL);

    /* add a message handler */
    bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
    gst_bus_add_watch (bus, bus_call, loop);
    gst_object_unref (bus);

    /* add elements to pipeline (and bin if necessary) before linking them */
    gst_bin_add_many(GST_BIN (pipeline),
                     source,
                     decodebin,
                     videosink,
                     NULL);

    gst_element_link_pads(source, "src", decodebin, "sink");

    /* decodebins src pad is a sometimes pad - it gets created dynamically */
    g_signal_connect(decodebin, "new-decoded-pad", G_CALLBACK(on_new_decoded_pad),   videosink);

    /* run pipeline */
    gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING);

    g_main_loop_run(loop);

    gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_NULL);
    gst_object_unref (pipeline);

    return 0;
}

What I expect to happen when I run this program, is for the on_new_decoded_pad to get called via a call back function, which is set in the line:

g_signal_connect(decodebin, "new-decoded-pad", G_CALLBACK(on_new_decoded_pad), videosink);

and would allow me to connect the pads appropriately. But it never gets called. In fact the program seems to pass through entirely and then just exit (the main loop does nothing).

I'd really appreciate it if someone could point out what I've done wrong with regards to the callback or explain what else needs to be done in order for this example to play mp4 using the provided elements.

Regards.

like image 927
user975326 Avatar asked Nov 04 '11 19:11

user975326


People also ask

What is Ghost pad in GStreamer?

A GhostPad acts as a proxy for another pad. Thus the bin can have sink and source ghost-pads that are associated with sink and source pads of the child elements. If the target pad is known at creation time, gst-ghost-pad-new is the function to use to get a ghost-pad.

Is GStreamer multithreaded?

A normal GStreamer pipeline can easily have dozens of threads interacting with each other.

What is dynamic pipeline?

Dynamic pipelines have the capability to schedule around stalls. A dynamic pipeline is divided into three units: the instruction fetch and decode unit, five to ten execute or functional units, and a commit unit. Each execute unit has reservation stations, which act as buffers and hold the operands and operations.

What is sink in GStreamer?

Sink elements consume data and normally have no source pads. Typical sink elements include: audio/video renderers. network sinks. filesinks.


2 Answers

on_new_decoded_pad is depreciated use "pad-added" instead.

I still have an issue relating to decodebin2 which you can find here: GStreamer force decodebin2 output type

like image 120
user975326 Avatar answered Oct 10 '22 01:10

user975326


See my rtp phone example [here]. Rtpbin is used there. Hope this helps.

like image 40
oblalex Avatar answered Oct 10 '22 02:10

oblalex