OpenMAX大意(四) OpenMAX组件
OpenMAX组件基类在omx_base_component.c中定义。
1. 组件构造和析构
1) 构造函数 Constructor
基类构造函数为omx_base_component_Constructor
这是基于C方式的构造函数实现,其中openmaxStandComp->pComponentPrivate指针指向可能的私有数据。私有数据指针原型为omx_base_component_PrivateType,所有的组件数据继承基本以此为基础。
构造函数的下一个任务是设置有关数据结构,包括:
messageQueue 消息队列
messageSem 消息信号量
bMgmtSem 管理信号量
bStateSem 状态信号量
bufferMgmtThread 缓冲管理线程结构体
messageHandlerThread 消息处理线程结构体
随后加载基类的方法(如果派生类有自定义的方法则在派生类的构造函数加载),并设置一些基本的数据。
最后创建该组件消息处理函数的线程,该线程入口函数为compMessageHandlerFunction。
2) 析构函数 Destructor
基类析构函数为omx_base_component_Destructor。
2. 组件方法
以下组件方法,OpenMAX组件基类均提供了实现,其函数命名为下列方法名加上前缀"omx_base_component_"。
1) 组件操作相关方法
- GetComponentVersion
获取组件版本
- SendCommand
向组件发送消息
首先创建命令结构体,并做一些检查。
设置messageParam,即nParam参数。
设置messageType,有以下不同情形,然后分别进行准备:
> OMX_CommandStateSet
nParam为目标状态。这里需要做一些状态转换的准备工作:
对于从OMX_StateLoaded到OMX_StateIdle的转换,为每个端口的分配bBufferStateAllocated数组,其元素个数为该端口的缓冲数,并为该数组赋初值BUFFER_FREE;和pInternalBufferStorage数组,个数亦为缓冲数。这些数据结构的销毁在状态转换OMX_StateIdle -> OMX_StateLoaded的实施过程中进行。之所以要在此处做内存分配是因为应用层调用SendCommand函数返回后可能直接会进行相关的内存操作,如果等到实际状态转换时(DoStateSet)再进行分配就迟了。
以下过渡量设置对应相应的状态转换命令:
OMX_TransStateIdleToLoaded
OMX_TransStateLoadedToIdle -- 在Buffer management函数中作为被处理的条件
OMX_TransStateExecutingToIdle
> OMX_CommandFlush
冲刷命令
nParam为端口号,检查。
> OMX_CommandPortDisable
端口禁用
nParam为端口号,检查。
如果nParam为-1则禁用所有端口,否则禁用指定端口。操作放在messageHandler中进行。
> OMX_CommandPortEnable
端口使能
nParam为端口号,检查。
如果nParam为-1则使能所有端口,否则使能指定端口。操作放在messageHandler中进行。
> OMX_CommandMarkBuffer
标注缓冲
最后将消息装入消息队列,并提升信号量messageSem以激活compMessageHandlerFunction。
- GetParameter
获取组件参数
- SetParameter
设置组件参数
- GetConfig
获取组件配置
- SetConfig
设置组件配置
- GetExtensionIndex
获取组件扩展名索引
- GetState
获取组件状态
- SetCallbacks
设置回调函数
- ComponentDeInit
反初始化组件
- ComponentRoleEnum
组件角色枚举
- ComponentTunnelRequest
组件隧道请求
2) 缓冲相关方法
- AllocateBuffer
为指定端口分配缓冲
调用端口的Port_AllocateBuffer方法完成功能
- UseBuffer
为指定端口指定缓冲
调用端口的Port_UseBuffer方法完成功能
- UseEGLImage
未实现
- FreeBuffer
将指定端口的缓冲释放
调用端口的Port_FreeBuffer方法完成功能
- EmptyThisBuffer
命令组件消耗指定缓冲
首先检查端口正确性,如端口索引,以及该端口是否为输入缓冲,然后调用端口的Port_SendBufferFunction方法完成功能。
- FillThisBuffer
命令组件填充指定缓冲
首先检查端口正确性,如端口索引,以及该端口是否为输出缓冲,然后调用端口的Port_SendBufferFunction方法完成功能。
3) 状态和消息相关处理
- DoStateSet
实施状态转换。这是一个重要的功能函数,它规定了组件的默认行为。它本质上反映了OpenMAX组件状态转换自动机。
以下列出允许的状态转换和相应需要进行的工作:
> OMX_StateWaitForResources <-> OMX_StateLoaded
无操作
> OMX_StateWaitForResources -> OMX_StateIdle
无操作
> OMX_StateIdle -> OMX_StateLoaded
释放各端口。如果端口是Tunnel模式中的缓冲主动方(供应者,Supplier),则需要释放该端口缓冲;否则,如果端口使能需要挂起等待 pAllocSem信号量(缓冲释放)。最后将端口bPopulated置为FALSE。然后提升bMgmtSem信号量以激活缓冲管理线程,退出并销毁缓冲管理线程。最后销毁各端口上bBufferStateAllocated和pInternalBufferStorage数据结构。
> OMX_StateLoaded -> OMX_StateIdle
配置各端口。如果端口是Tunnel模式中的缓冲主动方,则需要为之分配缓冲;否则,如果端口使能,需要挂起等待pAllocSem信号量(缓冲分配),并且把端口bPopulated置为TRUE。然后创建缓冲管理线程,其入口函数为BufferMgmtFunction,从而建立组件处理操作的基础。
> OMX_StateExecuting -> OMX_StateIdle
调用端口的FlushProcessingBuffers方法冲刷各端口的数据。
> OMX_StateIdle -> OMX_StateExecuting
对于Tunnel模式中的缓冲主动方端口,对其上所有缓冲提升(up)pBufferSem信号量,并提升bMgmtSem信号量。
该转换涉及到过渡量transientState复位(在0.9.0中改进)到OMX_TransStateMax。
> OMX_StatePause -> OMX_StateIdle
脉冲(signal)bStateSem信号量以通知可能挂起在Pause状态的缓冲管理线程。
> OMX_StateExecuting -> OMX_StatePause
无操作
> OMX_StateIdle -> OMX_StatePause
无操作
> OMX_StatePause -> OMX_StateExecuting
脉冲(signal)bStateSem信号量以通知可能挂起在Pause状态的缓冲管理线程。
> ANY -> OMX_StateInvalid
提升bMgmtSem信号量以激活缓冲管理线程,退出并销毁缓冲管理线程。
- messageHandler
处理消息
主要包括以下消息了:
> OMX_CommandStateSet
首先调用组件的DoStateSet方法实施状态切换。
如果切换成功,则调用组件的事件处理回调函数EventHandler通知应用层状态切换完成;否则也调用该函数通知状态切换失败
> OMX_CommandFlush
实施缓冲冲刷
message->messageParam为端口号,如果为-1则调用端口FlushProcessingBuffers方法冲刷所有端口,并将所有端口的bIsPortFlushed置为TRUE;否则仅冲刷指定端口。如果冲刷失败则调用回调函数通知;如果成功则对每个完成个冲刷端口调用回调函数EventHandler通知应用层操作成功,以冲刷过的端口作为参数。
> OMX_CommandPortDisable
如果状态不是Loaded,则首先冲刷需要禁用的端口,然后调用端口Port_DisablePort方法禁用端口。最后以相似的策略通知应用层操作结果。
> OMX_CommandPortEnable
调用Port_EnablePort方法使能端口,并通知应用层操作结果。
> OMX_CommandMarkBuffer
将组件成员变量pMark设置为(OMX_MARKTYPE*)message->pCmdData。
3. 全局方法
+ compMessageHandlerFunction
该函数是一个阻塞于messageSem信号量的死循环,它从messageQueue中读出消息并调用组件的messageHandler方法想组件发送消息。
+ BufferMgmtFunction
该函数是组件数据处理的主线程函数,OpenMAX常用的Filter组件基类对其做了详细定义。
+ checkHeader
+ setHeader
+ omx_base_component_ParameterSanityCheck