1 /*
2 * Copyright (c) 2021 - 2023 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 <chrono>
17 #include "camera_device_vdi_impl.h"
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_controller.h"
24 #include "metadata_utils.h"
25 #include "camera_dump.h"
26 #ifdef HITRACE_LOG_ENABLED
27 #include "hdf_trace.h"
28 #define HDF_CAMERA_TRACE HdfTrace trace(__func__, "HDI:CAM:")
29 #else
30 #define HDF_CAMERA_TRACE
31 #endif
32 #define HDI_DEVICE_PLACE_A_WATCHDOG \
33 PLACE_A_NOKILL_WATCHDOG(std::bind(&CameraDeviceVdiImpl::OnRequestTimeout, this))
34
35 namespace OHOS::Camera {
CameraDeviceVdiImpl(const std::string & cameraId,const std::shared_ptr<IPipelineCore> & pipelineCore)36 CameraDeviceVdiImpl::CameraDeviceVdiImpl(const std::string &cameraId,
37 const std::shared_ptr<IPipelineCore> &pipelineCore)
38 : isOpened_(false),
39 cameraId_(cameraId),
40 pipelineCore_(pipelineCore),
41 cameraDeciceCallback_(nullptr),
42 spStreamOperator_(nullptr),
43 metaResultMode_(PER_FRAME),
44 metadataResults_(nullptr)
45 {
46 }
47
CreateCameraDevice(const std::string & cameraId)48 std::shared_ptr<CameraDeviceVdiImpl> CameraDeviceVdiImpl::CreateCameraDevice(const std::string &cameraId)
49 {
50 HDF_CAMERA_TRACE;
51 // create pipelineCore
52 std::shared_ptr<IPipelineCore> pipelineCore = IPipelineCore::Create();
53 if (pipelineCore == nullptr) {
54 CAMERA_LOGW("create pipeline core failed. [cameraId = %{public}s]", cameraId.c_str());
55 return nullptr;
56 }
57
58 RetCode rc = pipelineCore->Init();
59 if (rc != RC_OK) {
60 CAMERA_LOGW("pipeline core init failed. [cameraId = %{public}s]", cameraId.c_str());
61 return nullptr;
62 }
63
64 std::shared_ptr<CameraDeviceVdiImpl> device = std::make_shared<CameraDeviceVdiImpl>(cameraId, pipelineCore);
65 if (device == nullptr) {
66 CAMERA_LOGW("create camera device failed. [cameraId = %{public}s]", cameraId.c_str());
67 return nullptr;
68 }
69 CAMERA_LOGD("create camera device success. [cameraId = %{public}s]", cameraId.c_str());
70
71 // set deviceManager metadata & dev status callback
72 std::shared_ptr<IDeviceManager> deviceManager = IDeviceManager::GetInstance();
73 if (deviceManager != nullptr) {
74 deviceManager->SetMetaDataCallBack([device](const std::shared_ptr<CameraMetadata> &metadata) {
75 device->OnMetadataChanged(metadata);
76 });
77 deviceManager->SetDevStatusCallBack([device]() {
78 device->OnDevStatusErr();
79 });
80 }
81
82 return device;
83 }
84
GetStreamOperator(const sptr<IStreamOperatorVdiCallback> & callbackObj,sptr<IStreamOperatorVdi> & streamOperator)85 int32_t CameraDeviceVdiImpl::GetStreamOperator(const sptr<IStreamOperatorVdiCallback> &callbackObj,
86 sptr<IStreamOperatorVdi> &streamOperator)
87 {
88 CAMERA_LOGI("CameraDeviceVdiImpl::GetStreamOperator Begin, deviceName = %{public}s", cameraId_.c_str());
89 HDF_CAMERA_TRACE;
90 HDI_DEVICE_PLACE_A_WATCHDOG;
91 DFX_LOCAL_HITRACE_BEGIN;
92 if (callbackObj == nullptr) {
93 CAMERA_LOGW("input callback is null.");
94 return INVALID_ARGUMENT;
95 }
96
97 if (spStreamOperator_ == nullptr) {
98 #ifdef CAMERA_BUILT_ON_OHOS_LITE
99 spStreamOperator_ = std::make_shared<StreamOperatorVdiImpl>(callbackObj, shared_from_this());
100 #else
101 spStreamOperator_ = new(std::nothrow) StreamOperatorVdiImpl(callbackObj, shared_from_this());
102 #endif
103 if (spStreamOperator_ == nullptr) {
104 CAMERA_LOGW("create stream operator failed.");
105 return DEVICE_ERROR;
106 }
107 spStreamOperator_->Init();
108 ismOperator_ = spStreamOperator_;
109 }
110 streamOperator = ismOperator_;
111 #ifndef CAMERA_BUILT_ON_OHOS_LITE
112 InitMetadataController();
113 #endif
114 DFX_LOCAL_HITRACE_END;
115 return VDI::Camera::V1_0::NO_ERROR;
116 }
117
UpdateSettings(const std::vector<uint8_t> & settings)118 int32_t CameraDeviceVdiImpl::UpdateSettings(const std::vector<uint8_t> &settings)
119 {
120 HDF_CAMERA_TRACE;
121 HDI_DEVICE_PLACE_A_WATCHDOG;
122 DFX_LOCAL_HITRACE_BEGIN;
123 if (settings.empty()) {
124 CAMERA_LOGE("input vector settings is empty.");
125 return INVALID_ARGUMENT;
126 }
127
128 if (pipelineCore_ == nullptr) {
129 CAMERA_LOGE("pipeline core is null.");
130 return CAMERA_CLOSED;
131 }
132
133 std::shared_ptr<CameraMetadata> updateSettings;
134 MetadataUtils::ConvertVecToMetadata(settings, updateSettings);
135
136 CameraDumper &dumper = CameraDumper::GetInstance();
137 dumper.DumpMetadata("updatesetting", ENABLE_METADATA, updateSettings);
138
139 MetadataController &metaDataController = MetadataController::GetInstance();
140 metaDataController.UpdateSettingsConfig(updateSettings);
141 DFX_LOCAL_HITRACE_END;
142 return VDI::Camera::V1_0::NO_ERROR;
143 }
144
GetSettings(std::vector<uint8_t> & settings)145 int32_t CameraDeviceVdiImpl::GetSettings(std::vector<uint8_t> &settings)
146 {
147 std::shared_ptr<CameraMetadata> meta = std::make_shared<CameraMetadata>(ENTRY_CAPACITY, DATA_CAPACITY);
148 if (meta == nullptr) {
149 CAMERA_LOGE("meta is nullptr.");
150 return DEVICE_ERROR;
151 }
152 MetadataController &metaDataController = MetadataController::GetInstance();
153 metaDataController.GetSettingsConfig(meta);
154 MetadataUtils::ConvertMetadataToVec(meta, settings);
155 return VDI::Camera::V1_0::NO_ERROR;
156 }
157
SetResultMode(VdiResultCallbackMode mode)158 int32_t CameraDeviceVdiImpl::SetResultMode(VdiResultCallbackMode mode)
159 {
160 CAMERA_LOGD("entry.");
161 MetadataController &metaDataController = MetadataController::GetInstance();
162 if (mode < PER_FRAME || mode > ON_CHANGED) {
163 CAMERA_LOGE("parameter out of range.");
164 return INVALID_ARGUMENT;
165 } else if (mode == PER_FRAME) {
166 metaDataController.SetPeerFrameFlag(true);
167 } else {
168 metaDataController.SetPeerFrameFlag(false);
169 }
170
171 metaResultMode_ = mode;
172 return VDI::Camera::V1_0::NO_ERROR;
173 }
174
GetMetaResultMode() const175 VdiResultCallbackMode CameraDeviceVdiImpl::GetMetaResultMode() const
176 {
177 return metaResultMode_;
178 }
179
GetEnabledResults(std::vector<int32_t> & results)180 int32_t CameraDeviceVdiImpl::GetEnabledResults(std::vector<int32_t> &results)
181 {
182 HDF_CAMERA_TRACE;
183 HDI_DEVICE_PLACE_A_WATCHDOG;
184 DFX_LOCAL_HITRACE_BEGIN;
185 if (deviceMetaTypes_.empty()) {
186 RetCode rc = GetEnabledFromCfg();
187 if (rc != RC_OK) {
188 CAMERA_LOGE("get enabled results from device manager failed.");
189 return DEVICE_ERROR;
190 }
191 }
192
193 std::unique_lock<std::mutex> l(enabledRstMutex_);
194 MetadataController &metaDataController = MetadataController::GetInstance();
195 metaDataController.GetEnabledAbility(results);
196 DFX_LOCAL_HITRACE_END;
197 return VDI::Camera::V1_0::NO_ERROR;
198 }
199
GetEnabledFromCfg()200 RetCode CameraDeviceVdiImpl::GetEnabledFromCfg()
201 {
202 // Get devicemanager
203 std::shared_ptr<IDeviceManager> deviceManager = IDeviceManager::GetInstance();
204 if (deviceManager == nullptr) {
205 CAMERA_LOGW("device manager is null.");
206 return RC_ERROR;
207 }
208
209 CameraHostConfig *config = CameraHostConfig::GetInstance();
210 if (config == nullptr) {
211 return RC_ERROR;
212 }
213 std::shared_ptr<CameraMetadata> ability;
214 RetCode rc = config->GetCameraAbility(cameraId_, ability);
215 if (rc != RC_OK || ability == nullptr) {
216 CAMERA_LOGD("GetCameraAbility failed.");
217 return RC_ERROR;
218 }
219
220 common_metadata_header_t *metadata = ability->get();
221 if (metadata == nullptr) {
222 CAMERA_LOGD("ability get metadata is null.");
223 return RC_ERROR;
224 }
225
226 camera_metadata_item_t entry;
227 int ret = FindCameraMetadataItem(metadata,
228 OHOS_ABILITY_STREAM_AVAILABLE_BASIC_CONFIGURATIONS, &entry);
229 if (ret == 0) {
230 CAMERA_LOGD("FindCameraMetadataIte tags = %{public}d. type = %{public}d", entry.count, entry.data_type);
231 for (uint32_t i = 0; i < entry.count; i++) {
232 deviceMetaTypes_.push_back(*(entry.data.i32 + i));
233 }
234 }
235
236 return RC_OK;
237 }
238
EnableResult(const std::vector<int32_t> & results)239 int32_t CameraDeviceVdiImpl::EnableResult(const std::vector<int32_t> &results)
240 {
241 HDF_CAMERA_TRACE;
242 HDI_DEVICE_PLACE_A_WATCHDOG;
243 DFX_LOCAL_HITRACE_BEGIN;
244 std::unique_lock<std::mutex> l(enabledRstMutex_);
245 for (auto &metaType : results) {
246 auto itr = std::find(enabledResults_.begin(), enabledResults_.end(), metaType);
247 if (itr == enabledResults_.end()) {
248 enabledResults_.push_back(metaType);
249 } else {
250 CAMERA_LOGW("enabled result is existed. [metaType = %{public}d]", metaType);
251 }
252 }
253 MetadataController &metaDataController = MetadataController::GetInstance();
254 metaDataController.AddEnabledAbility(enabledResults_);
255 DFX_LOCAL_HITRACE_END;
256 return VDI::Camera::V1_0::NO_ERROR;
257 }
258
DisableResult(const std::vector<int32_t> & results)259 int32_t CameraDeviceVdiImpl::DisableResult(const std::vector<int32_t> &results)
260 {
261 HDF_CAMERA_TRACE;
262 HDI_DEVICE_PLACE_A_WATCHDOG;
263 DFX_LOCAL_HITRACE_BEGIN;
264 VdiCamRetCode ret = VDI::Camera::V1_0::NO_ERROR;
265 std::unique_lock<std::mutex> l(enabledRstMutex_);
266 for (auto &metaType : results) {
267 auto itr = std::find(enabledResults_.begin(), enabledResults_.end(), metaType);
268 if (itr != enabledResults_.end()) {
269 enabledResults_.erase(itr);
270 } else {
271 CAMERA_LOGW("enabled result is not found. [metaType = %{public}d]", metaType);
272 ret = INVALID_ARGUMENT;
273 }
274 }
275 MetadataController &metaDataController = MetadataController::GetInstance();
276 metaDataController.DelEnabledAbility(results);
277 DFX_LOCAL_HITRACE_END;
278 return ret;
279 }
280
Close()281 int32_t CameraDeviceVdiImpl::Close()
282 {
283 HDI_DEVICE_PLACE_A_WATCHDOG;
284 HDF_CAMERA_TRACE;
285 DFX_LOCAL_HITRACE_BEGIN;
286
287 MetadataController &metaDataController = MetadataController::GetInstance();
288 metaDataController.Stop();
289 metaDataController.UnSetUpdateSettingCallback();
290
291 if (spStreamOperator_ != nullptr) {
292 spStreamOperator_->ReleaseStreams();
293 spStreamOperator_ = nullptr;
294 }
295
296 std::shared_ptr<IDeviceManager> deviceManager = IDeviceManager::GetInstance();
297 if (deviceManager == nullptr) {
298 CAMERA_LOGW("device manager is null [dm name MpiDeviceManager].");
299 return INVALID_ARGUMENT;
300 }
301
302 CameraHostConfig *config = CameraHostConfig::GetInstance();
303 if (config == nullptr) {
304 CAMERA_LOGD("CameraHostConfig get failed.");
305 return INVALID_ARGUMENT;
306 }
307
308 std::vector<std::string> phyCameraIds;
309 RetCode rc = config->GetPhysicCameraIds(cameraId_, phyCameraIds);
310 if (rc != RC_OK) {
311 CAMERA_LOGW("get physic cameraId failed.[cameraId = %{public}s]", cameraId_.c_str());
312 return INVALID_ARGUMENT;
313 }
314
315 for (auto &phyCameraId : phyCameraIds) {
316 auto itr = CameraHostConfig::enumCameraIdMap_.find(phyCameraId);
317 if (itr == CameraHostConfig::enumCameraIdMap_.end()) {
318 CAMERA_LOGW("config phyCameraId undefined in device manager.");
319 continue;
320 }
321
322 rc = deviceManager->PowerDown(itr->second);
323 if (rc != RC_OK) {
324 CAMERA_LOGE("physic camera powerdown failed [phyCameraId = %{public}s].", phyCameraId.c_str());
325 continue;
326 }
327 CAMERA_LOGD("[phyCameraId = %{public}s] powerdown success.", phyCameraId.c_str());
328 }
329
330 isOpened_ = false;
331 cameraDeciceCallback_ = nullptr;
332 DFX_LOCAL_HITRACE_END;
333 CAMERA_LOGD("camera close success.");
334 return VDI::Camera::V1_0::NO_ERROR;
335 }
336
SetCallback(const OHOS::sptr<ICameraDeviceVdiCallback> & callback)337 VdiCamRetCode CameraDeviceVdiImpl::SetCallback(const OHOS::sptr<ICameraDeviceVdiCallback> &callback)
338 {
339 if (callback == nullptr) {
340 return INVALID_ARGUMENT;
341 }
342 cameraDeciceCallback_ = callback;
343 return VDI::Camera::V1_0::NO_ERROR;
344 }
345
GetPipelineCore() const346 std::shared_ptr<IPipelineCore> CameraDeviceVdiImpl::GetPipelineCore() const
347 {
348 return pipelineCore_;
349 }
350
GetCurrentLocalTimeStamp()351 uint64_t CameraDeviceVdiImpl::GetCurrentLocalTimeStamp()
352 {
353 std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> tp =
354 std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
355 auto tmp = std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch());
356 return static_cast<uint64_t>(tmp.count());
357 }
358
InitMetadataController()359 void CameraDeviceVdiImpl::InitMetadataController()
360 {
361 std::shared_ptr<CameraMetadata> meta = std::make_shared<CameraMetadata>(ENTRY_CAPACITY, DATA_CAPACITY);
362 const int32_t deviceStreamId = 0;
363 meta->addEntry(OHOS_CAMERA_STREAM_ID, &deviceStreamId, 1);
364 MetadataController &metaDataController = MetadataController::GetInstance();
365 metaDataController.SetDeviceDefaultMetadata(meta);
366 metaDataController.Start();
367 metaDataController.SetUpdateSettingCallback([this](const std::shared_ptr<CameraMetadata> &metadata) {
368 OnMetadataChanged(metadata);
369 });
370 }
371
GetCameraId(std::string & cameraId) const372 void CameraDeviceVdiImpl::GetCameraId(std::string &cameraId) const
373 {
374 cameraId = cameraId_;
375 }
376
OnRequestTimeout()377 void CameraDeviceVdiImpl::OnRequestTimeout()
378 {
379 CAMERA_LOGD("OnRequestTimeout callback success.");
380 // request error
381 cameraDeciceCallback_->OnError(REQUEST_TIMEOUT, 0);
382 }
383
OnMetadataChanged(const std::shared_ptr<CameraMetadata> & metadata)384 void CameraDeviceVdiImpl::OnMetadataChanged(const std::shared_ptr<CameraMetadata> &metadata)
385 {
386 CAMERA_LOGI("OnMetadataChanged callback success.");
387
388 if (cameraDeciceCallback_ == nullptr) {
389 CAMERA_LOGE("camera device callback is null.");
390 return;
391 }
392
393 uint64_t timestamp = GetCurrentLocalTimeStamp();
394 std::vector<uint8_t> result;
395 MetadataUtils::ConvertMetadataToVec(metadata, result);
396
397 CameraDumper &dumper = CameraDumper::GetInstance();
398 dumper.DumpMetadata("reportmeta", ENABLE_METADATA, metadata);
399
400 cameraDeciceCallback_->OnResult(timestamp, result);
401 }
402
OnDevStatusErr()403 void CameraDeviceVdiImpl::OnDevStatusErr()
404 {
405 CAMERA_LOGD("OnDevStatusErr callback success.");
406 // device error
407 cameraDeciceCallback_->OnError(FATAL_ERROR, 0);
408 }
409
IsOpened() const410 bool CameraDeviceVdiImpl::IsOpened() const
411 {
412 return isOpened_;
413 }
414
SetStatus(bool isOpened)415 void CameraDeviceVdiImpl::SetStatus(bool isOpened)
416 {
417 isOpened_ = isOpened;
418 }
419 } // end namespace OHOS::Camera
420