• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }