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