• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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