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
-
/** The OMX_STATETYPE enumeration is used to indicate or change the component
-
* state. This enumeration reflects the current state of the component when
-
* used with the OMX_GetState macro or becomes the parameter in a state change
-
* command when used with the OMX_SendCommand macro.
-
*
-
* The component will be in the Loaded state after the component is initially
-
* loaded into memory. In the Loaded state, the component is not allowed to
-
* allocate or hold resources other than to build it's internal parameter
-
* and configuration tables. The application will send one or more
-
* SetParameters/GetParameters and SetConfig/GetConfig commands to the
-
* component and the component will record each of these parameter and
-
* configuration changes for use later. When the application sends the
-
* Idle command, the component will acquire the resources needed for the
-
* specified configuration and will transition to the idle state if the
-
* allocation is successful. If the component cannot successfully
-
* transition to the idle state for any reason, the state of the component
-
* shall be fully rolled back to the Loaded state (e.g. all allocated
-
* resources shall be released). When the component receives the command
-
* to go to the Executing state, it shall begin processing buffers by
-
* sending all input buffers it holds to the application. While
-
* the component is in the Idle state, the application may also send the
-
* Pause command. If the component receives the pause command while in the
-
* Idle state, the component shall send all input buffers it holds to the
-
* application, but shall not begin processing buffers. This will allow the
-
* application to prefill buffers.
-
*
-
* @ingroup comp
-
*/
-
-
typedef enum OMX_STATETYPE
-
{
-
OMX_StateInvalid, /**< component has detected that it's internal data
-
structures are corrupted to the point that
-
it cannot determine it's state properly */
-
OMX_StateLoaded, /**< component has been loaded but has not completed
-
initialization. The OMX_SetParameter macro
-
and the OMX_GetParameter macro are the only
-
valid macros allowed to be sent to the
-
component in this state. */
-
OMX_StateIdle, /**< component initialization has been completed
-
successfully and the component is ready to
-
to start. */
-
OMX_StateExecuting, /**< component has accepted the start command and
-
is processing data (if data is available) */
-
OMX_StatePause, /**< component has received pause command */
-
OMX_StateWaitForResources, /**< component is waiting for resources, either after
-
preemption or before it gets the resources requested.
-
See specification for complete details. */
-
OMX_StateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
-
OMX_StateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
-
OMX_StateMax = 0X7FFFFFFF
-
} 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)
-
/** Send a command to the component. This call is a non-blocking call.
-
The component should check the parameters and then queue the command
-
to the component thread to be executed. The component thread shall
-
send the EventHandler() callback at the conclusion of the command.
-
This macro will go directly from the application to the component (via
-
a core macro). The component will return from this call within 5 msec.
-
-
When the command is "OMX_CommandStateSet" the component will queue a
-
state transition to the new state idenfied in nParam.
-
-
When the command is "OMX_CommandFlush", to flush a port's buffer queues,
-
the command will force the component to return all buffers NOT CURRENTLY
-
BEING PROCESSED to the application, in the order in which the buffers
-
were received.
-
-
When the command is "OMX_CommandPortDisable" or
-
"OMX_CommandPortEnable", the component's port (given by the value of
-
nParam) will be stopped or restarted.
-
-
When the command "OMX_CommandMarkBuffer" is used to mark a buffer, the
-
pCmdData will point to a OMX_MARKTYPE structure containing the component
-
handle of the component to examine the buffer chain for the mark. nParam1
-
contains the index of the port on which the buffer mark is applied.
-
-
Specification text for more details.
-
-
@param [in] hComponent
-
handle of component to execute the command
-
@param [in] Cmd
-
Command for the component to execute
-
@param [in] nParam
-
Parameter for the command to be executed. When Cmd has the value
-
OMX_CommandStateSet, value is a member of OMX_STATETYPE. When Cmd has
-
the value OMX_CommandFlush, value of nParam indicates which port(s)
-
to flush. -1 is used to flush all ports a single port index will
-
only flush that port. When Cmd has the value "OMX_CommandPortDisable"
-
or "OMX_CommandPortEnable", the component's port is given by
-
the value of nParam. When Cmd has the value "OMX_CommandMarkBuffer"
-
the components pot is given by the value of nParam.
-
@param [in] pCmdData
-
Parameter pointing to the OMX_MARKTYPE structure when Cmd has the value
-
"OMX_CommandMarkBuffer".
-
@return OMX_ERRORTYPE
-
If the command successfully executes, the return code will be
-
OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
-
@ingroup comp
-
*/
-
#define OMX_SendCommand( \
-
hComponent, \
-
Cmd, \
-
nParam, \
-
pCmdData) \
-
((OMX_COMPONENTTYPE*)hComponent)->SendCommand( \
-
hComponent, \
-
Cmd, \
-
nParam, \
-
pCmdData) /* Macro End */
如客户端发给component:mOMX->sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle);
说到command,看一下都有哪些command吧:
coder在如下路径:hardware\ti\omap4xxx\domx\omx_core\inc\OMX_Core.h
-
/** The OMX_COMMANDTYPE enumeration is used to specify the action in the
-
* OMX_SendCommand macro.
-
* @ingroup core
-
*/
-
typedef enum OMX_COMMANDTYPE
-
{
-
OMX_CommandStateSet, /**< Change the component state */
-
OMX_CommandFlush, /**< Flush the data queue(s) of a component */
-
OMX_CommandPortDisable, /**< Disable a port on a component. */
-
OMX_CommandPortEnable, /**< Enable a port on a component. */
-
OMX_CommandMarkBuffer, /**< Mark a component/buffer for observation */
-
OMX_CommandKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
-
OMX_CommandVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
-
OMX_CommandMax = 0X7FFFFFFF
-
} 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接口当成最简单的集成方法。
OpenCORE与OMX 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_SendCommand向OMX组件发送命令以改变组件状态(Loaded->Idel)
l 调用OMX_UseBuffer或OMX_AllocateBuffer向OMX组件发送命令。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_SendCommand向OMX组件发送命令以改变组件状态(Idle->Executing)
l 等待EventHandler callback,组件的状态转换已完成
l 调用OMX_EmptyThisBuffer或OMX_FillThisBuffer向音频组件发送input或output 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_SendCommand向OMX组件发送命令以改变组件状态(Executing->Pause)
l 等待EventHandler callback,组件的状态转换已完成
向OMX组件发送pause命令后,PV框架立即停止向OMX组件发送inpupt/output buffers。
In order to resume, the PV framework:
l 调用OMX_SendCommand向OMX组件发送命令以改变组件状态(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_SendCommand向OMX组件发送命令flush所有ports。
l 等待两个来自组件input和output ports的EventHandler 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_SendCommand向OMX组件发送命令以改变组件的状态(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_SendCommand向OMX组件发送命令以改变组件的状态(Idle->Loaded)
l 发起一系列的OMX_FreeBuffer调用
l 等待EventHandler callback,组件的状态转换已完成
l 向OMX Core发起OMX_FreeHandle调用以释放组件的Handle
在发起状态转换命令之前,PV框架需要等待所有的输入输出buffers从OMX组件返回。
OMX component state transition from OMX_StateIdle->OMX_StateLoaded
10) OMX Core De-initialization
同样还有一个讲解OMX执行流程的文章,很值得一看:http://blog.csdn.net/yili_xie/article/details/4803193
谢谢大牛的分享
待续。。。。
阅读(4264) | 评论(0) | 转发(4) |