技术开发 频道

Android OMAP平台OpenMax IL的硬件实现

  一个TI OpenMax IL组件的实现

  TI OpenMax IL中各个组件都是通过调用LCML来实现的,实现的方式基本类似。主要都是实现了名称为OMX_ComponentInit的初始化函数,实现OMX_COMPONENTTYPE类型的结构体中的各个成员。各个组件其目录结构和文件结构也类似。

  以MP3解码器的实现为例,在audio/src/openmax_il/mp3_dec/src目录中,主要包含以下文件。

  OMX_Mp3Decoder.c:MP3解码器组件实现

  OMX_Mp3Dec_CompThread.c:MP3解码器组件的线程循环

  OMX_Mp3Dec_Utils.c:MP3解码器的相关工具,调用LCML实现真正的MP3解码的功能

  OMX_Mp3Decoder.c中的OMX_ComponentInit()函数负责组件的初始化,返回的内容再从参数中得到,这个函数的主要片断如下所示:

OMX_ERRORTYPE OMX_ComponentInit (OMX_HANDLETYPE hComp)
{    
    OMX_ERRORTYPE eError
= OMX_ErrorNone;
    OMX_COMPONENTTYPE
*pHandle = (OMX_COMPONENTTYPE*) hComp;
    OMX_PARAM_PORTDEFINITIONTYPE
*pPortDef_ip = NULL, *pPortDef_op = NULL;
    OMX_AUDIO_PARAM_PORTFORMATTYPE
*pPortFormat = NULL;
    OMX_AUDIO_PARAM_MP3TYPE
*mp3_ip = NULL;
    OMX_AUDIO_PARAM_PCMMODETYPE
*mp3_op = NULL;
    MP3DEC_COMPONENT_PRIVATE
*pComponentPrivate = NULL;
    MP3D_AUDIODEC_PORT_TYPE
*pCompPort = NULL;
    MP3D_BUFFERLIST
*pTemp = NULL;
    
int i=0;

    MP3D_OMX_CONF_CHECK_CMD(pHandle,
1,1);
/* ......省略,初始化OMX_COMPONENTTYPE类型的指针pHandle */
    OMX_MALLOC_GENERIC(pHandle
->pComponentPrivate,MP3DEC_COMPONENT_PRIVATE);
    pComponentPrivate
= pHandle->pComponentPrivate;  /* 私有指针互相指向 */
    pComponentPrivate
->pHandle = pHandle;
/* ......略,初始化似有数据指针pComponentPrivate */
    
/* 设置输入端口(OMX_PARAM_PORTDEFINITIONTYPE类型)的默认值 */
    pPortDef_ip
->nSize                   = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
    pPortDef_ip
->nPortIndex             = MP3D_INPUT_PORT;
    pPortDef_ip
->eDir                    = OMX_DirInput;
    pPortDef_ip
->nBufferCountActual    = MP3D_NUM_INPUT_BUFFERS;
    pPortDef_ip
->nBufferCountMin        = MP3D_NUM_INPUT_BUFFERS;
    pPortDef_ip
->nBufferSize             = MP3D_INPUT_BUFFER_SIZE;
    pPortDef_ip
->nBufferAlignment       = DSP_CACHE_ALIGNMENT;
    pPortDef_ip
->bEnabled                 = OMX_TRUE;
    pPortDef_ip
->bPopulated               = OMX_FALSE;
    pPortDef_ip
->eDomain                   = OMX_PortDomainAudio;
    pPortDef_ip
->format.audio.eEncoding = OMX_AUDIO_CodingMP3;
    pPortDef_ip
->format.audio.cMIMEType = NULL;
    pPortDef_ip
->format.audio.pNativeRender           = NULL;
    pPortDef_ip
->format.audio.bFlagErrorConcealment = OMX_FALSE;
    
/* 设置输出端口(OMX_PARAM_PORTDEFINITIONTYPE类型)的默认值 */
    pPortDef_op
->nSize                 = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
    pPortDef_op
->nPortIndex           = MP3D_OUTPUT_PORT;
    pPortDef_op
->eDir                  = OMX_DirOutput;
    pPortDef_op
->nBufferCountMin     = MP3D_NUM_OUTPUT_BUFFERS;
    pPortDef_op
->nBufferCountActual  = MP3D_NUM_OUTPUT_BUFFERS;
    pPortDef_op
->nBufferSize          = MP3D_OUTPUT_BUFFER_SIZE;
    pPortDef_op
->nBufferAlignment    = DSP_CACHE_ALIGNMENT;
    pPortDef_op
->bEnabled              = OMX_TRUE;
    pPortDef_op
->bPopulated            = OMX_FALSE;
    pPortDef_op
->eDomain               = OMX_PortDomainAudio;
    pPortDef_op
->format.audio.eEncoding      = OMX_AUDIO_CodingPCM;
    pPortDef_op
->format.audio.cMIMEType      = NULL;
    pPortDef_op
->format.audio.pNativeRender = NULL;
    pPortDef_op
->format.audio.bFlagErrorConcealment = OMX_FALSE;
/* ......省略,分配端口 */
    
/* 设置输入端口的默认格式 */
    pPortFormat
= pComponentPrivate->pCompPort[MP3D_INPUT_PORT]->pPortFormat;
    OMX_CONF_INIT_STRUCT(pPortFormat, OMX_AUDIO_PARAM_PORTFORMATTYPE);
    pPortFormat
->nPortIndex         = MP3D_INPUT_PORT;
    pPortFormat
->nIndex             = OMX_IndexParamAudioMp3;
    pPortFormat
->eEncoding          = OMX_AUDIO_CodingMP3;
    
/* 设置输出端口的默认格式 */
    pPortFormat
= pComponentPrivate->pCompPort[MP3D_OUTPUT_PORT]->pPortFormat;
    OMX_CONF_INIT_STRUCT(pPortFormat, OMX_AUDIO_PARAM_PORTFORMATTYPE);
    pPortFormat
->nPortIndex         = MP3D_OUTPUT_PORT;
    pPortFormat
->nIndex             = OMX_IndexParamAudioPcm;
    pPortFormat
->eEncoding          = OMX_AUDIO_CodingPCM;
/* ......省略部分内容 */
    eError
= Mp3Dec_StartCompThread(pHandle);   // 启动MP3解码线程
/* ......省略部分内容 */
    return eError;
}

  这个组件是OpenMax的标准实现方式,对外的接口的内容只有一个初始化函数。完成OMX_COMPONENTTYPE类型的初始化。输入端口的编号为MP3D_INPUT_PORT(==0),类型为OMX_PortDomainAudio,格式为OMX_AUDIO_CodingMP3。输出端口的编号是MP3D_OUTPUT_PORT(==1),类型为OMX_PortDomainAudio,格式为OMX_AUDIO_ CodingPCM。

  OMX_Mp3Dec_CompThread.c中定义了MP3DEC_ComponentThread()函数,用于创建MP3解码的线程的执行函数。

  OMX_Mp3Dec_Utils.c中的Mp3Dec_StartCompThread()函数,调用了POSIX的线程库建立MP3解码的线程,如下所示:

  nRet = pthread_create (&(pComponentPrivate->ComponentThread), NULL,

  MP3DEC_ComponentThread, pComponentPrivate);

  Mp3Dec_StartCompThread()函数就是在组件初始化函数OMX_ComponentInit()最后调用的内容。MP3线程的开始并不表示解码过程开始,线程需要等待通过pipe机制获得命令和数据(cmdPipe和dataPipe),在适当的时候开始工作。这个pipe在MP3解码组件的SendCommand等实现写操作,在线程中读取其内容。

0
相关文章