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