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