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