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 "hstream_capture.h"
17
18 #include "camera_util.h"
19 #include "camera_log.h"
20 #include "metadata_utils.h"
21
22 namespace OHOS {
23 namespace CameraStandard {
24 static const int32_t CAPTURE_ROTATE_360 = 360;
HStreamCapture(sptr<OHOS::IBufferProducer> producer,int32_t format,int32_t width,int32_t height)25 HStreamCapture::HStreamCapture(sptr<OHOS::IBufferProducer> producer, int32_t format, int32_t width, int32_t height)
26 : HStreamCommon(StreamType::CAPTURE, producer, format, width, height)
27 {}
28
~HStreamCapture()29 HStreamCapture::~HStreamCapture()
30 {}
31
LinkInput(sptr<IStreamOperator> streamOperator,std::shared_ptr<OHOS::Camera::CameraMetadata> cameraAbility,int32_t streamId)32 int32_t HStreamCapture::LinkInput(sptr<IStreamOperator> streamOperator,
33 std::shared_ptr<OHOS::Camera::CameraMetadata> cameraAbility, int32_t streamId)
34 {
35 return HStreamCommon::LinkInput(streamOperator, cameraAbility, streamId);
36 }
37
SetStreamInfo(StreamInfo & streamInfo)38 void HStreamCapture::SetStreamInfo(StreamInfo &streamInfo)
39 {
40 HStreamCommon::SetStreamInfo(streamInfo);
41 streamInfo.intent_ = STILL_CAPTURE;
42 streamInfo.encodeType_ = ENCODE_TYPE_JPEG;
43 }
44
Capture(const std::shared_ptr<OHOS::Camera::CameraMetadata> & captureSettings)45 int32_t HStreamCapture::Capture(const std::shared_ptr<OHOS::Camera::CameraMetadata> &captureSettings)
46 {
47 CAMERA_SYNC_TRACE;
48 if (streamOperator_ == nullptr) {
49 return CAMERA_INVALID_STATE;
50 }
51 int32_t ret = AllocateCaptureId(curCaptureID_);
52 if (ret != CAMERA_OK) {
53 MEDIA_ERR_LOG("HStreamCapture::Capture Failed to allocate a captureId");
54 return ret;
55 }
56 CaptureInfo captureInfoPhoto;
57 captureInfoPhoto.streamIds_ = {streamId_};
58 std::vector<uint8_t> setting;
59 if (!OHOS::Camera::GetCameraMetadataItemCount(captureSettings->get())) {
60 OHOS::Camera::MetadataUtils::ConvertMetadataToVec(cameraAbility_, setting);
61 captureInfoPhoto.captureSetting_ = setting;
62 } else {
63 OHOS::Camera::MetadataUtils::ConvertMetadataToVec(captureSettings, setting);
64 captureInfoPhoto.captureSetting_ = setting;
65 }
66 captureInfoPhoto.enableShutterCallback_ = true;
67
68 // debug log for jpeg quality
69 std::shared_ptr<OHOS::Camera::CameraMetadata> captureMetadataSetting_ = nullptr;
70 OHOS::Camera::MetadataUtils::ConvertVecToMetadata(captureInfoPhoto.captureSetting_, captureMetadataSetting_);
71 if (captureMetadataSetting_ != nullptr) {
72 // print quality, mirror log
73 PrintDebugLog(captureMetadataSetting_);
74 // convert rotation with application set rotation
75 SetRotation(captureMetadataSetting_);
76
77 // update settings
78 std::vector<uint8_t> finalSetting;
79 OHOS::Camera::MetadataUtils::ConvertMetadataToVec(captureMetadataSetting_, finalSetting);
80 captureInfoPhoto.captureSetting_ = finalSetting;
81 }
82 MEDIA_INFO_LOG("HStreamCapture::Capture Starting photo capture with capture ID: %{public}d", curCaptureID_);
83 CamRetCode rc = (CamRetCode)(streamOperator_->Capture(curCaptureID_, captureInfoPhoto, false));
84 if (rc != HDI::Camera::V1_0::NO_ERROR) {
85 MEDIA_ERR_LOG("HStreamCapture::Capture failed with error Code: %{public}d", rc);
86 ret = HdiToServiceError(rc);
87 }
88 ReleaseCaptureId(curCaptureID_);
89 curCaptureID_ = 0;
90 return ret;
91 }
92
PrintDebugLog(const std::shared_ptr<OHOS::Camera::CameraMetadata> & captureMetadataSetting_)93 void HStreamCapture::PrintDebugLog(const std::shared_ptr<OHOS::Camera::CameraMetadata> &captureMetadataSetting_)
94 {
95 camera_metadata_item_t item;
96 int result = OHOS::Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_JPEG_QUALITY, &item);
97 if (result != CAM_META_SUCCESS) {
98 MEDIA_DEBUG_LOG("HStreamCapture::Failed to find OHOS_JPEG_QUALITY tag");
99 } else {
100 MEDIA_DEBUG_LOG("HStreamCapture::find OHOS_JPEG_QUALITY value = %{public}d", item.data.u8[0]);
101 }
102
103 // debug log for capture mirror
104 result = OHOS::Camera::FindCameraMetadataItem(captureMetadataSetting_->get(),
105 OHOS_CONTROL_CAPTURE_MIRROR, &item);
106 if (result != CAM_META_SUCCESS) {
107 MEDIA_DEBUG_LOG("HStreamCapture::Failed to find OHOS_CONTROL_CAPTURE_MIRROR tag");
108 } else {
109 MEDIA_DEBUG_LOG("HStreamCapture::find OHOS_CONTROL_CAPTURE_MIRROR value = %{public}d", item.data.u8[0]);
110 }
111 }
112
SetRotation(const std::shared_ptr<OHOS::Camera::CameraMetadata> & captureMetadataSetting_)113 void HStreamCapture::SetRotation(const std::shared_ptr<OHOS::Camera::CameraMetadata> &captureMetadataSetting_)
114 {
115 // set orientation for capture
116 // sensor orientation, counter-clockwise rotation
117 camera_metadata_item_t item;
118 int result = OHOS::Camera::FindCameraMetadataItem(cameraAbility_->get(), OHOS_SENSOR_ORIENTATION, &item);
119 if (result != CAM_META_SUCCESS) {
120 MEDIA_ERR_LOG("HStreamCapture::Capture set rotation get sensor orientation failed");
121 }
122 int32_t sensorOrientation = item.data.i32[0];
123 MEDIA_INFO_LOG("HStreamCapture::Capture Capture set rotation sensor orientation %{public}d", sensorOrientation);
124
125 result = OHOS::Camera::FindCameraMetadataItem(cameraAbility_->get(), OHOS_ABILITY_CAMERA_POSITION, &item);
126 if (result != CAM_META_SUCCESS) {
127 MEDIA_ERR_LOG("HStreamCapture::Capture Capture set rotation get camera position failed");
128 }
129 camera_position_enum_t cameraPosition = static_cast<camera_position_enum_t>(item.data.u8[0]);
130 MEDIA_INFO_LOG("HStreamCapture::Capture Capture set rotation camera position %{public}d", cameraPosition);
131
132 // rotation from application
133 int32_t rotationValue = 0;
134 result = OHOS::Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_JPEG_ORIENTATION, &item);
135 if (result == CAM_META_SUCCESS) {
136 rotationValue = item.data.i32[0];
137 }
138 MEDIA_INFO_LOG("HStreamCapture::Capture set rotation app rotationValue %{public}d", rotationValue);
139
140 // real rotation
141 int32_t rotation = sensorOrientation + rotationValue;
142 if (rotation >= CAPTURE_ROTATE_360) {
143 rotation = rotation - CAPTURE_ROTATE_360;
144 }
145 MEDIA_INFO_LOG("HStreamCapture::Capture set rotation camera real rotation %{public}d", rotation);
146
147 bool status = false;
148 if (result == CAM_META_ITEM_NOT_FOUND) {
149 status = captureMetadataSetting_->addEntry(OHOS_JPEG_ORIENTATION, &rotation, 1);
150 } else if (result == CAM_META_SUCCESS) {
151 status = captureMetadataSetting_->updateEntry(OHOS_JPEG_ORIENTATION, &rotation, 1);
152 }
153 result = OHOS::Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_JPEG_ORIENTATION, &item);
154 if (result != CAM_META_SUCCESS) {
155 MEDIA_DEBUG_LOG("HStreamCapture::Capture set rotation Failed to find OHOS_JPEG_ORIENTATION tag");
156 } else {
157 MEDIA_DEBUG_LOG("HStreamCapture::Capture set rotation find OHOS_JPEG_ORIENTATION value = %{public}d",
158 item.data.i32[0]);
159 }
160 if (!status) {
161 MEDIA_ERR_LOG("HStreamCapture::Capture set rotation Failed to set Rotation");
162 }
163 }
164
CancelCapture()165 int32_t HStreamCapture::CancelCapture()
166 {
167 // Cancel cature is dummy till continuous/burst mode is supported
168 return CAMERA_OK;
169 }
170
Release()171 int32_t HStreamCapture::Release()
172 {
173 if (curCaptureID_) {
174 ReleaseCaptureId(curCaptureID_);
175 }
176 std::lock_guard<std::mutex> lock(callbackLock_);
177 streamCaptureCallback_ = nullptr;
178 return HStreamCommon::Release();
179 }
180
SetCallback(sptr<IStreamCaptureCallback> & callback)181 int32_t HStreamCapture::SetCallback(sptr<IStreamCaptureCallback> &callback)
182 {
183 if (callback == nullptr) {
184 MEDIA_ERR_LOG("HStreamCapture::SetCallback callback is null");
185 return CAMERA_INVALID_ARG;
186 }
187 std::lock_guard<std::mutex> lock(callbackLock_);
188 streamCaptureCallback_ = callback;
189 return CAMERA_OK;
190 }
191
OnCaptureStarted(int32_t captureId)192 int32_t HStreamCapture::OnCaptureStarted(int32_t captureId)
193 {
194 CAMERA_SYNC_TRACE;
195 std::lock_guard<std::mutex> lock(callbackLock_);
196 if (streamCaptureCallback_ != nullptr) {
197 streamCaptureCallback_->OnCaptureStarted(captureId);
198 }
199 return CAMERA_OK;
200 }
201
OnCaptureEnded(int32_t captureId,int32_t frameCount)202 int32_t HStreamCapture::OnCaptureEnded(int32_t captureId, int32_t frameCount)
203 {
204 CAMERA_SYNC_TRACE;
205 std::lock_guard<std::mutex> lock(callbackLock_);
206 if (streamCaptureCallback_ != nullptr) {
207 streamCaptureCallback_->OnCaptureEnded(captureId, frameCount);
208 }
209 return CAMERA_OK;
210 }
211
OnCaptureError(int32_t captureId,int32_t errorCode)212 int32_t HStreamCapture::OnCaptureError(int32_t captureId, int32_t errorCode)
213 {
214 std::lock_guard<std::mutex> lock(callbackLock_);
215 if (streamCaptureCallback_ != nullptr) {
216 int32_t captureErrorCode;
217 if (errorCode == BUFFER_LOST) {
218 captureErrorCode = CAMERA_STREAM_BUFFER_LOST;
219 } else {
220 captureErrorCode = CAMERA_UNKNOWN_ERROR;
221 }
222 CAMERA_SYSEVENT_FAULT(CreateMsg("Photo OnCaptureError! captureId:%d & "
223 "errorCode:%{public}d", captureId, captureErrorCode));
224 streamCaptureCallback_->OnCaptureError(captureId, captureErrorCode);
225 }
226 return CAMERA_OK;
227 }
228
OnFrameShutter(int32_t captureId,uint64_t timestamp)229 int32_t HStreamCapture::OnFrameShutter(int32_t captureId, uint64_t timestamp)
230 {
231 CAMERA_SYNC_TRACE;
232 std::lock_guard<std::mutex> lock(callbackLock_);
233 if (streamCaptureCallback_ != nullptr) {
234 streamCaptureCallback_->OnFrameShutter(captureId, timestamp);
235 }
236 return CAMERA_OK;
237 }
238
DumpStreamInfo(std::string & dumpString)239 void HStreamCapture::DumpStreamInfo(std::string& dumpString)
240 {
241 dumpString += "capture stream:\n";
242 HStreamCommon::DumpStreamInfo(dumpString);
243 }
244 } // namespace CameraStandard
245 } // namespace OHOS
246