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 "dcamera_device.h"
17 #include <iostream>
18 #include <iterator>
19 #include <sstream>
20 #include "dcamera_host.h"
21 #include "dcamera_provider.h"
22 #include "dcamera_utils_tools.h"
23 #include "distributed_hardware_log.h"
24 #include "metadata_utils.h"
25
26 namespace OHOS {
27 namespace DistributedHardware {
28 using ErrorCallback = std::function<void (ErrorType, int32_t)>;
29 using ResultCallback = std::function<void (uint64_t, std::shared_ptr<Camera::CameraMetadata>)>;
DCameraDevice(const std::shared_ptr<DHBase> & dhBase,const std::string & abilityInfo)30 DCameraDevice::DCameraDevice(const std::shared_ptr<DHBase> &dhBase, const std::string &abilityInfo)
31 : isOpened_(false),
32 dCameraId_(GenerateCameraId(dhBase)),
33 dhBase_(dhBase),
34 dCameraAbilityInfo_(abilityInfo),
35 dCameraDeviceCallback_(nullptr),
36 dCameraStreamOperator_(nullptr),
37 dMetadataProcessor_(nullptr)
38 {
39 DHLOGI("DCameraDevice::ctor, instance = %p.", this);
40 Init(abilityInfo);
41 }
42
Init(const std::string & abilityInfo)43 void DCameraDevice::Init(const std::string &abilityInfo)
44 {
45 if (dMetadataProcessor_ == nullptr) {
46 dMetadataProcessor_ = std::make_shared<DMetadataProcessor>();
47 }
48 dMetadataProcessor_->InitDCameraAbility(abilityInfo);
49 }
50
CreateDStreamOperator()51 DCamRetCode DCameraDevice::CreateDStreamOperator()
52 {
53 if (dCameraStreamOperator_ == nullptr) {
54 dCameraStreamOperator_ = new (std::nothrow) DStreamOperator(dMetadataProcessor_);
55 if (dCameraStreamOperator_ == nullptr) {
56 DHLOGE("Create distributed camera stream operator failed.");
57 return DEVICE_NOT_INIT;
58 }
59 }
60
61 DCamRetCode ret = dCameraStreamOperator_->InitOutputConfigurations(dhBase_, dCameraAbilityInfo_);
62 if (ret != SUCCESS) {
63 DHLOGE("Init distributed camera stream operator failed, ret=%d.", ret);
64 return ret;
65 }
66
67 ErrorCallback onErrorCallback =
68 [this](ErrorType type, int32_t errorMsg) -> void {
69 if (dCameraDeviceCallback_) {
70 dCameraDeviceCallback_->OnError(type, errorMsg);
71 }
72 };
73 ResultCallback onResultCallback =
74 [this](uint64_t timestamp, const std::shared_ptr<Camera::CameraMetadata> &result) -> void {
75 if (dCameraDeviceCallback_) {
76 dCameraDeviceCallback_->OnResult(timestamp, result);
77 }
78 };
79 dCameraStreamOperator_->SetDeviceCallback(onErrorCallback, onResultCallback);
80
81 return ret;
82 }
83
GetStreamOperator(const OHOS::sptr<IStreamOperatorCallback> & callback,OHOS::sptr<IStreamOperator> & streamOperator)84 CamRetCode DCameraDevice::GetStreamOperator(const OHOS::sptr<IStreamOperatorCallback> &callback,
85 OHOS::sptr<IStreamOperator> &streamOperator)
86 {
87 if (dCameraStreamOperator_ == nullptr) {
88 DHLOGE("Distributed camera stream operator not init.");
89 return CamRetCode::DEVICE_ERROR;
90 }
91
92 if (callback == nullptr) {
93 DHLOGE("Input callback is null.");
94 return CamRetCode::INVALID_ARGUMENT;
95 }
96
97 DCamRetCode ret = dCameraStreamOperator_->SetCallBack(callback);
98 if (ret != SUCCESS) {
99 DHLOGE("Set stream operator callback failed, ret=%d.", ret);
100 return MapToExternalRetCode(ret);
101 }
102
103 streamOperator = dCameraStreamOperator_;
104 return CamRetCode::NO_ERROR;
105 }
106
UpdateSettings(const std::shared_ptr<CameraSetting> & settings)107 CamRetCode DCameraDevice::UpdateSettings(const std::shared_ptr<CameraSetting> &settings)
108 {
109 if (settings == nullptr) {
110 DHLOGE("DCameraDevice::UpdateSettings, input settings is null.");
111 return CamRetCode::INVALID_ARGUMENT;
112 }
113
114 if (!IsOpened()) {
115 DHLOGE("DCameraDevice::UpdateSettings, dcamera device %s already closed.", dCameraId_.c_str());
116 return CamRetCode::CAMERA_CLOSED;
117 }
118
119 std::shared_ptr<DCameraSettings> dcSetting = std::make_shared<DCameraSettings>();
120
121 dcSetting->type_ = DCSettingsType::UPDATE_METADATA;
122 std::string abilityStr = Camera::MetadataUtils::EncodeToString(settings);
123 dcSetting->value_ = Base64Encode(reinterpret_cast<const unsigned char *>(abilityStr.c_str()), abilityStr.length());
124
125 std::vector<std::shared_ptr<DCameraSettings>> dcSettings;
126 dcSettings.push_back(dcSetting);
127
128 std::shared_ptr<DCameraProvider> provider = DCameraProvider::GetInstance();
129 if (provider == nullptr) {
130 DHLOGE("Distributed camera provider instance is null.");
131 return CamRetCode::DEVICE_ERROR;
132 }
133 DCamRetCode ret = provider->UpdateSettings(dhBase_, dcSettings);
134
135 return MapToExternalRetCode(ret);
136 }
137
SetResultMode(const ResultCallbackMode & mode)138 CamRetCode DCameraDevice::SetResultMode(const ResultCallbackMode &mode)
139 {
140 if (dMetadataProcessor_ == nullptr) {
141 DHLOGE("Metadata processor not init.");
142 return CamRetCode::DEVICE_ERROR;
143 }
144
145 DCamRetCode ret = dMetadataProcessor_->SetMetadataResultMode(mode);
146 if (ret != SUCCESS) {
147 DHLOGE("Set metadata result mode failed, ret=%d.", ret);
148 }
149 return MapToExternalRetCode(ret);
150 }
151
GetEnabledResults(std::vector<MetaType> & results)152 CamRetCode DCameraDevice::GetEnabledResults(std::vector<MetaType> &results)
153 {
154 if (dMetadataProcessor_ == nullptr) {
155 DHLOGE("Metadata processor not init.");
156 return CamRetCode::DEVICE_ERROR;
157 }
158
159 DCamRetCode ret = dMetadataProcessor_->GetEnabledMetadataResults(results);
160 if (ret != SUCCESS) {
161 DHLOGE("Get enabled metadata results failed, ret=%d.", ret);
162 }
163 return MapToExternalRetCode(ret);
164 }
165
EnableResult(const std::vector<MetaType> & results)166 CamRetCode DCameraDevice::EnableResult(const std::vector<MetaType> &results)
167 {
168 if (dMetadataProcessor_ == nullptr) {
169 DHLOGE("Metadata processor not init.");
170 return CamRetCode::DEVICE_ERROR;
171 }
172
173 DCamRetCode ret = dMetadataProcessor_->EnableMetadataResult(results);
174 if (ret != SUCCESS) {
175 DHLOGE("Enable metadata result failed, ret=%d.", ret);
176 return MapToExternalRetCode(ret);
177 }
178
179 stringstream sstream;
180 std::reverse_copy(results.begin(), results.end(), ostream_iterator<int32_t>(sstream, ""));
181 std::shared_ptr<DCameraSettings> dcSetting = std::make_shared<DCameraSettings>();
182 dcSetting->type_ = DCSettingsType::ENABLE_METADATA;
183 dcSetting->value_ = sstream.str();
184
185 std::shared_ptr<DCameraProvider> provider = DCameraProvider::GetInstance();
186 if (provider != nullptr) {
187 std::vector<std::shared_ptr<DCameraSettings>> dcSettings;
188 dcSettings.push_back(dcSetting);
189 ret = provider->UpdateSettings(dhBase_, dcSettings);
190 }
191 return MapToExternalRetCode(ret);
192 }
193
DisableResult(const std::vector<MetaType> & results)194 CamRetCode DCameraDevice::DisableResult(const std::vector<MetaType> &results)
195 {
196 if (dMetadataProcessor_ == nullptr) {
197 DHLOGE("Metadata processor not init.");
198 return CamRetCode::DEVICE_ERROR;
199 }
200
201 DCamRetCode ret = dMetadataProcessor_->DisableMetadataResult(results);
202 if (ret != SUCCESS) {
203 DHLOGE("Disable metadata result failed, ret=%d.", ret);
204 return MapToExternalRetCode(ret);
205 }
206
207 stringstream sstream;
208 std::reverse_copy(results.begin(), results.end(), ostream_iterator<int32_t>(sstream, ""));
209 std::shared_ptr<DCameraSettings> dcSetting = std::make_shared<DCameraSettings>();
210 dcSetting->type_ = DCSettingsType::DISABLE_METADATA;
211 dcSetting->value_ = sstream.str();
212
213 std::shared_ptr<DCameraProvider> provider = DCameraProvider::GetInstance();
214 if (provider != nullptr) {
215 std::vector<std::shared_ptr<DCameraSettings>> dcSettings;
216 dcSettings.push_back(dcSetting);
217 ret = provider->UpdateSettings(dhBase_, dcSettings);
218 }
219 return MapToExternalRetCode(ret);
220 }
221
Close()222 void DCameraDevice::Close()
223 {
224 DHLOGI("DCameraDevice::Close distributed camera: %s", dCameraId_.c_str());
225
226 std::shared_ptr<DCameraProvider> provider = DCameraProvider::GetInstance();
227 if (provider != nullptr) {
228 provider->StopCapture(dhBase_);
229 }
230 if (dCameraStreamOperator_ != nullptr) {
231 dCameraStreamOperator_->Release();
232 dCameraStreamOperator_ = nullptr;
233 }
234 if (provider != nullptr) {
235 provider->CloseSession(dhBase_);
236 }
237 if (dMetadataProcessor_ != nullptr) {
238 dMetadataProcessor_->ResetEnableResults();
239 }
240 dCameraDeviceCallback_ = nullptr;
241 isOpenSessFailed_ = false;
242 isOpened_ = false;
243 }
244
OpenDCamera(const OHOS::sptr<ICameraDeviceCallback> & callback)245 CamRetCode DCameraDevice::OpenDCamera(const OHOS::sptr<ICameraDeviceCallback> &callback)
246 {
247 if (callback == nullptr) {
248 DHLOGE("Input callback is null.");
249 return CamRetCode::INVALID_ARGUMENT;
250 }
251 dCameraDeviceCallback_ = callback;
252
253 std::shared_ptr<DCameraProvider> provider = DCameraProvider::GetInstance();
254 if (provider == nullptr) {
255 DHLOGE("Get distributed camera provider instance is null.");
256 return CamRetCode::DEVICE_ERROR;
257 }
258 DCamRetCode ret = provider->OpenSession(dhBase_);
259 if (ret != DCamRetCode::SUCCESS) {
260 DHLOGE("Open distributed camera control session failed, ret = %d.", ret);
261 return MapToExternalRetCode(ret);
262 }
263
264 unique_lock<mutex> lock(openSesslock_);
265 auto st = openSessCV_.wait_for(lock, chrono::seconds(WAIT_OPEN_TIMEOUT_SEC));
266 if (st == cv_status::timeout) {
267 DHLOGE("Wait for distributed camera session open timeout.");
268 return CamRetCode::DEVICE_ERROR;
269 }
270 {
271 unique_lock<mutex> lock(isOpenSessFailedlock_);
272 if (isOpenSessFailed_) {
273 DHLOGE("Open distributed camera session failed.");
274 return CamRetCode::DEVICE_ERROR;
275 }
276 }
277
278 ret = CreateDStreamOperator();
279 if (ret != SUCCESS) {
280 DHLOGE("Create distributed camera stream operator failed.");
281 return MapToExternalRetCode(ret);
282 }
283 isOpened_ = true;
284
285 return MapToExternalRetCode(ret);
286 }
287
GetDCameraAbility(std::shared_ptr<CameraAbility> & ability)288 CamRetCode DCameraDevice::GetDCameraAbility(std::shared_ptr<CameraAbility> &ability)
289 {
290 if (dMetadataProcessor_ == nullptr) {
291 DHLOGE("Metadata processor not init.");
292 return CamRetCode::DEVICE_ERROR;
293 }
294
295 DCamRetCode ret = dMetadataProcessor_->GetDCameraAbility(ability);
296 if (ret != SUCCESS) {
297 DHLOGE("Get distributed camera ability failed, ret=%d.", ret);
298 }
299 return MapToExternalRetCode(ret);
300 }
301
AcquireBuffer(int streamId,std::shared_ptr<DCameraBuffer> & buffer)302 DCamRetCode DCameraDevice::AcquireBuffer(int streamId, std::shared_ptr<DCameraBuffer> &buffer)
303 {
304 if (dCameraStreamOperator_ == nullptr) {
305 DHLOGE("Stream operator not init.");
306 return DEVICE_NOT_INIT;
307 }
308
309 DCamRetCode ret = dCameraStreamOperator_->AcquireBuffer(streamId, buffer);
310 if (ret != SUCCESS) {
311 DHLOGE("Acquire buffer failed, ret=%d.", ret);
312 }
313 return ret;
314 }
315
ShutterBuffer(int streamId,const std::shared_ptr<DCameraBuffer> & buffer)316 DCamRetCode DCameraDevice::ShutterBuffer(int streamId, const std::shared_ptr<DCameraBuffer> &buffer)
317 {
318 if (dCameraStreamOperator_ == nullptr) {
319 DHLOGE("Stream operator not init.");
320 return DEVICE_NOT_INIT;
321 }
322
323 DCamRetCode ret = dCameraStreamOperator_->ShutterBuffer(streamId, buffer);
324 if (ret != SUCCESS) {
325 DHLOGE("Shutter buffer failed, ret=%d.", ret);
326 }
327 return ret;
328 }
329
OnSettingsResult(const std::shared_ptr<DCameraSettings> & result)330 DCamRetCode DCameraDevice::OnSettingsResult(const std::shared_ptr<DCameraSettings> &result)
331 {
332 if (result == nullptr) {
333 DHLOGE("Input camera settings is null.");
334 return INVALID_ARGUMENT;
335 }
336
337 if (dMetadataProcessor_ == nullptr) {
338 DHLOGE("Metadata processor not init.");
339 return DEVICE_NOT_INIT;
340 }
341
342 if (result->type_ != DCSettingsType::METADATA_RESULT) {
343 DHLOGE("Invalid camera setting type = %d.", result->type_);
344 return INVALID_ARGUMENT;
345 }
346 if ((result->value_).empty()) {
347 DHLOGE("Camera settings result is empty.");
348 return INVALID_ARGUMENT;
349 }
350
351 DCamRetCode ret = dMetadataProcessor_->SaveResultMetadata(result->value_);
352 if (ret != SUCCESS) {
353 DHLOGE("Save result metadata failed, ret = %d", ret);
354 }
355 return ret;
356 }
357
Notify(const std::shared_ptr<DCameraHDFEvent> & event)358 DCamRetCode DCameraDevice::Notify(const std::shared_ptr<DCameraHDFEvent> &event)
359 {
360 DHLOGI("DCameraDevice::Notify for event type = %d, result = %d, content = %s.", event->type_, event->result_,
361 event->content_.c_str());
362 if ((event->type_ != DCameraEventType::DCAMERA_MESSAGE) && (event->type_ != DCameraEventType::DCAMERA_OPERATION)) {
363 DHLOGE("Invalid distributed camera event type = %d.", event->type_);
364 return INVALID_ARGUMENT;
365 }
366 switch (event->result_) {
367 case DCameraEventResult::DCAMERA_EVENT_CHANNEL_CONNECTED: {
368 {
369 unique_lock<mutex> lock(isOpenSessFailedlock_);
370 isOpenSessFailed_ = false;
371 }
372 openSessCV_.notify_one();
373 break;
374 }
375 case DCameraEventResult::DCAMERA_EVENT_OPEN_CHANNEL_ERROR: {
376 {
377 unique_lock<mutex> lock(isOpenSessFailedlock_);
378 isOpenSessFailed_ = true;
379 }
380 openSessCV_.notify_one();
381 break;
382 }
383 case DCameraEventResult::DCAMERA_EVENT_CHANNEL_DISCONNECTED: {
384 if (dCameraDeviceCallback_ != nullptr) {
385 dCameraDeviceCallback_->OnError(ErrorType::FATAL_ERROR, 0);
386 Close();
387 }
388 break;
389 }
390 case DCameraEventResult::DCAMERA_EVENT_CONFIG_STREAMS_ERROR:
391 case DCameraEventResult::DCAMERA_EVENT_START_CAPTURE_ERROR: {
392 if (dCameraDeviceCallback_ != nullptr) {
393 dCameraDeviceCallback_->OnError(ErrorType::REQUEST_TIMEOUT, 0);
394 }
395 std::shared_ptr<DCameraProvider> provider = DCameraProvider::GetInstance();
396 if (provider != nullptr) {
397 provider->StopCapture(dhBase_);
398 }
399 if (dCameraStreamOperator_ != nullptr) {
400 dCameraStreamOperator_->Release();
401 }
402 break;
403 }
404 case DCameraEventResult::DCAMERA_EVENT_CAMERA_ERROR: {
405 std::shared_ptr<DCameraHost> dCameraHost = DCameraHost::GetInstance();
406 if (dCameraHost != nullptr) {
407 dCameraHost->NotifyDCameraStatus(dhBase_, event->result_);
408 }
409 if (dCameraDeviceCallback_ != nullptr) {
410 dCameraDeviceCallback_->OnError(ErrorType::REQUEST_TIMEOUT, 0);
411 Close();
412 }
413 break;
414 }
415 default:
416 break;
417 }
418 return SUCCESS;
419 }
420
SetProviderCallback(const OHOS::sptr<IDCameraProviderCallback> & callback)421 void DCameraDevice::SetProviderCallback(const OHOS::sptr<IDCameraProviderCallback> &callback)
422 {
423 dCameraProviderCallback_ = callback;
424 }
425
GetProviderCallback()426 OHOS::sptr<IDCameraProviderCallback> DCameraDevice::GetProviderCallback()
427 {
428 return dCameraProviderCallback_;
429 }
430
GenerateCameraId(const std::shared_ptr<DHBase> & dhBase)431 std::string DCameraDevice::GenerateCameraId(const std::shared_ptr<DHBase> &dhBase)
432 {
433 return dhBase->deviceId_ + "__" + dhBase->dhId_;
434 }
435
GetDCameraId()436 std::string DCameraDevice::GetDCameraId()
437 {
438 return dCameraId_;
439 }
440
IsOpened()441 bool DCameraDevice::IsOpened()
442 {
443 return isOpened_;
444 }
445 } // end namespace DistributedHardware
446 } // end namespace OHOS