基本概念
我们先看看gstreamer结构体中的一些对象的继承关系图:
GObject
+----GstElement(包含GstBus,GstState, List of pad、GstClock等)
+----GstBin (元件的容器,包含GstClock,子bus等)
+----GstPipeline(包含stream_time等)
另外几个类关系:
GObject
±— GstPad
GObject
±— GstBus
GstObject
±— GstPluginFeature
±— GstElementFactory(factory that the element was created from,_GstElementClass保存有该结构的一个指针)
我们看一个pipeline的解释和示例图:
Pipeline
A pipeline is a special bin subclass that provides the following features to its
children:
-
Select and manage a global clock for all its children.
-
Manage running_time based on the selected clock. Running_time is the elapsed
time the pipeline spent in the PLAYING state and is used for
synchronisation. -
Manage latency in the pipeline.
-
Provide means for elements to comunicate with the application by the GstBus.
-
Manage the global state of the elements such as Errors and end-of-stream.
Normally the application creates one pipeline that will manage all the elements
in the application.
±----------------------------------------------------------+
| ----------> downstream -------------------> |
| |
| pipeline |
| ±--------+ ±---------+ ±----------+ ±---------+ |
| | filesrc | | oggdemux | | vorbisdec | | alsasink | |
| | src-sink src-sink src-sink | |
| ±--------+ ±---------+ ±----------+ ±---------+ |
| |
| <---------< upstream <-------------------< |
±----------------------------------------------------------+
The application does not have to manage any of the complexities of the
actual dataflow/decoding/conversions/synchronisation etc. but only calls high
level functions on the pipeline object such as PLAY/PAUSE/STOP.
GStreamer supports two possible types of dataflow, the push and pull model. In the
push model, an upstream element sends data to a downstream element by calling a
method on a sinkpad. In the pull model, a downstream element requests data from
an upstream element by calling a method on a source pad.
The most common dataflow is the push model. The pull model can be used in specific
circumstances by demuxer elements. The pull model can also be used by low latency
audio applications.
The data passed between pads is encapsulated in Buffers. The buffer contains a
pointer to the actual data and also metadata describing the data.
可见,pipeline的主要布局是elements, Bins 和pads.把上述几个对象继承关系牢记脑海中。PADs是连接器。pipeline的各对象之间的通信通过缓存buffers、事件event、查询query、消息message机制实现, 调度通过时钟和队列实现。
元件(Elements)
元件(element)是GStreamer中最重要的概念。它是整个gstreamer框架中最重要的一个对象,它定义了pipeline的结构。你可以通过创建一系列的元件(Elements),并把它们连接起来,从而让数据流在这个被连接的各个元件(Elements)之间传输。每个元件(Elements)都有一个特殊的函数接口,对于有些元件(Elements)的函数接口它们是用于能够读取文件的数据,解码文件数据的。而有些元件(Elements)的函数接口只是输出相应的数据到具体的设备上(例如,声卡设备)。你可以将若干个元件(Elements)连接在一起,从而创建一个管道(pipeline)来完成一个特殊的任务,例如,媒体播放或者录音。GStreamer已经默认安装了很多有用的元件(Elements),通过使用这些元件(Elements)你能够构建一个具有多种功能的应用程序。
每个元件包含有多个gstPad(衬垫)。这些gstpad随后用于元件(element)之间的连接和通信,并最终构成一个可以传递和处理数据的管道pipeline.几乎所有的decoder,encoder,demuxer,video or audio output都实际上是一个GstElement。( 注:面向对象里的is-a 关系)
gstelement实例的结构如下所示, 添加和删除pad的方法在gstelement的类结构体中有定义,这里从略。
struct _GstElement { |
箱柜(Bins)和管道(pipelines)
箱柜(Bins)是一个可装载一系列元件(element)的容器。管道(pipelines)是箱柜(Bins)的一个特殊的子类型,管道(pipelines)可以操作包含在它自身内部的所有元件(element)。gstbin的实例结构体定义如下:
A bin is an element subclass and acts as a container for other elements so that multiple
elements can be combined into one element.*
*A bin can have its own source and sinkpads by ghostpadding one or more of its children’s
pads to itself.
struct _GstBin { |
因为箱柜(Bins)本身又是元件(element)的子集,所以你能够象操作普通元件(element)一样的操作一个箱柜(Bins),通过这种方法可以降低你的应用程序的复杂度。你可以改变一个箱柜(Bins)的状态来改变箱柜(Bins)内部所有元件(element)的状态。箱柜(Bins)可以发送总线消息(bus messages)给它的子集元件(element)(这些消息包括:错误消息(error messages),标签消息(tag messages),EOS消息(EOS messages))。
struct _GstPipelineClass { |
管道(pipeline)是高级的箱柜(Bins)。当你设定管道的暂停或者播放状态的时候,数据流将开始流动,并且媒体数据处理也开始处理。一旦开始,管道将在一个单独的线程中运行,直到被停止或者数据流播放完毕。
衬垫(Pads)
衬垫在GStreamer中被用于多个元件的链接,从而让数据流能在这样的链接中流动。一个衬垫(Pads)可以被看作是一个元件(element)插座或者端口,元件(element)之间的链接就是依靠着衬垫(Pads)。衬垫(Pads)有处理特殊数据的能力:一个衬垫(Pads)能够限制数据流类型的通过。链接成功的条件是:只有在两个衬垫(Pads)允许通过的数据类型一致的时候才被建立。数据类型的设定使用了一个叫做caps negotiation的方法。数据类型被为一个GstCaps变量所描述。
struct _GstCaps { |
下面的这个比喻可能对你理解衬垫(Pads)有所帮助。一个衬垫(Pads)很象一个物理设备上的插头。例如一个家庭影院系统。一个家庭影院系统由一个功放(amplifier),一个DVD机,还有一个无声的视频投影组成。我们需要连接DVD机到功放(amplifier),因为两个设备都有音频插口;我们还需要连接投影机到DVD机上,因为两个设备都有视频处理插口。但我们很难将投影机与功放(amplifier)连接起来,因为他们之间处理的是不同的插口。GStreamer衬垫(Pads)的作用跟家庭影院系统中的插口是一样的。
对于大部分情况,所有的数据流都是在链接好的元素之间流动。数据向元件(element)以外流出可以通过一个或者多个 source衬垫(Pads),元件(element)接受数据是通过一个或者多个sink衬垫(Pads)来完成的。Source元件(element)和sink元件(element)分别有且仅有一个 sink 衬垫(Pads)或者source衬垫(Pads)。数据在这里代表的是缓冲区(buffers) (GstBuffer对象描述了数据的缓冲区(buffers)的信息)和事件(events) (GstEvent对象描述了数据的事件(events)信息)。
GstPad结构体字段:
/** |
在Linux上安装GStreamer
先决条件
GStreamer 已包含在大多数Linux发行版中。建议使用最新的快速更新的发行版(如Fedora、Ubuntu非LTS版、Debian sid或OpenSuse)来获取最近版本的GStreamer。
确保具有超级用户(root)权限来安装GStreamer。
在Fedora上安装GStreamer
在终端中运行以下命令:
dnf install gstreamer1-devel gstreamer1-plugins-base-tools gstreamer1-doc \ |
在Ubuntu或Debian上安装GStreamer
在终端中运行以下命令:
apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \ |
构建使用GStreamer的应用程序
除了需要安装的GStreamer库,还需要安装gcc编译器。编译代码时,需要在gcc命令中加入以下内容:
pkg-config --cflags --libs gstreamer-1.0 |
如果使用其他GStreamer库(如视频库),则需要在命令中添加相应的包(如 gstreamer-video-1.0
)。
获取教程源码
可以从教程页面复制源代码,也可以通过以下命令克隆GIT仓库:
git clone https://gitlab.freedesktop.org/gstreamer/gstreamer |
教程代码位于 subprojects/gst-docs/examples/tutorials
子目录中。
编译教程
例如,编译 basic-tutorial-1
:
gcc basic-tutorial-1.c -o basic-tutorial-1 `pkg-config --cflags --libs gstreamer-1.0` |
运行教程
运行教程代码:
./basic-tutorial-1 |
Reference
[1] Installing on Linux: https://gstreamer.freedesktop.org/documentation/installing/on-linux.html?gi-language=c