1 /*
2 * Copyright (c) 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 "algo_plugin.h"
16 #include <dlfcn.h>
17
18 namespace OHOS::Camera {
AlgoPlugin(std::string name,std::string description,int mode,std::string path)19 AlgoPlugin::AlgoPlugin(std::string name, std::string description, int mode, std::string path)
20 {
21 name_ = name;
22 desc_ = description;
23 mode_ = mode;
24 path_ = path;
25 }
26
~AlgoPlugin()27 AlgoPlugin::~AlgoPlugin()
28 {
29 if (algoHandler_ != nullptr) {
30 UnloadLib();
31 delete algoHandler_;
32 algoHandler_ = nullptr;
33 }
34 }
35
Init(std::shared_ptr<CameraMetadata> meta)36 RetCode AlgoPlugin::Init(std::shared_ptr<CameraMetadata> meta)
37 {
38 (void)meta;
39 if (algoHandler_->func.Init == nullptr) {
40 CAMERA_LOGE("unsupported operation.");
41 return RC_ERROR;
42 }
43 // parse metadata
44 int ret = algoHandler_->func.Init(nullptr);
45 if (ret == 0) {
46 CAMERA_LOGI("algo init success, ret = %{public}d", ret);
47 return RC_OK;
48 }
49
50 return RC_ERROR;
51 }
52
Start()53 RetCode AlgoPlugin::Start()
54 {
55 if (algoHandler_->func.Start == nullptr) {
56 CAMERA_LOGE("unsupported operation.");
57 return RC_ERROR;
58 }
59 int ret = algoHandler_->func.Start();
60 if (ret != 0) {
61 CAMERA_LOGE("start algo failed, ret = %{public}d", ret);
62 return RC_ERROR;
63 }
64
65 return RC_OK;
66 }
67
Flush()68 RetCode AlgoPlugin::Flush()
69 {
70 if (algoHandler_->func.Flush == nullptr) {
71 CAMERA_LOGE("unsupported operation.");
72 return RC_ERROR;
73 }
74 int ret = algoHandler_->func.Flush();
75 if (ret != 0) {
76 CAMERA_LOGE("flush algo failed, ret = %{public}d", ret);
77 return RC_ERROR;
78 }
79
80 return RC_OK;
81 }
82
Process(std::shared_ptr<IBuffer> & outBuffer,std::vector<std::shared_ptr<IBuffer>> & inBuffers,std::shared_ptr<CameraMetadata> & meta)83 RetCode AlgoPlugin::Process(std::shared_ptr<IBuffer>& outBuffer,
84 std::vector<std::shared_ptr<IBuffer>>& inBuffers,
85 std::shared_ptr<CameraMetadata>& meta)
86 {
87 (void)meta;
88 if (algoHandler_->func.Process == nullptr) {
89 CAMERA_LOGE("unsupported operation.");
90 return RC_ERROR;
91 }
92
93 IppAlgoBuffer* outAlgoBuffer = nullptr;
94 if (outBuffer == nullptr) {
95 outAlgoBuffer = nullptr;
96 } else {
97 outAlgoBuffer = new IppAlgoBuffer();
98 if (outAlgoBuffer != nullptr) {
99 outAlgoBuffer->addr = outBuffer->GetVirAddress();
100 outAlgoBuffer->size = outBuffer->GetSize();
101 }
102 }
103
104 IppAlgoBuffer** inAlgoBuffers = new IppAlgoBuffer* [inBuffers.size()];
105 for (uint32_t i = 0; i < inBuffers.size(); i++) {
106 if (inBuffers[i] == nullptr) {
107 inAlgoBuffers[i] = nullptr;
108 } else {
109 inAlgoBuffers[i] = new IppAlgoBuffer();
110 inAlgoBuffers[i]->addr = inBuffers[i]->GetVirAddress();
111 inAlgoBuffers[i]->size = inBuffers[i]->GetSize();
112 inAlgoBuffers[i]->width = inBuffers[i]->GetWidth();
113 inAlgoBuffers[i]->height = inBuffers[i]->GetHeight();
114 inAlgoBuffers[i]->stride = inBuffers[i]->GetStride();
115 inAlgoBuffers[i]->id = i;
116 }
117 }
118
119 int ret = algoHandler_->func.Process(inAlgoBuffers, inBuffers.size(), outAlgoBuffer, nullptr);
120 if (outAlgoBuffer != nullptr) {
121 delete outAlgoBuffer;
122 outAlgoBuffer = nullptr;
123 }
124
125 for (int i = 0; i < inBuffers.size(); i++) {
126 if (inAlgoBuffers[i] != nullptr) {
127 delete inAlgoBuffers[i];
128 inAlgoBuffers[i] = nullptr;
129 }
130 }
131 delete[] inAlgoBuffers;
132 inAlgoBuffers = nullptr;
133
134 if (ret != 0) {
135 CAMERA_LOGE("process algo failed, ret = %{public}d", ret);
136 return RC_ERROR;
137 }
138 return RC_OK;
139 }
140
Stop()141 RetCode AlgoPlugin::Stop()
142 {
143 if (algoHandler_->func.Stop == nullptr) {
144 CAMERA_LOGE("unsupported operation.");
145 return RC_ERROR;
146 }
147 int ret = algoHandler_->func.Stop();
148 if (ret != 0) {
149 CAMERA_LOGE("stop algo failed, ret = %{public}d", ret);
150 return RC_ERROR;
151 }
152
153 return RC_OK;
154 }
155
CheckLibPath(const char * path)156 RetCode AlgoPlugin::CheckLibPath(const char *path)
157 {
158 char absPath[PATH_MAX] = {0};
159 if (path == nullptr || (realpath(path, absPath) == nullptr)) {
160 CAMERA_LOGE("path is nullptr.");
161 return RC_ERROR;
162 }
163 return RC_OK;
164 }
165
LoadLib()166 RetCode AlgoPlugin::LoadLib()
167 {
168 algoHandler_ = new IppAlgoHandler();
169 if (algoHandler_ == nullptr) {
170 CAMERA_LOGE("create algo handler failed.");
171 return RC_ERROR;
172 }
173
174 if (path_.size() == 0) {
175 CAMERA_LOGE("path is null");
176 return RC_ERROR;
177 }
178
179 uint32_t ret = CheckLibPath(path_.c_str());
180 if (ret == RC_ERROR) {
181 CAMERA_LOGE("lib path:%{public}s is error.", path_.c_str());
182 return RC_ERROR;
183 }
184
185 algoHandler_->handle = ::dlopen(path_.c_str(), RTLD_NOW);
186 if (algoHandler_->handle == nullptr) {
187 CAMERA_LOGE("dlopen %{public}s failed, %{public}s", path_.c_str(), ::dlerror());
188 return RC_ERROR;
189 }
190
191 algoHandler_->func.Init = reinterpret_cast<AlgoFuncInit>(::dlsym(algoHandler_->handle, "Init"));
192 if (algoHandler_->func.Init == nullptr) {
193 CAMERA_LOGE("can't get symbol of function Init, %{public}s", ::dlerror());
194 return RC_ERROR;
195 }
196
197 algoHandler_->func.Start = reinterpret_cast<AlgoFuncStart>(::dlsym(algoHandler_->handle, "Start"));
198 if (algoHandler_->func.Start == nullptr) {
199 CAMERA_LOGE("can't get symbol of function Start, %{public}s", ::dlerror());
200 return RC_ERROR;
201 }
202
203 algoHandler_->func.Flush = reinterpret_cast<AlgoFuncFlush>(::dlsym(algoHandler_->handle, "Flush"));
204 if (algoHandler_->func.Flush == nullptr) {
205 CAMERA_LOGE("can't get symbol of function Flush, %{public}s", ::dlerror());
206 return RC_ERROR;
207 }
208
209 algoHandler_->func.Process = reinterpret_cast<AlgoFuncProcess>(::dlsym(algoHandler_->handle, "Process"));
210 if (algoHandler_->func.Process == nullptr) {
211 CAMERA_LOGE("can't get symbol of function Process, %{public}s", ::dlerror());
212 return RC_ERROR;
213 }
214
215 algoHandler_->func.Stop = reinterpret_cast<AlgoFuncStop>(::dlsym(algoHandler_->handle, "Stop"));
216 if (algoHandler_->func.Stop == nullptr) {
217 CAMERA_LOGE("can't get symbol of function Stop, %{public}s", ::dlerror());
218 return RC_ERROR;
219 }
220
221 return RC_OK;
222 }
223
UnloadLib()224 RetCode AlgoPlugin::UnloadLib()
225 {
226 if (algoHandler_->handle != nullptr) {
227 CAMERA_LOGI("handle is already closed.");
228 return RC_OK;
229 }
230
231 int ret = ::dlclose(algoHandler_->handle);
232 if (ret) {
233 CAMERA_LOGE("dlclose %{public}s failed", path_.c_str());
234 return RC_ERROR;
235 }
236
237 return RC_OK;
238 }
239
GetMode() const240 int AlgoPlugin::GetMode() const
241 {
242 return mode_;
243 }
244
GetName() const245 std::string AlgoPlugin::GetName() const
246 {
247 return name_;
248 }
249 } // namespace OHOS::Camera
250