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