1/*
2 * Copyright (c) 2022-2023 Shenzhen Kaihong DID 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 "component_mgr.h"
17#include <hdf_base.h>
18#include "codec_log_wrapper.h"
19
20namespace OHOS {
21namespace Codec {
22namespace Omx {
23ComponentMgr::ComponentMgr()
24{
25    AddVendorComponent();
26    AddSoftComponent();
27}
28
29ComponentMgr::~ComponentMgr()
30{
31    CleanComponent();
32}
33
34int32_t ComponentMgr::CreateComponentInstance(const char *componentName, const OMX_CALLBACKTYPE *callbacks,
35                                              void *appData, OMX_COMPONENTTYPE **component)
36{
37    int32_t err = HDF_ERR_INVALID_PARAM;
38    std::lock_guard<std::mutex> lk(mutex_);
39
40    auto iter = compoentsCore_.find(componentName);
41    if (iter == compoentsCore_.end() || iter->second == nullptr) {
42        CODEC_LOGE("can not find component[%{public}s] in core", componentName);
43        return err;
44    }
45    auto core = iter->second;
46    if (core == nullptr) {
47        CODEC_LOGE("null point");
48        return HDF_FAILURE;
49    }
50    OMX_HANDLETYPE handle = nullptr;
51    std::string name(componentName);
52    err = core->GetHandle(handle, name, appData, *callbacks);
53    if (err == OMX_ErrorNone && handle) {
54        OMXComponent comp;
55        comp.core = core;
56        *component = reinterpret_cast<OMX_COMPONENTTYPE *>(handle);
57        comp.handle = handle;
58        components_.push_back(comp);
59    }
60    return err;
61}
62
63int32_t ComponentMgr::DeleteComponentInstance(OMX_COMPONENTTYPE *component)
64{
65    std::lock_guard<std::mutex> lk(mutex_);
66    int32_t err = OMX_ErrorInvalidComponent;
67    for (size_t i = 0; i < components_.size(); i++) {
68        if (components_[i].handle == component) {
69            err = components_[i].core->FreeHandle(components_[i].handle);
70            components_.erase(components_.begin() + i);
71            break;
72        }
73    }
74    return err;
75}
76
77int32_t ComponentMgr::GetRolesForComponent(const char *componentName, std::vector<std::string> *roles)
78{
79    (void)roles;
80    (void)componentName;
81    return OMX_ErrorNone;
82}
83
84void ComponentMgr::AddVendorComponent()
85{
86    AddComponentByLibName("libOMX_Core.z.so");
87}
88
89void ComponentMgr::AddSoftComponent()
90{}
91
92void ComponentMgr::AddComponentByLibName(const char *libName)
93{
94    auto core = std::make_shared<CodecOMXCore>();
95    if (core == nullptr) {
96        CODEC_LOGE("fail to init CodecOMXCore");
97        return;
98    }
99    core->Init(libName);
100    std::lock_guard<std::mutex> lk(mutex_);
101    cores_.emplace_back(core);
102    std::string name("");
103    uint32_t index = 0;
104    while (HDF_SUCCESS == core->ComponentNameEnum(name, index)) {
105        ++index;
106        compoentsCore_.emplace(std::make_pair(name, core));
107    }
108}
109
110void ComponentMgr::CleanComponent()
111{
112    std::lock_guard<std::mutex> lk(mutex_);
113    for (size_t i = 0; i < components_.size(); i++) {
114        components_[i].core->FreeHandle(components_[i].handle);
115    }
116    components_.clear();
117
118    for (size_t i = 0; i < cores_.size(); i++) {
119        cores_[i]->DeInit();
120    }
121    cores_.clear();
122
123    compoentsCore_.clear();
124}
125
126int32_t ComponentMgr::GetCoreOfComponent(CodecOMXCore* &core, const char *componentName)
127{
128    std::lock_guard<std::mutex> lk(mutex_);
129    auto iter = compoentsCore_.find(componentName);
130    if (iter == compoentsCore_.end() || iter->second == nullptr) {
131        CODEC_LOGE("can not find component[%{public}s] in core", componentName);
132        return HDF_FAILURE;
133    }
134    core = iter->second.get();
135    return HDF_SUCCESS;
136}
137}  // namespace Omx
138}  // namespace Codec
139}  // namespace OHOS
140