概述
在使用gstreamer的过程中,相信很多是都通过gst-launch-1.0
直接使用playbin或者自建pipeline完成相应的播放测试,反而很少的会自己编写代码,其实,gst-launch-1.0帮助我们做了很多工作,在自己编写程序的时候,反而会忽略掉,比如我们要说的demux。
demux,解复用器,我将它理解为解封装,在播放封装音视频的时候,一般都会需要先进行解封装,然后在解码、播放或者显示。但是,在解封装之前,由于demux并不事先知道音视频的格式,所以在代码中,通过gst_element_link_many()
或者相关函数link element,发现在demux与下游element连接的时候返回是错误的。
为什么呢?下面我们来看看,以qtdemux为例。
首先我们看看qtdemux支持的pad信息,详细如下:
Pad Templates:
SINK template: 'sink'
Availability: Always
Capabilities:
video/quicktime
video/mj2
audio/x-m4a
application/x-3gp
SRC template: 'video_%u'
Availability: Sometimes
Capabilities:
ANY
SRC template: 'audio_%u'
Availability: Sometimes
Capabilities:
ANY
SRC template: 'subtitle_%u'
Availability: Sometimes
Capabilities:
ANY
细心的会发现,src pad是随机型的,就是说,qtdemux并不知道它的输出是什么,但是分别有这三种,在实际使用过程中,会根据输入数据相应的使用不同的src pad。
而在我们link的时候,element间数据并没有流通,demux并不知道它的输出是哪种类型的src pad,自然的,link就会失败,但是,有没有办法解决呢,肯定有的,要不然在我们通过gst-launch-1.0自建pipeline的时候又怎么会可以正常播放呢,下面我们再来分析。
在上面我们已经知道,demux的src pad是随机型的,那么,是什么时候知道src pad是什么类型呢。一般的,是在element从READY状态切换到PAUSED状态时,上游element的数据将会预流到demux,在这个时候,demux将会解析数据,然后配置stream信息,根据数据创建相应的src pad,完成这个操作之后,将会通过gst_element_add_pad()
将pad添加到demux,奥秘就在这个函数了。
在gst_element_add_pad()中,有以下这样的一行代码:
/* emit the PAD_ADDED signal */
g_signal_emit (element, gst_element_signals[PAD_ADDED], 0, pad);
看到这里就明白了吧,在demux添加src pad的时候,将会通过上面的函数发送一个pad-added
信号。然后我们在程序中,再接收这个信号,此时再进行link就可以了,简单实例代码如下:
static void qtdemux_pad_added_cb (GstElement *qtdemux, GstPad *pad, GstElement *mjpegdec)
{
gst_element_link_pads(qtdemux, GST_PAD_NAME (pad), mjpegdec, NULL);
}
int main(int argc, char *argv[])
{
...
/* 其实在这里link,只会link到filesrc和qtdemux,因为在qtdemux与后面的mjpegdec link会
* 失败,函数就返回了,所以我下面再重新link,这个只是简单示例,实际应用自己商榷 */
gst_bin_add_many(GST_BIN(pipeline), filesrc, qtdemux, mjpegdec, fbsink, NULL);
gst_element_link(filesrc, qtdemux);
gst_element_link(mjpegdec, fbsink);
/* We'll want to know when the source pad is added */
g_signal_connect (qtdemux, "pad-added", (GCallback) qtdemux_pad_added_cb, mjpegdec);
...
}
在程序中,通过g_signal_connect()
函数绑接收”pad-added”信号的回调函数qtdemux_pad_added_cb()。而回调函数的函数又是怎样确定的呢?可以看到qtdemux_pad_added_cb (GstElement *qtdemux, GstPad *pad, GstElement *mjpegdec)
,第一个函数参数qtdemux是我们在g_signal_connect()的第一个参数,而第二个参数pad是在g_signal_emit()发送信号是传进来的参数pad,而第三个参数则是g_signal_connect()传进来的mjpegdec,所以,大家知道怎么编写信号回调函数了吧,这里是假设只有视频srcpad的,可能还会有音频或者字幕的,可根据GST_PAD_NAME (pad)得到pad的信息,再相应的link element。
而为什么我们使用gst-launch-1.0会可以的,是因为在gstreamer-1.xx.x/gst/parse目录下的grammar.y文件进行了延迟link的操作,感兴趣的可以看看该文件的实现。
以上是个人理解,有理解错误的地方,欢迎指出,感谢
最后
以上就是俏皮钢笔为你收集整理的gstreamer学习笔记---demux使用的全部内容,希望文章能够帮你解决gstreamer学习笔记---demux使用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复