Gstreamer是一个支持Windows,Linux,Android, iOS的跨平台的多媒体框架,应用程序能够经过管道(Pipeline)的方式,将多媒体处理的各个步骤串联起来,达到预期的效果。每一个步骤经过元素(Element)基于GObject对象系统经过插件(plugins)的方式实现,方便了各项功能的扩展。html
下图是对基于Gstreamer框架的应用的简单分层:ios
最上面一层为应用,好比gstreamer自带的一些工具(gst-launch,gst-inspect等),以及基于gstreamer封装的库(gst-player,gst-rtsp-server,gst-editing-services等)根据不一样场景实现的应用。缓存
中间一层为Core Framework,主要提供:安全
最下层为各类插件,实现具体的数据处理及音视频输出,应用不须要关注插件的细节,会由Core Framework层负责插件的加载及管理。主要分类为:app
Gstreamer框架根据各个模块的成熟度以及所使用的开源协议,将core及plugins置于不一样的源码包中:框架
在进一步学习Gstreamer前,咱们须要掌握一些gstreamer的基础概念。异步
Element是Gstreamer中最重要的对象类型之一。一个element实现一个功能(读取文件,解码,输出等),程序须要建立多个element,并按顺序将其串连起来,构成一个完整的pipeline。tcp
Pad是一个element的输入/输出接口,分为src pad(生产数据)和sink pad(消费数据)两种。
两个element必须经过pad才能链接起来,pad拥有当前element能处理数据类型的能力(capabilities),会在链接时经过比较src pad和sink pad中所支持的能力,来选择最恰当的数据类型用于传输,若是element不支持,程序会直接退出。在element经过pad链接成功后,数据会从上一个element的src pad传到下一个element的sink pad而后进行处理。
当element支持多种数据处理能力时,咱们能够经过Cap来指定数据类型.
例如,下面的命令经过Cap指定了视频的宽高,videotestsrc会根据指定的宽高产生相应数据:ide
gst-launch-1.0 videotestsrc ! "video/x-raw,width=1280,height=720" ! autovideosink
Bin是一个容器,用于管理多个element,改变bin的状态时,bin会自动去修改所包含的element的状态,也会转发所收到的消息。若是没有bin,咱们须要依次操做咱们所使用的element。经过bin下降了应用的复杂度。
Pipeline继承自bin,为程序提供一个bus用于传输消息,而且对全部子element进行同步。当将pipeline的状态设置为PLAYING时,pipeline会在一个/多个新的线程中经过element处理数据。函数
下面咱们经过一个文件播放的例子来熟悉上述说起的概念:测试文件 sintel_trailer-480p.ogv
gst-launch-1.0 filesrc location=sintel_trailer-480p.ogv ! oggdemux name=demux ! queue ! vorbisdec ! autoaudiosink demux. ! queue ! theoradec ! videoconvert ! autovideosink
经过上面的命令播放文件时,会建立以下pipeline:
能够看到这个pipeline由8个element构成,每一个element都实现各自的功能:
filesrc读取文件,oggdemux解析文件,分别提取audio,video数据,queue缓存数据,vorbisdec解码audio,autoaudiosink自动选择音频设备并输出,theoradec解码video,videoconvert转换video数据格式,autovideosink自动选择显示设备并输出。
不一样的element拥有不一样数量及类型的pad,只有src pad的element被称为source element,只有sink pad的被称为sink element。
element能够同时拥有多个相同的pad,例如oggdemux在解析文件后,会将audio,video经过不一样的pad输出。
在pipeline运行的过程当中,各个element以及应用之间不可避免的须要进行数据消息的传输,gstreamer提供了bus系统以及多种数据类型(Buffers、Events、Messages,Queries)来达到此目的:
Bus是gstreamer内部用于将消息从内部不一样的streaming线程,传递到bus线程,再由bus所在线程将消息发送到应用程序。应用程序只须要向bus注册消息处理函数,便可接收到pipline中各element所发出的消息,使用bus后,应用程序就不用关心消息是从哪个线程发出的,避免了处理多个线程同时发出消息的复杂性。
用于从sources到sinks的媒体数据传输。
用于element之间或者应用到element之间的信息传递,好比播放时的seek操做是经过event实现的。
是由element发出的消息,经过bus,以异步的方式被应用程序处理。一般用于传递errors, tags, state changes, buffering state, redirects等消息。消息处理是线程安全的。因为大部分消息是经过异步方式处理,因此会在应用程序里存在一点延迟,若是要及时的相应消息,须要在streaming线程捕获处理。
用于应用程序向gstreamer查询总时间,当前时间,文件大小等信息。
Gstreamer自带了gst-inspect-1.0和gst-launch-1.0等其余命令行工具,咱们可使用这些工具完成常见的处理任务。
gst-inspect-1.0
查看gstreamer的plugin、element的信息。直接将plugin/element的类型做为参数,会列出其详细信息。若是不跟任何参数,会列出当前系统gstreamer所能查找到的全部插件。
$ gst-inspect-1.0 playbin
gst-launch-1.0
用于建立及执行一个Pipline,所以一般使用gst-launch先验证相关功能,而后再编写相应应用。
经过上面ogg视频播放的例子,咱们已经看到,一个pipeline的多个element之间经过 “!" 分隔,同时能够设置element及Cap的属性。例如:
播放音视频
gst-launch-1.0 playbin file:///home/root/test.mp4
转码
gst-launch-1.0 filesrc location=/videos/sintel_trailer-480p.ogv ! decodebin name=decode ! \
videoscale ! "video/x-raw,width=320,height=240" ! x264enc ! queue ! \
mp4mux name=mux ! filesink location=320x240.mp4 decode. ! audioconvert ! \
avenc_aac ! queue ! mux.
Streaming
#Server gst-launch-1.0 -v videotestsrc ! "video/x-raw,framerate=30/1" ! x264enc key-int-max=30 ! rtph264pay ! udpsink host=127.0.0.1 port=1234 #Client gst-launch-1.0 udpsrc port=1234 ! "application/x-rtp, payload=96" ! rtph264depay ! decodebin ! autovideosink sync=false
https://gstreamer.freedesktop.org/documentation/application-development/introduction/gstreamer.html
https://gstreamer.freedesktop.org/documentation/application-development/introduction/basics.html
https://gstreamer.freedesktop.org/documentation/tools/gst-launch.html