初探libOMX_Core
libOMX_Core.so是在xxxOMXPlugin的构造函数中打开的:
xxxOMXPlugin::xxxOMXPlugin()
:mLibHandle(dlopen("libOMX_Core.so", RTLD_NOW)),
{
if (mLibHandle != NULL) {
mInit = (InitFunc)dlsym(mLibHandle, "xxxOMX_Init");
mDeinit = (DeinitFunc)dlsym(mLibHandle, "xxxOMX_DeInit");
mComponentNameEnum =
(ComponentNameEnumFunc)dlsym(mLibHandle, "xxxOMX_ComponentNameEnum");
mGetHandle = (GetHandleFunc)dlsym(mLibHandle, "xxxOMX_GetHandle");
mFreeHandle = (FreeHandleFunc)dlsym(mLibHandle, "xxxOMX_FreeHandle");
mGetRolesOfComponentHandle =
(GetRolesOfComponentFunc)dlsym(
mLibHandle, "xxxOMX_GetRolesOfComponent");
(*mInit)();
}
}
这个是xxxOMXPlugin的构造函数的实现,最主要的是打开OMX_Core so,从dl找的symbol来看,OMX_Core实现了
xxxOMX_Init()、
xxxOMX_DeInit()、
xxxOMX_ComponentNameEnum()、
xxxOMX_GetHandle()、
xxxOMX_FreeHandle()、
xxxOMX_GetRolesOfComponent()
xxxOMX_Init
先看看xxxOMX_Init函数的实现:
OMX_ERRORTYPE xxxOMX_Init()
{
ALOGD("[%s %s]\n", __FILE__, __func__);
OMX_ERRORTYPE eError = OMX_ErrorNone;
if(pthread_mutex_lock(&mutex) != 0)
{
ALOGE("%d :: Core: Error in Mutex lock\n",__LINE__);
return OMX_ErrorUndefined;
}
count++;
ALOGD("init count = %d\n", count);
if (count == 1)
{
eError = RTKOMX_BuildComponentTable();
}
if(pthread_mutex_unlock(&mutex) != 0)
{
ALOGE("%d :: Core: Error in Mutex unlock\n",__LINE__);
return OMX_ErrorUndefined;
}
return eError;
}
函数主要做了一件事RTKOMX_BuildComponentTable,该函数主要是准备componentTable,准备这个table是通过tComponentName这个数组实现的。我们先看看componentTable是存放怎样的元素:
ComponentTable componentTable[MAX_TABLE_SIZE];
typedef struct _ComponentTable {
OMX_STRING name;
OMX_U16 nRoles;
OMX_STRING pRoleArray[MAX_ROLES];
OMX_HANDLETYPE* pHandle[MAX_CONCURRENT_INSTANCES];
int refCount;
}ComponentTable;
ComponentTable记录了每个Component的name,它的值有这些
(OMX.xxx.video.encoder、
OMX.xxx.video.decoder、
OMX.xxx.audio.encoder、
OMX.xxx.audio.decoder),充当的角色数nRoles。每个角色对应的名字pRoleArray,它的取值大概如下:
video_encoder.avc、
audio_decoder.mp2
...
componentTable的创建过程如下(不再详述):
OMX_ERRORTYPE xxxOMX_BuildComponentTable()
{
OMX_ERRORTYPE eError = OMX_ErrorNone;
OMX_CALLBACKTYPE sCallbacks;
int j = 0;
int numFiles = 0;
int i;
for (i = 0, numFiles = 0; i < MAXCOMP; i ++) {
if (tComponentName[i][0] == NULL) {
break;
}
if (numFiles <= MAX_TABLE_SIZE){
for (j = 0; j < numFiles; j ++) {
if (!strcmp(componentTable[j].name, tComponentName[i][0])) {
if (tComponentName[i][1] != NULL)
{
componentTable[j].pRoleArray[componentTable[j].nRoles] = tComponentName[i][1];
componentTable[j].nRoles ++;
}
break;
}
}
if (j == numFiles) {
if (tComponentName[i][1] != NULL){
componentTable[numFiles].pRoleArray[0] = tComponentName[i][1];
componentTable[numFiles].nRoles = 1;
}
strcpy(compName[numFiles], tComponentName[i][0]);
componentTable[numFiles].name = compName[numFiles];
componentTable[numFiles].refCount = 0;
numFiles ++;
}
}
}
tableCount = numFiles;
ALOGD("build tableCount = %lu\n", tableCount);
if (eError != OMX_ErrorNone){
ALOGE("Could not build Component Table\n");
}
return eError;
}
xxxOMX_GetHandle
xxxOMX_GetHandle是在xxxOMXPlugin中的makeComponentInstance函数中调用的:
OMX_ERRORTYPE RTKOMXPlugin::makeComponentInstance(
const char *name,
const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData,
OMX_COMPONENTTYPE **component) {
if (mLibHandle == NULL) {
return OMX_ErrorUndefined;
}
return (*mGetHandle)(
reinterpret_cast<OMX_HANDLETYPE *>(component),
const_cast<char *>(name),
appData, const_cast<OMX_CALLBACKTYPE *>(callbacks));
}
xxxOMX_GetHandle函数的实现如下:
OMX_ERRORTYPE RTKOMX_GetHandle( OMX_HANDLETYPE* pHandle, OMX_STRING cComponentName,
OMX_PTR pAppData, OMX_CALLBACKTYPE* pCallBacks)
{
ALOGD("[%s %s]\n", __FILE__, __func__);
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();
if(pthread_mutex_lock(&mutex) != 0)
{
ALOGE("%d :: Core: Error in Mutex lock\n",__LINE__);
return OMX_ErrorUndefined;
}
if ((NULL == cComponentName) || (NULL == pHandle) || (NULL == pCallBacks)) {
err = OMX_ErrorBadParameter;
goto UNLOCK_MUTEX;
}
if(strlen(cComponentName) >= MAXNAMESIZE) {
err = OMX_ErrorInvalidComponentName;
goto UNLOCK_MUTEX;
}
unsigned int i = 0;
for(i=0; i< COUNTOF(pModules); i++) {
if(pModules[i] == NULL) break;
}
if(i == COUNTOF(pModules)) {
err = OMX_ErrorInsufficientResources;
goto UNLOCK_MUTEX;
}
int refIndex = 0;
for (refIndex=0; refIndex < MAX_TABLE_SIZE; refIndex++) {
if (strcmp(componentTable[refIndex].name, cComponentName) == 0) {
ALOGD("Found component %s with refCount %d\n",
cComponentName, componentTable[refIndex].refCount);
if (componentTable[refIndex].refCount >= getMaxRefCnt(cComponentName)) {
err = OMX_ErrorInsufficientResources;
ALOGE("Max instances(%d) of component %s already created.\n", componentTable[refIndex].refCount, cComponentName);
goto UNLOCK_MUTEX;
} else {
char buf[sizeof(prefix) + MAXNAMESIZE + sizeof(postfix)];
strcpy(buf, prefix);
#if 0 /* luke.lin */
size_t length = strlen(cComponentName);
if (!strcmp( cComponentName + length - 7, ".secure")) {
length -= 7;
}
strncat(buf, cComponentName, length);
#else
strcat(buf, cComponentName);
#endif
strcat(buf, postfix);
pModules[i] = dlopen(buf, RTLD_LAZY | RTLD_GLOBAL);
if( pModules[i] == NULL ) {
ALOGE("dlopen %s failed because %s\n", buf, dlerror());
err = OMX_ErrorComponentNotFound;
goto UNLOCK_MUTEX;
}
pComponentInit = dlsym(pModules[i], "OMX_ComponentInit");
pErr = dlerror();
if( (pErr != NULL) || (pComponentInit == NULL) ) {
ALOGE("%d:: dlsym failed for module %p\n", __LINE__, pModules[i]);
err = OMX_ErrorInvalidComponent;
goto CLEAN_UP;
}
*pHandle = malloc(sizeof(OMX_COMPONENTTYPE));
if(*pHandle == NULL) {
err = OMX_ErrorInsufficientResources;
ALOGE("%d:: malloc of pHandle* failed\n", __LINE__);
goto CLEAN_UP;
}
pComponents[i] = *pHandle;
componentType = (OMX_COMPONENTTYPE*) *pHandle;
componentType->nSize = sizeof(OMX_COMPONENTTYPE);
err = (*pComponentInit)(*pHandle);
if (OMX_ErrorNone == err) {
err = (componentType->SetCallbacks)(*pHandle, pCallBacks, pAppData);
if (err != OMX_ErrorNone) {
ALOGE("%d :: Core: SetCallBack failed %d\n",__LINE__, err);
goto CLEAN_UP;
}
componentTable[refIndex].pHandle[componentTable[refIndex].refCount] = *pHandle;
componentTable[refIndex].refCount += 1;
goto UNLOCK_MUTEX;
}
else if (err == OMX_ErrorInsufficientResources) {
ALOGE("%d :: Core: Insufficient Resources for Component %d\n",__LINE__, err);
goto CLEAN_UP;
}
}
}
}
err = OMX_ErrorComponentNotFound;
goto UNLOCK_MUTEX;
CLEAN_UP:
if(*pHandle != NULL)
{
free(*pHandle);
*pHandle = NULL;
}
pComponents[i] = NULL;
dlclose(pModules[i]);
pModules[i] = NULL;
UNLOCK_MUTEX:
if(pthread_mutex_unlock(&mutex) != 0)
{
ALOGE("%d :: Core: Error in Mutex unlock\n",__LINE__);
err = OMX_ErrorUndefined;
}
return (err);
}
网友评论