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 "output/photo_output.h"
17 
18 #include <mutex>
19 #include <securec.h>
20 
21 #include "camera_error_code.h"
22 #include "camera_log.h"
23 #include "camera_manager.h"
24 #include "camera_output_capability.h"
25 #include "camera_util.h"
26 #include "capture_scene_const.h"
27 #include "hstream_capture_callback_stub.h"
28 #include "image_type.h"
29 #include "input/camera_device.h"
30 #include "metadata_common_utils.h"
31 #include "session/capture_session.h"
32 #include "session/night_session.h"
33 #include "picture.h"
34 #include "task_manager.h"
35 
36 using namespace std;
37 
38 namespace OHOS {
39 namespace CameraStandard {
PhotoCaptureSetting()40 PhotoCaptureSetting::PhotoCaptureSetting()
41 {
42     int32_t items = 10;
43     int32_t dataLength = 100;
44     captureMetadataSetting_ = std::make_shared<Camera::CameraMetadata>(items, dataLength);
45     location_ = std::make_shared<Location>();
46 }
47 
GetQuality()48 PhotoCaptureSetting::QualityLevel PhotoCaptureSetting::GetQuality()
49 {
50     QualityLevel quality = QUALITY_LEVEL_LOW;
51     camera_metadata_item_t item;
52 
53     int ret = Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_JPEG_QUALITY, &item);
54     if (ret != CAM_META_SUCCESS) {
55         return QUALITY_LEVEL_MEDIUM;
56     }
57     if (item.data.u8[0] == OHOS_CAMERA_JPEG_LEVEL_HIGH) {
58         quality = QUALITY_LEVEL_HIGH;
59     } else if (item.data.u8[0] == OHOS_CAMERA_JPEG_LEVEL_MIDDLE) {
60         quality = QUALITY_LEVEL_MEDIUM;
61     }
62     return quality;
63 }
64 
SetQuality(PhotoCaptureSetting::QualityLevel qualityLevel)65 void PhotoCaptureSetting::SetQuality(PhotoCaptureSetting::QualityLevel qualityLevel)
66 {
67     bool status = false;
68     camera_metadata_item_t item;
69     uint8_t quality = OHOS_CAMERA_JPEG_LEVEL_LOW;
70 
71     if (qualityLevel == QUALITY_LEVEL_HIGH) {
72         quality = OHOS_CAMERA_JPEG_LEVEL_HIGH;
73     } else if (qualityLevel == QUALITY_LEVEL_MEDIUM) {
74         quality = OHOS_CAMERA_JPEG_LEVEL_MIDDLE;
75     }
76     int ret = Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_JPEG_QUALITY, &item);
77     if (ret == CAM_META_ITEM_NOT_FOUND) {
78         status = captureMetadataSetting_->addEntry(OHOS_JPEG_QUALITY, &quality, 1);
79     } else if (ret == CAM_META_SUCCESS) {
80         status = captureMetadataSetting_->updateEntry(OHOS_JPEG_QUALITY, &quality, 1);
81     }
82     CHECK_ERROR_PRINT_LOG(!status, "PhotoCaptureSetting::SetQuality Failed to set Quality");
83 }
84 
GetRotation()85 PhotoCaptureSetting::RotationConfig PhotoCaptureSetting::GetRotation()
86 {
87     RotationConfig rotation;
88     camera_metadata_item_t item;
89 
90     int ret = Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_JPEG_ORIENTATION, &item);
91     if (ret == CAM_META_SUCCESS) {
92         rotation = static_cast<RotationConfig>(item.data.i32[0]);
93         return rotation;
94     }
95     return RotationConfig::Rotation_0;
96 }
97 
SetRotation(PhotoCaptureSetting::RotationConfig rotationValue)98 void PhotoCaptureSetting::SetRotation(PhotoCaptureSetting::RotationConfig rotationValue)
99 {
100     bool status = false;
101     camera_metadata_item_t item;
102     int32_t rotation = rotationValue;
103 
104     int ret = Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_JPEG_ORIENTATION, &item);
105     if (ret == CAM_META_ITEM_NOT_FOUND) {
106         status = captureMetadataSetting_->addEntry(OHOS_JPEG_ORIENTATION, &rotation, 1);
107     } else if (ret == CAM_META_SUCCESS) {
108         status = captureMetadataSetting_->updateEntry(OHOS_JPEG_ORIENTATION, &rotation, 1);
109     }
110     CHECK_ERROR_PRINT_LOG(!status, "PhotoCaptureSetting::SetRotation Failed to set Rotation");
111     return;
112 }
113 
SetGpsLocation(double latitude,double longitude)114 void PhotoCaptureSetting::SetGpsLocation(double latitude, double longitude)
115 {
116     std::shared_ptr<Location> location = std::make_shared<Location>();
117     location->latitude = latitude;
118     location->longitude = longitude;
119     location->altitude = 0;
120     SetLocation(location);
121 }
122 
SetLocation(std::shared_ptr<Location> & location)123 void PhotoCaptureSetting::SetLocation(std::shared_ptr<Location>& location)
124 {
125     CHECK_ERROR_RETURN(location == nullptr);
126     std::lock_guard<std::mutex> lock(locationMutex_);
127     location_ = location;
128     double gpsCoordinates[3] = {location->latitude, location->longitude, location->altitude};
129     bool status = false;
130     camera_metadata_item_t item;
131 
132     MEDIA_DEBUG_LOG("PhotoCaptureSetting::SetLocation lat=%{private}f, long=%{private}f and alt=%{private}f",
133         location_->latitude, location_->longitude, location_->altitude);
134     int ret = Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_JPEG_GPS_COORDINATES, &item);
135     if (ret == CAM_META_ITEM_NOT_FOUND) {
136         status = captureMetadataSetting_->addEntry(
137             OHOS_JPEG_GPS_COORDINATES, gpsCoordinates, sizeof(gpsCoordinates) / sizeof(gpsCoordinates[0]));
138     } else if (ret == CAM_META_SUCCESS) {
139         status = captureMetadataSetting_->updateEntry(
140             OHOS_JPEG_GPS_COORDINATES, gpsCoordinates, sizeof(gpsCoordinates) / sizeof(gpsCoordinates[0]));
141     }
142     CHECK_ERROR_PRINT_LOG(!status, "PhotoCaptureSetting::SetLocation Failed to set GPS co-ordinates");
143 }
144 
GetLocation(std::shared_ptr<Location> & location)145 void PhotoCaptureSetting::GetLocation(std::shared_ptr<Location>& location)
146 {
147     std::lock_guard<std::mutex> lock(locationMutex_);
148     location = location_;
149     MEDIA_DEBUG_LOG("PhotoCaptureSetting::GetLocation lat=%{private}f, long=%{private}f and alt=%{private}f",
150         location->latitude, location->longitude, location->altitude);
151 }
152 
153 
SetMirror(bool enable)154 void PhotoCaptureSetting::SetMirror(bool enable)
155 {
156     bool status = false;
157     camera_metadata_item_t item;
158     uint8_t mirror = enable;
159 
160     MEDIA_DEBUG_LOG("PhotoCaptureSetting::SetMirror value=%{public}d", enable);
161     int ret = Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_CONTROL_CAPTURE_MIRROR, &item);
162     if (ret == CAM_META_ITEM_NOT_FOUND) {
163         status = captureMetadataSetting_->addEntry(OHOS_CONTROL_CAPTURE_MIRROR, &mirror, 1);
164     } else if (ret == CAM_META_SUCCESS) {
165         status = captureMetadataSetting_->updateEntry(OHOS_CONTROL_CAPTURE_MIRROR, &mirror, 1);
166     }
167     CHECK_ERROR_PRINT_LOG(!status, "PhotoCaptureSetting::SetMirror Failed to set mirroring in photo capture setting");
168     return;
169 }
170 
GetMirror()171 bool PhotoCaptureSetting::GetMirror()
172 {
173     bool isMirror;
174     camera_metadata_item_t item;
175     int ret = Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_CONTROL_CAPTURE_MIRROR, &item);
176     if (ret == CAM_META_SUCCESS) {
177         isMirror = static_cast<bool>(item.data.u8[0]);
178         return isMirror;
179     }
180     return false;
181 }
182 
GetCaptureMetadataSetting()183 std::shared_ptr<Camera::CameraMetadata> PhotoCaptureSetting::GetCaptureMetadataSetting()
184 {
185     return captureMetadataSetting_;
186 }
187 
SetBurstCaptureState(uint8_t burstState)188 void PhotoCaptureSetting::SetBurstCaptureState(uint8_t burstState)
189 {
190     CAMERA_SYNC_TRACE;
191     MEDIA_INFO_LOG("SetBurstCaptureState");
192     bool status = false;
193     camera_metadata_item_t item;
194     int ret = Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_CONTROL_BURST_CAPTURE, &item);
195     if (ret == CAM_META_ITEM_NOT_FOUND) {
196         status = captureMetadataSetting_->addEntry(OHOS_CONTROL_BURST_CAPTURE, &burstState, 1);
197     } else if (ret == CAM_META_SUCCESS) {
198         status = captureMetadataSetting_->updateEntry(OHOS_CONTROL_BURST_CAPTURE, &burstState, 1);
199     }
200     if (!status) {
201         MEDIA_ERR_LOG("PhotoCaptureSetting::SetBurstCaptureState Failed");
202     }
203     return;
204 }
205 
OnCaptureStarted(const int32_t captureId)206 int32_t HStreamCaptureCallbackImpl::OnCaptureStarted(const int32_t captureId)
207 {
208     CAMERA_SYNC_TRACE;
209     auto photoOutput = GetPhotoOutput();
210     CHECK_ERROR_RETURN_RET_LOG(photoOutput == nullptr, CAMERA_OK,
211         "HStreamCaptureCallbackImpl::OnCaptureStarted photoOutput is nullptr");
212     auto callback = photoOutput->GetApplicationCallback();
213     CHECK_ERROR_RETURN_RET_LOG(callback == nullptr, CAMERA_OK,
214         "HStreamCaptureCallbackImpl::OnCaptureStarted callback is nullptr");
215 
216     sptr<CaptureSession> session = photoOutput->GetSession();
217     switch (session->GetMode()) {
218         case SceneMode::HIGH_RES_PHOTO: {
219             auto inputDevice = session->GetInputDevice();
220             CHECK_ERROR_RETURN_RET_LOG(inputDevice == nullptr, CAMERA_OK,
221                 "HStreamCaptureCallbackImpl::OnCaptureStarted inputDevice is nullptr");
222             sptr<CameraDevice> cameraObj = inputDevice->GetCameraDeviceInfo();
223             std::shared_ptr<Camera::CameraMetadata> metadata = cameraObj->GetMetadata();
224             camera_metadata_item_t meta;
225             int32_t ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_ABILITY_CAPTURE_EXPECT_TIME, &meta);
226             if (ret == CAM_META_SUCCESS) {
227                 photoOutput->GetApplicationCallback()->OnCaptureStarted(captureId, meta.data.ui32[1]);
228             } else {
229                 MEDIA_WARNING_LOG("Discarding OnCaptureStarted callback, mode:%{public}d."
230                                   "exposureTime is not found",
231                     meta.data.ui32[0]);
232             }
233             break;
234         }
235         default:
236             photoOutput->GetApplicationCallback()->OnCaptureStarted(captureId);
237             break;
238     }
239     return CAMERA_OK;
240 }
241 
OnCaptureStarted(const int32_t captureId,uint32_t exposureTime)242 int32_t HStreamCaptureCallbackImpl::OnCaptureStarted(const int32_t captureId, uint32_t exposureTime)
243 {
244     CAMERA_SYNC_TRACE;
245     auto photoOutput = GetPhotoOutput();
246     CHECK_ERROR_RETURN_RET_LOG(photoOutput == nullptr, CAMERA_OK,
247         "HStreamCaptureCallbackImpl::OnCaptureStarted photoOutput is nullptr");
248     auto callback = photoOutput->GetApplicationCallback();
249     CHECK_ERROR_RETURN_RET_LOG(callback == nullptr, CAMERA_OK,
250         "HStreamCaptureCallbackImpl::OnCaptureStarted callback is nullptr");
251     photoOutput->GetApplicationCallback()->OnCaptureStarted(captureId, exposureTime);
252     return CAMERA_OK;
253 }
254 
OnCaptureEnded(const int32_t captureId,const int32_t frameCount)255 int32_t HStreamCaptureCallbackImpl::OnCaptureEnded(const int32_t captureId, const int32_t frameCount)
256 {
257     CAMERA_SYNC_TRACE;
258     auto photoOutput = GetPhotoOutput();
259     CHECK_ERROR_RETURN_RET_LOG(photoOutput == nullptr, CAMERA_OK,
260         "HStreamCaptureCallbackImpl::OnCaptureEnded photoOutput is nullptr");
261     auto callback = photoOutput->GetApplicationCallback();
262     CHECK_ERROR_RETURN_RET_LOG(callback == nullptr, CAMERA_OK,
263         "HStreamCaptureCallbackImpl::OnCaptureEnded callback is nullptr");
264     callback->OnCaptureEnded(captureId, frameCount);
265     return CAMERA_OK;
266 }
267 
OnCaptureError(const int32_t captureId,const int32_t errorCode)268 int32_t HStreamCaptureCallbackImpl::OnCaptureError(const int32_t captureId, const int32_t errorCode)
269 {
270     auto photoOutput = GetPhotoOutput();
271     CHECK_ERROR_RETURN_RET_LOG(photoOutput == nullptr, CAMERA_OK,
272         "HStreamCaptureCallbackImpl::OnCaptureError photoOutput is nullptr");
273     auto callback = photoOutput->GetApplicationCallback();
274     CHECK_ERROR_RETURN_RET_LOG(callback == nullptr, CAMERA_OK,
275         "HStreamCaptureCallbackImpl::OnCaptureError callback is nullptr");
276     callback->OnCaptureError(captureId, errorCode);
277     return CAMERA_OK;
278 }
279 
OnFrameShutter(const int32_t captureId,const uint64_t timestamp)280 int32_t HStreamCaptureCallbackImpl::OnFrameShutter(const int32_t captureId, const uint64_t timestamp)
281 {
282     CAMERA_SYNC_TRACE;
283     auto photoOutput = GetPhotoOutput();
284     CHECK_ERROR_RETURN_RET_LOG(photoOutput == nullptr, CAMERA_OK,
285         "HStreamCaptureCallbackImpl::OnFrameShutter photoOutput is nullptr");
286     auto callback = photoOutput->GetApplicationCallback();
287     CHECK_ERROR_RETURN_RET_LOG(callback == nullptr, CAMERA_OK,
288         "HStreamCaptureCallbackImpl::OnFrameShutter callback is nullptr");
289     callback->OnFrameShutter(captureId, timestamp);
290     return CAMERA_OK;
291 }
292 
OnFrameShutterEnd(const int32_t captureId,const uint64_t timestamp)293 int32_t HStreamCaptureCallbackImpl::OnFrameShutterEnd(const int32_t captureId, const uint64_t timestamp)
294 {
295     CAMERA_SYNC_TRACE;
296     auto photoOutput = GetPhotoOutput();
297     CHECK_ERROR_RETURN_RET_LOG(photoOutput == nullptr, CAMERA_OK,
298         "HStreamCaptureCallbackImpl::OnFrameShutterEnd photoOutput is nullptr");
299     auto callback = photoOutput->GetApplicationCallback();
300     CHECK_ERROR_RETURN_RET_LOG(callback == nullptr, CAMERA_OK,
301         "HStreamCaptureCallbackImpl::OnFrameShutterEnd callback is nullptr");
302     callback->OnFrameShutterEnd(captureId, timestamp);
303     return CAMERA_OK;
304 }
305 
OnCaptureReady(const int32_t captureId,const uint64_t timestamp)306 int32_t HStreamCaptureCallbackImpl::OnCaptureReady(const int32_t captureId, const uint64_t timestamp)
307 {
308     CAMERA_SYNC_TRACE;
309     auto photoOutput = GetPhotoOutput();
310     CHECK_ERROR_RETURN_RET_LOG(photoOutput == nullptr, CAMERA_OK,
311         "HStreamCaptureCallbackImpl::OnCaptureReady photoOutput is nullptr");
312     auto callback = photoOutput->GetApplicationCallback();
313     CHECK_ERROR_RETURN_RET_LOG(callback == nullptr, CAMERA_OK,
314         "HStreamCaptureCallbackImpl::OnCaptureReady callback is nullptr");
315     callback->OnCaptureReady(captureId, timestamp);
316     return CAMERA_OK;
317 }
318 
PhotoOutput(sptr<IBufferProducer> bufferProducer)319 PhotoOutput::PhotoOutput(sptr<IBufferProducer> bufferProducer)
320     : CaptureOutput(CAPTURE_OUTPUT_TYPE_PHOTO, StreamType::CAPTURE, bufferProducer, nullptr)
321 {
322     defaultCaptureSetting_ = nullptr;
323     taskManager_ = nullptr;
324 }
325 
~PhotoOutput()326 PhotoOutput::~PhotoOutput()
327 {
328     MEDIA_DEBUG_LOG("Enter Into PhotoOutput::~PhotoOutput()");
329     defaultCaptureSetting_ = nullptr;
330     if (taskManager_) {
331         taskManager_->CancelAllTasks();
332         taskManager_.reset();
333         taskManager_ = nullptr;
334     }
335 }
336 
SetNativeSurface(bool isNativeSurface)337 void PhotoOutput::SetNativeSurface(bool isNativeSurface)
338 {
339     MEDIA_INFO_LOG("Enter Into SetNativeSurface %{public}d", isNativeSurface);
340     isNativeSurface_ = isNativeSurface;
341 }
342 
SetCallbackFlag(uint8_t callbackFlag)343 void PhotoOutput::SetCallbackFlag(uint8_t callbackFlag)
344 {
345     std::lock_guard<std::mutex> lock(callbackMutex_);
346     CHECK_ERROR_RETURN_LOG(!isNativeSurface_, "SetCallbackFlag when register imageReciver");
347     bool beforeStatus = IsEnableDeferred();
348     callbackFlag_ = callbackFlag;
349     bool afterStatus = IsEnableDeferred();
350     // if session is commit or start, and isEnableDeferred is oppsite, need to restart session config
351     auto session = GetSession();
352     if (beforeStatus != afterStatus && session) {
353         if (session->IsSessionStarted()) {
354             FocusMode focusMode = session->GetFocusMode();
355             MEDIA_INFO_LOG("session restart when callback status changed %d", focusMode);
356             session->BeginConfig();
357             session->CommitConfig();
358             session->LockForControl();
359             session->SetFocusMode(focusMode);
360             session->UnlockForControl();
361             session->Start();
362         } else if (session->IsSessionCommited()) {
363             FocusMode focusMode = session->GetFocusMode();
364             MEDIA_INFO_LOG("session recommit when callback status changed %d", focusMode);
365             session->BeginConfig();
366             session->CommitConfig();
367             session->LockForControl();
368             session->SetFocusMode(focusMode);
369             session->UnlockForControl();
370         }
371     }
372 }
373 
IsYuvOrHeifPhoto()374 bool PhotoOutput::IsYuvOrHeifPhoto()
375 {
376     if (!GetPhotoProfile()) {
377         return false;
378     }
379     bool ret = GetPhotoProfile()->GetCameraFormat() == CAMERA_FORMAT_YUV_420_SP;
380     MEDIA_INFO_LOG("IsYuvOrHeifPhoto res = %{public}d", ret);
381     return ret;
382 }
383 
SetAuxiliaryPhotoHandle(uint32_t handle)384 void PhotoOutput::SetAuxiliaryPhotoHandle(uint32_t handle)
385 {
386     std::lock_guard<std::mutex> lock(watchDogHandleMutex_);
387     watchDogHandle_ = handle;
388 }
389 
390 
GetAuxiliaryPhotoHandle()391 uint32_t PhotoOutput::GetAuxiliaryPhotoHandle()
392 {
393     std::lock_guard<std::mutex> lock(watchDogHandleMutex_);
394     return watchDogHandle_;
395 }
396 
CreateMultiChannel()397 void PhotoOutput::CreateMultiChannel()
398 {
399     CAMERA_SYNC_TRACE;
400     auto streamCapturePtr = static_cast<IStreamCapture*>(GetStream().GetRefPtr());
401     if (streamCapturePtr == nullptr) {
402         MEDIA_ERR_LOG("PhotoOutput::CreateMultiChannel Failed!streamCapturePtr is nullptr");
403         return;
404     }
405     std::string retStr = "";
406     int32_t ret = 0;
407     if (gainmapSurface_ == nullptr) {
408         std::string bufferName = "gainmapImage";
409         gainmapSurface_ = Surface::CreateSurfaceAsConsumer(bufferName);
410         ret = streamCapturePtr->SetBufferProducerInfo(bufferName, gainmapSurface_->GetProducer());
411         retStr += (ret != CAMERA_OK ? bufferName + "," : retStr);
412     }
413     if (deepSurface_ == nullptr) {
414         std::string bufferName = "deepImage";
415         deepSurface_ = Surface::CreateSurfaceAsConsumer(bufferName);
416         ret = streamCapturePtr->SetBufferProducerInfo(bufferName, deepSurface_->GetProducer());
417         retStr += (ret != CAMERA_OK ? bufferName + "," : retStr);
418     }
419     if (exifSurface_ == nullptr) {
420         std::string bufferName = "exifImage";
421         exifSurface_ = Surface::CreateSurfaceAsConsumer(bufferName);
422         ret = streamCapturePtr->SetBufferProducerInfo(bufferName, exifSurface_->GetProducer());
423         retStr += (ret != CAMERA_OK ? bufferName + "," : retStr);
424     }
425     if (debugSurface_ == nullptr) {
426         std::string bufferName = "debugImage";
427         debugSurface_ = Surface::CreateSurfaceAsConsumer(bufferName);
428         ret = streamCapturePtr->SetBufferProducerInfo(bufferName, debugSurface_->GetProducer());
429         retStr += (ret != CAMERA_OK ? bufferName + "," : retStr);
430     }
431     MEDIA_INFO_LOG("PhotoOutput::CreateMultiChannel! failed channel is = %{public}s", retStr.c_str());
432 }
433 
IsEnableDeferred()434 bool PhotoOutput::IsEnableDeferred()
435 {
436     CHECK_ERROR_RETURN_RET(!isNativeSurface_, false);
437     bool isEnabled = (callbackFlag_ & CAPTURE_PHOTO_ASSET) != 0 || (callbackFlag_ & CAPTURE_PHOTO) == 0;
438     MEDIA_INFO_LOG("Enter Into PhotoOutput::IsEnableDeferred %{public}d", isEnabled);
439     return isEnabled;
440 }
441 
SetCallback(std::shared_ptr<PhotoStateCallback> callback)442 void PhotoOutput::SetCallback(std::shared_ptr<PhotoStateCallback> callback)
443 {
444     std::lock_guard<std::mutex> lock(outputCallbackMutex_);
445     appCallback_ = callback;
446     if (appCallback_ != nullptr) {
447         if (cameraSvcCallback_ == nullptr) {
448             cameraSvcCallback_ = new (std::nothrow) HStreamCaptureCallbackImpl(this);
449             if (cameraSvcCallback_ == nullptr) {
450                 MEDIA_ERR_LOG("PhotoOutput::SetCallback new HStreamCaptureCallbackImpl Failed to register callback");
451                 appCallback_ = nullptr;
452                 return;
453             }
454         }
455         auto itemStream = static_cast<IStreamCapture*>(GetStream().GetRefPtr());
456         int32_t errorCode = CAMERA_OK;
457         if (itemStream) {
458             errorCode = itemStream->SetCallback(cameraSvcCallback_);
459         } else {
460             MEDIA_ERR_LOG("PhotoOutput::SetCallback() itemStream is nullptr");
461         }
462         if (errorCode != CAMERA_OK) {
463             MEDIA_ERR_LOG("PhotoOutput::SetCallback: Failed to register callback, errorCode: %{public}d", errorCode);
464             cameraSvcCallback_ = nullptr;
465             appCallback_ = nullptr;
466         }
467     }
468 }
469 
SetThumbnailListener(sptr<IBufferConsumerListener> & listener)470 void PhotoOutput::SetThumbnailListener(sptr<IBufferConsumerListener>& listener)
471 {
472     if (thumbnailSurface_) {
473         SurfaceError ret = thumbnailSurface_->RegisterConsumerListener(listener);
474         CHECK_ERROR_PRINT_LOG(ret != SURFACE_ERROR_OK,
475             "PhotoOutput::SetThumbnailListener Surface consumer listener registration failed");
476     } else {
477         MEDIA_ERR_LOG("PhotoOutput SetThumbnailListener surface is null");
478     }
479 }
480 
SetThumbnail(bool isEnabled)481 int32_t PhotoOutput::SetThumbnail(bool isEnabled)
482 {
483     CAMERA_SYNC_TRACE;
484     sptr<CameraDevice> cameraObj;
485     auto session = GetSession();
486     CHECK_ERROR_RETURN_RET_LOG(session == nullptr, SESSION_NOT_RUNNING,
487         "PhotoOutput SetThumbnail error!, session is nullptr");
488     auto inputDevice = session->GetInputDevice();
489     CHECK_ERROR_RETURN_RET_LOG(inputDevice == nullptr, SESSION_NOT_RUNNING,
490         "PhotoOutput SetThumbnail error!, inputDevice is nullptr");
491     cameraObj = inputDevice->GetCameraDeviceInfo();
492     CHECK_ERROR_RETURN_RET_LOG(cameraObj == nullptr, SESSION_NOT_RUNNING,
493         "PhotoOutput SetThumbnail error!, cameraObj is nullptr");
494     !thumbnailSurface_ && (thumbnailSurface_ = Surface::CreateSurfaceAsConsumer("quickThumbnail"));
495     CHECK_ERROR_RETURN_RET_LOG(thumbnailSurface_ == nullptr, SERVICE_FATL_ERROR,
496         "PhotoOutput SetThumbnail Failed to create surface");
497     auto streamCapturePtr = static_cast<IStreamCapture*>(GetStream().GetRefPtr());
498     CHECK_ERROR_RETURN_RET(streamCapturePtr == nullptr, SERVICE_FATL_ERROR);
499     return streamCapturePtr->SetThumbnail(isEnabled, thumbnailSurface_->GetProducer());
500 }
501 
EnableRawDelivery(bool enabled)502 int32_t PhotoOutput::EnableRawDelivery(bool enabled)
503 {
504     CAMERA_SYNC_TRACE;
505     auto session = GetSession();
506     CHECK_ERROR_RETURN_RET_LOG(session == nullptr, SESSION_NOT_RUNNING,
507         "PhotoOutput EnableRawDelivery error!, session is nullptr");
508     auto streamCapturePtr = static_cast<IStreamCapture*>(GetStream().GetRefPtr());
509     CHECK_ERROR_RETURN_RET_LOG(streamCapturePtr == nullptr, SERVICE_FATL_ERROR,
510         "PhotoOutput::EnableRawDelivery Failed to GetStream");
511     int32_t ret = CAMERA_OK;
512     if (rawPhotoSurface_ == nullptr) {
513         std::string bufferName = "rawImage";
514         rawPhotoSurface_ = Surface::CreateSurfaceAsConsumer(bufferName);
515         ret = streamCapturePtr->SetBufferProducerInfo(bufferName, rawPhotoSurface_->GetProducer());
516         CHECK_ERROR_RETURN_RET_LOG(ret != CAMERA_OK, SERVICE_FATL_ERROR,
517             "PhotoOutput::EnableRawDelivery Failed to SetBufferProducerInfo");
518     }
519     if (session->EnableRawDelivery(enabled) == CameraErrorCode::SUCCESS) {
520         ret = streamCapturePtr->EnableRawDelivery(enabled);
521         CHECK_ERROR_RETURN_RET_LOG(ret != CAMERA_OK, SERVICE_FATL_ERROR,
522             "PhotoOutput::EnableRawDelivery session EnableRawDelivery Failed");
523     }
524     isRawImageDelivery_ = enabled;
525     return ret;
526 }
527 
SetRawPhotoInfo(sptr<Surface> & surface)528 int32_t PhotoOutput::SetRawPhotoInfo(sptr<Surface> &surface)
529 {
530     CAMERA_SYNC_TRACE;
531     auto streamCapturePtr = static_cast<IStreamCapture*>(GetStream().GetRefPtr());
532     CHECK_ERROR_RETURN_RET_LOG(streamCapturePtr == nullptr, SERVICE_FATL_ERROR,
533         "PhotoOutput::SetRawPhotoInfo Failed to create surface");
534     rawPhotoSurface_ = surface;
535     return streamCapturePtr->SetBufferProducerInfo("rawImage", rawPhotoSurface_->GetProducer());
536 }
537 
GetApplicationCallback()538 std::shared_ptr<PhotoStateCallback> PhotoOutput::GetApplicationCallback()
539 {
540     std::lock_guard<std::mutex> lock(outputCallbackMutex_);
541     return appCallback_;
542 }
543 
AcquireBufferToPrepareProxy(int32_t captureId)544 void PhotoOutput::AcquireBufferToPrepareProxy(int32_t captureId)
545 {
546     auto itemStream = static_cast<IStreamCapture*>(GetStream().GetRefPtr());
547     if (itemStream) {
548         itemStream->AcquireBufferToPrepareProxy(captureId);
549     } else {
550         MEDIA_ERR_LOG("PhotoOutput::AcquireBufferToPrepareProxy() itemStream is nullptr");
551     }
552 }
553 
Capture(std::shared_ptr<PhotoCaptureSetting> photoCaptureSettings)554 int32_t PhotoOutput::Capture(std::shared_ptr<PhotoCaptureSetting> photoCaptureSettings)
555 {
556     std::lock_guard<std::mutex> lock(asyncOpMutex_);
557     auto session = GetSession();
558     CHECK_ERROR_RETURN_RET_LOG(session == nullptr || !session->IsSessionCommited(),
559         CameraErrorCode::SESSION_NOT_RUNNING, "PhotoOutput Failed to Capture with setting, session not commited");
560     CHECK_ERROR_RETURN_RET_LOG(GetStream() == nullptr,
561         CameraErrorCode::SERVICE_FATL_ERROR, "PhotoOutput Failed to Capture with setting, GetStream is nullptr");
562     defaultCaptureSetting_ = photoCaptureSettings;
563     auto itemStream = static_cast<IStreamCapture*>(GetStream().GetRefPtr());
564     int32_t errCode = CAMERA_UNKNOWN_ERROR;
565     if (itemStream) {
566         MEDIA_DEBUG_LOG("Capture start");
567         session->EnableMovingPhotoMirror(photoCaptureSettings->GetMirror(), true);
568         errCode = itemStream->Capture(photoCaptureSettings->GetCaptureMetadataSetting());
569         MEDIA_DEBUG_LOG("Capture End");
570     } else {
571         MEDIA_ERR_LOG("PhotoOutput::Capture() itemStream is nullptr");
572     }
573     CHECK_ERROR_PRINT_LOG(errCode != CAMERA_OK, "PhotoOutput Failed to Capture!, errCode: %{public}d", errCode);
574     return ServiceToCameraError(errCode);
575 }
576 
Capture()577 int32_t PhotoOutput::Capture()
578 {
579     std::lock_guard<std::mutex> lock(asyncOpMutex_);
580     auto session = GetSession();
581     CHECK_ERROR_RETURN_RET_LOG(session == nullptr || !session->IsSessionCommited(),
582         CameraErrorCode::SESSION_NOT_RUNNING, "PhotoOutput Failed to Capture, session not commited");
583     CHECK_ERROR_RETURN_RET_LOG(GetStream() == nullptr, CameraErrorCode::SERVICE_FATL_ERROR,
584         "PhotoOutput Failed to Capture, GetStream is nullptr");
585     int32_t items = 0;
586     int32_t dataLength = 0;
587     std::shared_ptr<Camera::CameraMetadata> captureMetadataSetting =
588         std::make_shared<Camera::CameraMetadata>(items, dataLength);
589     auto itemStream = static_cast<IStreamCapture*>(GetStream().GetRefPtr());
590     int32_t errCode = CAMERA_UNKNOWN_ERROR;
591     if (itemStream) {
592         MEDIA_DEBUG_LOG("Capture start");
593         session->EnableMovingPhotoMirror(false, true);
594         errCode = itemStream->Capture(captureMetadataSetting);
595         MEDIA_DEBUG_LOG("Capture end");
596     } else {
597         MEDIA_ERR_LOG("PhotoOutput::Capture() itemStream is nullptr");
598     }
599     CHECK_ERROR_PRINT_LOG(errCode != CAMERA_OK, "PhotoOutput Failed to Capture!, errCode: %{public}d", errCode);
600     return ServiceToCameraError(errCode);
601 }
602 
CancelCapture()603 int32_t PhotoOutput::CancelCapture()
604 {
605     std::lock_guard<std::mutex> lock(asyncOpMutex_);
606     auto session = GetSession();
607     CHECK_ERROR_RETURN_RET_LOG(session == nullptr || !session->IsSessionCommited(),
608         CameraErrorCode::SESSION_NOT_RUNNING, "PhotoOutput Failed to CancelCapture, session not commited");
609     CHECK_ERROR_RETURN_RET_LOG(GetStream() == nullptr,
610         CameraErrorCode::SERVICE_FATL_ERROR, "PhotoOutput Failed to CancelCapture, GetStream is nullptr");
611     auto itemStream = static_cast<IStreamCapture*>(GetStream().GetRefPtr());
612     int32_t errCode = CAMERA_UNKNOWN_ERROR;
613     if (itemStream) {
614         errCode = itemStream->CancelCapture();
615     } else {
616         MEDIA_ERR_LOG("PhotoOutput::CancelCapture() itemStream is nullptr");
617     }
618     CHECK_ERROR_PRINT_LOG(errCode != CAMERA_OK, "PhotoOutput Failed to CancelCapture, errCode: %{public}d", errCode);
619     return ServiceToCameraError(errCode);
620 }
621 
ConfirmCapture()622 int32_t PhotoOutput::ConfirmCapture()
623 {
624     std::lock_guard<std::mutex> lock(asyncOpMutex_);
625     auto session = GetSession();
626     CHECK_ERROR_RETURN_RET_LOG(session == nullptr || !session->IsSessionCommited(),
627         CameraErrorCode::SESSION_NOT_RUNNING, "PhotoOutput Failed to ConfirmCapture, session not commited");
628     CHECK_ERROR_RETURN_RET_LOG(GetStream() == nullptr, CameraErrorCode::SERVICE_FATL_ERROR,
629         "PhotoOutput Failed to ConfirmCapture, GetStream is nullptr");
630     auto itemStream = static_cast<IStreamCapture*>(GetStream().GetRefPtr());
631     int32_t errCode = CAMERA_UNKNOWN_ERROR;
632     if (itemStream) {
633         errCode = itemStream->ConfirmCapture();
634     } else {
635         MEDIA_ERR_LOG("PhotoOutput::ConfirmCapture() itemStream is nullptr");
636     }
637     CHECK_ERROR_PRINT_LOG(errCode != CAMERA_OK, "PhotoOutput Failed to ConfirmCapture, errCode: %{public}d", errCode);
638     return ServiceToCameraError(errCode);
639 }
640 
CreateStream()641 int32_t PhotoOutput::CreateStream()
642 {
643     auto stream = GetStream();
644     CHECK_ERROR_RETURN_RET_LOG(stream != nullptr, CameraErrorCode::OPERATION_NOT_ALLOWED,
645         "PhotoOutput::CreateStream stream is not null");
646     auto producer = GetBufferProducer();
647     CHECK_ERROR_RETURN_RET_LOG(producer == nullptr, CameraErrorCode::OPERATION_NOT_ALLOWED,
648         "PhotoOutput::CreateStream producer is null");
649     sptr<IStreamCapture> streamPtr = nullptr;
650     auto photoProfile = GetPhotoProfile();
651     CHECK_ERROR_RETURN_RET_LOG(photoProfile == nullptr, CameraErrorCode::SERVICE_FATL_ERROR,
652         "PhotoOutput::CreateStream photoProfile is null");
653 
654     int32_t res = CameraManager::GetInstance()->CreatePhotoOutputStream(streamPtr, *photoProfile, GetBufferProducer());
655     CHECK_ERROR_PRINT_LOG(res != CameraErrorCode::SUCCESS,
656         "PhotoOutput::CreateStream fail! error code :%{public}d", res);
657     SetStream(streamPtr);
658     return res;
659 }
660 
Release()661 int32_t PhotoOutput::Release()
662 {
663     {
664         std::lock_guard<std::mutex> lock(outputCallbackMutex_);
665         cameraSvcCallback_ = nullptr;
666         appCallback_ = nullptr;
667     }
668     std::lock_guard<std::mutex> lock(asyncOpMutex_);
669     MEDIA_DEBUG_LOG("Enter Into PhotoOutput::Release");
670     CHECK_ERROR_RETURN_RET_LOG(GetStream() == nullptr, CameraErrorCode::SERVICE_FATL_ERROR,
671         "PhotoOutput Failed to Release!, GetStream is nullptr");
672     auto itemStream = static_cast<IStreamCapture*>(GetStream().GetRefPtr());
673     int32_t errCode = CAMERA_UNKNOWN_ERROR;
674     if (itemStream) {
675         errCode = itemStream->Release();
676     } else {
677         MEDIA_ERR_LOG("PhotoOutput::Release() itemStream is nullptr");
678     }
679     CHECK_ERROR_PRINT_LOG(errCode != CAMERA_OK, "PhotoOutput Failed to release!, errCode: %{public}d", errCode);
680     defaultCaptureSetting_ = nullptr;
681     CaptureOutput::Release();
682     if (taskManager_) {
683         taskManager_->CancelAllTasks();
684         taskManager_.reset();
685         taskManager_ = nullptr;
686     }
687     return ServiceToCameraError(errCode);
688 }
689 
IsMirrorSupported()690 bool PhotoOutput::IsMirrorSupported()
691 {
692     auto session = GetSession();
693     CHECK_ERROR_RETURN_RET_LOG(session == nullptr, false,
694         "PhotoOutput IsMirrorSupported error!, session is nullptr");
695     auto inputDevice = session->GetInputDevice();
696     CHECK_ERROR_RETURN_RET_LOG(inputDevice == nullptr, false,
697         "PhotoOutput IsMirrorSupported error!, inputDevice is nullptr");
698     sptr<CameraDevice> cameraObj = inputDevice->GetCameraDeviceInfo();
699     CHECK_ERROR_RETURN_RET_LOG(cameraObj == nullptr, false,
700         "PhotoOutput IsMirrorSupported error!, cameraObj is nullptr");
701     std::shared_ptr<Camera::CameraMetadata> metadata = cameraObj->GetMetadata();
702     CHECK_ERROR_RETURN_RET(metadata == nullptr, false);
703 
704     camera_metadata_item_t item;
705     int32_t ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_CONTROL_CAPTURE_MIRROR_SUPPORTED, &item);
706     CHECK_ERROR_RETURN_RET_LOG(ret != CAM_META_SUCCESS, false,
707         "PhotoOutput Can not find OHOS_CONTROL_CAPTURE_MIRROR_SUPPORTED");
708     int step = 2;
709     const int32_t canMirrorVideoAndPhoto = 2;
710     const int32_t canMirrorPhotoOnly = 1;
711     bool isMirrorEnabled = false;
712     SceneMode currentSceneMode = session->GetMode();
713     for (int i = 0; i < static_cast<int>(item.count); i += step) {
714         MEDIA_DEBUG_LOG("mode u8[%{public}d]: %{public}d, u8[%{public}d], %{public}d",
715             i, item.data.u8[i], i + 1, item.data.u8[i + 1]);
716         if (currentSceneMode == static_cast<int>(item.data.u8[i])) {
717             isMirrorEnabled = (
718                 item.data.u8[i + 1] == canMirrorPhotoOnly ||
719                 item.data.u8[i + 1] == canMirrorVideoAndPhoto) ? true : false;
720         }
721     }
722     MEDIA_DEBUG_LOG("IsMirrorSupported isSupport: %{public}d", isMirrorEnabled);
723     return isMirrorEnabled;
724 }
725 
EnableMirror(bool isEnable)726 int32_t PhotoOutput::EnableMirror(bool isEnable)
727 {
728     MEDIA_INFO_LOG("PhotoOutput::EnableMirror enter, isEnable: %{public}d", isEnable);
729     auto session = GetSession();
730     CHECK_ERROR_RETURN_RET_LOG(session == nullptr, CameraErrorCode::SESSION_NOT_RUNNING,
731         "PhotoOutput EnableMirror error!, session is nullptr");
732 
733     int32_t ret = CAMERA_UNKNOWN_ERROR;
734     if (IsMirrorSupported()) {
735         auto isSessionConfiged = session->IsSessionCommited() || session->IsSessionStarted();
736         ret = session->EnableMovingPhotoMirror(isEnable, isSessionConfiged);
737         CHECK_ERROR_RETURN_RET_LOG(ret != CameraErrorCode::SUCCESS, ret,
738             "PhotoOutput EnableMirror error!, ret is not success");
739     } else {
740         MEDIA_ERR_LOG("PhotoOutput EnableMirror error!, mirror is not supported");
741     }
742     return ret;
743 }
744 
IsQuickThumbnailSupported()745 int32_t PhotoOutput::IsQuickThumbnailSupported()
746 {
747     int32_t isQuickThumbnailEnabled = -1;
748     auto session = GetSession();
749     CHECK_ERROR_RETURN_RET_LOG(session == nullptr, SESSION_NOT_RUNNING,
750         "PhotoOutput IsQuickThumbnailSupported error!, session is nullptr");
751     auto inputDevice = session->GetInputDevice();
752     CHECK_ERROR_RETURN_RET_LOG(inputDevice == nullptr, SESSION_NOT_RUNNING,
753         "PhotoOutput IsQuickThumbnailSupported error!, inputDevice is nullptr");
754     sptr<CameraDevice> cameraObj = inputDevice->GetCameraDeviceInfo();
755     CHECK_ERROR_RETURN_RET_LOG(cameraObj == nullptr, SESSION_NOT_RUNNING,
756         "PhotoOutput IsQuickThumbnailSupported error!, cameraObj is nullptr");
757     std::shared_ptr<Camera::CameraMetadata> metadata = cameraObj->GetMetadata();
758     CHECK_ERROR_RETURN_RET(metadata == nullptr, SESSION_NOT_RUNNING);
759     camera_metadata_item_t item;
760     int32_t ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_ABILITY_STREAM_QUICK_THUMBNAIL_AVAILABLE, &item);
761     if (ret == CAM_META_SUCCESS) {
762         isQuickThumbnailEnabled = (item.data.u8[0] == 1) ? 0 : -1;
763     }
764     const int32_t nightMode = 4;
765     if ((session->GetMode() == nightMode && (cameraObj->GetPosition() != CAMERA_POSITION_FRONT)) ||
766         session->GetMode() == LIGHT_PAINTING) {
767         isQuickThumbnailEnabled = -1;
768     }
769     return isQuickThumbnailEnabled;
770 }
771 
IsRawDeliverySupported()772 int32_t PhotoOutput::IsRawDeliverySupported()
773 {
774     int32_t isRawDevliveryEnabled = -1;
775     auto session = GetSession();
776     CHECK_ERROR_RETURN_RET_LOG(session == nullptr, SESSION_NOT_RUNNING,
777         "PhotoOutput IsRawDeliverySupported error!, session is nullptr");
778     const int32_t professionalPhotoMode = 11;
779     if ((session->GetMode() == professionalPhotoMode)) {
780         isRawDevliveryEnabled = 1;
781     }
782     return isRawDevliveryEnabled;
783 }
784 
DeferImageDeliveryFor(DeferredDeliveryImageType type)785 int32_t PhotoOutput::DeferImageDeliveryFor(DeferredDeliveryImageType type)
786 {
787     MEDIA_INFO_LOG("PhotoOutput DeferImageDeliveryFor type:%{public}d!", type);
788     CAMERA_SYNC_TRACE;
789     sptr<CameraDevice> cameraObj;
790     auto session = GetSession();
791     CHECK_ERROR_RETURN_RET_LOG(session == nullptr, SESSION_NOT_RUNNING,
792         "PhotoOutput DeferImageDeliveryFor error!, session is nullptr");
793     auto inputDevice = session->GetInputDevice();
794     CHECK_ERROR_RETURN_RET_LOG(inputDevice == nullptr, SESSION_NOT_RUNNING,
795         "PhotoOutput DeferImageDeliveryFor error!, inputDevice is nullptr");
796     cameraObj = inputDevice->GetCameraDeviceInfo();
797     CHECK_ERROR_RETURN_RET_LOG(cameraObj == nullptr, SESSION_NOT_RUNNING,
798         "PhotoOutput DeferImageDeliveryFor error!, cameraObj is nullptr");
799     session->EnableDeferredType(type, true);
800     session->SetUserId();
801     return 0;
802 }
803 
IsDeferredImageDeliverySupported(DeferredDeliveryImageType type)804 int32_t PhotoOutput::IsDeferredImageDeliverySupported(DeferredDeliveryImageType type)
805 {
806     MEDIA_INFO_LOG("IsDeferredImageDeliverySupported type:%{public}d!", type);
807     int32_t isSupported = -1;
808     if (type == DELIVERY_NONE) {
809         return isSupported;
810     }
811     sptr<CameraDevice> cameraObj;
812     auto session = GetSession();
813     CHECK_ERROR_RETURN_RET_LOG(session == nullptr, SESSION_NOT_RUNNING,
814         "PhotoOutput IsDeferredImageDeliverySupported error!, session is nullptr");
815     auto inputDevice = session->GetInputDevice();
816     CHECK_ERROR_RETURN_RET_LOG(inputDevice == nullptr, SESSION_NOT_RUNNING,
817         "PhotoOutput IsDeferredImageDeliverySupported error!, inputDevice is nullptr");
818     cameraObj = inputDevice->GetCameraDeviceInfo();
819     CHECK_ERROR_RETURN_RET_LOG(cameraObj == nullptr, SESSION_NOT_RUNNING,
820         "PhotoOutput IsDeferredImageDeliverySupported error!, cameraObj is nullptr");
821     int32_t curMode = session->GetMode();
822     int32_t modeSupportType = cameraObj->modeDeferredType_[curMode];
823     MEDIA_INFO_LOG("IsDeferredImageDeliverySupported curMode:%{public}d, modeSupportType:%{public}d",
824         curMode, modeSupportType);
825     if (modeSupportType == type) {
826         isSupported = 0;
827     }
828     return isSupported;
829 }
830 
IsDeferredImageDeliveryEnabled(DeferredDeliveryImageType type)831 int32_t PhotoOutput::IsDeferredImageDeliveryEnabled(DeferredDeliveryImageType type)
832 {
833     MEDIA_INFO_LOG("PhotoOutput IsDeferredImageDeliveryEnabled type:%{public}d!", type);
834     int32_t isEnabled = -1;
835     auto session = GetSession();
836     CHECK_ERROR_RETURN_RET_LOG(session == nullptr, SESSION_NOT_RUNNING,
837         "PhotoOutput IsDeferredImageDeliveryEnabled error!, session is nullptr");
838     auto inputDevice = session->GetInputDevice();
839     CHECK_ERROR_RETURN_RET_LOG(inputDevice == nullptr, SESSION_NOT_RUNNING,
840         "PhotoOutput IsDeferredImageDeliveryEnabled error!, inputDevice is nullptr");
841     sptr<CameraDevice> cameraObj = inputDevice->GetCameraDeviceInfo();
842     CHECK_ERROR_RETURN_RET_LOG(cameraObj == nullptr, SESSION_NOT_RUNNING,
843         "PhotoOutput IsDeferredImageDeliveryEnabled error!, cameraObj is nullptr");
844     isEnabled = session->IsImageDeferred() ? 0 : -1;
845     return isEnabled;
846 }
847 
IsAutoHighQualityPhotoSupported(int32_t & isAutoHighQualityPhotoSupported)848 int32_t PhotoOutput::IsAutoHighQualityPhotoSupported(int32_t &isAutoHighQualityPhotoSupported)
849 {
850     MEDIA_INFO_LOG("PhotoOutput IsAutoHighQualityPhotoSupported is called");
851     isAutoHighQualityPhotoSupported = -1;
852     camera_metadata_item_t item;
853     sptr<CameraDevice> cameraObj;
854     auto session = GetSession();
855     CHECK_ERROR_RETURN_RET_LOG(session == nullptr, SESSION_NOT_RUNNING,
856         "PhotoOutput IsAutoHighQualityPhotoSupported error!, session is nullptr");
857     auto inputDevice = session->GetInputDevice();
858     CHECK_ERROR_RETURN_RET_LOG(inputDevice == nullptr, SESSION_NOT_RUNNING,
859         "PhotoOutput IsAutoHighQualityPhotoSupported error!, inputDevice is nullptr");
860     cameraObj = inputDevice->GetCameraDeviceInfo();
861     CHECK_ERROR_RETURN_RET_LOG(cameraObj == nullptr, SESSION_NOT_RUNNING,
862         "PhotoOutput IsAutoHighQualityPhotoSupported error!, cameraObj is nullptr");
863     std::shared_ptr<Camera::CameraMetadata> metadata = cameraObj->GetMetadata();
864     CHECK_ERROR_RETURN_RET(metadata == nullptr, SESSION_NOT_RUNNING);
865     int32_t ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_ABILITY_HIGH_QUALITY_SUPPORT, &item);
866     if (ret == CAM_META_SUCCESS) {
867         isAutoHighQualityPhotoSupported = (item.data.u8[1] == 1) ? 0 : -1; // default mode
868     }
869 
870     int headLenPerMode = 2;
871     SceneMode currentSceneMode = session->GetMode();
872     for (int i = 0; i < static_cast<int>(item.count); i += headLenPerMode) {
873         if (currentSceneMode == static_cast<int>(item.data.u8[i])) {
874             isAutoHighQualityPhotoSupported = (item.data.u8[i + 1] == 1) ? 0 : -1;
875         }
876     }
877     MEDIA_INFO_LOG("PhotoOutput IsAutoHighQualityPhotoSupported curMode:%{public}d, modeSupportType:%{public}d",
878         currentSceneMode, isAutoHighQualityPhotoSupported);
879     return CAMERA_OK;
880 }
881 
EnableAutoHighQualityPhoto(bool enabled)882 int32_t PhotoOutput::EnableAutoHighQualityPhoto(bool enabled)
883 {
884     MEDIA_DEBUG_LOG("PhotoOutput EnableAutoHighQualityPhoto");
885     auto session = GetSession();
886     CHECK_ERROR_RETURN_RET_LOG(session == nullptr, SESSION_NOT_RUNNING,
887         "PhotoOutput EnableAutoHighQualityPhoto error!, session is nullptr");
888     auto inputDevice = session->GetInputDevice();
889     CHECK_ERROR_RETURN_RET_LOG(inputDevice == nullptr, SESSION_NOT_RUNNING,
890         "PhotoOutput EnableAutoHighQualityPhoto error!, inputDevice is nullptr");
891     int32_t isAutoHighQualityPhotoSupported;
892     int32_t ret = IsAutoHighQualityPhotoSupported(isAutoHighQualityPhotoSupported);
893     CHECK_ERROR_RETURN_RET_LOG(ret != CAMERA_OK, OPERATION_NOT_ALLOWED,
894         "PhotoOutput EnableAutoHighQualityPhoto error");
895     CHECK_ERROR_RETURN_RET_LOG(isAutoHighQualityPhotoSupported == -1, INVALID_ARGUMENT,
896         "PhotoOutput EnableAutoHighQualityPhoto not supported");
897     int32_t res = session->EnableAutoHighQualityPhoto(enabled);
898     return res;
899 }
900 
ProcessSnapshotDurationUpdates(int32_t snapshotDuration)901 void PhotoOutput::ProcessSnapshotDurationUpdates(int32_t snapshotDuration) __attribute__((no_sanitize("cfi")))
902 {
903     std::lock_guard<std::mutex> lock(outputCallbackMutex_);
904     if (appCallback_ != nullptr) {
905         MEDIA_DEBUG_LOG("appCallback not nullptr");
906         appCallback_->OnEstimatedCaptureDuration(snapshotDuration);
907     }
908 }
909 
GetDefaultCaptureSetting()910 std::shared_ptr<PhotoCaptureSetting> PhotoOutput::GetDefaultCaptureSetting()
911 {
912     return defaultCaptureSetting_;
913 }
914 
SetMovingPhotoVideoCodecType(int32_t videoCodecType)915 int32_t PhotoOutput::SetMovingPhotoVideoCodecType(int32_t videoCodecType)
916 {
917     std::lock_guard<std::mutex> lock(asyncOpMutex_);
918     MEDIA_DEBUG_LOG("Enter Into PhotoOutput::SetMovingPhotoVideoCodecType");
919     CHECK_ERROR_RETURN_RET_LOG(GetStream() == nullptr, CameraErrorCode::SERVICE_FATL_ERROR,
920         "PhotoOutput Failed to SetMovingPhotoVideoCodecType!, GetStream is nullptr");
921     auto itemStream = static_cast<IStreamCapture*>(GetStream().GetRefPtr());
922     int32_t errCode = CAMERA_UNKNOWN_ERROR;
923     if (itemStream) {
924         errCode = itemStream->SetMovingPhotoVideoCodecType(videoCodecType);
925     } else {
926         MEDIA_ERR_LOG("PhotoOutput::SetMovingPhotoVideoCodecType() itemStream is nullptr");
927     }
928     CHECK_ERROR_PRINT_LOG(errCode != CAMERA_OK, "PhotoOutput Failed to SetMovingPhotoVideoCodecType!, "
929         "errCode: %{public}d", errCode);
930     return ServiceToCameraError(errCode);
931 }
932 
CameraServerDied(pid_t pid)933 void PhotoOutput::CameraServerDied(pid_t pid)
934 {
935     MEDIA_ERR_LOG("camera server has died, pid:%{public}d!", pid);
936     std::lock_guard<std::mutex> lock(outputCallbackMutex_);
937     if (appCallback_ != nullptr) {
938         MEDIA_DEBUG_LOG("appCallback not nullptr");
939         int32_t serviceErrorType = ServiceToCameraError(CAMERA_INVALID_STATE);
940         int32_t captureId = -1;
941         appCallback_->OnCaptureError(captureId, serviceErrorType);
942     }
943 }
944 
GetPhotoRotation(int32_t imageRotation)945 int32_t PhotoOutput::GetPhotoRotation(int32_t imageRotation)
946 {
947     MEDIA_DEBUG_LOG("PhotoOutput GetPhotoRotation is called");
948     int32_t sensorOrientation = 0;
949     CameraPosition cameraPosition;
950     camera_metadata_item_t item;
951     ImageRotation result = ImageRotation::ROTATION_0;
952     sptr<CameraDevice> cameraObj;
953     auto session = GetSession();
954     CHECK_ERROR_RETURN_RET_LOG(session == nullptr, SERVICE_FATL_ERROR,
955         "PhotoOutput GetPhotoRotation error!, session is nullptr");
956     auto inputDevice = session->GetInputDevice();
957     CHECK_ERROR_RETURN_RET_LOG(inputDevice == nullptr, SERVICE_FATL_ERROR,
958         "PhotoOutput GetPhotoRotation error!, inputDevice is nullptr");
959     cameraObj = inputDevice->GetCameraDeviceInfo();
960     CHECK_ERROR_RETURN_RET_LOG(cameraObj == nullptr, SERVICE_FATL_ERROR,
961         "PhotoOutput GetPhotoRotation error!, cameraObj is nullptr");
962     cameraPosition = cameraObj->GetPosition();
963     CHECK_ERROR_RETURN_RET_LOG(cameraPosition == CAMERA_POSITION_UNSPECIFIED, SERVICE_FATL_ERROR,
964         "PhotoOutput GetPhotoRotation error!, cameraPosition is unspecified");
965     std::shared_ptr<Camera::CameraMetadata> metadata = cameraObj->GetMetadata();
966     CHECK_ERROR_RETURN_RET(metadata == nullptr, SERVICE_FATL_ERROR);
967     int32_t ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_SENSOR_ORIENTATION, &item);
968     CHECK_ERROR_RETURN_RET_LOG(ret != CAM_META_SUCCESS, SERVICE_FATL_ERROR,
969         "PhotoOutput Can not find OHOS_SENSOR_ORIENTATION");
970     sensorOrientation = item.data.i32[0];
971     imageRotation = (imageRotation + ROTATION_45_DEGREES) / ROTATION_90_DEGREES * ROTATION_90_DEGREES;
972     if (cameraPosition == CAMERA_POSITION_BACK) {
973         result = (ImageRotation)((imageRotation + sensorOrientation) % CAPTURE_ROTATION_BASE);
974     } else if (cameraPosition == CAMERA_POSITION_FRONT || cameraPosition == CAMERA_POSITION_FOLD_INNER) {
975         result = (ImageRotation)((sensorOrientation - imageRotation + CAPTURE_ROTATION_BASE) % CAPTURE_ROTATION_BASE);
976     }
977     auto streamCapturePtr = static_cast<IStreamCapture*>(GetStream().GetRefPtr());
978     int32_t errCode = CAMERA_UNKNOWN_ERROR;
979     if (streamCapturePtr) {
980         errCode = streamCapturePtr->SetCameraPhotoRotation(true);
981         CHECK_ERROR_RETURN_RET_LOG(errCode != CAMERA_OK, SERVICE_FATL_ERROR,
982             "Failed to SetCameraPhotoRotation!, errCode: %{public}d", errCode);
983     } else {
984         MEDIA_ERR_LOG("PhotoOutput::SetCameraPhotoRotation() streamCapturePtr is nullptr");
985         return CameraErrorCode::SERVICE_FATL_ERROR;
986     }
987     MEDIA_INFO_LOG("PhotoOutput GetPhotoRotation :result %{public}d, sensorOrientation:%{public}d",
988         result, sensorOrientation);
989     return result;
990 }
IsAutoCloudImageEnhancementSupported(bool & isAutoCloudImageEnhancementSupported)991 int32_t PhotoOutput::IsAutoCloudImageEnhancementSupported(bool &isAutoCloudImageEnhancementSupported)
992 {
993     MEDIA_INFO_LOG("PhotoOutput IsAutoCloudImageEnhancementSupported is called");
994     auto session = GetSession();
995     if (session == nullptr) {
996         return SERVICE_FATL_ERROR;
997     }
998     auto inputDevice = session->GetInputDevice();
999     if (inputDevice == nullptr) {
1000         MEDIA_ERR_LOG("PhotoOutput IsAutoCloudImageEnhancementSupported error!, inputDevice is nullptr");
1001         return SERVICE_FATL_ERROR;
1002     }
1003     sptr<CameraDevice> cameraObj = inputDevice->GetCameraDeviceInfo();
1004     if (cameraObj == nullptr) {
1005         MEDIA_ERR_LOG("PhotoOutput IsAutoCloudImageEnhancementSupported error!, cameraObj is nullptr");
1006         return SERVICE_FATL_ERROR;
1007     }
1008     std::shared_ptr<Camera::CameraMetadata> metadata = cameraObj->GetMetadata();
1009     if (metadata == nullptr) {
1010         return SERVICE_FATL_ERROR;
1011     }
1012     camera_metadata_item_t item;
1013     int32_t ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_ABILITY_AUTO_CLOUD_IMAGE_ENHANCE, &item);
1014     if (ret == CAM_META_SUCCESS) {
1015         if (item.count == 0) {
1016             MEDIA_WARNING_LOG("IsAutoCloudImageEnhancementNotSupported item is nullptr");
1017             return CAMERA_OK;
1018         }
1019         SceneMode currentSceneMode = session->GetMode();
1020         for (int i = 0; i < static_cast<int>(item.count); i++) {
1021             if (currentSceneMode == static_cast<int>(item.data.i32[i])) {
1022                 isAutoCloudImageEnhancementSupported = true;
1023                 return CAMERA_OK;
1024             }
1025         }
1026     }
1027     MEDIA_DEBUG_LOG("Judge Auto Cloud Image Enhancement Supported result:%{public}d ",
1028         isAutoCloudImageEnhancementSupported);
1029     return CAMERA_OK;
1030 }
1031 
EnableAutoCloudImageEnhancement(bool enabled)1032 int32_t PhotoOutput::EnableAutoCloudImageEnhancement(bool enabled)
1033 {
1034     MEDIA_DEBUG_LOG("PhotoOutput EnableAutoCloudImageEnhancement");
1035     auto captureSession = GetSession();
1036     if (captureSession == nullptr) {
1037         MEDIA_ERR_LOG("PhotoOutput IsAutoHighQualityPhotoSupported error!, captureSession is nullptr");
1038         return SERVICE_FATL_ERROR;
1039     }
1040     auto inputDevice = captureSession->GetInputDevice();
1041     if (inputDevice == nullptr) {
1042         MEDIA_ERR_LOG("PhotoOutput IsAutoHighQualityPhotoSupported error!, inputDevice is nullptr");
1043         return SERVICE_FATL_ERROR;
1044     }
1045     bool isAutoCloudImageEnhancementSupported = false;
1046     int32_t ret = IsAutoCloudImageEnhancementSupported(isAutoCloudImageEnhancementSupported);
1047     CHECK_ERROR_RETURN_RET_LOG(ret != CAMERA_OK, SERVICE_FATL_ERROR,
1048         "PhotoOutput EnableAutoCloudImageEnhancement error");
1049     CHECK_ERROR_RETURN_RET_LOG(isAutoCloudImageEnhancementSupported == false, INVALID_ARGUMENT,
1050         "PhotoOutput EnableAutoCloudImageEnhancement not supported");
1051     int32_t res = captureSession->EnableAutoCloudImageEnhancement(enabled);
1052     return res;
1053 }
1054 
IsDepthDataDeliverySupported()1055 bool PhotoOutput::IsDepthDataDeliverySupported()
1056 {
1057     CAMERA_SYNC_TRACE;
1058     MEDIA_INFO_LOG("Enter IsDepthDataDeliverySupported");
1059     return false;
1060 }
1061 
EnableDepthDataDelivery(bool enabled)1062 int32_t PhotoOutput::EnableDepthDataDelivery(bool enabled)
1063 {
1064     CAMERA_SYNC_TRACE;
1065     MEDIA_INFO_LOG("Enter EnableDepthDataDelivery, enabled:%{public}d", enabled);
1066     return CameraErrorCode::SUCCESS;
1067 }
1068 } // namespace CameraStandard
1069 } // namespace OHOS
1070