Opencore and OMX core/component interaction (一)

来源:互联网 发布:台式机电源检测软件 编辑:程序博客网 时间:2024/05/01 16:31

 在这里讲的是Opencore和OMX的调用sequence,基本来说是根据OMX的API过程来实现的,属于将OMX集成到Opencore的原理部分
对于omx IL的API,大家可以参考http://omxil.sourceforge.net/docs/modules.html

Opencore and OMX core/component interaction

 

1、将一个CODEC集成到PV Opencore multimedia framewok下的方式主要有三种:作为一个compressed MIO(media I/O) component,或者作为个node,或者作为一个Openmax component集成到Opencore framework下的Openmax codecs nodes。对于各种codec尤其是那些包含了HW acceleratincodec来说,Openmax IL interface是最直接的和有效的集成方式,为上层提供统一的接口。

2、具体omx componentomxcore的实现在developer文档在讨论,在这里只讨论Opencoreomx core/component的交互作用过程,即call sequencePVMFomx的调用大概可以用下面的图来描述:


所有这些过程都是通过PVMF来控制的,由PVMF发出command来控制Opencore component的状态转换。

3OpencoreOMX core/componentinteraction过程分为下面几个过程,所有这些过程都是根据API的典型sequence来实现的。

3.1PVMFOMX的调用首先是从对OMX core的初始化开始的:

PVMF首先调用OMX_Init来初始化omx core

@ 然后PVMF会向omx core请求所有他所拥有的component,并根据获得的component name,来请求有效componentrole,然后对有效的组件及其role建立一个registry

OMX_Init()用来对omx core进行初始化,它必须是进入omx前调用的第一个函数,而且在调用deinit之前只能被调用一次。

OMX_ComponentNameEnum()实质上就是检测出system runtime时所有的有效component

OMX_GetRolesOfComponent()实际上根据component name来取得component所支持的rolenumber

具体流程如下:


 

3.2、完成对omx core的初始化之后就要根据开始获得的comonent name,对omx component进行初始化,并且列举出相应componentcapabilities以及获得port目录。PVMF的工作流程如下:

@根据component namerole使用OMX_GetHandle来初始化指定的omx component

@使用所有权index“PV_OMX_CAPABILITY_TYPE_INDEX”根据OMX_GetParameter()取得componentcapabilities,根据capabilities就可以知道component是否支持部分祯,是否支持UseBuffer或者AllocateBuffer等等内容。如果OMX componentd对所有权index返回“OMX_ErrorUnsupportedIndex”或者其他错误信息,PVMF必须为component capabilities指定一组默认的数据

@使用OMX_GetParameter来获得Audio/Video component的有效port数[input/output port],然后遍历所有的输入输出端口,来获得输入输出端口的索引。

PVMF对“PV_OMX_COMPONENT_CAPABILITY_TYPE_INDEX” index的定义如下:

#define PV_OMX_COMPONENT_CAPABILITY_TYPE_INDEX 0xFF7A347

实际上所谓的index包括后面获取Audio/Video component port数使用的“OMX_IndexAudioInit”和“OMX_IndexAudioInit” index都是传到OMX_GetParameter()函数的第一个参数。

PVMF需要从component取得的capabilities被包裹在下面的structure中,需要component对这个structure进行赋值:

typedef struct PV_OMXComponentCapabilityFlagsType

{

OMX_BOOL ilsOMXComponentMultiThreaded;

OMX_BOOL iOMXComponentSupportsExternalOutputBufferAlloc;

OMX_BOOL iOMXComponentSupportsExtrenalInputBufferAlloc;

OMX_BOOL iOMXComponentSupportsMovableInputBuffers;

OMX_BOOL iOMXComponentSupportsPartialFrames;

OMX_BOOL iOMXComponentUsesNALStartCode;

OMX_BOOL iOMXComponentCanHandleIncompleteFrames;

OMX_BOOL iOMXComponentUsesFullAVCFrames;

}

iIsOMXComponentMultiThread默认值为OMX_TRUE,虽然OMX component一般运行在一个独立的线程,但是通过同步调用等方式也可以使其和PVMF运行在一个线程。

iOMXComponentSupportExternalOutput/inputBufferAlloc的默认值为OMX_TRUEOMX spec要求OMX component必须支持在外部分配的额外buffer(比如OMX_UseBuffer调用外部的buffer),如果Component不支持这个,它必须将其值设为OMX_FALSE,并且和PVMF进行协商,从而使PVMF使用OMX_AllocateBuffer

IOMXComponentSupportsMovableInputBuffers这个值默认也是OMX_TRUE,他类似于一种动态存储的概念,就是对于external allocated input buffer,可以将其的omx头部和实际数据进行分离,由omx头部的指针来指定实际数据的位置,如果这个指针可变,则component的可以访问不同的数据区域。如果omx component要求其起header总是指向同一个数据区域,则这个值必须设置false

iOMXComponentSupportsPartialFrames这个值的默认值为OMX_TRUE,根其字面意义一样,就是component是否支持部分桢,当桢/NAL的大小大于buffer的大小的时候,必须把桢/NAL分割成几块,PVMF会在每个桢的结束位添加“OMX_BUFFERFLAG_ENDOFFRAME”,从而使桢的组装变得很简单,如果component需要由PVMF完成对祯/NAL的组装并提供给component完整的桢/NAL,则必须设置这个值为false,不支持部分桢会对性能造成很大的影响。

iOMXComponentUsesNALStartCode这个值默认是OMX_false,这个标志位主要影响到H264的解码,主要是设计到H264 NAL格式的问题,就是说PVMF能够重构H264NAL,不需要再让omx component来解些比特流,如果OMX H264 component要求解些比特流,需要提供0x0001 NAL start codes,则这个值必须设置为true

iOMXComponentCanHandleIncompleteFrames这个值默认为OMX_TRUE,与对partial的支持不同,不完整的桢的是指由于丢包或其他原因导致的桢/NAL不完整,即已经被破坏的桢,comopnent是否能提供恰当的处理,如果component不能相应的处理则必须设置这个值为false

iOMXComponentUsesFullAVCFrames的值默认为OMX_FALSE,这个值定义了PVMF在使用AVC的情况下,以何种模式为Component提供数据。在OMX_FALSE情况下是采用NAL mode,即PCMF提供给comonent的数据是NAL单元,相反的在OMX_TRUE情况下采用的是Frame. mode,在Frame. mode情况下PVMF必须将NAL单元累在一起,然后为component提供完整的一桢数据。

OMX_GetHandle()根据component name载入指定的component到内存,并根据component的方法来为其创建一个componentinstance

OMX_GetParameter()这实际是一个宏,用来获得component的参数,根据第一个参数handle pointer的不同,可能返回值也是不同的。

具体过程如下:


 

3.3完成对omx coreomx component的初始化之后,第三个过程就是对omx component input/output buffer的协商。

@首先使用OMX_GetParameter()获得input/output port buffer parameters,然后对获得的parameters进行一个verify,最后调用OMX_SetParameter()input/output port设置一些buffer parameters

Component input/output port Buffer size在很大程度上影响着component的性能,如果一个buffer能载入多个桢/NAL就不存在分割的问题,PVMF在每个full/NAL后面添加一个“OMX_BUFFERFLAG_ENDOFFRAME”标记。如果一个buffer不够容纳一个桢/NAL,则不管是在输入还是输出都要把桢/NAL分割成多个buffer,并在最后一部分上打上一个end flag的标记。

OMX APIOMX_AllocateBufferOMX_UseBuffer的定义后觉得,所谓分配buffer就是,component每次都要自己分配一个新的bufferbuffer header,而使用buffer,是指可以使用其他component或者IL client分配好的buffer,但必须自己分配一个相应的buffer header,两种方式

具体过程如下:


3.4完成初始化以及对交换区buffer的协商之后,OMX component就被loaded了,载入后的component首先要进入Idle状态。

@首先PVMF会通过OMX_SendCommand函数向OMX component发送状态改变命令,将其状态从OMX_StateLoaded变为OMX_StateIdle

@然后使用两种分配buffer方式(use or allocate)的任一种来为所有的input/output port分配buffer,分配buffer的函数会根据NumInputBufferNumOutputBuffer的值被调用多次[这里有点小疑问,这个Num是不是就是port的数目?]

@当component完成state transition以后,会通过envenhandle callback来通知PVMFOMX_EventCmdComplete)。

根据OMX spec,所有的标准OMX component必须支持OMX_UseBuffer/Allocate两种分配buffer的方式,如果由于内部限制等原因不支持的话,component必须与PVMF进行协商。

一般来说INPUT bufferes一般分配在component外部,这样输入数据就可以省去不必要的copy操作。

具体过程如下:


原创粉丝点击