1 /*
2 * Copyright (c) 2021-2021 Huawei Device Co., Ltd.
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 #include "plugin/core/plugin_register.h"
16
17 #include <algorithm>
18 #include <dirent.h>
19
20 #include "all_plugin_static.h"
21 #include "foundation/log.h"
22 #include "plugin/interface/audio_sink_plugin.h"
23 #include "plugin/interface/codec_plugin.h"
24 #include "plugin/interface/demuxer_plugin.h"
25 #include "plugin/interface/generic_plugin.h"
26 #include "plugin/interface/muxer_plugin.h"
27 #include "plugin/interface/source_plugin.h"
28 #include "plugin/interface/video_sink_plugin.h"
29 #include "plugin/interface/output_sink_plugin.h"
30
31 using namespace OHOS::Media::Plugin;
32
~PluginRegister()33 PluginRegister::~PluginRegister()
34 {
35 UnregisterAllPlugins();
36 registerData_->registerNames.clear();
37 registerData_->registerTable.clear();
38 }
39
AddPackage(const PackageDef & def)40 Status PluginRegister::RegisterImpl::AddPackage(const PackageDef& def)
41 {
42 return SetPackageDef(def);
43 }
44
SetPackageDef(const PackageDef & def)45 Status PluginRegister::RegisterImpl::SetPackageDef(const PackageDef& def)
46 {
47 packageDef = std::make_shared<PackageDef>(def);
48 return Status::OK;
49 }
50
AddPlugin(const PluginDefBase & def)51 Status PluginRegister::RegisterImpl::AddPlugin(const PluginDefBase& def)
52 {
53 if (!Verification(def)) {
54 // 插件定义参数校验不合法
55 return Status::ERROR_INVALID_DATA;
56 }
57 if (!VersionMatched(def)) {
58 // 版本不匹配,不给注册
59 return Status::ERROR_UNKNOWN;
60 }
61 if (registerData->IsPluginExist(def.pluginType, def.name)) {
62 if (MoreAcceptable(registerData->registerTable[def.pluginType][def.name], def)) {
63 registerData->registerTable[def.pluginType].erase(def.name);
64 } else {
65 // 重复注册,且有更合适的版本存在
66 return Status::ERROR_PLUGIN_ALREADY_EXISTS;
67 }
68 }
69 UpdateRegisterTableAndRegisterNames(def);
70 return Status::OK;
71 }
72
UpdateRegisterTableAndRegisterNames(const PluginDefBase & def)73 void PluginRegister::RegisterImpl::UpdateRegisterTableAndRegisterNames(const PluginDefBase& def)
74 {
75 auto regInfo = std::make_shared<PluginRegInfo>();
76 regInfo->packageDef = packageDef;
77 switch (def.pluginType) {
78 case PluginType::SOURCE:
79 InitSourceInfo(regInfo, def);
80 break;
81 case PluginType::DEMUXER:
82 InitDemuxerInfo(regInfo, def);
83 break;
84 case PluginType::MUXER:
85 InitMuxerInfo(regInfo, def);
86 break;
87 case PluginType::AUDIO_DECODER:
88 case PluginType::VIDEO_DECODER:
89 case PluginType::AUDIO_ENCODER:
90 case PluginType::VIDEO_ENCODER:
91 InitCodecInfo(regInfo, def);
92 break;
93 case PluginType::AUDIO_SINK:
94 InitAudioSinkInfo(regInfo, def);
95 break;
96 case PluginType::VIDEO_SINK:
97 InitVideoSinkInfo(regInfo, def);
98 break;
99 case PluginType::OUTPUT_SINK:
100 InitOutputSinkInfo(regInfo, def);
101 break;
102 case PluginType::GENERIC_PLUGIN:
103 InitGenericPlugin(regInfo, def);
104 break;
105 default:
106 return;
107 }
108 regInfo->loader = std::move(pluginLoader);
109 registerData->registerTable[def.pluginType][def.name] = regInfo;
110 if ((def.pluginType == PluginType::AUDIO_DECODER || def.pluginType == PluginType::VIDEO_DECODER
111 || def.pluginType == PluginType::AUDIO_ENCODER || def.pluginType == PluginType::VIDEO_ENCODER)
112 && AnyCast<CodecMode>(regInfo->info->extra[PLUGIN_INFO_EXTRA_CODEC_MODE]) == CodecMode::HARDWARE) {
113 registerData->registerNames[def.pluginType].insert(registerData->registerNames[def.pluginType].begin(),
114 def.name);
115 } else {
116 registerData->registerNames[def.pluginType].push_back(def.name);
117 }
118 }
119
Verification(const PluginDefBase & definition)120 bool PluginRegister::RegisterImpl::Verification(const PluginDefBase& definition)
121 {
122 if (definition.rank < 0 || definition.rank > 100) { // 100
123 return false;
124 }
125 return (definition.pluginType != PluginType::INVALID_TYPE);
126 }
127
VersionMatched(const PluginDefBase & definition)128 bool PluginRegister::RegisterImpl::VersionMatched(const PluginDefBase& definition)
129 {
130 static std::map<PluginType, int> g_apiVersionMap = {
131 {PluginType::SOURCE, SOURCE_API_VERSION},
132 {PluginType::DEMUXER, DEMUXER_API_VERSION},
133 {PluginType::AUDIO_DECODER, CODEC_API_VERSION},
134 {PluginType::VIDEO_DECODER, CODEC_API_VERSION},
135 {PluginType::AUDIO_ENCODER, CODEC_API_VERSION},
136 {PluginType::VIDEO_ENCODER, CODEC_API_VERSION},
137 {PluginType::AUDIO_SINK, AUDIO_SINK_API_VERSION},
138 {PluginType::VIDEO_SINK, VIDEO_SINK_API_VERSION},
139 {PluginType::MUXER, MUXER_API_VERSION},
140 {PluginType::OUTPUT_SINK, OUTPUT_SINK_API_VERSION},
141 };
142 if (definition.pluginType == PluginType::GENERIC_PLUGIN) {
143 return true;
144 }
145 int major = (definition.apiVersion >> 16) & 0xFFFF; // 16
146 int minor = definition.apiVersion & 0xFFFF;
147 uint32_t version = g_apiVersionMap[definition.pluginType];
148 int coreMajor = (version >> 16) & 0xFFFF; // 16
149 int coreMinor = version & 0xFFFF;
150 return (major == coreMajor) && (minor <= coreMinor);
151 }
152
153 // NOLINTNEXTLINE: should be static or anonymous namespace
MoreAcceptable(std::shared_ptr<PluginRegInfo> & regInfo,const PluginDefBase & def)154 bool PluginRegister::RegisterImpl::MoreAcceptable(std::shared_ptr<PluginRegInfo>& regInfo, const PluginDefBase& def)
155 {
156 return false;
157 }
158
SetPluginInfo(std::shared_ptr<PluginInfo> & info,const PluginDefBase & def)159 void PluginRegister::RegisterImpl::SetPluginInfo(std::shared_ptr<PluginInfo>& info, const PluginDefBase& def)
160 {
161 info->apiVersion = def.apiVersion;
162 info->pluginType = def.pluginType;
163 info->name = def.name;
164 info->description = def.description;
165 info->rank = def.rank;
166 }
167
InitSourceInfo(std::shared_ptr<PluginRegInfo> & reg,const PluginDefBase & def)168 Status PluginRegister::RegisterImpl::InitSourceInfo(std::shared_ptr<PluginRegInfo>& reg, const PluginDefBase& def)
169 {
170 auto& base = (SourcePluginDef&)def;
171 reg->creator = base.creator;
172 auto info = std::make_shared<PluginInfo>();
173 SetPluginInfo(info, def);
174 info->extra.insert({PLUGIN_INFO_EXTRA_PROTOCOL, base.protocol});
175 info->extra.insert({PLUGIN_INFO_EXTRA_INPUT_TYPE, base.inputType});
176 SourceCapabilityConvert(info, def);
177 reg->info = info;
178 return Status::OK;
179 }
180
InitDemuxerInfo(std::shared_ptr<PluginRegInfo> & reg,const PluginDefBase & def)181 Status PluginRegister::RegisterImpl::InitDemuxerInfo(std::shared_ptr<PluginRegInfo>& reg, const PluginDefBase& def)
182 {
183 auto& base = (DemuxerPluginDef&)def;
184 reg->creator = base.creator;
185 reg->sniffer = base.sniffer;
186 auto info = std::make_shared<PluginInfo>();
187 SetPluginInfo(info, def);
188 info->extra.insert({PLUGIN_INFO_EXTRA_EXTENSIONS, base.extensions});
189 DemuxerCapabilityConvert(info, def);
190 reg->info = info;
191 return Status::OK;
192 }
193
InitMuxerInfo(std::shared_ptr<PluginRegInfo> & reg,const PluginDefBase & def)194 Status PluginRegister::RegisterImpl::InitMuxerInfo(std::shared_ptr<PluginRegInfo>& reg, const PluginDefBase& def)
195 {
196 auto& base = (MuxerPluginDef&)def;
197 reg->creator = base.creator;
198 auto info = std::make_shared<PluginInfo>();
199 SetPluginInfo(info, def);
200 info->inCaps = base.inCaps;
201 info->outCaps = base.outCaps;
202 reg->info = info;
203 return Status::OK;
204 }
205
InitCodecInfo(std::shared_ptr<PluginRegInfo> & reg,const PluginDefBase & def)206 Status PluginRegister::RegisterImpl::InitCodecInfo(std::shared_ptr<PluginRegInfo>& reg, const PluginDefBase& def)
207 {
208 auto& base = (CodecPluginDef&)def;
209 reg->creator = base.creator;
210 auto info = std::make_shared<PluginInfo>();
211 SetPluginInfo(info, def);
212 info->extra.insert({PLUGIN_INFO_EXTRA_CODEC_MODE, base.codecMode});
213 CodecCapabilityConvert(info, def);
214 reg->info = info;
215 return Status::OK;
216 }
217
InitAudioSinkInfo(std::shared_ptr<PluginRegInfo> & reg,const PluginDefBase & def)218 Status PluginRegister::RegisterImpl::InitAudioSinkInfo(std::shared_ptr<PluginRegInfo>& reg, const PluginDefBase& def)
219 {
220 reg->creator = ((AudioSinkPluginDef&)def).creator;
221 auto info = std::make_shared<PluginInfo>();
222 SetPluginInfo(info, def);
223 AudioSinkCapabilityConvert(info, def);
224 reg->info = info;
225 return Status::OK;
226 }
227
InitVideoSinkInfo(std::shared_ptr<PluginRegInfo> & reg,const PluginDefBase & def)228 Status PluginRegister::RegisterImpl::InitVideoSinkInfo(std::shared_ptr<PluginRegInfo>& reg, const PluginDefBase& def)
229 {
230 reg->creator = ((VideoSinkPluginDef&)def).creator;
231 auto info = std::make_shared<PluginInfo>();
232 SetPluginInfo(info, def);
233 VideoSinkCapabilityConvert(info, def);
234 reg->info = info;
235 return Status::OK;
236 }
237
InitOutputSinkInfo(std::shared_ptr<PluginRegInfo> & reg,const PluginDefBase & def)238 Status PluginRegister::RegisterImpl::InitOutputSinkInfo(std::shared_ptr<PluginRegInfo>& reg, const PluginDefBase& def)
239 {
240 auto& base = (OutputSinkPluginDef&)def;
241 reg->creator = base.creator;
242 auto info = std::make_shared<PluginInfo>();
243 SetPluginInfo(info, def);
244 info->extra[PLUGIN_INFO_EXTRA_OUTPUT_TYPE] = base.protocolType;
245 info->inCaps = base.inCaps;
246 reg->info = info;
247 return Status::OK;
248 }
249
InitGenericPlugin(std::shared_ptr<PluginRegInfo> & reg,const PluginDefBase & def)250 Status PluginRegister::RegisterImpl::InitGenericPlugin(std::shared_ptr<PluginRegInfo>& reg, const PluginDefBase& def)
251 {
252 auto& base = (GenericPluginDef&)def;
253 reg->creator = base.creator;
254 auto info = std::make_shared<PluginInfo>();
255 SetPluginInfo(info, def);
256 info->inCaps = base.inCaps;
257 info->outCaps = base.outCaps;
258 reg->info = info;
259 return Status::OK;
260 }
261
SourceCapabilityConvert(std::shared_ptr<PluginInfo> & info,const PluginDefBase & def)262 Status PluginRegister::RegisterImpl::SourceCapabilityConvert(std::shared_ptr<PluginInfo>& info,
263 const PluginDefBase& def)
264 {
265 auto& base = (SourcePluginDef&)def;
266 info->outCaps = base.outCaps;
267 return Status::OK;
268 }
269
DemuxerCapabilityConvert(std::shared_ptr<PluginInfo> & info,const PluginDefBase & def)270 Status PluginRegister::RegisterImpl::DemuxerCapabilityConvert(std::shared_ptr<PluginInfo>& info,
271 const PluginDefBase& def)
272 {
273 auto& base = (DemuxerPluginDef&)def;
274 info->inCaps = base.inCaps;
275 info->outCaps = base.outCaps;
276 return Status::OK;
277 }
278
CodecCapabilityConvert(std::shared_ptr<PluginInfo> & info,const PluginDefBase & def)279 Status PluginRegister::RegisterImpl::CodecCapabilityConvert(std::shared_ptr<PluginInfo>& info, const PluginDefBase& def)
280 {
281 auto& base = (CodecPluginDef&)def;
282 info->inCaps = base.inCaps;
283 info->outCaps = base.outCaps;
284 return Status::OK;
285 }
286
AudioSinkCapabilityConvert(std::shared_ptr<PluginInfo> & info,const PluginDefBase & def)287 Status PluginRegister::RegisterImpl::AudioSinkCapabilityConvert(std::shared_ptr<PluginInfo>& info,
288 const PluginDefBase& def)
289 {
290 auto& base = (AudioSinkPluginDef&)def;
291 info->inCaps = base.inCaps;
292 return Status::OK;
293 }
294
VideoSinkCapabilityConvert(std::shared_ptr<PluginInfo> & info,const PluginDefBase & def)295 Status PluginRegister::RegisterImpl::VideoSinkCapabilityConvert(std::shared_ptr<PluginInfo>& info,
296 const PluginDefBase& def)
297 {
298 auto& base = (VideoSinkPluginDef&)def;
299 info->inCaps = base.inCaps;
300 return Status::OK;
301 }
302
ListPlugins(PluginType type,CodecMode preferredCodecMode)303 std::vector<std::string> PluginRegister::ListPlugins(PluginType type, CodecMode preferredCodecMode)
304 {
305 if ((type == PluginType::AUDIO_DECODER || type == PluginType::VIDEO_DECODER
306 || type == PluginType::AUDIO_ENCODER || type == PluginType::VIDEO_ENCODER)
307 && preferredCodecMode != CodecMode::HARDWARE) {
308 std::vector<std::string> pluginNames {registerData_->registerNames[type]};
309 std::reverse(pluginNames.begin(), pluginNames.end());
310 return pluginNames;
311 } else {
312 return registerData_->registerNames[type];
313 }
314 }
315
GetAllRegisteredPluginCount()316 int PluginRegister::GetAllRegisteredPluginCount()
317 {
318 int count = 0;
319 for (auto it : registerData_->registerTable) {
320 count += it.second.size();
321 }
322 return count;
323 }
324
GetPluginRegInfo(PluginType type,const std::string & name)325 std::shared_ptr<PluginRegInfo> PluginRegister::GetPluginRegInfo(PluginType type, const std::string& name)
326 {
327 if (registerData_->IsPluginExist(type, name)) {
328 return registerData_->registerTable[type][name];
329 }
330 return {};
331 }
332
RegisterPlugins()333 void PluginRegister::RegisterPlugins()
334 {
335 RegisterStaticPlugins();
336 RegisterDynamicPlugins();
337 }
338
RegisterGenericPlugin(const GenericPluginDef & pluginDef)339 void PluginRegister::RegisterGenericPlugin(const GenericPluginDef& pluginDef)
340 {
341 (void)staticPluginRegister_->AddPackage({pluginDef.pkgVersion, pluginDef.pkgName, pluginDef.license});
342 FALSE_LOG_MSG(staticPluginRegister_->AddPlugin(pluginDef) == Status::OK,
343 "Plugin " PUBLIC_LOG_S " register fail.", pluginDef.name.c_str());
344 }
345
RegisterGenericPlugins(const std::vector<GenericPluginDef> & vecPluginDef)346 void PluginRegister::RegisterGenericPlugins(const std::vector<GenericPluginDef>& vecPluginDef)
347 {
348 for (auto& pluginDef : vecPluginDef) {
349 (void)staticPluginRegister_->AddPackage({pluginDef.pkgVersion, pluginDef.pkgName, pluginDef.license});
350 FALSE_LOG_MSG(staticPluginRegister_->AddPlugin(pluginDef) == Status::OK,
351 "Plugin " PUBLIC_LOG_S " register fail.", pluginDef.name.c_str());
352 }
353 }
354
RegisterStaticPlugins()355 void PluginRegister::RegisterStaticPlugins()
356 {
357 RegisterPluginStatic(staticPluginRegister_);
358 }
359
RegisterDynamicPlugins()360 void PluginRegister::RegisterDynamicPlugins()
361 {
362 RegisterPluginsFromPath(HST_PLUGIN_PATH);
363 }
364
RegisterPluginsFromPath(const char * libDirPath)365 void PluginRegister::RegisterPluginsFromPath(const char* libDirPath)
366 {
367 #ifdef DYNAMIC_PLUGINS
368 static std::string libFileHead = "libhistreamer_plugin_";
369 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
370 static std::string fileSeparator = "\\";
371 #else
372 static std::string fileSeparator = "/";
373 #endif
374 static std::string libFileTail = HST_PLUGIN_FILE_TAIL;
375 DIR* libDir = opendir(libDirPath);
376 if (libDir) {
377 struct dirent* lib = nullptr;
378 std::shared_ptr<PluginLoader> loader = nullptr;
379 while ((lib = readdir(libDir))) {
380 if (lib->d_name[0] == '.') {
381 continue;
382 }
383 std::string libName = lib->d_name;
384 if (libName.find(libFileHead) ||
385 libName.compare(libName.size() - libFileTail.size(), libFileTail.size(), libFileTail)) {
386 continue;
387 }
388 std::string pluginName =
389 libName.substr(libFileHead.size(), libName.size() - libFileHead.size() - libFileTail.size());
390 std::string libPath = libDirPath + fileSeparator + lib->d_name;
391 loader = PluginLoader::Create(pluginName, libPath);
392 if (loader) {
393 loader->FetchRegisterFunction()(std::make_shared<RegisterImpl>(registerData_, loader));
394 registeredLoaders_.push_back(loader);
395 }
396 }
397 closedir(libDir);
398 }
399 #endif
400 }
401
UnregisterAllPlugins()402 void PluginRegister::UnregisterAllPlugins()
403 {
404 UnregisterPluginStatic();
405 #ifdef DYNAMIC_PLUGINS
406 for (auto& loader : registeredLoaders_) {
407 EraseRegisteredPluginsByLoader(loader);
408 loader->FetchUnregisterFunction()();
409 loader.reset();
410 }
411 #endif
412 registeredLoaders_.clear();
413 }
414
DeletePlugin(std::map<std::string,std::shared_ptr<PluginRegInfo>> & plugins,std::map<std::string,std::shared_ptr<PluginRegInfo>>::iterator & info)415 void PluginRegister::DeletePlugin(std::map<std::string, std::shared_ptr<PluginRegInfo>>& plugins,
416 std::map<std::string, std::shared_ptr<PluginRegInfo>>::iterator& info)
417 {
418 auto type = info->second->info->pluginType;
419 for (auto it = registerData_->registerNames[type].begin();
420 it != registerData_->registerNames[type].end();) {
421 if (*it == info->first) {
422 it = registerData_->registerNames[type].erase(it);
423 } else {
424 ++it;
425 }
426 }
427 registerData_->registerTable[type].erase(info->first);
428 info = plugins.erase(info);
429 }
EraseRegisteredPluginsByLoader(const std::shared_ptr<PluginLoader> & loader)430 void PluginRegister::EraseRegisteredPluginsByLoader(const std::shared_ptr<PluginLoader>& loader)
431 {
432 for (auto& it : registerData_->registerTable) {
433 auto plugins = it.second;
434 for (auto info = plugins.begin(); info != plugins.end();) {
435 if (info->second->loader == loader) {
436 DeletePlugin(plugins, info);
437 } else {
438 info++;
439 }
440 }
441 }
442 }
443
IsPluginExist(PluginType type,const std::string & name)444 bool PluginRegister::RegisterData::IsPluginExist(PluginType type, const std::string& name)
445 {
446 return (registerTable.find(type) != registerTable.end() &&
447 registerTable[type].find(name) != registerTable[type].end());
448 }