• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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