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(std::nothrow) IppAlgoBuffer* [inBuffers.size()];
105 if (inAlgoBuffers == nullptr) {
106 CAMERA_LOGE("create inAlgoBuffers failed.");
107 if (outAlgoBuffer != nullptr) {
108 delete outAlgoBuffer;
109 outAlgoBuffer = nullptr;
110 }
111 return RC_ERROR;
112 }
113 SetInAlgoBuffers(inBuffers, inAlgoBuffers);
114 int ret = algoHandler_->func.Process(inAlgoBuffers, inBuffers.size(), outAlgoBuffer, nullptr);
115 if (outAlgoBuffer != nullptr) {
116 delete outAlgoBuffer;
117 outAlgoBuffer = nullptr;
118 }
119
120 for (unsigned int i = 0; i < inBuffers.size(); i++) {
121 if (inAlgoBuffers[i] != nullptr) {
122 delete inAlgoBuffers[i];
123 inAlgoBuffers[i] = nullptr;
124 }
125 }
126 delete[] inAlgoBuffers;
127 inAlgoBuffers = nullptr;
128
129 if (ret != 0) {
130 CAMERA_LOGE("process algo failed, ret = %{public}d", ret);
131 return RC_ERROR;
132 }
133 return RC_OK;
134 }
135
SetInAlgoBuffers(std::vector<std::shared_ptr<IBuffer>> & inBuffers,IppAlgoBuffer ** inAlgoBuffers)136 void AlgoPlugin::SetInAlgoBuffers(std::vector<std::shared_ptr<IBuffer>>& inBuffers, IppAlgoBuffer** inAlgoBuffers)
137 {
138 for (uint32_t i = 0; i < inBuffers.size(); i++) {
139 if (inBuffers[i] == nullptr) {
140 inAlgoBuffers[i] = nullptr;
141 } else {
142 inAlgoBuffers[i] = new(std::nothrow) IppAlgoBuffer();
143 if (inAlgoBuffers[i] != nullptr) {
144 inAlgoBuffers[i]->addr = inBuffers[i]->GetVirAddress();
145 inAlgoBuffers[i]->size = inBuffers[i]->GetSize();
146 inAlgoBuffers[i]->width = inBuffers[i]->GetWidth();
147 inAlgoBuffers[i]->height = inBuffers[i]->GetHeight();
148 inAlgoBuffers[i]->stride = inBuffers[i]->GetStride();
149 inAlgoBuffers[i]->id = static_cast<int>(i);
150 }
151 }
152 }
153 }
154
Stop()155 RetCode AlgoPlugin::Stop()
156 {
157 if (algoHandler_->func.Stop == nullptr) {
158 CAMERA_LOGE("unsupported operation.");
159 return RC_ERROR;
160 }
161 int ret = algoHandler_->func.Stop();
162 if (ret != 0) {
163 CAMERA_LOGE("stop algo failed, ret = %{public}d", ret);
164 return RC_ERROR;
165 }
166
167 return RC_OK;
168 }
169
CheckLibPath(const char * path)170 RetCode AlgoPlugin::CheckLibPath(const char *path)
171 {
172 char absPath[PATH_MAX] = {0};
173 if (path == nullptr || (realpath(path, absPath) == nullptr)) {
174 CAMERA_LOGE("path is nullptr.");
175 return RC_ERROR;
176 }
177 return RC_OK;
178 }
179
LoadLib()180 RetCode AlgoPlugin::LoadLib()
181 {
182 algoHandler_ = new IppAlgoHandler();
183 if (algoHandler_ == nullptr) {
184 CAMERA_LOGE("create algo handler failed.");
185 return RC_ERROR;
186 }
187
188 if (path_.size() == 0) {
189 CAMERA_LOGE("path is null");
190 return RC_ERROR;
191 }
192
193 uint32_t ret = CheckLibPath(path_.c_str());
194 if (ret == RC_ERROR) {
195 CAMERA_LOGE("lib path:%{public}s is error.", path_.c_str());
196 return RC_ERROR;
197 }
198
199 algoHandler_->handle = ::dlopen(path_.c_str(), RTLD_NOW);
200 if (algoHandler_->handle == nullptr) {
201 CAMERA_LOGE("dlopen %{public}s failed, %{public}s", path_.c_str(), ::dlerror());
202 return RC_ERROR;
203 }
204
205 algoHandler_->func.Init = reinterpret_cast<AlgoFuncInit>(::dlsym(algoHandler_->handle, "Init"));
206 if (algoHandler_->func.Init == nullptr) {
207 CAMERA_LOGE("can't get symbol of function Init, %{public}s", ::dlerror());
208 return RC_ERROR;
209 }
210
211 algoHandler_->func.Start = reinterpret_cast<AlgoFuncStart>(::dlsym(algoHandler_->handle, "Start"));
212 if (algoHandler_->func.Start == nullptr) {
213 CAMERA_LOGE("can't get symbol of function Start, %{public}s", ::dlerror());
214 return RC_ERROR;
215 }
216
217 algoHandler_->func.Flush = reinterpret_cast<AlgoFuncFlush>(::dlsym(algoHandler_->handle, "Flush"));
218 if (algoHandler_->func.Flush == nullptr) {
219 CAMERA_LOGE("can't get symbol of function Flush, %{public}s", ::dlerror());
220 return RC_ERROR;
221 }
222
223 algoHandler_->func.Process = reinterpret_cast<AlgoFuncProcess>(::dlsym(algoHandler_->handle, "Process"));
224 if (algoHandler_->func.Process == nullptr) {
225 CAMERA_LOGE("can't get symbol of function Process, %{public}s", ::dlerror());
226 return RC_ERROR;
227 }
228
229 algoHandler_->func.Stop = reinterpret_cast<AlgoFuncStop>(::dlsym(algoHandler_->handle, "Stop"));
230 if (algoHandler_->func.Stop == nullptr) {
231 CAMERA_LOGE("can't get symbol of function Stop, %{public}s", ::dlerror());
232 return RC_ERROR;
233 }
234
235 return RC_OK;
236 }
237
UnloadLib()238 RetCode AlgoPlugin::UnloadLib()
239 {
240 if (algoHandler_->handle != nullptr) {
241 CAMERA_LOGI("handle is already closed.");
242 return RC_OK;
243 }
244
245 int ret = ::dlclose(algoHandler_->handle);
246 if (ret) {
247 CAMERA_LOGE("dlclose %{public}s failed", path_.c_str());
248 return RC_ERROR;
249 }
250
251 return RC_OK;
252 }
253
GetMode() const254 int AlgoPlugin::GetMode() const
255 {
256 return mode_;
257 }
258
GetName() const259 std::string AlgoPlugin::GetName() const
260 {
261 return name_;
262 }
263 } // namespace OHOS::Camera
264