Enable multimedia HW CODECs

Bug: 16937452

Change-Id: If4aeea3d14168e8d7d2ed5605fdfac191cf515c8
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..a6596b0
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,35 @@
+ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true)
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+    WrsOMXPlugin.cpp
+
+
+LOCAL_CFLAGS := $(PV_CFLAGS_MINUS_VISIBILITY)
+
+#enable log
+#LOCAL_CFLAGS += -DLOG_NDEBUG=0
+
+ifeq ($(USE_MEDIASDK),true)
+    LOCAL_CFLAGS += -DUSE_MEDIASDK
+endif
+
+LOCAL_C_INCLUDES:= \
+        $(call include-path-for, frameworks-native)/media/hardware \
+        $(call include-path-for, frameworks-native)/media/openmax
+
+LOCAL_SHARED_LIBRARIES :=       \
+        libbinder               \
+        libutils                \
+        libcutils               \
+        libui                   \
+        libdl                   \
+        libstagefright_foundation
+
+LOCAL_MODULE := libstagefrighthw
+
+include $(BUILD_SHARED_LIBRARY)
+endif
+
diff --git a/WrsOMXPlugin.cpp b/WrsOMXPlugin.cpp
new file mode 100644
index 0000000..f9c62e2
--- /dev/null
+++ b/WrsOMXPlugin.cpp
@@ -0,0 +1,222 @@
+/*
+* Copyright (c) 2009-2011 Intel Corporation.  All rights reserved.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "WrsOMXPlugin.h"
+
+#include <dlfcn.h>
+
+#include <HardwareAPI.h>
+#include <media/stagefright/foundation/ADebug.h>
+
+namespace android {
+
+OMXPluginBase *createOMXPlugin() {
+    return new WrsOMXPlugin;
+}
+
+WrsOMXPlugin::WrsOMXPlugin()
+{
+   AddCore("libwrs_omxil_core_pvwrapped.so");
+#if defined(USE_MEDIASDK)
+   AddCore("libmfx_omx_core.so");
+#endif
+}
+
+OMX_ERRORTYPE WrsOMXPlugin::AddCore(const char* coreName)
+{
+   void* libHandle = dlopen(coreName, RTLD_NOW);
+
+   if (libHandle != NULL) {
+        WrsOMXCore* core = (WrsOMXCore*)calloc(1,sizeof(WrsOMXCore));
+
+        if (!core) {
+            dlclose(libHandle);
+            return OMX_ErrorUndefined;
+        }
+        // set plugin lib handle and methods
+        core->mLibHandle = libHandle;
+        core->mInit = (WrsOMXCore::InitFunc)dlsym(libHandle, "OMX_Init");
+        core->mDeinit = (WrsOMXCore::DeinitFunc)dlsym(libHandle, "OMX_Deinit");
+
+        core->mComponentNameEnum =
+            (WrsOMXCore::ComponentNameEnumFunc)dlsym(libHandle, "OMX_ComponentNameEnum");
+
+        core->mGetHandle = (WrsOMXCore::GetHandleFunc)dlsym(libHandle, "OMX_GetHandle");
+        core->mFreeHandle = (WrsOMXCore::FreeHandleFunc)dlsym(libHandle, "OMX_FreeHandle");
+
+        core->mGetRolesOfComponentHandle =
+            (WrsOMXCore::GetRolesOfComponentFunc)dlsym(
+                    libHandle, "OMX_GetRolesOfComponent");
+        if (core->mInit != NULL) {
+            (*(core->mInit))();
+        }
+        if (core->mComponentNameEnum != NULL) {
+            // calculating number of components registered inside given OMX core
+            char tmpComponentName[OMX_MAX_STRINGNAME_SIZE] = { 0 };
+            OMX_U32 tmpIndex = 0;
+            while (OMX_ErrorNone == ((*(core->mComponentNameEnum))(tmpComponentName, OMX_MAX_STRINGNAME_SIZE, tmpIndex))) {
+                tmpIndex++;
+            ALOGI("OMX IL core %s: declares component %s", coreName, tmpComponentName);
+            }
+            core->mNumComponents = tmpIndex;
+            ALOGI("OMX IL core %s: contains %ld components", coreName, core->mNumComponents);
+        }
+        // add plugin to the vector
+        mCores.push_back(core);
+    }
+    else {
+        ALOGW("OMX IL core %s not found", coreName);
+        return OMX_ErrorUndefined; // Do we need to return error message
+    }
+    return OMX_ErrorNone;
+}
+
+WrsOMXPlugin::~WrsOMXPlugin() {
+    for (OMX_U32 i = 0; i < mCores.size(); i++) {
+       if (mCores[i] != NULL && mCores[i]->mLibHandle != NULL) {
+          (*(mCores[i]->mDeinit))();
+
+          dlclose(mCores[i]->mLibHandle);
+          free(mCores[i]);
+       }
+    }
+}
+
+OMX_ERRORTYPE WrsOMXPlugin::makeComponentInstance(
+        const char *name,
+        const OMX_CALLBACKTYPE *callbacks,
+        OMX_PTR appData,
+        OMX_COMPONENTTYPE **component) {
+    for (OMX_U32 i = 0; i < mCores.size(); i++) {
+        if (mCores[i] != NULL) {
+            if (mCores[i]->mLibHandle == NULL) {
+                continue;
+            }
+
+            OMX_ERRORTYPE omx_res = (*(mCores[i]->mGetHandle))(
+                reinterpret_cast<OMX_HANDLETYPE *>(component),
+                const_cast<char *>(name),
+                appData, const_cast<OMX_CALLBACKTYPE *>(callbacks));
+            if(omx_res == OMX_ErrorNone) {
+                Mutex::Autolock autoLock(mMutex);
+                WrsOMXComponent comp;
+
+                comp.mComponent = *component;
+                comp.mCore = mCores[i];
+
+                mComponents.push_back(comp);
+                return OMX_ErrorNone;
+            }
+        }
+    }
+    return OMX_ErrorInvalidComponentName;
+}
+
+OMX_ERRORTYPE WrsOMXPlugin::destroyComponentInstance(
+        OMX_COMPONENTTYPE *component) {
+    Mutex::Autolock autoLock(mMutex);
+    for (OMX_U32 i = 0; i < mComponents.size(); i++) {
+        if (mComponents[i].mComponent == component) {
+            if (mComponents[i].mCore == NULL || mComponents[i].mCore->mLibHandle == NULL) {
+                return OMX_ErrorUndefined;
+            }
+            OMX_ERRORTYPE omx_res = (*(mComponents[i].mCore->mFreeHandle))(reinterpret_cast<OMX_HANDLETYPE *>(component));
+            mComponents.erase(mComponents.begin() + i);
+            return omx_res;
+        }
+    }
+    return OMX_ErrorInvalidComponent;
+}
+
+OMX_ERRORTYPE WrsOMXPlugin::enumerateComponents(
+        OMX_STRING name,
+        size_t size,
+        OMX_U32 index) {
+    // returning components
+    OMX_U32 relativeIndex = index;
+    for (OMX_U32 i = 0; i < mCores.size(); i++) {
+        if (mCores[i]->mLibHandle == NULL) {
+           continue;
+        }
+        if (relativeIndex < mCores[i]->mNumComponents) return ((*(mCores[i]->mComponentNameEnum))(name, size, relativeIndex));
+        else relativeIndex -= mCores[i]->mNumComponents;
+    }
+    return OMX_ErrorNoMore;
+}
+
+OMX_ERRORTYPE WrsOMXPlugin::getRolesOfComponent(
+        const char *name,
+        Vector<String8> *roles) {
+    roles->clear();
+    for (OMX_U32 j = 0; j < mCores.size(); j++) {
+        if (mCores[j]->mLibHandle == NULL) {
+           continue;
+        }
+
+        OMX_U32 numRoles;
+        OMX_ERRORTYPE err = (*(mCores[j]->mGetRolesOfComponentHandle))(
+                const_cast<OMX_STRING>(name), &numRoles, NULL);
+
+        if (err != OMX_ErrorNone) {
+            continue;
+        }
+
+        if (numRoles > 0) {
+            OMX_U8 **array = new OMX_U8 *[numRoles];
+            for (OMX_U32 i = 0; i < numRoles; ++i) {
+                array[i] = new OMX_U8[OMX_MAX_STRINGNAME_SIZE];
+            }
+
+            OMX_U32 numRoles2 = numRoles;
+            err = (*(mCores[j]->mGetRolesOfComponentHandle))(
+                    const_cast<OMX_STRING>(name), &numRoles2, array);
+
+            CHECK_EQ(err, OMX_ErrorNone);
+            CHECK_EQ(numRoles, numRoles2);
+
+            for (OMX_U32 i = 0; i < numRoles; ++i) {
+                String8 s((const char *)array[i]);
+                roles->push(s);
+
+                delete[] array[i];
+                array[i] = NULL;
+            }
+
+            delete[] array;
+            array = NULL;
+        }
+        return OMX_ErrorNone;
+    }
+    return OMX_ErrorInvalidComponent;
+}
+
+}  // namespace android
diff --git a/WrsOMXPlugin.h b/WrsOMXPlugin.h
new file mode 100644
index 0000000..5a409fb
--- /dev/null
+++ b/WrsOMXPlugin.h
@@ -0,0 +1,110 @@
+/*
+* Copyright (c) 2009-2011 Intel Corporation.  All rights reserved.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WRS_OMX_PLUGIN_H_
+
+#define WRS_OMX_PLUGIN_H_
+
+#include <OMXPluginBase.h>
+#include <utils/Mutex.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+struct WrsOMXCore {
+    typedef OMX_ERRORTYPE (*InitFunc)();
+    typedef OMX_ERRORTYPE (*DeinitFunc)();
+    typedef OMX_ERRORTYPE (*ComponentNameEnumFunc)(
+            OMX_STRING, OMX_U32, OMX_U32);
+
+    typedef OMX_ERRORTYPE (*GetHandleFunc)(
+            OMX_HANDLETYPE *, OMX_STRING, OMX_PTR, OMX_CALLBACKTYPE *);
+
+    typedef OMX_ERRORTYPE (*FreeHandleFunc)(OMX_HANDLETYPE *);
+
+    typedef OMX_ERRORTYPE (*GetRolesOfComponentFunc)(
+            OMX_STRING, OMX_U32 *, OMX_U8 **);
+
+    void *mLibHandle;
+
+    InitFunc mInit;
+    DeinitFunc mDeinit;
+    ComponentNameEnumFunc mComponentNameEnum;
+    GetHandleFunc mGetHandle;
+    FreeHandleFunc mFreeHandle;
+    GetRolesOfComponentFunc mGetRolesOfComponentHandle;
+
+    OMX_U32 mNumComponents;
+};
+
+struct WrsOMXComponent {
+    OMX_COMPONENTTYPE *mComponent;
+    WrsOMXCore *mCore;
+};
+
+struct WrsOMXPlugin : public OMXPluginBase {
+    WrsOMXPlugin();
+    virtual ~WrsOMXPlugin();
+
+    virtual OMX_ERRORTYPE makeComponentInstance(
+            const char *name,
+            const OMX_CALLBACKTYPE *callbacks,
+            OMX_PTR appData,
+            OMX_COMPONENTTYPE **component);
+
+    virtual OMX_ERRORTYPE destroyComponentInstance(
+            OMX_COMPONENTTYPE *component);
+
+    virtual OMX_ERRORTYPE enumerateComponents(
+            OMX_STRING name,
+            size_t size,
+            OMX_U32 index);
+
+    virtual OMX_ERRORTYPE getRolesOfComponent(
+            const char *name,
+            Vector<String8> *roles);
+
+private:
+
+    Mutex mMutex; // to protect access to mComponents
+
+    Vector<WrsOMXCore*> mCores;
+    Vector<WrsOMXComponent> mComponents;
+
+    OMX_ERRORTYPE AddCore(const char* coreName);
+
+    WrsOMXPlugin(const WrsOMXPlugin &);
+    WrsOMXPlugin &operator=(const WrsOMXPlugin &);
+};
+
+}  // namespace android
+
+#endif  // WRS_OMX_PLUGIN_H_