• 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 
163 class HStreamCaptureCallbackImpl : public HStreamCaptureCallbackStub {
164 public:
165     PhotoOutput* photoOutput_ = nullptr;
HStreamCaptureCallbackImpl()166     HStreamCaptureCallbackImpl() : photoOutput_(nullptr) {
167     }
168 
HStreamCaptureCallbackImpl(PhotoOutput * photoOutput)169     explicit HStreamCaptureCallbackImpl(PhotoOutput* photoOutput) : photoOutput_(photoOutput) {
170     }
171 
~HStreamCaptureCallbackImpl()172     ~HStreamCaptureCallbackImpl()
173     {
174         photoOutput_ = nullptr;
175     }
176 
OnCaptureStarted(const int32_t captureId)177     int32_t OnCaptureStarted(const int32_t captureId) override
178     {
179         CAMERA_SYNC_TRACE;
180         if (photoOutput_ != nullptr && photoOutput_->GetApplicationCallback() != nullptr) {
181             photoOutput_->GetApplicationCallback()->OnCaptureStarted(captureId);
182         } else {
183             MEDIA_INFO_LOG("Discarding HStreamCaptureCallbackImpl::OnCaptureStarted callback");
184         }
185         return CAMERA_OK;
186     }
187 
OnCaptureEnded(const int32_t captureId,const int32_t frameCount)188     int32_t OnCaptureEnded(const int32_t captureId, const int32_t frameCount) override
189     {
190         CAMERA_SYNC_TRACE;
191         if (photoOutput_ != nullptr && photoOutput_->GetApplicationCallback() != nullptr) {
192             photoOutput_->GetApplicationCallback()->OnCaptureEnded(captureId, frameCount);
193         } else {
194             MEDIA_INFO_LOG("Discarding HStreamCaptureCallbackImpl::OnCaptureEnded callback");
195         }
196         return CAMERA_OK;
197     }
198 
OnCaptureError(const int32_t captureId,const int32_t errorCode)199     int32_t OnCaptureError(const int32_t captureId, const int32_t errorCode) override
200     {
201         if (photoOutput_ != nullptr && photoOutput_->GetApplicationCallback() != nullptr) {
202             photoOutput_->GetApplicationCallback()->OnCaptureError(captureId, errorCode);
203         } else {
204             MEDIA_INFO_LOG("Discarding HStreamCaptureCallbackImpl::OnCaptureError callback");
205         }
206         return CAMERA_OK;
207     }
208 
OnFrameShutter(const int32_t captureId,const uint64_t timestamp)209     int32_t OnFrameShutter(const int32_t captureId, const uint64_t timestamp) override
210     {
211         CAMERA_SYNC_TRACE;
212         if (photoOutput_ != nullptr && photoOutput_->GetApplicationCallback() != nullptr) {
213             photoOutput_->GetApplicationCallback()->OnFrameShutter(captureId, timestamp);
214         } else {
215             MEDIA_INFO_LOG("Discarding HStreamCaptureCallbackImpl::OnFrameShutter callback");
216         }
217         return CAMERA_OK;
218     }
219 };
220 
PhotoOutput(sptr<IStreamCapture> & streamCapture)221 PhotoOutput::PhotoOutput(sptr<IStreamCapture> &streamCapture)
222     : CaptureOutput(CAPTURE_OUTPUT_TYPE_PHOTO, StreamType::CAPTURE, streamCapture)
223 {
224     defaultCaptureSetting_ = nullptr;
225 }
226 
~PhotoOutput()227 PhotoOutput::~PhotoOutput()
228 {
229     cameraSvcCallback_ = nullptr;
230     appCallback_ = nullptr;
231     defaultCaptureSetting_ = nullptr;
232 }
233 
SetCallback(std::shared_ptr<PhotoStateCallback> callback)234 void PhotoOutput::SetCallback(std::shared_ptr<PhotoStateCallback> callback)
235 {
236     appCallback_ = callback;
237     if (appCallback_ != nullptr) {
238         if (cameraSvcCallback_ == nullptr) {
239             cameraSvcCallback_ = new(std::nothrow) HStreamCaptureCallbackImpl(this);
240             if (cameraSvcCallback_ == nullptr) {
241                 MEDIA_ERR_LOG("PhotoOutput::SetCallback new HStreamCaptureCallbackImpl Failed to register callback");
242                 appCallback_ = nullptr;
243                 return;
244             }
245         }
246         auto itemStream = static_cast<IStreamCapture *>(GetStream().GetRefPtr());
247         int32_t errorCode = CAMERA_OK;
248         if (itemStream) {
249             errorCode = itemStream->SetCallback(cameraSvcCallback_);
250         } else {
251             MEDIA_ERR_LOG("PhotoOutput::SetCallback() itemStream is nullptr");
252         }
253         if (errorCode != CAMERA_OK) {
254             MEDIA_ERR_LOG("PhotoOutput::SetCallback: Failed to register callback, errorCode: %{public}d", errorCode);
255             cameraSvcCallback_ = nullptr;
256             appCallback_ = nullptr;
257         }
258     }
259 }
260 
GetApplicationCallback()261 std::shared_ptr<PhotoStateCallback> PhotoOutput::GetApplicationCallback()
262 {
263     return appCallback_;
264 }
265 
Capture(std::shared_ptr<PhotoCaptureSetting> photoCaptureSettings)266 int32_t PhotoOutput::Capture(std::shared_ptr<PhotoCaptureSetting> photoCaptureSettings)
267 {
268     std::lock_guard<std::mutex> lock(asyncOpMutex_);
269     CaptureSession* captureSession = GetSession();
270     if (captureSession == nullptr || !captureSession->IsSessionCommited()) {
271         MEDIA_ERR_LOG("PhotoOutput Failed to Capture!, session not runing");
272         return CameraErrorCode::SESSION_NOT_RUNNING;
273     }
274     if (GetStream() == nullptr) {
275         MEDIA_ERR_LOG("PhotoOutput Failed to Capture!, GetStream is nullptr");
276         return CameraErrorCode::SERVICE_FATL_ERROR;
277     }
278     defaultCaptureSetting_ = photoCaptureSettings;
279     auto itemStream = static_cast<IStreamCapture *>(GetStream().GetRefPtr());
280     int32_t errCode = CAMERA_UNKNOWN_ERROR;
281     if (itemStream) {
282         errCode = itemStream->Capture(photoCaptureSettings->GetCaptureMetadataSetting());
283     } else {
284         MEDIA_ERR_LOG("PhotoOutput::Capture() itemStream is nullptr");
285     }
286     if (errCode != CAMERA_OK) {
287         MEDIA_ERR_LOG("PhotoOutput Failed to Capture!, errCode: %{public}d", errCode);
288     }
289     return ServiceToCameraError(errCode);
290 }
291 
Capture()292 int32_t PhotoOutput::Capture()
293 {
294     std::lock_guard<std::mutex> lock(asyncOpMutex_);
295     CaptureSession* captureSession = GetSession();
296     if (captureSession == nullptr || !captureSession->IsSessionCommited()) {
297         MEDIA_ERR_LOG("PhotoOutput Failed to Capture!, session not runing");
298         return CameraErrorCode::SESSION_NOT_RUNNING;
299     }
300     if (GetStream() == nullptr) {
301         MEDIA_ERR_LOG("PhotoOutput Failed to Capture!, GetStream is nullptr");
302         return CameraErrorCode::SERVICE_FATL_ERROR;
303     }
304     int32_t items = 0;
305     int32_t dataLength = 0;
306     std::shared_ptr<Camera::CameraMetadata> captureMetadataSetting =
307         std::make_shared<Camera::CameraMetadata>(items, dataLength);
308     auto itemStream = static_cast<IStreamCapture *>(GetStream().GetRefPtr());
309     int32_t errCode = CAMERA_UNKNOWN_ERROR;
310     if (itemStream) {
311         errCode = itemStream->Capture(captureMetadataSetting);
312     } else {
313         MEDIA_ERR_LOG("PhotoOutput::Capture() itemStream is nullptr");
314     }
315     if (errCode != CAMERA_OK) {
316         MEDIA_ERR_LOG("PhotoOutput Failed to Capture!, errCode: %{public}d", errCode);
317     }
318     return ServiceToCameraError(errCode);
319 }
320 
CancelCapture()321 int32_t PhotoOutput::CancelCapture()
322 {
323     std::lock_guard<std::mutex> lock(asyncOpMutex_);
324     CaptureSession* captureSession = GetSession();
325     if (captureSession == nullptr || !captureSession->IsSessionCommited()) {
326         MEDIA_ERR_LOG("PhotoOutput Failed to Capture!, session not runing");
327         return CameraErrorCode::SESSION_NOT_RUNNING;
328     }
329     if (GetStream() == nullptr) {
330         MEDIA_ERR_LOG("PhotoOutput Failed to CancelCapture!, GetStream is nullptr");
331         return CameraErrorCode::SERVICE_FATL_ERROR;
332     }
333     auto itemStream = static_cast<IStreamCapture *>(GetStream().GetRefPtr());
334     int32_t errCode = CAMERA_UNKNOWN_ERROR;
335     if (itemStream) {
336         errCode = itemStream->CancelCapture();
337     } else {
338         MEDIA_ERR_LOG("PhotoOutput::CancelCapture() itemStream is nullptr");
339     }
340     if (errCode != CAMERA_OK) {
341         MEDIA_ERR_LOG("PhotoOutput Failed to CancelCapture!, errCode: %{public}d", errCode);
342     }
343     return ServiceToCameraError(errCode);
344 }
345 
Release()346 int32_t PhotoOutput::Release()
347 {
348     std::lock_guard<std::mutex> lock(asyncOpMutex_);
349     if (GetStream() == nullptr) {
350         MEDIA_ERR_LOG("PhotoOutput Failed to Release!, GetStream is nullptr");
351         return CameraErrorCode::SERVICE_FATL_ERROR;
352     }
353     auto itemStream = static_cast<IStreamCapture *>(GetStream().GetRefPtr());
354     int32_t errCode = CAMERA_UNKNOWN_ERROR;
355     if (itemStream) {
356         errCode = itemStream->Release();
357     } else {
358         MEDIA_ERR_LOG("PhotoOutput::Release() itemStream is nullptr");
359     }
360     if (errCode != CAMERA_OK) {
361         MEDIA_ERR_LOG("PhotoOutput Failed to release!, errCode: %{public}d", errCode);
362     }
363     cameraSvcCallback_ = nullptr;
364     appCallback_ = nullptr;
365     defaultCaptureSetting_ = nullptr;
366     CaptureOutput::Release();
367     return ServiceToCameraError(errCode);
368 }
369 
IsMirrorSupported()370 bool PhotoOutput::IsMirrorSupported()
371 {
372     bool isMirrorEnabled = false;
373     camera_metadata_item_t item;
374     sptr<CameraDevice> cameraObj_;
375     CaptureSession* captureSession = GetSession();
376     if ((captureSession == nullptr) || (captureSession->inputDevice_ == nullptr)) {
377         MEDIA_ERR_LOG("PhotoOutput IsMirrorSupported error!, captureSession or inputDevice_ is nullptr");
378         return isMirrorEnabled;
379     }
380     cameraObj_ = captureSession->inputDevice_->GetCameraDeviceInfo();
381     if (cameraObj_ == nullptr) {
382         MEDIA_ERR_LOG("PhotoOutput IsMirrorSupported error!, cameraObj is nullptr");
383         return isMirrorEnabled;
384     }
385     std::shared_ptr<Camera::CameraMetadata> metadata = cameraObj_->GetMetadata();
386 
387     int ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_CONTROL_CAPTURE_MIRROR_SUPPORTED, &item);
388     if (ret == CAM_META_SUCCESS) {
389         isMirrorEnabled = ((item.data.u8[0] == 1) || (item.data.u8[0] == 0));
390     }
391     return isMirrorEnabled;
392 }
393 
GetDefaultCaptureSetting()394 std::shared_ptr<PhotoCaptureSetting> PhotoOutput::GetDefaultCaptureSetting()
395 {
396     return defaultCaptureSetting_;
397 }
398 } // CameraStandard
399 } // OHOS
400