• 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     cameraSvcCallback_ = nullptr;
216     appCallback_ = nullptr;
217     defaultCaptureSetting_ = nullptr;
218 }
219 
SetCallback(std::shared_ptr<PhotoStateCallback> callback)220 void PhotoOutput::SetCallback(std::shared_ptr<PhotoStateCallback> callback)
221 {
222     appCallback_ = callback;
223     if (appCallback_ != nullptr) {
224         if (cameraSvcCallback_ == nullptr) {
225             cameraSvcCallback_ = new(std::nothrow) HStreamCaptureCallbackImpl(this);
226             if (cameraSvcCallback_ == nullptr) {
227                 MEDIA_ERR_LOG("PhotoOutput::SetCallback new HStreamCaptureCallbackImpl Failed to register callback");
228                 appCallback_ = nullptr;
229                 return;
230             }
231         }
232         auto itemStream = static_cast<IStreamCapture *>(GetStream().GetRefPtr());
233         int32_t errorCode = CAMERA_OK;
234         if (itemStream) {
235             errorCode = itemStream->SetCallback(cameraSvcCallback_);
236         } else {
237             MEDIA_ERR_LOG("PhotoOutput::SetCallback() itemStream is nullptr");
238         }
239         if (errorCode != CAMERA_OK) {
240             MEDIA_ERR_LOG("PhotoOutput::SetCallback: Failed to register callback, errorCode: %{public}d", errorCode);
241             cameraSvcCallback_ = nullptr;
242             appCallback_ = nullptr;
243         }
244     }
245 }
246 
SetThumbnailListener(sptr<IBufferConsumerListener> & listener)247 void PhotoOutput::SetThumbnailListener(sptr<IBufferConsumerListener>& listener)
248 {
249     if (thumbnailSurface_) {
250         SurfaceError ret = thumbnailSurface_->RegisterConsumerListener(listener);
251         if (ret != SURFACE_ERROR_OK) {
252             MEDIA_ERR_LOG("PhotoOutput::SetThumbnailListener Surface consumer listener registration failed");
253         }
254     } else {
255         MEDIA_ERR_LOG("PhotoOutput SetThumbnailListener surface is null");
256     }
257 }
258 
SetThumbnail(bool isEnabled)259 int32_t PhotoOutput::SetThumbnail(bool isEnabled)
260 {
261     CAMERA_SYNC_TRACE;
262     int32_t retCode = 0;
263     sptr<CameraDevice> cameraObj;
264     CaptureSession* captureSession = GetSession();
265     if ((captureSession == nullptr) || (captureSession->inputDevice_ == nullptr)) {
266         MEDIA_ERR_LOG("PhotoOutput isQuickThumbnailEnabled error!, captureSession or inputDevice_ is nullptr");
267         return SESSION_NOT_RUNNING;
268     }
269     cameraObj = captureSession->inputDevice_->GetCameraDeviceInfo();
270     if (cameraObj == nullptr) {
271         MEDIA_ERR_LOG("PhotoOutput SetThumbnail error!, cameraObj is nullptr");
272         return SESSION_NOT_RUNNING;
273     }
274     !thumbnailSurface_ && (thumbnailSurface_ = Surface::CreateSurfaceAsConsumer("quickThumbnail"));
275     if (thumbnailSurface_ == nullptr) {
276         MEDIA_ERR_LOG("PhotoOutput::SetThumbnail Failed to create surface");
277         return SERVICE_FATL_ERROR;
278     }
279     retCode = static_cast<IStreamCapture *>(
280                 GetStream().GetRefPtr())->SetThumbnail(isEnabled, thumbnailSurface_->GetProducer());
281     return retCode;
282 }
283 
GetApplicationCallback()284 std::shared_ptr<PhotoStateCallback> PhotoOutput::GetApplicationCallback()
285 {
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     std::lock_guard<std::mutex> lock(asyncOpMutex_);
372     MEDIA_DEBUG_LOG("Enter Into PhotoOutput::Release");
373     if (GetStream() == nullptr) {
374         MEDIA_ERR_LOG("PhotoOutput Failed to Release!, GetStream is nullptr");
375         return CameraErrorCode::SERVICE_FATL_ERROR;
376     }
377     auto itemStream = static_cast<IStreamCapture *>(GetStream().GetRefPtr());
378     int32_t errCode = CAMERA_UNKNOWN_ERROR;
379     if (itemStream) {
380         errCode = itemStream->Release();
381     } else {
382         MEDIA_ERR_LOG("PhotoOutput::Release() itemStream is nullptr");
383     }
384     if (errCode != CAMERA_OK) {
385         MEDIA_ERR_LOG("PhotoOutput Failed to release!, errCode: %{public}d", errCode);
386     }
387     cameraSvcCallback_ = nullptr;
388     appCallback_ = nullptr;
389     defaultCaptureSetting_ = nullptr;
390     CaptureOutput::Release();
391     return ServiceToCameraError(errCode);
392 }
393 
IsMirrorSupported()394 bool PhotoOutput::IsMirrorSupported()
395 {
396     bool isMirrorEnabled = false;
397     camera_metadata_item_t item;
398     sptr<CameraDevice> cameraObj;
399     CaptureSession* captureSession = GetSession();
400     if ((captureSession == nullptr) || (captureSession->inputDevice_ == nullptr)) {
401         MEDIA_ERR_LOG("PhotoOutput IsMirrorSupported error!, captureSession or inputDevice_ is nullptr");
402         return isMirrorEnabled;
403     }
404     cameraObj = captureSession->inputDevice_->GetCameraDeviceInfo();
405     if (cameraObj == nullptr) {
406         MEDIA_ERR_LOG("PhotoOutput IsMirrorSupported error!, cameraObj is nullptr");
407         return isMirrorEnabled;
408     }
409     std::shared_ptr<Camera::CameraMetadata> metadata = cameraObj->GetMetadata();
410 
411     int32_t ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_CONTROL_CAPTURE_MIRROR_SUPPORTED, &item);
412     if (ret == CAM_META_SUCCESS) {
413         isMirrorEnabled = ((item.data.u8[0] == 1) || (item.data.u8[0] == 0));
414     }
415     return isMirrorEnabled;
416 }
417 
IsQuickThumbnailSupported()418 int32_t PhotoOutput::IsQuickThumbnailSupported()
419 {
420     int32_t isQuickThumbnailEnabled = -1;
421     camera_metadata_item_t item;
422     sptr<CameraDevice> cameraObj;
423     CaptureSession* captureSession = GetSession();
424     if ((captureSession == nullptr) || (captureSession->inputDevice_ == nullptr)) {
425         MEDIA_ERR_LOG("PhotoOutput isQuickThumbnailEnabled error!, captureSession or inputDevice_ is nullptr");
426         return SESSION_NOT_RUNNING;
427     }
428     cameraObj = captureSession->inputDevice_->GetCameraDeviceInfo();
429     if (cameraObj == nullptr) {
430         MEDIA_ERR_LOG("PhotoOutput isQuickThumbnailEnabled error!, cameraObj is nullptr");
431         return SESSION_NOT_RUNNING;
432     }
433     std::shared_ptr<Camera::CameraMetadata> metadata = cameraObj->GetMetadata();
434     int32_t ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_ABILITY_STREAM_QUICK_THUMBNAIL_AVAILABLE, &item);
435     if (ret == CAM_META_SUCCESS) {
436         isQuickThumbnailEnabled = (item.data.u8[0] == 1) ? 0 : -1;
437     }
438     return isQuickThumbnailEnabled;
439 }
440 
GetDefaultCaptureSetting()441 std::shared_ptr<PhotoCaptureSetting> PhotoOutput::GetDefaultCaptureSetting()
442 {
443     return defaultCaptureSetting_;
444 }
445 } // CameraStandard
446 } // OHOS
447