转载: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堆和栈 简单的说值类型存放在堆栈上面,引 ...
随机推荐
- Windows Server 2012 R2的安装(GUI桌面版本)
镜像:cn_windows_server_2012_r2_x64_dvd_2707961.iso 1.将安装光盘插入服务器,开机会读取到Windows安装程序,点击下一步 2.点击现在安装 3 ...
- PL/SQL不安装Oracle连接,Oracle instantclient安装
================================ ©Copyright 蕃薯耀 2020-01-07 https://www.cnblogs.com/fanshuyao/ 第一步: 下 ...
- MRAM技术进入汽车应用
在整个地址空间范围内读写各种类型的数据.通常MRAM的操作和时序类似于32位微控制器的规范和时序.与DLFASH相比,当今的非易失性存储器可以接受MRAM设备的性能和吞吐量. 与当今的DFLASH相比 ...
- Excel开启宏以后保存是会提示安全警告,怎么取消
如果你用的(应该)是2007以上版本的话 请点左上角的EXCEL图标,EXCEL选项,信任中心,信任中心设置,个人信息选项,保存时从文件属性中删除个人信息前面的对号取消.确定就可以了. (补充:如果你 ...
- .Net Core程序最终只产生1个exe
1.用VS新建一个.Net Core 命令行程序,程序里面写什么都行,我的是这样的 2.打开程序包控制台,或者使用PowerShell等可以执行dotnet命令的工具,把你的.Net 程序发布(编译) ...
- Quartz.NET - 教程 5: 简单触发器
译者注: 目录在这 Quartz.NET 3.x 教程 原文在这 Lesson 5: SimpleTrigger 如果你需要在特定的时间点执行一次作业, 或者在特定的时间点执行一次作业, 然后在特定的 ...
- 我眼中的ASP.NET.MVC
MVC MVC全名 : Model View Controller ( Model-模型 View-视图 Controller-控制器)是一种经典的,经久不衰的,屹立不倒的软件设计框架.实现了业务逻 ...
- CF1230E Kamil and Making a Stream
题目大意是求 \(\sum_{v,fa,lca(v,fa)=fa}gcd(v \to fa)\) 容易发现 \(\gcd\) 只会变小,所以根据这玩意是从上到下的,每次暴力一下就可以了,\(\gcd\ ...
- Origin-作图相关
1.跨越缺失数据连接直线
- 进程无法连接到 Subscriber"XXXXXXX"
进程无法连接到 Subscriber“APP07”. 在订阅的机器上config 添加别名 APP07