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 CHECK_RETURN(!photoNative_);
48 delete photoNative_;
49 photoNative_ = nullptr;
50 }
51
RegisterCallback(PhotoOutput_Callbacks * callback)52 Camera_ErrorCode Camera_PhotoOutput::RegisterCallback(PhotoOutput_Callbacks* callback)
53 {
54 if (innerCallback_ == nullptr) {
55 innerCallback_ = make_shared<InnerPhotoOutputCallback>(this);
56 CHECK_RETURN_RET_ELOG(innerCallback_ == nullptr, CAMERA_SERVICE_FATAL_ERROR,
57 "create innerCallback_ failed!");
58 innerCallback_->SaveCallback(callback);
59 innerPhotoOutput_->SetCallback(innerCallback_);
60 } else {
61 innerCallback_->SaveCallback(callback);
62 }
63 return CAMERA_OK;
64 }
65
RegisterPhotoAvailableCallback(OH_PhotoOutput_PhotoAvailable callback)66 Camera_ErrorCode Camera_PhotoOutput::RegisterPhotoAvailableCallback(OH_PhotoOutput_PhotoAvailable callback)
67 {
68 CHECK_RETURN_RET_ELOG(innerPhotoOutput_ == nullptr, CAMERA_SERVICE_FATAL_ERROR, "PhotoOutput is null!");
69 if (innerCallback_ == nullptr) {
70 innerCallback_ = make_shared<InnerPhotoOutputCallback>(this);
71 CHECK_RETURN_RET_ELOG(innerCallback_ == nullptr, CAMERA_SERVICE_FATAL_ERROR,
72 "create innerCallback_ failed!");
73 innerPhotoOutput_->SetCallback(innerCallback_);
74 }
75
76 innerPhotoOutput_->SetPhotoAvailableCallback(innerCallback_);
77 innerCallback_->SavePhotoAvailableCallback(callback);
78 callbackFlag_ |= CAPTURE_PHOTO;
79 innerPhotoOutput_->SetCallbackFlag(callbackFlag_);
80
81 // Preconfig can't support rawPhotoListener.
82 return CAMERA_OK;
83 }
84
RegisterPhotoAssetAvailableCallback(OH_PhotoOutput_PhotoAssetAvailable callback)85 Camera_ErrorCode Camera_PhotoOutput::RegisterPhotoAssetAvailableCallback(OH_PhotoOutput_PhotoAssetAvailable callback)
86 {
87 CHECK_RETURN_RET_ELOG(innerPhotoOutput_ == nullptr, CAMERA_SERVICE_FATAL_ERROR, "PhotoOutput is null!");
88 if (innerCallback_ == nullptr) {
89 innerCallback_ = make_shared<InnerPhotoOutputCallback>(this);
90 CHECK_RETURN_RET_ELOG(innerCallback_ == nullptr, CAMERA_SERVICE_FATAL_ERROR,
91 "create innerCallback_ failed!");
92 innerPhotoOutput_->SetCallback(innerCallback_);
93 }
94
95 innerPhotoOutput_->SetPhotoAssetAvailableCallback(innerCallback_);
96 innerCallback_->SavePhotoAssetAvailableCallback(callback);
97 callbackFlag_ |= CAPTURE_PHOTO_ASSET;
98 innerPhotoOutput_->SetCallbackFlag(callbackFlag_);
99 return CAMERA_OK;
100 }
101
UnregisterCallback(PhotoOutput_Callbacks * callback)102 Camera_ErrorCode Camera_PhotoOutput::UnregisterCallback(PhotoOutput_Callbacks* callback)
103 {
104 CHECK_RETURN_RET_ELOG(innerCallback_ == nullptr, CAMERA_OPERATION_NOT_ALLOWED,
105 "innerCallback_ is null! Please RegisterCallback first!");
106 innerCallback_->RemoveCallback(callback);
107 return CAMERA_OK;
108 }
109
RegisterCaptureStartWithInfoCallback(OH_PhotoOutput_CaptureStartWithInfo callback)110 Camera_ErrorCode Camera_PhotoOutput::RegisterCaptureStartWithInfoCallback(
111 OH_PhotoOutput_CaptureStartWithInfo callback)
112 {
113 if (innerCallback_ == nullptr) {
114 innerCallback_ = make_shared<InnerPhotoOutputCallback>(this);
115 CHECK_RETURN_RET_ELOG(innerCallback_ == nullptr, CAMERA_SERVICE_FATAL_ERROR,
116 "create innerCallback_ failed!");
117 innerCallback_->SaveCaptureStartWithInfoCallback(callback);
118 innerPhotoOutput_->SetCallback(innerCallback_);
119 } else {
120 innerCallback_->SaveCaptureStartWithInfoCallback(callback);
121 }
122 return CAMERA_OK;
123 }
124
UnregisterCaptureStartWithInfoCallback(OH_PhotoOutput_CaptureStartWithInfo callback)125 Camera_ErrorCode Camera_PhotoOutput::UnregisterCaptureStartWithInfoCallback(
126 OH_PhotoOutput_CaptureStartWithInfo callback)
127 {
128 CHECK_RETURN_RET_ELOG(innerCallback_ == nullptr, CAMERA_OPERATION_NOT_ALLOWED,
129 "innerCallback_ is null! Please RegisterCallback first!");
130 innerCallback_->RemoveCaptureStartWithInfoCallback(callback);
131 return CAMERA_OK;
132 }
133
RegisterCaptureEndCallback(OH_PhotoOutput_CaptureEnd callback)134 Camera_ErrorCode Camera_PhotoOutput::RegisterCaptureEndCallback(OH_PhotoOutput_CaptureEnd callback)
135 {
136 if (innerCallback_ == nullptr) {
137 innerCallback_ = make_shared<InnerPhotoOutputCallback>(this);
138 CHECK_RETURN_RET_ELOG(innerCallback_ == nullptr, CAMERA_SERVICE_FATAL_ERROR,
139 "create innerCallback_ failed!");
140 innerCallback_->SaveCaptureEndCallback(callback);
141 innerPhotoOutput_->SetCallback(innerCallback_);
142 } else {
143 innerCallback_->SaveCaptureEndCallback(callback);
144 }
145 return CAMERA_OK;
146 }
147
UnregisterCaptureEndCallback(OH_PhotoOutput_CaptureEnd callback)148 Camera_ErrorCode Camera_PhotoOutput::UnregisterCaptureEndCallback(OH_PhotoOutput_CaptureEnd callback)
149 {
150 CHECK_RETURN_RET_ELOG(innerCallback_ == nullptr, CAMERA_OPERATION_NOT_ALLOWED,
151 "innerCallback_ is null! Please RegisterCallback first!");
152 innerCallback_->RemoveCaptureEndCallback(callback);
153 return CAMERA_OK;
154 }
155
RegisterFrameShutterEndCallback(OH_PhotoOutput_OnFrameShutterEnd callback)156 Camera_ErrorCode Camera_PhotoOutput::RegisterFrameShutterEndCallback(OH_PhotoOutput_OnFrameShutterEnd callback)
157 {
158 if (innerCallback_ == nullptr) {
159 innerCallback_ = make_shared<InnerPhotoOutputCallback>(this);
160 CHECK_RETURN_RET_ELOG(innerCallback_ == nullptr, CAMERA_SERVICE_FATAL_ERROR,
161 "create innerCallback_ failed!");
162 innerCallback_->SaveFrameShutterEndCallback(callback);
163 innerPhotoOutput_->SetCallback(innerCallback_);
164 } else {
165 innerCallback_->SaveFrameShutterEndCallback(callback);
166 }
167 return CAMERA_OK;
168 }
169
UnregisterFrameShutterEndCallback(OH_PhotoOutput_OnFrameShutterEnd callback)170 Camera_ErrorCode Camera_PhotoOutput::UnregisterFrameShutterEndCallback(OH_PhotoOutput_OnFrameShutterEnd callback)
171 {
172 CHECK_RETURN_RET_ELOG(innerCallback_ == nullptr, CAMERA_OPERATION_NOT_ALLOWED,
173 "innerCallback_ is null! Please RegisterCallback first!");
174 innerCallback_->RemoveFrameShutterEndCallback(callback);
175 return CAMERA_OK;
176 }
177
RegisterCaptureReadyCallback(OH_PhotoOutput_CaptureReady callback)178 Camera_ErrorCode Camera_PhotoOutput::RegisterCaptureReadyCallback(OH_PhotoOutput_CaptureReady callback)
179 {
180 if (innerCallback_ == nullptr) {
181 innerCallback_ = make_shared<InnerPhotoOutputCallback>(this);
182 CHECK_RETURN_RET_ELOG(innerCallback_ == nullptr, CAMERA_SERVICE_FATAL_ERROR,
183 "create innerCallback_ failed!");
184 innerCallback_->SaveCaptureReadyCallback(callback);
185 innerPhotoOutput_->SetCallback(innerCallback_);
186 } else {
187 innerCallback_->SaveCaptureReadyCallback(callback);
188 }
189 return CAMERA_OK;
190 }
191
UnregisterCaptureReadyCallback(OH_PhotoOutput_CaptureReady callback)192 Camera_ErrorCode Camera_PhotoOutput::UnregisterCaptureReadyCallback(OH_PhotoOutput_CaptureReady callback)
193 {
194 CHECK_RETURN_RET_ELOG(innerCallback_ == nullptr, CAMERA_OPERATION_NOT_ALLOWED,
195 "innerCallback_ is null! Please RegisterCallback first!");
196 innerCallback_->RemoveCaptureReadyCallback(callback);
197 return CAMERA_OK;
198 }
199
RegisterEstimatedCaptureDurationCallback(OH_PhotoOutput_EstimatedCaptureDuration callback)200 Camera_ErrorCode Camera_PhotoOutput::RegisterEstimatedCaptureDurationCallback(
201 OH_PhotoOutput_EstimatedCaptureDuration callback)
202 {
203 if (innerCallback_ == nullptr) {
204 innerCallback_ = make_shared<InnerPhotoOutputCallback>(this);
205 CHECK_RETURN_RET_ELOG(innerCallback_ == nullptr, CAMERA_SERVICE_FATAL_ERROR,
206 "create innerCallback_ failed!");
207 innerCallback_->SaveEstimatedCaptureDurationCallback(callback);
208 innerPhotoOutput_->SetCallback(innerCallback_);
209 } else {
210 innerCallback_->SaveEstimatedCaptureDurationCallback(callback);
211 }
212 return CAMERA_OK;
213 }
214
UnregisterEstimatedCaptureDurationCallback(OH_PhotoOutput_EstimatedCaptureDuration callback)215 Camera_ErrorCode Camera_PhotoOutput::UnregisterEstimatedCaptureDurationCallback(
216 OH_PhotoOutput_EstimatedCaptureDuration callback)
217 {
218 CHECK_RETURN_RET_ELOG(innerCallback_ == nullptr, CAMERA_OPERATION_NOT_ALLOWED,
219 "innerCallback_ is null! Please RegisterCallback first!");
220 innerCallback_->RemoveEstimatedCaptureDurationCallback(callback);
221 return CAMERA_OK;
222 }
223
UnregisterPhotoAvailableCallback(OH_PhotoOutput_PhotoAvailable callback)224 Camera_ErrorCode Camera_PhotoOutput::UnregisterPhotoAvailableCallback(OH_PhotoOutput_PhotoAvailable callback)
225 {
226 CHECK_RETURN_RET_ELOG(innerPhotoOutput_ == nullptr, CAMERA_OPERATION_NOT_ALLOWED, "PhotoOutput is null!");
227 CHECK_RETURN_RET_ELOG(innerCallback_ == nullptr, CAMERA_OPERATION_NOT_ALLOWED, "callback is null!");
228 innerPhotoOutput_->UnSetPhotoAvailableCallback();
229 callbackFlag_ &= ~CAPTURE_PHOTO;
230 innerPhotoOutput_->SetCallbackFlag(callbackFlag_);
231 innerCallback_->RemovePhotoAvailableCallback(callback);
232 return CAMERA_OK;
233 }
234
UnregisterPhotoAssetAvailableCallback(OH_PhotoOutput_PhotoAssetAvailable callback)235 Camera_ErrorCode Camera_PhotoOutput::UnregisterPhotoAssetAvailableCallback(OH_PhotoOutput_PhotoAssetAvailable callback)
236 {
237 CHECK_RETURN_RET_ELOG(innerPhotoOutput_ == nullptr, CAMERA_OPERATION_NOT_ALLOWED, "PhotoOutput is null!");
238 CHECK_RETURN_RET_ELOG(innerCallback_ == nullptr, CAMERA_OPERATION_NOT_ALLOWED, "callback is null!");
239 innerPhotoOutput_->UnSetPhotoAssetAvailableCallback();
240 callbackFlag_ &= ~CAPTURE_PHOTO_ASSET;
241 innerPhotoOutput_->SetCallbackFlag(callbackFlag_);
242 innerCallback_->RemovePhotoAssetAvailableCallback(callback);
243 return CAMERA_OK;
244 }
245
Capture()246 Camera_ErrorCode Camera_PhotoOutput::Capture()
247 {
248 std::shared_ptr<PhotoCaptureSetting> capSettings = make_shared<PhotoCaptureSetting>();
249 capSettings->SetMirror(isMirrorEnable_);
250 int32_t ret = innerPhotoOutput_->Capture(capSettings);
251 return FrameworkToNdkCameraError(ret);
252 }
253
Capture_WithCaptureSetting(Camera_PhotoCaptureSetting setting)254 Camera_ErrorCode Camera_PhotoOutput::Capture_WithCaptureSetting(Camera_PhotoCaptureSetting setting)
255 {
256 std::shared_ptr<PhotoCaptureSetting> capSettings = make_shared<PhotoCaptureSetting>();
257
258 capSettings->SetQuality(static_cast<PhotoCaptureSetting::QualityLevel>(setting.quality));
259
260 capSettings->SetRotation(static_cast<PhotoCaptureSetting::RotationConfig>(setting.rotation));
261
262 if (setting.location != nullptr) {
263 std::shared_ptr<Location> location = std::make_shared<Location>();
264 location->latitude = setting.location->latitude;
265 location->longitude = setting.location->longitude;
266 location->altitude = setting.location->altitude;
267 capSettings->SetLocation(location);
268 }
269
270 capSettings->SetMirror(setting.mirror);
271
272 int32_t ret = innerPhotoOutput_->Capture(capSettings);
273 return FrameworkToNdkCameraError(ret);
274 }
275
Release()276 Camera_ErrorCode Camera_PhotoOutput::Release()
277 {
278 int32_t ret = innerPhotoOutput_->Release();
279 return FrameworkToNdkCameraError(ret);
280 }
281
IsMirrorSupported(bool * isSupported)282 Camera_ErrorCode Camera_PhotoOutput::IsMirrorSupported(bool* isSupported)
283 {
284 *isSupported = innerPhotoOutput_->IsMirrorSupported();
285
286 return CAMERA_OK;
287 }
288
EnableMirror(bool enableMirror)289 Camera_ErrorCode Camera_PhotoOutput::EnableMirror(bool enableMirror)
290 {
291 int32_t ret = innerPhotoOutput_->EnableMirror(enableMirror);
292 isMirrorEnable_ = (ret == napi_ok) ? enableMirror : isMirrorEnable_;
293
294 return FrameworkToNdkCameraError(ret);
295 }
296
GetInnerPhotoOutput()297 sptr<PhotoOutput> Camera_PhotoOutput::GetInnerPhotoOutput()
298 {
299 return innerPhotoOutput_;
300 }
301
CreateCameraPhotoNative(shared_ptr<Media::NativeImage> & image,bool isMain)302 OH_PhotoNative* Camera_PhotoOutput::CreateCameraPhotoNative(shared_ptr<Media::NativeImage> &image, bool isMain)
303 {
304 photoNative_ = (photoNative_ == nullptr) ? new(std::nothrow) OH_PhotoNative : photoNative_;
305 CHECK_RETURN_RET_ELOG(photoNative_ == nullptr, nullptr, "Create camera photo native object failed");
306
307 if (isMain) {
308 photoNative_->SetMainImage(image);
309 } else {
310 photoNative_->SetRawImage(image);
311 }
312 return photoNative_;
313 }
314
GetActiveProfile(Camera_Profile ** profile)315 Camera_ErrorCode Camera_PhotoOutput::GetActiveProfile(Camera_Profile** profile)
316 {
317 auto photoOutputProfile = innerPhotoOutput_->GetPhotoProfile();
318 CHECK_RETURN_RET_ELOG(photoOutputProfile == nullptr, CAMERA_SERVICE_FATAL_ERROR,
319 "Camera_PhotoOutput::GetActiveProfile failed to get photo profile!");
320
321 CameraFormat cameraFormat = photoOutputProfile->GetCameraFormat();
322 auto itr = g_fwToNdkCameraFormat.find(cameraFormat);
323 CHECK_RETURN_RET_ELOG(itr == g_fwToNdkCameraFormat.end(), CAMERA_SERVICE_FATAL_ERROR,
324 "Camera_PhotoOutput::GetActiveProfile unsupported camera format %{public}d", cameraFormat);
325
326 Camera_Profile* newProfile = new Camera_Profile;
327 CHECK_RETURN_RET_ELOG(newProfile == nullptr, CAMERA_SERVICE_FATAL_ERROR,
328 "Camera_PhotoOutput::GetActiveProfile failed to allocate memory for camera profile!");
329
330 newProfile->format = itr->second;
331 newProfile->size.width = photoOutputProfile->GetSize().width;
332 newProfile->size.height = photoOutputProfile->GetSize().height;
333
334 *profile = newProfile;
335 return CAMERA_OK;
336 }
337
IsMovingPhotoSupported(bool * isSupported)338 Camera_ErrorCode Camera_PhotoOutput::IsMovingPhotoSupported(bool* isSupported)
339 {
340 MEDIA_DEBUG_LOG("Camera_PhotoOutput IsMovingPhotoSupported is called");
341 auto session = innerPhotoOutput_->GetSession();
342 CHECK_RETURN_RET_ELOG(session == nullptr, CAMERA_SERVICE_FATAL_ERROR, "GetSession failed");
343
344 *isSupported = session->IsMovingPhotoSupported();
345 return CAMERA_OK;
346 }
347
EnableMovingPhoto(bool enableMovingPhoto)348 Camera_ErrorCode Camera_PhotoOutput::EnableMovingPhoto(bool enableMovingPhoto)
349 {
350 MEDIA_DEBUG_LOG("Camera_PhotoOutput EnableMovingPhoto is called");
351 auto session = innerPhotoOutput_->GetSession();
352 CHECK_RETURN_RET_ELOG(session == nullptr, CAMERA_SERVICE_FATAL_ERROR, "GetSession failed");
353
354 session->LockForControl();
355 int32_t ret = session->EnableMovingPhoto(enableMovingPhoto);
356 session->UnlockForControl();
357
358 return FrameworkToNdkCameraError(ret);
359 }
360
GetPhotoRotation(int32_t imageRotation,Camera_ImageRotation * cameraImageRotation)361 Camera_ErrorCode Camera_PhotoOutput::GetPhotoRotation(int32_t imageRotation, Camera_ImageRotation* cameraImageRotation)
362 {
363 CHECK_RETURN_RET_ELOG(cameraImageRotation == nullptr, CAMERA_SERVICE_FATAL_ERROR,
364 "GetCameraImageRotation failed");
365 int32_t cameraOutputRotation = innerPhotoOutput_->GetPhotoRotation(imageRotation);
366 CHECK_RETURN_RET_ELOG(cameraOutputRotation == CAMERA_SERVICE_FATAL_ERROR, CAMERA_SERVICE_FATAL_ERROR,
367 "Camera_PhotoOutput::GetPhotoRotation failed to get photo profile! ret: %{public}d", cameraOutputRotation);
368 *cameraImageRotation = static_cast<Camera_ImageRotation>(cameraOutputRotation);
369 return CAMERA_OK;
370 }