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