1 /*
2 * Copyright (c) 2023 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
16 #include "extension_manager.h"
17 #include <cstdint>
18 #include <dlfcn.h>
19 #include <functional>
20 #include <string>
21 #include <unordered_map>
22 #include "static_extension_list.h"
23 #include "vpe_log.h"
24 #include "extension_base.h"
25 namespace {
26 using LibFunctionGetRegisters = std::unordered_map<std::string,
27 OHOS::Media::VideoProcessingEngine::Extension::RegisterExtensionFunc>* (*)();
28 LibFunctionGetRegisters GetRegisterExtensionFuncs{nullptr};
29 LibFunctionGetRegisters GetRegisterMetdataGenExtensionFuncs{nullptr};
30 LibFunctionGetRegisters GetRegisterComposeExtensionFuncs{nullptr};
31 LibFunctionGetRegisters GetRegisterDecomposeExtensionFuncs{nullptr};
32 using LibFunctionGetRegisterFunction = OHOS::Media::VideoProcessingEngine::Extension::RegisterExtensionFunc (*)();
33 LibFunctionGetRegisterFunction GetRegisterVRRExtensionFuncs{nullptr};
34 void* g_algoHandle{nullptr};
35 } // namespace
36
37 namespace OHOS {
38 namespace Media {
39 namespace VideoProcessingEngine {
40 namespace Extension {
41
GetInstance()42 ExtensionManager& ExtensionManager::GetInstance()
43 {
44 static ExtensionManager instance;
45 return instance;
46 }
47
ExtensionManager()48 ExtensionManager::ExtensionManager()
49 {
50 (void)Init();
51 g_algoHandle = dlopen("libvideoprocessingengine_ext.z.so", RTLD_NOW);
52 if (g_algoHandle == nullptr) {
53 VPE_LOGE("dlopen libvideoprocessingengine_ext failed %{public}s", dlerror());
54 }
55 }
56
~ExtensionManager()57 ExtensionManager::~ExtensionManager()
58 {
59 if (g_algoHandle != nullptr) {
60 dlclose(g_algoHandle);
61 g_algoHandle = nullptr;
62 }
63 }
64
Init()65 VPEAlgoErrCode ExtensionManager::Init()
66 {
67 if (initialized_) {
68 return VPE_ALGO_ERR_OK;
69 }
70 initialized_ = true;
71 return VPE_ALGO_ERR_OK;
72 }
73
IncreaseInstance()74 void ExtensionManager::IncreaseInstance()
75 {
76 std::lock_guard<std::mutex> lock(instanceCountMtx_);
77 if (usedInstance_ == 0 && g_algoHandle == nullptr) {
78 g_algoHandle = dlopen("libvideoprocessingengine_ext.z.so", RTLD_NOW);
79 }
80 usedInstance_++;
81 }
82
DecreaseInstance()83 void ExtensionManager::DecreaseInstance()
84 {
85 std::lock_guard<std::mutex> lock(instanceCountMtx_);
86 usedInstance_--;
87 if ((usedInstance_ == 0) && (g_algoHandle != nullptr)) {
88 dlclose(g_algoHandle);
89 g_algoHandle = nullptr;
90 }
91 }
92
IsColorSpaceConversionSupported(const FrameInfo & inputInfo,const FrameInfo & outputInfo) const93 bool ExtensionManager::IsColorSpaceConversionSupported(const FrameInfo &inputInfo, const FrameInfo &outputInfo) const
94 {
95 if (!initialized_) {
96 return false;
97 }
98 return FindColorSpaceConverterExtension(inputInfo, outputInfo) == nullptr;
99 }
100
CreateColorSpaceConverter(const FrameInfo & inputInfo,const FrameInfo & outputInfo,Extension::ExtensionInfo & extensionInfo) const101 std::shared_ptr<ColorSpaceConverterBase> ExtensionManager::CreateColorSpaceConverter(const FrameInfo &inputInfo,
102 const FrameInfo &outputInfo, Extension::ExtensionInfo &extensionInfo) const
103 {
104 CHECK_AND_RETURN_RET_LOG(initialized_ == true, nullptr, "Not initialized");
105 auto extension = FindColorSpaceConverterExtension(inputInfo, outputInfo);
106 CHECK_AND_RETURN_RET_LOG(extension != nullptr, nullptr, "Create extension failed, get an empty extension");
107 auto impl = extension->creator();
108 CHECK_AND_RETURN_RET_LOG(impl != nullptr, nullptr,
109 "Call extension creator failed, return a empty impl, extension: %{public}s", extension->info.name.c_str());
110 extensionInfo = extension->info;
111 return impl;
112 }
113
CreateVideoRefreshRatePredictor() const114 std::shared_ptr<VideoRefreshRatePredictionBase> ExtensionManager::CreateVideoRefreshRatePredictor() const
115 {
116 std::shared_ptr<ExtensionBase> extension;
117 CHECK_AND_RETURN_RET_LOG(g_algoHandle != nullptr, {}, "dlopen ext fail!");
118 GetRegisterVRRExtensionFuncs = reinterpret_cast<LibFunctionGetRegisterFunction>
119 (dlsym(g_algoHandle, "GetRegisterVRRExtensionFuncs"));
120 CHECK_AND_RETURN_RET_LOG(GetRegisterVRRExtensionFuncs != nullptr, {}, "dlsym Get VRR Extension fail!");
121
122 auto registerFunctionPtr = GetRegisterVRRExtensionFuncs();
123 CHECK_AND_RETURN_RET_LOG(registerFunctionPtr != nullptr, {}, "get GetRegisterVRRExtensionFuncs fail!!");
124 registerFunctionPtr(reinterpret_cast<uintptr_t>(&extension));
125 std::shared_ptr<VideoRefreshratePredictionExtension> vrrExtension =
126 std::static_pointer_cast<VideoRefreshratePredictionExtension>(extension);
127 auto impl = vrrExtension->creator();
128 return impl;
129 }
130
CreateColorSpaceConverterDisplay() const131 ColorSpaceConverterDisplaySet ExtensionManager::CreateColorSpaceConverterDisplay() const
132 {
133 CHECK_AND_RETURN_RET_LOG(initialized_ == true, {}, "Not initialized");
134
135 ColorSpaceConverterDisplaySet impl;
136 for (const auto &extension : FindColorSpaceConverterDisplayExtension()) {
137 auto temp = extension->creator();
138 CHECK_AND_RETURN_RET_LOG(temp != nullptr, {}, "Create failed, extension: %{public}s",
139 extension->info.name.c_str());
140 impl.emplace(std::move(temp));
141 }
142 return impl;
143 }
144
CreateMetadataGenerator(const FrameInfo & inputInfo,Extension::ExtensionInfo & extensionInfo,MetadataGeneratorAlgoType algoType) const145 std::shared_ptr<MetadataGeneratorBase> ExtensionManager::CreateMetadataGenerator(const FrameInfo &inputInfo,
146 Extension::ExtensionInfo &extensionInfo, MetadataGeneratorAlgoType algoType) const
147 {
148 CHECK_AND_RETURN_RET_LOG(initialized_ == true, nullptr, "Not initialized");
149 auto extension = FindMetadataGeneratorExtension(inputInfo, algoType);
150 CHECK_AND_RETURN_RET_LOG(extension != nullptr, nullptr, "Create failed, get an empty extension");
151 auto impl = extension->creator();
152 CHECK_AND_RETURN_RET_LOG(impl != nullptr, nullptr,
153 "Call extension creator failed, return a empty impl, extension: %{public}s", extension->info.name.c_str());
154 extensionInfo = extension->info;
155 return impl;
156 }
157
CreateAihdrEnhancer(const FrameInfo & inputInfo,Extension::ExtensionInfo & extensionInfo) const158 std::shared_ptr<AihdrEnhancerBase> ExtensionManager::CreateAihdrEnhancer(const FrameInfo &inputInfo,
159 Extension::ExtensionInfo &extensionInfo) const
160 {
161 CHECK_AND_RETURN_RET_LOG(initialized_ == true, nullptr, "Not initialized");
162 auto extension = FindAihdrEnhancerExtension(inputInfo);
163 CHECK_AND_RETURN_RET_LOG(extension != nullptr, nullptr, "Create failed, get an empty extension");
164 auto impl = extension->creator();
165 CHECK_AND_RETURN_RET_LOG(impl != nullptr, nullptr,
166 "Call extension creator failed, return a empty impl, extension: %{public}s", extension->info.name.c_str());
167 extensionInfo = extension->info;
168 return impl;
169 }
170
NewInstanceId(const ExtensionManager::InstanceVariableType & instance)171 int32_t ExtensionManager::NewInstanceId(const ExtensionManager::InstanceVariableType& instance)
172 {
173 std::lock_guard<std::mutex> lock(instanceManagementMtx_);
174 int32_t newId = currentId_;
175 do {
176 currentId_ = (currentId_ == MAX_INSTANCE_NUM) ? 0 : currentId_;
177 if (instanceList_[currentId_] == std::nullopt) {
178 instanceList_[currentId_] = instance;
179 newId = currentId_;
180 ++currentId_;
181 return newId;
182 }
183 ++currentId_;
184 } while (currentId_ != newId);
185
186 return -1;
187 }
188
RemoveInstanceReference(int32_t & id)189 int32_t ExtensionManager::RemoveInstanceReference(int32_t& id)
190 {
191 std::lock_guard<std::mutex> lock(instanceManagementMtx_);
192 CHECK_AND_RETURN_RET_LOG(id >= 0 && id < MAX_INSTANCE_NUM, VPE_ALGO_ERR_INVALID_VAL, "invalid instance id");
193 instanceList_[id].reset() ;
194 id = -1;
195
196 return VPE_ALGO_ERR_OK;
197 }
198
GetInstance(int32_t id)199 std::optional<ExtensionManager::InstanceVariableType> ExtensionManager::GetInstance(int32_t id)
200 {
201 std::lock_guard<std::mutex> lock(instanceManagementMtx_);
202 CHECK_AND_RETURN_RET_LOG(id >= 0 && id < MAX_INSTANCE_NUM, std::nullopt, "invalid instance id");
203 return instanceList_[id];
204 }
205
CreateDetailEnhancer(uint32_t level) const206 std::shared_ptr<DetailEnhancerBase> ExtensionManager::CreateDetailEnhancer(uint32_t level) const
207 {
208 CHECK_AND_RETURN_RET_LOG(initialized_ == true, nullptr, "Not initialized");
209 auto extension = FindDetailEnhancerExtension(level);
210 CHECK_AND_RETURN_RET_LOG(extension != nullptr, nullptr,
211 "Create failed, get an empty extension. level: %{public}d", level);
212 auto impl = extension->creator();
213 CHECK_AND_RETURN_RET_LOG(impl != nullptr, nullptr,
214 "Call extension creator failed, return a empty impl, extension: %{public}s, level: %{public}d",
215 extension->info.name.c_str(), level);
216 return impl;
217 }
218
CreateContrastEnhancer(ContrastEnhancerType type) const219 std::shared_ptr<ContrastEnhancerBase> ExtensionManager::CreateContrastEnhancer(ContrastEnhancerType type) const
220 {
221 CHECK_AND_RETURN_RET_LOG(initialized_ == true, nullptr, "Not initialized");
222 auto extension = FindContrastEnhancerExtension(type);
223 CHECK_AND_RETURN_RET_LOG(extension != nullptr, nullptr,
224 "Create failed, get an empty extension. type: %{public}d", type);
225 auto impl = extension->creator();
226 CHECK_AND_RETURN_RET_LOG(impl != nullptr, nullptr,
227 "Call extension creator failed, return a empty impl, extension: %{public}s, type: %{public}d",
228 extension->info.name.c_str(), type);
229 return impl;
230 }
231
LoadExtensions() const232 ExtensionList ExtensionManager::LoadExtensions() const
233 {
234 ExtensionList extensionList {};
235 LoadDynamicExtensions(extensionList);
236 VPEAlgoErrCode ret = LoadStaticExtensions(extensionList);
237 CHECK_AND_RETURN_RET_LOG(ret == VPE_ALGO_ERR_OK, {}, "Load extension failed");
238 return extensionList;
239 }
240
LoadStaticImageExtensions(const std::unordered_map<std::string,RegisterExtensionFunc> staticListRegisterMap) const241 ExtensionList ExtensionManager::LoadStaticImageExtensions(
242 const std::unordered_map<std::string, RegisterExtensionFunc> staticListRegisterMap) const
243 {
244 ExtensionList extensionList {};
245 for (auto ® : staticListRegisterMap) {
246 CHECK_AND_RETURN_RET_LOG(reg.second != nullptr, {},
247 "Get an empty register, extension: %{public}s", reg.first.c_str());
248 VPE_LOGD("Load extension set: %{public}s", reg.first.c_str());
249 reg.second(reinterpret_cast<uintptr_t>(&extensionList));
250 }
251 return extensionList;
252 }
253
FindImageConverterExtension(const FrameInfo & inputInfo,const FrameInfo & outputInfo) const254 bool ExtensionManager::FindImageConverterExtension(
255 const FrameInfo &inputInfo, const FrameInfo &outputInfo) const
256 {
257 auto extensionList = LoadExtensions();
258 CHECK_AND_RETURN_RET_LOG(!extensionList.empty(), false, "No extension found");
259 auto colorSpaceConverterCapabilityMap = BuildCaps<ColorSpaceConverterCapabilityMap>(extensionList);
260 CHECK_AND_RETURN_RET_LOG(!colorSpaceConverterCapabilityMap.empty(), false, "No extension available");
261 auto key =
262 std::make_tuple(inputInfo.colorSpace, inputInfo.pixelFormat, outputInfo.colorSpace, outputInfo.pixelFormat);
263 VPE_LOG_PRINT_COLOR_SPACE_CAPBILITY(inputInfo.colorSpace.colorSpaceInfo, inputInfo.pixelFormat);
264 VPE_LOG_PRINT_COLOR_SPACE_CAPBILITY(outputInfo.colorSpace.colorSpaceInfo, outputInfo.pixelFormat);
265 const auto iter = colorSpaceConverterCapabilityMap.find(key);
266 CHECK_AND_RETURN_RET_LOG(iter != colorSpaceConverterCapabilityMap.cend() && !iter->second.empty(), false,
267 "CSC Extension is not found");
268 return true;
269 }
270
FindImageComposeExtension(const FrameInfo & inputInfo,const FrameInfo & outputInfo) const271 bool ExtensionManager::FindImageComposeExtension(
272 const FrameInfo &inputInfo, const FrameInfo &outputInfo) const
273 {
274 auto extensionList = LoadDynamicComposeExtensions();
275 CHECK_AND_RETURN_RET_LOG(!extensionList.empty(), false, "No extension found");
276 auto colorSpaceConverterCapabilityMap = BuildCaps<ColorSpaceConverterCapabilityMap>(extensionList);
277 CHECK_AND_RETURN_RET_LOG(!colorSpaceConverterCapabilityMap.empty(), false, "No extension available");
278 auto key =
279 std::make_tuple(inputInfo.colorSpace, inputInfo.pixelFormat, outputInfo.colorSpace, outputInfo.pixelFormat);
280 VPE_LOG_PRINT_COLOR_SPACE_CAPBILITY(inputInfo.colorSpace.colorSpaceInfo, inputInfo.pixelFormat);
281 VPE_LOG_PRINT_COLOR_SPACE_CAPBILITY(outputInfo.colorSpace.colorSpaceInfo, outputInfo.pixelFormat);
282 const auto iter = colorSpaceConverterCapabilityMap.find(key);
283 CHECK_AND_RETURN_RET_LOG(iter != colorSpaceConverterCapabilityMap.cend() && !iter->second.empty(), false,
284 "CSC Extension is not found");
285 return true;
286 }
287
FindImageDecomposeExtension(const FrameInfo & inputInfo,const FrameInfo & outputInfo) const288 bool ExtensionManager::FindImageDecomposeExtension(
289 const FrameInfo &inputInfo, const FrameInfo &outputInfo) const
290 {
291 auto extensionList = LoadDynamicDecomposeExtensions();
292 CHECK_AND_RETURN_RET_LOG(!extensionList.empty(), false, "No extension found");
293 auto colorSpaceConverterCapabilityMap = BuildCaps<ColorSpaceConverterCapabilityMap>(extensionList);
294 CHECK_AND_RETURN_RET_LOG(!colorSpaceConverterCapabilityMap.empty(), false, "No extension available");
295 auto key =
296 std::make_tuple(inputInfo.colorSpace, inputInfo.pixelFormat, outputInfo.colorSpace, outputInfo.pixelFormat);
297 VPE_LOG_PRINT_COLOR_SPACE_CAPBILITY(inputInfo.colorSpace.colorSpaceInfo, inputInfo.pixelFormat);
298 VPE_LOG_PRINT_COLOR_SPACE_CAPBILITY(outputInfo.colorSpace.colorSpaceInfo, outputInfo.pixelFormat);
299 const auto iter = colorSpaceConverterCapabilityMap.find(key);
300 CHECK_AND_RETURN_RET_LOG(iter != colorSpaceConverterCapabilityMap.cend() && !iter->second.empty(), false,
301 "CSC Extension is not found");
302 return true;
303 }
304
FindImageMetadataGenExtension(const FrameInfo & inputInfo) const305 bool ExtensionManager::FindImageMetadataGenExtension(const FrameInfo &inputInfo) const
306 {
307 auto extensionList = LoadDynamicMetadataGenExtensions();
308 CHECK_AND_RETURN_RET_LOG(!extensionList.empty(), false, "No extension found");
309 auto metadataGeneratorCapabilityMap = BuildCaps<MetadataGeneratorCapabilityMap>(extensionList);
310 CHECK_AND_RETURN_RET_LOG(!metadataGeneratorCapabilityMap.empty(), false, "No extension available");
311 auto key = std::make_tuple(inputInfo.colorSpace, inputInfo.pixelFormat,
312 MetadataGeneratorAlgoType::META_GEN_ALGO_TYPE_IMAGE);
313 VPE_LOG_PRINT_METADATA_GEN_CAPBILITY(inputInfo.colorSpace.colorSpaceInfo, inputInfo.pixelFormat,
314 MetadataGeneratorAlgoType::META_GEN_ALGO_TYPE_IMAGE);
315 const auto iter = metadataGeneratorCapabilityMap.find(key);
316 CHECK_AND_RETURN_RET_LOG(iter != metadataGeneratorCapabilityMap.cend() && !iter->second.empty(), false,
317 "CSC metadata generator extension is not found");
318 return true;
319 }
320
ImageProcessing_IsColorSpaceConversionSupported(const ColorSpaceInfo inputInfo,const ColorSpaceInfo outputInfo)321 bool ImageProcessing_IsColorSpaceConversionSupported(const ColorSpaceInfo inputInfo, const ColorSpaceInfo outputInfo)
322 {
323 FrameInfo inputFrameInfo;
324 inputFrameInfo.colorSpace = {GetColorSpaceInfo(inputInfo.colorSpace), inputInfo.metadataType};
325 inputFrameInfo.pixelFormat = inputInfo.pixelFormat;
326
327 FrameInfo outputFrameInfo;
328 outputFrameInfo.colorSpace = {GetColorSpaceInfo(outputInfo.colorSpace), outputInfo.metadataType};
329 outputFrameInfo.pixelFormat = outputInfo.pixelFormat;
330 ExtensionManager::GetInstance().IncreaseInstance();
331 auto flag = ExtensionManager::GetInstance().FindImageConverterExtension(inputFrameInfo, outputFrameInfo);
332 ExtensionManager::GetInstance().DecreaseInstance();
333 return flag;
334 }
335
ImageProcessing_IsCompositionSupported(const ColorSpaceInfo inputInfo,const ColorSpaceInfo outputInfo)336 bool ImageProcessing_IsCompositionSupported(const ColorSpaceInfo inputInfo, const ColorSpaceInfo outputInfo)
337 {
338 FrameInfo inputFrameInfo;
339 inputFrameInfo.colorSpace = {GetColorSpaceInfo(inputInfo.colorSpace), inputInfo.metadataType};
340 inputFrameInfo.pixelFormat = inputInfo.pixelFormat;
341
342 FrameInfo outputFrameInfo;
343 outputFrameInfo.colorSpace = {GetColorSpaceInfo(outputInfo.colorSpace), outputInfo.metadataType};
344 outputFrameInfo.pixelFormat = outputInfo.pixelFormat;
345 ExtensionManager::GetInstance().IncreaseInstance();
346 auto flag = ExtensionManager::GetInstance().FindImageComposeExtension(inputFrameInfo, outputFrameInfo);
347 ExtensionManager::GetInstance().DecreaseInstance();
348 return flag;
349 }
350
ImageProcessing_IsDecompositionSupported(const ColorSpaceInfo inputInfo,const ColorSpaceInfo outputInfo)351 bool ImageProcessing_IsDecompositionSupported(const ColorSpaceInfo inputInfo, const ColorSpaceInfo outputInfo)
352 {
353 FrameInfo inputFrameInfo;
354 inputFrameInfo.colorSpace = {GetColorSpaceInfo(inputInfo.colorSpace), inputInfo.metadataType};
355 inputFrameInfo.pixelFormat = inputInfo.pixelFormat;
356
357 FrameInfo outputFrameInfo;
358 outputFrameInfo.colorSpace = {GetColorSpaceInfo(outputInfo.colorSpace), outputInfo.metadataType};
359 outputFrameInfo.pixelFormat = outputInfo.pixelFormat;
360 ExtensionManager::GetInstance().IncreaseInstance();
361 auto flag = ExtensionManager::GetInstance().FindImageDecomposeExtension(inputFrameInfo, outputFrameInfo);
362 ExtensionManager::GetInstance().DecreaseInstance();
363 return flag;
364 }
365
ImageProcessing_IsMetadataGenerationSupported(const ColorSpaceInfo inputInfo)366 bool ImageProcessing_IsMetadataGenerationSupported(const ColorSpaceInfo inputInfo)
367 {
368 FrameInfo inputFrameInfo;
369 inputFrameInfo.colorSpace = {GetColorSpaceInfo(inputInfo.colorSpace), inputInfo.metadataType};
370 inputFrameInfo.pixelFormat = inputInfo.pixelFormat;
371 ExtensionManager::GetInstance().IncreaseInstance();
372 auto flag = ExtensionManager::GetInstance().FindImageMetadataGenExtension(inputFrameInfo);
373 ExtensionManager::GetInstance().DecreaseInstance();
374 return flag;
375 }
376
LoadStaticExtensions(ExtensionList & extensionList) const377 VPEAlgoErrCode ExtensionManager::LoadStaticExtensions(ExtensionList& extensionList) const
378 {
379 for (auto ® : staticExtensionsRegisterMap) {
380 CHECK_AND_RETURN_RET_LOG(reg.second != nullptr, VPE_ALGO_ERR_UNKNOWN,
381 "Get an empty register, extension: %{public}s", reg.first.c_str());
382 VPE_LOGD("Load extension set: %{public}s", reg.first.c_str());
383 reg.second(reinterpret_cast<uintptr_t>(&extensionList));
384 }
385 return VPE_ALGO_ERR_OK;
386 }
387
LoadDynamicExtensions(ExtensionList & extensionList) const388 void ExtensionManager::LoadDynamicExtensions(ExtensionList& extensionList) const
389 {
390 CHECK_AND_RETURN_LOG(g_algoHandle != nullptr, "dlopen ext fail!");
391 GetRegisterExtensionFuncs = reinterpret_cast<LibFunctionGetRegisters>
392 (dlsym(g_algoHandle, "GetRegisterExtensionFuncs"));
393 CHECK_AND_RETURN_LOG(GetRegisterExtensionFuncs != nullptr, "dlsym GetRegisterExtensionFuncs fail!");
394 auto dynamicExtensionsRegisterMapPtr = GetRegisterExtensionFuncs();
395 CHECK_AND_RETURN_LOG(dynamicExtensionsRegisterMapPtr != nullptr, "get dynamicExtensionsRegisterMap fail!!");
396 auto dynamicExtensionsRegisterMap = *dynamicExtensionsRegisterMapPtr;
397 for (auto ® : dynamicExtensionsRegisterMap) {
398 if (reg.second != nullptr) {
399 VPE_LOGD("Load extension set: %{public}s", reg.first.c_str());
400 reg.second(reinterpret_cast<uintptr_t>(&extensionList));
401 }
402 }
403 }
404
LoadDynamicMetadataGenExtensions() const405 ExtensionList ExtensionManager::LoadDynamicMetadataGenExtensions() const
406 {
407 ExtensionList extensionList {};
408 CHECK_AND_RETURN_RET_LOG(g_algoHandle != nullptr, {}, "dlopen ext fail!");
409
410 GetRegisterMetdataGenExtensionFuncs = reinterpret_cast<LibFunctionGetRegisters>
411 (dlsym(g_algoHandle, "GetRegisterMetdataGenExtensionFuncs"));
412 CHECK_AND_RETURN_RET_LOG(GetRegisterMetdataGenExtensionFuncs != nullptr, {},
413 "dlsym GetRegisterMetdataGenExtensionFuncs fail!");
414
415 auto dynamicExtensionsRegisterMapPtr = GetRegisterMetdataGenExtensionFuncs();
416 CHECK_AND_RETURN_RET_LOG(dynamicExtensionsRegisterMapPtr != nullptr, {},
417 "get dynamicMetadataGenExtensions fail!!");
418 auto dynamicExtensionsRegisterMap = *dynamicExtensionsRegisterMapPtr;
419 for (auto ® : dynamicExtensionsRegisterMap) {
420 if (reg.second != nullptr) {
421 VPE_LOGD("Load extension set: %{public}s", reg.first.c_str());
422 reg.second(reinterpret_cast<uintptr_t>(&extensionList));
423 }
424 }
425 return extensionList;
426 }
427
LoadDynamicComposeExtensions() const428 ExtensionList ExtensionManager::LoadDynamicComposeExtensions() const
429 {
430 ExtensionList extensionList {};
431 CHECK_AND_RETURN_RET_LOG(g_algoHandle != nullptr, {}, "dlopen ext fail!");
432
433 GetRegisterComposeExtensionFuncs = reinterpret_cast<LibFunctionGetRegisters>
434 (dlsym(g_algoHandle, "GetRegisterComposeExtensionFuncs"));
435 CHECK_AND_RETURN_RET_LOG(GetRegisterComposeExtensionFuncs != nullptr, {},
436 "dlsym GetRegisterComposeExtensionFuncs fail!");
437
438 auto dynamicExtensionsRegisterMapPtr = GetRegisterComposeExtensionFuncs();
439 CHECK_AND_RETURN_RET_LOG(dynamicExtensionsRegisterMapPtr != nullptr, {},
440 "get dynamicMetadataGenExtensions fail!!");
441 auto dynamicExtensionsRegisterMap = *dynamicExtensionsRegisterMapPtr;
442 for (auto ® : dynamicExtensionsRegisterMap) {
443 if (reg.second != nullptr) {
444 VPE_LOGD("Load extension set: %{public}s", reg.first.c_str());
445 reg.second(reinterpret_cast<uintptr_t>(&extensionList));
446 }
447 }
448 return extensionList;
449 }
450
LoadDynamicDecomposeExtensions() const451 ExtensionList ExtensionManager::LoadDynamicDecomposeExtensions() const
452 {
453 ExtensionList extensionList {};
454 CHECK_AND_RETURN_RET_LOG(g_algoHandle != nullptr, {}, "dlopen ext fail, g_algoHandle null!");
455
456 GetRegisterDecomposeExtensionFuncs = reinterpret_cast<LibFunctionGetRegisters>
457 (dlsym(g_algoHandle, "GetRegisterDecomposeExtensionFuncs"));
458 CHECK_AND_RETURN_RET_LOG(GetRegisterDecomposeExtensionFuncs != nullptr, {},
459 "dlsym GetRegisterDecomposeExtensionFuncs fail!");
460
461 auto dynamicExtensionsRegisterMapPtr = GetRegisterDecomposeExtensionFuncs();
462 CHECK_AND_RETURN_RET_LOG(dynamicExtensionsRegisterMapPtr != nullptr, {},
463 "get dynamicMetadataGenExtensions fail!!");
464 auto dynamicExtensionsRegisterMap = *dynamicExtensionsRegisterMapPtr;
465 for (auto ® : dynamicExtensionsRegisterMap) {
466 if (reg.second != nullptr) {
467 VPE_LOGD("Load extension set: %{public}s", reg.first.c_str());
468 reg.second(reinterpret_cast<uintptr_t>(&extensionList));
469 }
470 }
471 return extensionList;
472 }
473
474 template<typename T>
BuildCaps(const ExtensionList & extensionList) const475 T ExtensionManager::BuildCaps(const ExtensionList& extensionList) const
476 {
477 VPEAlgoErrCode err = VPE_ALGO_ERR_OK;
478 T capMap {};
479 for (size_t idx = 0; idx < extensionList.size(); ++idx) {
480 auto extension = extensionList[idx];
481 CHECK_AND_RETURN_RET_LOG(extension != nullptr, {}, "Extension is nullptr");
482 if constexpr (std::is_same_v<T, ColorSpaceConverterCapabilityMap>) {
483 if (extension->info.type == ExtensionType::COLORSPACE_CONVERTER) {
484 err = BuildColorSpaceConverterCaps(extension, idx, capMap);
485 CHECK_AND_LOG(err == VPE_ALGO_ERR_OK, "Build caps failed, extension: %{public}s",
486 extension->info.name.c_str());
487 }
488 } else if constexpr (std::is_same_v<T, ColorSpaceConverterDisplayCapabilityMap>) {
489 if (extension->info.type == ExtensionType::COLORSPACE_CONVERTER_DISPLAY) {
490 err = BuildColorSpaceConverterDisplayCaps(extension, idx, capMap);
491 CHECK_AND_LOG(err == VPE_ALGO_ERR_OK, "Build caps failed, extension: %{public}s",
492 extension->info.name.c_str());
493 }
494 } else if constexpr (std::is_same_v<T, MetadataGeneratorCapabilityMap>) {
495 if (extension->info.type == ExtensionType::METADATA_GENERATOR) {
496 err = BuildMetadataGeneratorCaps(extension, idx, capMap);
497 CHECK_AND_LOG(err == VPE_ALGO_ERR_OK, "Build caps failed, extension: %{public}s",
498 extension->info.name.c_str());
499 }
500 } else if constexpr (std::is_same_v<T, DetailEnhancerCapabilityMap>) {
501 if (extension->info.type == ExtensionType::DETAIL_ENHANCER) {
502 err = BuildDetailEnhancerCaps(extension, idx, capMap);
503 CHECK_AND_LOG(err == VPE_ALGO_ERR_OK, "Build caps failed, extension: %{public}s",
504 extension->info.name.c_str());
505 }
506 } else if constexpr (std::is_same_v<T, ContrastEnhancerCapabilityMap>) {
507 if (extension->info.type == ExtensionType::CONTRAST_ENHANCER) {
508 err = BuildContrastEnhancerCaps(extension, idx, capMap);
509 CHECK_AND_LOG(err == VPE_ALGO_ERR_OK, "Build caps failed, extension: %{public}s",
510 extension->info.name.c_str());
511 }
512 } else if constexpr (std::is_same_v<T, AihdrEnhancerCapabilityMap>) {
513 if (extension->info.type == ExtensionType::AIHDR_ENHANCER) {
514 err = BuildAihdrEnhancerCaps(extension, idx, capMap);
515 CHECK_AND_LOG(err == VPE_ALGO_ERR_OK, "Build caps failed, extension: %{public}s",
516 extension->info.name.c_str());
517 }
518 } else {
519 VPE_LOGE("Unknown extension type");
520 return {};
521 }
522 }
523 return capMap;
524 }
525
FindColorSpaceConverterExtension(const FrameInfo & inputInfo,const FrameInfo & outputInfo) const526 std::shared_ptr<ColorSpaceConverterExtension> ExtensionManager::FindColorSpaceConverterExtension(
527 const FrameInfo &inputInfo, const FrameInfo &outputInfo) const
528 {
529 VPE_LOG_PRINT_COLOR_SPACE_CAPBILITY(inputInfo.colorSpace.colorSpaceInfo, inputInfo.pixelFormat);
530 VPE_LOG_PRINT_COLOR_SPACE_CAPBILITY(outputInfo.colorSpace.colorSpaceInfo, outputInfo.pixelFormat);
531 auto extensionList = LoadExtensions();
532 CHECK_AND_RETURN_RET_LOG(!extensionList.empty(), nullptr, "No extension found");
533 auto colorSpaceConverterCapabilityMap = BuildCaps<ColorSpaceConverterCapabilityMap>(extensionList);
534 CHECK_AND_RETURN_RET_LOG(!colorSpaceConverterCapabilityMap.empty(), nullptr, "No extension available");
535 auto key =
536 std::make_tuple(inputInfo.colorSpace, inputInfo.pixelFormat, outputInfo.colorSpace, outputInfo.pixelFormat);
537 const auto iter = colorSpaceConverterCapabilityMap.find(key);
538 if (iter == colorSpaceConverterCapabilityMap.cend() || iter->second.empty()) {
539 VPE_LOGE("CSC Extension is not found");
540 CM_ColorSpaceInfo CSDesc = inputInfo.colorSpace.colorSpaceInfo;
541 VPE_LOGE("input: (primary=%{public}3d,trans=%{public}3d,mat=%{public}3d,range=%{public}3d,"\
542 "pixel=%{public}3d,metadata=%{public}3d", (CSDesc).primaries, (CSDesc).transfunc, (CSDesc).matrix,
543 (CSDesc).range, inputInfo.pixelFormat, inputInfo.colorSpace.metadataType);
544 CSDesc = outputInfo.colorSpace.colorSpaceInfo;
545 VPE_LOGE("output: (primary=%{public}3d,trans=%{public}3d,mat=%{public}3d,range=%{public}3d,"\
546 "pixel=%{public}3d,metadata=%{public}3d", (CSDesc).primaries, (CSDesc).transfunc, (CSDesc).matrix,
547 (CSDesc).range, outputInfo.pixelFormat, outputInfo.colorSpace.metadataType);
548 return nullptr;
549 }
550 size_t idx = std::get<2>(*(iter->second.cbegin()));
551 for (const auto &cap : iter->second) {
552 if (std::get<0>(cap) == Rank::RANK_HIGH) {
553 idx = std::get<2>(cap); // 2
554 break;
555 }
556 }
557 return std::static_pointer_cast<ColorSpaceConverterExtension>(extensionList[idx]);
558 }
559
FindColorSpaceConverterDisplayExtension() const560 ColorSpaceConverterDisplayExtensionSet ExtensionManager::FindColorSpaceConverterDisplayExtension() const
561 {
562 auto extensionList = LoadExtensions();
563 CHECK_AND_RETURN_RET_LOG(!extensionList.empty(), {}, "No extension found");
564 ColorSpaceConverterDisplayExtensionSet extensions {};
565 for (const auto &extension : extensionList) {
566 CHECK_AND_CONTINUE_LOG(extension != nullptr, "Get an empty extension");
567 if (extension->info.type != ExtensionType::COLORSPACE_CONVERTER_DISPLAY) {
568 continue;
569 }
570 extensions.emplace(std::static_pointer_cast<ColorSpaceConverterDisplayExtension>(extension));
571 }
572 return extensions;
573 }
574
FindMetadataGeneratorExtension(const FrameInfo & inputInfo,MetadataGeneratorAlgoType algoType) const575 std::shared_ptr<MetadataGeneratorExtension> ExtensionManager::FindMetadataGeneratorExtension(const FrameInfo &inputInfo,
576 MetadataGeneratorAlgoType algoType) const
577 {
578 auto extensionList = LoadExtensions();
579 CHECK_AND_RETURN_RET_LOG(!extensionList.empty(), nullptr, "No extension found");
580 auto metadataGeneratorCapabilityMap = BuildCaps<MetadataGeneratorCapabilityMap>(extensionList);
581 CHECK_AND_RETURN_RET_LOG(!metadataGeneratorCapabilityMap.empty(), nullptr, "No extension available");
582 auto key = std::make_tuple(inputInfo.colorSpace, inputInfo.pixelFormat, algoType);
583 VPE_LOG_PRINT_METADATA_GEN_CAPBILITY(inputInfo.colorSpace.colorSpaceInfo, inputInfo.pixelFormat, algoType);
584 const auto iter = metadataGeneratorCapabilityMap.find(key);
585 CHECK_AND_RETURN_RET_LOG(iter != metadataGeneratorCapabilityMap.cend() && !iter->second.empty(), nullptr,
586 "CSC metadata generator extension is not found");
587 size_t idx = std::get<2>(*(iter->second.cbegin()));
588 for (const auto &cap : iter->second) {
589 if (std::get<0>(cap) == Rank::RANK_HIGH) {
590 idx = std::get<2>(cap); // 2
591 break;
592 }
593 }
594 return std::static_pointer_cast<MetadataGeneratorExtension>(extensionList[idx]);
595 }
596
BuildColorSpaceConverterCaps(const std::shared_ptr<ExtensionBase> & ext,size_t idx,ColorSpaceConverterCapabilityMap & colorSpaceConverterCapabilityMap) const597 VPEAlgoErrCode ExtensionManager::BuildColorSpaceConverterCaps(const std::shared_ptr<ExtensionBase> &ext, size_t idx,
598 ColorSpaceConverterCapabilityMap& colorSpaceConverterCapabilityMap) const
599 {
600 VPEAlgoErrCode err = VPE_ALGO_ERR_OK;
601 auto realExtension = std::static_pointer_cast<ColorSpaceConverterExtension>(ext);
602 auto capabilities = realExtension->capabilitiesBuilder();
603 for (const auto &cap : capabilities) {
604 err = ExtractColorSpaceConverterCap(cap, idx, colorSpaceConverterCapabilityMap);
605 }
606 return err;
607 }
608
FindDetailEnhancerExtension(uint32_t level) const609 std::shared_ptr<DetailEnhancerExtension> ExtensionManager::FindDetailEnhancerExtension(uint32_t level) const
610 {
611 auto extensionList = LoadExtensions();
612 CHECK_AND_RETURN_RET_LOG(!extensionList.empty(), nullptr, "No extension found");
613 auto detailEnhancerCapabilityMap = BuildCaps<DetailEnhancerCapabilityMap>(extensionList);
614 CHECK_AND_RETURN_RET_LOG(!detailEnhancerCapabilityMap.empty(), nullptr, "No extension available");
615 const auto iter = detailEnhancerCapabilityMap.find(level);
616 CHECK_AND_RETURN_RET_LOG(iter != detailEnhancerCapabilityMap.cend(), nullptr,
617 "Detail enhancer Extension is not found");
618 size_t idx = iter->second;
619 return std::static_pointer_cast<DetailEnhancerExtension>(extensionList[idx]);
620 }
621
FindAihdrEnhancerExtension(const FrameInfo & inputInfo) const622 std::shared_ptr<AihdrEnhancerExtension> ExtensionManager::FindAihdrEnhancerExtension(const FrameInfo &inputInfo) const
623 {
624 auto extensionList = LoadExtensions();
625 CHECK_AND_RETURN_RET_LOG(!extensionList.empty(), nullptr, "No extension found");
626 auto aihdrEnhancerCapabilityMap = BuildCaps<AihdrEnhancerCapabilityMap>(extensionList);
627 CHECK_AND_RETURN_RET_LOG(!aihdrEnhancerCapabilityMap.empty(), nullptr, "No extension available");
628 auto key = std::make_tuple(inputInfo.colorSpace, inputInfo.pixelFormat);
629 const auto iter = aihdrEnhancerCapabilityMap.find(key);
630 CHECK_AND_RETURN_RET_LOG(iter != aihdrEnhancerCapabilityMap.cend() && !iter->second.empty(), nullptr,
631 "Aihdr enhancer extension is not found");
632 size_t idx = std::get<2>(*(iter->second.cbegin()));
633 for (const auto &cap : iter->second) {
634 if (std::get<0>(cap) == Rank::RANK_HIGH) {
635 idx = std::get<2>(cap); // 2
636 break;
637 }
638 }
639 return std::static_pointer_cast<AihdrEnhancerExtension>(extensionList[idx]);
640 }
641
FindContrastEnhancerExtension(ContrastEnhancerType type) const642 std::shared_ptr<ContrastEnhancerExtension> ExtensionManager::FindContrastEnhancerExtension(
643 ContrastEnhancerType type) const
644 {
645 auto extensionList = LoadExtensions();
646 CHECK_AND_RETURN_RET_LOG(!extensionList.empty(), nullptr, "No extension found");
647 auto contrastEnhancerCapabilityMap = BuildCaps<ContrastEnhancerCapabilityMap>(extensionList);
648 CHECK_AND_RETURN_RET_LOG(!contrastEnhancerCapabilityMap.empty(), nullptr, "No extension available");
649 const auto iter = contrastEnhancerCapabilityMap.find(type);
650 CHECK_AND_RETURN_RET_LOG(iter != contrastEnhancerCapabilityMap.cend(), nullptr,
651 "Contrast enhancer Extension is not found");
652 size_t idx = iter->second;
653 return std::static_pointer_cast<ContrastEnhancerExtension>(extensionList[idx]);
654 }
655
ExtractColorSpaceConverterCap(const ColorSpaceConverterCapability & cap,size_t idx,ColorSpaceConverterCapabilityMap & colorSpaceConverterCapabilityMap) const656 VPEAlgoErrCode ExtensionManager::ExtractColorSpaceConverterCap(const ColorSpaceConverterCapability& cap, size_t idx,
657 ColorSpaceConverterCapabilityMap& colorSpaceConverterCapabilityMap) const
658 {
659 auto inputColorSpaceDesc = cap.inputColorSpaceDesc;
660 auto outputColorSpaceDesc = cap.outputColorSpaceDesc;
661 Rank rank = cap.rank;
662 int32_t version = cap.version;
663 for (const auto &[inputPixelFormat, outputPixelFormats] : cap.pixelFormatMap) {
664 for (const auto &outputPixelFormat : outputPixelFormats) {
665 auto key = std::make_tuple(inputColorSpaceDesc, inputPixelFormat, outputColorSpaceDesc, outputPixelFormat);
666 VPE_LOG_PRINT_COLOR_SPACE_CAPBILITY(inputColorSpaceDesc.colorSpaceInfo, inputPixelFormat);
667 VPE_LOG_PRINT_COLOR_SPACE_CAPBILITY(outputColorSpaceDesc.colorSpaceInfo, outputPixelFormat);
668 auto value = std::make_tuple(rank, version, idx);
669 colorSpaceConverterCapabilityMap[key].push_back(value);
670 }
671 }
672 return VPE_ALGO_ERR_OK;
673 }
674
BuildColorSpaceConverterDisplayCaps(const std::shared_ptr<ExtensionBase> & ext,size_t idx,ColorSpaceConverterDisplayCapabilityMap & colorSpaceConverterDisplayCapabilityMap) const675 VPEAlgoErrCode ExtensionManager::BuildColorSpaceConverterDisplayCaps(const std::shared_ptr<ExtensionBase> &ext,
676 size_t idx, ColorSpaceConverterDisplayCapabilityMap& colorSpaceConverterDisplayCapabilityMap) const
677 {
678 (void)ext;
679 (void)idx;
680 (void)colorSpaceConverterDisplayCapabilityMap;
681 return VPE_ALGO_ERR_OK;
682 }
683
ExtractMetadataGeneratorCap(const MetadataGeneratorCapability & cap,size_t idx,MetadataGeneratorAlgoType algoType,MetadataGeneratorCapabilityMap & metadataGeneratorCapabilityMap) const684 VPEAlgoErrCode ExtensionManager::ExtractMetadataGeneratorCap(const MetadataGeneratorCapability &cap, size_t idx,
685 MetadataGeneratorAlgoType algoType, MetadataGeneratorCapabilityMap& metadataGeneratorCapabilityMap) const
686 {
687 auto colorSpaceDesc = cap.colorspaceDesc;
688 Rank rank = cap.rank;
689 int32_t version = cap.version;
690 for (const auto &pixelFormat : cap.pixelFormats) {
691 auto key = std::make_tuple(colorSpaceDesc, pixelFormat, algoType);
692 VPE_LOG_PRINT_METADATA_GEN_CAPBILITY(colorSpaceDesc.colorSpaceInfo, pixelFormat, algoType);
693 auto value = std::make_tuple(rank, version, idx);
694 metadataGeneratorCapabilityMap[key].push_back(value);
695 }
696 return VPE_ALGO_ERR_OK;
697 }
698
BuildMetadataGeneratorCaps(const std::shared_ptr<ExtensionBase> & ext,size_t idx,MetadataGeneratorCapabilityMap & metadataGeneratorCapabilityMap) const699 VPEAlgoErrCode ExtensionManager::BuildMetadataGeneratorCaps(const std::shared_ptr<ExtensionBase> &ext, size_t idx,
700 MetadataGeneratorCapabilityMap& metadataGeneratorCapabilityMap) const
701 {
702 VPEAlgoErrCode err = VPE_ALGO_ERR_OK;
703 auto realExtension = std::static_pointer_cast<MetadataGeneratorExtension>(ext);
704 auto capabilities = realExtension->capabilitiesBuilder();
705 MetadataGeneratorAlgoType algoType = MetadataGeneratorAlgoType::META_GEN_ALGO_TYPE_IMAGE;
706 if (ext->info.name == "VideoMetadataGen") {
707 algoType = MetadataGeneratorAlgoType::META_GEN_ALGO_TYPE_VIDEO;
708 }
709 for (const auto &cap : capabilities) {
710 err = ExtractMetadataGeneratorCap(cap, idx, algoType, metadataGeneratorCapabilityMap);
711 }
712 return err;
713 }
714
BuildDetailEnhancerCaps(const std::shared_ptr<ExtensionBase> & ext,size_t idx,DetailEnhancerCapabilityMap & detailEnhancerCapabilityMap) const715 VPEAlgoErrCode ExtensionManager::BuildDetailEnhancerCaps(const std::shared_ptr<ExtensionBase>& ext, size_t idx,
716 DetailEnhancerCapabilityMap& detailEnhancerCapabilityMap) const
717 {
718 auto realExtension = std::static_pointer_cast<DetailEnhancerExtension>(ext);
719 auto capabilities = realExtension->capabilitiesBuilder();
720 for (const auto &level : capabilities.levels) {
721 auto itr = detailEnhancerCapabilityMap.find(level);
722 if (itr == detailEnhancerCapabilityMap.end()) {
723 detailEnhancerCapabilityMap.emplace(level, idx);
724 } else {
725 if (capabilities.rank == Rank::RANK_HIGH) {
726 itr->second = idx;
727 }
728 }
729 }
730 return VPE_ALGO_ERR_OK;
731 }
732
ExtractAihdrEnhancerCap(const AihdrEnhancerCapability & cap,size_t idx,AihdrEnhancerCapabilityMap & aihdrEnhancerCapabilityMap) const733 VPEAlgoErrCode ExtensionManager::ExtractAihdrEnhancerCap(const AihdrEnhancerCapability &cap, size_t idx,
734 AihdrEnhancerCapabilityMap& aihdrEnhancerCapabilityMap) const
735 {
736 auto colorSpaceDesc = cap.colorspaceDesc;
737 Rank rank = cap.rank;
738 int32_t version = cap.version;
739 for (const auto &pixelFormat : cap.pixelFormats) {
740 auto key = std::make_tuple(colorSpaceDesc, pixelFormat);
741 auto value = std::make_tuple(rank, version, idx);
742 aihdrEnhancerCapabilityMap[key].push_back(value);
743 }
744 return VPE_ALGO_ERR_OK;
745 }
746
BuildAihdrEnhancerCaps(const std::shared_ptr<ExtensionBase> & ext,size_t idx,AihdrEnhancerCapabilityMap & aihdrEnhancerCapabilityMap) const747 VPEAlgoErrCode ExtensionManager::BuildAihdrEnhancerCaps(const std::shared_ptr<ExtensionBase> &ext, size_t idx,
748 AihdrEnhancerCapabilityMap& aihdrEnhancerCapabilityMap) const
749 {
750 VPEAlgoErrCode err = VPE_ALGO_ERR_OK;
751 auto realExtension = std::static_pointer_cast<AihdrEnhancerExtension>(ext);
752 auto capabilities = realExtension->capabilitiesBuilder();
753 for (const auto &cap : capabilities) {
754 err = ExtractAihdrEnhancerCap(cap, idx, aihdrEnhancerCapabilityMap);
755 }
756 return err;
757 }
BuildContrastEnhancerCaps(const std::shared_ptr<ExtensionBase> & ext,size_t idx,ContrastEnhancerCapabilityMap & contrastEnhancerCapabilityMap) const758 VPEAlgoErrCode ExtensionManager::BuildContrastEnhancerCaps(const std::shared_ptr<ExtensionBase>& ext, size_t idx,
759 ContrastEnhancerCapabilityMap& contrastEnhancerCapabilityMap) const
760 {
761 auto realExtension = std::static_pointer_cast<ContrastEnhancerExtension>(ext);
762 auto capabilities = realExtension->capabilitiesBuilder();
763 for (const auto &level : capabilities.types) {
764 contrastEnhancerCapabilityMap.emplace(level, idx);
765 }
766 return VPE_ALGO_ERR_OK;
767 }
768 } // namespace Extension
769 } // namespace VideoProcessingEngine
770 } // namespace Media
771 } // namespace OHOS
772