gstreamer插件开发手册.pdf(2)
只有当两个衬垫允许通过的数据类型兼容时才可以将它们连接起来。也许打一个比方可以有助于理解这些概念。衬垫类似于物理设备上的a plug or jack。想象一个包含功放,DVD 播放器和一个视频投影仪器的家庭影院系统。将投影仪和DVD播放器相连是允许的,因为这两个设备具有兼容的video jacks。而要将投影仪和功放连9lenove 内部使用 PDF 文件使用 "pdfFactory Pro" 试用版本创建GStreamer 件开发手册起来也许就行 通了,因为它们之间的jack 不同。GStreamer 中的衬垫具有和家庭影院系统中的jack 相同的功能。大部分情况下,所有在GStreamer 中流经的数据都遵循一个原则。数据从element 的一个或多个源衬垫流出,从一个或多个sink 衬垫流入。源和sink 元件分别只有源和sink衬垫。查阅GStreamer 库索引来获取GstPad 的当前实现细节。2.3. 数据,缓冲区和事件GStreamer 中的所有数据流被分割成一块一块的,并从一个元件的源衬垫传到另一个元件的sink 衬垫。数据就是用来承载一块一块数据的数据结构。
数据包含以下的重要组成部分:一个类型域标识该数据的准确类型(control,content,...)。一个指示当前有多少元件引用缓冲区的引用计数器。当计数器的值为0 时,缓冲区将被销毁,内存被释放 (更详细的细节看下面)。当前存在两种数据类型:事件(control)和缓冲区(content)。缓冲区可以包含两个相连接的pad 所能处理的任 数据。通常,一个缓冲区包含一块音频或视频数据块,该数据块从一个元件流向另一个元件。缓冲区同样包含描述缓冲区内容的元数据(metadata)。一些重要的元数据类型有:一个指向缓冲区数据的指针。一个标识缓冲区数据大小的整型变量。一个指示缓冲区的最佳显示时间的时间戳。事件包含两个相连的衬垫间的流的状态的信息。只有事件被元件显式地支持时它们才会被发送,否则核心层将 (尝试)自动处理事件。举例来说,事件会被用来表示一个时钟中断,媒体流的结束或高速缓冲区(cache)需要刷新。事件结构可能会包含如下的成员:一个用来标明事件类型的子类型。事件类型相关的其他部分。事件将在Chapter 19 一章中广泛讨论。在那之前,只会涉及流结束(EOS)事件,该事件通常在文件结束时发出,标识流的结束。
10lenove 内部使用 PDF 文件使用 "pdfFactory Pro" 试用版本创建GStreamer 件开发手册查阅GStreamer 库索引来获取GstMiniObject, GstBuffer 和GstEvent 的当前实现细节。2.3.1. 缓冲区的分配缓冲区是一块可以存放各种数据的内存。缓冲区的内存一般用malloc()函数分配。这样虽然很方便,但不总是最高效,因为数据经常需要被显式的拷入缓冲区。有些特殊的元件创建指向特殊内存的缓冲区。例如,filesrc 元件通常会(使用 mmap())将一个文件映射到应用程序的地址空间,并创建指向那个地址范围的缓冲区。这些由filesrc 创建的缓冲区具有和其它通用的缓冲区一样的行为,唯一的区别是它们是只读的。释放缓冲区的代码将自动检测内存类型并使用正确的方法释放内存。另一种可能得到特殊缓冲区的途径是向下游同伙 (downstream peer)发出请求。这样得到的缓冲区称为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")和对类型的描述,类型相关的属性,以及每个属性的意义。已定义类型列表一节中列出了所有支持的类型。11lenove 内部使用 PDF 文件使用 "pdfFactory Pro" 试用版本创建GStreamer件开发手册Table 2-1. Table of Example TypesMim描述e属性属性类型属性值属性描述rate 整型大于0数据的采样率,每秒的样本数(每个声道audio/*所有音频类型channels 整型大于0音频数据的声道数。样本的字节序列。值 G_LITTLE_ENDIANG_BIG_ENDIAN () o意r 味着"little-endian" (字节序列是endianness整型G_LITTLE_ENDIA位N字节优先"). 值 G_BIG_ENDIAN ( 1234)(4321)意味着"big-endian" (字节序列是"高位字节优先").整型样本值是否 号。
号的样本值用signed 布尔型TRUE 或FALSE 一个位来指示 号位(正或负)。号的未结构化的及未压缩的audio/x样本值总为正。原始整型音频数据width 整型大于0每个样本的最大位数。每个样本所使用的位数。该值小于等于width 。如果depth 小于width ,从低位开始算被使用的位数。举例来说,一个32 的depth 整型大于024 的depth,意味着每个样本存储在字节 (4 个字节)中,但只有低24 位被使用了。压缩数据的MPEG-版本。值1 表示mpegversio整型1, 2 或4-2 和-2.5 layer 1, 2 或 3 。值 2 和MPEG-AAC 音频压缩算法。true 值表示每个缓存只包含一帧。falseframed 布尔型0 或1使用 MPEG 音频算法压audio/mpeg示缓存数和帧数并 是1:1。缩过的音频数据用来压缩数据的压缩策略层次。layer 整型1, 2,或3mp egversion=1).位率,每秒的位数。对于 VBR(variablebitrate 整型大于0bitrate) MPEG 数据,这是个平均位率audio/xVorbis 音频数据对这种类型的数据通常没有特定的属性12lenove 内部使用 PDF 文件使用 "pdfFactory Pro" 试用版本创建GStreamer 件开发手册II. 构建插件现在可以学习如 编写一个插件了。
在这一部分,你将学习如 利用GStreamer 的基本编程概念来写一个简单的插件。也许前一部分没有涉及代码,导致事情变的有点抽象和难于理解。相比而言,这一部分将出现程序和代码,我们将开发一个名为"ExampleFilter".示例过滤器元件的开发将以一个单一的输入衬垫和输出衬垫开始。起初,过滤器只是简单的将媒体和事件数据从它的sink pad 传送到它的source pad 而 作任 改动。但在这一部分的最后,你将学到如何给它添加一些包括属性和信号处理等有趣的功能。并且,读完下一部分,即Advanced Filter Concepts 后,你将可以给你的插件添加更多的功能。你可以在GStreamer 目录下的 examples/pwg/examplefilter/中找到着一部分所使用的示例代码。13lenove 内部使用 PDF 文件使用 "pdfFactory Pro" 试用版本创建GStreamer件开发手册Chapter 3. 构建样板(Boilerplate)本章你将学习如 用少量的代码创建一个新的插件。你将看到如 从零开始得到GStreamer 的模板代码。
随后你将学习怎样通过使用一些基本工具拷贝修改模板插件来生成一个新的插件。如果你照着示例做,到本章结束,你将得到一个可在GStreamer 程序中编译使用的音频过滤插件。3.1. 获取GStreamer 插件模板当前有两种方法可以用来开发一个新的GStreamer 插件:你可以手写全部的代码,或者你可以拷贝一份现成的插件模板然后添加你需要的代码。迄今为止,第二种方法是比较简单的,因此,第一种方法将 再提及 (这是留给读者的一个作业)。第一步,从CVS 模块中取出 gst-template 的一份拷贝,其中包含了一个重要的工具以及GStreamer 基本插件的源代码模板。为了顺利得到 gst-template 模块,确保你已经连到网络上,然后在终端中执行如下命令:shell $ cvs -d:pserver:anoncvs@/cvs/gstreamer loginLogging in to :pserver:anoncvs@:/cvs/gstreamerCVS password: [ENTER]shell $ cvs -z3 -d:pserver:anoncvs@:/cvs/gstreamer cogst-templateU gst-template/READMEU gst-template/gst-app/AUTHORSU gst-template/gst-app/ChangeLogU gst-template/gst-app/Makefile.amU gst-template/gst-app/NEWSU gst-template/gst-app/READMEU gst-template/gst-app/autogen.shU gst-template/gst-app/configure.acU gst-template/gst-app/src/Makefile.am...敲入第一个命令后,你必须按回车键登陆CVS 服务器。
(你或许必须登陆两次。)第二个命令将check out 出一系列文件,并放到./gst-template 目录下。你要使用的模板将位于./gst-template/gst-plugin/目录下。你应该先浏览一下该目录中的文件,并对插件的源码树结构有一个总体的了解。3.2. 使用项目戳(Project Stamp)14lenove 内部使用 PDF 文件使用 "pdfFactory Pro" 试用版本创建GStreamer件开发手册编写一个新的元件所要做的第一件事为它指定一些基本信息:它的名字,作者,版本号等等。我们还必须定义一个对象来表示 element,并存放元件需要的数据。所有的这些统称为样板文件(boilerplate).定义样板文件的标准方法是:写一些简单的代码,并填入一些结构。正如前一部分所说,实现这一目的的最简单方法拷贝一个模板然后根据你的需要增加一些功能。在./gst-plugins/tools/录下有个工具会对你有所帮助。这个名为make_element 的程序是一个快速的命令行工具。要使用make_element,首先开启一个终端窗口,进入gst-template/gst-plugin/src录,然后运行make_element 命令。
直接击沉