GStreamer 插件开发指南.docx
- 文档编号:5329852
- 上传时间:2022-12-15
- 格式:DOCX
- 页数:105
- 大小:85.10KB
GStreamer 插件开发指南.docx
《GStreamer 插件开发指南.docx》由会员分享,可在线阅读,更多相关《GStreamer 插件开发指南.docx(105页珍藏版)》请在冰豆网上搜索。
GStreamer插件开发指南
GStreamer插件开发指南(0.10.9.1)
I.介绍
GStreamer是一个用来创建流媒体应用程序的非常强大和通用的框架。
GStreamer框架的许多优点来源于它的模块性:
GStreamer可以无缝地接纳新的插件模块。
但是由于模块性和强大的功能通常以极高的复杂性为代价(例如CORBA),编写一个新的插件并不总是一件简单的事。
本手册旨在帮助你了解GStreamer的框架0.10.9.1版)以便你能够开发新的插件来扩展当前的功能。
本手册通过用C语言开发一个示例插件──一个音频过滤器──来定位大多数问题。
然而,接下来的部分会通过编写其它类型的插件引入另一些问题,在本手册的结尾介绍了一些GStreamer的Python绑定。
1.前言
1.1.GStreamer是什么?
1.2.谁应该读该指南?
1.3.预备知识
1.4.该指南的结构
2.基本知识
2.1.元件(Elements)和插件(Plugins)
2.2.衬垫(Pads)
2.3.数据(Data),缓冲区(Buffers)和事件(Events)
2.3.1.缓冲区分配
2.4.MIME类型(Mimetypes)和属性
2.4.1.基本类型
Chapter1.前言
1.1.GStreamer是什么?
GStreamer是一个创建流媒体应用程序的框架。
其基本设计思想来自于俄勒冈(Oregon)研究生学院有关视频管道的创意,同时也借鉴了DirectShow的设计思想。
GStreamer的开发框架使它有可能被用来编写任何类型的流媒体应用程序。
基于GStreamer的程序开发框架使得编写任意类型的流媒体应用程序成为了可能。
在编写处理音频、视频或者两者皆有的应用程序时,GStreamer可以让你的工作变得简单。
GStreamer并不受限于音频和视频处理,它能够处理任意类型的数据流。
管道的设计对于一般应用的滤镜(filter)绰绰有余。
这使得GStreamer成为一个优秀的框架,它甚至可以用来设计出对延时有很高要求的高端音频应用程序。
GStreamer最显著的用途是在构建一个播放器上。
GStreamer已经支持很多格式的文件了,包括:
MP3,Ogg/Vorbis,MPEG-1/2,AVI,Quicktime,mod等等。
从这个角度看,GStreamer更象是一个播放器。
但是它主要的优点确是在于:
它的可插入组件能够很方便的接入到任意的管道当中。
这个优点使得利用GStreamer编写一个万能的可编辑音视频应用程序成为可能。
GStreamer框架是基于插件的,有些插件中提供了各种各样的多媒体数字信号编解码器,也有些提供了其他的功能。
所有的插件都能够被链接到任意的已经定义了的数据流管道中。
GStreamer的管道能够被GUI编辑器编辑,能够以XML文件来保存。
这样的设计使得管道程序库的消耗变得非常少。
GStreamer核心库函数是一个处理插件、数据流和媒体操作的框架。
GStreamer核心库还提供了一个API,这个API是开放给程序员使用的---当程序员需要使用其他的插件来编写他所需要的应用程序的时候可以使用它。
1.2.谁应该读该指南?
该指南叙述了如何为GStreamer编写新的模块。
本指南针对以下几种人:
∙那些想给GStreamer增加新的数据处理方法的人。
例如,可能有人想创建一个新的可见的工具---数据类型转换器,或者新的编码器或者解码器。
∙那些想支持新的输入输出设备的人。
例如:
某人可能会想增加将数据输出到新的视频输出系统或从一个数码相机或耳机中读取数据的功能。
∙那些想通过任何方法扩展GStreamer的人。
你必须事先了解插件系统是如何工作的,这样你才能知道插件系统对其它代码有什么限制。
读完了该手册,你也许会因为插件可以做如此多的事而感到惊讶。
如果你只是想使用GStreamer的已有功能,或者只想使用那些基于GStreamer程序,那么你可以不用再看下去了。
如果你只关注与使用现有的插件去便写新的程序──现在有许多这样的插件──你也许想看的是《GStreamer应用程序开发手册》如果你只是想获得那些基于GStreamer的程序的帮助,那么你应该查看那些程序的用户手册。
1.3.预备知识
该指南假定你已经稍微了解了GStreamer的基本工作原理。
你也许希望首先阅读《GStreamer应用程序开发手册》,以便获得对GStreamer编程概念的了解。
另外,不要忘了查看GStreamer网站上的已有文档。
为了理解这份手册,你必须对C语言有一个基本的了解。
因为GStreamer是基于GObject编程模型,所以本指南假定你也已经对GObject编程有了一个基本的了解。
你或许也想看一下EricHarlow's的《DevelopingLinuxApplicationswithGTK+andGDK》一书。
1.4.该指南的结构
为了帮助你驾驭这份指南,我们将其分为几个大的部分。
每一部分致力于一个特定的GStreamer插件开发相关的广泛概念。
该指南的所有部分按照以下顺序组织:
∙编写一个插件──介绍插件的结构,并用一个音频滤镜作为演示。
这一部分涵盖了编写一个插件的所有基本步骤,例如将element注册到GStreamer并进行一些初步设置以便能和相邻的element互传数据。
讨论以一个示例程序开始,该程序创建一些基本的结构并在构建样板一节中注册一个element。
接着,你将在Chapter4,Chapter5和Chapter6中学会怎样通过一段代码得到一个基本的滤镜插件。
随后,在增加参数和Chapter8中,我们将演示如何使用GObject使element在程序中可配置,以及怎样使你的程序和element交互。
下一步,你将学习如何快速的创建一个测试程序来测试你在Chapter9所学的所有知识。
这里只涉及一些应用程序开发的基本知识,要想对此有一个全面的了解,请查看应用程序开发手册。
∙高阶滤镜概念──GStreamer插件开发的高级特性信息。
通过对初步知识的学习,你应该能够创建一个有很好的特性的音频或视频过滤器插件了。
然而,GStreamer为插件编写者提供了更多的东西。
这一部分的章节包含了一些更高级的主题。
例如调度,GStreamer的类型定义,时钟,接口和标签。
因为这些特性是针对特定应用的(purpose-specific),你可以按任何顺序阅读它们,它们大多不依赖于其他章节的知识。
在该部分的第一章不同的调度模式我们将解释一些element调度的基本知识。
这部分不会很深入,只是一种介绍性的阐述为什么那些东西会那样工作。
如果你对GStreamer的内部感兴趣,请阅读这一章。
接下来,我们将这一知识运用于另一种类型的数据传输Chapter5:
不同的调度模式基于环路的(Loop-based)元件将让你能对其输入速率有更多的控制。
这些在编写muxers或demuxers时是很有用的。
下一步,我们将在Chapter12中讨论GStreamer媒体标识。
你将学到怎样定义新的媒体类型及得到GStreamer内部的标准媒体类型列表。
在下一章,你将学习request-pads和sometimes-pads的概念,这些pad都是动态创建的,或者是因为应用程序的需要(request),或者是因为媒体类型的要求(sometimes),这些都将在Chapter13中叙述。
接着,在Chapter14,将解释GStreamer中的时钟概念。
如果你的element中需要同步音视频,你必须知道这些信息。
接下来的几章,我们将讨论应用程序和element进行交互的高级方法。
之前,我们在添加参数和Chapter8中学会了如何通过GObject的方法来完成这一功能。
我们将在Chapter15中讨论动态参数,这是一种预先定义element行为的方法。
下一步,我们会在Chapter17中学习到接口的方方面面。
接口是个非常特别的东西-应用级元件的特定方式,基于GObject的GInterface之上。
最后,你将在Chapter18中学到GStreamer是怎样处理元数据的。
在最后一章,Chapter19中,将讨论GStreamer的事件机制。
一方面,事件也是应用程序和element间交互的方法,例如定位事件。
另一方面,事件也是element间进行交互的一种方法,例如,element可以通过事件传递媒体流断开的状况,在管道内转发标签等等。
∙创建特殊类型的元件──编写其它类型的插件
由于前两部分以一个音频过滤器为例,所介绍的概念可以运用到过滤器插件的开发中。
同时许多概念也可以运用到sources,sinks和autopluggers等其它类型的插件中。
这一部分讨论编写其他特定类型的插件会碰到的问题。
本章开始将焦点集中在可以使用基类(Pre-madebaseclasses)编写的element上。
接下来,在写一个Demuxer或Parser,写一个N-to-1元件或Muxer和写一个管理器中,讨论编写特殊的元件。
∙附录──关于插件开发的进一步信息
附录中包含一些不适合在手册的其它章节讲述的信息,这些大部分还没有完成。
手册的剩余部分总揽了GStreamer插件开发中的基本概念,涵盖的内容包括元件(Elements)和插件(Plugins),衬垫,数据(Data),缓冲区(Buffers)和事件(Events)和类型和属性。
如果你已经熟悉了对这一部分,你可以将之当作一次回顾,或者直接跳到编写一个插件。
正如你所见,我们有许多的东西需要学习,让我们就此开始吧!
∙通过扩展GstBin创建复杂的element,这样可以创建包含其它插件的插件。
∙通过在类型侦测函数(typedetectfunctions)中加入新的mime类型,可以让你的插件处理全新的媒体类型。
Chapter2.基础概念介绍
本章介绍GStreamer的基本概念。
掌握了这些基本概念将有助于你解决在扩展GStreamer时遇到的问题。
关于这些概念的更详尽的解释请参考GStreamer应用程序开发指南;这些基本概念放在这儿主要是为了帮助你回顾一遍。
2.1.元件和插件
元件是GStreamer的核心。
在插件的开发中,一个元件就是继承于GstElement的一个对象。
元件在与其他元件连接时提供了如下一些功能:
例如,一个源元件为一个流提供数据,一个滤镜元件对流中的数据进行操作。
没有了元件,GStreamer只是一堆概念性的管道,没有任何东西可供连接。
GStreamer已经自带了一大堆元件,但是我们仍然可以编写额外的元件。
然而,仅仅写一个新的元件并不够,为了使GStreamer能够使用它,你必须将元件封装到一个插件中。
一个插件是一块可以加载的代码,通常被称为共享对象文件(sharedobjectfile)或动态链接库(dynamicallylinkedlibrary)。
一个插件中可以包含一个或若干element。
为简单起见,本手册主要涉及只包含一个element的插件。
滤镜是一类处理流数据的重要插件。
数据的生产者和消费者分别被称为source和sink元件。
箱柜(Bin)元件可以包含其它的元件。
箱柜的主要职责是调度它包含的元件并使得数据流更平滑。
热插拔(autoplugger)元件是另一种箱柜,它可以动态的加载其它元件,并将它们连接起了形成一个可以处理两个任意流的滤镜。
GStreamerr充斥着插件的概念,即使你只使用到一些标准的包。
核心库中只有少量基本函数,其它所有的功能都由插件来实现。
一个XML文件被用来保存所有注册的插件的详细信息。
这样,使用GStreamer的程序可以只在需要时加载插件,而不必事先全部加载。
插件也只在需要它们的元件时才被加载。
查阅GStreamer库索引来获取GstElement和GstPlugin的当前实现细节。
2.2.衬垫(Pads)
在GStreamer中,衬垫是用来在元件间协商连接和数据流的。
衬垫可以看作元件间互相连接的“接口”,数据流通过这些接口流入流出元件。
Pad具有特殊的数据处理能力:
衬垫可以限制通过它的数据类型。
只有当两个衬垫允许通过的数据类型兼容时才可以将它们连接起来。
也许打一个比方可以有助于理解这些概念。
衬垫类似于物理设备上的aplugorjack。
想象一个包含功放,DVD播放器和一个视频投影仪器的家庭影院系统。
将投影仪和DVD播放器相连是允许的,因为这两个设备具有兼容的videojacks。
而要将投影仪和功放连起来也许就行不通了,因为它们之间的jack不同。
GStreamer中的衬垫具有和家庭影院系统中的jack相同的功能。
大部分情况下,所有在GStreamer中流经的数据都遵循一个原则。
数据从element的一个或多个源衬垫流出,从一个或多个sink衬垫流入。
源和sink元件分别只有源和sink衬垫。
查阅GStreamer库索引来获取GstPad的当前实现细节。
2.3.数据,缓冲区和事件
GStreamer中的所有数据流被分割成一块一块的,并从一个元件的源衬垫传到另一个元件的sink衬垫。
数据就是用来承载一块一块数据的数据结构。
数据包含以下的重要组成部分:
∙一个类型域标识该数据的准确类型(control,content,...)。
∙一个指示当前有多少元件引用缓冲区的引用计数器。
当计数器的值为0时,缓冲区将被销毁,内存被释放(更详细的细节看下面)。
当前存在两种数据类型:
事件(control)和缓冲区(content)。
缓冲区可以包含两个相连接的pad所能处理的任何数据。
通常,一个缓冲区包含一块音频或视频数据块,该数据块从一个元件流向另一个元件。
缓冲区同样包含描述缓冲区内容的元数据(metadata)。
一些重要的元数据类型有:
∙一个指向缓冲区数据的指针。
∙一个标识缓冲区数据大小的整型变量。
∙一个指示缓冲区的最佳显示时间的时间戳。
事件包含两个相连的衬垫间的流的状态的信息。
只有事件被元件显式地支持时它们才会被发送,否则核心层将(尝试)自动处理事件。
举例来说,事件会被用来表示一个时钟中断,媒体流的结束或高速缓冲区(cache)需要刷新。
事件结构可能会包含如下的成员:
∙一个用来标明事件类型的子类型。
∙事件类型相关的其他部分。
事件将在Chapter19一章中广泛讨论。
在那之前,只会涉及流结束(EOS)事件,该事件通常在文件结束时发出,标识流的结束。
查阅GStreamer库索引来获取GstMiniObject,GstBuffer和GstEvent的当前实现细节。
2.3.1.缓冲区的分配
缓冲区是一块可以存放各种数据的内存。
缓冲区的内存一般用malloc()函数分配。
这样虽然很方便,但不总是最高效,因为数据经常需要被显式的拷入缓冲区。
有些特殊的元件创建指向特殊内存的缓冲区。
例如,filesrc元件通常会(使用mmap())将一个文件映射到应用程序的地址空间,并创建指向那个地址范围的缓冲区。
这些由filesrc创建的缓冲区具有和其它通用的缓冲区一样的行为,唯一的区别是它们是只读的。
释放缓冲区的代码将自动检测内存类型并使用正确的方法释放内存。
另一种可能得到特殊缓冲区的途径是向下游同伙(downstreampeer)发出请求。
这样得到的缓冲区称为downstream-allocated缓冲区。
元件可以请求一个连接到源衬垫的同伙创建一个指定大小的空缓冲区。
如果下游元件可以创建一个正确大小的特殊缓冲区,它将会这样做。
否则,GStreamer将会自动创建一个通用缓冲区。
接着,请求缓冲区的元件就可以将数据拷入缓冲区,并将缓冲区push给创建它的源衬垫。
许多sink元件的将数据拷到硬件的函数都经过了优化,或者可以直接操作硬件。
这些元件为它们的上游伙伴创建downstream-allocated缓冲区是很平常的事。
其中一例是ximagesink。
它创建包含XImage的缓冲区,因此当一个上游伙伴将数据拷入缓冲区时,数据被直接拷入XImage,这样ximagesink可以直接将图象画到屏幕上而不用先将数据拷到一个XImage中。
滤镜元件通常有机会可以直接作用于缓冲区,或者在将数据从源缓冲区拷入目标缓冲区时发生作用。
最佳方案是两种算法都予以实现,因为GStreamer框架会在可能的时候选择最快的算法。
自然地,这只在元件的源和sink衬垫完全一致的情况下才有效果。
2.4.MIME类型(Mimetypes)和属性
GStreamer使用一个类型系统来保障流经元件的数据格式是可识别的。
当连接元件中的衬垫时,类型系统对于确保特定的参数有着非常重要的作用,这些参数对正连接的元件间的衬垫的格式匹配有着特定作用。
元件间的每一个连接有一个指定的类型和可选的属性集。
2.4.1.基本类型
GStreamer已经支持许多基本的媒体类型。
下表是GStreamer中的缓冲区所使用的一些基本类型。
表中包含了类型的名字("mimetype")和对类型的描述,类型相关的属性,以及每个属性的意义。
已定义类型列表一节中列出了所有支持的类型。
Table2-1.TableofExampleTypes
Mime类型
描述
属性
属性类型
属性值
属性描述
audio/*
所有音频类型
rate
整型
大于0
数据的采样率,每秒的样本数(每个声道)。
channels
整型
大于0
音频数据的声道数。
audio/x-raw-int
未结构化的及未压缩的原始整型音频数据.
endianness
整型
G_BIG_ENDIAN(1234)orG_LITTLE_ENDIAN(4321)
样本的字节序列。
值G_LITTLE_ENDIAN(4321)意味着"little-endian"(字节序列是"低位字节优先").值G_BIG_ENDIAN(1234)意味着"big-endian"(字节序列是"高位字节优先").
signed
布尔型
TRUE或FALSE
整型样本值是否带符号。
带符号的样本值用一个位来指示符号位(正或负)。
不带符号的样本值总为正。
width
整型
大于0
每个样本的最大位数。
depth
整型
大于0
每个样本所使用的位数。
该值小于等于width。
如果depth小于width,从低位开始算被使用的位数。
举例来说,一个32的width,24的depth,意味着每个样本存储在32位的字节(4个字节)中,但只有低24位被使用了。
audio/mpeg
使用MPEG音频算法压缩过的音频数据。
mpegversion
整型
1,2或4
压缩数据的MPEG-版本。
值1表示MPEG-1,-2和-2.5layer1,2或3。
值2和4表示MPEG-AAC音频压缩算法。
framed
布尔型
0或1
true值表示每个缓存只包含一帧。
false值表示缓存数和帧数并不是1:
1。
layer
整型
1,2,或3
用来压缩数据的压缩策略层次。
(onlyifmpegversion=1).
bitrate
整型
大于0
位率,每秒的位数。
对于VBR(variablebitrate)MPEG数据,这是个平均位率。
audio/x-vorbis
Vorbis音频数据
对这种类型的数据通常没有特定的属性。
II.构建插件
现在可以学习如何编写一个插件了。
在这一部分,你将学习如何利用GStreamer的基本编程概念来写一个简单的插件。
也许前一部分没有涉及代码,导致事情变的有点抽象和难于理解。
相比而言,这一部分将出现程序和代码,我们将开发一个名为"ExampleFilter".
示例过滤器元件的开发将以一个单一的输入衬垫和输出衬垫开始。
起初,过滤器只是简单的将媒体和事件数据从它的sinkpad传送到它的sourcepad而不作任何改动。
但在这一部分的最后,你将学到如何给它添加一些包括属性和信号处理等有趣的功能。
并且,读完下一部分,即AdvancedFilterConcepts后,你将可以给你的插件添加更多的功能。
你可以在GStreamer目录下的examples/pwg/examplefilter/中找到着一部分所使用的示例代码。
3.构建样板(Boilerplate)
3.1.获取GStreamer插件模板
3.2.使用项目戳(ProjectStamp)
3.3.检查基本代码
3.4.GstElementDetails
3.5.GstStaticPadTemplate
3.6.构造函数
3.7.Plugin_init函数
4.指定衬垫(pads)
4.1.Setcaps-函数
5.链函数(Thechainfunction)
6.什么是状态?
6.1.管理滤镜的状态
7.添加参数
8.信号
9.编写测试程序
Chapter3.构建样板(Boilerplate)
本章你将学习如何用少量的代码创建一个新的插件。
你将看到如何从零开始得到GStreamer的模板代码。
随后你将学习怎样通过使用一些基本工具拷贝修改模板插件来生成一个新的插件。
如果你照着示例做,到本章结束,你将得到一个可在GStreamer程序中编译使用的音频过滤插件。
3.1.获取GStreamer插件模板
当前有两种方法可以用来开发一个新的GStreamer插件:
你可以手写全部的代码,或者你可以拷贝一份现成的插件模板然后添加你需要的代码。
迄今为止,第二种方法是比较简单的,因此,第一种方法将不再提及(这是留给读者的一个作业)。
第一步,从CVS模块中取出gst-template的一份拷贝,其中包含了一个重要的工具以及GStreamer基本插件的源代码模板。
为了顺利得到gst-template模块,确保你已经连到网络上,然后在终端中执行如下命令:
shell$
Logginginto:
pserver:
anoncvs@cvs.freedesktop.org:
/cvs/gstreamer
CVSpassword:
[ENTER]
shell$cvs-z3-d:
pserver:
anoncvs@cvs.freedesktop.org:
/cvs/gstreamercogst-template
Ugst-template/README
Ugst-template/gst-app/AUTHORS
Ugst-template/gst-app/ChangeLog
Ugst-template/gst-app/NEWS
Ugst-template/gst-app/README
...
敲入第一个命令后,你必须按回车键登陆CVS服务器。
(你或许必须登陆两次。
)第二个命令将checkout出一系列文件,并放到./gst-template目录下。
你要使用的模板将位于./gst-template/gst-plugin/目录下。
你应该先浏览一下该目录中的文件,并对插件的源码树结构有一个总体的了解。
3.2.使用项目戳(ProjectStamp)
编写一个新的元件所要做的第一件事为它指定一些基本信息:
它的名字,作者,版本号等
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- GStreamer 插件开发指南 插件 开发 指南