This chapter of the guide introduces the basic concepts of GStreamer. Understanding these concepts will help you grok the issues involved in extending GStreamer. Many of these concepts are explained in greater detail in the GStreamer Application Development Manual; the basic concepts presented here serve mainly to refresh your memory.
本章将介绍 GStreamer 的基本概念,了解这些概念将有助于你理解扩展 GStreamer 所涉及的问题。其中许多概念在《GStreamer 应用程序开发手册》中有更详细的解释;这里介绍的基本概念主要是为了加深记忆。
Elements and Plugins 元素和插件
Elements are at the core of GStreamer. In the context of plugin development, an element is an object derived from the GstElement class. Elements provide some sort of functionality when linked with other elements: For example, a source element provides data to a stream, and a filter element acts on the data in a stream. Without elements, GStreamer is just a bunch of conceptual pipe fittings with nothing to link. A large number of elements ship with GStreamer, but extra elements can also be written.
元素是 GStreamer 的核心。在插件开发中,元素是从 GstElement 类派生出来的对象。当与其他元素链接时,元素会提供某种功能:例如,源元素为流提供数据,过滤元素对流中的数据进行过滤。如果没有元素,GStreamer 只是一堆概念上的管接头,没有任何联系。GStreamer 随附了大量的元素,但也可以编写额外的元素。
Just writing a new element is not entirely enough, however: You will need to encapsulate your element in a plugin to enable GStreamer to use it. A plugin is essentially a loadable block of code, usually called a shared object file or a dynamically linked library. A single plugin may contain the implementation of several elements, or just a single one. For simplicity, this guide concentrates primarily on plugins containing one element.
不过,仅仅编写一个新元素还远远不够:你需要将元素封装在一个插件中,以便 GStreamer 使用它。插件本质上是一个可加载的代码块,通常称为共享对象文件或动态链接库。一个插件可以包含多个元素的实现,也可以只包含一个元素。为简单起见,本指南主要介绍包含一个元素的插件。
A filter is an important type of element that processes a stream of data. Producers and consumers of data are called source and sink elements, respectively. Bin elements contain other elements. One type of bin is responsible for synchronization of the elements that they contain so that data flows smoothly. Another type of bin, called autoplugger elements, automatically add other elements to the bin and links them together so that they act as a filter between two arbitrary stream types.
过滤器是处理数据流的一种重要元素。数据的生产者和消费者分别称为源元素和sink元素。Bin 元素包含其他元素。其中一种 Bin 元素负责同步它们所包含的元素,使数据流畅地流动。另一种 bin 称为自动插拔器元素,可自动将其他元素添加到 bin 中,并将它们连接在一起,从而在两种任意流类型之间起到过滤器的作用。
The plugin mechanism is used everywhere in GStreamer, even if only the standard packages are being used. A few very basic functions reside in the core library, and all others are implemented in plugins. A plugin registry is used to store the details of the plugins in a binary registry file. This way, a program using GStreamer does not have to load all plugins to determine which are needed. Plugins are only loaded when their provided elements are requested.
插件机制在 GStreamer 中随处可见,即使只使用标准软件包也不例外。核心库中只有几个非常基本的功能,其他功能都在插件中实现。插件注册表用于在二进制注册表文件中存储插件的详细信息。这样,使用 GStreamer 的程序就不必加载所有插件来确定需要哪些插件。插件只在其提供的元素被请求时才被加载。
See the GStreamer Library Reference for the current implementation details of GstElement and GstPlugin.
有关 GstElement 和 GstPlugin 的当前实现细节,请参阅《GStreamer 库参考》。
Pads 垫子
Pads are used to negotiate links and data flow between elements in GStreamer. A pad can be viewed as a “place” or “port” on an element where links may be made with other elements, and through which data can flow to or from those elements. Pads have specific data handling capabilities: A pad can restrict the type of data that flows through it. Links are only allowed between two pads when the allowed data types of the two pads are compatible.
Pads用于协商 GStreamer 中元素之间的链接和数据流。Pads可以看作是元素上的一个 "位置 "或 "端口",在这里可以与其他元素建立链接,数据也可以通过它流向或流出这些元素。Pads具有特定的数据处理功能:只有当两个Pads允许的数据类型兼容时,两个焊盘之间才允许链接。
An analogy may be helpful here. A pad is similar to a plug or jack on a physical device. Consider, for example, a home theater system consisting of an amplifier, a DVD player, and a (silent) video projector. Linking the DVD player to the amplifier is allowed because both devices have audio jacks, and linking the projector to the DVD player is allowed because both devices have compatible video jacks. Links between the projector and the amplifier may not be made because the projector and amplifier have different types of jacks. Pads in GStreamer serve the same purpose as the jacks in the home theater system.
打个比方可能会有帮助。Pads类似于物理设备上的插头或插孔。例如,一个家庭影院系统包括一个放大器、一个 DVD 播放器和一个(静音)视频投影仪。允许将 DVD 播放器链接到功放,因为这两个设备都有音频插孔;允许将投影仪链接到 DVD 播放器,因为这两个设备都有兼容的视频插孔。投影仪和功放之间不能链接,因为投影仪和功放的插孔类型不同。GStreamer 中的 PAD 与家庭影院系统中的插孔具有相同的用途。
For the most part, all data in GStreamer flows one way through a link between elements. Data flows out of one element through one or more source pads, and elements accept incoming data through one or more sink pads. Source and sink elements have only source and sink pads, respectively.
在大多数情况下,GStreamer 中的所有数据都是通过元素之间的链接单向流动的。数据通过一个或多个源Pads从一个元素流出,而元素则通过一个或多个汇接Pads接受输入数据。源元素和汇元素分别只有源Pads和汇Pads。
See the GStreamer Library Reference for the current implementation details of a GstPad.
有关 GstPad 的当前实现细节,请参阅《GStreamer 库参考》。
GstMiniObject, Buffers and Events
GstMiniObject、缓冲区和事件
All streams of data in GStreamer are chopped up into chunks that are passed from a source pad on one element to a sink pad on another element. GstMiniObject is the structure used to hold these chunks of data.
GStreamer 中的所有数据流都被分割成数据块,这些数据块从一个元素上的源焊盘传递到另一个元素上的汇焊盘。GstMiniObject 就是用来保存这些数据块的结构。
GstMiniObject contains the following important types:
GstMiniObject 包含以下重要类型:
- An exact type indicating what type of data (event, buffer, ...) this GstMiniObject is.
- 精确类型,表示此 GstMiniObject 是哪种类型的数据(事件、缓冲区......)。
- A reference count indicating the number of elements currently holding a reference to the miniobject. When the reference count falls to zero, the miniobject will be disposed, and its memory will be freed in some sense (see below for more details).
- 引用计数,表示当前持有迷你对象引用的元素数量。当引用计数为零时,迷你对象将被弃置,其内存也将在某种程度上被释放(详见下文)。
For data transport, there are two types of GstMiniObject defined: events (control) and buffers (content).
在数据传输方面,定义了两种类型的 GstMiniObject:事件(控制)和缓冲区(内容)。
Buffers may contain any sort of data that the two linked pads know how to handle. Normally, a buffer contains a chunk of some sort of audio or video data that flows from one element to another.
缓冲区可包含两个链接焊盘知道如何处理的任何类型的数据。通常,缓冲区包含从一个元素流向另一个元素的音频或视频数据块。
Buffers also contain metadata describing the buffer's contents. Some of the important types of metadata are:
缓冲区还包含描述缓冲区内容的元数据。其中一些重要的元数据类型包括
- Pointers to one or more GstMemory objects. GstMemory objects are refcounted objects that encapsulate a region of memory.
- 指向一个或多个 GstMemory 对象的指针。GstMemory 对象是封装内存区域的计数对象。
- A timestamp indicating the preferred display timestamp of the content in the buffer.
- 时间戳,表示缓冲区中内容的首选显示时间戳。
Events contain information on the state of the stream flowing between the two linked pads. Events will only be sent if the element explicitly supports them, else the core will (try to) handle the events automatically. Events are used to indicate, for example, a media type, the end of a media stream or that the cache should be flushed.
事件包含两个链接垫之间的流状态信息。只有当元素明确支持事件时,才会发送事件,否则内核将(尝试)自动处理事件。例如,事件用于指示媒体类型、媒体流结束或缓存应被刷新。
Events may contain several of the following items:
活动可能包含以下几个项目:
- A subtype indicating the type of the contained event.
- 表示所含事件类型的子类型。
- The other contents of the event depend on the specific event type.
- 事件的其他内容取决于具体的事件类型。
Events will be discussed extensively in Events: Seeking, Navigation and More. Until then, the only event that will be used is the EOS event, which is used to indicate the end-of-stream (usually end-of-file).
将对事件进行广泛讨论《事件:寻找、导航及其他》一书中将详细讨论事件。在此之前,将使用的唯一事件是 EOS 事件,它用于指示流的结束(通常是文件的结束)。
See the GStreamer Library Reference for the current implementation details of a GstMiniObject, GstBuffer and GstEvent.
有关 GstMiniObject、GstBuffer 和 GstEvent 的当前实现细节,请参阅《GStreamer 库参考》。
Buffer Allocation
缓冲区分配
Buffers are able to store chunks of memory of several different types. The most generic type of buffer contains memory allocated by malloc(). Such buffers, although convenient, are not always very fast, since data often needs to be specifically copied into the buffer.
缓冲区可以存储几种不同类型的内存块。最普通的缓冲区类型包含由 malloc() 分配的内存。这种缓冲区虽然方便,但速度并不总是很快,因为数据往往需要专门复制到缓冲区中。
Many specialized elements create buffers that point to special memory. For example, the filesrc element usually maps a file into the address space of the application (using mmap()), and creates buffers that point into that address range. These buffers created by filesrc act exactly like generic buffers, except that they are read-only. The buffer freeing code automatically determines the correct method of freeing the underlying memory. Downstream elements that receive these kinds of buffers do not need to do anything special to handle or unreference it.
例如,filesrc 元素通常将文件映射到应用程序的地址空间(使用 mmap()),并创建指向该地址范围的缓冲区。这些由 filesrc 创建的缓冲区与一般缓冲区完全相同,只是它们是只读的。缓冲区释放代码会自动确定释放底层内存的正确方法。接收这类缓冲区的下游元素不需要做任何特殊处理或取消引用。
Another way an element might get specialized buffers is to request them from a downstream peer through a GstBufferPool or GstAllocator. Elements can ask a GstBufferPool or GstAllocator from the downstream peer element. If downstream is able to provide these objects, upstream can use them to allocate buffers. See more in Memory allocation.
元素获取专用缓冲区的另一种方式是通过 GstBufferPool 或 GstAllocator 向下游对等元素申请。元素可以向下游对等元素申请 GstBufferPool 或 GstAllocator。如果下游能够提供这些对象,上游就可以使用它们来分配缓冲区。更多信息,请参阅内存分配。
Many sink elements have accelerated methods for copying data to hardware, or have direct access to hardware. It is common for these elements to be able to create a GstBufferPool or GstAllocator for their upstream peers. One such example is ximagesink. It creates buffers that contain XImages. Thus, when an upstream peer copies data into the buffer, it is copying directly into the XImage, enabling ximagesink to draw the image directly to the screen instead of having to copy data into an XImage first.
许多汇元素都有将数据复制到硬件的加速方法,或者可以直接访问硬件。这些元素通常可以为其上游对等元素创建 GstBufferPool 或 GstAllocator。ximagesink 就是这样一个例子。它创建了包含 XImages 的缓冲区。这样,当上游对等程序将数据拷贝到缓冲区时,就等于直接拷贝到 XImage 中,从而使 ximagesink 可以直接将图像绘制到屏幕上,而不必先将数据拷贝到 XImage 中。
Filter elements often have the opportunity to either work on a buffer in-place, or work while copying from a source buffer to a destination buffer. It is optimal to implement both algorithms, since the GStreamer framework can choose the fastest algorithm as appropriate. Naturally, this only makes sense for strict filters -- elements that have exactly the same format on source and sink pads.过滤元件通常有机会在缓冲区就地工作,或者在从源缓冲区复制到目标缓冲区时工作。实现这两种算法是最佳选择,因为 GStreamerframework 可以根据情况选择最快的算法。当然,这只适用于严格的过滤器--在源缓冲区和目标缓冲区中格式完全相同的元素。
Media types and Properties 媒体类型和属性
GStreamer uses a type system to ensure that the data passed between elements is in a recognized format. The type system is also important for ensuring that the parameters required to fully specify a format match up correctly when linking pads between elements. Each link that is made between elements has a specified type and optionally a set of properties. See more about caps negotiation in Caps negotiation.GStreamer
使用类型系统来确保元素之间传递的数据是公认的格式。类型系统对于确保在元素之间链接垫块时,完全指定格式所需的参数能正确匹配也很重要。元素之间的每个链接都有一个指定的类型和一组可选属性。有关上限协商的更多信息,请参阅上限协商。
The Basic Types 基本类型
GStreamer already supports many basic media types. Following is a table of a few of the basic types used for buffers in GStreamer. The table contains the name ("media type") and a description of the type, the properties associated with the type, and the meaning of each property. A full list of supported types is included in List of Defined Types.
GStreamer 已经支持许多基本媒体类型。下面的表格列出了 GStreamer 缓冲区使用的几种基本类型。该表包含名称("媒体类型")、类型描述、与类型相关的属性以及每个属性的含义。支持类型的完整列表包含在定义类型列表(List of DefinedTypes)中。
Table of Example Types 示例类型表 | |||||
Media Type 媒体类型 | Description 说明 | Property 物业 | Property Type 物业类型 | Property Values 物业价值 | Property Description 物业描述 |
audio/* 音频/* | All audio types 所有音频类型 | rate 费率 | integer 整数 | greater than 0 大于 0 | The sample rate of the data, in samples (per channel) per second.数据采样率,单位为每秒采样(每个通道)。 |
channels 频道 | integer 整数 | greater than 0 大于 0 | The number of channels of audio data.音频数据的通道数。 | ||
audio/x-raw 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 F64BEs8 u8 s16le s16be u16le u16be s24_32le s24_32be u24_32le u24_32be s32le s32be u32le u32be s24le s24be u24le u24be s20le s20be u20le u20le u20be s18le s18be u18le u18be f32le f32le f32be f64le f64be | The format of the sample data.样本数据的格式。 |
audio/mpeg 音频/mpeg | Audio data compressed using the MPEG audio encoding scheme.使用 MPEG 音频编码方案压缩的音频数据。 | mpegversion mpegversion | integer 整数 | 1, 2 or 4 1、2 或 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.用于编码数据的 MPEG 版本。值 1 指的是 MPEG-1、-2 和-2.5 第 1、2 或 3 层。数值 2 和 4 指的是 MPEG-AAC 音频编码方案。 |
framed 有框架的 | boolean 布尔 | 0 or 1 0 或 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 1、2 或 3 | The compression scheme layer used to compress the data (only if mpegversion=1).用于压缩数据的压缩方案层(仅当 mpegversion=1 时)。 | ||
bitrate 比特率 | integer 整数 | greater than 0 大于 0 | The bitrate, in bits per second. For VBR (variable bitrate) MPEG data, this is the average bitrate.比特率,单位为比特/秒。对于 VBR(可变比特率)MPEG 数据,这是平均比特率。 | ||
audio/x-vorbis 音频/x-vorbis | Vorbis audio data Vorbis 音频数据 | There are currently no specific properties defined for this type.目前还没有为该类型定义特定属性。 |