1 /* 2 * Copyright 2018, The Android Open Source Project 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 //#define LOG_NDEBUG 0 18 #define LOG_TAG "StagefrightPluginLoader" 19 #include <utils/Log.h> 20 21 #include <android-base/properties.h> 22 #include <dlfcn.h> 23 24 #include "StagefrightPluginLoader.h" 25 26 namespace android { 27 28 /* static */ Mutex StagefrightPluginLoader::sMutex; 29 /* static */ std::unique_ptr<StagefrightPluginLoader> StagefrightPluginLoader::sInstance; 30 31 namespace /* unnamed */ { 32 33 constexpr const char kCCodecPluginPath[] = "libsfplugin_ccodec.so"; 34 35 } // unnamed namespace 36 37 StagefrightPluginLoader::StagefrightPluginLoader(const char *libPath) { 38 if (android::base::GetIntProperty("debug.stagefright.ccodec", 1) == 0) { 39 ALOGD("CCodec is disabled."); 40 return; 41 } 42 mLibHandle = dlopen(libPath, RTLD_NOW | RTLD_NODELETE); 43 if (mLibHandle == nullptr) { 44 ALOGD("Failed to load library: %s (%s)", libPath, dlerror()); 45 return; 46 } 47 mCreateCodec = (CodecBase::CreateCodecFunc)dlsym(mLibHandle, "CreateCodec"); 48 if (mCreateCodec == nullptr) { 49 ALOGD("Failed to find symbol: CreateCodec (%s)", dlerror()); 50 } 51 mCreateBuilder = (MediaCodecListBuilderBase::CreateBuilderFunc)dlsym( 52 mLibHandle, "CreateBuilder"); 53 if (mCreateBuilder == nullptr) { 54 ALOGD("Failed to find symbol: CreateBuilder (%s)", dlerror()); 55 } 56 mCreateInputSurface = (CodecBase::CreateInputSurfaceFunc)dlsym( 57 mLibHandle, "CreateInputSurface"); 58 if (mCreateInputSurface == nullptr) { 59 ALOGD("Failed to find symbol: CreateInputSurface (%s)", dlerror()); 60 } 61 } 62 63 StagefrightPluginLoader::~StagefrightPluginLoader() { 64 if (mLibHandle != nullptr) { 65 ALOGV("Closing handle"); 66 dlclose(mLibHandle); 67 } 68 } 69 70 CodecBase *StagefrightPluginLoader::createCodec() { 71 if (mLibHandle == nullptr || mCreateCodec == nullptr) { 72 ALOGD("Handle or CreateCodec symbol is null"); 73 return nullptr; 74 } 75 return mCreateCodec(); 76 } 77 78 MediaCodecListBuilderBase *StagefrightPluginLoader::createBuilder() { 79 if (mLibHandle == nullptr || mCreateBuilder == nullptr) { 80 ALOGD("Handle or CreateBuilder symbol is null"); 81 return nullptr; 82 } 83 return mCreateBuilder(); 84 } 85 86 PersistentSurface *StagefrightPluginLoader::createInputSurface() { 87 if (mLibHandle == nullptr || mCreateInputSurface == nullptr) { 88 ALOGD("Handle or CreateInputSurface symbol is null"); 89 return nullptr; 90 } 91 return mCreateInputSurface(); 92 } 93 94 //static 95 const std::unique_ptr<StagefrightPluginLoader> &StagefrightPluginLoader::GetCCodecInstance() { 96 Mutex::Autolock _l(sMutex); 97 if (!sInstance) { 98 ALOGV("Loading library"); 99 sInstance.reset(new StagefrightPluginLoader(kCCodecPluginPath)); 100 } 101 return sInstance; 102 } 103 104 } // namespace android 105