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},
};
{"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);
}
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符号来执行各个组件的初始化。