OpenMAX/IL: OMX IL 学习笔记【1】- 结构框架
作者:互联网
一、OpenMax简介
OpenMAX(Open Media Acceleration的缩写,开放多媒体加速层)是一个多媒体应用程序的标准。由NVIDIA公司和Khronos™在2006年推出。
它是无授权费的、跨平台的C语言程序接口序列,这些接口对音频、视频、静态图片的常用操作进行封装。
它包括三层,自上而下分别是应用层(AL)、集成层(IL)和开发层(DL)。
- OpenMAX AL:Application Layer,应用和多媒体中间层的标准接口,使得应用在多媒体接口上具有了可移植性。
- OpenMAX IL:Integration Layer,作为在嵌入式和移动设备中使用的audio,video,images codecs的底层接口。使得AP和多媒体框架可以以统一的方式访问多媒体codec和支持组件。Codec可以是硬件和软件的任意组合,对用户透明。
- OpenMAX DL:Development Layer,定义了一套API,包含了audio,video和imaging使用的函数集合,这些函数可以由芯片厂商针对新的处理器进行实现和优化,然后被codec 厂商在各种codec上使用。
其中IL层已经成为了事实上的多媒体框架标准。 嵌入式处理器或者多媒体编解码模块的硬件生产者,通常提供标准的OpenMax IL层的软件接口,这样软件的开发者就可以基于这个层次的标准化接口进行多媒体程序的开发。
二、OpenMAX/IL: OMX IL - 结构框架
OpenMAX IL 层 API 旨在为媒体组件提供跨平台的可移植能力。这些接口将系统的软硬件结构进行抽象化。每个组件及其相关的转换都被封装在组件接口的内部。OpenMAX IL API 允许用户去加载,控制,连接以及卸载各独立的组件。这种极具灵活性的内核结构使得 Intergration Layer 能够很容易的实现几乎所有的多媒体应用情形,并且能够很好的与现有的基于图像的多媒体框架相结合。
1. 主要的功能和优点
OpenMAX IL API 能够在应用程序、多媒体框架和编解码库,以及其支持的组件(比如,sources 和 sinks)之间建立统一的接口。对于用户来说,组件自身及其内部的软硬件结合情况都是完全透明的。其主要功能如下:
- A flexible component-based API core;
- Ability to easily plug in new components;
- Coverage of targeted domains (audio, video, and imaging) while remaining easily extensible by both the Khronos Group and individual vendors;
- Capable of being implemented as either static or dynamic libraries;
- Retention of key features and configuration options needed by parent software (such as media frameworks);
- Ease of communication between the client and the components and between components themselves;
- Standardized definition of key components so all implementations of such “standard components” expose the same external interface (i.e. same inputs, outputs, and controls).
2. OpenMAX IL 软件结构
OpenMax的主要概念
客户端(Client):访问IL core或IL component的软件层,可能是位于GUI应用程序的下层,如GStreamer。IL client是一个典型的功能块,如filter graph multimedia framework,OpenMAX AL,或application都可以调用它。IL client与OpenMAX IL core进行交互,利用IL core加载和卸载组件、在组件间建立直接通信以及获得组件方法的入口。
core:相关平台的代码,具有将IL component载入主存储器的功能,当应用程序不再需要某组件时,IL core将负责把该组件从存储器卸去。一般来说,组件一旦载入存储器,IL core将不在参与应用程序与组件之间的通信。
端口(Port):组件的输入输出接口
组件(Component):OpenMax IL的单元,每一个组件实现一种功能。组件按照端口可分类为Source(只有一个输出端口)、Sink(只有一个输入端口)和Host组件(一个输入端口和一个输出端口),此外有一个Accelerator组件,它具有一个输入端口,调用了硬件的编解码器,加速主要体现在这个环节上。
隧道化(Tunneled):让两个组件直接连接的方式。通过隧道化可以将不同的组件的一个输入端口和一个输出端口连接到一起,在这种情况下,两个组件的处理过程合并,共同处理。尤其对于单输入和单输出的组件,两个组件将作为类似一个使用。
3. OpenMAX IL 接口
core API:负责动态加载和卸载组件,协助组件间通信。一旦加载组件,API 允许用户直接与组件进行通信,类似的,core API 允许用户在组件之间建立tunnel通信通道,一旦建立,core API 不再被需要,其通信直接发生在两个组件之间。
component API:在IL层,组件代表了独立的功能模块。一个组件可以是sources, sinks, codecs, filters, splitters, mixers, or any other data operator。各个组件的参数可以通过一组相关的数据结构,枚举类型和接口来设置或者获取。buffer状态,错误信息,以及其他的时间敏感信息会通过回调函数转发给应用程序。与组件进行数据的交换是通过端口(ports)完成的。 类似哦,组件间的tunnel通道也是通过将一个组件的输出端口连接到另一个组件的输入端口来建立的。
4. System 组件
OpenMAX IL 定义了三种通信方式:
1)Non-tunneled:用于client 与 component 之间交换data buffers;
2)Tunneling:用于组件之间互相交换data buffers的标准机制;
3)Proprietary communication:用于两个组件之间直接数据交换的专属机制,并且可以作为tunneling的备选机制。
openMAX IL的客户端,通过调用四个OpenMAX IL组件,实现了一个功能。四个组件分别是Source组件、Host组件、Accelerator组件和Sink组件。
- Source组件只有一个输出端口;
- Host组件有一个输入端口和一个输出端口;
- Accelerator组件具有一个输入端口,调用了硬件的编解码器,加速主要体现在这个环节上。Accelerator组件和Sink组件通过私有通讯方式在内部进行连接,没有经过明确的组件端口。
OpenMAL IL在使用的时候,其数据流也有不同的处理方式:既可以经由客户端,也可以不经由客户端。 图中,Source组件到Host组件的数据流就是经过客户端的;而Host组件到Accelerator组件的数据流就没有经过客户端,使用了隧道化的方式;Accelerator组件和Sink组件甚至可以使用私有的通讯方式。
OpenMAL IL的组件是OpenMax IL实现的核心内容,一个组件以输入、输出端口为接口,端口可以被连接到另一个组件上。外部对组件可以发送命令,还进行设置/获取参数、配置等内容。组件的端口可以包含缓冲区(Buffer)的队列。 组件的处理的核心内容是:通过输入端口消耗Buffer,通过输出端口填充Buffer,由此多组件相联接可以构成流式的处理。
5. Component profiles
OpenMAX IL 组件的功能被分成两种profiles:base profiles 和 interop profiles。
6. Component states
1)无效的数据会导致组件进入invalid状态;
2)在IDEL状态,组件应该获取了所有所需的静态资源;
3)在executing状态,组件不再接收buffer,而是进行处理数据;
4)在paused状态,组件维护一个buffer context,且不再处理数据和交换buffers;
7. Component 架构
OpenMAL IL中一个组件的结构如图:
组件的功能和其定义的端口类型密切相关,通常情况下:
只有一个输出端口的,为Source组件;只有一个输入端口的,为Sink组件;有多个输入端口,一个输出端口的为Mux组件;有一个输入端口,多个输出端口的为DeMux组件;输入输出端口各一个的组件为中间处理环节,这是最常见的组件。
端口具体支持的数据也有不同的类型。例如,对于一个输入、输出端口各一个组件,其输入端口使用MP3格式的数据,输出端口使用PCM格式的数据,那么这个组件就是一个MP3解码组件。
隧道化(Tunneled)是一个关于组件连接方式的概念。 通过隧道化可以将不同的组件的一个输入端口和一个输出端口连接到一起,在这种情况下,两个组件的处理过程合并,共同处理。尤其对于单输入和单输出的组件,两个组件将作为类似一个使用。
8. Communication behavior
Client与component之间的通信:
client通过 OMX_EmptyThisBuffer
来调用component的输入端口;
client通过 OMX_FillThisBuffer
来调用component的输出端口。
9. Tunneled buffer allocation
对于tunnel的两个端口,supplier端口会调用UseBuffer函数来要求邻接的端口来处理buffers;non-supplier端口会接受UseBuffer调用。Component需要遵循以下规则:
1)supplier端口都要提供buffers;
2)在端口上可靠的传输buffer配置;
3)通过OMX_EmptyThisBuffer调用将buffer从输出端口传递到另一component的输入端口;
4)通过OMX_Fill_This_Buffer调用将buffer从输入端口返回给component的输出端口。
10. Buffer payload
一般情况下,buffer中可用数据的起始点和范围由定义在buffer头中的 pBuffer,nOffset 和 nFilledLen 三个参数来决定。pBuffer指向buffer的起始地址;nOffset代表了buffer起始地址与实际可用数据地址之间的偏移量;nFilledLen表示buffer中连续可用的数据的大小。因此,buffer中可用数据的起始范围分别为pBuffer + nOffset 和 pBuffer + nOffset + nFilledLen 。
在buffer中数据的存放方式有三种:
1)每个buffer要么填满,要么部分填满;
2)每个buffer中存放的压缩数据都是以完整的帧为单位的;
3)每个buffer中只存放一帧的压缩数据。
前两种都要求解码器在解码之前对每帧数据进行解析,第三种情况则不需要解析。
11. Buffer flags and timestamps
Buffer flags 是存放在buffer中的表示特定属性的数据,比如数据流结束;
Timestamps 是以微秒为单位的存放在buffer中的数据,用来在播放时确定各buffer的播放时刻。
12. OMX IL 示例结构
标签:buffer,端口,IL,组件,OMX,输入,OpenMAX 来源: https://blog.csdn.net/houxiaoni01/article/details/117824147