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