Chinaunix首页 | 论坛 | 博客
  • 博客访问: 51899
  • 博文数量: 50
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-30 20:59
文章分类

全部博文(50)

文章存档

2015年(9)

2014年(41)

我的朋友

分类: Android平台

2014-07-25 14:13:20

OpenMax IL: component 基础知识

OpenMax IL 有四个部分组成:        
1.客户端(Client):OpenMax IL的调用者
2.组件(Component):OpenMax IL的单元,每一个组件实现一种功能
3.端口(Port):组件的输入输出接口
4.隧道化(Tunneled):让两个组件直接连接的方式
OpenMax IL 中重要的组成部分是component,component是OpenMax IL实现的核心内容,一个组件以输入、输出端口为接口,端口可以被连接到另一个组件上。外部对组件可以发送命令,还进行设置/获取参数、配置等内容。component的端口可以包含缓冲区(Buffer)的队列。
OpenMAL IL的客户端,通过调用四个OpenMAL IL组件,实现了一个功能。四个组件分别是Source组件、Host组件、Accelerator组件和Sink组件。Source组件只有一个输出端口;而Host组件有一个输入端口和一个输出端口;Accelerator组件具有一个输入端口,调用了硬件的编解码器,加速主要体现在这个环节上。Accelerator组件和Sink组件通过私有通讯方式在内部进行连接,没有经过明确的组件端口。如下图

组件的处理的核心内容是:通过输入端口消耗Buffer,通过输出端口填充Buffer,由此多组件相联接可以构成流式的处理。
component state有如下,具体定义在OMX_Core.h
具体在以下目录:hardware\ti\omap4xxx\domx\omx_core\inc\OMX_Core.h
  1. /** The OMX_STATETYPE enumeration is used to indicate or change the component
  2.  * state. This enumeration reflects the current state of the component when
  3.  * used with the OMX_GetState macro or becomes the parameter in a state change
  4.  * command when used with the OMX_SendCommand macro.
  5.  *
  6.  * The component will be in the Loaded state after the component is initially
  7.  * loaded into memory. In the Loaded state, the component is not allowed to
  8.  * allocate or hold resources other than to build it's internal parameter
  9.  * and configuration tables. The application will send one or more
  10.  * SetParameters/GetParameters and SetConfig/GetConfig commands to the
  11.  * component and the component will record each of these parameter and
  12.  * configuration changes for use later. When the application sends the
  13.  * Idle command, the component will acquire the resources needed for the
  14.  * specified configuration and will transition to the idle state if the
  15.  * allocation is successful. If the component cannot successfully
  16.  * transition to the idle state for any reason, the state of the component
  17.  * shall be fully rolled back to the Loaded state (e.g. all allocated 
  18.  * resources shall be released). When the component receives the command
  19.  * to go to the Executing state, it shall begin processing buffers by
  20.  * sending all input buffers it holds to the application. While
  21.  * the component is in the Idle state, the application may also send the
  22.  * Pause command. If the component receives the pause command while in the
  23.  * Idle state, the component shall send all input buffers it holds to the 
  24.  * application, but shall not begin processing buffers. This will allow the
  25.  * application to prefill buffers.
  26.  * 
  27.  * @ingroup comp
  28.  */

  29. typedef enum OMX_STATETYPE
  30. {
  31.     OMX_StateInvalid, /**< component has detected that it's internal data 
  32.                                 structures are corrupted to the point that
  33.                                 it cannot determine it's state properly */
  34.     OMX_StateLoaded, /**< component has been loaded but has not completed
  35.                                 initialization. The OMX_SetParameter macro
  36.                                 and the OMX_GetParameter macro are the only 
  37.                                 valid macros allowed to be sent to the 
  38.                                 component in this state. */
  39.     OMX_StateIdle, /**< component initialization has been completed
  40.                                 successfully and the component is ready to
  41.                                 to start. */
  42.     OMX_StateExecuting, /**< component has accepted the start command and
  43.                                 is processing data (if data is available) */
  44.     OMX_StatePause, /**< component has received pause command */
  45.     OMX_StateWaitForResources, /**< component is waiting for resources, either after 
  46.                                 preemption or before it gets the resources requested.
  47.                                 See specification for complete details. */
  48.     OMX_StateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
  49.     OMX_StateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
  50.     OMX_StateMax = 0X7FFFFFFF
  51. } OMX_STATETYPE;
component在LOADER状态下,只能建立它本身一些属性和配置信息,客户端能做什么呢?客户端可以发送 SetParameters/GetParameters and SetConfig/GetConfig这些command给component,以便以后component记录下这些parameter和configuration的变化。
在IDLE状态下,就可以分得buffer之类的资源,但是不能操作这些buffer直到component处于Executing状态下。
component state 如何转换呢?
一般change state可以通过OMX_SendCommand的方式通知给component,格式如下:
OMX_SendCommand(  hComponent, Cmd,mParam,pCmdData)
  1. /** Send a command to the component. This call is a non-blocking call.
  2.     The component should check the parameters and then queue the command
  3.     to the component thread to be executed. The component thread shall 
  4.     send the EventHandler() callback at the conclusion of the command. 
  5.     This macro will go directly from the application to the component (via
  6.     a core macro). The component will return from this call within 5 msec.
  7.     
  8.     When the command is "OMX_CommandStateSet" the component will queue a
  9.     state transition to the new state idenfied in nParam.
  10.     
  11.     When the command is "OMX_CommandFlush", to flush a port's buffer queues,
  12.     the command will force the component to return all buffers NOT CURRENTLY 
  13.     BEING PROCESSED to the application, in the order in which the buffers 
  14.     were received.
  15.     
  16.     When the command is "OMX_CommandPortDisable" or 
  17.     "OMX_CommandPortEnable", the component's port (given by the value of
  18.     nParam) will be stopped or restarted. 
  19.     
  20.     When the command "OMX_CommandMarkBuffer" is used to mark a buffer, the
  21.     pCmdData will point to a OMX_MARKTYPE structure containing the component
  22.     handle of the component to examine the buffer chain for the mark. nParam1
  23.     contains the index of the port on which the buffer mark is applied.

  24.     Specification text for more details. 
  25.     
  26.     @param [in] hComponent
  27.         handle of component to execute the command
  28.     @param [in] Cmd
  29.         Command for the component to execute
  30.     @param [in] nParam
  31.         Parameter for the command to be executed. When Cmd has the value 
  32.         OMX_CommandStateSet, value is a member of OMX_STATETYPE. When Cmd has 
  33.         the value OMX_CommandFlush, value of nParam indicates which port(s) 
  34.         to flush. -is used to flush all ports a single port index will 
  35.         only flush that port. When Cmd has the value "OMX_CommandPortDisable"
  36.         or "OMX_CommandPortEnable", the component's port is given by 
  37.         the value of nParam. When Cmd has the value "OMX_CommandMarkBuffer"
  38.         the components pot is given by the value of nParam.
  39.     @param [in] pCmdData
  40.         Parameter pointing to the OMX_MARKTYPE structure when Cmd has the value
  41.         "OMX_CommandMarkBuffer". 
  42.     @return OMX_ERRORTYPE
  43.         If the command successfully executes, the return code will be
  44.         OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
  45.     @ingroup comp
  46.  */
  47. #define OMX_SendCommand( \
  48.          hComponent, \
  49.          Cmd, \
  50.          nParam, \
  51.          pCmdData) \
  52.      ((OMX_COMPONENTTYPE*)hComponent)->SendCommand( \
  53.          hComponent, \
  54.          Cmd, \
  55.          nParam, \
  56.          pCmdData) /* Macro End */
如客户端发给component:mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);

说到command,看一下都有哪些command吧:
coder在如下路径:hardware\ti\omap4xxx\domx\omx_core\inc\OMX_Core.h

  1. /** The OMX_COMMANDTYPE enumeration is used to specify the action in the
  2.  * OMX_SendCommand macro. 
  3.  * @ingroup core
  4.  */
  5. typedef enum OMX_COMMANDTYPE
  6. {
  7.     OMX_CommandStateSet, /**< Change the component state */
  8.     OMX_CommandFlush, /**< Flush the data queue(s) of a component */
  9.     OMX_CommandPortDisable, /**< Disable a port on a component. */
  10.     OMX_CommandPortEnable, /**< Enable a port on a component. */
  11.     OMX_CommandMarkBuffer, /**< Mark a component/buffer for observation */
  12.     OMX_CommandKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
  13.     OMX_CommandVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
  14.     OMX_CommandMax = 0X7FFFFFFF
  15. } OMX_COMMANDTYPE;

具体 omx component 和 omxcore 的实现在 developer 文档在讨论,在这里只讨论 Opencore 和 omx core/component 的交互作用过程,即 call sequence 。 PVMF 对 omx 的调用大概可以用下面的图来描述:

下面花一些时间说明OMX的执行流程
以下转载自:
谢谢分享

codec集成到PV OpenCORE多媒体框架的方法有几种:
1)作为压缩多媒体输入输出(MIO)组件,
2)作为节点(node)
3)作为OpenMAX组件集成到OpenMAX codecs节点中。
许多
codecs,特别是包含硬件加速器的codes执行OpenMAX IL接口,并且将OpenMAX接口当成最简单的集成方法。

OpenCOREOMX core/component的交互

1) OMX core初始化

PlayerDriver::playerThread()

->OMX_MasterInit() (pv_omxmastercore.cpp)

->_Try_OMX_MasterInit(error, status, data)

->_OMX_MasterInit(data) 执行所有的OpenMAX IL Core标准函数

->OMX_Init()

  OMX_ComponentNameEnum()

  OMX_GetRolesOfComponent()


 OMX Core Initialization
2) OMX Component instantiation, capabilities and port indices
After the OMX Core is initialized, the next step is typically to instantiate a specific component and enumerate capabilities and port indices. The PV framework will: 

l       利用OMX_GetHandle调用来实例化想要的OMX组件

l       利用OMX_GetParameter调用来获取OMX组件的能力和OMX组件上可用端口的数量

l       遍历可用的端口以查找输入端口的索引

l       遍历可用的端口以查找输出端口的索引

 

OMX Component Instantiation through OMX_GetHandle


3) OMX component input and output buffer negotiation

Before any data can be exchanged, parameters for input and output buffers need to be negotiated. To accomplish this, the PV framework:

l       调用OMX_GetParameter来获取input port buffer参数

l       核实(verify) input buffer参数的有效性

l       调用OMX_SetParameter来设置input buffer参数

l       调用OMX_GetParameter来获取output port buffer参数

l       核实(verify) output buffer参数的有效性

l       调用OMX_SetParameter来设置output buffer参数
 OMX Component Buffer Negotiation
 
4) OMX Transition Loaded->Idel State

The buffer allocation is handled as part of the allocation to the Idle state. During this transition, PV Framework:

l       调用OMX_SendCommandOMX组件发送命令以改变组件状态(Loaded->Idel)

l       调用OMX_UseBufferOMX_AllocateBufferOMX组件发送命令。The call is used NumInputBuffer times for input port, and NumOutputBuffer for output port.

l       等待组件的EventHandler回调。这个callback通知框架组件的状态转换已经完成。
 OMX Component state transition from OMX_StateLoaded->OMX_StateIdle
 
5) Transition to “Executing”state and data exchange

The transition to executing starts the active processing of data. In this step, PV Framework:

l       调用OMX_SendCommandOMX组件发送命令以改变组件状态(Idle->Executing)

l       等待EventHandler callback,组件的状态转换已完成

l       调用OMX_EmptyThisBufferOMX_FillThisBuffer向音频组件发送inputoutput buffers。组件利用适当的callback返回buffers

  OMX component state transition from idle to execute and data exchange

 6) Pausing

A common use-case involves pausing and resuming. In this case, the PV framework:

l       调用OMX_SendCommandOMX组件发送命令以改变组件状态(Executing->Pause)

l       等待EventHandler callback,组件的状态转换已完成

OMX组件发送pause命令后,PV框架立即停止向OMX组件发送inpupt/output buffers

 In order to resume, the PV framework:

l       调用OMX_SendCommandOMX组件发送命令以改变组件状态(Pause->Executing)

l       等待EventHandler callback,组件的状态转换已完成

当接到callback组件状态转换成Executing后,PV框架可以恢复向组件发送OMX input/output buffers

OMX component state transition from execute to pause and back

 7) Port flush (if applicable)

The port flush call is typically used with a decoder component during repositioning so that any queued data is discarded. In this situation, the PV framework:

l       调用OMX_SendCommandOMX组件发送命令flush所有ports

l       等待两个来自组件inputoutput portsEventHandler callback,组件已完成ports flushing

当发送flush命令后,PV框架立刻停止向OMX组件发送input/output buffers。当收到第二个callback后,PV框架可以恢复向组件发送input/output buffers

OMX component port flush procedure

 8) Stop/Transition to “Idle” state

In order to stop processing, the PV framework:

l       调用OMX_SendCommandOMX组件发送命令以改变组件的状态(Executing/Pause->Idle)

l       等待EventHandler callback,组件的状态转换已完成

当接收到Idle状态转换命令完成的callback时,PV框架认为所有的OMX输入buffers和输出buffers都已经从OMX组件返回。

OMX component state transition from OMX_StateExecuting/Paused->OMX_StateIdle

 9) OMX Component Transition from Idle->Loaded State and De-initialization

当结束与OMX组件的交互后,PV框架将:

l       调用OMX_SendCommandOMX组件发送命令以改变组件的状态(Idle->Loaded)

l       发起一系列的OMX_FreeBuffer调用

l       等待EventHandler callback,组件的状态转换已完成

l       OMX Core发起OMX_FreeHandle调用以释放组件的Handle

在发起状态转换命令之前,PV框架需要等待所有的输入输出buffersOMX组件返回。

OMX component state transition from OMX_StateIdle->OMX_StateLoaded

 10)   OMX Core De-initialization

PV框架简单地调用OMX_Deinit()


同样还有一个讲解OMX执行流程的文章,很值得一看:http://blog.csdn.net/yili_xie/article/details/4803193
谢谢大牛的分享
待续。。。。
阅读(281) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~