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 #include <cstdint>
18 #include <uuid.h>
19 
20 #include "camera_log.h"
21 #include "camera_service_ipc_interface_code.h"
22 #include "camera_util.h"
23 #include "hstream_common.h"
24 #include "ipc_skeleton.h"
25 #include "metadata_utils.h"
26 #include "camera_report_uitls.h"
27 #include "camera_report_dfx_uitls.h"
28 
29 namespace OHOS {
30 namespace CameraStandard {
31 using namespace OHOS::HDI::Camera::V1_0;
32 static const int32_t CAPTURE_ROTATE_360 = 360;
33 static const std::string BURST_UUID_BEGIN = "";
34 static std::string g_currentBurstUuid = BURST_UUID_BEGIN;
35 
GenerateBurstUuid()36 static std::string GenerateBurstUuid()
37 {
38     MEDIA_INFO_LOG("HStreamCapture::GenerateBurstUuid");
39     uuid_t uuid;
40     char str[37] = {}; // UUIDs are 36 characters plus the null terminator
41     uuid_generate(uuid);
42     uuid_unparse(uuid, str); // Convert the UUID to a string
43     std::string burstUuid(str);
44     g_currentBurstUuid = burstUuid;
45     return burstUuid;
46 }
47 
HStreamCapture(sptr<OHOS::IBufferProducer> producer,int32_t format,int32_t width,int32_t height)48 HStreamCapture::HStreamCapture(sptr<OHOS::IBufferProducer> producer, int32_t format, int32_t width, int32_t height)
49     : HStreamCommon(StreamType::CAPTURE, producer, format, width, height)
50 {
51     MEDIA_INFO_LOG(
52         "HStreamCapture::HStreamCapture construct, format:%{public}d size:%{public}dx%{public}d streamId:%{public}d",
53         format, width, height, GetFwkStreamId());
54     thumbnailSwitch_ = 0;
55     rawDeliverySwitch_ = 0;
56     modeName_ = 0;
57     deferredPhotoSwitch_ = 0;
58     deferredVideoSwitch_ = 0;
59     burstNum_ = 0;
60 }
61 
~HStreamCapture()62 HStreamCapture::~HStreamCapture()
63 {
64     rotationMap_.Clear();
65     MEDIA_INFO_LOG(
66         "HStreamCapture::~HStreamCapture deconstruct, format:%{public}d size:%{public}dx%{public}d streamId:%{public}d",
67         format_, width_, height_, GetFwkStreamId());
68 }
69 
LinkInput(sptr<HDI::Camera::V1_0::IStreamOperator> streamOperator,std::shared_ptr<OHOS::Camera::CameraMetadata> cameraAbility)70 int32_t HStreamCapture::LinkInput(sptr<HDI::Camera::V1_0::IStreamOperator> streamOperator,
71     std::shared_ptr<OHOS::Camera::CameraMetadata> cameraAbility)
72 {
73     MEDIA_INFO_LOG("HStreamCapture::LinkInput streamId:%{public}d", GetFwkStreamId());
74     return HStreamCommon::LinkInput(streamOperator, cameraAbility);
75 }
76 
FullfillPictureExtendStreamInfos(StreamInfo_V1_1 & streamInfo,int32_t format)77 void HStreamCapture::FullfillPictureExtendStreamInfos(StreamInfo_V1_1 &streamInfo, int32_t format)
78 {
79     HDI::Camera::V1_1::ExtendedStreamInfo gainmapExtendedStreamInfo = {
80         .type = static_cast<HDI::Camera::V1_1::ExtendedStreamInfoType>(HDI::Camera::V1_3::EXTENDED_STREAM_INFO_GAINMAP),
81         .width = width_,
82         .height = height_,
83         .format = format,
84         .bufferQueue = gainmapBufferQueue_,
85     };
86     HDI::Camera::V1_1::ExtendedStreamInfo deepExtendedStreamInfo = {
87         .type = static_cast<HDI::Camera::V1_1::ExtendedStreamInfoType>(HDI::Camera::V1_3::EXTENDED_STREAM_INFO_DEPTH),
88         .width = width_,
89         .height = height_,
90         .format = format,
91         .bufferQueue = deepBufferQueue_,
92     };
93     HDI::Camera::V1_1::ExtendedStreamInfo exifExtendedStreamInfo = {
94         .type = static_cast<HDI::Camera::V1_1::ExtendedStreamInfoType>(HDI::Camera::V1_3::EXTENDED_STREAM_INFO_EXIF),
95         .width = width_,
96         .height = height_,
97         .format = format,
98         .bufferQueue = exifBufferQueue_,
99     };
100     HDI::Camera::V1_1::ExtendedStreamInfo debugExtendedStreamInfo = {
101         .type =
102             static_cast<HDI::Camera::V1_1::ExtendedStreamInfoType>(HDI::Camera::V1_3::EXTENDED_STREAM_INFO_MAKER_INFO),
103         .width = width_,
104         .height = height_,
105         .format = format,
106         .bufferQueue = debugBufferQueue_,
107     };
108     std::vector<HDI::Camera::V1_1::ExtendedStreamInfo> extendedStreams = { gainmapExtendedStreamInfo,
109         deepExtendedStreamInfo, exifExtendedStreamInfo, debugExtendedStreamInfo };
110     streamInfo.extendedStreamInfos.insert(streamInfo.extendedStreamInfos.end(),
111         extendedStreams.begin(), extendedStreams.end());
112 }
113 
SetStreamInfo(StreamInfo_V1_1 & streamInfo)114 void HStreamCapture::SetStreamInfo(StreamInfo_V1_1 &streamInfo)
115 {
116     HStreamCommon::SetStreamInfo(streamInfo);
117     streamInfo.v1_0.intent_ = STILL_CAPTURE;
118     if (format_ == OHOS_CAMERA_FORMAT_HEIC) {
119         streamInfo.v1_0.encodeType_ =
120             static_cast<HDI::Camera::V1_0::EncodeType>(HDI::Camera::V1_3::ENCODE_TYPE_HEIC);
121         streamInfo.v1_0.format_ = GRAPHIC_PIXEL_FMT_BLOB;
122     } else if (format_ == OHOS_CAMERA_FORMAT_YCRCB_420_SP) { // NV21
123         streamInfo.v1_0.encodeType_ = ENCODE_TYPE_NULL;
124         if (GetMode() == static_cast<int32_t>(HDI::Camera::V1_3::OperationMode::TIMELAPSE_PHOTO)) {
125             streamInfo.v1_0.format_ = GRAPHIC_PIXEL_FMT_YCRCB_420_SP; // NV21
126         } else {
127             streamInfo.v1_0.format_ = GRAPHIC_PIXEL_FMT_YCBCR_420_SP; // NV12
128             FullfillPictureExtendStreamInfos(streamInfo, GRAPHIC_PIXEL_FMT_YCBCR_420_SP);
129         }
130     } else {
131         streamInfo.v1_0.encodeType_ = ENCODE_TYPE_JPEG;
132     }
133     if (rawDeliverySwitch_) {
134         MEDIA_INFO_LOG("HStreamCapture::SetStreamInfo Set DNG info, streamId:%{public}d", GetFwkStreamId());
135         HDI::Camera::V1_1::ExtendedStreamInfo extendedStreamInfo = {
136             .type =
137                 static_cast<HDI::Camera::V1_1::ExtendedStreamInfoType>(HDI::Camera::V1_3::EXTENDED_STREAM_INFO_RAW),
138             .width = width_,
139             .height = height_,
140             .format = streamInfo.v1_0.format_,
141             .dataspace = 0,
142             .bufferQueue = rawBufferQueue_,
143         };
144         streamInfo.extendedStreamInfos.push_back(extendedStreamInfo);
145     }
146     if (thumbnailSwitch_) {
147         HDI::Camera::V1_1::ExtendedStreamInfo extendedStreamInfo = {
148             .type = HDI::Camera::V1_1::EXTENDED_STREAM_INFO_QUICK_THUMBNAIL,
149             .width = 0,
150             .height = 0,
151             .format = 0,
152             .dataspace = 0,
153             .bufferQueue = thumbnailBufferQueue_,
154         };
155         streamInfo.extendedStreamInfos.push_back(extendedStreamInfo);
156     }
157 }
158 
SetThumbnail(bool isEnabled,const sptr<OHOS::IBufferProducer> & producer)159 int32_t HStreamCapture::SetThumbnail(bool isEnabled, const sptr<OHOS::IBufferProducer> &producer)
160 {
161     if (isEnabled && producer != nullptr) {
162         thumbnailSwitch_ = 1;
163         thumbnailBufferQueue_ = new BufferProducerSequenceable(producer);
164     } else {
165         thumbnailSwitch_ = 0;
166         thumbnailBufferQueue_ = nullptr;
167     }
168     return CAMERA_OK;
169 }
170 
EnableRawDelivery(bool enabled)171 int32_t HStreamCapture::EnableRawDelivery(bool enabled)
172 {
173     if (enabled) {
174         rawDeliverySwitch_ = 1;
175     } else {
176         rawDeliverySwitch_ = 0;
177     }
178     return CAMERA_OK;
179 }
180 
SetBufferProducerInfo(const std::string bufName,const sptr<OHOS::IBufferProducer> & producer)181 int32_t HStreamCapture::SetBufferProducerInfo(const std::string bufName, const sptr<OHOS::IBufferProducer> &producer)
182 {
183     std::string resStr = "";
184     if (bufName == "rawImage") {
185         if (producer != nullptr) {
186             rawBufferQueue_ = new BufferProducerSequenceable(producer);
187         } else {
188             rawBufferQueue_ = nullptr;
189             resStr += bufName + ",";
190         }
191     }
192     if (bufName == "gainmapImage") {
193         if (producer != nullptr) {
194             gainmapBufferQueue_ = new BufferProducerSequenceable(producer);
195         } else {
196             gainmapBufferQueue_ = nullptr;
197             resStr += bufName + ",";
198         }
199     }
200     if (bufName == "deepImage") {
201         if (producer != nullptr) {
202             deepBufferQueue_ = new BufferProducerSequenceable(producer);
203         } else {
204             deepBufferQueue_ = nullptr;
205             resStr += bufName + ",";
206         }
207     }
208     if (bufName == "exifImage") {
209         if (producer != nullptr) {
210             exifBufferQueue_ = new BufferProducerSequenceable(producer);
211         } else {
212             exifBufferQueue_ = nullptr;
213             resStr += bufName + ",";
214         }
215     }
216     if (bufName == "debugImage") {
217         if (producer != nullptr) {
218             debugBufferQueue_ = new BufferProducerSequenceable(producer);
219         } else {
220             debugBufferQueue_ = nullptr;
221             resStr += bufName + ",";
222         }
223     }
224     MEDIA_INFO_LOG("HStreamCapture::SetBufferProducerInfo bufferQueue whether is nullptr: %{public}s", resStr.c_str());
225     return CAMERA_OK;
226 }
227 
DeferImageDeliveryFor(int32_t type)228 int32_t HStreamCapture::DeferImageDeliveryFor(int32_t type)
229 {
230     MEDIA_INFO_LOG("HStreamCapture::DeferImageDeliveryFor type: %{public}d", type);
231     if (type == OHOS::HDI::Camera::V1_2::STILL_IMAGE) {
232         MEDIA_INFO_LOG("HStreamCapture STILL_IMAGE");
233         deferredPhotoSwitch_ = 1;
234     } else if (type == OHOS::HDI::Camera::V1_2::MOVING_IMAGE) {
235         MEDIA_INFO_LOG("HStreamCapture MOVING_IMAGE");
236         deferredVideoSwitch_ = 1;
237     } else {
238         MEDIA_INFO_LOG("HStreamCapture NONE");
239         deferredPhotoSwitch_ = 0;
240         deferredVideoSwitch_ = 0;
241     }
242     return CAMERA_OK;
243 }
244 
PrepareBurst(int32_t captureId)245 int32_t HStreamCapture::PrepareBurst(int32_t captureId)
246 {
247     MEDIA_INFO_LOG("HStreamCapture::PrepareBurst captureId:%{public}d", captureId);
248     isBursting_ = true;
249     std::lock_guard<std::mutex> lock(burstLock_);
250     curBurstKey_ = GenerateBurstUuid();
251     burstkeyMap_.emplace(captureId, curBurstKey_);
252     std::vector<std::string> imageList = {};
253     burstImagesMap_.emplace(captureId, imageList);
254     burstNumMap_.emplace(captureId, 0);
255     burstNum_ = 0;
256     return CAMERA_OK;
257 }
258 
ResetBurst()259 void HStreamCapture::ResetBurst()
260 {
261     MEDIA_INFO_LOG("HStreamCapture::ResetBurst");
262     curBurstKey_ = BURST_UUID_UNSET;
263     isBursting_ = false;
264 }
265 
ResetBurstKey(int32_t captureId)266 void HStreamCapture::ResetBurstKey(int32_t captureId)
267 {
268     if (burstkeyMap_.erase(captureId) > 0 &&
269         burstImagesMap_.erase(captureId) > 0 &&
270         burstNumMap_.erase(captureId) > 0) {
271         MEDIA_INFO_LOG("HStreamCapture::ResetBurstKey captureId:%{public}d", captureId);
272     } else {
273         MEDIA_DEBUG_LOG("HStreamCapture::ResetBurstKey captureId not found");
274     }
275 }
276 
GetBurstKey(int32_t captureId) const277 std::string HStreamCapture::GetBurstKey(int32_t captureId) const
278 {
279     MEDIA_DEBUG_LOG("HStreamCapture::GetBurstKey captureId:%{public}d", captureId);
280     std::string burstKey = BURST_UUID_UNSET;
281     std::lock_guard<std::mutex> lock(burstLock_);
282     auto iter = burstkeyMap_.find(captureId);
283     if (iter != burstkeyMap_.end()) {
284         burstKey = iter->second;
285         MEDIA_DEBUG_LOG("HStreamCapture::GetBurstKey %{public}s", burstKey.c_str());
286     } else {
287         MEDIA_DEBUG_LOG("HStreamCapture::GetBurstKey not found");
288     }
289     return burstKey;
290 }
291 
IsBurstCapture(int32_t captureId) const292 bool HStreamCapture::IsBurstCapture(int32_t captureId) const
293 {
294     MEDIA_DEBUG_LOG("HStreamCapture::captureId:%{public}d", captureId);
295     auto iter = burstkeyMap_.find(captureId);
296     return iter != burstkeyMap_.end();
297 }
298 
IsBurstCover(int32_t captureId) const299 bool HStreamCapture::IsBurstCover(int32_t captureId) const
300 {
301     MEDIA_DEBUG_LOG("HStreamCapture::IsBurstCover for captureId: %d", captureId);
302     std::lock_guard<std::mutex> lock(burstLock_);
303     auto iter = burstImagesMap_.find(captureId);
304     return (iter != burstImagesMap_.end()) ? (iter->second.size() == 1) : false;
305 }
306 
GetCurBurstSeq(int32_t captureId) const307 int32_t HStreamCapture::GetCurBurstSeq(int32_t captureId) const
308 {
309     MEDIA_DEBUG_LOG("HStreamCapture::GetCurBurstSeq for captureId: %d", captureId);
310     std::lock_guard<std::mutex> lock(burstLock_);
311     auto iter = burstImagesMap_.find(captureId);
312     if (iter != burstImagesMap_.end()) {
313         return iter->second.size();
314     }
315     return -1;
316 }
317 
SetBurstImages(int32_t captureId,std::string imageId)318 void HStreamCapture::SetBurstImages(int32_t captureId, std::string imageId)
319 {
320     MEDIA_DEBUG_LOG("HStreamCapture::SetBurstImages captureId:%{public}d imageId:%{public}s",
321         captureId, imageId.c_str());
322     std::lock_guard<std::mutex> lock(burstLock_);
323     auto iter = burstImagesMap_.find(captureId);
324     if (iter != burstImagesMap_.end()) {
325         iter->second.emplace_back(imageId);
326         MEDIA_DEBUG_LOG("HStreamCapture::SetBurstImages success");
327     } else {
328         MEDIA_ERR_LOG("HStreamCapture::SetBurstImages error");
329     }
330 }
331 
CheckResetBurstKey(int32_t captureId)332 void HStreamCapture::CheckResetBurstKey(int32_t captureId)
333 {
334     MEDIA_DEBUG_LOG("HStreamCapture::CheckResetBurstKey captureId:%{public}d", captureId);
335     std::lock_guard<std::mutex> lock(burstLock_);
336     auto numIter = burstNumMap_.find(captureId);
337     auto imageIter = burstImagesMap_.find(captureId);
338     if (numIter != burstNumMap_.end() && imageIter != burstImagesMap_.end()) {
339         int32_t burstSum = numIter->second;
340         size_t curBurstSum = imageIter->second.size();
341         MEDIA_DEBUG_LOG("CheckResetBurstKey: burstSum=%d, curBurstSum=%zu", burstSum, curBurstSum);
342         if (static_cast<size_t>(burstSum) == curBurstSum) {
343             ResetBurstKey(captureId);
344         }
345     } else {
346         MEDIA_DEBUG_LOG("CheckResetBurstKey: captureId %d not found in one or both maps", captureId);
347     }
348 }
349 
350 
CheckBurstCapture(const std::shared_ptr<OHOS::Camera::CameraMetadata> & captureSettings,const int32_t & preparedCaptureId)351 int32_t HStreamCapture::CheckBurstCapture(const std::shared_ptr<OHOS::Camera::CameraMetadata>& captureSettings,
352                                           const int32_t &preparedCaptureId)
353 {
354     MEDIA_INFO_LOG("CheckBurstCapture start!");
355     camera_metadata_item_t item;
356     if (captureSettings == nullptr) {
357         MEDIA_ERR_LOG("captureSettings is nullptr");
358         return CAMERA_INVALID_STATE;
359     }
360     int32_t result = OHOS::Camera::FindCameraMetadataItem(captureSettings->get(), OHOS_CONTROL_BURST_CAPTURE, &item);
361     if (result == CAM_META_SUCCESS && item.count > 0) {
362         CameraBurstCaptureEnum burstState = static_cast<CameraBurstCaptureEnum>(item.data.u8[0]);
363         MEDIA_INFO_LOG("CheckBurstCapture get burstState:%{public}d", item.data.u8[0]);
364         if (burstState) {
365             std::string burstUuid = GetBurstKey(preparedCaptureId);
366             if (burstUuid != BURST_UUID_UNSET || isBursting_) {
367                 MEDIA_ERR_LOG("CheckBurstCapture faild!");
368                 return CAMERA_INVALID_STATE;
369             }
370             PrepareBurst(preparedCaptureId);
371             MEDIA_INFO_LOG("CheckBurstCapture ready!");
372         }
373     }
374     return CAM_META_SUCCESS;
375 }
376 
AcquireBufferToPrepareProxy(int32_t captureId)377 int32_t HStreamCapture::AcquireBufferToPrepareProxy(int32_t captureId)
378 {
379     MEDIA_DEBUG_LOG("HStreamCapture::AcquireBufferToPrepareProxy start");
380     CameraReportDfxUtils::GetInstance()->SetFirstBufferEndInfo(captureId);
381     CameraReportDfxUtils::GetInstance()->SetPrepareProxyStartInfo(captureId);
382     MEDIA_DEBUG_LOG("HStreamCapture::AcquireBufferToPrepareProxy end");
383     return CAMERA_OK;
384 }
385 
Capture(const std::shared_ptr<OHOS::Camera::CameraMetadata> & captureSettings)386 int32_t HStreamCapture::Capture(const std::shared_ptr<OHOS::Camera::CameraMetadata>& captureSettings)
387 {
388     CAMERA_SYNC_TRACE;
389     MEDIA_INFO_LOG("HStreamCapture::Capture Entry, streamId:%{public}d", GetFwkStreamId());
390     auto streamOperator = GetStreamOperator();
391     CHECK_AND_RETURN_RET(streamOperator != nullptr, CAMERA_INVALID_STATE);
392     CHECK_ERROR_RETURN_RET_LOG(isCaptureReady_ == false, CAMERA_OPERATION_NOT_ALLOWED,
393         "HStreamCapture::Capture failed due to capture not ready");
394     auto preparedCaptureId = GetPreparedCaptureId();
395     CHECK_ERROR_RETURN_RET_LOG(preparedCaptureId != CAPTURE_ID_UNSET, CAMERA_INVALID_STATE,
396         "HStreamCapture::Capture, Already started with captureID: %{public}d", preparedCaptureId);
397     int32_t ret = PrepareCaptureId();
398     preparedCaptureId = GetPreparedCaptureId();
399     CHECK_ERROR_RETURN_RET_LOG(ret != CAMERA_OK || preparedCaptureId == CAPTURE_ID_UNSET, ret,
400         "HStreamCapture::Capture Failed to allocate a captureId");
401     ret = CheckBurstCapture(captureSettings, preparedCaptureId);
402     CHECK_ERROR_RETURN_RET_LOG(ret != CAMERA_OK, ret, "HStreamCapture::Capture Failed with burst state error");
403 
404     CaptureDfxInfo captureDfxInfo;
405     captureDfxInfo.captureId = preparedCaptureId;
406     captureDfxInfo.isSystemApp = CheckSystemApp();
407     CameraReportDfxUtils::GetInstance()->SetFirstBufferStartInfo(captureDfxInfo);
408 
409     CaptureInfo captureInfoPhoto;
410     captureInfoPhoto.streamIds_ = { GetHdiStreamId() };
411     ProcessCaptureInfoPhoto(captureInfoPhoto, captureSettings, preparedCaptureId);
412     auto callingTokenId = IPCSkeleton::GetCallingTokenID();
413     const std::string permissionName = "ohos.permission.CAMERA";
414     AddCameraPermissionUsedRecord(callingTokenId, permissionName);
415 
416     // report capture performance dfx
417     std::shared_ptr<OHOS::Camera::CameraMetadata> captureMetadataSetting_ = nullptr;
418     OHOS::Camera::MetadataUtils::ConvertVecToMetadata(captureInfoPhoto.captureSetting_, captureMetadataSetting_);
419     if (captureMetadataSetting_ == nullptr) {
420         captureMetadataSetting_ = std::make_shared<OHOS::Camera::CameraMetadata>(0, 0);
421     }
422     DfxCaptureInfo captureInfo;
423     captureInfo.captureId = preparedCaptureId;
424     captureInfo.caller = CameraReportUtils::GetCallerInfo();
425     CameraReportUtils::GetInstance().SetCapturePerfStartInfo(captureInfo);
426     MEDIA_INFO_LOG("HStreamCapture::Capture Starting photo capture with capture ID: %{public}d", preparedCaptureId);
427     HStreamCommon::PrintCaptureDebugLog(captureMetadataSetting_);
428     CamRetCode rc = (CamRetCode)(streamOperator->Capture(preparedCaptureId, captureInfoPhoto, isBursting_));
429     if (rc != HDI::Camera::V1_0::NO_ERROR) {
430         ResetCaptureId();
431         captureIdForConfirmCapture_ = CAPTURE_ID_UNSET;
432         MEDIA_ERR_LOG("HStreamCapture::Capture failed with error Code: %{public}d", rc);
433         CameraReportUtils::ReportCameraError(
434             "HStreamCapture::Capture", rc, true, CameraReportUtils::GetCallerInfo());
435         ret = HdiToServiceError(rc);
436     }
437     camera_metadata_item_t item;
438     camera_position_enum_t cameraPosition = OHOS_CAMERA_POSITION_FRONT;
439     {
440         std::lock_guard<std::mutex> lock(cameraAbilityLock_);
441         if (cameraAbility_ == nullptr) {
442             MEDIA_ERR_LOG("HStreamCapture::cameraAbility_ is null");
443             return CAMERA_INVALID_STATE;
444         }
445         int32_t result = OHOS::Camera::FindCameraMetadataItem(cameraAbility_->get(), OHOS_ABILITY_CAMERA_POSITION,
446                                                               &item);
447         if (result == CAM_META_SUCCESS && item.count > 0) {
448             cameraPosition = static_cast<camera_position_enum_t>(item.data.u8[0]);
449         }
450     }
451 
452     int32_t NightMode = 4;
453     if (GetMode() == NightMode && cameraPosition == OHOS_CAMERA_POSITION_BACK) {
454         return ret;
455     }
456     ResetCaptureId();
457 
458     uint32_t major;
459     uint32_t minor;
460     streamOperator->GetVersion(major, minor);
461     MEDIA_INFO_LOG("streamOperator GetVersion major:%{public}d, minor:%{public}d", major, minor);
462     // intercept when streamOperatorCallback support onCaptureReady
463     if (major >= HDI_VERSION_1 && minor >= HDI_VERSION_2 && !isBursting_) {
464         MEDIA_INFO_LOG("HStreamCapture::Capture set capture not ready");
465         isCaptureReady_ = false;
466     }
467     return ret;
468 }
469 
ProcessCaptureInfoPhoto(CaptureInfo & captureInfoPhoto,const std::shared_ptr<OHOS::Camera::CameraMetadata> & captureSettings,int32_t captureId)470 void HStreamCapture::ProcessCaptureInfoPhoto(CaptureInfo& captureInfoPhoto,
471     const std::shared_ptr<OHOS::Camera::CameraMetadata>& captureSettings, int32_t captureId)
472 {
473     if (!OHOS::Camera::GetCameraMetadataItemCount(captureSettings->get())) {
474         std::lock_guard<std::mutex> lock(cameraAbilityLock_);
475         OHOS::Camera::MetadataUtils::ConvertMetadataToVec(cameraAbility_, captureInfoPhoto.captureSetting_);
476     } else {
477         OHOS::Camera::MetadataUtils::ConvertMetadataToVec(captureSettings, captureInfoPhoto.captureSetting_);
478     }
479     captureInfoPhoto.enableShutterCallback_ = true;
480     std::shared_ptr<OHOS::Camera::CameraMetadata> captureMetadataSetting_ = nullptr;
481     OHOS::Camera::MetadataUtils::ConvertVecToMetadata(captureInfoPhoto.captureSetting_, captureMetadataSetting_);
482     if (captureMetadataSetting_ == nullptr) {
483         captureMetadataSetting_ = std::make_shared<OHOS::Camera::CameraMetadata>(0, 0);
484     }
485     if (captureMetadataSetting_ != nullptr) {
486         // convert rotation with application set rotation
487         SetRotation(captureMetadataSetting_, captureId);
488 
489         // update settings
490         std::vector<uint8_t> finalSetting;
491         OHOS::Camera::MetadataUtils::ConvertMetadataToVec(captureMetadataSetting_, finalSetting);
492         captureInfoPhoto.captureSetting_ = finalSetting;
493     }
494 }
495 
SetRotation(const std::shared_ptr<OHOS::Camera::CameraMetadata> & captureMetadataSetting_,int32_t captureId)496 void HStreamCapture::SetRotation(const std::shared_ptr<OHOS::Camera::CameraMetadata> &captureMetadataSetting_,
497     int32_t captureId)
498 {
499     // set orientation for capture
500     // sensor orientation, counter-clockwise rotation
501     int32_t sensorOrientation = 0;
502     int result;
503     camera_metadata_item_t item;
504     {
505         std::lock_guard<std::mutex> lock(cameraAbilityLock_);
506         if (cameraAbility_ == nullptr) {
507             return;
508         }
509         result = OHOS::Camera::FindCameraMetadataItem(cameraAbility_->get(), OHOS_SENSOR_ORIENTATION, &item);
510         if (result == CAM_META_SUCCESS && item.count > 0) {
511             sensorOrientation = item.data.i32[0];
512         }
513         MEDIA_INFO_LOG("set rotation sensor orientation %{public}d", sensorOrientation);
514 
515         camera_position_enum_t cameraPosition = OHOS_CAMERA_POSITION_BACK;
516         result = OHOS::Camera::FindCameraMetadataItem(cameraAbility_->get(), OHOS_ABILITY_CAMERA_POSITION, &item);
517         if (result == CAM_META_SUCCESS && item.count > 0) {
518             cameraPosition = static_cast<camera_position_enum_t>(item.data.u8[0]);
519         }
520         MEDIA_INFO_LOG("set rotation camera position %{public}d", cameraPosition);
521     }
522 
523     // rotation from application
524     int32_t rotationValue = 0;
525     int32_t rotation = 0;
526     result = OHOS::Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_JPEG_ORIENTATION, &item);
527     if (result == CAM_META_SUCCESS && item.count > 0) {
528         rotationValue = item.data.i32[0];
529     }
530     MEDIA_INFO_LOG("set rotation app rotationValue %{public}d", rotationValue);
531     rotationMap_.EnsureInsert(captureId, rotationValue);
532     // real rotation
533     if (enableCameraPhotoRotation_) {
534         rotation = rotationValue;
535     } else {
536         rotation = sensorOrientation + rotationValue;
537         if (rotation >= CAPTURE_ROTATE_360) {
538             rotation = rotation - CAPTURE_ROTATE_360;
539         }
540     }
541     {
542         uint8_t connectType = 0;
543         std::lock_guard<std::mutex> lock(cameraAbilityLock_);
544         if (cameraAbility_ == nullptr) {
545             return;
546         }
547         int ret = OHOS::Camera::FindCameraMetadataItem(
548             cameraAbility_->get(), OHOS_ABILITY_CAMERA_CONNECTION_TYPE, &item);
549         if (ret == CAM_META_SUCCESS && item.count > 0) {
550             connectType = item.data.u8[0];
551         }
552         if (connectType == OHOS_CAMERA_CONNECTION_TYPE_REMOTE) {
553             rotation = rotationValue;
554         }
555         MEDIA_INFO_LOG("set rotation camera real rotation %{public}d", rotation);
556     }
557 
558     bool status = false;
559     if (result == CAM_META_ITEM_NOT_FOUND) {
560         status = captureMetadataSetting_->addEntry(OHOS_JPEG_ORIENTATION, &rotation, 1);
561     } else if (result == CAM_META_SUCCESS) {
562         status = captureMetadataSetting_->updateEntry(OHOS_JPEG_ORIENTATION, &rotation, 1);
563     }
564     result = OHOS::Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_JPEG_ORIENTATION, &item);
565     if (result != CAM_META_SUCCESS) {
566         MEDIA_ERR_LOG("set rotation Failed to find OHOS_JPEG_ORIENTATION tag");
567     }
568     CHECK_ERROR_PRINT_LOG(!status, "set rotation Failed to set Rotation");
569 }
570 
CancelCapture()571 int32_t HStreamCapture::CancelCapture()
572 {
573     CAMERA_SYNC_TRACE;
574     // Cancel capture is dummy till continuous/burst mode is supported
575     StopStream();
576     return CAMERA_OK;
577 }
578 
SetMode(int32_t modeName)579 void HStreamCapture::SetMode(int32_t modeName)
580 {
581     modeName_ = modeName;
582     MEDIA_INFO_LOG("HStreamCapture SetMode modeName = %{public}d", modeName);
583 }
584 
GetMode()585 int32_t HStreamCapture::GetMode()
586 {
587     MEDIA_INFO_LOG("HStreamCapture GetMode modeName = %{public}d", modeName_);
588     return modeName_;
589 }
590 
ConfirmCapture()591 int32_t HStreamCapture::ConfirmCapture()
592 {
593     CAMERA_SYNC_TRACE;
594     auto streamOperator = GetStreamOperator();
595     CHECK_ERROR_RETURN_RET(streamOperator == nullptr, CAMERA_INVALID_STATE);
596     int32_t ret = 0;
597 
598     // end burst capture
599     if (isBursting_) {
600         MEDIA_INFO_LOG("HStreamCapture::ConfirmCapture when burst capture");
601         std::vector<uint8_t> settingVector;
602         std::shared_ptr<OHOS::Camera::CameraMetadata> burstCaptureSettings = nullptr;
603         OHOS::Camera::MetadataUtils::ConvertMetadataToVec(cameraAbility_, settingVector);
604         OHOS::Camera::MetadataUtils::ConvertVecToMetadata(settingVector, burstCaptureSettings);
605         if (burstCaptureSettings == nullptr) {
606             burstCaptureSettings = std::make_shared<OHOS::Camera::CameraMetadata>(0, 0);
607         }
608         EndBurstCapture(burstCaptureSettings);
609         ret = Capture(burstCaptureSettings);
610         if (ret != CAMERA_OK) {
611             MEDIA_ERR_LOG("HStreamCapture::ConfirmCapture end burst faild!");
612         }
613         return ret;
614     }
615 
616     auto preparedCaptureId = captureIdForConfirmCapture_;
617     MEDIA_INFO_LOG("HStreamCapture::ConfirmCapture with capture ID: %{public}d", preparedCaptureId);
618     sptr<HDI::Camera::V1_2::IStreamOperator> streamOperatorV1_2 =
619         OHOS::HDI::Camera::V1_2::IStreamOperator::CastFrom(streamOperator);
620     CHECK_ERROR_RETURN_RET_LOG(streamOperatorV1_2 == nullptr, CAMERA_UNKNOWN_ERROR,
621         "HStreamCapture::ConfirmCapture streamOperatorV1_2 castFrom failed!");
622     OHOS::HDI::Camera::V1_2::CamRetCode rc =
623         (HDI::Camera::V1_2::CamRetCode)(streamOperatorV1_2->ConfirmCapture(preparedCaptureId));
624     if (rc != HDI::Camera::V1_2::NO_ERROR) {
625         MEDIA_ERR_LOG("HStreamCapture::ConfirmCapture failed with error Code: %{public}d", rc);
626         ret = HdiToServiceErrorV1_2(rc);
627     }
628     ResetCaptureId();
629     captureIdForConfirmCapture_ = CAPTURE_ID_UNSET;
630     return ret;
631 }
632 
EndBurstCapture(const std::shared_ptr<OHOS::Camera::CameraMetadata> & captureMetadataSetting)633 void HStreamCapture::EndBurstCapture(const std::shared_ptr<OHOS::Camera::CameraMetadata>& captureMetadataSetting)
634 {
635     CHECK_ERROR_RETURN(captureMetadataSetting == nullptr);
636     MEDIA_INFO_LOG("HStreamCapture::EndBurstCapture");
637     camera_metadata_item_t item;
638     bool status = false;
639     int result = OHOS::Camera::FindCameraMetadataItem(captureMetadataSetting->get(), OHOS_CONTROL_BURST_CAPTURE, &item);
640     uint8_t burstState = 0;
641     if (result == CAM_META_ITEM_NOT_FOUND) {
642         status = captureMetadataSetting->addEntry(OHOS_CONTROL_BURST_CAPTURE, &burstState, 1);
643     } else if (result == CAM_META_SUCCESS) {
644         status = captureMetadataSetting->updateEntry(OHOS_CONTROL_BURST_CAPTURE, &burstState, 1);
645     }
646 
647     if (!status) {
648         MEDIA_ERR_LOG("HStreamCapture::EndBurstCapture Failed");
649     }
650 }
651 
Release()652 int32_t HStreamCapture::Release()
653 {
654     return ReleaseStream(false);
655 }
656 
ReleaseStream(bool isDelay)657 int32_t HStreamCapture::ReleaseStream(bool isDelay)
658 {
659     {
660         std::lock_guard<std::mutex> lock(callbackLock_);
661         streamCaptureCallback_ = nullptr;
662     }
663     return HStreamCommon::ReleaseStream(isDelay);
664 }
665 
SetCallback(sptr<IStreamCaptureCallback> & callback)666 int32_t HStreamCapture::SetCallback(sptr<IStreamCaptureCallback> &callback)
667 {
668     CHECK_ERROR_RETURN_RET_LOG(callback == nullptr, CAMERA_INVALID_ARG, "HStreamCapture::SetCallback input is null");
669     std::lock_guard<std::mutex> lock(callbackLock_);
670     streamCaptureCallback_ = callback;
671     return CAMERA_OK;
672 }
673 
OnCaptureStarted(int32_t captureId)674 int32_t HStreamCapture::OnCaptureStarted(int32_t captureId)
675 {
676     CAMERA_SYNC_TRACE;
677     std::lock_guard<std::mutex> lock(callbackLock_);
678     if (streamCaptureCallback_ != nullptr) {
679         streamCaptureCallback_->OnCaptureStarted(captureId);
680     }
681     return CAMERA_OK;
682 }
683 
OnCaptureStarted(int32_t captureId,uint32_t exposureTime)684 int32_t HStreamCapture::OnCaptureStarted(int32_t captureId, uint32_t exposureTime)
685 {
686     CAMERA_SYNC_TRACE;
687     std::lock_guard<std::mutex> lock(callbackLock_);
688     if (streamCaptureCallback_ != nullptr) {
689         streamCaptureCallback_->OnCaptureStarted(captureId, exposureTime);
690     }
691     return CAMERA_OK;
692 }
693 
OnCaptureEnded(int32_t captureId,int32_t frameCount)694 int32_t HStreamCapture::OnCaptureEnded(int32_t captureId, int32_t frameCount)
695 {
696     CAMERA_SYNC_TRACE;
697     std::lock_guard<std::mutex> lock(callbackLock_);
698     if (streamCaptureCallback_ != nullptr) {
699         streamCaptureCallback_->OnCaptureEnded(captureId, frameCount);
700     }
701     CameraReportUtils::GetInstance().SetCapturePerfEndInfo(captureId);
702     auto preparedCaptureId = GetPreparedCaptureId();
703     if (preparedCaptureId != CAPTURE_ID_UNSET) {
704         MEDIA_INFO_LOG("HStreamCapture::OnCaptureEnded capturId = %{public}d already used, need release",
705                        preparedCaptureId);
706         ResetCaptureId();
707         captureIdForConfirmCapture_ = CAPTURE_ID_UNSET;
708     }
709     return CAMERA_OK;
710 }
711 
OnCaptureError(int32_t captureId,int32_t errorCode)712 int32_t HStreamCapture::OnCaptureError(int32_t captureId, int32_t errorCode)
713 {
714     std::lock_guard<std::mutex> lock(callbackLock_);
715     if (streamCaptureCallback_ != nullptr) {
716         int32_t captureErrorCode;
717         if (errorCode == BUFFER_LOST) {
718             captureErrorCode = CAMERA_STREAM_BUFFER_LOST;
719         } else {
720             captureErrorCode = CAMERA_UNKNOWN_ERROR;
721         }
722         CAMERA_SYSEVENT_FAULT(CreateMsg("Photo OnCaptureError! captureId:%d & "
723                                         "errorCode:%{public}d", captureId, captureErrorCode));
724         streamCaptureCallback_->OnCaptureError(captureId, captureErrorCode);
725     }
726     auto preparedCaptureId = GetPreparedCaptureId();
727     if (preparedCaptureId != CAPTURE_ID_UNSET) {
728         MEDIA_INFO_LOG("HStreamCapture::OnCaptureError capturId = %{public}d already used, need release",
729                        preparedCaptureId);
730         ResetCaptureId();
731         captureIdForConfirmCapture_ = CAPTURE_ID_UNSET;
732     }
733     return CAMERA_OK;
734 }
735 
OnFrameShutter(int32_t captureId,uint64_t timestamp)736 int32_t HStreamCapture::OnFrameShutter(int32_t captureId, uint64_t timestamp)
737 {
738     CAMERA_SYNC_TRACE;
739     std::lock_guard<std::mutex> lock(callbackLock_);
740     if (streamCaptureCallback_ != nullptr) {
741         streamCaptureCallback_->OnFrameShutter(captureId, timestamp);
742     }
743     return CAMERA_OK;
744 }
745 
OnFrameShutterEnd(int32_t captureId,uint64_t timestamp)746 int32_t HStreamCapture::OnFrameShutterEnd(int32_t captureId, uint64_t timestamp)
747 {
748     CAMERA_SYNC_TRACE;
749     std::lock_guard<std::mutex> lock(callbackLock_);
750     if (streamCaptureCallback_ != nullptr) {
751         streamCaptureCallback_->OnFrameShutterEnd(captureId, timestamp);
752     }
753     if (isBursting_) {
754         burstNum_++;
755         MEDIA_DEBUG_LOG("HStreamCapture::OnFrameShutterEnd burstNum:%{public}d", burstNum_);
756     }
757     return CAMERA_OK;
758 }
759 
760 
OnCaptureReady(int32_t captureId,uint64_t timestamp)761 int32_t HStreamCapture::OnCaptureReady(int32_t captureId, uint64_t timestamp)
762 {
763     CAMERA_SYNC_TRACE;
764     std::lock_guard<std::mutex> lock(callbackLock_);
765     MEDIA_INFO_LOG("HStreamCapture::Capture, notify OnCaptureReady with capture ID: %{public}d", captureId);
766     isCaptureReady_ = true;
767     if (streamCaptureCallback_ != nullptr) {
768         streamCaptureCallback_->OnCaptureReady(captureId, timestamp);
769     }
770     std::lock_guard<std::mutex> burstLock(burstLock_);
771     if (IsBurstCapture(captureId)) {
772         burstNumMap_[captureId] = burstNum_;
773         ResetBurst();
774     }
775     return CAMERA_OK;
776 }
777 
DumpStreamInfo(CameraInfoDumper & infoDumper)778 void HStreamCapture::DumpStreamInfo(CameraInfoDumper& infoDumper)
779 {
780     infoDumper.Title("capture stream");
781     infoDumper.Msg("ThumbnailSwitch:[" + std::to_string(thumbnailSwitch_) + "]");
782     infoDumper.Msg("RawDeliverSwitch:[" + std::to_string(rawDeliverySwitch_) + "]");
783     if (thumbnailBufferQueue_) {
784         infoDumper.Msg(
785             "ThumbnailBuffer producer Id:[" + std::to_string(thumbnailBufferQueue_->producer_->GetUniqueId()) + "]");
786     }
787     HStreamCommon::DumpStreamInfo(infoDumper);
788 }
789 
OperatePermissionCheck(uint32_t interfaceCode)790 int32_t HStreamCapture::OperatePermissionCheck(uint32_t interfaceCode)
791 {
792     switch (static_cast<StreamCaptureInterfaceCode>(interfaceCode)) {
793         case CAMERA_STREAM_CAPTURE_START: {
794             auto callerToken = IPCSkeleton::GetCallingTokenID();
795             if (callerToken_ != callerToken) {
796                 MEDIA_ERR_LOG("HStreamCapture::OperatePermissionCheck fail, callerToken not legal");
797                 return CAMERA_OPERATION_NOT_ALLOWED;
798             }
799             break;
800         }
801         default:
802             break;
803     }
804     return CAMERA_OK;
805 }
806 
IsDeferredPhotoEnabled()807 int32_t HStreamCapture::IsDeferredPhotoEnabled()
808 {
809     MEDIA_INFO_LOG("HStreamCapture IsDeferredPhotoEnabled  deferredPhotoSwitch_: %{public}d", deferredPhotoSwitch_);
810     if (deferredPhotoSwitch_ == 1) {
811         return 1;
812     }
813     MEDIA_INFO_LOG("HStreamCapture IsDeferredPhotoEnabled return 0");
814     return 0;
815 }
816 
IsDeferredVideoEnabled()817 int32_t HStreamCapture::IsDeferredVideoEnabled()
818 {
819     MEDIA_INFO_LOG("HStreamCapture IsDeferredVideoEnabled  deferredVideoSwitch_: %{public}d", deferredVideoSwitch_);
820     if (deferredVideoSwitch_ == 1) {
821         return 1;
822     }
823     return 0;
824 }
825 
GetMovingPhotoVideoCodecType()826 int32_t HStreamCapture::GetMovingPhotoVideoCodecType()
827 {
828     MEDIA_INFO_LOG("HStreamCapture GetMovingPhotoVideoCodecType videoCodecType_: %{public}d", videoCodecType_);
829     return videoCodecType_;
830 }
831 
SetMovingPhotoVideoCodecType(int32_t videoCodecType)832 int32_t HStreamCapture::SetMovingPhotoVideoCodecType(int32_t videoCodecType)
833 {
834     MEDIA_INFO_LOG("HStreamCapture SetMovingPhotoVideoCodecType videoCodecType_: %{public}d", videoCodecType);
835     videoCodecType_ = videoCodecType;
836     return 0;
837 }
838 
SetCameraPhotoRotation(bool isEnable)839 int32_t HStreamCapture::SetCameraPhotoRotation(bool isEnable)
840 {
841     enableCameraPhotoRotation_ = isEnable;
842     return 0;
843 }
844 } // namespace CameraStandard
845 } // namespace OHOS
846