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