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