• 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 "camera_metadata_operator.h"
16 #include "ipp_node.h"
17 
18 namespace OHOS::Camera {
IppNode(const std::string & name,const std::string & type)19 IppNode::IppNode(const std::string& name, const std::string& type)
20     : NodeBase(name, type)
21 {
22 }
23 
~IppNode()24 IppNode::~IppNode()
25 {
26     RetCode rc = GetDeviceController();
27     if (rc == RC_ERROR) {
28         CAMERA_LOGE("GetDeviceController failed.");
29         return;
30     }
31     sensorController_->SetMetaDataCallBack(nullptr);
32 }
33 
Init(const int32_t streamId)34 RetCode IppNode::Init(const int32_t streamId)
35 {
36     (void)streamId;
37     // initialize algo plugin
38     if (offlineMode_.load()) {
39         return RC_OK;
40     }
41     algoPluginManager_ = std::make_shared<AlgoPluginManager>();
42     if (algoPluginManager_ == nullptr) {
43         CAMERA_LOGE("create AlgoPluginManager failed");
44         return RC_ERROR;
45     }
46     RetCode ret = algoPluginManager_->LoadPlugin();
47     if (ret != RC_OK) {
48         CAMERA_LOGE("load plugin failed.");
49         return RC_ERROR;
50     }
51     return RC_OK;
52 }
53 
Start(const int32_t streamId)54 RetCode IppNode::Start(const int32_t streamId)
55 {
56     NodeBase::Start(streamId);
57     // start offline stream process thread
58     if (offlineMode_.load()) {
59         return RC_OK;
60     }
61     algoPlugin_ = algoPluginManager_->GetAlgoPlugin(IPP_ALGO_MODE_NORMAL);
62     StartProcess();
63     return RC_OK;
64 }
65 
Flush(const int32_t streamId)66 RetCode IppNode::Flush(const int32_t streamId)
67 {
68     if (offlineMode_.load()) {
69         return RC_OK;
70     }
71 
72     if (algoPlugin_ == nullptr) {
73         CAMERA_LOGW("IppNode algoPlugin_ is null");
74         return RC_ERROR;
75     } else {
76         algoPlugin_->Flush();
77         NodeBase::Flush(streamId);
78     }
79     return RC_OK;
80 }
81 
SetCallback(const MetaDataCb cb)82 RetCode IppNode::SetCallback(const MetaDataCb cb)
83 {
84     CAMERA_LOGI("IppNode line: %{public}d", __LINE__);
85     metaDataCb_ = cb;
86     RetCode rc = GetDeviceController();
87     if (rc == RC_ERROR) {
88         CAMERA_LOGE("GetDeviceController failed.");
89         return RC_ERROR;
90     }
91     sensorController_->SetMetaDataCallBack([this](const std::shared_ptr<CameraMetadata>& metadata) {
92         OnMetadataChanged(metadata);
93     });
94     return RC_OK;
95 }
96 
OnMetadataChanged(const std::shared_ptr<CameraMetadata> & metadata)97 void IppNode::OnMetadataChanged(const std::shared_ptr<CameraMetadata>& metadata)
98 {
99     if (metadata == nullptr) {
100         CAMERA_LOGE("meta is nullptr");
101         return;
102     }
103     // device metadata changed callback
104     GetNodeMetaData(metadata);
105     if (metaDataCb_ == nullptr) {
106         CAMERA_LOGE("metaDataCb_ is nullptr");
107         return;
108     }
109     metaDataCb_(metadata);
110 }
111 
GetNodeMetaData(std::shared_ptr<CameraMetadata> metadata)112 void IppNode::GetNodeMetaData(std::shared_ptr<CameraMetadata> metadata)
113 {
114     GetFocusMode(metadata);
115     GetFocusState(metadata);
116     GetExposureMode(metadata);
117     GetExposureTime(metadata);
118     GetExposureCompensation(metadata);
119     GetExposureState(metadata);
120 }
121 
GetFocusMode(std::shared_ptr<CameraMetadata> meta)122 void IppNode::GetFocusMode(std::shared_ptr<CameraMetadata> meta)
123 {
124     uint8_t focusMode = OHOS_CAMERA_FOCUS_MODE_LOCKED;
125     meta->addEntry(OHOS_CONTROL_FOCUS_MODE, &focusMode, sizeof(focusMode));
126 }
127 
GetFocusState(std::shared_ptr<CameraMetadata> meta)128 void IppNode::GetFocusState(std::shared_ptr<CameraMetadata> meta)
129 {
130     uint8_t focusState = OHOS_CAMERA_FOCUS_STATE_UNFOCUSED;
131     meta->addEntry(OHOS_CONTROL_FOCUS_STATE, &focusState, sizeof(focusState));
132 }
133 
GetExposureMode(std::shared_ptr<CameraMetadata> meta)134 void IppNode::GetExposureMode(std::shared_ptr<CameraMetadata> meta)
135 {
136     uint8_t exposureMode = OHOS_CAMERA_EXPOSURE_MODE_AUTO;
137     meta->addEntry(OHOS_CONTROL_EXPOSURE_MODE, &exposureMode, sizeof(exposureMode));
138 }
139 
GetExposureTime(std::shared_ptr<CameraMetadata> meta)140 void IppNode::GetExposureTime(std::shared_ptr<CameraMetadata> meta)
141 {
142     int64_t exposureTime = 1;
143     meta->addEntry(OHOS_SENSOR_EXPOSURE_TIME, &exposureTime, sizeof(exposureTime));
144 }
145 
GetExposureCompensation(std::shared_ptr<CameraMetadata> meta)146 void IppNode::GetExposureCompensation(std::shared_ptr<CameraMetadata> meta)
147 {
148     int32_t exposureCompensation = 1;
149     meta->addEntry(OHOS_CONTROL_AE_EXPOSURE_COMPENSATION, &exposureCompensation, sizeof(exposureCompensation));
150 }
151 
GetExposureState(std::shared_ptr<CameraMetadata> meta)152 void IppNode::GetExposureState(std::shared_ptr<CameraMetadata> meta)
153 {
154     uint8_t exposureState = OHOS_CAMERA_EXPOSURE_STATE_SCAN;
155     meta->addEntry(OHOS_CONTROL_EXPOSURE_STATE, &exposureState, sizeof(exposureState));
156 }
157 
GetDeviceController()158 RetCode IppNode::GetDeviceController()
159 {
160     deviceManager_ = IDeviceManager::GetInstance();
161     if (deviceManager_ == nullptr) {
162         CAMERA_LOGE("get device manager failed.");
163         return RC_ERROR;
164     }
165     CameraId cameraId = CAMERA_FIRST;
166     sensorController_ = std::static_pointer_cast<IController>
167         (deviceManager_->GetController(cameraId, DM_M_SENSOR, DM_C_SENSOR));
168     if (sensorController_ == nullptr) {
169         CAMERA_LOGE("get device controller failed");
170         return RC_ERROR;
171     }
172     return RC_OK;
173 }
174 
Stop(const int32_t streamId)175 RetCode IppNode::Stop(const int32_t streamId)
176 {
177     // stop offline stream process thread
178     if (offlineMode_.load()) {
179         return RC_OK;
180     }
181     algoPlugin_->Stop();
182 
183     StopProcess();
184     NodeBase::Stop(streamId);
185     return RC_OK;
186 }
187 
Config(const int32_t streamId,const CaptureMeta & meta)188 RetCode IppNode::Config(const int32_t streamId, const CaptureMeta& meta)
189 {
190     (void)streamId;
191     (void)meta;
192     // configure algo
193     // NodeBase::Configure
194     if (offlineMode_.load()) {
195         return RC_OK;
196     }
197 
198     return RC_OK;
199 }
200 
UpdateSettingsConfig(const CaptureMeta & meta)201 RetCode IppNode::UpdateSettingsConfig(const CaptureMeta& meta)
202 {
203     CAMERA_LOGI("IppNode line: %{public}d", __LINE__);
204     return SendNodeMetaData(meta);
205 }
206 
SendNodeMetaData(const std::shared_ptr<CameraMetadata> meta)207 RetCode IppNode::SendNodeMetaData(const std::shared_ptr<CameraMetadata> meta)
208 {
209     if (meta == nullptr) {
210         CAMERA_LOGE("meta is nullptr");
211         return RC_ERROR;
212     }
213     common_metadata_header_t *data = meta->get();
214     if (data == nullptr) {
215         CAMERA_LOGE("data is nullptr");
216         return RC_ERROR;
217     }
218 
219     RetCode rc = SendExposureMetaData(data);
220     if (rc == RC_ERROR) {
221         CAMERA_LOGE("SendExposureMetaData fail");
222     }
223     rc = SendFocusMetaData(data);
224     if (rc == RC_ERROR) {
225         CAMERA_LOGE("SendFocusMetaData fail");
226     }
227     return rc;
228 }
229 
SendExposureMetaData(const common_metadata_header_t * data)230 RetCode IppNode::SendExposureMetaData(const common_metadata_header_t *data)
231 {
232     camera_metadata_item_t entry;
233     (void) data;
234 
235     int ret = FindCameraMetadataItem(data, OHOS_CONTROL_EXPOSURE_MODE, &entry);
236     if (ret == 0) {
237         uint8_t exposureMode = *(entry.data.u8);
238         CAMERA_LOGI("Set  exposureMode [%{public}d]", exposureMode);
239     }
240 
241     ret = FindCameraMetadataItem(data, OHOS_SENSOR_EXPOSURE_TIME, &entry);
242     if (ret == 0) {
243         int64_t exposureTime = *(entry.data.i64);
244         CAMERA_LOGI("Set exposureTime [%{public}d]", exposureTime);
245     }
246 
247     ret = FindCameraMetadataItem(data, OHOS_CONTROL_AE_EXPOSURE_COMPENSATION, &entry);
248     if (ret == 0) {
249         int32_t exposureCompensation = *(entry.data.i32);
250         CAMERA_LOGI("Set exposureCompensation [%{public}d]", exposureCompensation);
251     }
252 
253     return RC_OK;
254 }
255 
SendFocusMetaData(const common_metadata_header_t * data)256 RetCode IppNode::SendFocusMetaData(const common_metadata_header_t *data)
257 {
258     camera_metadata_item_t entry;
259     (void) data;
260 
261     int ret = FindCameraMetadataItem(data, OHOS_CONTROL_FOCUS_MODE, &entry);
262     if (ret == 0) {
263         uint8_t focusMode = *(entry.data.u8);
264         CAMERA_LOGI("Set focusMode [%{public}d]", focusMode);
265     }
266 
267     ret = FindCameraMetadataItem(data, OHOS_CONTROL_AF_REGIONS, &entry);
268     if (ret == 0) {
269         std::vector<int32_t> afRegions;
270         for (int i = 0; i < entry.count; i++) {
271             CAMERA_LOGI("Set afRegions [%{public}d]", *(entry.data.i32 + i));
272             afRegions.push_back(*(entry.data.i32 + i));
273         }
274     }
275 
276     return RC_OK;
277 }
278 
DeliverBuffer(std::shared_ptr<IBuffer> & buffer)279 void IppNode::DeliverBuffer(std::shared_ptr<IBuffer>& buffer)
280 {
281     std::vector<std::shared_ptr<IBuffer>> cache;
282     cache.emplace_back(buffer);
283 
284     ReceiveCache(cache);
285     return;
286 }
287 
DeliverBuffers(std::vector<std::shared_ptr<IBuffer>> & buffers)288 void IppNode::DeliverBuffers(std::vector<std::shared_ptr<IBuffer>>& buffers)
289 {
290     std::vector<std::shared_ptr<IBuffer>> cache;
291     for (auto it : buffers) {
292         cache.emplace_back(it);
293     }
294 
295     ReceiveCache(cache);
296     return;
297 }
298 
ProcessCache(std::vector<std::shared_ptr<IBuffer>> & buffers)299 void IppNode::ProcessCache(std::vector<std::shared_ptr<IBuffer>>& buffers)
300 {
301     // process buffers with algorithm
302     std::shared_ptr<IBuffer> outBuffer = nullptr;
303     RetCode ret = GetOutputBuffer(buffers, outBuffer);
304     if (ret != RC_OK) {
305         CAMERA_LOGE("fatal error, can't get output buffer, ipp will do nothing.");
306         return;
307     }
308     std::shared_ptr<CameraMetadata> meta = nullptr;
309     if (algoPlugin_ != nullptr) {
310         CAMERA_LOGV("process buffers with algo, input buffer count = %{public}u.", buffers.size());
311         algoPlugin_->Process(outBuffer, buffers, meta);
312     }
313 
314     std::shared_ptr<IBuffer> algoProduct = nullptr;
315     std::vector<std::shared_ptr<IBuffer>> recycleBuffers{};
316     ClassifyOutputBuffer(outBuffer, buffers, algoProduct, recycleBuffers);
317 
318     DeliverAlgoProductBuffer(algoProduct);
319     DeliverCache(recycleBuffers);
320     CAMERA_LOGV("process algo completed.");
321     return;
322 }
323 
DeliverCache(std::vector<std::shared_ptr<IBuffer>> & buffers)324 void IppNode::DeliverCache(std::vector<std::shared_ptr<IBuffer>>& buffers)
325 {
326     OfflinePipeline::DeliverCacheCheck(buffers);
327 }
328 
DeliverCancelCache(std::vector<std::shared_ptr<IBuffer>> & buffers)329 void IppNode::DeliverCancelCache(std::vector<std::shared_ptr<IBuffer>>& buffers)
330 {
331     std::shared_ptr<IBuffer> outBuffer = nullptr;
332     RetCode ret = GetOutputBuffer(buffers, outBuffer);
333     if (ret != RC_OK) {
334         CAMERA_LOGE("fatal error, can't return buffer.");
335         return;
336     }
337 
338     std::shared_ptr<IBuffer> algoProduct = nullptr;
339     std::vector<std::shared_ptr<IBuffer>> recycleBuffers{};
340     ClassifyOutputBuffer(outBuffer, buffers, algoProduct, recycleBuffers);
341     if (algoProduct == nullptr) {
342         return;
343     }
344     DeliverAlgoProductBuffer(algoProduct);
345     DeliverCache(recycleBuffers);
346 
347     return;
348 }
349 
GetOutputBuffer(std::vector<std::shared_ptr<IBuffer>> & buffers,std::shared_ptr<IBuffer> & outBuffer)350 RetCode IppNode::GetOutputBuffer(std::vector<std::shared_ptr<IBuffer>>& buffers, std::shared_ptr<IBuffer>& outBuffer)
351 {
352     auto outPort = GetOutPortById(0);
353     if (outPort == nullptr) {
354         CAMERA_LOGE("fatal error, can't get out port.");
355         return RC_ERROR;
356     }
357 
358     PortFormat format {};
359     outPort->GetFormat(format);
360     auto id = format.bufferPoolId_;
361     for (auto it : buffers) {
362         if (id == it->GetPoolId()) {
363             outBuffer = nullptr;
364             return RC_OK;
365         }
366     }
367 
368     auto bufferManager = BufferManager::GetInstance();
369     if (bufferManager == nullptr) {
370         CAMERA_LOGE("fatal error, can't get buffer manager.");
371         return RC_ERROR;
372     }
373     auto bufferPool = bufferManager->GetBufferPool(id);
374     if (bufferPool == nullptr) {
375         CAMERA_LOGE("fatal error, can't get buffer pool.");
376         return RC_ERROR;
377     }
378 
379     outBuffer = bufferPool->AcquireBuffer(-1);
380 
381     return RC_OK;
382 }
383 
DeliverAlgoProductBuffer(std::shared_ptr<IBuffer> & result)384 void IppNode::DeliverAlgoProductBuffer(std::shared_ptr<IBuffer>& result)
385 {
386     if (offlineMode_.load()) {
387         CAMERA_LOGV("deliver buffer to offline stream");
388         DeliverOfflineBuffer(result);
389     } else {
390         std::shared_ptr<IPort> outPort = GetOutPortById(0);
391         if (outPort == nullptr) {
392             CAMERA_LOGE("can't find out port, deliver algo product failed.");
393             return;
394         }
395         outPort->DeliverBuffer(result);
396     }
397 
398     return;
399 }
400 
ClassifyOutputBuffer(std::shared_ptr<IBuffer> & outBuffer,std::vector<std::shared_ptr<IBuffer>> & inBuffers,std::shared_ptr<IBuffer> & product,std::vector<std::shared_ptr<IBuffer>> & recycleBuffers)401 void IppNode::ClassifyOutputBuffer(std::shared_ptr<IBuffer>& outBuffer,
402                                    std::vector<std::shared_ptr<IBuffer>>& inBuffers,
403                                    std::shared_ptr<IBuffer>& product,
404                                    std::vector<std::shared_ptr<IBuffer>>& recycleBuffers)
405 {
406     if (outBuffer != nullptr) {
407         product = outBuffer;
408         recycleBuffers = inBuffers;
409         return;
410     }
411     auto outPort = GetOutPortById(0);
412     if (outPort == nullptr) {
413         CAMERA_LOGE("fatal error, can't get out port.");
414         return;
415     }
416 
417     PortFormat format {};
418     outPort->GetFormat(format);
419     auto id = format.bufferPoolId_;
420     auto it = std::find_if(inBuffers.begin(), inBuffers.end(),
421                            [&id](const std::shared_ptr<IBuffer>& buffer) { return buffer->GetPoolId() == id; });
422     if (it == inBuffers.end()) {
423         CAMERA_LOGE("fatal error, outBuffer should be null.");
424         return;
425     }
426     product = *it;
427     inBuffers.erase(it);
428     recycleBuffers = inBuffers;
429     product->SetCaptureId(inBuffers[0]->GetCaptureId());
430     product->SetBufferStatus(inBuffers[0]->GetBufferStatus());
431     return;
432 }
433 REGISTERNODE(IppNode, {"ipp"});
434 } // namespace OHOS::Camera
435