• 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 
16 #include "camera_device_impl.h"
17 #include <chrono>
18 #include "ipipeline_core.h"
19 #include "camera_host_config.h"
20 #include "idevice_manager.h"
21 #include "camera_metadata_info.h"
22 #include "watchdog.h"
23 #include "metadata_utils.h"
24 
25 #define HDI_DEVICE_PLACE_A_WATCHDOG \
26     PLACE_A_NOKILL_WATCHDOG(std::bind(&CameraDeviceImpl::OnRequestTimeout, this))
27 
28 namespace OHOS::Camera {
CameraDeviceImpl(const std::string & cameraId,const std::shared_ptr<IPipelineCore> & pipelineCore)29 CameraDeviceImpl::CameraDeviceImpl(const std::string &cameraId,
30     const std::shared_ptr<IPipelineCore> &pipelineCore)
31     : isOpened_(false),
32       cameraId_(cameraId),
33       pipelineCore_(pipelineCore),
34       cameraDeciceCallback_(nullptr),
35       spStreamOperator_(nullptr),
36       metaResultMode_(PER_FRAME),
37       metadataResultsBase_(nullptr),
38       metadataResults_(nullptr)
39 {
40 }
41 
CreateCameraDevice(const std::string & cameraId)42 std::shared_ptr<CameraDeviceImpl> CameraDeviceImpl::CreateCameraDevice(const std::string &cameraId)
43 {
44     // create pipelineCore
45     std::shared_ptr<IPipelineCore> pipelineCore = IPipelineCore::Create();
46     if (pipelineCore == nullptr) {
47         CAMERA_LOGW("create pipeline core failed. [cameraId = %{public}s]", cameraId.c_str());
48         return nullptr;
49     }
50 
51     RetCode rc = pipelineCore->Init();
52     if (rc != RC_OK) {
53         CAMERA_LOGW("pipeline core init failed. [cameraId = %{public}s]", cameraId.c_str());
54         return nullptr;
55     }
56 
57     std::shared_ptr<CameraDeviceImpl> device = std::make_shared<CameraDeviceImpl>(cameraId, pipelineCore);
58     if (device == nullptr) {
59         CAMERA_LOGW("create camera device failed. [cameraId = %{public}s]", cameraId.c_str());
60         return nullptr;
61     }
62     CAMERA_LOGD("create camera device success. [cameraId = %{public}s]", cameraId.c_str());
63 
64     // set deviceManager metadata & dev status callback
65     std::shared_ptr<IDeviceManager> deviceManager = IDeviceManager::GetInstance();
66     if (deviceManager != nullptr) {
67         deviceManager->SetMetaDataCallBack([device](const std::shared_ptr<CameraMetadata> &metadata) {
68             device->OnMetadataChanged(metadata);
69         });
70         deviceManager->SetDevStatusCallBack([device]() {
71             device->OnDevStatusErr();
72         });
73     }
74 
75     return device;
76 }
77 
GetStreamOperator(const sptr<IStreamOperatorCallback> & callbackObj,sptr<IStreamOperator> & streamOperator)78 int32_t CameraDeviceImpl::GetStreamOperator(const sptr<IStreamOperatorCallback>& callbackObj,
79     sptr<IStreamOperator>& streamOperator)
80 {
81     HDI_DEVICE_PLACE_A_WATCHDOG;
82     DFX_LOCAL_HITRACE_BEGIN;
83     if (callbackObj == nullptr) {
84         CAMERA_LOGW("input callback is null.");
85         return INVALID_ARGUMENT;
86     }
87 
88     spCameraDeciceCallback_ = callbackObj;
89     if (spStreamOperator_ == nullptr) {
90 #ifdef CAMERA_BUILT_ON_OHOS_LITE
91         spStreamOperator_ = std::make_shared<StreamOperator>(spCameraDeciceCallback_, shared_from_this());
92 #else
93         spStreamOperator_ = new(std::nothrow) StreamOperator(spCameraDeciceCallback_, shared_from_this());
94 #endif
95         if (spStreamOperator_ == nullptr) {
96             CAMERA_LOGW("create stream operator failed.");
97             return DEVICE_ERROR;
98         }
99         spStreamOperator_->Init();
100         ismOperator_ = spStreamOperator_;
101     }
102     streamOperator = ismOperator_;
103 #ifndef CAMERA_BUILT_ON_OHOS_LITE
104     CAMERA_LOGI("CameraDeviceImpl %{public}s: line: %{public}d", __FUNCTION__, __LINE__);
105     pipelineCore_->GetStreamPipelineCore()->SetCallback(
106         [this](const std::shared_ptr<CameraMetadata> &metadata) {
107         OnMetadataChanged(metadata);
108     });
109 #endif
110     DFX_LOCAL_HITRACE_END;
111     return HDI::Camera::V1_0::NO_ERROR;
112 }
113 
UpdateSettings(const std::vector<uint8_t> & settings)114 int32_t CameraDeviceImpl::UpdateSettings(const std::vector<uint8_t>& settings)
115 {
116     HDI_DEVICE_PLACE_A_WATCHDOG;
117     DFX_LOCAL_HITRACE_BEGIN;
118     if (settings.empty()) {
119         CAMERA_LOGE("input vector settings is empty.");
120         return INVALID_ARGUMENT;
121     }
122 
123     if (pipelineCore_ == nullptr) {
124         CAMERA_LOGE("pipeline core is null.");
125         return CAMERA_CLOSED;
126     }
127 
128     std::shared_ptr<CameraMetadata> updateSettings;
129     MetadataUtils::ConvertVecToMetadata(settings, updateSettings);
130     pipelineCore_->UpdateMetadata(updateSettings);
131     DFX_LOCAL_HITRACE_END;
132     return HDI::Camera::V1_0::NO_ERROR;
133 }
134 
SetResultMode(ResultCallbackMode mode)135 int32_t CameraDeviceImpl::SetResultMode(ResultCallbackMode mode)
136 {
137     CAMERA_LOGD("entry.");
138     if (mode < PER_FRAME || mode > ON_CHANGED) {
139         CAMERA_LOGE("parameter out of range.");
140         return INVALID_ARGUMENT;
141     } else if (mode == PER_FRAME) {
142         std::shared_ptr<IDeviceManager> deviceManager = IDeviceManager::GetInstance();
143         deviceManager->SetSendflag(true);
144     }
145 
146     metaResultMode_ = mode;
147     return HDI::Camera::V1_0::NO_ERROR;
148 }
149 
GetMetaResultMode() const150 ResultCallbackMode CameraDeviceImpl::GetMetaResultMode() const
151 {
152     return metaResultMode_;
153 }
154 
GetEnabledResults(std::vector<int32_t> & results)155 int32_t CameraDeviceImpl::GetEnabledResults(std::vector<int32_t>& results)
156 {
157     HDI_DEVICE_PLACE_A_WATCHDOG;
158     DFX_LOCAL_HITRACE_BEGIN;
159     if (deviceMetaTypes_.empty()) {
160         RetCode rc = GetEnabledFromCfg();
161         if (rc != RC_OK) {
162             CAMERA_LOGE("get enabled results from device manager failed.");
163             return DEVICE_ERROR;
164         }
165     }
166 
167     std::unique_lock<std::mutex> l(enabledRstMutex_);
168     results = enabledResults_;
169     DFX_LOCAL_HITRACE_END;
170     return HDI::Camera::V1_0::NO_ERROR;
171 }
172 
GetEnabledFromCfg()173 RetCode CameraDeviceImpl::GetEnabledFromCfg()
174 {
175     // Get devicemanager
176     std::shared_ptr<IDeviceManager> deviceManager = IDeviceManager::GetInstance();
177     if (deviceManager == nullptr) {
178         CAMERA_LOGW("device manager is null.");
179         return RC_ERROR;
180     }
181 
182     CameraHostConfig *config = CameraHostConfig::GetInstance();
183     if (config == nullptr) {
184         return RC_ERROR;
185     }
186     std::shared_ptr<CameraMetadata> ability;
187     RetCode rc = config->GetCameraAbility(cameraId_, ability);
188     if (rc != RC_OK || ability == nullptr) {
189         CAMERA_LOGD("GetCameraAbility failed.");
190         return RC_ERROR;
191     }
192 
193     common_metadata_header_t *metadata = ability->get();
194     if (metadata == nullptr) {
195         CAMERA_LOGD("ability get metadata is null.");
196         return RC_ERROR;
197     }
198 
199     camera_metadata_item_t entry;
200     int ret = FindCameraMetadataItem(metadata,
201         OHOS_ABILITY_STREAM_AVAILABLE_BASIC_CONFIGURATIONS, &entry);
202     if (ret == 0) {
203         CAMERA_LOGD("FindCameraMetadataIte tags = %{public}d. type = %{public}d", entry.count, entry.data_type);
204         for (uint32_t i = 0; i < entry.count; i++) {
205             deviceMetaTypes_.push_back(*(entry.data.i32 + i));
206         }
207     }
208 
209     return RC_OK;
210 }
211 
EnableResult(const std::vector<int32_t> & results)212 int32_t CameraDeviceImpl::EnableResult(const std::vector<int32_t>& results)
213 {
214     HDI_DEVICE_PLACE_A_WATCHDOG;
215     DFX_LOCAL_HITRACE_BEGIN;
216     std::unique_lock<std::mutex> l(enabledRstMutex_);
217     for (auto &metaType : results) {
218         auto itr = std::find(enabledResults_.begin(), enabledResults_.end(), metaType);
219         if (itr == enabledResults_.end()) {
220             enabledResults_.push_back(metaType);
221         } else {
222             CAMERA_LOGW("enabled result is existed. [metaType = %{public}d]", metaType);
223         }
224     }
225 
226     std::shared_ptr<IDeviceManager> deviceManager = IDeviceManager::GetInstance();
227     if (deviceManager == nullptr) {
228         CAMERA_LOGW("device manager is null [dm name MpiDeviceManager].");
229         return INVALID_ARGUMENT;
230     }
231     deviceManager->SetAbilityMetaDataTag(enabledResults_);
232     DFX_LOCAL_HITRACE_END;
233     return HDI::Camera::V1_0::NO_ERROR;
234 }
235 
DisableResult(const std::vector<int32_t> & results)236 int32_t CameraDeviceImpl::DisableResult(const std::vector<int32_t>& results)
237 {
238     HDI_DEVICE_PLACE_A_WATCHDOG;
239     DFX_LOCAL_HITRACE_BEGIN;
240     CamRetCode ret = HDI::Camera::V1_0::NO_ERROR;
241     std::unique_lock<std::mutex> l(enabledRstMutex_);
242     for (auto &metaType : results) {
243         auto itr = std::find(enabledResults_.begin(), enabledResults_.end(), metaType);
244         if (itr != enabledResults_.end()) {
245             enabledResults_.erase(itr);
246         } else {
247             CAMERA_LOGW("enabled result is not found. [metaType = %{public}d]", metaType);
248             ret = INVALID_ARGUMENT;
249         }
250     }
251 
252     std::shared_ptr<IDeviceManager> deviceManager1 = IDeviceManager::GetInstance();
253     if (deviceManager1 == nullptr) {
254         CAMERA_LOGW("device manager is null [dm name MpiDeviceManager].");
255         return INVALID_ARGUMENT;
256     }
257     deviceManager1->SetAbilityMetaDataTag(enabledResults_);
258     DFX_LOCAL_HITRACE_END;
259     return HDI::Camera::V1_0::NO_ERROR;
260 }
261 
GetMetadataResults(std::shared_ptr<CameraMetadata> & metadata)262 RetCode CameraDeviceImpl::GetMetadataResults(std::shared_ptr<CameraMetadata> &metadata)
263 {
264     // the value of metadataResults_ comes from event or directly from devicemanager
265     RetCode rc = RC_OK;
266     if (metadataResultsBase_ == nullptr) {
267         std::unique_lock<std::mutex> lock(metaRstMutex_);
268         if (metadataResults_ == nullptr) {
269             CAMERA_LOGE("new metadata results is null.");
270             rc = RC_ERROR;
271         } else {
272             metadataResultsBase_ = metadataResults_;
273         }
274     } else {
275         rc = UpdataMetadataResultsBase();
276     }
277     metadata = metadataResultsBase_;
278 
279     return rc;
280 }
281 
UpdataMetadataResultsBase()282 RetCode CameraDeviceImpl::UpdataMetadataResultsBase()
283 {
284     std::unique_lock<std::mutex> lock(metaRstMutex_);
285     RetCode rc = RC_ERROR;
286     if (metadataResultsBase_ == nullptr || metadataResults_ == nullptr) {
287         CAMERA_LOGD("metadataResultsBase_ or metadataResults_ is null.");
288         return rc;
289     }
290 
291     common_metadata_header_t *metadataBase = metadataResultsBase_->get();
292     common_metadata_header_t *metadataNew = metadataResults_->get();
293     if (metadataBase == nullptr || metadataNew == nullptr) {
294         lock.unlock();
295         CAMERA_LOGE("get metadata failed.");
296         return rc;
297     }
298 
299     for (auto &metaType : enabledResults_) {
300         camera_metadata_item_t baseEntry;
301         int ret = FindCameraMetadataItem(metadataBase, metaType, &baseEntry);
302         if (ret == -ENOENT) {
303             CAMERA_LOGE("metadata base not found tag.[metaType = %{public}d]", metaType);
304             continue;
305         }
306         camera_metadata_item_t newEntry;
307         ret = FindCameraMetadataItem(metadataNew, metaType, &newEntry);
308         if (ret == -ENOENT) {
309             CAMERA_LOGE("metadata result not found tag.[metaType = %{public}d]", metaType);
310             continue;
311         }
312         if (baseEntry.count == 0 || newEntry.count == 0) {
313             CAMERA_LOGE("metadata Entry count is 0");
314             continue;
315         }
316         if (!CompareTagData(baseEntry, newEntry)) {
317             metadataResultsBase_ = metadataResults_;
318             rc = RC_OK;
319         }
320     }
321 
322     return rc;
323 }
324 
CompareTagData(const camera_metadata_item_t & baseEntry,const camera_metadata_item_t & newEntry)325 bool CameraDeviceImpl::CompareTagData(const camera_metadata_item_t &baseEntry,
326     const camera_metadata_item_t &newEntry)
327 {
328     if (baseEntry.data_type == META_TYPE_BYTE && newEntry.data_type == META_TYPE_BYTE) {
329         if (*(baseEntry.data.u8) != *(newEntry.data.u8)) {
330             return false;
331         }
332     } else if (baseEntry.data_type == META_TYPE_INT32 && newEntry.data_type == META_TYPE_INT32) {
333         if (*(baseEntry.data.i32) != *(newEntry.data.i32)) {
334             return false;
335         }
336     } else if (baseEntry.data_type == META_TYPE_FLOAT && newEntry.data_type == META_TYPE_FLOAT) {
337         if (*(baseEntry.data.f) != *(newEntry.data.f)) {
338             return false;
339         }
340     } else if (baseEntry.data_type == META_TYPE_INT64 && newEntry.data_type == META_TYPE_INT64) {
341         if (*(baseEntry.data.i64) != *(newEntry.data.i64)) {
342             return false;
343         }
344     } else if (baseEntry.data_type == META_TYPE_DOUBLE && newEntry.data_type == META_TYPE_DOUBLE) {
345         if (*(baseEntry.data.d) != *(newEntry.data.d)) {
346             return false;
347         }
348     } else if (baseEntry.data_type == META_TYPE_RATIONAL && newEntry.data_type == META_TYPE_RATIONAL) {
349         if (baseEntry.data.r->numerator != newEntry.data.r->numerator ||
350             baseEntry.data.r->denominator != newEntry.data.r->denominator) {
351             return false;
352         }
353     }
354     return true;
355 }
356 
Close()357 int32_t CameraDeviceImpl::Close()
358 {
359     HDI_DEVICE_PLACE_A_WATCHDOG;
360     DFX_LOCAL_HITRACE_BEGIN;
361 
362     if (spStreamOperator_ != nullptr) {
363         spStreamOperator_->ReleaseStreams();
364         spStreamOperator_ = nullptr;
365     }
366 
367     std::shared_ptr<IDeviceManager> deviceManager = IDeviceManager::GetInstance();
368     if (deviceManager == nullptr) {
369         CAMERA_LOGW("device manager is null [dm name MpiDeviceManager].");
370         return INVALID_ARGUMENT;
371     }
372 
373     CameraHostConfig *config = CameraHostConfig::GetInstance();
374     if (config == nullptr) {
375         CAMERA_LOGD("CameraHostConfig get failed.");
376         return INVALID_ARGUMENT;
377     }
378 
379     std::vector<std::string> phyCameraIds;
380     RetCode rc = config->GetPhysicCameraIds(cameraId_, phyCameraIds);
381     if (rc != RC_OK) {
382         CAMERA_LOGW("get physic cameraId failed.[cameraId = %{public}s]", cameraId_.c_str());
383         return INVALID_ARGUMENT;
384     }
385 
386     for (auto &phyCameraId : phyCameraIds) {
387         auto itr = CameraHostConfig::enumCameraIdMap_.find(phyCameraId);
388         if (itr == CameraHostConfig::enumCameraIdMap_.end()) {
389             CAMERA_LOGW("config phyCameraId undefined in device manager.");
390             continue;
391         }
392 
393         rc = deviceManager->PowerDown(itr->second);
394         if (rc != RC_OK) {
395             CAMERA_LOGE("physic camera powerdown failed [phyCameraId = %{public}s].", phyCameraId.c_str());
396             continue;
397         }
398         CAMERA_LOGD("[phyCameraId = %{public}s] powerdown success.", phyCameraId.c_str());
399     }
400 
401     isOpened_ = false;
402     DFX_LOCAL_HITRACE_END;
403     CAMERA_LOGD("camera close success.");
404     return HDI::Camera::V1_0::NO_ERROR;
405 }
406 
SetCallback(const OHOS::sptr<ICameraDeviceCallback> & callback)407 CamRetCode CameraDeviceImpl::SetCallback(const OHOS::sptr<ICameraDeviceCallback> &callback)
408 {
409     if (callback == nullptr) {
410         return INVALID_ARGUMENT;
411     }
412     cameraDeciceCallback_ = callback;
413     return HDI::Camera::V1_0::NO_ERROR;
414 }
415 
GetPipelineCore() const416 std::shared_ptr<IPipelineCore> CameraDeviceImpl::GetPipelineCore() const
417 {
418     return pipelineCore_;
419 }
420 
ResultMetadata()421 void CameraDeviceImpl::ResultMetadata()
422 {
423     if (cameraDeciceCallback_ == nullptr) {
424         CAMERA_LOGE("camera device callback is null.");
425         return;
426     }
427 
428     std::shared_ptr<CameraMetadata> metadata;
429     RetCode rc = GetMetadataResults(metadata);
430     if (rc == RC_OK || metaResultMode_ == PER_FRAME) {
431         std::vector<uint8_t> result;
432         uint64_t timestamp = GetCurrentLocalTimeStamp();
433         MetadataUtils::ConvertMetadataToVec(metadata, result);
434         cameraDeciceCallback_->OnResult(timestamp, result);
435     }
436 }
437 
GetCurrentLocalTimeStamp()438 uint64_t CameraDeviceImpl::GetCurrentLocalTimeStamp()
439 {
440     std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> tp =
441         std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
442     auto tmp = std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch());
443     return static_cast<uint64_t>(tmp.count());
444 }
445 
GetCameraId(std::string & cameraId) const446 void CameraDeviceImpl::GetCameraId(std::string &cameraId) const
447 {
448     cameraId = cameraId_;
449 }
450 
OnRequestTimeout()451 void CameraDeviceImpl::OnRequestTimeout()
452 {
453     CAMERA_LOGD("OnRequestTimeout callback success.");
454     // request error
455     cameraDeciceCallback_->OnError(REQUEST_TIMEOUT, 0);
456 }
457 
OnMetadataChanged(const std::shared_ptr<CameraMetadata> & metadata)458 void CameraDeviceImpl::OnMetadataChanged(const std::shared_ptr<CameraMetadata> &metadata)
459 {
460     CAMERA_LOGI("OnMetadataChanged callback success.");
461     // device metadata changed callback
462     {
463         std::unique_lock<std::mutex> lock(metaRstMutex_);
464         metadataResults_ = metadata;
465     }
466     if (metaResultMode_ == ON_CHANGED || metaResultMode_ == PER_FRAME) {
467         ResultMetadata();
468     }
469 }
470 
OnDevStatusErr()471 void CameraDeviceImpl::OnDevStatusErr()
472 {
473     CAMERA_LOGD("OnDevStatusErr callback success.");
474     // device error
475     cameraDeciceCallback_->OnError(FATAL_ERROR, 0);
476 }
477 
IsOpened() const478 bool CameraDeviceImpl::IsOpened() const
479 {
480     return isOpened_;
481 }
482 
SetStatus(bool isOpened)483 void CameraDeviceImpl::SetStatus(bool isOpened)
484 {
485     isOpened_ = isOpened;
486 }
487 } // end namespace OHOS::Camera
488