技术开发 频道

Android OMAP平台OpenMax IL的硬件实现

  TI OpenMax IL的核心和公共内容

  LCML的全称是“Linux Common Multimedia Layer”,是TI的Linux公共多媒体层。在OpenMax IL的实现中,这个内容在system/src/openmax_il/lcml/目录中,主要文件是子目录src中的LCML_DspCodec.c文件。通过调用DSPBridge的内容, 让ARM和DSP进行通信,然DSP进行编解码方面的处理。DSP的运行还需要固件的支持。

  TI OpenMax IL的核心实现在system/src/openmax_il/omx_core/目录中,生成TI OpenMax IL的核心库libOMX_Core.so。

  其中子目录src中的OMX_Core.c为主要文件,其中定义了编解码器的名称等,其片断如下所示:

char *tComponentName[MAXCOMP][2] = {
    {
"OMX.TI.JPEG.decoder", "image_decoder.jpeg"},  /* 图像和视频编解码器 */
    {
"OMX.TI.JPEG.Encoder", "image_encoder.jpeg"},
    {
"OMX.TI.Video.Decoder", "video_decoder.avc"},
    {
"OMX.TI.Video.Decoder", "video_decoder.mpeg4"},
    {
"OMX.TI.Video.Decoder", "video_decoder.wmv"},
    {
"OMX.TI.Video.encoder", "video_encoder.mpeg4"},
    {
"OMX.TI.Video.encoder", "video_encoder.h263"},
    {
"OMX.TI.Video.encoder", "video_encoder.avc"},
    
/* ......省略 ,语音相关组件*/
#ifdef BUILD_WITH_TI_AUDIO                              
/* 音频编解码器 */
    {
"OMX.TI.MP3.decode", "audio_decoder.mp3"},
    {
"OMX.TI.AAC.encode", "audio_encoder.aac"},
    {
"OMX.TI.AAC.decode", "audio_decoder.aac"},
    {
"OMX.TI.WMA.decode", "audio_decoder.wma"},
    {
"OMX.TI.WBAMR.decode", "audio_decoder.amrwb"},
    {
"OMX.TI.AMR.decode", "audio_decoder.amrnb"},
    {
"OMX.TI.AMR.encode", "audio_encoder.amrnb"},
    {
"OMX.TI.WBAMR.encode", "audio_encoder.amrwb"},
#endif
    {
NULL, NULL},
};

  tComponentName数组的各个项中,第一个表示编解码库内容,第二个表示库所实现的功能。

  其中,TIOMX_GetHandle()函数用于获得各个组建的句柄,其实现的主要片断如下所示:

OMX_ERRORTYPE TIOMX_GetHandle( OMX_HANDLETYPE* pHandle, OMX_STRING cComponentName,
    OMX_PTR pAppData, OMX_CALLBACKTYPE
* pCallBacks)
{
    static
const char prefix[] = "lib";
    static
const char postfix[] = ".so";
    OMX_ERRORTYPE (
*pComponentInit)(OMX_HANDLETYPE*);
    OMX_ERRORTYPE err
= OMX_ErrorNone;
    OMX_COMPONENTTYPE
*componentType;
    
const char* pErr = dlerror();
// ...... 省略错误处理内容
    
int i = 0;
    
for(i=0; i< COUNTOF(pModules); i++) {       // 循环查找
        
if(pModules[i] == NULL) break;
    }
// ...... 省略错误处理内容
    
int refIndex = 0;
    
for (refIndex=0; refIndex < MAX_TABLE_SIZE; refIndex++) {            
// 循环查找组件列表
        
if (strcmp(componentTable[refIndex].name, cComponentName) == 0) {
            
if (componentTable[refIndex].refCount >= MAX_CONCURRENT_INSTANCES) {
// ...... 省略错误处理内容
            }
else {
                char buf[sizeof(prefix)
+ MAXNAMESIZE + sizeof(postfix)];
                strcpy(buf, prefix);
                strcat(buf, cComponentName);
                strcat(buf, postfix);
                pModules[i]
= dlopen(buf, RTLD_LAZY | RTLD_GLOBAL);
            
// ...... 省略错误处理内容
            
// 动态取出初始化的符号
                pComponentInit
= dlsym(pModules[i], "OMX_ComponentInit");  
                pErr
= dlerror();
            
// ...... 省略错误处理内容
                
*pHandle = malloc(sizeof(OMX_COMPONENTTYPE));
            
// ...... 省略错误处理内容
                pComponents[i]
= *pHandle;
                componentType
= (OMX_COMPONENTTYPE*) *pHandle;
                componentType
->nSize = sizeof(OMX_COMPONENTTYPE);
                err
= (*pComponentInit)(*pHandle);   // 执行初始化工作
            
// ...... 省略部分内容
            }
        }
    }
    err
= OMX_ErrorComponentNotFound;
    
goto UNLOCK_MUTEX;
// ...... 省略部分内容
    return (err);
}

  在TIOMX_GetHandle()函数中,根据tComponentName数组中动态库的名称,动态打开各个编解码实现的动态库,取出其中的OMX_ComponentInit符号来执行各个组件的初始化。

0
相关文章