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 }