1 /*
2  * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "photo_output_impl.h"
17 
18 #include "camera_log.h"
19 #include "camera_util.h"
20 #include "inner_api/native/camera/include/session/capture_session.h"
21 
22 using namespace std;
23 using namespace OHOS;
24 using namespace OHOS::CameraStandard;
25 const std::unordered_map<CameraFormat, Camera_Format> g_fwToNdkCameraFormat = {
26     {CameraFormat::CAMERA_FORMAT_RGBA_8888, Camera_Format::CAMERA_FORMAT_RGBA_8888},
27     {CameraFormat::CAMERA_FORMAT_YUV_420_SP, Camera_Format::CAMERA_FORMAT_YUV_420_SP},
28     {CameraFormat::CAMERA_FORMAT_JPEG, Camera_Format::CAMERA_FORMAT_JPEG},
29     {CameraFormat::CAMERA_FORMAT_YCBCR_P010, Camera_Format::CAMERA_FORMAT_YCBCR_P010},
30     {CameraFormat::CAMERA_FORMAT_YCRCB_P010, Camera_Format::CAMERA_FORMAT_YCRCB_P010}
31 };
32 
Camera_PhotoOutput(sptr<PhotoOutput> & innerPhotoOutput)33 Camera_PhotoOutput::Camera_PhotoOutput(sptr<PhotoOutput> &innerPhotoOutput) : innerPhotoOutput_(innerPhotoOutput)
34 {
35     MEDIA_DEBUG_LOG("Camera_PhotoOutput Constructor is called");
36 }
37 
~Camera_PhotoOutput()38 Camera_PhotoOutput::~Camera_PhotoOutput()
39 {
40     MEDIA_DEBUG_LOG("~Camera_PhotoOutput is called");
41     if (innerPhotoOutput_) {
42         innerPhotoOutput_ = nullptr;
43     }
44     if (innerCallback_) {
45         innerCallback_ = nullptr;
46     }
47     if (photoSurface_) {
48         photoSurface_ = nullptr;
49     }
50     if (photoListener_) {
51         photoListener_ = nullptr;
52     }
53     if (rawPhotoListener_) {
54         rawPhotoListener_ = nullptr;
55     }
56     if (photoNative_) {
57         delete photoNative_;
58         photoNative_ = nullptr;
59     }
60 }
61 
RegisterCallback(PhotoOutput_Callbacks * callback)62 Camera_ErrorCode Camera_PhotoOutput::RegisterCallback(PhotoOutput_Callbacks* callback)
63 {
64     if (innerCallback_ == nullptr) {
65         innerCallback_ = make_shared<InnerPhotoOutputCallback>(this);
66         CHECK_AND_RETURN_RET_LOG(innerCallback_ != nullptr, CAMERA_SERVICE_FATAL_ERROR,
67             "create innerCallback_ failed!");
68         innerCallback_->SaveCallback(callback);
69         innerPhotoOutput_->SetCallback(innerCallback_);
70     } else {
71         innerCallback_->SaveCallback(callback);
72     }
73     return CAMERA_OK;
74 }
75 
RegisterPhotoAvailableCallback(OH_PhotoOutput_PhotoAvailable callback)76 Camera_ErrorCode Camera_PhotoOutput::RegisterPhotoAvailableCallback(OH_PhotoOutput_PhotoAvailable callback)
77 {
78     CHECK_AND_RETURN_RET_LOG(photoSurface_ != nullptr, CAMERA_OPERATION_NOT_ALLOWED,
79         "Photo surface is nullptr");
80 
81     if (photoListener_ == nullptr) {
82         photoListener_ = new (std::nothrow) PhotoListener(this, photoSurface_);
83         CHECK_AND_RETURN_RET_LOG(photoListener_ != nullptr, CAMERA_SERVICE_FATAL_ERROR,
84             "Create photo listener failed");
85 
86         SurfaceError ret = photoSurface_->RegisterConsumerListener((sptr<IBufferConsumerListener>&)photoListener_);
87         CHECK_AND_RETURN_RET_LOG(ret == SURFACE_ERROR_OK, CAMERA_SERVICE_FATAL_ERROR,
88             "Register surface consumer listener failed");
89     }
90 
91     photoListener_->SetPhotoAvailableCallback(callback);
92     callbackFlag_ |= CAPTURE_PHOTO;
93     photoListener_->SetCallbackFlag(callbackFlag_);
94     innerPhotoOutput_->SetCallbackFlag(callbackFlag_);
95 
96     // Preconfig can't support rawPhotoListener.
97     return RegisterRawPhotoAvailableCallback(callback);
98 }
99 
RegisterRawPhotoAvailableCallback(OH_PhotoOutput_PhotoAvailable callback)100 Camera_ErrorCode Camera_PhotoOutput::RegisterRawPhotoAvailableCallback(OH_PhotoOutput_PhotoAvailable callback)
101 {
102     std::shared_ptr<Profile> profile = innerPhotoOutput_->GetPhotoProfile();
103     if (rawPhotoListener_ == nullptr && profile != nullptr &&
104         innerPhotoOutput_->isRawImageDelivery_ &&
105         innerPhotoOutput_->rawPhotoSurface_ != nullptr) {
106         rawPhotoListener_ =
107             new (std::nothrow) RawPhotoListener(this, innerPhotoOutput_->rawPhotoSurface_);
108         CHECK_AND_RETURN_RET_LOG(rawPhotoListener_ != nullptr, CAMERA_SERVICE_FATAL_ERROR,
109             "Create raw photo listener failed");
110 
111         SurfaceError ret = innerPhotoOutput_->rawPhotoSurface_->RegisterConsumerListener(
112             (sptr<IBufferConsumerListener>&)rawPhotoListener_);
113         CHECK_AND_RETURN_RET_LOG(ret == SURFACE_ERROR_OK, CAMERA_SERVICE_FATAL_ERROR,
114             "Register surface consumer listener failed");
115         rawPhotoListener_->SetCallback(callback);
116     }
117     return CAMERA_OK;
118 }
119 
RegisterPhotoAssetAvailableCallback(OH_PhotoOutput_PhotoAssetAvailable callback)120 Camera_ErrorCode Camera_PhotoOutput::RegisterPhotoAssetAvailableCallback(OH_PhotoOutput_PhotoAssetAvailable callback)
121 {
122     CHECK_AND_RETURN_RET_LOG(photoSurface_ != nullptr, CAMERA_INVALID_ARGUMENT,
123         "Photo surface is invalid");
124     if (photoListener_ == nullptr) {
125         photoListener_ = new (std::nothrow) PhotoListener(this, photoSurface_);
126         CHECK_AND_RETURN_RET_LOG(photoListener_ != nullptr, CAMERA_SERVICE_FATAL_ERROR,
127             "Create raw photo listener failed");
128 
129         SurfaceError ret = photoSurface_->RegisterConsumerListener((sptr<IBufferConsumerListener>&)photoListener_);
130         CHECK_AND_RETURN_RET_LOG(ret == SURFACE_ERROR_OK, CAMERA_SERVICE_FATAL_ERROR,
131             "Register surface consumer listener failed");
132     }
133     photoListener_->SetPhotoAssetAvailableCallback(callback);
134     callbackFlag_ |= CAPTURE_PHOTO_ASSET;
135     photoListener_->SetCallbackFlag(callbackFlag_);
136     innerPhotoOutput_->SetCallbackFlag(callbackFlag_);
137     return CAMERA_OK;
138 }
139 
UnregisterCallback(PhotoOutput_Callbacks * callback)140 Camera_ErrorCode Camera_PhotoOutput::UnregisterCallback(PhotoOutput_Callbacks* callback)
141 {
142     CHECK_AND_RETURN_RET_LOG(innerCallback_ != nullptr, CAMERA_OPERATION_NOT_ALLOWED,
143         "innerCallback_ is null! Please RegisterCallback first!");
144     innerCallback_->RemoveCallback(callback);
145     return CAMERA_OK;
146 }
147 
RegisterCaptureStartWithInfoCallback(OH_PhotoOutput_CaptureStartWithInfo callback)148 Camera_ErrorCode Camera_PhotoOutput::RegisterCaptureStartWithInfoCallback(
149     OH_PhotoOutput_CaptureStartWithInfo callback)
150 {
151     if (innerCallback_ == nullptr) {
152         innerCallback_ = make_shared<InnerPhotoOutputCallback>(this);
153         CHECK_AND_RETURN_RET_LOG(innerCallback_ != nullptr, CAMERA_SERVICE_FATAL_ERROR,
154             "create innerCallback_ failed!");
155         innerCallback_->SaveCaptureStartWithInfoCallback(callback);
156         innerPhotoOutput_->SetCallback(innerCallback_);
157     } else {
158         innerCallback_->SaveCaptureStartWithInfoCallback(callback);
159     }
160     return CAMERA_OK;
161 }
162 
UnregisterCaptureStartWithInfoCallback(OH_PhotoOutput_CaptureStartWithInfo callback)163 Camera_ErrorCode Camera_PhotoOutput::UnregisterCaptureStartWithInfoCallback(
164     OH_PhotoOutput_CaptureStartWithInfo callback)
165 {
166     CHECK_AND_RETURN_RET_LOG(innerCallback_ != nullptr, CAMERA_OPERATION_NOT_ALLOWED,
167         "innerCallback_ is null! Please RegisterCallback first!");
168     innerCallback_->RemoveCaptureStartWithInfoCallback(callback);
169     return CAMERA_OK;
170 }
171 
RegisterCaptureEndCallback(OH_PhotoOutput_CaptureEnd callback)172 Camera_ErrorCode Camera_PhotoOutput::RegisterCaptureEndCallback(OH_PhotoOutput_CaptureEnd callback)
173 {
174     if (innerCallback_ == nullptr) {
175         innerCallback_ = make_shared<InnerPhotoOutputCallback>(this);
176         CHECK_AND_RETURN_RET_LOG(innerCallback_ != nullptr, CAMERA_SERVICE_FATAL_ERROR,
177             "create innerCallback_ failed!");
178         innerCallback_->SaveCaptureEndCallback(callback);
179         innerPhotoOutput_->SetCallback(innerCallback_);
180     } else {
181         innerCallback_->SaveCaptureEndCallback(callback);
182     }
183     return CAMERA_OK;
184 }
185 
UnregisterCaptureEndCallback(OH_PhotoOutput_CaptureEnd callback)186 Camera_ErrorCode Camera_PhotoOutput::UnregisterCaptureEndCallback(OH_PhotoOutput_CaptureEnd callback)
187 {
188     CHECK_AND_RETURN_RET_LOG(innerCallback_ != nullptr, CAMERA_OPERATION_NOT_ALLOWED,
189         "innerCallback_ is null! Please RegisterCallback first!");
190     innerCallback_->RemoveCaptureEndCallback(callback);
191     return CAMERA_OK;
192 }
193 
RegisterFrameShutterEndCallback(OH_PhotoOutput_OnFrameShutterEnd callback)194 Camera_ErrorCode Camera_PhotoOutput::RegisterFrameShutterEndCallback(OH_PhotoOutput_OnFrameShutterEnd callback)
195 {
196     if (innerCallback_ == nullptr) {
197         innerCallback_ = make_shared<InnerPhotoOutputCallback>(this);
198         CHECK_AND_RETURN_RET_LOG(innerCallback_ != nullptr, CAMERA_SERVICE_FATAL_ERROR,
199             "create innerCallback_ failed!");
200         innerCallback_->SaveFrameShutterEndCallback(callback);
201         innerPhotoOutput_->SetCallback(innerCallback_);
202     } else {
203         innerCallback_->SaveFrameShutterEndCallback(callback);
204     }
205     return CAMERA_OK;
206 }
207 
UnregisterFrameShutterEndCallback(OH_PhotoOutput_OnFrameShutterEnd callback)208 Camera_ErrorCode Camera_PhotoOutput::UnregisterFrameShutterEndCallback(OH_PhotoOutput_OnFrameShutterEnd callback)
209 {
210     CHECK_AND_RETURN_RET_LOG(innerCallback_ != nullptr, CAMERA_OPERATION_NOT_ALLOWED,
211         "innerCallback_ is null! Please RegisterCallback first!");
212     innerCallback_->RemoveFrameShutterEndCallback(callback);
213     return CAMERA_OK;
214 }
215 
RegisterCaptureReadyCallback(OH_PhotoOutput_CaptureReady callback)216 Camera_ErrorCode Camera_PhotoOutput::RegisterCaptureReadyCallback(OH_PhotoOutput_CaptureReady callback)
217 {
218     if (innerCallback_ == nullptr) {
219         innerCallback_ = make_shared<InnerPhotoOutputCallback>(this);
220         CHECK_AND_RETURN_RET_LOG(innerCallback_ != nullptr, CAMERA_SERVICE_FATAL_ERROR,
221             "create innerCallback_ failed!");
222         innerCallback_->SaveCaptureReadyCallback(callback);
223         innerPhotoOutput_->SetCallback(innerCallback_);
224     } else {
225         innerCallback_->SaveCaptureReadyCallback(callback);
226     }
227     return CAMERA_OK;
228 }
229 
UnregisterCaptureReadyCallback(OH_PhotoOutput_CaptureReady callback)230 Camera_ErrorCode Camera_PhotoOutput::UnregisterCaptureReadyCallback(OH_PhotoOutput_CaptureReady callback)
231 {
232     CHECK_AND_RETURN_RET_LOG(innerCallback_ != nullptr, CAMERA_OPERATION_NOT_ALLOWED,
233         "innerCallback_ is null! Please RegisterCallback first!");
234     innerCallback_->RemoveCaptureReadyCallback(callback);
235     return CAMERA_OK;
236 }
237 
RegisterEstimatedCaptureDurationCallback(OH_PhotoOutput_EstimatedCaptureDuration callback)238 Camera_ErrorCode Camera_PhotoOutput::RegisterEstimatedCaptureDurationCallback(
239     OH_PhotoOutput_EstimatedCaptureDuration callback)
240 {
241     if (innerCallback_ == nullptr) {
242         innerCallback_ = make_shared<InnerPhotoOutputCallback>(this);
243         CHECK_AND_RETURN_RET_LOG(innerCallback_ != nullptr, CAMERA_SERVICE_FATAL_ERROR,
244             "create innerCallback_ failed!");
245         innerCallback_->SaveEstimatedCaptureDurationCallback(callback);
246         innerPhotoOutput_->SetCallback(innerCallback_);
247     } else {
248         innerCallback_->SaveEstimatedCaptureDurationCallback(callback);
249     }
250     return CAMERA_OK;
251 }
252 
UnregisterEstimatedCaptureDurationCallback(OH_PhotoOutput_EstimatedCaptureDuration callback)253 Camera_ErrorCode Camera_PhotoOutput::UnregisterEstimatedCaptureDurationCallback(
254     OH_PhotoOutput_EstimatedCaptureDuration callback)
255 {
256     CHECK_AND_RETURN_RET_LOG(innerCallback_ != nullptr, CAMERA_OPERATION_NOT_ALLOWED,
257         "innerCallback_ is null! Please RegisterCallback first!");
258     innerCallback_->RemoveEstimatedCaptureDurationCallback(callback);
259     return CAMERA_OK;
260 }
261 
UnregisterPhotoAvailableCallback(OH_PhotoOutput_PhotoAvailable callback)262 Camera_ErrorCode Camera_PhotoOutput::UnregisterPhotoAvailableCallback(OH_PhotoOutput_PhotoAvailable callback)
263 {
264     if (callback != nullptr) {
265         if (photoListener_ != nullptr) {
266             callbackFlag_ &= ~CAPTURE_PHOTO;
267             photoListener_->SetCallbackFlag(callbackFlag_);
268             photoListener_->UnregisterPhotoAvailableCallback(callback);
269         }
270         if (rawPhotoListener_ != nullptr) {
271             rawPhotoListener_->UnregisterCallback(callback);
272         }
273     }
274     return CAMERA_OK;
275 }
276 
UnregisterPhotoAssetAvailableCallback(OH_PhotoOutput_PhotoAssetAvailable callback)277 Camera_ErrorCode Camera_PhotoOutput::UnregisterPhotoAssetAvailableCallback(OH_PhotoOutput_PhotoAssetAvailable callback)
278 {
279     if (callback != nullptr) {
280         if (photoListener_ != nullptr) {
281             callbackFlag_ &= ~CAPTURE_PHOTO_ASSET;
282             photoListener_->SetCallbackFlag(callbackFlag_);
283             photoListener_->UnregisterPhotoAssetAvailableCallback(callback);
284         }
285     }
286     return CAMERA_OK;
287 }
288 
SetPhotoSurface(OHOS::sptr<OHOS::Surface> & photoSurface)289 void Camera_PhotoOutput::SetPhotoSurface(OHOS::sptr<OHOS::Surface> &photoSurface)
290 {
291     photoSurface_ = photoSurface;
292 }
293 
Capture()294 Camera_ErrorCode Camera_PhotoOutput::Capture()
295 {
296     std::shared_ptr<PhotoCaptureSetting> capSettings = make_shared<PhotoCaptureSetting>();
297     capSettings->SetMirror(isMirrorEnable_);
298     int32_t ret = innerPhotoOutput_->Capture(capSettings);
299     return FrameworkToNdkCameraError(ret);
300 }
301 
Capture_WithCaptureSetting(Camera_PhotoCaptureSetting setting)302 Camera_ErrorCode Camera_PhotoOutput::Capture_WithCaptureSetting(Camera_PhotoCaptureSetting setting)
303 {
304     std::shared_ptr<PhotoCaptureSetting> capSettings = make_shared<PhotoCaptureSetting>();
305 
306     capSettings->SetQuality(static_cast<PhotoCaptureSetting::QualityLevel>(setting.quality));
307 
308     capSettings->SetRotation(static_cast<PhotoCaptureSetting::RotationConfig>(setting.rotation));
309 
310     if (setting.location != nullptr) {
311         std::shared_ptr<Location> location = std::make_shared<Location>();
312         location->latitude = setting.location->latitude;
313         location->longitude = setting.location->longitude;
314         location->altitude = setting.location->altitude;
315         capSettings->SetLocation(location);
316     }
317 
318     capSettings->SetMirror(setting.mirror);
319 
320     int32_t ret = innerPhotoOutput_->Capture(capSettings);
321     return FrameworkToNdkCameraError(ret);
322 }
323 
Release()324 Camera_ErrorCode Camera_PhotoOutput::Release()
325 {
326     int32_t ret = innerPhotoOutput_->Release();
327     return FrameworkToNdkCameraError(ret);
328 }
329 
IsMirrorSupported(bool * isSupported)330 Camera_ErrorCode Camera_PhotoOutput::IsMirrorSupported(bool* isSupported)
331 {
332     *isSupported = innerPhotoOutput_->IsMirrorSupported();
333 
334     return CAMERA_OK;
335 }
336 
EnableMirror(bool enableMirror)337 Camera_ErrorCode Camera_PhotoOutput::EnableMirror(bool enableMirror)
338 {
339     int32_t ret = innerPhotoOutput_->EnableMirror(enableMirror);
340     if (ret == napi_ok) {
341         isMirrorEnable_ = enableMirror;
342     }
343 
344     return FrameworkToNdkCameraError(ret);
345 }
346 
GetInnerPhotoOutput()347 sptr<PhotoOutput> Camera_PhotoOutput::GetInnerPhotoOutput()
348 {
349     return innerPhotoOutput_;
350 }
351 
CreateCameraPhotoNative(shared_ptr<Media::NativeImage> & image,bool isMain)352 OH_PhotoNative* Camera_PhotoOutput::CreateCameraPhotoNative(shared_ptr<Media::NativeImage> &image, bool isMain)
353 {
354     if (!photoNative_) {
355         photoNative_ = new(std::nothrow) OH_PhotoNative;
356         CHECK_AND_RETURN_RET_LOG(photoNative_ != nullptr, nullptr, "Create camera photo native object failed");
357     }
358 
359     if (isMain) {
360         photoNative_->SetMainImage(image);
361     } else {
362         photoNative_->SetRawImage(image);
363     }
364     return photoNative_;
365 }
366 
GetActiveProfile(Camera_Profile ** profile)367 Camera_ErrorCode Camera_PhotoOutput::GetActiveProfile(Camera_Profile** profile)
368 {
369     auto photoOutputProfile = innerPhotoOutput_->GetPhotoProfile();
370     CHECK_AND_RETURN_RET_LOG(photoOutputProfile != nullptr, CAMERA_SERVICE_FATAL_ERROR,
371         "Camera_PhotoOutput::GetActiveProfile failed to get photo profile!");
372 
373     CameraFormat cameraFormat = photoOutputProfile->GetCameraFormat();
374     auto itr = g_fwToNdkCameraFormat.find(cameraFormat);
375     CHECK_AND_RETURN_RET_LOG(itr != g_fwToNdkCameraFormat.end(), CAMERA_SERVICE_FATAL_ERROR,
376         "Camera_PhotoOutput::GetActiveProfile unsupported camera format %{public}d", cameraFormat);
377 
378     Camera_Profile* newProfile = new Camera_Profile;
379     CHECK_AND_RETURN_RET_LOG(newProfile != nullptr, CAMERA_SERVICE_FATAL_ERROR,
380         "Camera_PhotoOutput::GetActiveProfile failed to allocate memory for camera profile!");
381 
382     newProfile->format = itr->second;
383     newProfile->size.width = photoOutputProfile->GetSize().width;
384     newProfile->size.height = photoOutputProfile->GetSize().height;
385 
386     *profile = newProfile;
387     return CAMERA_OK;
388 }
IsMovingPhotoSupported(bool * isSupported)389 Camera_ErrorCode Camera_PhotoOutput::IsMovingPhotoSupported(bool* isSupported)
390 {
391     MEDIA_DEBUG_LOG("Camera_PhotoOutput IsMovingPhotoSupported is called");
392     auto session = innerPhotoOutput_->GetSession();
393     CHECK_AND_RETURN_RET_LOG(session != nullptr, CAMERA_SERVICE_FATAL_ERROR, "GetSession failed");
394 
395     *isSupported = session->IsMovingPhotoSupported();
396     return CAMERA_OK;
397 }
398 
EnableMovingPhoto(bool enableMovingPhoto)399 Camera_ErrorCode Camera_PhotoOutput::EnableMovingPhoto(bool enableMovingPhoto)
400 {
401     MEDIA_DEBUG_LOG("Camera_PhotoOutput EnableMovingPhoto is called");
402     auto session = innerPhotoOutput_->GetSession();
403     CHECK_AND_RETURN_RET_LOG(session != nullptr, CAMERA_SERVICE_FATAL_ERROR, "GetSession failed");
404 
405     session->LockForControl();
406     int32_t ret = session->EnableMovingPhoto(enableMovingPhoto);
407     session->UnlockForControl();
408 
409     return FrameworkToNdkCameraError(ret);
410 }
411 
GetPhotoRotation(int32_t imageRotation,Camera_ImageRotation * cameraImageRotation)412 Camera_ErrorCode Camera_PhotoOutput::GetPhotoRotation(int32_t imageRotation, Camera_ImageRotation* cameraImageRotation)
413 {
414     CHECK_AND_RETURN_RET_LOG(cameraImageRotation != nullptr, CAMERA_SERVICE_FATAL_ERROR,
415         "GetCameraImageRotation failed");
416     int32_t cameraOutputRotation = innerPhotoOutput_->GetPhotoRotation(imageRotation);
417     CHECK_AND_RETURN_RET_LOG(cameraOutputRotation != CAMERA_SERVICE_FATAL_ERROR, CAMERA_SERVICE_FATAL_ERROR,
418         "Camera_PhotoOutput::GetPhotoRotation failed to get photo profile! ret: %{public}d", cameraOutputRotation);
419     *cameraImageRotation = static_cast<Camera_ImageRotation>(cameraOutputRotation);
420     return CAMERA_OK;
421 }