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