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 <dlfcn.h>
22 
23 #include "StagefrightPluginLoader.h"
24 
25 namespace android {
26 
27 /* static */ Mutex StagefrightPluginLoader::sMutex;
28 /* static */ std::unique_ptr<StagefrightPluginLoader> StagefrightPluginLoader::sInstance;
29 
StagefrightPluginLoader(const char * libPath)30 StagefrightPluginLoader::StagefrightPluginLoader(const char *libPath)
31     : mCreateCodec(nullptr),
32       mCreateBuilder(nullptr) {
33     mLibHandle = dlopen(libPath, RTLD_NOW | RTLD_NODELETE);
34     if (mLibHandle == nullptr) {
35         ALOGD("Failed to load library: %s (%s)", libPath, dlerror());
36         return;
37     }
38     mCreateCodec = (CodecBase::CreateCodecFunc)dlsym(mLibHandle, "CreateCodec");
39     if (mCreateCodec == nullptr) {
40         ALOGD("Failed to find symbol: CreateCodec (%s)", dlerror());
41     }
42     mCreateBuilder = (MediaCodecListBuilderBase::CreateBuilderFunc)dlsym(
43             mLibHandle, "CreateBuilder");
44     if (mCreateBuilder == nullptr) {
45         ALOGD("Failed to find symbol: CreateBuilder (%s)", dlerror());
46     }
47     mCreateInputSurface = (CodecBase::CreateInputSurfaceFunc)dlsym(
48             mLibHandle, "CreateInputSurface");
49     if (mCreateBuilder == nullptr) {
50         ALOGD("Failed to find symbol: CreateInputSurface (%s)", dlerror());
51     }
52 }
53 
~StagefrightPluginLoader()54 StagefrightPluginLoader::~StagefrightPluginLoader() {
55     if (mLibHandle != nullptr) {
56         ALOGV("Closing handle");
57         dlclose(mLibHandle);
58     }
59 }
60 
createCodec()61 CodecBase *StagefrightPluginLoader::createCodec() {
62     if (mLibHandle == nullptr || mCreateCodec == nullptr) {
63         ALOGD("Handle or CreateCodec symbol is null");
64         return nullptr;
65     }
66     return mCreateCodec();
67 }
68 
createBuilder()69 MediaCodecListBuilderBase *StagefrightPluginLoader::createBuilder() {
70     if (mLibHandle == nullptr || mCreateBuilder == nullptr) {
71         ALOGD("Handle or CreateBuilder symbol is null");
72         return nullptr;
73     }
74     return mCreateBuilder();
75 }
76 
createInputSurface()77 PersistentSurface *StagefrightPluginLoader::createInputSurface() {
78     if (mLibHandle == nullptr || mCreateInputSurface == nullptr) {
79         ALOGD("Handle or CreateInputSurface symbol is null");
80         return nullptr;
81     }
82     return mCreateInputSurface();
83 }
84 
85 //static
GetCCodecInstance()86 const std::unique_ptr<StagefrightPluginLoader> &StagefrightPluginLoader::GetCCodecInstance() {
87     Mutex::Autolock _l(sMutex);
88     if (!sInstance) {
89         ALOGV("Loading library");
90         sInstance.reset(new StagefrightPluginLoader("libstagefright_ccodec.so"));
91     }
92     return sInstance;
93 }
94 
95 }  // namespace android
96