GStreamer: how to connect dynamic pads

匿名 (未验证) 提交于 2019-12-03 02:20:02

问题:

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.

回答1:

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



回答2:

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



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!