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