当前位置: 代码迷 >> 综合 >> 编写 GStreamer 插件1:概述
  详细解决方案

编写 GStreamer 插件1:概述

热度:71   发布时间:2023-12-12 15:36:40.0

GStreamer是一个非常强大和通用的框架,用于创建流媒体应用程序。GStreamer框架的许多优点来自于它的模块化:GStreamer可以无缝地合并新的插件模块。但由于模块化和强大的功能往往以更高的复杂性为代价(例如,考虑CORBA),编写新插件并不总是那么容易。

本指南旨在帮助您理解GStreamer框架,以便开发新插件来扩展现有功能。本指南通过开发一个用C编写的示例插件(音频过滤器插件)来解决大多数问题。但是,本指南后面的部分还介绍了编写其他类型插件所涉及的一些问题,并且本指南的结尾描述了GStreamer的一些Python绑定。

1. 前言

1.1 什么是GStreamer?

GStreamer是一个用于创建流媒体应用程序的框架。基本设计来自俄勒冈研究生院的视频管道,以及DirectShow的一些想法。

GStreamer的开发框架使得编写任何类型的流媒体应用程序成为可能。GStreamer框架旨在使编写处理音频或视频或两者的应用程序变得容易。它不局限于音频和视频,可以处理任何类型的数据流。管道设计的开销比应用的过滤器所产生的开销要小。这使得GStreamer成为设计对延迟或性能有很高要求的高端音频应用程序的良好框架。

GStreamer最明显的用途之一就是用来构建媒体播放器。GStreamer已经包含用于构建媒体播放器的组件,该播放器可以支持多种格式,包括MP3、Ogg/Vorbis、MPEG-1/2、AVI、Quicktime、mod等等。然而,GStreamer不仅仅是另一个媒体播放器。它的主要优点是可插入组件可以混合并匹配到任意管道中,这样就可以编写一个完整的视频或音频编辑应用程序。

该框架基于插件,插件将提供各种编解码器和其他功能。这些插件可以链接并排列在管道中。这个管道定义了数据流。

GStreamer的核心功能是为插件、数据流、同步和媒体类型处理/协商提供一个框架。它还提供了一个API来使用各种插件编写应用程序。

1.2 谁应该阅读本指南?

本指南介绍如何为GStreamer编写新模块。本指南与以下几个人群相关:

  • 任何想在GStreamer中添加对处理数据的新方法的支持的人。例如,此组中的某个人可能希望创建新的数据格式转换器、新的可视化工具或新的解码器或编码器。
  • 任何想要添加对新输入和输出设备的支持的人。例如,这一组中的人可能希望增加向新的视频输出系统写入数据或从数码相机或专用麦克风读取数据的能力。
  • 任何想以任何方式扩展GStreamer的人。在理解插件系统对其余代码的约束之前,您需要了解插件系统是如何工作的。另外,读完本文后,您可能会惊讶于插件可以完成多少工作。

如果您只想使用GStreamer的现有功能,或者只想使用使用GStreamer的应用程序,则本指南与您无关。如果您只对使用现有的插件来编写新的应用程序感兴趣,而且已经有很多插件了,那么您可能需要查看GStreamer应用程序开发手册。如果您只是想获得有关GStreamer应用程序的帮助,那么您应该查看该特定应用程序的用户手册。

1.3 初步阅读

本指南假设您对GStreamer的基本工作原理比较熟悉。对于GStreamer中编程概念的简单介绍,您可能希望先阅读GStreamer应用程序开发手册。还可以查看GStreamer网站上提供的其他文档。

为了理解本手册,您需要对C语言有基本的了解。由于GStreamer遵循GObject编程模型,因此本指南还假设您了解GObject编程的基础知识。您可能还想看一下ericharlow的《使用GTK+和GDK开发Linux应用
程序》一书。

1.4 本指南的结构

为了帮助您浏览本指南,它分为几个大的部分。每一部分都涉及到一个关于GStreamer插件开发的特别广泛的主题。本指南各部分按以下顺序排列:

  • 构建一个插件-介绍一个插件的结构,使用一个示例音频过滤器进行说明。
    .
    这一部分涵盖了构建插件通常需要执行的所有基本步骤,例如向GStreamer注册元素,并设置基本步骤,以便它可以从相邻元素接收数据并向其发送数据。讨论首先给出生成基本结构和在构建样板文件时注册元素的示例。然后,您将学习如何编写代码,以获得一个基本的过滤器插件在指定垫,链函数和什么是状态?。
    .
    之后,我们将展示GObject的一些概念,这些概念涉及如何为应用程序配置元素,以及如何在添加属性和信号时进行应用程序元素交互。接下来,您将学习构建一个快速测试应用程序,以测试您在构建测试应用程序时所学的所有内容。我们在这里只谈基本问题。对于全面的应用程序开发,您应该查看应用程序开发手册。
    .
  • 高级过滤器概念-有关GStreamer插件开发高级功能的信息。
    .
    在学习了基本步骤之后,您应该能够创建一个功能强大的音频或视频过滤器插件,其中包含一些不错的特性。然而,GStreamer为插件编写器提供了更多的功能。本指南的这一部分包括有关更高级主题的章节,如调度、GStreamer中的媒体类型定义、时钟、接口和标记。由于这些特性是特定于目的的,因此您可以按任何顺序阅读它们,其中大多数不需要其他部分的知识。
    .
    第一章,命名为不同的调度模式,将解释一些基本的元素调度。这不是很深入,但主要是介绍为什么其他事情会像它们那样工作。如果您对GStreamer内部结构感兴趣,请阅读本章。下一步,我们将应用这些知识并讨论另一种类型的数据传输,而不是您在链函数中所学到的:不同的调度模式。基于循环的元素将使您能够更好地控制输入速率。这在编写muxer或demuxer时非常有用。
    接下来,我们将在媒体类型和属性中讨论GStreamer中的媒体标识。您将学习如何定义新的媒体类型,并了解GStreamer中定义的标准媒体类型列表。
    .
    在下一章中,您将学习请求的概念,有时是pad,它们是动态创建的pad,要么是因为应用程序请求它(请求),要么是因为媒体流需要它(有时)。这将是在要求,有时垫。
    下一章“时钟”将解释GStreamer中时钟的概念。当您想知道元素应该如何实现音频/视频同步时,需要这些信息。
    .
    接下来的几章将讨论进行应用程序元素交互的高级方法。之前,我们在GObject上学习了添加属性和信号的方法。我们将讨论动态参数,它是一种在支持动态参数时,预先定义元素随时间变化的行为的方法。接下来,您将在interfaces中了解接口。接口是基于GObject的GInterface的特定于目标的应用程序元素交互方式。最后,您将了解如何在标记(metadata和Streaminfo)中的GStreamer中处理元数据。
    .
    最后一章“事件:寻找、导航等”将讨论GStreamer中的事件概念。事件是执行应用程序元素交互的另一种方式。例如,他们负责寻找。它们也是元素相互作用的另一种方式,例如让彼此知道媒体流的不连续性、在管道中转发标记等等。
    .
  • 创建特殊元素类型-编写其他插件类型的说明。
    .
    因为指南的前两部分以音频过滤器为例,所以介绍的概念适用于过滤器插件。但许多概念同样适用于其他插件类型,包括源、接收器和自动插件。指南的这一部分介绍了在处理这些更专门的插件类型时出现的问题。本章首先特别关注可以使用基类(预先生成的基类)编写的元素,然后还将在编写解复用器或解析器、编写N-to-1元素或复用器以及编写管理器时讨论编写特殊类型的元素。
    .
  • 附录-插件开发人员的进一步信息。
    .
    附录中包含了一些顽固地拒绝与指南的其他部分完全吻合的信息。本节大部分内容尚未完成。

本指南介绍部分的其余部分简要概述了GStreamer插件开发中涉及的基本概念。涵盖的主题包括元素和插件、pad、GstMiniObject、缓冲区和事件以及媒体类型和属性。如果您已经熟悉这些信息,您可以使用这个简短的概述来刷新您的内存,或者您可以跳到构建一个插件。

正如你所看到的,有很多东西要学,所以让我们开始吧!

  • 通过从GstBin扩展来创建复合元素和复杂元素。这将允许您创建嵌入了其他插件的插件。
  • 向注册表添加新的媒体类型以及typedetect函数。这将允许你的插件操作一个全新的媒体类型。

2. 基础

本章介绍了GStreamer的基本概念。理解这些概念将帮助您探索扩展GStreamer所涉及的问题。其中许多概念在GStreamer应用程序开发手册中有更详细的解释;这里介绍的基本概念主要用于刷新你的记忆。

2.1 元素和插件

元素是GStreamer的核心。在插件开发的上下文中,元素是从GstElement类派生的对象。元素在与其他元素链接时提供某种功能:例如,源元素向流提供数据,而过滤器元素作用于流中的数据。没有元素,GStreamer只是一堆没有任何链接的概念性管件。GStreamer附带了大量元素,但也可以编写额外的元素。

然而,仅仅编写一个新元素是不够的:您需要将您的元素封装在一个插件中,以使GStreamer能够使用它。插件本质上是一个可加载的代码块,通常称为共享对象文件或动态链接库。一个插件可以包含多个元素的实现,也可以只包含一个元素。为了简单起见,本指南主要关注包含一个元素的插件。

过滤器是处理数据流的一种重要元素。数据的生产者和消费者分别称为源元素和汇元素。Bin元素包含其他元素。一种类型的bin负责同步它们所包含的元素,以便数据顺利流动。另一种类型的bin称为autoplugger elements,它会自动将其他元素添加到bin中并将它们链接在一起,以便它们充当两种任意流类型之间的过滤器。

插件机制在GStreamer中无处不在,即使只使用标准包。一些非常基本的函数驻留在核心库中,其他所有函数都在插件中实现。插件注册表用于将插件的详细信息存储在二进制注册表文件中。这样,使用GStreamer的程序就不必加载所有插件来确定需要哪些插件。插件只有在请求它们提供的元素时才被加载。

有关GstElement和GstPlugin的当前实现细节,请参阅GStreamer库参考。

2.2 Pad

pad用于协商GStreamer中元素之间的链接和数据流。pad可以被看作是元素上的一个“地方”或“端口”,在这里可以与其他元素建立链接,并且数据可以通过它流入或流出这些元素。pad具有特定的数据处理能力:pad可以限制流经它的数据类型。当两个焊盘允许的数据类型兼容时,才允许在两个焊盘之间进行链接。

打个比方可能会有帮助。Pad类似于物理设备上的插头或插孔。例如,考虑一个家庭影院系统,它由一个放大器、一个DVD播放器和一个(无声的)视频投影仪组成。允许将DVD播放机连接到放大器,因为两个设备都有音频插孔;允许将投影仪连接到DVD播放机,因为两个设备都有兼容的视频插孔。投影仪和放大器之间可能没有连接,因为投影仪和放大器有不同类型的插孔。GStreamer中的垫子与家庭影院系统中的插孔具有相同的用途。

在大多数情况下,GStreamer中的所有数据都单向流过元素之间的链接。数据通过一个或多个源Pad从一个元素流出,元素通过一个或多个接收器Pad接受传入的数据。源和汇元素分别只有源和汇Pad。
有关GstPad的当前实现细节,请参阅GStreamer库参考。

2.3 GstMiniObject、缓冲区和事件

GStreamer中的所有数据流都被切碎成块,从一个元素上的源pad传递到另一个元素上的sink pad。GstMiniObject是用来保存这些数据块的结构。

GstMiniObject包含以下重要类型:

  • 一个确切的类型,指示此GstMiniObject是什么类型的数据(事件、缓冲区等)。
  • 一种引用计数,表示当前保存对微型对象引用的元素数。当引用计数降为零时,将释放miniobject,并在某种意义上释放其内存(有关详细信息,请参阅下文)。

对于数据传输,定义了两种类型的GstMiniObject:事件(控件)和缓冲区(内容)。

缓冲区可以包含两个连接的焊盘知道如何处理的任何类型的数据。通常,缓冲区包含从一个元素流到另一个元素的某种音频或视频数据块。

缓冲区还包含描述缓冲区内容的元数据。一些重要的元数据类型包括:

  • 指向一个或多个GstMemory对象的指针。GstMemory对象是封装内存区域的refcounted对象。
  • 表示缓冲区中内容的优选显示时间戳的时间戳。

事件包含两个连接Pad之间流的状态信息。只有当元素显式支持事件时才会发送事件,否则核心将(尝试)自动处理事件。例如,事件用于指示媒体类型、媒体流的结束或应刷新缓存。

事件可能包含以下几项:

  • 指示所包含事件类型的子类型。
  • 事件的其他内容取决于特定的事件类型。

事件将在事件中广泛讨论:搜索、导航等。在此之前,将使用的唯一事件是EOS事件,它用于指示流的结束(通常是文件的结束)。

有关GstMiniObject、GstBuffer和GstEvent的当前实现细节,请参阅GStreamer库参考。

2.3.1 缓冲区分配

缓冲区能够存储几种不同类型的内存块。最通用的缓冲区类型包含malloc()分配的内存。这样的缓冲区虽然方便,但并不总是很快,因为数据通常需要专门复制到缓冲区中。

许多专用元素创建指向特殊内存的缓冲区。例如,filesrc元素通常将文件映射到应用程序的地址空间(使用mmap()),并创建指向该地址范围的缓冲区。filesrc创建的这些缓冲区的行为与普通缓冲区完全相同,只是它们是只读的。缓冲区释放代码自动确定释放底层内存的正确方法。接收这类缓冲区的下游元素不需要做任何特殊的处理或取消引用。

元素获取专用缓冲区的另一种方法是通过GstBufferPool或GstAllocator从下游对等方请求它们。元素可以从下游对等元素请求GstBufferPool或GstAllocator。如果下游能够提供这些对象,那么上游可以使用它们来分配缓冲区。有关内存分配的更多信息。

许多接收器单元都有将数据复制到硬件或直接访问硬件的加速方法。这些元素通常能够为它们的上游同级创建GstBufferPool或GstAllocator。一个这样的例子是ximagesink。它创建包含XImages的缓冲区。因此,当上游对等机将数据复制到缓冲区中时,它直接复制到XImage中,使得ximagesink能够将图像直接绘制到屏幕上,而不必首先将数据复制到XImage中。

过滤器元素通常有机会在缓冲区上工作,或者在从源缓冲区复制到目标缓冲区时工作。这两种算法的实现都是最佳的,因为GStreamer框架可以根据需要选择最快的算法。当然,这只对严格的过滤器有意义——在源和接收器Pad上具有完全相同格式的元素。

2.4 介质类型和属性

GStreamer使用类型系统来确保元素之间传递的数据采用可识别的格式。类型系统对于确保在元素之间链接焊盘时,完全指定格式所需的参数正确匹配也很重要。元素之间的每个链接都有一个指定的类型和一组可选的属性。请参阅caps协商中有关caps协商的更多信息。

2.4.1 基本类型

GStreamer已经支持许多基本的媒体类型。下表列出了GStreamer中用于缓冲区的一些基本类型。该表包含名称(“媒体类型”)和类型描述、与类型关联的属性以及每个属性的含义。支持的类型的完整列表包含在已定义类型的列表中。

示例类型表

Media Type Description Property Property Type Property Values Property Description
audio/* All audio types rate integer greater than 0 The sample rate of the data, in samples (per channel) per second.
channels integer greater than 0 The number of channels of audio data.
audio/x-raw Unstructured and uncompressed raw integer audio data. format string S8 U8 S16LE S16BE U16LE U16BE S24_32LE S24_32BE U24_32LE U24_32BE S32LE S32BE U32LE U32BE S24LE S24BE U24LE U24BE S20LE S20BE U20LE U20BE S18LE S18BE U18LE U18BE F32LE F32BE F64LE F64BE The format of the sample data.
audio/mpeg Audio data compressed using the MPEG audio encoding scheme. mpegversion integer 1, 2 or 4 The MPEG-version used for encoding the data. The value 1 refers to MPEG-1, -2 and -2.5 layer 1, 2 or 3. The values 2 and 4 refer to the MPEG-AAC audio encoding schemes.
framed boolean 0 or 1 A true value indicates that each buffer contains exactly one frame. A false value indicates that frames and buffers do not necessarily match up.
layer integer 1, 2, or 3 The compression scheme layer used to compress the data (only if mpegversion=1).
bitrate integer greater than 0 The bitrate, in bits per second. For VBR (variable bitrate) MPEG data, this is the average bitrate.
audio/x-vorbis Vorbis audio data There are currently no specific properties defined for this type.
  相关解决方案