转载:openmax基本概念
https://yellowmax.blog.csdn.net/article/details/78080168
https://yellowmax.blog.csdn.net/article/details/78242464
https://yellowmax.blog.csdn.net/article/details/78997854
https://wenku.baidu.com/view/18472c1387c24028915fc3e9.html (OpenMax_IL_Bellagio_代码分析_-_台湾清华RTlab实验室_OpenMax_IL_代码分析)
组件

从上图可以看出组件内部大概有这么几个组成部分:
1.组件句柄(组件的描述符,类似文件描述符一样)。
2.配置相关的结构体方法(set/get parameter/configuration)。
3.命令队列。
4.端口(port)。
5.端口的buffer管理。
6.组件事件句柄(用于向IL Client发送事件)。
7.buffer发送模块。
IL Clinet
顾名思义,IL Client就是指IL的客户端,可以在上图里面看到有IL Clinet的字样,对于组件来说,IL Client就是组件的管理者,Client通过组件内部提供的相关回调函数来对组件进行管理,应用程序可以调用Client的代码来操作组件,包括设置组件的状态、添加一个组件、销毁一个组件等等。
IL Client对组件的操作流程大概如下:

端口
1.PORT(端口)是用来干什么的?
PORT充当了组件之间数据交流的代理人(驻外大使馆),通过PORT端口,两个组件之间可以互相传递数据,同时也可以进行其它的一些控制。
2.如何通过PORT(端口)来交换数据?
组件之间是可以进行绑定的,在组件绑定完成之后,绑定组件的双方PORT口里面就存放了绑定双方组件的实例化组件句柄以及绑定端口信息等数据,然后通过PORT来调用绑定组件的buffer相关的回调函数,这样就可以实现组件之间互相调用对方的内部方法来实现数据交换(包括数据发送与数据回收)。
3.如何定义一个PORT?
一个PORT的定义需要三个结构体来完成,在OpenMAX标准下,这三个结构体分别是:OMX_PARAM_PORTDEFINITIONTYPE,OMX_VIDEO_PARAM_PORTFORMATTYPE,OMX_PARAM_BUFFERSUPPLIERTYPE,其中第二个结构体是跟组件的PORT端口类型有关的,分别有video、image、audio等类型,这里给出的就是video类型。这三个结构体描述囊括了了PORT类型,端口号,COMP句柄等信息。
4.如何通过PORT建立连接?
调用组件的内部方法进行协商连接(协商建立外交),具体到OpenMAX里面就是OMX_SetupTunnel这个宏定义,在绑定组件的时候需要调用双方组件的这个宏定义,最终可以回调到双方组件内部的一个ComponentTunnelRequest方法来完成组件的绑定(该方法的具体代码内容需要自行实现)。

两个组件通过port进行相互链接,然后组件内部自行协调进行数据交流。整个链接过程是由组件的管理者连续调用两个组件的链接函数完成的,组件的链接函数里面会判断两个port是否适合链接,如果适合的话就将对方port以及COMP的句柄信息记录下来,存放到一个port结构体描述当中,这样的话两个组件就可以通过port来进行通信以及数据传输了。
组件的事件句柄
组件在初始化的时候会向IL Client注册一个OMX_CALLBACKTYPE类型的回调函数集
里面的三个回调成员由IL Client实现,在组件内部可以通过某种事件触发这三种回调成员的回调,比如EventHandler回调成员就会在组件状态转换完成的时候被回调,其余两个则会在EmptyBuffer,FillThisBuffer操作完成的时候被调用,利用这几个回调函数,IL Client可以接收来自于组件内部的若干消息事件,从而达到某种同步以及接收组件的反馈。
buffer发送模块
1.tunnel模式

由图中可以看出,如果组件A是数据的提供者,那么完整的一帧数据传递就是:
1.组件A调用组件B(通过PORT端口实现)的OMX_EmptyThisBuffer(B, pBuffer)宏来实现数据从A传递到B。
2.组件B调用组件A(通过PORT端口实现)的OMX_FillThisBuffer(A, pBuffer)宏来完成数据从B到A的还回过程。
2.Non-tunnel模式

在该模式下,数据传递的双方变为IL Client与组件了,整个过程变成了:
1.IL Client通过OMX_FillThisBuffer(pHandle,1,pBufferOut)向组件A的Output端口提供一个空的buffer结构体以待填充,该宏是通过IL Core来最终完成对A组件的FillThisBuffer回调方法的调用的。
2.然后IL Client向组件A传递一个pBufferIn数据,这时组件A可以对pBufferIn内的buffer数据进行处理,然后处理完毕之后生成的新的buffer数据填充到上一步接收到的空pBufferOut的buffer结构体里。
3.等待组件A将pBufferOut里的buffer填充完毕,组件A就会调用OMX_FillBufferDone(pBufferOut)方法来通知IL Client接收处理后的数据。
4.IL Client数据处理完毕之后就会再次调用OMX_FillThisBuffer(pHandle,1,pBufferOut)来还回buffer到Output列表等待再次填充。
5.组件A处理完接收到的buffer数据之后就会调用OMX_EmptyBufferDone(pBufferIn)方法来通知IL Client,说明组件A已完成接收buffer的数据处理。
组件的状态转换
1.组件状态转换有什么作用?
状态转换用于控制组件运行、暂停、恢复、销毁等等。多个组件同时运行的时候状态转换就可以用来进行多组件之间的数据同步,协调组件之间的工作节奏。
2.由谁来进行状态转换控制,如何去实现控制
状态转换一般是由IL Client调用需要控制的组件的SendCommand来进行状态转换命令的发送,Cmd参数填充OMX_CommandStateSet枚举成员,nParam1参数填充需要转换的命令。当然除了IL Client的控制,组件内部也可能会主动给产生一些状态转换的命令,比如在组件发生严重错误的时候,此时组件内部就需要主动转入Invalid状态。组件内部需要实现OMX_CommandStateSet命令的获取与解析,通常在组件的内部线程里面完成,在接收到该命令之后,组件内部线程需要根据命令指定的状态进行相关的动作。
3.有哪些状态,分别对应什么场景
组件内部有6种状态,分别对应如下:
OMX_StateLoaded:该状态在组件被OMX_GetHandle调用初始化之后就转入,此时相关的buffer资源还没有被分配,IL Client可以使用OMX_SetParameter函数回调来进行参数的设定,使用OMX_SetupTunnel函数进行组件之间的绑定操作,最后控制组件从该状态转入OMX_StateIdle或者OMX_StateWaitForResources状态,后者是在组件尝试分配相关的buffer资源并转入OMX_StateIdle状态失败的时候才转入。
OMX_StateIdle:表明组件所有的资源都已经准备好了,正等待正式运行,该状态下,组件持有buffer,但是不传输也不处理buffer。当组件从OMX_StateExecuting或者OMX_StatePause状态转入该状态时需要归还所有处理完毕的buffer到buffer提供者。
OMX_StateExecuting:该状态下,组件持有buffer,传输同时处理buffer。此时组件应该接受其它组件对该组件的OMX_EmptyThisBuffer与OMX_FillThisBuffer函数回调,同时在非绑定的情况下使用EmptyBufferDone与FillBufferDone来归还Empty以及full buffer。绑定情况下就使用OMX_FillThisBuffer与OMX_EmptyThisBuffer来进行buffer的传递。
OMX_StatePause:该状态下,组件持有buffer,不传输也不理buffer,但是组件不必归还buffer到buffer的提供者。为了避免丢失数据,此时组件可以选择将接收到的数据存放到自己的buffer队列里面,但是不进一步传输也不去处理,当然也可以选择不去存放,这跟组件的具体类型与功能有关系。
OMX_StateWaitForResources:顾名思义,在该状态下,组件正在等待资源被分配并变得可用。通常情况下该状态由组件自己主动转入,原因前面说过,是因为资源分配失败导致。
OMX_StateInvalid:该状态是在组件发生不可修复的错误时转入,此时组件需要产生一个事件,类型为OMX_ErrorEvent,值为OMX_ErrorInvalidState,最后转入OMX_StateInvalid状态,当IL Client接收到该消息的时候就需要调用OMX_FreeHandle来释放所有组件持有的资源。
组件之间的状态转换图如下:
转载:openmax基本概念的更多相关文章
- [转载]oracle游标概念讲解
原文URL:http://www.2cto.com/database/201203/122387.html ORACLE游标概念讲解 什么是游标? ①从表中检索出结果集,从中每次指向一条记录进行交互 ...
- [转载]hashmap hashtable 的区别
Hashtable 和 HashMap 做为 Map 的基本特性 两者都实现了Map接口,基本特性相同 - 对同一个Key,只会有一个对应的value值存在 - 如 ...
- 《机器学习实战》——k-近邻算法Python实现问题记录(转载)
py2.7 : <机器学习实战> k-近邻算法 11.19 更新完毕 原文链接 <机器学习实战>第二章k-近邻算法,自己实现时遇到的问题,以及解决方法.做个记录. 1.写一个k ...
- iOS沙盒机制介绍,Block 的介绍
一.iOS沙盒机制介绍 (转载) 1)概念:每个ios应用都有自己的应用沙盒,应用沙盒就是文件系统目录,与其他应用放入文件 系统隔离,ios系统不允许访问 其他应用的应用沙盒,但在ios8中已经开放访 ...
- Java 集合系列 11 hashmap 和 hashtable 的区别
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- 我的Spark SQL单元测试实践
最近加入一个Spark项目,作为临时的开发人员协助进行开发工作.该项目中不存在测试的概念,开发人员按需求进行编码工作后,直接向生产系统部署,再由需求的提出者在生产系统检验程序运行结果的正确性.在这种原 ...
- IEnumerator<TItem>和IEnumerator Java 抽象类和普通类、接口的区别——看完你就顿悟了
IEnumerable 其原型至少可以说有15年历史,或者更长,它是通过 IEnumerator 来定义的,而后者中使用装箱的 object 方式来定义,也就是弱类型的.弱类型不但会有性能问题,最主要 ...
- (转)hashmap hashtable 的区别 Hash table 内部的数据结构
转自:http://www.cnblogs.com/carbs/archive/2012/07/04/2576995.html Hashtable 和 HashMap 做为 Map 的基本特性 两者都 ...
- 转载文章----C#基础概念
转载地址:http://www.cnblogs.com/zhouzhou-aspnet/articles/2591596.html 1.值类型和引用类型 1.1堆和栈 简单的说值类型存放在堆栈上面,引 ...
随机推荐
- webapi+Quartz.NET解决若干定时程序同时运行的问题
项目现状: 有若干定时程序需要自启动运行,为了简便程序部署等问题,采取这种办法把定时程序集中管理到webapi中跟随api发布 代码架构介绍: 新建一个类库,类库引用Quartz(Quartz.2.3 ...
- jSon和Ajax登录功能,ajax数据交互案例
ajax实例,检测用户与注册 检测用户名是否被占用: 在用户填写完用户名之后,ajax会异步向服务器发送请求,判断用户名是否存在 首先写好静态页面: index.html <!DOCTYPE h ...
- Android Binder实现浅析-Binder驱动
简介 Android是如何实现跨进程通信的,大家熟悉的Binder是什么,怎么设计的,进程间的数据如何发送接收的.本文将以及解析,并对Binder驱动实现.Native层实现.Java层实现三块做一个 ...
- Android5.0和Android6.0适配
gradle配置项 compileSdkVersion 用哪个 Android SDK 版本编译你的应用.因此我们强烈推荐总是使用最新的 SDK 进行编译.在现有代码上使用新的编译检查可以获得很多好处 ...
- Oracle行结果合计的实现
Oracle行结果合计的实现,主要应用于日期结果的集计,下面是具体的实现代码. With AA as ( select 'A' tNo , 10 B from dual union select ' ...
- mybatis实体为什么要提供一个无参的构造函数
提问:Mybatis查询结果映射到实体类的时候,实体类为什么必须有一个空的构造函数? 类中如果没有构造函数,隐藏是无参构造函数,方便实体类需要通过Mybatis进行动态反射生成.如果实体类中一旦声明构 ...
- .NET CORE(C#) WPF 重新设计Instagram
微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. .NET CORE(C#) WPF 重新设计Instagram 阅读导航 本文背景 代码实现 ...
- javaSE学习笔记(17)---锁
javaSE学习笔记(17)---锁 Java提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率.本文旨在对锁相关源码(本文中的源码来自JDK 8).使用场景进行举例,为读 ...
- 记录zabbix4.0升级4.2
系统环境 [root@localhost ~]# cat /etc/redhat-release CentOS release 6.9 (Final) 官方网站 官方文档升级其实很简单如果 ...
- day 12 函数
函数 函数的定义和调用 def 函数名(形参): 函数体 return 返回值 调用 函数名(实参) 站在形参的角度上: 位置参数, *args, 默认参数(陷阱), 关键字参数, **kwargs ...