I am trying to use GStreamer to play MP4 video from a file. I was able to play the file using playbin2 and from the command line using:
gst-launch filesrc location=bbb.mp4 ! decodebin2 ! autovideosink
In the future, I expect that I will need to create more complex pipelines, and therefore I am trying to "program" the pipeline. In my program, I am trying to replicate the pipeline above, however, I have a problem that I suspect is connected to connecting the dynamic or "sometimes" source site decodebin2 to the autovideo receiver. I use these elements only to make 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 do I expect when I run this program so that on_new_decoded_pad is called through the callback function, which is set in the line:
g_signal_connect(decodebin, "new-decoded-pad", G_CALLBACK(on_new_decoded_pad), videosink);
and let me choose the right pillows. But he is never called. In fact, the program seems to go through completely and then just exit (the main loop does nothing).
I would really appreciate it if someone could indicate what I did wrong with respect to the callback or explain what else needs to be done to make this example play mp4 using the provided elements.
Sincerely.