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"
19namespace OHOS {
20namespace Codec {
21namespace Omx {
22ComponentMgr::ComponentMgr()
23{
24    AddVendorComponent();
25    AddSoftComponent();
26}
27
28ComponentMgr::~ComponentMgr()
29{
30    CleanComponent();
31}
32
33int32_t ComponentMgr::CreateComponentInstance(const char *componentName, const OMX_CALLBACKTYPE *callbacks,
34                                              void *appData, OMX_COMPONENTTYPE **component)
35{
36    int32_t err = HDF_ERR_INVALID_PARAM;
37    std::lock_guard<std::mutex> lk(mutex_);
38
39    auto iter = compoentsCore_.find(componentName);
40    if (iter == compoentsCore_.end() || iter->second == nullptr) {
41        CODEC_LOGE("can not find component[%{public}s] in core", componentName);
42        return err;
43    }
44    auto core = iter->second;
45    if (core == nullptr) {
46        CODEC_LOGE("can not find core of comonentName");
47        return HDF_FAILURE;
48    }
49    OMX_HANDLETYPE handle = nullptr;
50    std::string name(componentName);
51    err = core->GetHandle(handle, name, appData, *callbacks);
52    if (err == OMX_ErrorNone && handle) {
53        OMXComponent comp;
54        comp.core = core;
55        *component = reinterpret_cast<OMX_COMPONENTTYPE *>(handle);
56        comp.handle = handle;
57        components_.push_back(comp);
58    }
59    return err;
60}
61
62int32_t ComponentMgr::DeleteComponentInstance(OMX_COMPONENTTYPE *component)
63{
64    std::lock_guard<std::mutex> lk(mutex_);
65    int32_t err = OMX_ErrorInvalidComponent;
66    for (size_t i = 0; i < components_.size(); i++) {
67        if (components_[i].handle == component) {
68            err = components_[i].core->FreeHandle(components_[i].handle);
69            components_.erase(components_.begin() + i);
70            break;
71        }
72    }
73    return err;
74}
75
76int32_t ComponentMgr::GetRolesForComponent(const char *componentName, std::vector<std::string> *roles)
77{
78    (void)roles;
79    (void)componentName;
80    return OMX_ErrorNone;
81}
82
83void ComponentMgr::AddVendorComponent()
84{
85    AddComponentByLibName("libOMX_Core.z.so");
86    AddComponentByLibName("libomx_audio_codec.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 std::string compName)
127{
128    std::lock_guard<std::mutex> lk(mutex_);
129    auto iter = compoentsCore_.find(compName);
130    if (iter == compoentsCore_.end() || iter->second == nullptr) {
131        CODEC_LOGE("can not find component[%{public}s] in core", compName.c_str());
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