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