1 /*
2  * Copyright (c) 2021-2024 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_client.h"
17 
18 #include "anonymous_string.h"
19 #include "camera_util.h"
20 #include "camera_metadata_operator.h"
21 #include "dcamera_input_callback.h"
22 #include "dcamera_manager_callback.h"
23 #include "dcamera_photo_callback.h"
24 #include "dcamera_preview_callback.h"
25 #include "dcamera_session_callback.h"
26 #include "dcamera_utils_tools.h"
27 #include "dcamera_video_callback.h"
28 #include "distributed_camera_constants.h"
29 #include "distributed_camera_errno.h"
30 #include "distributed_hardware_log.h"
31 #include "metadata_utils.h"
32 
33 namespace OHOS {
34 namespace DistributedHardware {
DCameraClient(const std::string & dhId)35 DCameraClient::DCameraClient(const std::string& dhId)
36 {
37     DHLOGI("DCameraClient Constructor dhId: %{public}s", GetAnonyString(dhId).c_str());
38     cameraId_ = dhId.substr(CAMERA_ID_PREFIX.size());
39     isInit_ = false;
40 }
41 
~DCameraClient()42 DCameraClient::~DCameraClient()
43 {
44     if (isInit_) {
45         UnInit();
46     }
47 }
48 
Init()49 int32_t DCameraClient::Init()
50 {
51     DHLOGI("Init cameraId: %{public}s", GetAnonyString(cameraId_).c_str());
52     cameraManager_ = CameraStandard::CameraManager::GetInstance();
53     if (cameraManager_ == nullptr) {
54         DHLOGE("Init cameraManager getInstance failed");
55         return DCAMERA_BAD_VALUE;
56     }
57     cameraManager_->SetCallback(std::make_shared<DCameraManagerCallback>());
58 
59     std::vector<sptr<CameraStandard::CameraDevice>> cameraList = cameraManager_->GetSupportedCameras();
60     if (cameraList.empty()) {
61         DHLOGE("Init no camera device");
62         return DCAMERA_BAD_VALUE;
63     }
64     uint64_t listSize = static_cast<uint64_t>(cameraList.size());
65     DHLOGI("Init camera size: %{public}" PRIu64, listSize);
66     for (auto& info : cameraList) {
67         if (info->GetID() == cameraId_) {
68             DHLOGI("Init cameraInfo get id: %{public}s", GetAnonyString(info->GetID()).c_str());
69             cameraInfo_ = info;
70             break;
71         }
72     }
73     if (cameraInfo_ == nullptr) {
74         DHLOGE("Init cameraInfo is null");
75         return DCAMERA_BAD_VALUE;
76     }
77 
78     isInit_ = true;
79     DHLOGI("Init %{public}s success", GetAnonyString(cameraId_).c_str());
80     return DCAMERA_OK;
81 }
82 
UnInit()83 int32_t DCameraClient::UnInit()
84 {
85     DHLOGI("UnInit cameraId: %{public}s", GetAnonyString(cameraId_).c_str());
86     if (cameraManager_ != nullptr) {
87         DHLOGI("UnInit unregister cameraManager callback");
88         cameraManager_->SetCallback(nullptr);
89     }
90 
91     isInit_ = false;
92     cameraInfo_ = nullptr;
93     cameraManager_ = nullptr;
94     DHLOGI("UnInit %{public}s success", GetAnonyString(cameraId_).c_str());
95     return DCAMERA_OK;
96 }
97 
UpdateSettings(std::vector<std::shared_ptr<DCameraSettings>> & settings)98 int32_t DCameraClient::UpdateSettings(std::vector<std::shared_ptr<DCameraSettings>>& settings)
99 {
100     DHLOGI("UpdateSettings cameraId: %{public}s", GetAnonyString(cameraId_).c_str());
101     for (auto& setting : settings) {
102         switch (setting->type_) {
103             case UPDATE_METADATA: {
104                 DHLOGI("UpdateSettings %{public}s update metadata settings", GetAnonyString(cameraId_).c_str());
105                 std::string dcSettingValue = setting->value_;
106                 std::string metadataStr = Base64Decode(dcSettingValue);
107                 FindCameraMetadata(metadataStr);
108 
109                 if (cameraInput_ == nullptr) {
110                     DHLOGE("UpdateSettings %{public}s cameraInput is null", GetAnonyString(cameraId_).c_str());
111                     UpdateSettingCache(metadataStr);
112                     return DCAMERA_OK;
113                 }
114 
115                 int32_t ret = ((sptr<CameraStandard::CameraInput> &)cameraInput_)->SetCameraSettings(metadataStr);
116                 if (ret != DCAMERA_OK) {
117                     DHLOGE("UpdateSettings %{public}s update metadata settings failed, ret: %{public}d",
118                         GetAnonyString(cameraId_).c_str(), ret);
119                     return ret;
120                 }
121                 break;
122             }
123             default: {
124                 DHLOGE("UpdateSettings unknown setting type");
125                 break;
126             }
127         }
128     }
129     DHLOGI("UpdateSettings %{public}s success", GetAnonyString(cameraId_).c_str());
130     return DCAMERA_OK;
131 }
132 
UpdateSettingCache(const std::string & metadataStr)133 void DCameraClient::UpdateSettingCache(const std::string& metadataStr)
134 {
135     if (cameraMetadatas_.size() == DCAMERA_MAX_METADATA_SIZE) {
136         DHLOGE("UpdateSettingCache %{public}s camera metadata oversize",
137             GetAnonyString(cameraId_).c_str());
138         cameraMetadatas_.pop();
139     }
140     cameraMetadatas_.push(metadataStr);
141 }
142 
FindCameraMetadata(const std::string & metadataStr)143 void DCameraClient::FindCameraMetadata(const std::string& metadataStr)
144 {
145     std::shared_ptr<Camera::CameraMetadata> cameraMetadata = Camera::MetadataUtils::DecodeFromString(metadataStr);
146     CHECK_AND_RETURN_LOG(cameraMetadata == nullptr, "FindCameraMetadata get cameraMetadata is null");
147     camera_metadata_item_t focusItem;
148     int32_t ret = Camera::FindCameraMetadataItem(cameraMetadata->get(), OHOS_CONTROL_FOCUS_MODE, &focusItem);
149     if (ret == CAM_META_SUCCESS) {
150         DHLOGI("FindCameraMetadata focus mode: %{public}d", focusItem.data.u8[0]);
151     } else {
152         DHLOGE("FindCameraMetadata %{public}s find focus mode failed, ret: %{public}d",
153             GetAnonyString(cameraId_).c_str(), ret);
154     }
155 
156     camera_metadata_item_t exposureItem;
157     ret = Camera::FindCameraMetadataItem(cameraMetadata->get(), OHOS_CONTROL_EXPOSURE_MODE, &exposureItem);
158     if (ret == CAM_META_SUCCESS) {
159         DHLOGI("FindCameraMetadata exposure mode: %{public}d", exposureItem.data.u8[0]);
160     } else {
161         DHLOGE("FindCameraMetadata %{public}s find exposure mode failed, ret: %{public}d",
162             GetAnonyString(cameraId_).c_str(), ret);
163     }
164 
165     camera_metadata_item_t stabilityItem;
166     ret = Camera::FindCameraMetadataItem(cameraMetadata->get(), OHOS_CONTROL_VIDEO_STABILIZATION_MODE, &stabilityItem);
167     if (ret == CAM_META_SUCCESS) {
168         DHLOGI("FindCameraMetadata stabilization mode: %{public}d", stabilityItem.data.u8[0]);
169     } else {
170         DHLOGE("FindCameraMetadata %{public}s find stabilization mode failed, ret: %{public}d",
171             GetAnonyString(cameraId_).c_str(), ret);
172     }
173 }
174 
StartCapture(std::vector<std::shared_ptr<DCameraCaptureInfo>> & captureInfos,sptr<Surface> & surface,int32_t sceneMode)175 int32_t DCameraClient::StartCapture(std::vector<std::shared_ptr<DCameraCaptureInfo>>& captureInfos,
176     sptr<Surface>& surface, int32_t sceneMode)
177 {
178     DHLOGI("StartCapture cameraId: %{public}s, mode: %{public}d", GetAnonyString(cameraId_).c_str(), sceneMode);
179     if ((photoOutput_ == nullptr) && (previewOutput_ == nullptr)) {
180         DHLOGI("StartCapture %{public}s config capture session", GetAnonyString(cameraId_).c_str());
181         if (surface == nullptr) {
182             DHLOGE("StartCapture: input surface is nullptr.");
183             return DCAMERA_BAD_VALUE;
184         }
185         previewSurface_ = surface;
186         int32_t ret = ConfigCaptureSession(captureInfos, sceneMode);
187         if (ret != DCAMERA_OK) {
188             DHLOGE("StartCapture config capture session failed, cameraId: %{public}s, ret: %{public}d",
189                    GetAnonyString(cameraId_).c_str(), ret);
190             return CameraServiceErrorType(ret);
191         }
192     }
193 
194     for (auto& info : captureInfos) {
195         if ((info->streamType_ == CONTINUOUS_FRAME) || (!info->isCapture_)) {
196             continue;
197         }
198         int32_t ret = StartCaptureInner(info);
199         if (ret != DCAMERA_OK) {
200             DHLOGE("StartCapture failed, cameraId: %{public}s, ret: %{public}d",
201                 GetAnonyString(cameraId_).c_str(), ret);
202             return CameraServiceErrorType(ret);
203         }
204     }
205     DHLOGI("StartCapture %{public}s success", GetAnonyString(cameraId_).c_str());
206     return DCAMERA_OK;
207 }
208 
CameraServiceErrorType(const int32_t errorType)209 int32_t DCameraClient::CameraServiceErrorType(const int32_t errorType)
210 {
211     if (errorType == CameraStandard::CamServiceError::CAMERA_ALLOC_ERROR) {
212         return DCAMERA_ALLOC_ERROR;
213     } else if (errorType == CameraStandard::CamServiceError::CAMERA_DEVICE_BUSY) {
214         return DCAMERA_DEVICE_BUSY;
215     }
216     return errorType;
217 }
218 
StopCapture()219 int32_t DCameraClient::StopCapture()
220 {
221     DHLOGI("StopCapture cameraId: %{public}s", GetAnonyString(cameraId_).c_str());
222     StopOutput();
223 
224     if (cameraInput_ != nullptr) {
225         DHLOGI("StopCapture %{public}s release cameraInput", GetAnonyString(cameraId_).c_str());
226         int32_t ret = cameraInput_->Close();
227         if (ret != DCAMERA_OK) {
228             DHLOGE("StopCapture cameraInput Close failed, cameraId: %{public}s, ret: %{public}d",
229                 GetAnonyString(cameraId_).c_str(), ret);
230         }
231         ret = cameraInput_->Release();
232         if (ret != DCAMERA_OK) {
233             DHLOGE("StopCapture cameraInput Release failed, cameraId: %{public}s, ret: %{public}d",
234                 GetAnonyString(cameraId_).c_str(), ret);
235         }
236         cameraInput_ = nullptr;
237     }
238     ReleaseCaptureSession();
239 
240     if (previewSurface_ != nullptr) {
241         DHLOGI("StopCapture %s previewsurface unregister consumer listener",
242             GetAnonyString(cameraId_).c_str());
243         previewSurface_ = nullptr;
244     }
245 
246     if (photoSurface_ != nullptr) {
247         DHLOGI("StopCapture %{public}s photosurface unregister consumer listener",
248             GetAnonyString(cameraId_).c_str());
249         int32_t ret = photoSurface_->UnregisterConsumerListener();
250         if (ret != DCAMERA_OK) {
251             DHLOGE("StopCapture %{public}s photosurface unregister consumer listener failed, ret: %{public}d",
252                 GetAnonyString(cameraId_).c_str(), ret);
253         }
254         photoListener_ = nullptr;
255         photoSurface_ = nullptr;
256     }
257 
258     DHLOGI("StopCapture %{public}s success", GetAnonyString(cameraId_).c_str());
259     return DCAMERA_OK;
260 }
261 
StopOutput()262 void DCameraClient::StopOutput()
263 {
264     if (previewOutput_ != nullptr) {
265         DHLOGI("StopCapture %{public}s stop previewOutput", GetAnonyString(cameraId_).c_str());
266         int32_t ret = ((sptr<CameraStandard::PreviewOutput> &)previewOutput_)->Stop();
267         if (ret != DCAMERA_OK) {
268             DHLOGE("StopCapture videoOutput stop failed, cameraId: %{public}s, ret: %{public}d",
269                    GetAnonyString(cameraId_).c_str(), ret);
270         }
271         DHLOGI("StopCapture %{public}s release previewOutput", GetAnonyString(cameraId_).c_str());
272         ret = previewOutput_->Release();
273         if (ret != DCAMERA_OK) {
274             DHLOGE("StopCapture previewOutput Release failed, cameraId: %{public}s, ret: %{public}d",
275                    GetAnonyString(cameraId_).c_str(), ret);
276         }
277         previewOutput_ = nullptr;
278     }
279 
280     if (photoOutput_ != nullptr) {
281         DHLOGI("StopCapture %{public}s release photoOutput", GetAnonyString(cameraId_).c_str());
282         int32_t ret = photoOutput_->Release();
283         if (ret != DCAMERA_OK) {
284             DHLOGE("StopCapture photoOutput Release failed, cameraId: %{public}s, ret: %{public}d",
285                    GetAnonyString(cameraId_).c_str(), ret);
286         }
287         photoOutput_ = nullptr;
288     }
289 }
290 
ReleaseCaptureSession()291 void DCameraClient::ReleaseCaptureSession()
292 {
293     if (captureSession_ == nullptr) {
294         return;
295     }
296     DHLOGI("StopCapture %{public}s stop captureSession", GetAnonyString(cameraId_).c_str());
297     int32_t ret = captureSession_->Stop();
298     if (ret != DCAMERA_OK) {
299         DHLOGE("StopCapture captureSession stop failed, cameraId: %{public}s, ret: %{public}d",
300                GetAnonyString(cameraId_).c_str(), ret);
301     }
302     DHLOGI("StopCapture %{public}s release captureSession", GetAnonyString(cameraId_).c_str());
303     ret = captureSession_->Release();
304     if (ret != DCAMERA_OK) {
305         DHLOGE("StopCapture captureSession Release failed, cameraId: %{public}s, ret: %{public}d",
306                GetAnonyString(cameraId_).c_str(), ret);
307     }
308     captureSession_ = nullptr;
309 }
310 
SetStateCallback(std::shared_ptr<StateCallback> & callback)311 int32_t DCameraClient::SetStateCallback(std::shared_ptr<StateCallback>& callback)
312 {
313     DHLOGI("SetStateCallback cameraId: %{public}s", GetAnonyString(cameraId_).c_str());
314     if (callback == nullptr) {
315         DHLOGE("SetStateCallback %{public}s unregistering state callback", GetAnonyString(cameraId_).c_str());
316     }
317     stateCallback_ = callback;
318     return DCAMERA_OK;
319 }
320 
SetResultCallback(std::shared_ptr<ResultCallback> & callback)321 int32_t DCameraClient::SetResultCallback(std::shared_ptr<ResultCallback>& callback)
322 {
323     DHLOGI("SetResultCallback cameraId: %{public}s", GetAnonyString(cameraId_).c_str());
324     if (callback == nullptr) {
325         DHLOGE("SetResultCallback %{public}s unregistering result callback", GetAnonyString(cameraId_).c_str());
326     }
327     resultCallback_ = callback;
328     return DCAMERA_OK;
329 }
330 
ConfigCaptureSession(std::vector<std::shared_ptr<DCameraCaptureInfo>> & captureInfos,int32_t sceneMode)331 int32_t DCameraClient::ConfigCaptureSession(std::vector<std::shared_ptr<DCameraCaptureInfo>>& captureInfos,
332     int32_t sceneMode)
333 {
334     DHLOGI("ConfigCaptureSession cameraId: %{public}s", GetAnonyString(cameraId_).c_str());
335     CHECK_AND_RETURN_RET_LOG(cameraManager_ == nullptr, DCAMERA_BAD_VALUE, "cameraManager is null.");
336     int rv = cameraManager_->CreateCameraInput(cameraInfo_, &((sptr<CameraStandard::CameraInput> &)cameraInput_));
337     if (rv != DCAMERA_OK) {
338         DHLOGE("ConfigCaptureSession %{public}s create cameraInput failed", GetAnonyString(cameraId_).c_str());
339         return DCAMERA_BAD_VALUE;
340     }
341     int32_t rc = ((sptr<CameraStandard::CameraInput> &)cameraInput_)->Open();
342     if (rc != DCAMERA_OK) {
343         DHLOGE("ConfigCaptureSession cameraInput_ Open failed, cameraId: %{public}s, ret: %{public}d",
344             GetAnonyString(cameraId_).c_str(), rc);
345         return DCAMERA_BAD_VALUE;
346     }
347     std::shared_ptr<DCameraInputCallback> inputCallback = std::make_shared<DCameraInputCallback>(stateCallback_);
348     ((sptr<CameraStandard::CameraInput> &)cameraInput_)->SetErrorCallback(inputCallback);
349 
350     while (!cameraMetadatas_.empty()) {
351         std::string metadataStr = cameraMetadatas_.front();
352         FindCameraMetadata(metadataStr);
353         int32_t ret = ((sptr<CameraStandard::CameraInput> &)cameraInput_)->SetCameraSettings(metadataStr);
354         if (ret != DCAMERA_OK) {
355             DHLOGE("ConfigCaptureSession %{public}s set camera settings failed, ret: %{public}d",
356                 GetAnonyString(cameraId_).c_str(), ret);
357             return ret;
358         }
359         cameraMetadatas_.pop();
360     }
361 
362     captureSession_ = cameraManager_->CreateCaptureSession(static_cast<CameraStandard::SceneMode>(sceneMode));
363     if (captureSession_ == nullptr) {
364         DHLOGE("ConfigCaptureSession %{public}s create captureSession failed",
365                GetAnonyString(cameraId_).c_str());
366         return DCAMERA_BAD_VALUE;
367     }
368 
369     std::shared_ptr<DCameraSessionCallback> sessionCallback = std::make_shared<DCameraSessionCallback>(stateCallback_);
370     captureSession_->SetFocusCallback(sessionCallback);
371     captureSession_->SetCallback(sessionCallback);
372 
373     int32_t ret = CreateCaptureOutput(captureInfos);
374     if (ret != DCAMERA_OK) {
375         DHLOGE("ConfigCaptureSession create capture output failed, cameraId: %{public}s, ret: %{public}d",
376                GetAnonyString(cameraId_).c_str(), ret);
377         return ret;
378     }
379 
380     return ConfigCaptureSessionInner();
381 }
382 
ConfigCaptureSessionInner()383 int32_t DCameraClient::ConfigCaptureSessionInner()
384 {
385     int32_t ret = captureSession_->BeginConfig();
386     if (ret != DCAMERA_OK) {
387         DHLOGE("ConfigCaptureSession %{public}s config captureSession failed, ret: %{public}d",
388                GetAnonyString(cameraId_).c_str(), ret);
389         return ret;
390     }
391 
392     ret = captureSession_->AddInput(cameraInput_);
393     if (ret != DCAMERA_OK) {
394         DHLOGE("ConfigCaptureSession %{public}s add cameraInput to captureSession failed, ret: %{public}d",
395                GetAnonyString(cameraId_).c_str(), ret);
396         return ret;
397     }
398 
399     if (photoOutput_ != nullptr) {
400         ret = captureSession_->AddOutput(photoOutput_);
401         if (ret != DCAMERA_OK) {
402             DHLOGE("ConfigCaptureSession %{public}s add photoOutput to captureSession failed, ret: %{public}d",
403                    GetAnonyString(cameraId_).c_str(), ret);
404             return ret;
405         }
406     }
407 
408     if (previewOutput_ != nullptr) {
409         ret = captureSession_->AddOutput(previewOutput_);
410         if (ret != DCAMERA_OK) {
411             DHLOGE("ConfigCaptureSession %{public}s add previewOutput to captureSession failed, ret: %{public}d",
412                    GetAnonyString(cameraId_).c_str(), ret);
413             return ret;
414         }
415     }
416 
417     ret = captureSession_->CommitConfig();
418     if (ret != DCAMERA_OK) {
419         DHLOGE("ConfigCaptureSession %{public}s commit captureSession failed, ret: %{public}d",
420                GetAnonyString(cameraId_).c_str(), ret);
421         return ret;
422     }
423 
424     ret = captureSession_->Start();
425     if (ret != DCAMERA_OK) {
426         DHLOGE("ConfigCaptureSession %{public}s start captureSession failed, ret: %{public}d",
427                GetAnonyString(cameraId_).c_str(), ret);
428     }
429 
430     DHLOGI("ConfigCaptureSession %{public}s success", GetAnonyString(cameraId_).c_str());
431     return DCAMERA_OK;
432 }
433 
CreateCaptureOutput(std::vector<std::shared_ptr<DCameraCaptureInfo>> & captureInfos)434 int32_t DCameraClient::CreateCaptureOutput(std::vector<std::shared_ptr<DCameraCaptureInfo>>& captureInfos)
435 {
436     if (captureInfos.empty()) {
437         DHLOGE("CreateCaptureOutput no capture info, cameraId: %{public}s", GetAnonyString(cameraId_).c_str());
438         return DCAMERA_BAD_VALUE;
439     }
440 
441     for (auto& info : captureInfos) {
442         if (info->streamType_ == SNAPSHOT_FRAME) {
443             int32_t ret = CreatePhotoOutput(info);
444             if (ret != DCAMERA_OK) {
445                 DHLOGE("CreateCaptureOutput %{public}s create photo output failed, ret: %{public}d",
446                        GetAnonyString(cameraId_).c_str(), ret);
447                 return ret;
448             }
449         } else if (info->streamType_ == CONTINUOUS_FRAME) {
450             int32_t ret = CreatePreviewOutput(info);
451             if (ret != DCAMERA_OK) {
452                 DHLOGE("CreateCaptureOutput %{public}s create video output failed, ret: %{public}d",
453                        GetAnonyString(cameraId_).c_str(), ret);
454                 return ret;
455             }
456         } else {
457             DHLOGE("CreateCaptureOutput unknown stream type");
458             return DCAMERA_BAD_VALUE;
459         }
460     }
461     return DCAMERA_OK;
462 }
463 
CreatePhotoOutput(std::shared_ptr<DCameraCaptureInfo> & info)464 int32_t DCameraClient::CreatePhotoOutput(std::shared_ptr<DCameraCaptureInfo>& info)
465 {
466     DHLOGI("CreatePhotoOutput dhId: %{public}s, width: %{public}d, height: %{public}d, format: %{public}d, stream: "
467         "%{public}d, isCapture: %{public}d", GetAnonyString(cameraId_).c_str(), info->width_, info->height_,
468         info->format_, info->streamType_, info->isCapture_);
469     photoSurface_ = IConsumerSurface::Create();
470     photoListener_ = sptr<DCameraPhotoSurfaceListener>(
471         new DCameraPhotoSurfaceListener(photoSurface_, resultCallback_));
472     photoSurface_->RegisterConsumerListener((sptr<IBufferConsumerListener> &)photoListener_);
473     CameraStandard::CameraFormat photoFormat = ConvertToCameraFormat(info->format_);
474     CameraStandard::Size photoSize = {info->width_, info->height_};
475     CameraStandard::Profile photoProfile(photoFormat, photoSize);
476     sptr<IBufferProducer> bp = photoSurface_->GetProducer();
477     int32_t rv = cameraManager_->CreatePhotoOutput(
478         photoProfile, bp, &((sptr<CameraStandard::PhotoOutput> &)photoOutput_));
479     if (rv != DCAMERA_OK) {
480         DHLOGE("CreatePhotoOutput %{public}s create photo output failed", GetAnonyString(cameraId_).c_str());
481         return DCAMERA_BAD_VALUE;
482     }
483     std::shared_ptr<DCameraPhotoCallback> photoCallback = std::make_shared<DCameraPhotoCallback>(stateCallback_);
484     ((sptr<CameraStandard::PhotoOutput> &)photoOutput_)->SetCallback(photoCallback);
485     DHLOGI("CreatePhotoOutput %{public}s success", GetAnonyString(cameraId_).c_str());
486     return DCAMERA_OK;
487 }
488 
CreatePreviewOutput(std::shared_ptr<DCameraCaptureInfo> & info)489 int32_t DCameraClient::CreatePreviewOutput(std::shared_ptr<DCameraCaptureInfo>& info)
490 {
491     DHLOGI("CreatePreviewOutput dhId: %{public}s, width: %{public}d, height: %{public}d, format: %{public}d, stream:"
492         " %{public}d, isCapture: %{public}d", GetAnonyString(cameraId_).c_str(), info->width_, info->height_,
493         info->format_, info->streamType_, info->isCapture_);
494     CameraStandard::CameraFormat previewFormat = ConvertToCameraFormat(info->format_);
495     CameraStandard::Size previewSize = {info->width_, info->height_};
496     CameraStandard::Profile previewProfile(previewFormat, previewSize);
497     int32_t rv = cameraManager_->CreatePreviewOutput(
498         previewProfile, previewSurface_, &((sptr<CameraStandard::PreviewOutput> &)previewOutput_));
499     if (rv != DCAMERA_OK) {
500         DHLOGE("CreatePreviewOutput %{public}s create preview output failed", GetAnonyString(cameraId_).c_str());
501         return DCAMERA_BAD_VALUE;
502     }
503     auto previewCallback = std::make_shared<DCameraPreviewCallback>(stateCallback_);
504     ((sptr<CameraStandard::PreviewOutput> &)previewOutput_)->SetCallback(previewCallback);
505     DHLOGI("CreatePreviewOutput %{public}s success", GetAnonyString(cameraId_).c_str());
506     return DCAMERA_OK;
507 }
508 
ConvertToCameraFormat(int32_t format)509 CameraStandard::CameraFormat DCameraClient::ConvertToCameraFormat(int32_t format)
510 {
511     CameraStandard::CameraFormat ret = CameraStandard::CameraFormat::CAMERA_FORMAT_INVALID;
512     DCameraFormat df = static_cast<DCameraFormat>(format);
513     switch (df) {
514         case DCameraFormat::OHOS_CAMERA_FORMAT_RGBA_8888:
515             ret = CameraStandard::CameraFormat::CAMERA_FORMAT_RGBA_8888;
516             break;
517         case DCameraFormat::OHOS_CAMERA_FORMAT_YCBCR_420_888:
518             ret = CameraStandard::CameraFormat::CAMERA_FORMAT_YCBCR_420_888;
519             break;
520         case DCameraFormat::OHOS_CAMERA_FORMAT_YCRCB_420_SP:
521             ret = CameraStandard::CameraFormat::CAMERA_FORMAT_YUV_420_SP;
522             break;
523         case DCameraFormat::OHOS_CAMERA_FORMAT_JPEG:
524             ret = CameraStandard::CameraFormat::CAMERA_FORMAT_JPEG;
525             break;
526         default:
527             break;
528     }
529     return ret;
530 }
531 
StartCaptureInner(std::shared_ptr<DCameraCaptureInfo> & info)532 int32_t DCameraClient::StartCaptureInner(std::shared_ptr<DCameraCaptureInfo>& info)
533 {
534     if (info->streamType_ != SNAPSHOT_FRAME) {
535         DHLOGE("StartCaptureInner unknown stream type");
536         return DCAMERA_BAD_VALUE;
537     }
538     return StartPhotoOutput(info);
539 }
540 
StartPhotoOutput(std::shared_ptr<DCameraCaptureInfo> & info)541 int32_t DCameraClient::StartPhotoOutput(std::shared_ptr<DCameraCaptureInfo>& info)
542 {
543     DHLOGI("StartPhotoOutput cameraId: %{public}s", GetAnonyString(cameraId_).c_str());
544     if (photoOutput_ == nullptr) {
545         DHLOGE("StartPhotoOutput photoOutput is null");
546         return DCAMERA_BAD_VALUE;
547     }
548 
549     std::vector<std::shared_ptr<DCameraSettings>> captureSettings = info->captureSettings_;
550     std::string metadataSetting;
551     for (const auto& setting : captureSettings) {
552         if (setting->type_ == UPDATE_METADATA) {
553             DHLOGI("StartPhotoOutput %{public}s update metadata settings", GetAnonyString(cameraId_).c_str());
554             metadataSetting = setting->value_;
555         }
556     }
557 
558     if (metadataSetting.empty()) {
559         DHLOGE("StartPhotoOutput no metadata settings to update");
560         int32_t ret = ((sptr<CameraStandard::PhotoOutput> &)photoOutput_)->Capture();
561         if (ret != DCAMERA_OK) {
562             DHLOGE("StartPhotoOutput %{public}s photoOutput capture failed, ret: %{public}d",
563                 GetAnonyString(cameraId_).c_str(), ret);
564             return ret;
565         }
566         return DCAMERA_OK;
567     }
568 
569     std::string metadataStr = Base64Decode(metadataSetting);
570     std::shared_ptr<Camera::CameraMetadata> cameraMetadata = Camera::MetadataUtils::DecodeFromString(metadataStr);
571     std::shared_ptr<CameraStandard::PhotoCaptureSetting> photoCaptureSetting =
572         std::make_shared<CameraStandard::PhotoCaptureSetting>();
573     SetPhotoCaptureRotation(cameraMetadata, photoCaptureSetting);
574     SetPhotoCaptureQuality(cameraMetadata, photoCaptureSetting);
575     SetPhotoCaptureLocation(cameraMetadata, photoCaptureSetting);
576     int32_t ret = ((sptr<CameraStandard::PhotoOutput> &)photoOutput_)->Capture(photoCaptureSetting);
577     if (ret != DCAMERA_OK) {
578         DHLOGE("StartPhotoOutput %{public}s photoOutput capture failed, ret: %{public}d",
579             GetAnonyString(cameraId_).c_str(), ret);
580         return ret;
581     }
582     return DCAMERA_OK;
583 }
584 
SetPhotoCaptureRotation(const std::shared_ptr<Camera::CameraMetadata> & cameraMetadata,std::shared_ptr<CameraStandard::PhotoCaptureSetting> & photoCaptureSetting)585 void DCameraClient::SetPhotoCaptureRotation(const std::shared_ptr<Camera::CameraMetadata>& cameraMetadata,
586     std::shared_ptr<CameraStandard::PhotoCaptureSetting>& photoCaptureSetting)
587 {
588     CHECK_AND_RETURN_LOG(cameraMetadata == nullptr, "SetPhotoCaptureRotation param cameraMetadata is null");
589     uint32_t rotationCount = 1;
590     camera_metadata_item_t item;
591     int32_t ret = Camera::FindCameraMetadataItem(cameraMetadata->get(), OHOS_JPEG_ORIENTATION, &item);
592     if ((ret == CAM_META_SUCCESS) && (rotationCount == item.count)) {
593         CameraStandard::PhotoCaptureSetting::RotationConfig rotation =
594             static_cast<CameraStandard::PhotoCaptureSetting::RotationConfig>(item.data.i32[0]);
595         photoCaptureSetting->SetRotation(rotation);
596         DHLOGI("SetPhotoCaptureRotation %{public}s photo capture settings set %{public}d rotation: %{public}d",
597             GetAnonyString(cameraId_).c_str(), item.count, rotation);
598     }
599 }
600 
SetPhotoCaptureQuality(const std::shared_ptr<Camera::CameraMetadata> & cameraMetadata,std::shared_ptr<CameraStandard::PhotoCaptureSetting> & photoCaptureSetting)601 void DCameraClient::SetPhotoCaptureQuality(const std::shared_ptr<Camera::CameraMetadata>& cameraMetadata,
602     std::shared_ptr<CameraStandard::PhotoCaptureSetting>& photoCaptureSetting)
603 {
604     uint32_t qualityCount = 1;
605     camera_metadata_item_t item;
606     int32_t ret = Camera::FindCameraMetadataItem(cameraMetadata->get(), OHOS_JPEG_QUALITY, &item);
607     if ((ret == CAM_META_SUCCESS) && (qualityCount == item.count)) {
608         CameraStandard::PhotoCaptureSetting::QualityLevel quality =
609             static_cast<CameraStandard::PhotoCaptureSetting::QualityLevel>(item.data.u8[0]);
610         photoCaptureSetting->SetQuality(quality);
611         DHLOGI("SetPhotoCaptureQuality %{public}s photo capture settings set %{public}d quality: %{public}d",
612             GetAnonyString(cameraId_).c_str(), item.count, quality);
613     }
614 }
615 
SetPhotoCaptureLocation(const std::shared_ptr<Camera::CameraMetadata> & cameraMetadata,std::shared_ptr<CameraStandard::PhotoCaptureSetting> & photoCaptureSetting)616 void DCameraClient::SetPhotoCaptureLocation(const std::shared_ptr<Camera::CameraMetadata>& cameraMetadata,
617     std::shared_ptr<CameraStandard::PhotoCaptureSetting>& photoCaptureSetting)
618 {
619     uint32_t locationCount = 3;
620     camera_metadata_item_t item;
621     int32_t ret = Camera::FindCameraMetadataItem(cameraMetadata->get(), OHOS_JPEG_GPS_COORDINATES, &item);
622     if ((ret == CAM_META_SUCCESS) && (locationCount == item.count)) {
623         int32_t latitudeIndex = 0;
624         int32_t longitudeIndex = 1;
625         int32_t altitudeIndex = 2;
626         std::shared_ptr<CameraStandard::Location> location = std::make_shared<CameraStandard::Location>();
627         location->latitude = item.data.d[latitudeIndex];
628         location->longitude = item.data.d[longitudeIndex];
629         location->altitude = item.data.d[altitudeIndex];
630         photoCaptureSetting->SetLocation(location);
631         DHLOGI("SetPhotoCaptureLocation %{public}s photo capture settings set %{public}d location: "
632             "latitude=%{public}s, longitude=%{public}s, altitude=%{public}s", GetAnonyString(cameraId_).c_str(),
633             item.count, GetAnonyString(std::to_string(item.data.d[latitudeIndex])).c_str(),
634             GetAnonyString(std::to_string(item.data.d[longitudeIndex])).c_str(),
635             GetAnonyString(std::to_string(item.data.d[altitudeIndex])).c_str());
636     }
637 }
638 
PauseCapture()639 int32_t DCameraClient::PauseCapture()
640 {
641     if (captureSession_ == nullptr) {
642         DHLOGE("PauseCapture captureSession_ is nullptr.");
643         return DCAMERA_BAD_VALUE;
644     }
645     int32_t ret = captureSession_->Stop();
646     if (ret != DCAMERA_OK) {
647         DHLOGE("PauseCapture captureSession stop failed, cameraId: %{public}s, ret: %{public}d",
648                GetAnonyString(cameraId_).c_str(), ret);
649     }
650     return ret;
651 }
652 
ResumeCapture()653 int32_t DCameraClient::ResumeCapture()
654 {
655     if (captureSession_ == nullptr) {
656         DHLOGE("ResumeCapture captureSession_ is nullptr.");
657         return DCAMERA_BAD_VALUE;
658     }
659     int32_t ret = captureSession_->Start();
660     if (ret != DCAMERA_OK) {
661         DHLOGE("ResumeCapture captureSession Start failed, cameraId: %{public}s, ret: %{public}d",
662             GetAnonyString(cameraId_).c_str(), ret);
663     }
664     return ret;
665 }
666 } // namespace DistributedHardware
667 } // namespace OHOS
668