摘要:本文简要介绍了OpenMax 的集成层,并阐述了其在Android上的实现和运行过程。

关键字:OMX, 多媒体框架, IL, Android, Stagefright

1、OpenMax 集成层介绍

OpenMax是一个多媒体应用程序的框架标准。它自上而下分为三层,Application Layer, Integration Layer和Development Layer。应用层规定了应用程序和多媒体中间层的标准接口,使应用程序的移植性更好。集成层定义了多媒体组件的接口,使得多媒体框架能以一种统一的方式访问多媒体Codec和组件,以便在嵌入式流媒体框架中快速集成加速编解码器。。开发层为Codec厂商和硬件厂商提供了一套API,使开发更加便捷。

图1 OpenMax的分层结构

OMX集成层由Client、Core、Component和Port组成,Client通过Core得到对应Component的Handle,而后通过命令直接和Component进行交互。每个Component至少有一个Port进行数据交互,如Decoder有一个输入Port接收码流,一个输出Port输出YUV序列。Component内部可能通过消息处理机制完成Client要求的任务。

图2 OMX IL层的组成

在Android中,OpenMax IL层,通常可以用于多媒体引擎的插件,Android2.2的多媒体引擎StageFright都可以使用OpenMax作为插件,主要用于编解码(Codec)处理。

在Android的框架层,定义了由Android封装的OpenMax接口,和标准的接口概念基本相同,使用C++类型的接口,并且使用了Android的Binder IPC机制实现了函数远程调用。Android封装OpenMax的接口被StageFright使用。

解码Component通过输入Port和输出Port来进行交互,可以通过和OMXCodec共享buffer来进行编解码。

图3 StageFright的OMX结构

2、OMX相关的类关系

StageFright的核心播放器AwesomePlayer中包含了sp<MediaSource>型的mVideoSource指针,初始化时指向OMXCodec的实际对象。OMXCodec使用了Binder机制,实现了远程函数调用,且函数调用模式于本地函数无异,其中IOMX作为接口类定义了OMX的大部分接口函数。OMX的具体实现时,OMXMaster类用于管理OMX的插件,OMXNodeInstance类代表OMX的具体实例,完成和Component的调用和交互,内部类CallbackDispatcher是一个主动类,它用于调度处理回调函数传回的消息。OMXNodeInstance和CallbackDispatcher一一对应,协同工作,完成不同实例的消息处理。

图4 OMX相关类关系图

OMXNodeInstance类中最重要的几个函数为:

allocateBuffer: Client通过调用此函数让Component分配Buffer。

useBuffer: Client通过此函数将已分配好的Buffer传给Component,让其使用。

freeBuffer: Client通过调用此函数让Component释放allocateBuffer()分配的Buffer。

fillBuffer: Client通过调用此函数传递空的Buffer给Component,让其将处理好的数据填入其中。此函数会调用OMX标准接口OMX_FillThisBuffer()。

emptyBuffer: Client通过调用此函数传递输入Buffer给Component,让其读取其中的数据进行编解码等处理。此函数会调用OMX标准接口OMX_ EmptyThisBuffer ()。

OnEmptyBufferDone: Component完成对输入buffer的读取后,调用此回调函数,向Client发送EmptyBufferDone消息。

OnFillBufferDone: Component完成相应处理将输出数据填入输出Buffer后,调用此回调函数,向Client发送FillBufferDone消息。

以Decoder为例,说明OMX Codec执行解码的过程,

图5 OMX Codec解码序列图

OMXCodec使用emptyBuffer()函数(IL层中为OMX_EmptyThisBuffer()传递未解码的buffer给component,component收到该命令后会读取input port buffer中的数据,将其组装成帧进行解码,读取buffer中的数据完成后会调用EmptyBufferDone通知OMXCodec。

Compoment使用EmptyBufferDone消息通知OMXCodec已完成input buffer的读取, 具体的实现是通过调用回调函数OnEmptyBufferDone()实现的。OMXCodec收到该命令后会通过mVideoTrack读取新的视频码流到input port的buffer中,并调用OMX_EmptyThisBuffer通知component。

OMXCodec使用OMX_FillThisBuffer传递空的bffer给component用于存储解码后的帧,Component收到该命令后将解码好的帧数据复制到该buffer上,然后调用FillBufferDone通知OMXCodec。

Compoment使用FillBufferDone通知OMXCodec已完成output port buffer的填充,具体的实现是通过调用回调函数OnFillBufferDone()实现的。OMXCodec收到该命令后将解码好的帧存入可显示队列中,AwesomePlayer调用OMXCodec::read()函数读出可显示队列的对头送给Renderer完成颜色转换等操作再传递给mISurface进行图像绘制,同时Render调用release()函数,其中的SignalBufferDone()会用OMX_FillThisBuffer通知component有空的buffer可填充。

OpenMax在Android上的实现相关推荐

  1. android4.0 音频框架 opensl openmax,适用于android的OpenSL ES指南-面向Android的OpenSL ES

    本文将详细说明NDK中OpenSL ES™的实现与OpenSL ES 1.0.1参考规范的不同.在使用规范中的示例代码时,可能需要修改它以在Android上工作. 除非另有说明,所有功能都可以在And ...

  2. android上传本地图片到服务器上,Android使用post方式上传图片到服务器的方法

    本文实例讲述了Android使用post方式上传图片到服务器的方法.分享给大家供大家参考,具体如下: /** * 上传文件到服务器类 * * @author tom */ public class U ...

  3. 构建node.js基础镜像_在Android上构建Node.js应用程序

    构建node.js基础镜像 by Aurélien Giraud 通过AurélienGiraud 在Android上构建Node.js应用程序-第1部分:Termux,Vim和Node.js (Bu ...

  4. 如何为Android上的产品设计一款合适的图标

    如 果你已经完成了你的app,你一定会马上向其它人宣布这件事情.但是你需要注意一个很重要的问题,那就是app的图标.你的图标可能在项目启动之 前就已经设计好了,但我不喜欢这样,如果app没有完成实际上 ...

  5. Android上的MVP:如何组织显示层的内容

    MVP(Model View Presenter)模式是著名的MVC(Model View Controller)模式的一个演化版本,目前它在Android应用开发中越来越重要了,大家也都在讨论关于M ...

  6. android上的i-jetty (1)环境搭建

    android上的i-jetty (1)环境搭建 android ftp swiftp  http://code.google.com/p/swiftp/ 介绍下如果把android设备作为一个web ...

  7. 在Android上实现HttpServer

    本文讲的是在Android上实现HttpServer,在最近的项目中因为要用Android作为一个服务器去做一个实时接收数据的功能,所以这个时候就要去做一个Android本地的微型服务器. 那么此时我 ...

  8. 安卓平台运行python_在 android 上运行 python 的方法

    android官方目前没有支持在android设备运行python,但是网上有一些项目组做了这个事情:http://geeknizer.com/install-run-python-apps-scri ...

  9. android heic图片,如何在Windows / MacOS / Android上打開HEIC照片

    HEIC顧名思義是指高效率圖像文件格式.它是種更好儲存照片的方式,因為跟JPEG格式相比,它的照片容量較小且能保持高畫質的照片. 使用HEIC有很多好處.以下是HEIC比JPEG更好的原因. HEIC ...

最新文章

  1. python自动化办公脚本下载-python自动化办公:文件篇(自动整理文件,一键完成)...
  2. Dockerfile镜像的制作
  3. large_IPYi_09ef000018c21215
  4. 嫦娥奔月(KMP,找循环节)及其扩展KMP
  5. 对高并发流量控制的一点思考
  6. 3-pycharm找不到库的解决办法
  7. cesium billboard 设置距离控制可见度
  8. 傲梦python笔试题_python笔试题
  9. codevs1018 单词接龙(DFS)
  10. 为何身为程序员的你,不选择开源?
  11. string 常用函数
  12. 毕向东的Java基础视频教程的学习,作为java基础的基础学习视频
  13. C语言自学之路九(用C语言编写小游戏-扫雷)
  14. 浏览器内核学习笔记一
  15. 实测:熊猫烧香考验五大杀毒软件
  16. 相机参数(焦距)初始化对三维重建过程的影响
  17. Objective-C简介
  18. Octave 安装步骤(仅供记录)
  19. 字符数组与字符串的转换
  20. 谷歌弃用20多年的OKR,再创内卷神器?

热门文章

  1. 在CSDN的第一篇文章
  2. uniapp跳转第三方地图导航
  3. 【K3s】第3篇 解决K3s状态一直是ContainerCreating
  4. Unix系统 - 存储管理中的文件系统
  5. 解决laravel Use of undefined constant JSON_INVALID_UTF8_SUBSTITUTE - assumed ‘JSON_INVAL
  6. 关于 ExpandableListView 的列子
  7. linux mplayer 一键安装,MPlayer Linux安装教程
  8. 安卓 linux 信令,呼叫信令
  9. Unity学习笔记:监听函数有什么卵用?(似乎就是从一件事过渡到另一件事?)
  10. 考研复试_英语面试_必备的30个问题