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_ERROR_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_ERROR_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_ERROR_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_ERROR_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_ERROR_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_ERROR_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_ERROR_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_ERROR_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_ERROR_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_ERROR_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_ERROR_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_ERROR_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_ERROR_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_ERROR_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_ERROR_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_ERROR_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_ERROR_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_ERROR_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_ERROR_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_ERROR_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 CHECK_EXECUTE(rawPhotoListener_ != nullptr, rawPhotoListener_->UnregisterCallback(callback));
271 }
272 return CAMERA_OK;
273 }
274
UnregisterPhotoAssetAvailableCallback(OH_PhotoOutput_PhotoAssetAvailable callback)275 Camera_ErrorCode Camera_PhotoOutput::UnregisterPhotoAssetAvailableCallback(OH_PhotoOutput_PhotoAssetAvailable callback)
276 {
277 if (callback != nullptr) {
278 if (photoListener_ != nullptr) {
279 callbackFlag_ &= ~CAPTURE_PHOTO_ASSET;
280 photoListener_->SetCallbackFlag(callbackFlag_);
281 photoListener_->UnregisterPhotoAssetAvailableCallback(callback);
282 }
283 }
284 return CAMERA_OK;
285 }
286
SetPhotoSurface(OHOS::sptr<OHOS::Surface> & photoSurface)287 void Camera_PhotoOutput::SetPhotoSurface(OHOS::sptr<OHOS::Surface> &photoSurface)
288 {
289 photoSurface_ = photoSurface;
290 }
291
Capture()292 Camera_ErrorCode Camera_PhotoOutput::Capture()
293 {
294 std::shared_ptr<PhotoCaptureSetting> capSettings = make_shared<PhotoCaptureSetting>();
295 capSettings->SetMirror(isMirrorEnable_);
296 int32_t ret = innerPhotoOutput_->Capture(capSettings);
297 return FrameworkToNdkCameraError(ret);
298 }
299
Capture_WithCaptureSetting(Camera_PhotoCaptureSetting setting)300 Camera_ErrorCode Camera_PhotoOutput::Capture_WithCaptureSetting(Camera_PhotoCaptureSetting setting)
301 {
302 std::shared_ptr<PhotoCaptureSetting> capSettings = make_shared<PhotoCaptureSetting>();
303
304 capSettings->SetQuality(static_cast<PhotoCaptureSetting::QualityLevel>(setting.quality));
305
306 capSettings->SetRotation(static_cast<PhotoCaptureSetting::RotationConfig>(setting.rotation));
307
308 if (setting.location != nullptr) {
309 std::shared_ptr<Location> location = std::make_shared<Location>();
310 location->latitude = setting.location->latitude;
311 location->longitude = setting.location->longitude;
312 location->altitude = setting.location->altitude;
313 capSettings->SetLocation(location);
314 }
315
316 capSettings->SetMirror(setting.mirror);
317
318 int32_t ret = innerPhotoOutput_->Capture(capSettings);
319 return FrameworkToNdkCameraError(ret);
320 }
321
Release()322 Camera_ErrorCode Camera_PhotoOutput::Release()
323 {
324 int32_t ret = innerPhotoOutput_->Release();
325 return FrameworkToNdkCameraError(ret);
326 }
327
IsMirrorSupported(bool * isSupported)328 Camera_ErrorCode Camera_PhotoOutput::IsMirrorSupported(bool* isSupported)
329 {
330 *isSupported = innerPhotoOutput_->IsMirrorSupported();
331
332 return CAMERA_OK;
333 }
334
EnableMirror(bool enableMirror)335 Camera_ErrorCode Camera_PhotoOutput::EnableMirror(bool enableMirror)
336 {
337 int32_t ret = innerPhotoOutput_->EnableMirror(enableMirror);
338 if (ret == napi_ok) {
339 isMirrorEnable_ = enableMirror;
340 }
341
342 return FrameworkToNdkCameraError(ret);
343 }
344
GetInnerPhotoOutput()345 sptr<PhotoOutput> Camera_PhotoOutput::GetInnerPhotoOutput()
346 {
347 return innerPhotoOutput_;
348 }
349
CreateCameraPhotoNative(shared_ptr<Media::NativeImage> & image,bool isMain)350 OH_PhotoNative* Camera_PhotoOutput::CreateCameraPhotoNative(shared_ptr<Media::NativeImage> &image, bool isMain)
351 {
352 if (!photoNative_) {
353 photoNative_ = new(std::nothrow) OH_PhotoNative;
354 CHECK_ERROR_RETURN_RET_LOG(photoNative_ == nullptr, nullptr, "Create camera photo native object failed");
355 }
356
357 if (isMain) {
358 photoNative_->SetMainImage(image);
359 } else {
360 photoNative_->SetRawImage(image);
361 }
362 return photoNative_;
363 }
364
GetActiveProfile(Camera_Profile ** profile)365 Camera_ErrorCode Camera_PhotoOutput::GetActiveProfile(Camera_Profile** profile)
366 {
367 auto photoOutputProfile = innerPhotoOutput_->GetPhotoProfile();
368 CHECK_ERROR_RETURN_RET_LOG(photoOutputProfile == nullptr, CAMERA_SERVICE_FATAL_ERROR,
369 "Camera_PhotoOutput::GetActiveProfile failed to get photo profile!");
370
371 CameraFormat cameraFormat = photoOutputProfile->GetCameraFormat();
372 auto itr = g_fwToNdkCameraFormat.find(cameraFormat);
373 CHECK_ERROR_RETURN_RET_LOG(itr == g_fwToNdkCameraFormat.end(), CAMERA_SERVICE_FATAL_ERROR,
374 "Camera_PhotoOutput::GetActiveProfile unsupported camera format %{public}d", cameraFormat);
375
376 Camera_Profile* newProfile = new Camera_Profile;
377 CHECK_ERROR_RETURN_RET_LOG(newProfile == nullptr, CAMERA_SERVICE_FATAL_ERROR,
378 "Camera_PhotoOutput::GetActiveProfile failed to allocate memory for camera profile!");
379
380 newProfile->format = itr->second;
381 newProfile->size.width = photoOutputProfile->GetSize().width;
382 newProfile->size.height = photoOutputProfile->GetSize().height;
383
384 *profile = newProfile;
385 return CAMERA_OK;
386 }
387
IsMovingPhotoSupported(bool * isSupported)388 Camera_ErrorCode Camera_PhotoOutput::IsMovingPhotoSupported(bool* isSupported)
389 {
390 MEDIA_DEBUG_LOG("Camera_PhotoOutput IsMovingPhotoSupported is called");
391 auto session = innerPhotoOutput_->GetSession();
392 CHECK_ERROR_RETURN_RET_LOG(session == nullptr, CAMERA_SERVICE_FATAL_ERROR, "GetSession failed");
393
394 *isSupported = session->IsMovingPhotoSupported();
395 return CAMERA_OK;
396 }
397
EnableMovingPhoto(bool enableMovingPhoto)398 Camera_ErrorCode Camera_PhotoOutput::EnableMovingPhoto(bool enableMovingPhoto)
399 {
400 MEDIA_DEBUG_LOG("Camera_PhotoOutput EnableMovingPhoto is called");
401 auto session = innerPhotoOutput_->GetSession();
402 CHECK_ERROR_RETURN_RET_LOG(session == nullptr, CAMERA_SERVICE_FATAL_ERROR, "GetSession failed");
403
404 session->LockForControl();
405 int32_t ret = session->EnableMovingPhoto(enableMovingPhoto);
406 session->UnlockForControl();
407
408 return FrameworkToNdkCameraError(ret);
409 }
410
GetPhotoRotation(int32_t imageRotation,Camera_ImageRotation * cameraImageRotation)411 Camera_ErrorCode Camera_PhotoOutput::GetPhotoRotation(int32_t imageRotation, Camera_ImageRotation* cameraImageRotation)
412 {
413 CHECK_ERROR_RETURN_RET_LOG(cameraImageRotation == nullptr, CAMERA_SERVICE_FATAL_ERROR,
414 "GetCameraImageRotation failed");
415 int32_t cameraOutputRotation = innerPhotoOutput_->GetPhotoRotation(imageRotation);
416 CHECK_ERROR_RETURN_RET_LOG(cameraOutputRotation == CAMERA_SERVICE_FATAL_ERROR, CAMERA_SERVICE_FATAL_ERROR,
417 "Camera_PhotoOutput::GetPhotoRotation failed to get photo profile! ret: %{public}d", cameraOutputRotation);
418 *cameraImageRotation = static_cast<Camera_ImageRotation>(cameraOutputRotation);
419 return CAMERA_OK;
420 }