Home | History | Annotate | Download | only in libstagefrighthw
      1 /*
      2 * Copyright (c) 2009-2011 Intel Corporation.  All rights reserved.
      3 *
      4 * Licensed under the Apache License, Version 2.0 (the "License");
      5 * you may not use this file except in compliance with the License.
      6 * You may obtain a copy of the License at
      7 *
      8 * http://www.apache.org/licenses/LICENSE-2.0
      9 *
     10 * Unless required by applicable law or agreed to in writing, software
     11 * distributed under the License is distributed on an "AS IS" BASIS,
     12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 * See the License for the specific language governing permissions and
     14 * limitations under the License.
     15 */
     16 
     17 /*
     18  * Copyright (C) 2009 The Android Open Source Project
     19  *
     20  * Licensed under the Apache License, Version 2.0 (the "License");
     21  * you may not use this file except in compliance with the License.
     22  * You may obtain a copy of the License at
     23  *
     24  *      http://www.apache.org/licenses/LICENSE-2.0
     25  *
     26  * Unless required by applicable law or agreed to in writing, software
     27  * distributed under the License is distributed on an "AS IS" BASIS,
     28  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     29  * See the License for the specific language governing permissions and
     30  * limitations under the License.
     31  */
     32 
     33 #include "WrsOMXPlugin.h"
     34 
     35 #include <dlfcn.h>
     36 
     37 #include <HardwareAPI.h>
     38 #include <media/stagefright/foundation/ADebug.h>
     39 
     40 namespace android {
     41 
     42 OMXPluginBase *createOMXPlugin() {
     43     return new WrsOMXPlugin;
     44 }
     45 
     46 WrsOMXPlugin::WrsOMXPlugin()
     47 {
     48 #ifdef TARGET_HAS_ISV
     49    AddCore("libisv_omx_core.so");
     50 #else
     51    AddCore("libwrs_omxil_core_pvwrapped.so");
     52 #if defined(USE_MEDIASDK)
     53    AddCore("libmfx_omx_core.so");
     54 #endif
     55 #endif
     56 }
     57 
     58 OMX_ERRORTYPE WrsOMXPlugin::AddCore(const char* coreName)
     59 {
     60    void* libHandle = dlopen(coreName, RTLD_NOW);
     61 
     62    if (libHandle != NULL) {
     63         WrsOMXCore* core = (WrsOMXCore*)calloc(1,sizeof(WrsOMXCore));
     64 
     65         if (!core) {
     66             dlclose(libHandle);
     67             return OMX_ErrorUndefined;
     68         }
     69         // set plugin lib handle and methods
     70         core->mLibHandle = libHandle;
     71         core->mInit = (WrsOMXCore::InitFunc)dlsym(libHandle, "OMX_Init");
     72         core->mDeinit = (WrsOMXCore::DeinitFunc)dlsym(libHandle, "OMX_Deinit");
     73 
     74         core->mComponentNameEnum =
     75             (WrsOMXCore::ComponentNameEnumFunc)dlsym(libHandle, "OMX_ComponentNameEnum");
     76 
     77         core->mGetHandle = (WrsOMXCore::GetHandleFunc)dlsym(libHandle, "OMX_GetHandle");
     78         core->mFreeHandle = (WrsOMXCore::FreeHandleFunc)dlsym(libHandle, "OMX_FreeHandle");
     79 
     80         core->mGetRolesOfComponentHandle =
     81             (WrsOMXCore::GetRolesOfComponentFunc)dlsym(
     82                     libHandle, "OMX_GetRolesOfComponent");
     83         if (core->mInit != NULL) {
     84             (*(core->mInit))();
     85         }
     86         if (core->mComponentNameEnum != NULL) {
     87             // calculating number of components registered inside given OMX core
     88             char tmpComponentName[OMX_MAX_STRINGNAME_SIZE] = { 0 };
     89             OMX_U32 tmpIndex = 0;
     90             while (OMX_ErrorNone == ((*(core->mComponentNameEnum))(tmpComponentName, OMX_MAX_STRINGNAME_SIZE, tmpIndex))) {
     91                 tmpIndex++;
     92             ALOGI("OMX IL core %s: declares component %s", coreName, tmpComponentName);
     93             }
     94             core->mNumComponents = tmpIndex;
     95             ALOGI("OMX IL core %s: contains %ld components", coreName, core->mNumComponents);
     96         }
     97         // add plugin to the vector
     98         mCores.push_back(core);
     99     }
    100     else {
    101         ALOGW("OMX IL core %s not found", coreName);
    102         return OMX_ErrorUndefined; // Do we need to return error message
    103     }
    104     return OMX_ErrorNone;
    105 }
    106 
    107 WrsOMXPlugin::~WrsOMXPlugin() {
    108     for (OMX_U32 i = 0; i < mCores.size(); i++) {
    109        if (mCores[i] != NULL && mCores[i]->mLibHandle != NULL) {
    110           (*(mCores[i]->mDeinit))();
    111 
    112           dlclose(mCores[i]->mLibHandle);
    113           free(mCores[i]);
    114        }
    115     }
    116 }
    117 
    118 OMX_ERRORTYPE WrsOMXPlugin::makeComponentInstance(
    119         const char *name,
    120         const OMX_CALLBACKTYPE *callbacks,
    121         OMX_PTR appData,
    122         OMX_COMPONENTTYPE **component) {
    123     for (OMX_U32 i = 0; i < mCores.size(); i++) {
    124         if (mCores[i] != NULL) {
    125             if (mCores[i]->mLibHandle == NULL) {
    126                 continue;
    127             }
    128 
    129             OMX_ERRORTYPE omx_res = (*(mCores[i]->mGetHandle))(
    130                 reinterpret_cast<OMX_HANDLETYPE *>(component),
    131                 const_cast<char *>(name),
    132                 appData, const_cast<OMX_CALLBACKTYPE *>(callbacks));
    133             if(omx_res == OMX_ErrorNone) {
    134                 Mutex::Autolock autoLock(mMutex);
    135                 WrsOMXComponent comp;
    136 
    137                 comp.mComponent = *component;
    138                 comp.mCore = mCores[i];
    139 
    140                 mComponents.push_back(comp);
    141                 return OMX_ErrorNone;
    142             } else if(omx_res == OMX_ErrorInsufficientResources) {
    143                 return OMX_ErrorInsufficientResources;
    144             }
    145         }
    146     }
    147     return OMX_ErrorInvalidComponentName;
    148 }
    149 
    150 OMX_ERRORTYPE WrsOMXPlugin::destroyComponentInstance(
    151         OMX_COMPONENTTYPE *component) {
    152     Mutex::Autolock autoLock(mMutex);
    153     for (OMX_U32 i = 0; i < mComponents.size(); i++) {
    154         if (mComponents[i].mComponent == component) {
    155             if (mComponents[i].mCore == NULL || mComponents[i].mCore->mLibHandle == NULL) {
    156                 return OMX_ErrorUndefined;
    157             }
    158             OMX_ERRORTYPE omx_res = (*(mComponents[i].mCore->mFreeHandle))(reinterpret_cast<OMX_HANDLETYPE *>(component));
    159             mComponents.erase(mComponents.begin() + i);
    160             return omx_res;
    161         }
    162     }
    163     return OMX_ErrorInvalidComponent;
    164 }
    165 
    166 OMX_ERRORTYPE WrsOMXPlugin::enumerateComponents(
    167         OMX_STRING name,
    168         size_t size,
    169         OMX_U32 index) {
    170     // returning components
    171     OMX_U32 relativeIndex = index;
    172     for (OMX_U32 i = 0; i < mCores.size(); i++) {
    173         if (mCores[i]->mLibHandle == NULL) {
    174            continue;
    175         }
    176         if (relativeIndex < mCores[i]->mNumComponents) return ((*(mCores[i]->mComponentNameEnum))(name, size, relativeIndex));
    177         else relativeIndex -= mCores[i]->mNumComponents;
    178     }
    179     return OMX_ErrorNoMore;
    180 }
    181 
    182 OMX_ERRORTYPE WrsOMXPlugin::getRolesOfComponent(
    183         const char *name,
    184         Vector<String8> *roles) {
    185     roles->clear();
    186     for (OMX_U32 j = 0; j < mCores.size(); j++) {
    187         if (mCores[j]->mLibHandle == NULL) {
    188            continue;
    189         }
    190 
    191         OMX_U32 numRoles;
    192         OMX_ERRORTYPE err = (*(mCores[j]->mGetRolesOfComponentHandle))(
    193                 const_cast<OMX_STRING>(name), &numRoles, NULL);
    194 
    195         if (err != OMX_ErrorNone) {
    196             continue;
    197         }
    198 
    199         if (numRoles > 0) {
    200             OMX_U8 **array = new OMX_U8 *[numRoles];
    201             for (OMX_U32 i = 0; i < numRoles; ++i) {
    202                 array[i] = new OMX_U8[OMX_MAX_STRINGNAME_SIZE];
    203             }
    204 
    205             OMX_U32 numRoles2 = numRoles;
    206             err = (*(mCores[j]->mGetRolesOfComponentHandle))(
    207                     const_cast<OMX_STRING>(name), &numRoles2, array);
    208 
    209             CHECK_EQ(err, OMX_ErrorNone);
    210             CHECK_EQ(numRoles, numRoles2);
    211 
    212             for (OMX_U32 i = 0; i < numRoles; ++i) {
    213                 String8 s((const char *)array[i]);
    214                 roles->push(s);
    215 
    216                 delete[] array[i];
    217                 array[i] = NULL;
    218             }
    219 
    220             delete[] array;
    221             array = NULL;
    222         }
    223         return OMX_ErrorNone;
    224     }
    225     return OMX_ErrorInvalidComponent;
    226 }
    227 
    228 }  // namespace android
    229