GStreamer基础
参考资源:Gstreamer 官方用户手册GSstreamer是一个用于开发流式多媒体应用的开源框架,更像是一个播放器。但是它主要的优点却是在于: GStreamer框架是基于插件的,所有的插件都能够被链接到任意的已经定义了的数据流管道中。GStreamer的管道能够被GUI编辑器编辑, 能够以XML文件来保存。这样的设计使得管道程序库的消耗变得非常少上面这个图就是个典型的meida播放器的...
参考资源:Gstreamer 官方用户手册
GSstreamer是一个用于开发流式多媒体应用的开源框架,更像是一个播放器。但是它主要的优点却是在于: GStreamer框架是基于插件的,所有的插件都能够被链接到任意的已经定义了的数据流管道中。GStreamer的管道能够被GUI编辑器编辑, 能够以XML文件来保存。这样的设计使得管道程序库的消耗变得非常少
上面这个图就是个典型的meida播放器的模型:
source:数据来源,可能是file、http、rtp、rtsp等.
demux: 负责把容器里的音视频数据剥离出来,然后分别送给audio\video decoder.
decoder:解码,然后把解完后的数据(yuv、pcm)送给audio\video output输出.
output:负责将decoder过来的数据呈现出来.
如果把数据想象成流水的话,每个模块的功能虽然不同,但是他们大致抽象的功能都是接收上个模块过来的数据,然后加工把加工后的数据送到下一个模块。
把上述这些模块通过某种方式连接起来,就形成了一个流水线(pipeline),这个流水线就是一个media播放器。
GStreamer 就是把每个模块都看做是一个Element,然后构建了连接和操作这些Element的方法,用户可以通过自己的需求把不同的Elements 排列组合,形成一个又一个的不同的pipeline。
一、Gstreamer整体框架
GStreamer核心库函数是一个处理插件、数据流和媒体操作的框架,整体功能核心是pipeline框架以及用于扩展功能的插件:
1、pipeline用于安排数据流图,明确数据流处理过程。通过gstreamer多媒体数据协商机制和同步机制,pipeline能够很好的地处理流式数据。
2、插件用于扩展功能,开发者可以灵活利用已有插件,而且还可以自定义特定功能插件。
GStreamer(具有核心库与插件分离的特点)被打包成:
- gstreamer: 核心库函数
- gst-plugins-base: 一组重要的示例元素
- gst-plugins-good: LGPL下的一套优质插件
- gst-plugins-ugly:一组可能造成分发问题的高质量插件
- gst-plugins-bad: 一组需要更高质量的插件
- gst-libav: 一组包装libav用于解码和编码的插件
- 其他的一些包
该框架大致包含了应用层接口、主核心框架以及扩展插件三个部分。
Gstreamer编程,首先创建基本元件,pipeline,filesrc,decoder,alsasink等,然后把这些元件加入到pipeline中,并链接起来,最后改变pipeline的状态,就可以启动对媒体数据的处理。
二、Gstreamer基础概念
面向物件的编程思想:
GStreamer 是依附于 GLib 2.0 对象模型的,采用了信号与对象属性的机制,所有对象的属性和功能都能在运行态被查询。
所有的 GStreamer 对象都可以采用 GObject 继承的方法进行扩展。所有的插件都可以被动态装载,可以独立的扩展或升级。
2.1 Elements组件
Elements是一个pipeline中的基本组成功能实体,通过将不同功能的elements连起来,就可以实现一个数据流处理功能。
对程序员来说,组件就像一个黑盒子。你从组件的一端输入数据,组件对数据进行一些处理,然后数据从组件的另一段输出。
如图所示,通过将source filer sink三种element连起来,可以实现对pipeline中传输数据格式的过滤。
element主要有三种:
(1) source element,主要是作为一个pipeline中的source节点,是数据源。source element只有src pad,即只有输出口。
源组件(Source elements)为管道产生数据,比如从磁盘或者声卡读取数据,总是将源衬垫(source pad)画在组件的右端。
(2) sink element ,作为pipline的end节点 。sink element 只有sink pad,即只有输入口。
接收组件(sink element)是媒体管道的末端,它接收数据但不产生任何数据。写磁盘、利用声卡播放声音以及视频输出等都是由接收组件实现的。
(3) common element,作为pipline中的中间数据处理单元,既有sink pad,也有src pad,通常有:过滤器(Filters),转换器(convertors),分流器 (demuxers),整流器(muxers) ,编译码器 (codecs)等
上图是形象化了类过滤组件
过滤器(Filters)以及类过滤组件(Filter-like elements)都同时拥有输入和输出衬垫,从输入衬垫得到的数据进行操作,然后将数据提供给输出衬垫。这个特殊的组件同时拥有源端和接收端。接收输入数据的接收衬垫在组件的左端,源衬垫在右端。
上图是形象化的拥有多个输出的过滤组件
类过滤组件可以拥有任意个的源衬垫或者接收衬垫。像一个视频分流器可能有一个接收衬垫以及多个源衬垫,每个接收衬垫对应一种元数据流 (elementary stream)。相反地,译码器只有一个源衬垫及一个接收衬垫。
一个组件在被创建后,它不会执行任何操作。所以你可以通过函数 gst_element_set_state()来改变一个组件的状态,使得它能够做某些事情。 Gstreamer 中组件有四种状态,每种状态都有其特定的意义:
- GST_STATE_NULL: 默认状态。该状态将会回收所有被该组件占用的资源。
- GST_STATE_READY:准备状态。组件会得到所有所需的全局资源,这些全局资源将被通过该组件的数据流所使用。
但是在这种状态下,数据流仍未开始被处理,所以数据流的位置信息应该自动置 0。如果数据流先前被打开过,它应该被关闭,并且其位置信息、特性信息应该被重新置为初始状态。 - GST_STATE_PAUSED: 在这种状态下,组件已经对流开始了处理,但此刻暂停了处理。因此该状态下组件可以修改流的位置信息,读取或者处理流数据,以及一旦状态变为 PLAYING,流可以重放数据流。这种情况下,时钟是禁止运行的。处于 PAUSED 状态的组件会很快变换到 PLAYING 状态。
- GST_STATE_PLAYING: PLAYING 状态除了当前运行时钟外,其它与PAUSED 状态一模一样。当处于GST_STATE_PLAYING 状态,管道会自动处理数据。它们不需要任何形式的迭代。
状态迁移只能在相邻的状态里迁移,也就是说,你不能从NULL一下跳到PLAYING。你必须经过READY和PAUSED状态。如果你把pipeline设到PLAYING状态,GStreamer自动会经过中间状态的过渡。
绝大多数应用都是在PLAYING状态开始播放,然后跳转到PAUSE状态来提供暂停功能,最后在退出时退到NULL状态。
2.2 Pads衬垫
pad是element的输入和输出,作为协商链接和数据传输用,链接只能是两个pad之间的,每个Pad都可以限定支持的数据格式。
一个衬垫(Pads)可以被看作是一个组件(element)插座或者端口,组件(element)之间的链接就是依靠着衬垫(Pads),当两个不同Pad之间的格式匹配,两个Pad就可以进行链接,并传输数据。
对于大部分情况,所有的数据流都是在链接好的元素之间流动。数据向组件(element)以外流出可以通过一个或者多个 source 衬垫(Pads) ,组件(element)接受数据是通过一个或者多个 sink 衬垫(Pads) 来完成的。Source组件(element)和sink组件(element)分别有且仅有一个 sink 衬垫(Pads)或者source 衬垫(Pads)。
数据在这里代表的是缓冲区(buffers)和事件(events)。
一个衬垫可以拥有三种类型的时效性:
- 永久型(always):永久型的衬垫一直会存在
- 随机型(sometimes):随机型的衬垫只在某种特定的条件下才存在(会随机消失的衬垫也属于随机型)
- 请求型(on request):请求型的衬垫不是自动被创建只在应用程序明确发出请求时才出现
2.3 Bins箱柜和Pipelines管道
箱柜(Bins) 是一个可以装载组件(element)的容器。管道(pipelines)是箱柜(Bins)的一个特殊的子类型,管道(pipelines)可以操作包含在它自身内部的所有组件(element)。
因为箱柜(Bins)本身又是组件(element)的子集,所以你能够操作普通组件(element)一样的操作一个箱柜(Bins), 通过这种方法可以降低你的应用程序的复杂度。你可以改变一个箱柜(Bins)的状态来改变箱柜(Bins)内部所有组件(element)的状态。箱柜(Bins)可以发送总线消息(bus messages)给它的子集组件(element)
(这些消息包括:错误消息(error messages),标签消息(tag messages),EOS消息(EOS messages))。
bin是element的一个集合,bin中的element理应互联,从而使bin也能提供某种功能,由于bin是element的子类,所以所有的element的操作,bin几乎都继承了。
pipeline是一个完整的流式数据处理流程,可以看成一个顶级的bin。顶层(toplevel)箱柜必须为一个管道。因此每个 GStreamer 应用程序都至少需要一个管道。当应用程序启动后,管道会自动运行在后台线程中。当你设定管道的暂停或者播放状态的时候,数据流将开始流动,并且媒体数据处理也开始处理。一旦开始,管道将在一个单独的线程中运行,直到被停止或者数据流播放完毕。
pipeline如下图所示
Ogg分流器是一个很好的实例,Ogg流包含了视频和音频。一个源衬垫可能包含视频元数据流,另一个则包含音频元数据流。当一个新的衬垫被创建时,分流器通常会产生一个信号。程序员可以在信号处理事件中处理新的元数据流。
2.4 Bus总线
总线是一个简单的系统,它采用自己的线程机制将一个管道线程的消息分发到一个应用程序当中。总线的优势是:当使用 GStreamer 的时候,应用程序不需要线程识别,即便 GStreamer 已经被加载了多个线程。
每一个管道默认包含一个总线,所以应用程序不需要再创建总线。应用程序只需要在总线上设置一个类似于对象的信号处理器的消息处理器。当主循环运行的时候,总线将会轮询这个消息处理器是否有新的消息,当消息被采集到后,总线将呼叫相应的回调函数来完成任务。
使用总线有如下两种方法:
- gst_bus_add_watch () /gst_bus_add_signal_watch ()
运行 GLib/Gtk+ 主循环 (你也可以自己运行默认的 GLib 的主循环),然后使用侦听器对总线进行侦听。使用这种方法,GLib 的主循环将轮询总线上是否存在新的消息,当存在新的消息的时候,总线会马上通知你。
当使用总线时,设置消息处理器到管道的总线上可以使用gst_bus_add_watch ()。 来创建一个消息处理器来侦听管道。每当管道
发出一个消息到总线,这个消息处理器就会被触发,消息处理器则开始检测消息信号类型从而决定哪些事件将被处理。当处理器从总线删除某个消息的时候,其返回值应为TRUE。
- gst_bus_peek () 和/或 gst_bus_poll ()
自己侦听总线消息
2.5 通信
管道的数据流由一组缓冲区(buffers)和事件(events)组成,缓冲区包括实际的管道数据,事件包括控制信息,如寻找信息和流的终止信号。所有这些数据流在运行的时候自动的流过管道。
GStreamer为应用程序和管道之间的通信和数据交换提供了几种通信机制。
- buffer
缓冲区buffer包含了你创建的管道里的数据流。通常一个源组件会创建一个新的缓冲区,同时组件还将会把缓冲区的数据传递给下一个组件。buffer用于element之间数据传递,buffer中包含的是媒体数据,buffer的传输方向永远是从src pad 到sink pad的,即向下传输。
一个缓冲区主要由以下几个部分组成:
- 指向某块内存的指针
- 内存的大小
- 缓冲区的时间戳
- 一个引用计数,指出了缓冲区所使用的组件数。没有组件可引用的时候,这个引用将用于销毁缓冲区。
我们先创建了一个缓冲区,然后为这个缓冲区分配内存,然后将数据存放在缓冲区中,并传递至下一个组件。该组件读取数据,处理某些事件(像创建一个新的缓冲区并进行译码),对该缓冲区解引用,这将造成数据空闲,导致缓冲区被销毁。典型的音频和视频译码器就是这样工作的。
- event
事件(events)是一系列控制粒子,随着缓冲区被发送到管道的上游和下游。下游事件通知流状态相同的组件,可能的事件包括中断,flush,流的终止信号等等。在应用程序与组件之间的交互以及事件与事件之间的交互中,上游事件被用于改变管道中
数据流的状态,如查找。
event是element之间或者application到element的信息传输,包含的是控制数据。event既可以向下也可以向上传输。
- message
message是由element向application传输,用于传输 errors,tags,state changes, buffering state, redirects等信息。
- queries
通常由application向pipeline发送,用于请求一些持续时间和播放点等信息。queries的应答是同步的。element也可以使用queries来向相邻element请求相应的信息
三、基于Gstreamer框架的软件应用
- Rhythmbox是一个综合的音乐管理软件,属于建筑于网络之上的播放器。可以直接下载歌曲,支持网络电台和播客。
- Sound juicer是一种在Linux及其它Unix-Like等操作系统平台上可将CD音轨转档的软件,能透过GStreamer的插件来进行各种音效编码。可转换包括mp3、Ogg、FLAC、及PCM等不同格式。
- Monkey Bubble 是一个很有趣又很酷的GNOME下的一个游戏软件,它通过GStreamer播放音乐产生惊悚的或甜美的音响效果。
- AviSynth是一个功能强大的视频文件后期处理工具,提供了许多编辑和处理视频文件的方法。能够提供各种方式来合并和滤镜处理影像文件。最独特的就是AviSynth并不是一个孤立的影像处理程序,而是在影像文件和应用程序之间担任“中间人”的角色。
- GNOME Media 是用GStreamer 来进行声音控制、音频录制和CD播放。
- Thoggen 是一个高效的 DVD 备份软件,它基于GStreamer,拥有一个漂亮的 GTK+ 界面,功能强大且容易使用。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)