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