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

posted @ 2008-10-07 16:54  quanben  阅读(338)  评论(0编辑  收藏  举报