• 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 "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 (int 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 
314     ReceiveCache(cache);
315     return;
316 }
317 
DeliverBuffers(std::vector<std::shared_ptr<IBuffer>> & buffers)318 void IppNode::DeliverBuffers(std::vector<std::shared_ptr<IBuffer>>& buffers)
319 {
320     std::vector<std::shared_ptr<IBuffer>> cache;
321     for (auto it : buffers) {
322         cache.emplace_back(it);
323     }
324 
325     ReceiveCache(cache);
326     return;
327 }
328 
ProcessCache(std::vector<std::shared_ptr<IBuffer>> & buffers)329 void IppNode::ProcessCache(std::vector<std::shared_ptr<IBuffer>>& buffers)
330 {
331     // process buffers with algorithm
332     std::shared_ptr<IBuffer> outBuffer = nullptr;
333     RetCode ret = GetOutputBuffer(buffers, outBuffer);
334     if (ret != RC_OK) {
335         CAMERA_LOGE("fatal error, can't get output buffer, ipp will do nothing.");
336         return;
337     }
338     std::shared_ptr<CameraMetadata> meta = nullptr;
339     if (algoPlugin_ != nullptr) {
340         CAMERA_LOGV("process buffers with algo, input buffer count = %{public}u.", buffers.size());
341         algoPlugin_->Process(outBuffer, buffers, meta);
342     }
343 
344     std::shared_ptr<IBuffer> algoProduct = nullptr;
345     std::vector<std::shared_ptr<IBuffer>> recycleBuffers{};
346     ClassifyOutputBuffer(outBuffer, buffers, algoProduct, recycleBuffers);
347 
348     DeliverAlgoProductBuffer(algoProduct);
349     DeliverCache(recycleBuffers);
350     CAMERA_LOGV("process algo completed.");
351     return;
352 }
353 
DeliverCache(std::vector<std::shared_ptr<IBuffer>> & buffers)354 void IppNode::DeliverCache(std::vector<std::shared_ptr<IBuffer>>& buffers)
355 {
356     OfflinePipeline::DeliverCacheCheck(buffers);
357 }
358 
DeliverCancelCache(std::vector<std::shared_ptr<IBuffer>> & buffers)359 void IppNode::DeliverCancelCache(std::vector<std::shared_ptr<IBuffer>>& buffers)
360 {
361     std::shared_ptr<IBuffer> outBuffer = nullptr;
362     RetCode ret = GetOutputBuffer(buffers, outBuffer);
363     if (ret != RC_OK) {
364         CAMERA_LOGE("fatal error, can't return buffer.");
365         return;
366     }
367 
368     std::shared_ptr<IBuffer> algoProduct = nullptr;
369     std::vector<std::shared_ptr<IBuffer>> recycleBuffers{};
370     ClassifyOutputBuffer(outBuffer, buffers, algoProduct, recycleBuffers);
371     if (algoProduct == nullptr) {
372         return;
373     }
374     DeliverAlgoProductBuffer(algoProduct);
375     DeliverCache(recycleBuffers);
376 
377     return;
378 }
379 
GetOutputBuffer(std::vector<std::shared_ptr<IBuffer>> & buffers,std::shared_ptr<IBuffer> & outBuffer)380 RetCode IppNode::GetOutputBuffer(std::vector<std::shared_ptr<IBuffer>>& buffers, std::shared_ptr<IBuffer>& outBuffer)
381 {
382     auto outPort = GetOutPortById(0);
383     if (outPort == nullptr) {
384         CAMERA_LOGE("fatal error, can't get out port.");
385         return RC_ERROR;
386     }
387 
388     PortFormat format {};
389     outPort->GetFormat(format);
390     auto id = format.bufferPoolId_;
391     for (auto it : buffers) {
392         if (id == it->GetPoolId()) {
393             outBuffer = nullptr;
394             return RC_OK;
395         }
396     }
397 
398     auto bufferManager = BufferManager::GetInstance();
399     if (bufferManager == nullptr) {
400         CAMERA_LOGE("fatal error, can't get buffer manager.");
401         return RC_ERROR;
402     }
403     auto bufferPool = bufferManager->GetBufferPool(id);
404     if (bufferPool == nullptr) {
405         CAMERA_LOGE("fatal error, can't get buffer pool.");
406         return RC_ERROR;
407     }
408 
409     outBuffer = bufferPool->AcquireBuffer(-1);
410 
411     return RC_OK;
412 }
413 
DeliverAlgoProductBuffer(std::shared_ptr<IBuffer> & result)414 void IppNode::DeliverAlgoProductBuffer(std::shared_ptr<IBuffer>& result)
415 {
416     if (offlineMode_.load()) {
417         CAMERA_LOGV("deliver buffer to offline stream");
418         DeliverOfflineBuffer(result);
419     } else {
420         std::shared_ptr<IPort> outPort = GetOutPortById(0);
421         if (outPort == nullptr) {
422             CAMERA_LOGE("can't find out port, deliver algo product failed.");
423             return;
424         }
425         outPort->DeliverBuffer(result);
426     }
427 
428     return;
429 }
430 
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)431 void IppNode::ClassifyOutputBuffer(std::shared_ptr<IBuffer>& outBuffer,
432                                    std::vector<std::shared_ptr<IBuffer>>& inBuffers,
433                                    std::shared_ptr<IBuffer>& product,
434                                    std::vector<std::shared_ptr<IBuffer>>& recycleBuffers)
435 {
436     if (outBuffer != nullptr) {
437         product = outBuffer;
438         recycleBuffers = inBuffers;
439         return;
440     }
441     auto outPort = GetOutPortById(0);
442     if (outPort == nullptr) {
443         CAMERA_LOGE("fatal error, can't get out port.");
444         return;
445     }
446 
447     PortFormat format {};
448     outPort->GetFormat(format);
449     auto id = format.bufferPoolId_;
450     auto it = std::find_if(inBuffers.begin(), inBuffers.end(),
451                            [&id](const std::shared_ptr<IBuffer>& buffer) { return buffer->GetPoolId() == id; });
452     if (it == inBuffers.end()) {
453         CAMERA_LOGE("fatal error, outBuffer should be null.");
454         return;
455     }
456     product = *it;
457     inBuffers.erase(it);
458     recycleBuffers = inBuffers;
459     product->SetCaptureId(inBuffers[0]->GetCaptureId());
460     product->SetBufferStatus(inBuffers[0]->GetBufferStatus());
461     return;
462 }
463 REGISTERNODE(IppNode, {"ipp"});
464 } // namespace OHOS::Camera
465