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<OHOS::HDI::Camera::V1_1::IStreamOperator> streamOperator,std::shared_ptr<OHOS::Camera::CameraMetadata> cameraAbility,int32_t streamId)32 int32_t HStreamCapture::LinkInput(sptr<OHOS::HDI::Camera::V1_1::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_V1_1 & streamInfo)38 void HStreamCapture::SetStreamInfo(StreamInfo_V1_1 &streamInfo)
39 {
40 HStreamCommon::SetStreamInfo(streamInfo);
41 streamInfo.v1_0.intent_ = STILL_CAPTURE;
42 streamInfo.v1_0.encodeType_ = ENCODE_TYPE_JPEG;
43 HDI::Camera::V1_1::ExtendedStreamInfo extendedStreamInfo;
44 extendedStreamInfo.type = HDI::Camera::V1_1::EXTENDED_STREAM_INFO_QUICK_THUMBNAIL;
45 extendedStreamInfo.bufferQueue = thumbnailBufferQueue_;
46 // quickThumbnial do not need these param
47 extendedStreamInfo.width = 0;
48 extendedStreamInfo.height = 0;
49 extendedStreamInfo.format = 0;
50 extendedStreamInfo.dataspace = 0;
51 streamInfo.extendedStreamInfos = {extendedStreamInfo};
52 }
53
SetThumbnail(bool isEnabled,const sptr<OHOS::IBufferProducer> & producer)54 int32_t HStreamCapture::SetThumbnail(bool isEnabled, const sptr<OHOS::IBufferProducer> &producer)
55 {
56 if (isEnabled && producer != nullptr) {
57 thumbnailSwitch_ = 1;
58 thumbnailBufferQueue_ = new BufferProducerSequenceable(producer);
59 } else {
60 thumbnailSwitch_ = 0;
61 thumbnailBufferQueue_ = nullptr;
62 }
63 return CAMERA_OK;
64 }
65
Capture(const std::shared_ptr<OHOS::Camera::CameraMetadata> & captureSettings)66 int32_t HStreamCapture::Capture(const std::shared_ptr<OHOS::Camera::CameraMetadata> &captureSettings)
67 {
68 CAMERA_SYNC_TRACE;
69 {
70 std::lock_guard<std::mutex> lock(streamOperatorLock_);
71 if (streamOperator_ == nullptr) {
72 return CAMERA_INVALID_STATE;
73 }
74 }
75 int32_t ret = AllocateCaptureId(curCaptureID_);
76 if (ret != CAMERA_OK) {
77 MEDIA_ERR_LOG("HStreamCapture::Capture Failed to allocate a captureId");
78 return ret;
79 }
80 CaptureInfo captureInfoPhoto;
81 captureInfoPhoto.streamIds_ = {streamId_};
82 std::vector<uint8_t> setting;
83 if (!OHOS::Camera::GetCameraMetadataItemCount(captureSettings->get())) {
84 std::lock_guard<std::mutex> lock(cameraAbilityLock_);
85 OHOS::Camera::MetadataUtils::ConvertMetadataToVec(cameraAbility_, setting);
86 captureInfoPhoto.captureSetting_ = setting;
87 } else {
88 OHOS::Camera::MetadataUtils::ConvertMetadataToVec(captureSettings, setting);
89 captureInfoPhoto.captureSetting_ = setting;
90 }
91 captureInfoPhoto.enableShutterCallback_ = true;
92
93 // debug log for jpeg quality
94 std::shared_ptr<OHOS::Camera::CameraMetadata> captureMetadataSetting_ = nullptr;
95 OHOS::Camera::MetadataUtils::ConvertVecToMetadata(captureInfoPhoto.captureSetting_, captureMetadataSetting_);
96 if (captureMetadataSetting_ != nullptr) {
97 // print quality, mirror log
98 PrintDebugLog(captureMetadataSetting_);
99 // convert rotation with application set rotation
100 SetRotation(captureMetadataSetting_);
101
102 // update settings
103 std::vector<uint8_t> finalSetting;
104 OHOS::Camera::MetadataUtils::ConvertMetadataToVec(captureMetadataSetting_, finalSetting);
105 captureInfoPhoto.captureSetting_ = finalSetting;
106 }
107 MEDIA_INFO_LOG("HStreamCapture::Capture Starting photo capture with capture ID: %{public}d", curCaptureID_);
108 CamRetCode rc;
109 {
110 std::lock_guard<std::mutex> lock(streamOperatorLock_);
111 rc = (CamRetCode)(streamOperator_->Capture(curCaptureID_, captureInfoPhoto, false));
112 }
113 if (rc != HDI::Camera::V1_0::NO_ERROR) {
114 MEDIA_ERR_LOG("HStreamCapture::Capture failed with error Code: %{public}d", rc);
115 ret = HdiToServiceError(rc);
116 }
117 ReleaseCaptureId(curCaptureID_);
118 curCaptureID_ = 0;
119 return ret;
120 }
121
PrintDebugLog(const std::shared_ptr<OHOS::Camera::CameraMetadata> & captureMetadataSetting_)122 void HStreamCapture::PrintDebugLog(const std::shared_ptr<OHOS::Camera::CameraMetadata> &captureMetadataSetting_)
123 {
124 camera_metadata_item_t item;
125 int result = OHOS::Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_JPEG_QUALITY, &item);
126 if (result != CAM_META_SUCCESS) {
127 MEDIA_DEBUG_LOG("HStreamCapture::Failed to find OHOS_JPEG_QUALITY tag");
128 } else {
129 MEDIA_DEBUG_LOG("HStreamCapture::find OHOS_JPEG_QUALITY value = %{public}d", item.data.u8[0]);
130 }
131
132 // debug log for capture mirror
133 result = OHOS::Camera::FindCameraMetadataItem(captureMetadataSetting_->get(),
134 OHOS_CONTROL_CAPTURE_MIRROR, &item);
135 if (result != CAM_META_SUCCESS) {
136 MEDIA_DEBUG_LOG("HStreamCapture::Failed to find OHOS_CONTROL_CAPTURE_MIRROR tag");
137 } else {
138 MEDIA_DEBUG_LOG("HStreamCapture::find OHOS_CONTROL_CAPTURE_MIRROR value = %{public}d", item.data.u8[0]);
139 }
140 }
141
SetRotation(const std::shared_ptr<OHOS::Camera::CameraMetadata> & captureMetadataSetting_)142 void HStreamCapture::SetRotation(const std::shared_ptr<OHOS::Camera::CameraMetadata> &captureMetadataSetting_)
143 {
144 // set orientation for capture
145 // sensor orientation, counter-clockwise rotation
146 int32_t sensorOrientation = 0;
147 int result;
148 camera_metadata_item_t item;
149 {
150 std::lock_guard<std::mutex> lock(cameraAbilityLock_);
151 if (cameraAbility_ == nullptr) {
152 return;
153 }
154 result = OHOS::Camera::FindCameraMetadataItem(cameraAbility_->get(), OHOS_SENSOR_ORIENTATION, &item);
155 if (result == CAM_META_SUCCESS && item.count > 0) {
156 sensorOrientation = item.data.i32[0];
157 }
158 MEDIA_INFO_LOG("set rotation sensor orientation %{public}d", sensorOrientation);
159
160 camera_position_enum_t cameraPosition = OHOS_CAMERA_POSITION_BACK;
161 result = OHOS::Camera::FindCameraMetadataItem(cameraAbility_->get(), OHOS_ABILITY_CAMERA_POSITION, &item);
162 if (result == CAM_META_SUCCESS && item.count > 0) {
163 cameraPosition = static_cast<camera_position_enum_t>(item.data.u8[0]);
164 }
165 MEDIA_INFO_LOG("set rotation camera position %{public}d", cameraPosition);
166 }
167
168 // rotation from application
169 int32_t rotationValue = 0;
170 result = OHOS::Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_JPEG_ORIENTATION, &item);
171 if (result == CAM_META_SUCCESS && item.count > 0) {
172 rotationValue = item.data.i32[0];
173 }
174 MEDIA_INFO_LOG("set rotation app rotationValue %{public}d", rotationValue);
175
176 // real rotation
177 int32_t rotation = sensorOrientation + rotationValue;
178 if (rotation >= CAPTURE_ROTATE_360) {
179 rotation = rotation - CAPTURE_ROTATE_360;
180 }
181 MEDIA_INFO_LOG("set rotation camera real rotation %{public}d", rotation);
182
183 bool status = false;
184 if (result == CAM_META_ITEM_NOT_FOUND) {
185 status = captureMetadataSetting_->addEntry(OHOS_JPEG_ORIENTATION, &rotation, 1);
186 } else if (result == CAM_META_SUCCESS) {
187 status = captureMetadataSetting_->updateEntry(OHOS_JPEG_ORIENTATION, &rotation, 1);
188 }
189 result = OHOS::Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_JPEG_ORIENTATION, &item);
190 if (result != CAM_META_SUCCESS) {
191 MEDIA_ERR_LOG("set rotation Failed to find OHOS_JPEG_ORIENTATION tag");
192 }
193 if (!status) {
194 MEDIA_ERR_LOG("set rotation Failed to set Rotation");
195 }
196 }
197
CancelCapture()198 int32_t HStreamCapture::CancelCapture()
199 {
200 // Cancel cature is dummy till continuous/burst mode is supported
201 return CAMERA_OK;
202 }
203
Release()204 int32_t HStreamCapture::Release()
205 {
206 if (curCaptureID_) {
207 ReleaseCaptureId(curCaptureID_);
208 }
209 std::lock_guard<std::mutex> lock(callbackLock_);
210 streamCaptureCallback_ = nullptr;
211 return HStreamCommon::Release();
212 }
213
SetCallback(sptr<IStreamCaptureCallback> & callback)214 int32_t HStreamCapture::SetCallback(sptr<IStreamCaptureCallback> &callback)
215 {
216 if (callback == nullptr) {
217 MEDIA_ERR_LOG("HStreamCapture::SetCallback callback is null");
218 return CAMERA_INVALID_ARG;
219 }
220 std::lock_guard<std::mutex> lock(callbackLock_);
221 streamCaptureCallback_ = callback;
222 return CAMERA_OK;
223 }
224
OnCaptureStarted(int32_t captureId)225 int32_t HStreamCapture::OnCaptureStarted(int32_t captureId)
226 {
227 CAMERA_SYNC_TRACE;
228 std::lock_guard<std::mutex> lock(callbackLock_);
229 if (streamCaptureCallback_ != nullptr) {
230 streamCaptureCallback_->OnCaptureStarted(captureId);
231 }
232 return CAMERA_OK;
233 }
234
OnCaptureEnded(int32_t captureId,int32_t frameCount)235 int32_t HStreamCapture::OnCaptureEnded(int32_t captureId, int32_t frameCount)
236 {
237 CAMERA_SYNC_TRACE;
238 std::lock_guard<std::mutex> lock(callbackLock_);
239 if (streamCaptureCallback_ != nullptr) {
240 streamCaptureCallback_->OnCaptureEnded(captureId, frameCount);
241 }
242 return CAMERA_OK;
243 }
244
OnCaptureError(int32_t captureId,int32_t errorCode)245 int32_t HStreamCapture::OnCaptureError(int32_t captureId, int32_t errorCode)
246 {
247 std::lock_guard<std::mutex> lock(callbackLock_);
248 if (streamCaptureCallback_ != nullptr) {
249 int32_t captureErrorCode;
250 if (errorCode == BUFFER_LOST) {
251 captureErrorCode = CAMERA_STREAM_BUFFER_LOST;
252 } else {
253 captureErrorCode = CAMERA_UNKNOWN_ERROR;
254 }
255 CAMERA_SYSEVENT_FAULT(CreateMsg("Photo OnCaptureError! captureId:%d & "
256 "errorCode:%{public}d", captureId, captureErrorCode));
257 streamCaptureCallback_->OnCaptureError(captureId, captureErrorCode);
258 }
259 return CAMERA_OK;
260 }
261
OnFrameShutter(int32_t captureId,uint64_t timestamp)262 int32_t HStreamCapture::OnFrameShutter(int32_t captureId, uint64_t timestamp)
263 {
264 CAMERA_SYNC_TRACE;
265 std::lock_guard<std::mutex> lock(callbackLock_);
266 if (streamCaptureCallback_ != nullptr) {
267 streamCaptureCallback_->OnFrameShutter(captureId, timestamp);
268 }
269 return CAMERA_OK;
270 }
271
DumpStreamInfo(std::string & dumpString)272 void HStreamCapture::DumpStreamInfo(std::string& dumpString)
273 {
274 dumpString += "capture stream:\n";
275 dumpString += "ThumbnailSwitch:[" + std::to_string(thumbnailSwitch_);
276 if (thumbnailBufferQueue_) {
277 dumpString += "] ThumbnailBuffer producer Id:["
278 + std::to_string(thumbnailBufferQueue_->producer_->GetUniqueId());
279 }
280 dumpString += "]\n";
281 HStreamCommon::DumpStreamInfo(dumpString);
282 }
283 } // namespace CameraStandard
284 } // namespace OHOS
285