gstreamer提供了gst-launch工具,使用该工具我们可以很方便的搭建各种管道,比如gst-launc-1.0 videotestsrc ! autovideosink输入上述命令,我们就能测试视频通路是否OK。但有些场景需要我们提供代码形式,而在gst-launch的管道转换为代码时,经常会遇到管道间连接失败的问题,通常提示这个问题的主要原因是元件的pad的Pad Templates类型不为Always的问题。
1. Always类型
例如queue元件,通过gst-inspect工具,我们可以知道,queue元件的src资源端和sink链接端的Pad Template都是Always类型,同样是Always的两端可以直接使用gst_element_link
或gst_element_link_many进行链接即可。
queue元件Pad Templates
2. sometimes类型重点
例如decodebin元件,该类型如果直接通过link函数链接,通常会报错:
gst_element_link_many: assertion 'GST_IS_ELEMENT (element_2)' failed Elements could not be linked.
通过gst-inspect工具,我们可以知道,decodebin元件的src端是Sometimes类型,这就导致decodebin元件的前方的元件在链接decodebin元件的时候不能直接使用gst_element_link进行链接,这种情况需要使用pad-added的signal来实现
Decodebin元件的Pad Templates
使用方法为,比如管道命令:
gst-launch-1.0 rtspsrc location="rtsp://b1.dnsdojo.com:1935/live/sys3.stream" ! rtph264depay ! video/x-h264, stream-format=avc ! h264parse ! avdec_h264 ! video/x-raw,formate=NV12,width=1280,height=720 ! videoconvert ! autovideosink
如果使用gst_element_link(rtspsrc, rtph264depay),则会连接失败。此时应该用rtspsrc元素的pad-added Signal处理函数通过Pad进行连接。
rtsp_source = gst_element_factory_make ("rtspsrc", "rtsp_source");
rtp_h264depay = gst_element_factory_make ("rtph264depay", "rtp_h264depay");
......
g_object_set (rtsp_source, "location", "rtsp://b1.dnsdojo.com:1935/live/sys3.stream", NULL);
......
g_signal_connect(rtsp_source, "pad-added", G_CALLBACK(pad_added_handler), rtp_h264depay);
pad_added_handler实现代码为:
3. On request类型
在request类型中最典型的一个例子就是tee,如果直接link进行链接则通常会报错:
gst_pad_link_full: assertion 'GST_IS_PAD (srcpad)' failed Tee-video could not be linked
由gst-inspect-1.0工具我们知道,tee的src端为On request类型的;
原件tee Pad Templates类型
这种类型也不可以直接通过link函数进行链接,这种特殊的类型需要特殊的方法进行链接。比如我们要链接tee->record_queue这两个元件,代码如下:
//元件定义
GstElement *tee,record_queue;
GstPad *tee_record_pad, *queue_record_pad;
。。。。。。。。。
//添加箱柜
//链接tee之前的元件
//链接record_queue之后的元件
。。。。。。。。。
//链接tee->record_queue
tee_record_pad = gst_element_get_request_pad (tee, "src_%u");
g_print ("Obtained request pad %s for capture branch.\n", gst_pad_get_name (tee_record_pad));
queue_record_pad = gst_element_get_static_pad (record_queue, "sink");