美文网首页
libOMX_Core

libOMX_Core

作者: Tsing2015 | 来源:发表于2016-04-26 15:30 被阅读530次

    初探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);
    }
    

    相关文章

      网友评论

          本文标题:libOMX_Core

          本文链接:https://www.haomeiwen.com/subject/xryekttx.html