1 /*
2 * Copyright (c) 2021-2022 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 #include <securec.h>
18 #include "camera_util.h"
19 #include "hstream_capture_callback_stub.h"
20 #include "input/camera_device.h"
21 #include "session/capture_session.h"
22 #include "camera_log.h"
23
24 using namespace std;
25
26 namespace OHOS {
27 namespace CameraStandard {
PhotoCaptureSetting()28 PhotoCaptureSetting::PhotoCaptureSetting()
29 {
30 int32_t items = 10;
31 int32_t dataLength = 100;
32 captureMetadataSetting_ = std::make_shared<Camera::CameraMetadata>(items, dataLength);
33 }
34
GetQuality()35 PhotoCaptureSetting::QualityLevel PhotoCaptureSetting::GetQuality()
36 {
37 QualityLevel quality = QUALITY_LEVEL_LOW;
38 camera_metadata_item_t item;
39
40 int ret = Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_JPEG_QUALITY, &item);
41 if (ret != CAM_META_SUCCESS) {
42 return QUALITY_LEVEL_MEDIUM;
43 }
44 if (item.data.u8[0] == OHOS_CAMERA_JPEG_LEVEL_HIGH) {
45 quality = QUALITY_LEVEL_HIGH;
46 } else if (item.data.u8[0] == OHOS_CAMERA_JPEG_LEVEL_MIDDLE) {
47 quality = QUALITY_LEVEL_MEDIUM;
48 }
49 return quality;
50 }
51
SetQuality(PhotoCaptureSetting::QualityLevel qualityLevel)52 void PhotoCaptureSetting::SetQuality(PhotoCaptureSetting::QualityLevel qualityLevel)
53 {
54 bool status = false;
55 camera_metadata_item_t item;
56 uint8_t quality = OHOS_CAMERA_JPEG_LEVEL_LOW;
57
58 if (qualityLevel == QUALITY_LEVEL_HIGH) {
59 quality = OHOS_CAMERA_JPEG_LEVEL_HIGH;
60 } else if (qualityLevel == QUALITY_LEVEL_MEDIUM) {
61 quality = OHOS_CAMERA_JPEG_LEVEL_MIDDLE;
62 }
63 int ret = Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_JPEG_QUALITY, &item);
64 if (ret == CAM_META_ITEM_NOT_FOUND) {
65 status = captureMetadataSetting_->addEntry(OHOS_JPEG_QUALITY, &quality, 1);
66 } else if (ret == CAM_META_SUCCESS) {
67 status = captureMetadataSetting_->updateEntry(OHOS_JPEG_QUALITY, &quality, 1);
68 }
69
70 if (!status) {
71 MEDIA_ERR_LOG("PhotoCaptureSetting::SetQuality Failed to set Quality");
72 }
73 }
74
GetRotation()75 PhotoCaptureSetting::RotationConfig PhotoCaptureSetting::GetRotation()
76 {
77 RotationConfig rotation;
78 camera_metadata_item_t item;
79
80 int ret = Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_JPEG_ORIENTATION, &item);
81 if (ret == CAM_META_SUCCESS) {
82 rotation = static_cast<RotationConfig>(item.data.i32[0]);
83 return rotation;
84 }
85 return RotationConfig::Rotation_0;
86 }
87
SetRotation(PhotoCaptureSetting::RotationConfig rotationValue)88 void PhotoCaptureSetting::SetRotation(PhotoCaptureSetting::RotationConfig rotationValue)
89 {
90 bool status = false;
91 camera_metadata_item_t item;
92 int32_t rotation = rotationValue;
93
94 int ret = Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_JPEG_ORIENTATION, &item);
95 if (ret == CAM_META_ITEM_NOT_FOUND) {
96 status = captureMetadataSetting_->addEntry(OHOS_JPEG_ORIENTATION, &rotation, 1);
97 } else if (ret == CAM_META_SUCCESS) {
98 status = captureMetadataSetting_->updateEntry(OHOS_JPEG_ORIENTATION, &rotation, 1);
99 }
100
101 if (!status) {
102 MEDIA_ERR_LOG("PhotoCaptureSetting::SetRotation Failed to set Rotation");
103 }
104 return;
105 }
106
SetGpsLocation(double latitude,double longitude)107 void PhotoCaptureSetting::SetGpsLocation(double latitude, double longitude)
108 {
109 std::unique_ptr<Location> location = std::make_unique<Location>();
110 location->latitude = latitude;
111 location->longitude = longitude;
112 location->altitude = 0;
113 SetLocation(location);
114 }
115
SetLocation(std::unique_ptr<Location> & location)116 void PhotoCaptureSetting::SetLocation(std::unique_ptr<Location> &location)
117 {
118 double gpsCoordinates[3] = {location->latitude, location->longitude, location->altitude};
119 bool status = false;
120 camera_metadata_item_t item;
121
122 MEDIA_DEBUG_LOG("PhotoCaptureSetting::SetLocation lat=%{public}f, long=%{public}f and alt=%{public}f",
123 location->latitude, location->longitude, location->altitude);
124 int ret = Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_JPEG_GPS_COORDINATES, &item);
125 if (ret == CAM_META_ITEM_NOT_FOUND) {
126 status = captureMetadataSetting_->addEntry(OHOS_JPEG_GPS_COORDINATES, gpsCoordinates,
127 sizeof(gpsCoordinates) / sizeof(gpsCoordinates[0]));
128 } else if (ret == CAM_META_SUCCESS) {
129 status = captureMetadataSetting_->updateEntry(OHOS_JPEG_GPS_COORDINATES, gpsCoordinates,
130 sizeof(gpsCoordinates) / sizeof(gpsCoordinates[0]));
131 }
132
133 if (!status) {
134 MEDIA_ERR_LOG("PhotoCaptureSetting::SetLocation Failed to set GPS co-ordinates");
135 }
136 }
137
SetMirror(bool enable)138 void PhotoCaptureSetting::SetMirror(bool enable)
139 {
140 bool status = false;
141 camera_metadata_item_t item;
142 uint8_t mirror = enable;
143
144 MEDIA_DEBUG_LOG("PhotoCaptureSetting::SetMirror value=%{public}d", enable);
145 int ret = Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_CONTROL_CAPTURE_MIRROR, &item);
146 if (ret == CAM_META_ITEM_NOT_FOUND) {
147 status = captureMetadataSetting_->addEntry(OHOS_CONTROL_CAPTURE_MIRROR, &mirror, 1);
148 } else if (ret == CAM_META_SUCCESS) {
149 status = captureMetadataSetting_->updateEntry(OHOS_CONTROL_CAPTURE_MIRROR, &mirror, 1);
150 }
151
152 if (!status) {
153 MEDIA_ERR_LOG("PhotoCaptureSetting::SetMirror Failed to set mirroring in photo capture setting");
154 }
155 return;
156 }
157
GetCaptureMetadataSetting()158 std::shared_ptr<Camera::CameraMetadata> PhotoCaptureSetting::GetCaptureMetadataSetting()
159 {
160 return captureMetadataSetting_;
161 }
162
OnCaptureStarted(const int32_t captureId)163 int32_t HStreamCaptureCallbackImpl::OnCaptureStarted(const int32_t captureId)
164 {
165 CAMERA_SYNC_TRACE;
166 if (photoOutput_ != nullptr && photoOutput_->GetApplicationCallback() != nullptr) {
167 photoOutput_->GetApplicationCallback()->OnCaptureStarted(captureId);
168 } else {
169 MEDIA_INFO_LOG("Discarding HStreamCaptureCallbackImpl::OnCaptureStarted callback");
170 }
171 return CAMERA_OK;
172 }
173
OnCaptureEnded(const int32_t captureId,const int32_t frameCount)174 int32_t HStreamCaptureCallbackImpl::OnCaptureEnded(const int32_t captureId, const int32_t frameCount)
175 {
176 CAMERA_SYNC_TRACE;
177 if (photoOutput_ != nullptr && photoOutput_->GetApplicationCallback() != nullptr) {
178 photoOutput_->GetApplicationCallback()->OnCaptureEnded(captureId, frameCount);
179 } else {
180 MEDIA_INFO_LOG("Discarding HStreamCaptureCallbackImpl::OnCaptureEnded callback");
181 }
182 return CAMERA_OK;
183 }
184
OnCaptureError(const int32_t captureId,const int32_t errorCode)185 int32_t HStreamCaptureCallbackImpl::OnCaptureError(const int32_t captureId, const int32_t errorCode)
186 {
187 if (photoOutput_ != nullptr && photoOutput_->GetApplicationCallback() != nullptr) {
188 photoOutput_->GetApplicationCallback()->OnCaptureError(captureId, errorCode);
189 } else {
190 MEDIA_INFO_LOG("Discarding HStreamCaptureCallbackImpl::OnCaptureError callback");
191 }
192 return CAMERA_OK;
193 }
194
OnFrameShutter(const int32_t captureId,const uint64_t timestamp)195 int32_t HStreamCaptureCallbackImpl::OnFrameShutter(const int32_t captureId, const uint64_t timestamp)
196 {
197 CAMERA_SYNC_TRACE;
198 if (photoOutput_ != nullptr && photoOutput_->GetApplicationCallback() != nullptr) {
199 photoOutput_->GetApplicationCallback()->OnFrameShutter(captureId, timestamp);
200 } else {
201 MEDIA_INFO_LOG("Discarding HStreamCaptureCallbackImpl::OnFrameShutter callback");
202 }
203 return CAMERA_OK;
204 }
205
PhotoOutput(sptr<IStreamCapture> & streamCapture)206 PhotoOutput::PhotoOutput(sptr<IStreamCapture> &streamCapture)
207 : CaptureOutput(CAPTURE_OUTPUT_TYPE_PHOTO, StreamType::CAPTURE, streamCapture)
208 {
209 defaultCaptureSetting_ = nullptr;
210 }
211
~PhotoOutput()212 PhotoOutput::~PhotoOutput()
213 {
214 MEDIA_DEBUG_LOG("Enter Into PhotoOutput::~PhotoOutput()");
215 defaultCaptureSetting_ = nullptr;
216 }
217
SetCallback(std::shared_ptr<PhotoStateCallback> callback)218 void PhotoOutput::SetCallback(std::shared_ptr<PhotoStateCallback> callback)
219 {
220 std::lock_guard<std::mutex> lock(outputCallbackMutex_);
221 appCallback_ = callback;
222 if (appCallback_ != nullptr) {
223 if (cameraSvcCallback_ == nullptr) {
224 cameraSvcCallback_ = new(std::nothrow) HStreamCaptureCallbackImpl(this);
225 if (cameraSvcCallback_ == nullptr) {
226 MEDIA_ERR_LOG("PhotoOutput::SetCallback new HStreamCaptureCallbackImpl Failed to register callback");
227 appCallback_ = nullptr;
228 return;
229 }
230 }
231 auto itemStream = static_cast<IStreamCapture *>(GetStream().GetRefPtr());
232 int32_t errorCode = CAMERA_OK;
233 if (itemStream) {
234 errorCode = itemStream->SetCallback(cameraSvcCallback_);
235 } else {
236 MEDIA_ERR_LOG("PhotoOutput::SetCallback() itemStream is nullptr");
237 }
238 if (errorCode != CAMERA_OK) {
239 MEDIA_ERR_LOG("PhotoOutput::SetCallback: Failed to register callback, errorCode: %{public}d", errorCode);
240 cameraSvcCallback_ = nullptr;
241 appCallback_ = nullptr;
242 }
243 }
244 }
245
SetThumbnailListener(sptr<IBufferConsumerListener> & listener)246 void PhotoOutput::SetThumbnailListener(sptr<IBufferConsumerListener>& listener)
247 {
248 if (thumbnailSurface_) {
249 SurfaceError ret = thumbnailSurface_->RegisterConsumerListener(listener);
250 if (ret != SURFACE_ERROR_OK) {
251 MEDIA_ERR_LOG("PhotoOutput::SetThumbnailListener Surface consumer listener registration failed");
252 }
253 } else {
254 MEDIA_ERR_LOG("PhotoOutput SetThumbnailListener surface is null");
255 }
256 }
257
SetThumbnail(bool isEnabled)258 int32_t PhotoOutput::SetThumbnail(bool isEnabled)
259 {
260 CAMERA_SYNC_TRACE;
261 int32_t retCode = 0;
262 sptr<CameraDevice> cameraObj;
263 CaptureSession* captureSession = GetSession();
264 if ((captureSession == nullptr) || (captureSession->inputDevice_ == nullptr)) {
265 MEDIA_ERR_LOG("PhotoOutput isQuickThumbnailEnabled error!, captureSession or inputDevice_ is nullptr");
266 return SESSION_NOT_RUNNING;
267 }
268 cameraObj = captureSession->inputDevice_->GetCameraDeviceInfo();
269 if (cameraObj == nullptr) {
270 MEDIA_ERR_LOG("PhotoOutput SetThumbnail error!, cameraObj is nullptr");
271 return SESSION_NOT_RUNNING;
272 }
273 !thumbnailSurface_ && (thumbnailSurface_ = Surface::CreateSurfaceAsConsumer("quickThumbnail"));
274 if (thumbnailSurface_ == nullptr) {
275 MEDIA_ERR_LOG("PhotoOutput::SetThumbnail Failed to create surface");
276 return SERVICE_FATL_ERROR;
277 }
278 retCode = static_cast<IStreamCapture *>(
279 GetStream().GetRefPtr())->SetThumbnail(isEnabled, thumbnailSurface_->GetProducer());
280 return retCode;
281 }
282
GetApplicationCallback()283 std::shared_ptr<PhotoStateCallback> PhotoOutput::GetApplicationCallback()
284 {
285 std::lock_guard<std::mutex> lock(outputCallbackMutex_);
286 return appCallback_;
287 }
288
Capture(std::shared_ptr<PhotoCaptureSetting> photoCaptureSettings)289 int32_t PhotoOutput::Capture(std::shared_ptr<PhotoCaptureSetting> photoCaptureSettings)
290 {
291 std::lock_guard<std::mutex> lock(asyncOpMutex_);
292 CaptureSession* captureSession = GetSession();
293 if (captureSession == nullptr || !captureSession->IsSessionCommited()) {
294 MEDIA_ERR_LOG("PhotoOutput Failed to Capture!, session not runing");
295 return CameraErrorCode::SESSION_NOT_RUNNING;
296 }
297 if (GetStream() == nullptr) {
298 MEDIA_ERR_LOG("PhotoOutput Failed to Capture!, GetStream is nullptr");
299 return CameraErrorCode::SERVICE_FATL_ERROR;
300 }
301 defaultCaptureSetting_ = photoCaptureSettings;
302 auto itemStream = static_cast<IStreamCapture *>(GetStream().GetRefPtr());
303 int32_t errCode = CAMERA_UNKNOWN_ERROR;
304 if (itemStream) {
305 errCode = itemStream->Capture(photoCaptureSettings->GetCaptureMetadataSetting());
306 } else {
307 MEDIA_ERR_LOG("PhotoOutput::Capture() itemStream is nullptr");
308 }
309 if (errCode != CAMERA_OK) {
310 MEDIA_ERR_LOG("PhotoOutput Failed to Capture!, errCode: %{public}d", errCode);
311 }
312 return ServiceToCameraError(errCode);
313 }
314
Capture()315 int32_t PhotoOutput::Capture()
316 {
317 std::lock_guard<std::mutex> lock(asyncOpMutex_);
318 CaptureSession* captureSession = GetSession();
319 if (captureSession == nullptr || !captureSession->IsSessionCommited()) {
320 MEDIA_ERR_LOG("PhotoOutput Failed to Capture!, session not runing");
321 return CameraErrorCode::SESSION_NOT_RUNNING;
322 }
323 if (GetStream() == nullptr) {
324 MEDIA_ERR_LOG("PhotoOutput Failed to Capture!, GetStream is nullptr");
325 return CameraErrorCode::SERVICE_FATL_ERROR;
326 }
327 int32_t items = 0;
328 int32_t dataLength = 0;
329 std::shared_ptr<Camera::CameraMetadata> captureMetadataSetting =
330 std::make_shared<Camera::CameraMetadata>(items, dataLength);
331 auto itemStream = static_cast<IStreamCapture *>(GetStream().GetRefPtr());
332 int32_t errCode = CAMERA_UNKNOWN_ERROR;
333 if (itemStream) {
334 errCode = itemStream->Capture(captureMetadataSetting);
335 } else {
336 MEDIA_ERR_LOG("PhotoOutput::Capture() itemStream is nullptr");
337 }
338 if (errCode != CAMERA_OK) {
339 MEDIA_ERR_LOG("PhotoOutput Failed to Capture!, errCode: %{public}d", errCode);
340 }
341 return ServiceToCameraError(errCode);
342 }
343
CancelCapture()344 int32_t PhotoOutput::CancelCapture()
345 {
346 std::lock_guard<std::mutex> lock(asyncOpMutex_);
347 CaptureSession* captureSession = GetSession();
348 if (captureSession == nullptr || !captureSession->IsSessionCommited()) {
349 MEDIA_ERR_LOG("PhotoOutput Failed to Capture!, session not runing");
350 return CameraErrorCode::SESSION_NOT_RUNNING;
351 }
352 if (GetStream() == nullptr) {
353 MEDIA_ERR_LOG("PhotoOutput Failed to CancelCapture!, GetStream is nullptr");
354 return CameraErrorCode::SERVICE_FATL_ERROR;
355 }
356 auto itemStream = static_cast<IStreamCapture *>(GetStream().GetRefPtr());
357 int32_t errCode = CAMERA_UNKNOWN_ERROR;
358 if (itemStream) {
359 errCode = itemStream->CancelCapture();
360 } else {
361 MEDIA_ERR_LOG("PhotoOutput::CancelCapture() itemStream is nullptr");
362 }
363 if (errCode != CAMERA_OK) {
364 MEDIA_ERR_LOG("PhotoOutput Failed to CancelCapture!, errCode: %{public}d", errCode);
365 }
366 return ServiceToCameraError(errCode);
367 }
368
Release()369 int32_t PhotoOutput::Release()
370 {
371 {
372 std::lock_guard<std::mutex> lock(outputCallbackMutex_);
373 cameraSvcCallback_ = nullptr;
374 appCallback_ = nullptr;
375 }
376 std::lock_guard<std::mutex> lock(asyncOpMutex_);
377 MEDIA_DEBUG_LOG("Enter Into PhotoOutput::Release");
378 if (GetStream() == nullptr) {
379 MEDIA_ERR_LOG("PhotoOutput Failed to Release!, GetStream is nullptr");
380 return CameraErrorCode::SERVICE_FATL_ERROR;
381 }
382 auto itemStream = static_cast<IStreamCapture *>(GetStream().GetRefPtr());
383 int32_t errCode = CAMERA_UNKNOWN_ERROR;
384 if (itemStream) {
385 errCode = itemStream->Release();
386 } else {
387 MEDIA_ERR_LOG("PhotoOutput::Release() itemStream is nullptr");
388 }
389 if (errCode != CAMERA_OK) {
390 MEDIA_ERR_LOG("PhotoOutput Failed to release!, errCode: %{public}d", errCode);
391 }
392 defaultCaptureSetting_ = nullptr;
393 CaptureOutput::Release();
394 return ServiceToCameraError(errCode);
395 }
396
IsMirrorSupported()397 bool PhotoOutput::IsMirrorSupported()
398 {
399 bool isMirrorEnabled = false;
400 camera_metadata_item_t item;
401 sptr<CameraDevice> cameraObj;
402 CaptureSession* captureSession = GetSession();
403 if ((captureSession == nullptr) || (captureSession->inputDevice_ == nullptr)) {
404 MEDIA_ERR_LOG("PhotoOutput IsMirrorSupported error!, captureSession or inputDevice_ is nullptr");
405 return isMirrorEnabled;
406 }
407 cameraObj = captureSession->inputDevice_->GetCameraDeviceInfo();
408 if (cameraObj == nullptr) {
409 MEDIA_ERR_LOG("PhotoOutput IsMirrorSupported error!, cameraObj is nullptr");
410 return isMirrorEnabled;
411 }
412 std::shared_ptr<Camera::CameraMetadata> metadata = cameraObj->GetMetadata();
413
414 int32_t ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_CONTROL_CAPTURE_MIRROR_SUPPORTED, &item);
415 if (ret == CAM_META_SUCCESS) {
416 isMirrorEnabled = ((item.data.u8[0] == 1) || (item.data.u8[0] == 0));
417 }
418 return isMirrorEnabled;
419 }
420
IsQuickThumbnailSupported()421 int32_t PhotoOutput::IsQuickThumbnailSupported()
422 {
423 int32_t isQuickThumbnailEnabled = -1;
424 camera_metadata_item_t item;
425 sptr<CameraDevice> cameraObj;
426 CaptureSession* captureSession = GetSession();
427 if ((captureSession == nullptr) || (captureSession->inputDevice_ == nullptr)) {
428 MEDIA_ERR_LOG("PhotoOutput isQuickThumbnailEnabled error!, captureSession or inputDevice_ is nullptr");
429 return SESSION_NOT_RUNNING;
430 }
431 cameraObj = captureSession->inputDevice_->GetCameraDeviceInfo();
432 if (cameraObj == nullptr) {
433 MEDIA_ERR_LOG("PhotoOutput isQuickThumbnailEnabled error!, cameraObj is nullptr");
434 return SESSION_NOT_RUNNING;
435 }
436 std::shared_ptr<Camera::CameraMetadata> metadata = cameraObj->GetMetadata();
437 int32_t ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_ABILITY_STREAM_QUICK_THUMBNAIL_AVAILABLE, &item);
438 if (ret == CAM_META_SUCCESS) {
439 isQuickThumbnailEnabled = (item.data.u8[0] == 1) ? 0 : -1;
440 }
441 return isQuickThumbnailEnabled;
442 }
443
GetDefaultCaptureSetting()444 std::shared_ptr<PhotoCaptureSetting> PhotoOutput::GetDefaultCaptureSetting()
445 {
446 return defaultCaptureSetting_;
447 }
448 } // CameraStandard
449 } // OHOS
450