一、OpenMax相关概念
OpenMax存在背景—为多媒体硬解方案提供标准提升移植效率
随着消费者对视频、音频、语音和 3D 等应用程序在智能手机、音频和视频媒体播放器和游戏机等各种平台上的改进功能的需求不断增长,多媒体硬件平台出现了各种解决方案加速多媒体应用程序。(如具:有特定多媒体扩展功能的通用处理器、低级硬件加速器,包括 DSP 在内的多处理器架构、专用硬件视频解码器) 所有这些架构变体的主要挑战之一是开发高效的代码。尽管通常会提供编译器,但很少能从高级编程语言中挖掘整个架构的全部潜力。结果是应用程序的很大一部分通常是用汇编语言编写的,专门针对硬件平台。不同多媒体硬件解决方案的激增意味着必须针对移植到的每个新平台重新编写和优化软件。OpenMAX为多媒体应用程序定义一套标准的、开放的应用程序编程接口 (API)。该开放标准的目标是降低将多媒体软件移植到新处理器和架构的成本和复杂性。
OpenMax概念—一个C语言实现的跨平台开放多媒体的软件抽象层
OpenMAX是一个多媒体应用程序的标准。由NVIDIA公司和Khronos?在2006年推出。 它是无授权费的、跨平台的C语言程序接口序列,这些接口对音频、视频、静态图片的常用操作进行封装。 它包括三层,分别是应用层(AI)、集成层(IL)和开发层(DL)。其中IL层已经成为了事实上的多媒体框架标准。 嵌入式处理器或者多媒体编解码模块的硬件生产者,通常提供标准的OpenMax IL层的软件接口,这样软件的开发者就可以基于这个层次的标准化接口进行多媒体程序的开发。
OpenMax与FFmpeg、MediaCodec、Gstreamer的适配
正如上面所说,openmax给各种硬解码方案提供了一套统一的抽象接口,各种芯片厂商根据各自的私有硬件解码方案对接openmax实现,然后ffmpeg(常见的视频软解码开源库)、MediaCodec(安卓自带的视频编解码接口,代表播放器是ExoPlayer)、Gstreamer(常用开源流媒体应用框架)都已经适配了openmax,可以通过配置打开与openmax的对接。然后再针对性的识别对接方案中如一些性能问题进行方案优化调整 问题修复,整个软硬件解码对接就完成了。
二、OpenMax 整体介绍
OpenMax三层架构简介—AL层/IL层/DL层
OpenMAX自上而下分为三个层次:OpenMAX AL,OpenMAX IL和OpenMAX DL。 Application Layer:应用和多媒体中间层的标准接口,使得应用在多媒体接口上具有了可移植性。(实际很少人会直接用这一层构建播放器,或者 使用api来播放文件)。 Integration Layer:用作嵌入式和/或移动设备中使用的音频、视频和图像编解码器的低级接口。使应用程序和媒体框架能够以统一的方式与多媒体编解码器和支持组件(即源和接收器)交互。编解码器本身可以是硬件或软件的任意组合,并且对用户完全透明。主要目标是使用专门的功能库为编解码器提供一定程度的系统抽象,以解决许多截然不同的媒体系统之间的可移植性问题。(IL层已经成为了事实上的多媒体框架标准,大多数设备厂商都会进行适配) Development Layer:包含一组全面的音频、视频和图像功能API,这些功能可以由芯片供应商在新处理器上实现和优化,然后由编解码器供应商用于编码各种编解码器功能。它包括音频信号处理功能(例如 FFT 和滤波器)、图像处理基元(例如色彩空间转换)和视频处理基元,以支持编解码器(例如 MPEG-4、H.264、MP3、AAC 和 JPEG)的优化实施。。(目的是指导硬件设计,但是实际上也很少参考使用,各家都是私有方案)
OpenMax IL层设计目标、主要特性、设计理念
1、OpenMax的IL层的核心目标:提升媒体解码在不同平台上的的可移植性; 针对硬件和软件架构进行抽象,每一种解码器及其相关转换都被封装到组件compontent内部;OpenMAX IL API 允许用户去加载,控制,连接以及卸载各独立的组件compontent。这种极具灵活性的内核结构使得 Intergration Layer 能够很容易的实现几乎所有的多媒体应用情形,并且能够很好的与现有的基于图像的多媒体框架相结合。 2、OpenMax基于可移植性的主要特性: 基于组件compoment化的核心API接口设计,保持灵活性。 能方便的新增集成新解码器codec的能力。 同时给Khronos Group和供应商提供针对音频、视频、图像领域良好扩展性; 可以被实现为静态库 或者 动态链接库。 提供对父平台(如多媒体frameworks)的关键特性和配置可选项。 保持client和解码器codec、解码器codec之间通信的简易性; 3、OpenMax的设计理念—媒体框架的抽象/异步处理/组件组合 : 为了提升多媒体的可移植性,同时又能兼顾对接当前设备媒体多样性方案,OpenMAX IL相对这些方案抽象到更高的层次,通常意味着一个多媒体框架。OpenMax IL层的接口来源于媒体框架层次,设计实现上 要更容易集成新的解码器,其他比如文件处理也可以进行方便添加,考虑到各种可扩展性。同时设计上使用高度异步通信方式,者可以是处理通过一个或多个执行线程、或 专用硬件IP(硬件加速),通过多组件链接处理的方式 也给了架构更大的灵活性和效率。
三、OpenMAX IL 内部设计概念 与接口API
Core组件管理 与 Component组件功能
OpenMAX IL层 API主要分为Core API与Component API: 1、Core:负责载卸载组件、组件间通信。 用于动态加载和卸载组件Component和用于促进组件通信。一旦用户把组件之间建立起链接通道,就不再需要通过CoreAPI来对组件间进行通信。 Component 介绍—各类数据处理功能模块 2、Component 组件代表各个处理数据的功能模块:1)从类型上可以是源sources、接收器sinks、编解码器codecs、过滤器filters、分离器splitters、混频器mixers或任何其他数据控制模块。 2)从实现上看,组件可以是一个独立硬件处理IP、一个软件解码器、一个独立的处理器 或者 他们之间的组合。
Component组件的架构设计
从组件的角度看,除了配置参数Set/Get,还要理解如下回调、端口等概念。 1)回调函数callback functions:组件buffer缓冲区状态、错误信息、和一些对时间敏感的信息,都是通过回调函数的方式通知上层应用。这种设计方式给与系统异步特性支持。 2)端口ports:组件之间的数据通信是通道称为端口port,端口代表组件到数据流的连接。用户可以通过组件的input port送入数据,从组件的output port接受数据。同样的,组件之间也可以通过格式类似的input port和output port对接来传输数据。
Component组件的状态机state管理
每个组件都有一个状态机管理内部的状态切换,每个组件首先被认为是卸载的,组件被CoreAPI进行加载,然后在通信过程中与其他状态转换,当遇到无效数据时组件可能进入Invalid无效状态。不同的状态下组件的行为操作存在差异和限制。 如下是更细节的切换流程:
Component组件的buffer轮转调度管理
参考OMX_Component.h中接口。 通过EmptyThisBuffer传递未解码的buffer给component,component收到该命令后会去读取input port buffer中的数据,将其组装为帧之后进行解码,buffer处理完成后会通过EmptyBufferDone通知上层输入使用完成,上层收到命令可以继续送输入帧流程。输出buffer方面,通过FillThisBuffer传递填充输出的空buffer给component,component在解码之后通过FillBufferDone通知上层输出填写完成,上层可以继续送待填充的输出帧流程。
Component组件的接口简介(待更新)
OMX_Init/OMX_Deinit:组件的初始化/销毁。 OMX_GetHandle:获取组件的实例化对象(句柄)。 OMX_SendCommand:向指定的组件发送命令。 OMX_CommandStateSet:设置指定组件的状态。 OMX_Get/SetParameter:获取/设置指定组件的参数。 OMX_Get/SetConfig:获取/设置指定组件的配置。 OMX_EmptyThisBuffer:像指定组件传递buffer数据,传递buffer数据到组件的输入端口。 OMX_FillThisBuffer:像指定组件还回buffer数据,传递buffer数据到组件的输出端口。 OMX_SetupTunnel:在两个组件之间建立连接(tunnel)。
四、新增一个Component组件流程(待更新)
五、Android MediaCodec对接OpenMax分析(待更新)
参考
官网:https://www.khronos.org/openmax/ 官网IL层详细文档:https://www.khronos.org/files/openmax_il_spec_1_0.pdf https://www.cnblogs.com/dyufei/p/8018520.html https://yellowmax.blog.csdn.net/article/details/78997854
|