• 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 "hcapture_session.h"
17 
18 #include <algorithm>
19 #include <atomic>
20 #include <cerrno>
21 #include <cinttypes>
22 #include <cstddef>
23 #include <cstdint>
24 #include <functional>
25 #include <mutex>
26 #include <new>
27 #include <sched.h>
28 #include <string>
29 #include <sync_fence.h>
30 #include <utility>
31 #include <vector>
32 
33 #include "avcodec_task_manager.h"
34 #include "blocking_queue.h"
35 #include "bundle_mgr_interface.h"
36 #include "camera_info_dumper.h"
37 #include "camera_log.h"
38 #include "camera_report_uitls.h"
39 #include "camera_server_photo_proxy.h"
40 #include "camera_service_ipc_interface_code.h"
41 #include "camera_util.h"
42 #include "datetime_ex.h"
43 #include "display/composer/v1_1/display_composer_type.h"
44 #include "display_manager.h"
45 #include "errors.h"
46 #include "hcamera_device_manager.h"
47 #include "hcamera_restore_param.h"
48 #include "hstream_capture.h"
49 #include "hstream_common.h"
50 #include "hstream_depth_data.h"
51 #include "hstream_metadata.h"
52 #include "hstream_repeat.h"
53 #include "icamera_util.h"
54 #include "icapture_session.h"
55 #include "iconsumer_surface.h"
56 #include "image_type.h"
57 #include "ipc_skeleton.h"
58 #include "iservice_registry.h"
59 #include "istream_common.h"
60 #include "media_library/photo_asset_interface.h"
61 #include "metadata_utils.h"
62 #include "moving_photo/moving_photo_surface_wrapper.h"
63 #include "moving_photo_video_cache.h"
64 #include "refbase.h"
65 #include "smooth_zoom.h"
66 #include "surface.h"
67 #include "surface_buffer.h"
68 #include "system_ability_definition.h"
69 #include "v1_0/types.h"
70 #include "deferred_processing_service.h"
71 #include "picture.h"
72 #include "camera_timer.h"
73 #include "fixed_size_list.h"
74 #include "camera_timer.h"
75 
76 using namespace OHOS::AAFwk;
77 namespace OHOS {
78 namespace CameraStandard {
79 using namespace OHOS::HDI::Display::Composer::V1_1;
80 std::shared_ptr<CameraDynamicLoader> HCaptureSession::dynamicLoader_ = std::make_shared<CameraDynamicLoader>();
81 std::optional<uint32_t> HCaptureSession::closeTimerId_ = std::nullopt;
82 std::mutex HCaptureSession::g_mediaTaskLock_;
83 
84 namespace {
85 static std::map<pid_t, sptr<HCaptureSession>> g_totalSessions;
86 static std::mutex g_totalSessionLock;
87 #ifdef CAMERA_USE_SENSOR
88 constexpr int32_t POSTURE_INTERVAL = 100000000; //100ms
89 constexpr int VALID_INCLINATION_ANGLE_THRESHOLD_COEFFICIENT = 3;
90 #endif
91 static GravityData gravityData = {0.0, 0.0, 0.0};
92 static int32_t sensorRotation = 0;
93 const char *CAMERA_BUNDLE_NAME = "com.huawei.hmos.camera";
TotalSessionSize()94 static size_t TotalSessionSize()
95 {
96     std::lock_guard<std::mutex> lock(g_totalSessionLock);
97     return g_totalSessions.size();
98 }
99 
TotalSessionsCopy()100 static const std::map<pid_t, sptr<HCaptureSession>> TotalSessionsCopy()
101 {
102     std::lock_guard<std::mutex> lock(g_totalSessionLock);
103     return g_totalSessions;
104 }
105 
TotalSessionsInsert(pid_t pid,sptr<HCaptureSession> session)106 static void TotalSessionsInsert(pid_t pid, sptr<HCaptureSession> session)
107 {
108     std::lock_guard<std::mutex> lock(g_totalSessionLock);
109     auto it = g_totalSessions.find(pid);
110     if (it != g_totalSessions.end()) {
111         MEDIA_ERR_LOG("HCaptureSession TotalSessionsInsert insert session but pid already exist!, memory leak may "
112                       "occurred, pid is:%{public}d",
113             pid);
114         it->second = session;
115         return;
116     }
117     g_totalSessions.emplace(pid, session);
118 }
119 
TotalSessionsGet(pid_t pid)120 static sptr<HCaptureSession> TotalSessionsGet(pid_t pid)
121 {
122     std::lock_guard<std::mutex> lock(g_totalSessionLock);
123     auto it = g_totalSessions.find(pid);
124     CHECK_AND_RETURN_RET(it == g_totalSessions.end(), it->second);
125     return nullptr;
126 }
127 
TotalSessionErase(pid_t pid)128 static void TotalSessionErase(pid_t pid)
129 {
130     std::lock_guard<std::mutex> lock(g_totalSessionLock);
131     g_totalSessions.erase(pid);
132 }
133 } // namespace
134 
135 static const std::map<CaptureSessionState, std::string> SESSION_STATE_STRING_MAP = {
136     {CaptureSessionState::SESSION_INIT, "Init"},
137     {CaptureSessionState::SESSION_CONFIG_INPROGRESS, "Config_In-progress"},
138     {CaptureSessionState::SESSION_CONFIG_COMMITTED, "Committed"},
139     {CaptureSessionState::SESSION_RELEASED, "Released"},
140     {CaptureSessionState::SESSION_STARTED, "Started"}
141 };
142 
NewInstance(const uint32_t callerToken,int32_t opMode)143 sptr<HCaptureSession> HCaptureSession::NewInstance(const uint32_t callerToken, int32_t opMode)
144 {
145     sptr<HCaptureSession> session = new HCaptureSession();
146     CHECK_AND_RETURN_RET(session->Initialize(callerToken, opMode) != CAMERA_OK, session);
147     return nullptr;
148 }
149 
Initialize(const uint32_t callerToken,int32_t opMode)150 int32_t HCaptureSession::Initialize(const uint32_t callerToken, int32_t opMode)
151 {
152     pid_ = IPCSkeleton::GetCallingPid();
153     uid_ = static_cast<uint32_t>(IPCSkeleton::GetCallingUid());
154     MEDIA_DEBUG_LOG("HCaptureSession: camera stub services(%{public}zu) pid(%{public}d).", TotalSessionSize(), pid_);
155     auto pidSession = TotalSessionsGet(pid_);
156     if (pidSession != nullptr) {
157         auto disconnectDevice = pidSession->GetCameraDevice();
158         if (disconnectDevice != nullptr) {
159             disconnectDevice->OnError(HDI::Camera::V1_0::DEVICE_PREEMPT, 0);
160         }
161         MEDIA_ERR_LOG("HCaptureSession::HCaptureSession doesn't support multiple sessions per pid");
162         pidSession->Release();
163     }
164     TotalSessionsInsert(pid_, this);
165     callerToken_ = callerToken;
166     opMode_ = opMode;
167     featureMode_ = 0;
168     CameraReportUtils::GetInstance().updateModeChangePerfInfo(opMode, CameraReportUtils::GetCallerInfo());
169     MEDIA_INFO_LOG(
170         "HCaptureSession: camera stub services(%{public}zu). opMode_= %{public}d", TotalSessionSize(), opMode_);
171     return CAMERA_OK;
172 }
173 
HCaptureSession()174 HCaptureSession::HCaptureSession()
175 {
176     pid_ = 0;
177     uid_ = 0;
178     callerToken_ = 0;
179     opMode_ = 0;
180     featureMode_ = 0;
181 }
182 
HCaptureSession(const uint32_t callingTokenId,int32_t opMode)183 HCaptureSession::HCaptureSession(const uint32_t callingTokenId, int32_t opMode)
184 {
185     Initialize(callingTokenId, opMode);
186 }
187 
~HCaptureSession()188 HCaptureSession::~HCaptureSession()
189 {
190     CAMERA_SYNC_TRACE;
191     Release(CaptureSessionReleaseType::RELEASE_TYPE_OBJ_DIED);
192     if (displayListener_) {
193         OHOS::Rosen::DisplayManager::GetInstance().UnregisterDisplayListener(displayListener_);
194         displayListener_ = nullptr;
195     }
196 }
197 
GetPid()198 pid_t HCaptureSession::GetPid()
199 {
200     return pid_;
201 }
202 
GetopMode()203 int32_t HCaptureSession::GetopMode()
204 {
205     CHECK_AND_RETURN_RET(!featureMode_, featureMode_);
206     return opMode_;
207 }
208 
GetCurrentStreamInfos(std::vector<StreamInfo_V1_1> & streamInfos)209 int32_t HCaptureSession::GetCurrentStreamInfos(std::vector<StreamInfo_V1_1>& streamInfos)
210 {
211     auto streams = streamContainer_.GetAllStreams();
212     for (auto& stream : streams) {
213         if (stream) {
214             StreamInfo_V1_1 curStreamInfo;
215             stream->SetStreamInfo(curStreamInfo);
216             if (stream->GetStreamType() != StreamType::METADATA) {
217                 streamInfos.push_back(curStreamInfo);
218             }
219         }
220     }
221     return CAMERA_OK;
222 }
223 
DynamicConfigStream()224 void HCaptureSession::DynamicConfigStream()
225 {
226     isDynamicConfiged_ = false;
227     MEDIA_INFO_LOG("HCaptureSession::DynamicConfigStream enter. currentState = %{public}s",
228         GetSessionState().c_str());
229     auto currentState = stateMachine_.GetCurrentState();
230     if (currentState == CaptureSessionState::SESSION_STARTED) {
231         std::string bundleName = GetClientBundle(IPCSkeleton::GetCallingUid());
232         isDynamicConfiged_ = (bundleName == CAMERA_BUNDLE_NAME);
233         MEDIA_INFO_LOG("HCaptureSession::DynamicConfigStream support dynamic stream config");
234     }
235 }
236 
IsNeedDynamicConfig()237 bool HCaptureSession::IsNeedDynamicConfig()
238 {
239     return isDynamicConfiged_;
240 }
241 
BeginConfig()242 int32_t HCaptureSession::BeginConfig()
243 {
244     CAMERA_SYNC_TRACE;
245     int32_t errCode;
246     MEDIA_INFO_LOG("HCaptureSession::BeginConfig prepare execute");
247     stateMachine_.StateGuard([&errCode, this](const CaptureSessionState state) {
248         DynamicConfigStream();
249         bool isStateValid = stateMachine_.Transfer(CaptureSessionState::SESSION_CONFIG_INPROGRESS);
250         if (!isStateValid) {
251             MEDIA_ERR_LOG("HCaptureSession::BeginConfig in invalid state %{public}d", state);
252             errCode = CAMERA_INVALID_STATE;
253             isDynamicConfiged_ = false;
254             return;
255         }
256         if (!IsNeedDynamicConfig()) {
257             UnlinkInputAndOutputs();
258             ClearSketchRepeatStream();
259             ClearMovingPhotoRepeatStream();
260         }
261     });
262     if (errCode == CAMERA_OK) {
263         MEDIA_INFO_LOG("HCaptureSession::BeginConfig execute success");
264     } else {
265         CameraReportUtils::ReportCameraError(
266             "HCaptureSession::BeginConfig", errCode, false, CameraReportUtils::GetCallerInfo());
267     }
268     return errCode;
269 }
270 
CanAddInput(sptr<ICameraDeviceService> cameraDevice,bool & result)271 int32_t HCaptureSession::CanAddInput(sptr<ICameraDeviceService> cameraDevice, bool& result)
272 {
273     CAMERA_SYNC_TRACE;
274     int32_t errorCode = CAMERA_OK;
275     result = false;
276     stateMachine_.StateGuard([this, &errorCode](const CaptureSessionState currentState) {
277         if (currentState != CaptureSessionState::SESSION_CONFIG_INPROGRESS) {
278             MEDIA_ERR_LOG("HCaptureSession::CanAddInput Need to call BeginConfig before adding input");
279             errorCode = CAMERA_INVALID_STATE;
280             return;
281         }
282         if ((GetCameraDevice() != nullptr)) {
283             MEDIA_ERR_LOG("HCaptureSession::CanAddInput Only one input is supported");
284             errorCode = CAMERA_INVALID_SESSION_CFG;
285             return;
286         }
287     });
288     if (errorCode == CAMERA_OK) {
289         result = true;
290         CAMERA_SYSEVENT_STATISTIC(CreateMsg("CaptureSession::CanAddInput"));
291     }
292     return errorCode;
293 }
294 
AddInput(sptr<ICameraDeviceService> cameraDevice)295 int32_t HCaptureSession::AddInput(sptr<ICameraDeviceService> cameraDevice)
296 {
297     CAMERA_SYNC_TRACE;
298     int32_t errorCode = CAMERA_OK;
299     if (cameraDevice == nullptr) {
300         errorCode = CAMERA_INVALID_ARG;
301         MEDIA_ERR_LOG("HCaptureSession::AddInput cameraDevice is null");
302         CameraReportUtils::ReportCameraError(
303             "HCaptureSession::AddInput", errorCode, false, CameraReportUtils::GetCallerInfo());
304         return errorCode;
305     }
306     MEDIA_INFO_LOG("HCaptureSession::AddInput prepare execute");
307     stateMachine_.StateGuard([this, &errorCode, &cameraDevice](const CaptureSessionState currentState) {
308         if (currentState != CaptureSessionState::SESSION_CONFIG_INPROGRESS) {
309             MEDIA_ERR_LOG("HCaptureSession::AddInput Need to call BeginConfig before adding input");
310             errorCode = CAMERA_INVALID_STATE;
311             return;
312         }
313         if ((GetCameraDevice() != nullptr)) {
314             MEDIA_ERR_LOG("HCaptureSession::AddInput Only one input is supported");
315             errorCode = CAMERA_INVALID_SESSION_CFG;
316             return;
317         }
318         sptr<HCameraDevice> hCameraDevice = static_cast<HCameraDevice*>(cameraDevice.GetRefPtr());
319         MEDIA_INFO_LOG("HCaptureSession::AddInput device:%{public}s", hCameraDevice->GetCameraId().c_str());
320         hCameraDevice->SetStreamOperatorCallback(this);
321         SetCameraDevice(hCameraDevice);
322         hCameraDevice->DispatchDefaultSettingToHdi();
323     });
324     if (errorCode == CAMERA_OK) {
325         CAMERA_SYSEVENT_STATISTIC(CreateMsg("CaptureSession::AddInput"));
326     } else {
327         CameraReportUtils::ReportCameraError(
328             "HCaptureSession::AddInput", errorCode, false, CameraReportUtils::GetCallerInfo());
329     }
330     MEDIA_INFO_LOG("HCaptureSession::AddInput execute success");
331     return errorCode;
332 }
333 
AddOutputStream(sptr<HStreamCommon> stream)334 int32_t HCaptureSession::AddOutputStream(sptr<HStreamCommon> stream)
335 {
336     CAMERA_SYNC_TRACE;
337     CHECK_ERROR_RETURN_RET_LOG(stream == nullptr, CAMERA_INVALID_ARG,
338         "HCaptureSession::AddOutputStream stream is null");
339     MEDIA_INFO_LOG("HCaptureSession::AddOutputStream streamId:%{public}d streamType:%{public}d",
340         stream->GetFwkStreamId(), stream->GetStreamType());
341     CHECK_ERROR_RETURN_RET_LOG(
342         stream->GetFwkStreamId() == STREAM_ID_UNSET && stream->GetStreamType() != StreamType::METADATA,
343         CAMERA_INVALID_ARG, "HCaptureSession::AddOutputStream stream is released!");
344     bool isAddSuccess = streamContainer_.AddStream(stream);
345     CHECK_ERROR_RETURN_RET_LOG(!isAddSuccess, CAMERA_INVALID_SESSION_CFG,
346         "HCaptureSession::AddOutputStream add stream fail");
347     if (stream->GetStreamType() == StreamType::CAPTURE) {
348         auto captureStream = CastStream<HStreamCapture>(stream);
349         captureStream->SetMode(opMode_);
350         captureStream->SetColorSpace(currCaptureColorSpace_);
351         HCaptureSession::OpenMediaLib();
352     } else {
353         stream->SetColorSpace(currColorSpace_);
354     }
355     return CAMERA_OK;
356 }
357 
OpenMediaLib()358 void HCaptureSession::OpenMediaLib()
359 {
360     std::lock_guard<std::mutex> lock(g_mediaTaskLock_);
361     if (closeTimerId_.has_value()) {
362         CameraTimer::GetInstance().Unregister(closeTimerId_.value());
363         closeTimerId_.reset();
364     }
365     CameraTimer::GetInstance().Register([&] { dynamicLoader_->OpenDynamicHandle(MEDIA_LIB_SO); }, 0, true);
366 }
367 
StartMovingPhotoStream()368 void HCaptureSession::StartMovingPhotoStream()
369 {
370     int32_t errorCode = 0;
371     stateMachine_.StateGuard([&errorCode, this](CaptureSessionState currentState) {
372         if (currentState != CaptureSessionState::SESSION_STARTED) {
373             MEDIA_ERR_LOG("EnableMovingPhoto, invalid session state: %{public}d, start after preview", currentState);
374             errorCode = CAMERA_INVALID_STATE;
375             return;
376         }
377         auto repeatStreams = streamContainer_.GetStreams(StreamType::REPEAT);
378         bool isPreviewStarted = false;
379         for (auto& item : repeatStreams) {
380             auto curStreamRepeat = CastStream<HStreamRepeat>(item);
381             auto repeatType = curStreamRepeat->GetRepeatStreamType();
382             if (repeatType != RepeatStreamType::PREVIEW) {
383                 continue;
384             }
385             if (curStreamRepeat->GetPreparedCaptureId() != CAPTURE_ID_UNSET && curStreamRepeat->producer_ != nullptr) {
386                 isPreviewStarted = true;
387                 break;
388             }
389         }
390         CHECK_ERROR_RETURN_LOG(!isPreviewStarted, "EnableMovingPhoto, preview is not streaming");
391         std::shared_ptr<OHOS::Camera::CameraMetadata> settings = nullptr;
392         auto cameraDevice = GetCameraDevice();
393         if (cameraDevice != nullptr) {
394             settings = cameraDevice->CloneCachedSettings();
395             DumpMetadata(settings);
396         }
397         for (auto& item : repeatStreams) {
398             auto curStreamRepeat = CastStream<HStreamRepeat>(item);
399             auto repeatType = curStreamRepeat->GetRepeatStreamType();
400             if (repeatType != RepeatStreamType::LIVEPHOTO) {
401                 continue;
402             }
403             if (isSetMotionPhoto_) {
404                 errorCode = curStreamRepeat->Start(settings);
405                 #ifdef MOVING_PHOTO_ADD_AUDIO
406                 std::lock_guard<std::mutex> lock(movingPhotoStatusLock_);
407                 audioCapturerSession_ != nullptr && audioCapturerSession_->StartAudioCapture();
408                 #endif
409             } else {
410                 errorCode = curStreamRepeat->Stop();
411                 StopMovingPhoto();
412             }
413             break;
414         }
415     });
416     MEDIA_INFO_LOG("HCaptureSession::StartMovingPhotoStream result:%{public}d", errorCode);
417 }
418 
419 class DisplayRotationListener : public OHOS::Rosen::DisplayManager::IDisplayListener {
420 public:
DisplayRotationListener()421     explicit DisplayRotationListener() {};
422     virtual ~DisplayRotationListener() = default;
OnCreate(OHOS::Rosen::DisplayId)423     void OnCreate(OHOS::Rosen::DisplayId) override {}
OnDestroy(OHOS::Rosen::DisplayId)424     void OnDestroy(OHOS::Rosen::DisplayId) override {}
OnChange(OHOS::Rosen::DisplayId displayId)425     void OnChange(OHOS::Rosen::DisplayId displayId) override
426     {
427         sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
428         if (display == nullptr) {
429             MEDIA_INFO_LOG("Get display info failed, display:%{public}" PRIu64"", displayId);
430             display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
431             CHECK_ERROR_RETURN_LOG(display == nullptr, "Get display info failed, display is nullptr");
432         }
433         {
434             Rosen::Rotation currentRotation = display->GetRotation();
435             std::lock_guard<std::mutex> lock(mStreamManagerLock_);
436             for (auto& repeatStream : repeatStreamList_) {
437                 if (repeatStream) {
438                     repeatStream->SetStreamTransform(static_cast<int>(currentRotation));
439                 }
440             }
441         }
442     }
443 
AddHstreamRepeatForListener(sptr<HStreamRepeat> repeatStream)444     void AddHstreamRepeatForListener(sptr<HStreamRepeat> repeatStream)
445     {
446         std::lock_guard<std::mutex> lock(mStreamManagerLock_);
447         if (repeatStream) {
448             repeatStreamList_.push_back(repeatStream);
449         }
450     }
451 
RemoveHstreamRepeatForListener(sptr<HStreamRepeat> repeatStream)452     void RemoveHstreamRepeatForListener(sptr<HStreamRepeat> repeatStream)
453     {
454         std::lock_guard<std::mutex> lock(mStreamManagerLock_);
455         if (repeatStream) {
456             repeatStreamList_.erase(std::remove(repeatStreamList_.begin(), repeatStreamList_.end(), repeatStream),
457                 repeatStreamList_.end());
458         }
459     }
460 
461 public:
462     std::list<sptr<HStreamRepeat>> repeatStreamList_;
463     std::mutex mStreamManagerLock_;
464 };
465 
RegisterDisplayListener(sptr<HStreamRepeat> repeat)466 void HCaptureSession::RegisterDisplayListener(sptr<HStreamRepeat> repeat)
467 {
468     if (displayListener_ == nullptr) {
469         displayListener_ = new DisplayRotationListener();
470         OHOS::Rosen::DisplayManager::GetInstance().RegisterDisplayListener(displayListener_);
471     }
472     displayListener_->AddHstreamRepeatForListener(repeat);
473 }
474 
UnRegisterDisplayListener(sptr<HStreamRepeat> repeatStream)475 void HCaptureSession::UnRegisterDisplayListener(sptr<HStreamRepeat> repeatStream)
476 {
477     if (displayListener_) {
478         displayListener_->RemoveHstreamRepeatForListener(repeatStream);
479     }
480 }
481 
SetPreviewRotation(std::string & deviceClass)482 int32_t HCaptureSession::SetPreviewRotation(std::string &deviceClass)
483 {
484     enableStreamRotate_ = true;
485     deviceClass_ = deviceClass;
486     return CAMERA_OK;
487 }
488 
AddOutput(StreamType streamType,sptr<IStreamCommon> stream)489 int32_t HCaptureSession::AddOutput(StreamType streamType, sptr<IStreamCommon> stream)
490 {
491     int32_t errorCode = CAMERA_INVALID_ARG;
492     if (stream == nullptr) {
493         MEDIA_ERR_LOG("HCaptureSession::AddOutput stream is null");
494         CameraReportUtils::ReportCameraError(
495             "HCaptureSession::AddOutput", errorCode, false, CameraReportUtils::GetCallerInfo());
496         return errorCode;
497     }
498     stateMachine_.StateGuard([this, &errorCode, streamType, &stream](const CaptureSessionState currentState) {
499         if (currentState != CaptureSessionState::SESSION_CONFIG_INPROGRESS) {
500             MEDIA_ERR_LOG("HCaptureSession::AddOutput Need to call BeginConfig before adding output");
501             errorCode = CAMERA_INVALID_STATE;
502             return;
503         }
504         // Temp hack to fix the library linking issue
505         sptr<IConsumerSurface> captureSurface = IConsumerSurface::Create();
506         if (streamType == StreamType::CAPTURE) {
507             errorCode = AddOutputStream(static_cast<HStreamCapture*>(stream.GetRefPtr()));
508         } else if (streamType == StreamType::REPEAT) {
509             HStreamRepeat* repeatSteam = static_cast<HStreamRepeat*>(stream.GetRefPtr());
510             if (enableStreamRotate_ && repeatSteam != nullptr &&
511                 repeatSteam->GetRepeatStreamType() == RepeatStreamType::PREVIEW) {
512                 RegisterDisplayListener(repeatSteam);
513                 repeatSteam->SetPreviewRotation(deviceClass_);
514             }
515             errorCode = AddOutputStream(repeatSteam);
516         } else if (streamType == StreamType::METADATA) {
517             errorCode = AddOutputStream(static_cast<HStreamMetadata*>(stream.GetRefPtr()));
518         } else if (streamType == StreamType::DEPTH) {
519             errorCode = AddOutputStream(static_cast<HStreamDepthData*>(stream.GetRefPtr()));
520         }
521     });
522     if (errorCode == CAMERA_OK) {
523         CAMERA_SYSEVENT_STATISTIC(CreateMsg("CaptureSession::AddOutput with %d", streamType));
524     } else {
525         CameraReportUtils::ReportCameraError(
526             "HCaptureSession::AddOutput", errorCode, false, CameraReportUtils::GetCallerInfo());
527     }
528     MEDIA_INFO_LOG("CaptureSession::AddOutput with with %{public}d, rc = %{public}d", streamType, errorCode);
529     return errorCode;
530 }
531 
RemoveInput(sptr<ICameraDeviceService> cameraDevice)532 int32_t HCaptureSession::RemoveInput(sptr<ICameraDeviceService> cameraDevice)
533 {
534     int32_t errorCode = CAMERA_OK;
535     if (cameraDevice == nullptr) {
536         errorCode = CAMERA_INVALID_ARG;
537         MEDIA_ERR_LOG("HCaptureSession::RemoveInput cameraDevice is null");
538         CameraReportUtils::ReportCameraError(
539             "HCaptureSession::RemoveInput", errorCode, false, CameraReportUtils::GetCallerInfo());
540         return errorCode;
541     }
542     MEDIA_INFO_LOG("HCaptureSession::RemoveInput prepare execute");
543     stateMachine_.StateGuard([this, &errorCode, &cameraDevice](const CaptureSessionState currentState) {
544         if (currentState != CaptureSessionState::SESSION_CONFIG_INPROGRESS) {
545             MEDIA_ERR_LOG("HCaptureSession::RemoveInput Need to call BeginConfig before removing input");
546             errorCode = CAMERA_INVALID_STATE;
547             return;
548         }
549         if (IsNeedDynamicConfig()) {
550             UnlinkInputAndOutputs();
551             ClearSketchRepeatStream();
552             ClearMovingPhotoRepeatStream();
553         }
554         auto currentDevice = GetCameraDevice();
555         if (currentDevice != nullptr && cameraDevice->AsObject() == currentDevice->AsObject()) {
556             // Do not close device while remove input!
557             MEDIA_INFO_LOG(
558                 "HCaptureSession::RemoveInput camera id is %{public}s", currentDevice->GetCameraId().c_str());
559             currentDevice->ResetDeviceSettings();
560             SetCameraDevice(nullptr);
561         } else {
562             MEDIA_ERR_LOG("HCaptureSession::RemoveInput Invalid camera device");
563             errorCode = CAMERA_INVALID_SESSION_CFG;
564         }
565     });
566     if (errorCode == CAMERA_OK) {
567         CAMERA_SYSEVENT_STATISTIC(CreateMsg("CaptureSession::RemoveInput"));
568     } else {
569         CameraReportUtils::ReportCameraError(
570             "HCaptureSession::RemoveInput", errorCode, false, CameraReportUtils::GetCallerInfo());
571     }
572     MEDIA_INFO_LOG("HCaptureSession::RemoveInput execute success");
573     return errorCode;
574 }
575 
RemoveOutputStream(sptr<HStreamCommon> stream)576 int32_t HCaptureSession::RemoveOutputStream(sptr<HStreamCommon> stream)
577 {
578     CAMERA_SYNC_TRACE;
579     CHECK_ERROR_RETURN_RET_LOG(stream == nullptr, CAMERA_INVALID_ARG,
580         "HCaptureSession::RemoveOutputStream stream is null");
581     MEDIA_INFO_LOG("HCaptureSession::RemoveOutputStream,streamType:%{public}d, streamId:%{public}d",
582         stream->GetStreamType(), stream->GetFwkStreamId());
583     bool isRemoveSuccess = streamContainer_.RemoveStream(stream);
584     CHECK_ERROR_RETURN_RET_LOG(!isRemoveSuccess, CAMERA_INVALID_SESSION_CFG,
585         "HCaptureSession::RemoveOutputStream Invalid output");
586     return CAMERA_OK;
587 }
588 
DelayCloseMediaLib()589 void HCaptureSession::DelayCloseMediaLib()
590 {
591     std::lock_guard<std::mutex> lock(g_mediaTaskLock_);
592     constexpr uint32_t waitMs = 30 * 1000;
593     if (closeTimerId_.has_value()) {
594         CameraTimer::GetInstance().Unregister(closeTimerId_.value());
595         MEDIA_INFO_LOG("delete closeDynamicHandle task id: %{public}d", closeTimerId_.value());
596     }
597     closeTimerId_ = CameraTimer::GetInstance().Register([]() {
598         dynamicLoader_->CloseDynamicHandle(MEDIA_LIB_SO);
599     }, waitMs, true);
600     MEDIA_INFO_LOG("create closeDynamicHandle task id: %{public}d", closeTimerId_.value());
601 }
602 
RemoveOutput(StreamType streamType,sptr<IStreamCommon> stream)603 int32_t HCaptureSession::RemoveOutput(StreamType streamType, sptr<IStreamCommon> stream)
604 {
605     int32_t errorCode = CAMERA_INVALID_ARG;
606     if (stream == nullptr) {
607         MEDIA_ERR_LOG("HCaptureSession::RemoveOutput stream is null");
608         CameraReportUtils::ReportCameraError(
609             "HCaptureSession::RemoveOutput", errorCode, false, CameraReportUtils::GetCallerInfo());
610         return errorCode;
611     }
612     MEDIA_INFO_LOG("HCaptureSession::RemoveOutput prepare execute");
613     stateMachine_.StateGuard([this, &errorCode, streamType, &stream](const CaptureSessionState currentState) {
614         if (currentState != CaptureSessionState::SESSION_CONFIG_INPROGRESS) {
615             MEDIA_ERR_LOG("HCaptureSession::RemoveOutput Need to call BeginConfig before removing output");
616             errorCode = CAMERA_INVALID_STATE;
617             return;
618         }
619         if (streamType == StreamType::CAPTURE) {
620             errorCode = RemoveOutputStream(static_cast<HStreamCapture*>(stream.GetRefPtr()));
621             HCaptureSession::DelayCloseMediaLib();
622         } else if (streamType == StreamType::REPEAT) {
623             HStreamRepeat* repeatSteam = static_cast<HStreamRepeat*>(stream.GetRefPtr());
624             if (enableStreamRotate_ && repeatSteam != nullptr &&
625                 repeatSteam->GetRepeatStreamType() == RepeatStreamType::PREVIEW) {
626                 UnRegisterDisplayListener(repeatSteam);
627             }
628             errorCode = RemoveOutputStream(repeatSteam);
629         } else if (streamType == StreamType::METADATA) {
630             errorCode = RemoveOutputStream(static_cast<HStreamMetadata*>(stream.GetRefPtr()));
631         }
632     });
633     if (errorCode == CAMERA_OK) {
634         CAMERA_SYSEVENT_STATISTIC(CreateMsg("CaptureSession::RemoveOutput with %d", streamType));
635     } else {
636         CameraReportUtils::ReportCameraError(
637             "HCaptureSession::RemoveOutput", errorCode, false, CameraReportUtils::GetCallerInfo());
638     }
639     MEDIA_INFO_LOG("HCaptureSession::RemoveOutput execute success");
640     return errorCode;
641 }
642 
ValidateSessionInputs()643 int32_t HCaptureSession::ValidateSessionInputs()
644 {
645     CHECK_ERROR_RETURN_RET_LOG(GetCameraDevice() == nullptr, CAMERA_INVALID_SESSION_CFG,
646         "HCaptureSession::ValidateSessionInputs No inputs present");
647     return CAMERA_OK;
648 }
649 
ValidateSessionOutputs()650 int32_t HCaptureSession::ValidateSessionOutputs()
651 {
652     CHECK_ERROR_RETURN_RET_LOG(streamContainer_.Size() == 0, CAMERA_INVALID_SESSION_CFG,
653         "HCaptureSession::ValidateSessionOutputs No outputs present");
654     return CAMERA_OK;
655 }
656 
LinkInputAndOutputs()657 int32_t HCaptureSession::LinkInputAndOutputs()
658 {
659     int32_t rc;
660     std::vector<StreamInfo_V1_1> allStreamInfos;
661     sptr<OHOS::HDI::Camera::V1_0::IStreamOperator> streamOperator;
662     auto device = GetCameraDevice();
663     MEDIA_INFO_LOG("HCaptureSession::LinkInputAndOutputs prepare execute");
664     CHECK_ERROR_RETURN_RET_LOG(device == nullptr, CAMERA_INVALID_SESSION_CFG,
665         "HCaptureSession::LinkInputAndOutputs device is null");
666     auto settings = device->GetDeviceAbility();
667     CHECK_ERROR_RETURN_RET_LOG(settings == nullptr, CAMERA_UNKNOWN_ERROR,
668         "HCaptureSession::LinkInputAndOutputs deviceAbility is null");
669     streamOperator = device->GetStreamOperator();
670     auto allStream = streamContainer_.GetAllStreams();
671     MEDIA_INFO_LOG("HCaptureSession::LinkInputAndOutputs allStream size:%{public}zu", allStream.size());
672     CHECK_ERROR_RETURN_RET_LOG(!IsValidMode(opMode_, settings), CAMERA_INVALID_SESSION_CFG,
673         "HCaptureSession::LinkInputAndOutputs IsValidMode false");
674     for (auto& stream : allStream) {
675         rc = stream->LinkInput(streamOperator, settings);
676         if (rc == CAMERA_OK) {
677             if (stream->GetHdiStreamId() == STREAM_ID_UNSET) {
678                 stream->SetHdiStreamId(device->GenerateHdiStreamId());
679             }
680         }
681         MEDIA_INFO_LOG(
682             "HCaptureSession::LinkInputAndOutputs streamType:%{public}d, streamId:%{public}d ,hdiStreamId:%{public}d",
683             stream->GetStreamType(), stream->GetFwkStreamId(), stream->GetHdiStreamId());
684         CHECK_ERROR_RETURN_RET_LOG(rc != CAMERA_OK, rc, "HCaptureSession::LinkInputAndOutputs IsValidMode false");
685         StreamInfo_V1_1 curStreamInfo;
686         stream->SetStreamInfo(curStreamInfo);
687         if (stream->GetStreamType() != StreamType::METADATA) {
688             allStreamInfos.push_back(curStreamInfo);
689         }
690     }
691 
692     rc = device->CreateAndCommitStreams(allStreamInfos, settings, GetopMode());
693     MEDIA_INFO_LOG("HCaptureSession::LinkInputAndOutputs execute success");
694     return rc;
695 }
696 
UnlinkInputAndOutputs()697 int32_t HCaptureSession::UnlinkInputAndOutputs()
698 {
699     CAMERA_SYNC_TRACE;
700     int32_t rc = CAMERA_UNKNOWN_ERROR;
701     std::vector<int32_t> fwkStreamIds;
702     std::vector<int32_t> hdiStreamIds;
703     auto allStream = streamContainer_.GetAllStreams();
704     for (auto& stream : allStream) {
705         fwkStreamIds.emplace_back(stream->GetFwkStreamId());
706         hdiStreamIds.emplace_back(stream->GetHdiStreamId());
707         stream->UnlinkInput();
708     }
709     MEDIA_INFO_LOG("HCaptureSession::UnlinkInputAndOutputs() streamIds size() = %{public}zu, streamIds:%{public}s, "
710                    "hdiStreamIds:%{public}s",
711         fwkStreamIds.size(), Container2String(fwkStreamIds.begin(), fwkStreamIds.end()).c_str(),
712         Container2String(hdiStreamIds.begin(), hdiStreamIds.end()).c_str());
713 
714     // HDI release streams, do not clear streamContainer_
715     auto cameraDevice = GetCameraDevice();
716     if ((cameraDevice != nullptr)) {
717         cameraDevice->ReleaseStreams(hdiStreamIds);
718         std::vector<StreamInfo_V1_1> emptyStreams;
719         cameraDevice->UpdateStreams(emptyStreams);
720         cameraDevice->ResetHdiStreamId();
721     }
722     return rc;
723 }
724 
ExpandSketchRepeatStream()725 void HCaptureSession::ExpandSketchRepeatStream()
726 {
727     MEDIA_DEBUG_LOG("Enter HCaptureSession::ExpandSketchRepeatStream()");
728     std::set<sptr<HStreamCommon>> sketchStreams;
729     auto repeatStreams = streamContainer_.GetStreams(StreamType::REPEAT);
730     for (auto& stream : repeatStreams) {
731         if (stream == nullptr) {
732             continue;
733         }
734         auto streamRepeat = CastStream<HStreamRepeat>(stream);
735         if (streamRepeat->GetRepeatStreamType() == RepeatStreamType::SKETCH) {
736             continue;
737         }
738         sptr<HStreamRepeat> sketchStream = streamRepeat->GetSketchStream();
739         if (sketchStream == nullptr) {
740             continue;
741         }
742         sketchStreams.insert(sketchStream);
743     }
744     MEDIA_DEBUG_LOG("HCaptureSession::ExpandSketchRepeatStream() sketch size is:%{public}zu", sketchStreams.size());
745     for (auto& stream : sketchStreams) {
746         AddOutputStream(stream);
747     }
748     MEDIA_DEBUG_LOG("Exit HCaptureSession::ExpandSketchRepeatStream()");
749 }
750 
ExpandMovingPhotoRepeatStream()751 void HCaptureSession::ExpandMovingPhotoRepeatStream()
752 {
753     CAMERA_SYNC_TRACE;
754     MEDIA_ERR_LOG("ExpandMovingPhotoRepeatStream");
755     if (!GetCameraDevice()->CheckMovingPhotoSupported(GetopMode())) {
756         MEDIA_DEBUG_LOG("movingPhoto is not supported");
757         return;
758     }
759     auto captureStreams = streamContainer_.GetStreams(StreamType::CAPTURE);
760     MEDIA_INFO_LOG("HCameraService::ExpandMovingPhotoRepeatStream capture stream size = %{public}zu",
761         captureStreams.size());
762     VideoCodecType videoCodecType = VIDEO_ENCODE_TYPE_AVC;
763     for (auto &stream : captureStreams) {
764         int32_t type = static_cast<HStreamCapture*>(stream.GetRefPtr())->GetMovingPhotoVideoCodecType();
765         videoCodecType = static_cast<VideoCodecType>(type);
766         break;
767     }
768     MEDIA_INFO_LOG("HCameraService::ExpandMovingPhotoRepeatStream videoCodecType = %{public}d", videoCodecType);
769     auto repeatStreams = streamContainer_.GetStreams(StreamType::REPEAT);
770     for (auto& stream : repeatStreams) {
771         if (stream == nullptr) {
772             continue;
773         }
774         auto streamRepeat = CastStream<HStreamRepeat>(stream);
775         if (streamRepeat->GetRepeatStreamType() == RepeatStreamType::PREVIEW) {
776             std::lock_guard<std::mutex> lock(movingPhotoStatusLock_);
777             auto movingPhotoSurfaceWrapper =
778                 MovingPhotoSurfaceWrapper::CreateMovingPhotoSurfaceWrapper(streamRepeat->width_, streamRepeat->height_);
779             if (movingPhotoSurfaceWrapper == nullptr) {
780                 MEDIA_ERR_LOG("HCaptureSession::ExpandMovingPhotoRepeatStream CreateMovingPhotoSurfaceWrapper fail.");
781                 continue;
782             }
783             auto producer = movingPhotoSurfaceWrapper->GetProducer();
784             metaSurface_ = Surface::CreateSurfaceAsConsumer("movingPhotoMeta");
785             auto metaCache = make_shared<FixedSizeList<pair<int64_t, sptr<SurfaceBuffer>>>>(3);
786             CHECK_AND_CONTINUE_LOG(producer != nullptr, "get producer fail.");
787             livephotoListener_ = new (std::nothrow) MovingPhotoListener(movingPhotoSurfaceWrapper,
788                 metaSurface_, metaCache, preCacheFrameCount_, postCacheFrameCount_);
789             CHECK_AND_CONTINUE_LOG(livephotoListener_ != nullptr, "failed to new livephotoListener_!");
790             movingPhotoSurfaceWrapper->SetSurfaceBufferListener(livephotoListener_);
791             livephotoMetaListener_ = new(std::nothrow) MovingPhotoMetaListener(metaSurface_, metaCache);
792             CHECK_AND_CONTINUE_LOG(livephotoMetaListener_ != nullptr, "failed to new livephotoMetaListener_!");
793             metaSurface_->RegisterConsumerListener((sptr<IBufferConsumerListener> &)livephotoMetaListener_);
794             CreateMovingPhotoStreamRepeat(streamRepeat->format_, streamRepeat->width_, streamRepeat->height_, producer);
795             std::lock_guard<std::mutex> streamLock(livePhotoStreamLock_);
796             AddOutputStream(livePhotoStreamRepeat_);
797             if (!audioCapturerSession_) {
798                 audioCapturerSession_ = new AudioCapturerSession();
799             }
800             if (!taskManager_ && audioCapturerSession_) {
801                 taskManager_->SetVideoBufferDuration(preCacheFrameCount_, postCacheFrameCount_);
802             }
803             if (!videoCache_ && taskManager_) {
804                 videoCache_ = new MovingPhotoVideoCache(taskManager_);
805             }
806             break;
807         }
808     }
809     MEDIA_DEBUG_LOG("Exit HCaptureSession::ExpandMovingPhotoRepeatStream()");
810 }
811 
CreateMovingPhotoStreamRepeat(int32_t format,int32_t width,int32_t height,sptr<OHOS::IBufferProducer> producer)812 int32_t HCaptureSession::CreateMovingPhotoStreamRepeat(
813     int32_t format, int32_t width, int32_t height, sptr<OHOS::IBufferProducer> producer)
814 {
815     CAMERA_SYNC_TRACE;
816     std::lock_guard<std::mutex> lock(livePhotoStreamLock_);
817     CHECK_ERROR_RETURN_RET_LOG(width <= 0 || height <= 0, CAMERA_INVALID_ARG,
818         "HCameraService::CreateLivePhotoStreamRepeat args is illegal");
819     if (livePhotoStreamRepeat_ != nullptr) {
820         livePhotoStreamRepeat_->Release();
821     }
822     auto streamRepeat = new (std::nothrow) HStreamRepeat(producer, format, width, height, RepeatStreamType::LIVEPHOTO);
823     CHECK_AND_RETURN_RET_LOG(streamRepeat != nullptr, CAMERA_ALLOC_ERROR, "HStreamRepeat allocation failed");
824     MEDIA_DEBUG_LOG("para is:%{public}dx%{public}d,%{public}d", width, height, format);
825     livePhotoStreamRepeat_ = streamRepeat;
826     streamRepeat->SetMetaProducer(metaSurface_->GetProducer());
827     MEDIA_INFO_LOG("HCameraService::CreateLivePhotoStreamRepeat end");
828     return CAMERA_OK;
829 }
830 
GetStreamByStreamID(int32_t streamId)831 const sptr<HStreamCommon> HCaptureSession::GetStreamByStreamID(int32_t streamId)
832 {
833     auto stream = streamContainer_.GetStream(streamId);
834     CHECK_ERROR_PRINT_LOG(stream == nullptr,
835         "HCaptureSession::GetStreamByStreamID get stream fail, streamId is:%{public}d", streamId);
836     return stream;
837 }
838 
GetHdiStreamByStreamID(int32_t streamId)839 const sptr<HStreamCommon> HCaptureSession::GetHdiStreamByStreamID(int32_t streamId)
840 {
841     auto stream = streamContainer_.GetHdiStream(streamId);
842     CHECK_ERROR_PRINT_LOG(stream == nullptr,
843         "HCaptureSession::GetHdiStreamByStreamID get stream fail, streamId is:%{public}d", streamId);
844     return stream;
845 }
846 
ClearSketchRepeatStream()847 void HCaptureSession::ClearSketchRepeatStream()
848 {
849     MEDIA_DEBUG_LOG("Enter HCaptureSession::ClearSketchRepeatStream()");
850 
851     // Already added session lock in BeginConfig()
852     auto repeatStreams = streamContainer_.GetStreams(StreamType::REPEAT);
853     for (auto& repeatStream : repeatStreams) {
854         if (repeatStream == nullptr) {
855             continue;
856         }
857         auto sketchStream = CastStream<HStreamRepeat>(repeatStream);
858         if (sketchStream->GetRepeatStreamType() != RepeatStreamType::SKETCH) {
859             continue;
860         }
861         MEDIA_DEBUG_LOG(
862             "HCaptureSession::ClearSketchRepeatStream() stream id is:%{public}d", sketchStream->GetFwkStreamId());
863         RemoveOutputStream(repeatStream);
864     }
865     MEDIA_DEBUG_LOG("Exit HCaptureSession::ClearSketchRepeatStream()");
866 }
867 
ClearMovingPhotoRepeatStream()868 void HCaptureSession::ClearMovingPhotoRepeatStream()
869 {
870     CAMERA_SYNC_TRACE;
871     MEDIA_DEBUG_LOG("Enter HCaptureSession::ClearMovingPhotoRepeatStream()");
872     // Already added session lock in BeginConfig()
873     auto repeatStreams = streamContainer_.GetStreams(StreamType::REPEAT);
874     for (auto& repeatStream : repeatStreams) {
875         if (repeatStream == nullptr) {
876             continue;
877         }
878         auto movingPhotoStream = CastStream<HStreamRepeat>(repeatStream);
879         if (movingPhotoStream->GetRepeatStreamType() != RepeatStreamType::LIVEPHOTO) {
880             continue;
881         }
882         StopMovingPhoto();
883         std::lock_guard<std::mutex> lock(movingPhotoStatusLock_);
884         livephotoListener_ = nullptr;
885         videoCache_ = nullptr;
886         MEDIA_DEBUG_LOG("HCaptureSession::ClearLivePhotoRepeatStream() stream id is:%{public}d",
887             movingPhotoStream->GetFwkStreamId());
888         RemoveOutputStream(repeatStream);
889     }
890     MEDIA_DEBUG_LOG("Exit HCaptureSession::ClearLivePhotoRepeatStream()");
891 }
892 
StopMovingPhoto()893 void HCaptureSession::StopMovingPhoto() __attribute__((no_sanitize("cfi")))
894 {
895     CAMERA_SYNC_TRACE;
896     MEDIA_DEBUG_LOG("Enter HCaptureSession::StopMovingPhoto");
897     std::lock_guard<std::mutex> lock(movingPhotoStatusLock_);
898     if (livephotoListener_) {
899         livephotoListener_->StopDrainOut();
900     }
901     if (videoCache_) {
902         videoCache_->ClearCache();
903     }
904     #ifdef MOVING_PHOTO_ADD_AUDIO
905     if (audioCapturerSession_) {
906         audioCapturerSession_->Stop();
907     }
908     #endif
909     if (taskManager_) {
910         taskManager_->Stop();
911     }
912 }
913 
ValidateSession()914 int32_t HCaptureSession::ValidateSession()
915 {
916     int32_t errorCode = CAMERA_OK;
917     errorCode = ValidateSessionInputs();
918     if (errorCode != CAMERA_OK) {
919         return errorCode;
920     }
921     errorCode = ValidateSessionOutputs();
922     return errorCode;
923 }
924 
CommitConfig()925 int32_t HCaptureSession::CommitConfig()
926 {
927     CAMERA_SYNC_TRACE;
928     MEDIA_INFO_LOG("HCaptureSession::CommitConfig begin");
929     int32_t errorCode = CAMERA_OK;
930     stateMachine_.StateGuard([&errorCode, this](CaptureSessionState currentState) {
931         bool isTransferSupport = stateMachine_.CheckTransfer(CaptureSessionState::SESSION_CONFIG_COMMITTED);
932         if (!isTransferSupport) {
933             MEDIA_ERR_LOG("HCaptureSession::CommitConfig() Need to call BeginConfig before committing configuration");
934             errorCode = CAMERA_INVALID_STATE;
935             return;
936         }
937         errorCode = ValidateSession();
938         if (errorCode != CAMERA_OK) {
939             return;
940         }
941         if (!IsNeedDynamicConfig()) {
942             // expand moving photo always
943             ExpandMovingPhotoRepeatStream();
944             ExpandSketchRepeatStream();
945         }
946         auto device = GetCameraDevice();
947         if (device == nullptr) {
948             MEDIA_ERR_LOG("HCaptureSession::CommitConfig() Failed to commit config. camera device is null");
949             errorCode = CAMERA_INVALID_STATE;
950             return;
951         }
952         const int32_t secureMode = 15;
953         uint64_t secureSeqId = 0L;
954         device ->GetSecureCameraSeq(&secureSeqId);
955         if (((GetopMode() == secureMode) ^ (secureSeqId != 0))) {
956             MEDIA_ERR_LOG("secureCamera is not allowed commit mode = %{public}d.", GetopMode());
957             errorCode = CAMERA_OPERATION_NOT_ALLOWED;
958             return;
959         }
960 
961         MEDIA_INFO_LOG("HCaptureSession::CommitConfig secureSeqId = %{public}" PRIu64 "", secureSeqId);
962         errorCode = LinkInputAndOutputs();
963         if (errorCode != CAMERA_OK) {
964             MEDIA_ERR_LOG("HCaptureSession::CommitConfig() Failed to commit config. rc: %{public}d", errorCode);
965             return;
966         }
967         stateMachine_.Transfer(CaptureSessionState::SESSION_CONFIG_COMMITTED);
968     });
969     if (errorCode != CAMERA_OK) {
970         CameraReportUtils::ReportCameraError(
971             "HCaptureSession::CommitConfig", errorCode, false, CameraReportUtils::GetCallerInfo());
972     }
973     MEDIA_INFO_LOG("HCaptureSession::CommitConfig end");
974     return errorCode;
975 }
976 
GetActiveColorSpace(ColorSpace & colorSpace)977 int32_t HCaptureSession::GetActiveColorSpace(ColorSpace& colorSpace)
978 {
979     colorSpace = currColorSpace_;
980     return CAMERA_OK;
981 }
982 
SetColorSpace(ColorSpace colorSpace,ColorSpace captureColorSpace,bool isNeedUpdate)983 int32_t HCaptureSession::SetColorSpace(ColorSpace colorSpace, ColorSpace captureColorSpace, bool isNeedUpdate)
984 {
985     int32_t result = CAMERA_OK;
986     CHECK_ERROR_RETURN_RET_LOG(colorSpace == currColorSpace_ && captureColorSpace == currCaptureColorSpace_, result,
987         "HCaptureSession::SetColorSpace() colorSpace no need to update.");
988     stateMachine_.StateGuard(
989         [&result, this, &colorSpace, &captureColorSpace, &isNeedUpdate](CaptureSessionState currentState) {
990             if (!(currentState == CaptureSessionState::SESSION_CONFIG_INPROGRESS ||
991                     currentState == CaptureSessionState::SESSION_CONFIG_COMMITTED ||
992                     currentState == CaptureSessionState::SESSION_STARTED)) {
993                 MEDIA_ERR_LOG("HCaptureSession::SetColorSpace(), Invalid session state: %{public}d", currentState);
994                 result = CAMERA_INVALID_STATE;
995                 return;
996             }
997 
998             currColorSpace_ = colorSpace;
999             currCaptureColorSpace_ = captureColorSpace;
1000             MEDIA_INFO_LOG("HCaptureSession::SetColorSpace() colorSpace %{public}d, captureColorSpace %{public}d, "
1001                 "isNeedUpdate %{public}d", colorSpace, captureColorSpace, isNeedUpdate);
1002 
1003             result = CheckIfColorSpaceMatchesFormat(colorSpace);
1004             if (result != CAMERA_OK && isNeedUpdate) {
1005                 MEDIA_ERR_LOG("HCaptureSession::SetColorSpace() Failed, format and colorSpace not match.");
1006                 return;
1007             }
1008             if (result != CAMERA_OK && !isNeedUpdate) {
1009                 MEDIA_ERR_LOG("HCaptureSession::SetColorSpace() %{public}d, format and colorSpace not match.", result);
1010                 currColorSpace_ = ColorSpace::BT709;
1011             }
1012 
1013             SetColorSpaceForStreams();
1014 
1015             if (isNeedUpdate) {
1016                 result = UpdateStreamInfos();
1017             }
1018         });
1019     return result;
1020 }
1021 
SetColorSpaceForStreams()1022 void HCaptureSession::SetColorSpaceForStreams()
1023 {
1024     auto streams = streamContainer_.GetAllStreams();
1025     for (auto& stream : streams) {
1026         MEDIA_DEBUG_LOG("HCaptureSession::SetColorSpaceForStreams() streams type %{public}d", stream->GetStreamType());
1027         if (stream->GetStreamType() == StreamType::CAPTURE) {
1028             stream->SetColorSpace(currCaptureColorSpace_);
1029         } else {
1030             stream->SetColorSpace(currColorSpace_);
1031         }
1032     }
1033 }
1034 
CancelStreamsAndGetStreamInfos(std::vector<StreamInfo_V1_1> & streamInfos)1035 void HCaptureSession::CancelStreamsAndGetStreamInfos(std::vector<StreamInfo_V1_1>& streamInfos)
1036 {
1037     MEDIA_INFO_LOG("HCaptureSession::CancelStreamsAndGetStreamInfos enter.");
1038     StreamInfo_V1_1 curStreamInfo;
1039     auto streams = streamContainer_.GetAllStreams();
1040     for (auto& stream : streams) {
1041         if (stream && stream->GetStreamType() == StreamType::METADATA) {
1042             continue;
1043         }
1044         if (stream && stream->GetStreamType() == StreamType::CAPTURE && isSessionStarted_) {
1045             static_cast<HStreamCapture*>(stream.GetRefPtr())->CancelCapture();
1046         } else if (stream && stream->GetStreamType() == StreamType::REPEAT && isSessionStarted_) {
1047             static_cast<HStreamRepeat*>(stream.GetRefPtr())->Stop();
1048         }
1049         if (stream) {
1050             stream->SetStreamInfo(curStreamInfo);
1051             streamInfos.push_back(curStreamInfo);
1052         }
1053     }
1054 }
1055 
RestartStreams()1056 void HCaptureSession::RestartStreams()
1057 {
1058     MEDIA_INFO_LOG("HCaptureSession::RestartStreams() enter.");
1059     if (!isSessionStarted_) {
1060         MEDIA_DEBUG_LOG("HCaptureSession::RestartStreams() session is not started yet.");
1061         return;
1062     }
1063     auto cameraDevice = GetCameraDevice();
1064     if (cameraDevice == nullptr) {
1065         return;
1066     }
1067     auto streams = streamContainer_.GetAllStreams();
1068     for (auto& stream : streams) {
1069         if (stream && stream->GetStreamType() == StreamType::REPEAT &&
1070             CastStream<HStreamRepeat>(stream)->GetRepeatStreamType() == RepeatStreamType::PREVIEW) {
1071             std::shared_ptr<OHOS::Camera::CameraMetadata> settings = cameraDevice->CloneCachedSettings();
1072             MEDIA_INFO_LOG("HCaptureSession::RestartStreams() CloneCachedSettings");
1073             DumpMetadata(settings);
1074             CastStream<HStreamRepeat>(stream)->Start(settings);
1075         }
1076     }
1077 }
1078 
UpdateStreamInfos()1079 int32_t HCaptureSession::UpdateStreamInfos()
1080 {
1081     std::vector<StreamInfo_V1_1> streamInfos;
1082     CancelStreamsAndGetStreamInfos(streamInfos);
1083 
1084     auto cameraDevice = GetCameraDevice();
1085     CHECK_ERROR_RETURN_RET_LOG(cameraDevice == nullptr, CAMERA_UNKNOWN_ERROR,
1086         "HCaptureSession::UpdateStreamInfos() cameraDevice is null");
1087     int errorCode = cameraDevice->UpdateStreams(streamInfos);
1088     if (errorCode == CAMERA_OK) {
1089         RestartStreams();
1090     } else {
1091         MEDIA_DEBUG_LOG("HCaptureSession::UpdateStreamInfos err %{public}d", errorCode);
1092     }
1093     return errorCode;
1094 }
1095 
CheckIfColorSpaceMatchesFormat(ColorSpace colorSpace)1096 int32_t HCaptureSession::CheckIfColorSpaceMatchesFormat(ColorSpace colorSpace)
1097 {
1098     if (!(colorSpace == ColorSpace::BT2020_HLG || colorSpace == ColorSpace::BT2020_PQ ||
1099         colorSpace == ColorSpace::BT2020_HLG_LIMIT || colorSpace == ColorSpace::BT2020_PQ_LIMIT)) {
1100         return CAMERA_OK;
1101     }
1102 
1103     // 选择BT2020,需要匹配10bit的format;若不匹配,返回error
1104     auto streams = streamContainer_.GetAllStreams();
1105     for (auto& curStream : streams) {
1106         if (!curStream) {
1107             continue;
1108         }
1109         // 当前拍照流不支持BT2020,无需校验format
1110         if (curStream->GetStreamType() != StreamType::REPEAT) {
1111             continue;
1112         }
1113         StreamInfo_V1_1 curStreamInfo;
1114         curStream->SetStreamInfo(curStreamInfo);
1115         MEDIA_INFO_LOG("HCaptureSession::CheckFormat, stream repeatType: %{public}d, format: %{public}d",
1116             static_cast<HStreamRepeat*>(curStream.GetRefPtr())->GetRepeatStreamType(), curStreamInfo.v1_0.format_);
1117         if (!(curStreamInfo.v1_0.format_ == OHOS::HDI::Display::Composer::V1_1::PIXEL_FMT_YCBCR_P010 ||
1118             curStreamInfo.v1_0.format_ == OHOS::HDI::Display::Composer::V1_1::PIXEL_FMT_YCRCB_P010)) {
1119             MEDIA_ERR_LOG("HCaptureSession::CheckFormat, stream format not match");
1120             return CAMERA_OPERATION_NOT_ALLOWED;
1121         }
1122     }
1123     return CAMERA_OK;
1124 }
1125 
GetSessionState(CaptureSessionState & sessionState)1126 int32_t HCaptureSession::GetSessionState(CaptureSessionState& sessionState)
1127 {
1128     sessionState = stateMachine_.GetCurrentState();
1129     return CAMERA_OK;
1130 }
1131 
QueryFpsAndZoomRatio(float & currentFps,float & currentZoomRatio)1132 bool HCaptureSession::QueryFpsAndZoomRatio(float& currentFps, float& currentZoomRatio)
1133 {
1134     auto cameraDevice = GetCameraDevice();
1135     CHECK_ERROR_RETURN_RET_LOG(cameraDevice == nullptr, false,
1136         "HCaptureSession::QueryFpsAndZoomRatio() cameraDevice is null");
1137     int32_t DEFAULT_ITEMS = 2;
1138     int32_t DEFAULT_DATA_LENGTH = 100;
1139     std::shared_ptr<OHOS::Camera::CameraMetadata> metaIn =
1140         std::make_shared<OHOS::Camera::CameraMetadata>(DEFAULT_ITEMS, DEFAULT_DATA_LENGTH);
1141     std::shared_ptr<OHOS::Camera::CameraMetadata> metaOut =
1142         std::make_shared<OHOS::Camera::CameraMetadata>(DEFAULT_ITEMS, DEFAULT_DATA_LENGTH);
1143     uint32_t count = 1;
1144     uint32_t fps = 30;
1145     uint32_t zoomRatio = 100;
1146     metaIn->addEntry(OHOS_STATUS_CAMERA_CURRENT_FPS, &fps, count);
1147     metaIn->addEntry(OHOS_STATUS_CAMERA_CURRENT_ZOOM_RATIO, &zoomRatio, count);
1148     cameraDevice->GetStatus(metaIn, metaOut);
1149 
1150     camera_metadata_item_t item;
1151     int retFindMeta = OHOS::Camera::FindCameraMetadataItem(metaOut->get(),
1152         OHOS_STATUS_CAMERA_CURRENT_ZOOM_RATIO, &item);
1153     if (retFindMeta == CAM_META_ITEM_NOT_FOUND) {
1154         MEDIA_ERR_LOG("HCaptureSession::QueryFpsAndZoomRatio() current zoom not found");
1155         return false;
1156     } else if (retFindMeta == CAM_META_SUCCESS) {
1157         currentZoomRatio = static_cast<float>(item.data.ui32[0]);
1158         MEDIA_INFO_LOG("HCaptureSession::QueryFpsAndZoomRatio() current zoom %{public}d.", item.data.ui32[0]);
1159     }
1160     retFindMeta = OHOS::Camera::FindCameraMetadataItem(metaOut->get(), OHOS_STATUS_CAMERA_CURRENT_FPS, &item);
1161     if (retFindMeta == CAM_META_ITEM_NOT_FOUND) {
1162         MEDIA_ERR_LOG("HCaptureSession::QueryFpsAndZoomRatio() current fps not found");
1163         return false;
1164     } else if (retFindMeta == CAM_META_SUCCESS) {
1165         currentFps = static_cast<float>(item.data.ui32[0]);
1166         MEDIA_INFO_LOG("HCaptureSession::QueryFpsAndZoomRatio() current fps %{public}d.", item.data.ui32[0]);
1167     }
1168     return true;
1169 }
1170 
QueryZoomPerformance(std::vector<float> & crossZoomAndTime,int32_t operationMode)1171 bool HCaptureSession::QueryZoomPerformance(std::vector<float>& crossZoomAndTime, int32_t operationMode)
1172 {
1173     auto cameraDevice = GetCameraDevice();
1174     CHECK_ERROR_RETURN_RET_LOG(cameraDevice == nullptr, false,
1175         "HCaptureSession::QueryZoomPerformance() cameraDevice is null");
1176     // query zoom performance. begin
1177     std::shared_ptr<OHOS::Camera::CameraMetadata> ability = cameraDevice->GetDeviceAbility();
1178     camera_metadata_item_t zoomItem;
1179     int retFindMeta =
1180         OHOS::Camera::FindCameraMetadataItem(ability->get(), OHOS_ABILITY_CAMERA_ZOOM_PERFORMANCE, &zoomItem);
1181     if (retFindMeta == CAM_META_ITEM_NOT_FOUND) {
1182         MEDIA_ERR_LOG("HCaptureSession::QueryZoomPerformance() current zoom not found");
1183         return false;
1184     } else if (retFindMeta == CAM_META_SUCCESS) {
1185         MEDIA_DEBUG_LOG("HCaptureSession::QueryZoomPerformance() zoom performance count %{public}d.", zoomItem.count);
1186         for (int i = 0; i < static_cast<int>(zoomItem.count); i++) {
1187             MEDIA_DEBUG_LOG(
1188                 "HCaptureSession::QueryZoomPerformance() zoom performance value %{public}d.", zoomItem.data.ui32[i]);
1189         }
1190     }
1191     int dataLenPerPoint = 3;
1192     int headLenPerMode = 2;
1193     MEDIA_DEBUG_LOG("HCaptureSession::QueryZoomPerformance() operationMode %{public}d.",
1194         static_cast<OHOS::HDI::Camera::V1_3::OperationMode>(operationMode));
1195     for (int i = 0; i < static_cast<int>(zoomItem.count);) {
1196         int sceneMode = static_cast<int>(zoomItem.data.ui32[i]);
1197         int zoomPointsNum = static_cast<int>(zoomItem.data.ui32[i + 1]);
1198         if (static_cast<OHOS::HDI::Camera::V1_3::OperationMode>(operationMode) == sceneMode) {
1199             for (int j = 0; j < dataLenPerPoint * zoomPointsNum; j++) {
1200                 crossZoomAndTime.push_back(zoomItem.data.ui32[i + headLenPerMode + j]);
1201                 MEDIA_DEBUG_LOG("HCaptureSession::QueryZoomPerformance()  crossZoomAndTime %{public}d.",
1202                     static_cast<int>(zoomItem.data.ui32[i + headLenPerMode + j]));
1203             }
1204             break;
1205         } else {
1206             i = i + 1 + zoomPointsNum * dataLenPerPoint + 1;
1207         }
1208     }
1209     return true;
1210 }
1211 
GetSensorOritation()1212 int32_t HCaptureSession::GetSensorOritation()
1213 {
1214     auto cameraDevice = GetCameraDevice();
1215     int32_t sensorOrientation = 0;
1216     CHECK_ERROR_RETURN_RET_LOG(cameraDevice == nullptr, sensorOrientation,
1217         "HCaptureSession::GetSensorOritation() cameraDevice is null");
1218     std::shared_ptr<OHOS::Camera::CameraMetadata> ability = cameraDevice->GetDeviceAbility();
1219     CHECK_ERROR_RETURN_RET(ability == nullptr, sensorOrientation);
1220     camera_metadata_item_t item;
1221     int ret = OHOS::Camera::FindCameraMetadataItem(ability->get(), OHOS_SENSOR_ORIENTATION, &item);
1222     CHECK_ERROR_RETURN_RET_LOG(ret != CAM_META_SUCCESS, sensorOrientation,
1223         "HCaptureSession::GetSensorOritation get sensor orientation failed");
1224     sensorOrientation = item.data.i32[0];
1225     MEDIA_INFO_LOG("HCaptureSession::GetSensorOritation sensor orientation %{public}d", sensorOrientation);
1226     return sensorOrientation;
1227 }
1228 
GetMovingPhotoBufferDuration()1229 int32_t HCaptureSession::GetMovingPhotoBufferDuration()
1230 {
1231     auto cameraDevice = GetCameraDevice();
1232     uint32_t preBufferDuration = 0;
1233     uint32_t postBufferDuration = 0;
1234     constexpr int32_t MILLSEC_MULTIPLE = 1000;
1235     CHECK_ERROR_RETURN_RET_LOG(cameraDevice == nullptr, 0,
1236         "HCaptureSession::GetMovingPhotoBufferDuration() cameraDevice is null");
1237     std::shared_ptr<OHOS::Camera::CameraMetadata> ability = cameraDevice->GetDeviceAbility();
1238     CHECK_ERROR_RETURN_RET(ability == nullptr, 0);
1239     camera_metadata_item_t item;
1240     int ret = OHOS::Camera::FindCameraMetadataItem(ability->get(), OHOS_MOVING_PHOTO_BUFFER_DURATION, &item);
1241     CHECK_ERROR_RETURN_RET_LOG(ret != CAM_META_SUCCESS, 0,
1242         "HCaptureSession::GetMovingPhotoBufferDuration get buffer duration failed");
1243     preBufferDuration = item.data.ui32[0];
1244     postBufferDuration = item.data.ui32[1];
1245     preCacheFrameCount_ = preBufferDuration == 0 ? preCacheFrameCount_ :
1246         static_cast<uint32_t>(float(preBufferDuration) / MILLSEC_MULTIPLE * VIDEO_FRAME_RATE);
1247     postCacheFrameCount_ = preBufferDuration == 0 ? postCacheFrameCount_ :
1248         static_cast<uint32_t>(float(postBufferDuration) / MILLSEC_MULTIPLE * VIDEO_FRAME_RATE);
1249     MEDIA_INFO_LOG("HCaptureSession::GetMovingPhotoBufferDuration preBufferDuration : %{public}u, "
1250         "postBufferDuration : %{public}u, preCacheFrameCount_ : %{public}u, postCacheFrameCount_ : %{public}u",
1251         preBufferDuration, postBufferDuration, preCacheFrameCount_, postCacheFrameCount_);
1252     return CAMERA_OK;
1253 }
1254 
SetSmoothZoom(int32_t smoothZoomType,int32_t operationMode,float targetZoomRatio,float & duration)1255 int32_t HCaptureSession::SetSmoothZoom(
1256     int32_t smoothZoomType, int32_t operationMode, float targetZoomRatio, float& duration)
1257 {
1258     constexpr int32_t ZOOM_RATIO_MULTIPLE = 100;
1259     auto cameraDevice = GetCameraDevice();
1260     CHECK_ERROR_RETURN_RET_LOG(cameraDevice == nullptr, CAMERA_UNKNOWN_ERROR,
1261         "HCaptureSession::SetSmoothZoom device is null");
1262     float currentFps = 30.0f;
1263     float currentZoomRatio = 1.0f;
1264     QueryFpsAndZoomRatio(currentFps, currentZoomRatio);
1265     std::vector<float> crossZoomAndTime {};
1266     QueryZoomPerformance(crossZoomAndTime, operationMode);
1267     float waitTime = 0.0;
1268     int dataLenPerPoint = 3;
1269     float frameIntervalMs = 1000.0 / currentFps;
1270     targetZoomRatio = targetZoomRatio * ZOOM_RATIO_MULTIPLE;
1271     int indexAdded = targetZoomRatio > currentZoomRatio ? 1 : 2;
1272     auto zoomAlgorithm = SmoothZoom::GetZoomAlgorithm(static_cast<SmoothZoomType>(smoothZoomType));
1273     auto array = zoomAlgorithm->GetZoomArray(currentZoomRatio, targetZoomRatio, frameIntervalMs);
1274     CHECK_ERROR_RETURN_RET_LOG(array.empty(), CAMERA_UNKNOWN_ERROR, "HCaptureSession::SetSmoothZoom array is empty");
1275     for (int i = 0; i < static_cast<int>(crossZoomAndTime.size()); i = i + dataLenPerPoint) {
1276         float crossZoom = crossZoomAndTime[i];
1277         if ((crossZoom - currentZoomRatio) * (crossZoom - targetZoomRatio) > 0) {
1278             continue;
1279         }
1280         float waitMs = crossZoomAndTime[i + indexAdded];
1281         if (std::fabs(currentZoomRatio - crossZoom) <= std::numeric_limits<float>::epsilon() &&
1282             currentZoomRatio > targetZoomRatio) {
1283             waitTime = crossZoomAndTime[i + indexAdded];
1284         }
1285         for (int j = 0; j < static_cast<int>(array.size()); j++) {
1286             if (static_cast<int>(array[j] - crossZoom) * static_cast<int>(array[0] - crossZoom) < 0) {
1287                 waitTime = fmax(waitMs - frameIntervalMs * j, waitTime);
1288                 break;
1289             }
1290         }
1291     }
1292     std::vector<uint32_t> zoomAndTimeArray {};
1293     for (int i = 0; i < static_cast<int>(array.size()); i++) {
1294         zoomAndTimeArray.push_back(static_cast<uint32_t>(array[i]));
1295         zoomAndTimeArray.push_back(static_cast<uint32_t>(i * frameIntervalMs + waitTime));
1296         MEDIA_DEBUG_LOG("HCaptureSession::SetSmoothZoom() zoom %{public}d, waitMs %{public}d.",
1297             static_cast<uint32_t>(array[i]), static_cast<uint32_t>(i * frameIntervalMs + waitTime));
1298     }
1299     duration = (static_cast<int>(array.size()) - 1) * frameIntervalMs + waitTime;
1300     MEDIA_DEBUG_LOG("HCaptureSession::SetSmoothZoom() duration %{public}f", duration);
1301     ProcessMetaZoomArray(zoomAndTimeArray, cameraDevice);
1302     return CAMERA_OK;
1303 }
1304 
ProcessMetaZoomArray(std::vector<uint32_t> & zoomAndTimeArray,sptr<HCameraDevice> & cameraDevice)1305 void HCaptureSession::ProcessMetaZoomArray(
1306     std::vector<uint32_t>& zoomAndTimeArray, sptr<HCameraDevice>& cameraDevice)
1307 {
1308     std::shared_ptr<OHOS::Camera::CameraMetadata> metaZoomArray = std::make_shared<OHOS::Camera::CameraMetadata>(1, 1);
1309     uint32_t zoomCount = static_cast<uint32_t>(zoomAndTimeArray.size());
1310     MEDIA_INFO_LOG("HCaptureSession::ProcessMetaZoomArray() zoomArray size: %{public}zu, zoomCount: %{public}u",
1311         zoomAndTimeArray.size(), zoomCount);
1312     metaZoomArray->addEntry(OHOS_CONTROL_SMOOTH_ZOOM_RATIOS, zoomAndTimeArray.data(), zoomCount);
1313     cameraDevice->UpdateSettingOnce(metaZoomArray);
1314 }
1315 
EnableMovingPhoto(bool isEnable)1316 int32_t HCaptureSession::EnableMovingPhoto(bool isEnable)
1317 {
1318     isSetMotionPhoto_ = isEnable;
1319     StartMovingPhotoStream();
1320     auto device = GetCameraDevice();
1321     if (device != nullptr) {
1322         device->EnableMovingPhoto(isEnable);
1323     }
1324     GetMovingPhotoBufferDuration();
1325     GetMovingPhotoStartAndEndTime();
1326     #ifdef CAMERA_USE_SENSOR
1327     if (isSetMotionPhoto_) {
1328         RegisterSensorCallback();
1329     } else {
1330         UnRegisterSensorCallback();
1331     }
1332     #endif
1333     return CAMERA_OK;
1334 }
1335 
Start()1336 int32_t HCaptureSession::Start()
1337 {
1338     CAMERA_SYNC_TRACE;
1339     int32_t errorCode = CAMERA_OK;
1340     MEDIA_INFO_LOG("HCaptureSession::Start prepare execute");
1341     stateMachine_.StateGuard([&errorCode, this](CaptureSessionState currentState) {
1342         bool isTransferSupport = stateMachine_.CheckTransfer(CaptureSessionState::SESSION_STARTED);
1343         if (!isTransferSupport) {
1344             MEDIA_ERR_LOG("HCaptureSession::Start() Need to call after committing configuration");
1345             errorCode = CAMERA_INVALID_STATE;
1346             return;
1347         }
1348 
1349         std::shared_ptr<OHOS::Camera::CameraMetadata> settings = nullptr;
1350         auto cameraDevice = GetCameraDevice();
1351         uint8_t usedAsPositionU8 = OHOS_CAMERA_POSITION_OTHER;
1352         MEDIA_INFO_LOG("HCaptureSession::Start usedAsPositionU8 default = %{public}d", usedAsPositionU8);
1353         if (cameraDevice != nullptr) {
1354             settings = cameraDevice->CloneCachedSettings();
1355             usedAsPositionU8 = cameraDevice->GetUsedAsPosition();
1356             MEDIA_INFO_LOG("HCaptureSession::Start usedAsPositionU8 set %{public}d", usedAsPositionU8);
1357             DumpMetadata(settings);
1358             UpdateMuteSetting(cameraDevice->GetDeviceMuteMode(), settings);
1359         }
1360         camera_position_enum_t cameraPosition = static_cast<camera_position_enum_t>(usedAsPositionU8);
1361         errorCode = StartPreviewStream(settings, cameraPosition);
1362         if (errorCode == CAMERA_OK) {
1363             isSessionStarted_ = true;
1364         }
1365         stateMachine_.Transfer(CaptureSessionState::SESSION_STARTED);
1366     });
1367     MEDIA_INFO_LOG("HCaptureSession::Start execute success");
1368     return errorCode;
1369 }
1370 
UpdateMuteSetting(bool muteMode,std::shared_ptr<OHOS::Camera::CameraMetadata> & settings)1371 void HCaptureSession::UpdateMuteSetting(bool muteMode, std::shared_ptr<OHOS::Camera::CameraMetadata> &settings)
1372 {
1373     int32_t count = 1;
1374     uint8_t mode = muteMode? OHOS_CAMERA_MUTE_MODE_SOLID_COLOR_BLACK:OHOS_CAMERA_MUTE_MODE_OFF;
1375     settings->addEntry(OHOS_CONTROL_MUTE_MODE, &mode, count);
1376 }
1377 
StartMovingPhoto(sptr<HStreamRepeat> & curStreamRepeat)1378 void HCaptureSession::StartMovingPhoto(sptr<HStreamRepeat>& curStreamRepeat)
1379 {
1380     auto thisPtr = wptr<HCaptureSession>(this);
1381     curStreamRepeat->SetMovingPhotoStartCallback([thisPtr]() {
1382         auto sessionPtr = thisPtr.promote();
1383         if (sessionPtr != nullptr) {
1384             MEDIA_INFO_LOG("StartMovingPhotoStream when addDeferedSurface");
1385             sessionPtr->StartMovingPhotoStream();
1386         }
1387     });
1388 }
1389 
GetMovingPhotoStartAndEndTime()1390 void HCaptureSession::GetMovingPhotoStartAndEndTime()
1391 {
1392     auto thisPtr = wptr<HCaptureSession>(this);
1393     auto cameraDevice = GetCameraDevice();
1394     CHECK_ERROR_RETURN_LOG(cameraDevice == nullptr, "HCaptureSession::GetMovingPhotoStartAndEndTime device is null");
1395     cameraDevice->SetMovingPhotoStartTimeCallback([thisPtr](int32_t captureId, int64_t startTimeStamp) {
1396         MEDIA_INFO_LOG("SetMovingPhotoStartTimeCallback function enter");
1397         auto sessionPtr = thisPtr.promote();
1398         CHECK_ERROR_RETURN_LOG(sessionPtr == nullptr, "Set start time callback sessionPtr is null");
1399         CHECK_ERROR_RETURN_LOG(sessionPtr->taskManager_ == nullptr, "Set start time callback taskManager_ is null");
1400         std::lock_guard<mutex> lock(sessionPtr->taskManager_->startTimeMutex_);
1401         if (sessionPtr->taskManager_->mPStartTimeMap_.count(captureId) == 0) {
1402             MEDIA_INFO_LOG("Save moving photo start info, captureId : %{public}d, start timestamp : %{public}" PRId64,
1403                 captureId, startTimeStamp);
1404             sessionPtr->taskManager_->mPStartTimeMap_.insert(make_pair(captureId, startTimeStamp));
1405         }
1406     });
1407 
1408     cameraDevice->SetMovingPhotoEndTimeCallback([thisPtr](int32_t captureId, int64_t endTimeStamp) {
1409         auto sessionPtr = thisPtr.promote();
1410         CHECK_ERROR_RETURN_LOG(sessionPtr == nullptr, "Set end time callback sessionPtr is null");
1411         CHECK_ERROR_RETURN_LOG(sessionPtr->taskManager_ == nullptr, "Set end time callback taskManager_ is null");
1412         std::lock_guard<mutex> lock(sessionPtr->taskManager_->endTimeMutex_);
1413         if (sessionPtr->taskManager_->mPEndTimeMap_.count(captureId) == 0) {
1414             MEDIA_INFO_LOG("Save moving photo end info, captureId : %{public}d, end timestamp : %{public}" PRId64,
1415                 captureId, endTimeStamp);
1416             sessionPtr->taskManager_->mPEndTimeMap_.insert(make_pair(captureId, endTimeStamp));
1417         }
1418     });
1419 }
1420 
StartPreviewStream(const std::shared_ptr<OHOS::Camera::CameraMetadata> & settings,camera_position_enum_t cameraPosition)1421 int32_t HCaptureSession::StartPreviewStream(const std::shared_ptr<OHOS::Camera::CameraMetadata>& settings,
1422     camera_position_enum_t cameraPosition)
1423 {
1424     int32_t errorCode = CAMERA_OK;
1425     auto repeatStreams = streamContainer_.GetStreams(StreamType::REPEAT);
1426     bool hasDerferedPreview = false;
1427     // start preview
1428     for (auto& item : repeatStreams) {
1429         auto curStreamRepeat = CastStream<HStreamRepeat>(item);
1430         auto repeatType = curStreamRepeat->GetRepeatStreamType();
1431         if (repeatType != RepeatStreamType::PREVIEW) {
1432             continue;
1433         }
1434         if (curStreamRepeat->GetPreparedCaptureId() != CAPTURE_ID_UNSET) {
1435             continue;
1436         }
1437         curStreamRepeat->SetUsedAsPosition(cameraPosition);
1438         errorCode = curStreamRepeat->Start(settings);
1439         hasDerferedPreview = curStreamRepeat->producer_ == nullptr;
1440         if (isSetMotionPhoto_ && hasDerferedPreview) {
1441             StartMovingPhoto(curStreamRepeat);
1442         }
1443         if (errorCode != CAMERA_OK) {
1444             MEDIA_ERR_LOG("HCaptureSession::Start(), Failed to start preview, rc: %{public}d", errorCode);
1445             break;
1446         }
1447     }
1448     // start movingPhoto
1449     for (auto& item : repeatStreams) {
1450         auto curStreamRepeat = CastStream<HStreamRepeat>(item);
1451         auto repeatType = curStreamRepeat->GetRepeatStreamType();
1452         if (repeatType != RepeatStreamType::LIVEPHOTO) {
1453             continue;
1454         }
1455         int32_t movingPhotoErrorCode = CAMERA_OK;
1456         if (isSetMotionPhoto_ && !hasDerferedPreview) {
1457             movingPhotoErrorCode = curStreamRepeat->Start(settings);
1458             #ifdef MOVING_PHOTO_ADD_AUDIO
1459             std::lock_guard<std::mutex> lock(movingPhotoStatusLock_);
1460             audioCapturerSession_ != nullptr && audioCapturerSession_->StartAudioCapture();
1461             #endif
1462         }
1463         if (movingPhotoErrorCode != CAMERA_OK) {
1464             MEDIA_ERR_LOG("Failed to start movingPhoto, rc: %{public}d", movingPhotoErrorCode);
1465             break;
1466         }
1467     }
1468     return errorCode;
1469 }
1470 
Stop()1471 int32_t HCaptureSession::Stop()
1472 {
1473     CAMERA_SYNC_TRACE;
1474     int32_t errorCode = CAMERA_OK;
1475     MEDIA_INFO_LOG("HCaptureSession::Stop prepare execute");
1476     stateMachine_.StateGuard([&errorCode, this](CaptureSessionState currentState) {
1477         bool isTransferSupport = stateMachine_.CheckTransfer(CaptureSessionState::SESSION_CONFIG_COMMITTED);
1478         if (!isTransferSupport) {
1479             MEDIA_ERR_LOG("HCaptureSession::Stop() Need to call after Start");
1480             errorCode = CAMERA_INVALID_STATE;
1481             return;
1482         }
1483         auto allStreams = streamContainer_.GetAllStreams();
1484         for (auto& item : allStreams) {
1485             if (item->GetStreamType() == StreamType::REPEAT) {
1486                 auto repeatStream = CastStream<HStreamRepeat>(item);
1487                 if (repeatStream->GetRepeatStreamType() == RepeatStreamType::PREVIEW) {
1488                     errorCode = repeatStream->Stop();
1489                 } else if (repeatStream->GetRepeatStreamType() == RepeatStreamType::LIVEPHOTO) {
1490                     repeatStream->Stop();
1491                     StopMovingPhoto();
1492                 } else {
1493                     repeatStream->Stop();
1494                 }
1495             } else if (item->GetStreamType() == StreamType::METADATA) {
1496                 CastStream<HStreamMetadata>(item)->Stop();
1497             } else if (item->GetStreamType() == StreamType::CAPTURE) {
1498                 CastStream<HStreamCapture>(item)->CancelCapture();
1499             } else if (item->GetStreamType() == StreamType::DEPTH) {
1500                 CastStream<HStreamDepthData>(item)->Stop();
1501             } else {
1502                 MEDIA_ERR_LOG("HCaptureSession::Stop(), get unknow stream, streamType: %{public}d, streamId:%{public}d",
1503                     item->GetStreamType(), item->GetFwkStreamId());
1504             }
1505             if (errorCode != CAMERA_OK) {
1506                 MEDIA_ERR_LOG("HCaptureSession::Stop(), Failed to stop stream, rc: %{public}d, streamId:%{public}d",
1507                     errorCode, item->GetFwkStreamId());
1508             }
1509         }
1510         if (errorCode == CAMERA_OK) {
1511             isSessionStarted_ = false;
1512         }
1513         stateMachine_.Transfer(CaptureSessionState::SESSION_CONFIG_COMMITTED);
1514     });
1515     MEDIA_INFO_LOG("HCaptureSession::Stop execute success");
1516     return errorCode;
1517 }
1518 
ReleaseStreams()1519 void HCaptureSession::ReleaseStreams()
1520 {
1521     CAMERA_SYNC_TRACE;
1522     std::vector<int32_t> fwkStreamIds;
1523     std::vector<int32_t> hdiStreamIds;
1524     auto allStream = streamContainer_.GetAllStreams();
1525     for (auto& stream : allStream) {
1526         auto fwkStreamId = stream->GetFwkStreamId();
1527         if (fwkStreamId != STREAM_ID_UNSET) {
1528             fwkStreamIds.emplace_back(fwkStreamId);
1529         }
1530         auto hdiStreamId = stream->GetHdiStreamId();
1531         if (hdiStreamId != STREAM_ID_UNSET) {
1532             hdiStreamIds.emplace_back(hdiStreamId);
1533         }
1534         stream->ReleaseStream(true);
1535     }
1536     streamContainer_.Clear();
1537     MEDIA_INFO_LOG("HCaptureSession::ReleaseStreams() streamIds size() = %{public}zu, fwkStreamIds:%{public}s, "
1538         "hdiStreamIds:%{public}s,",
1539         fwkStreamIds.size(), Container2String(fwkStreamIds.begin(), fwkStreamIds.end()).c_str(),
1540         Container2String(hdiStreamIds.begin(), hdiStreamIds.end()).c_str());
1541     auto cameraDevice = GetCameraDevice();
1542     if ((cameraDevice != nullptr) && !hdiStreamIds.empty()) {
1543         cameraDevice->ReleaseStreams(hdiStreamIds);
1544     }
1545     HCaptureSession::DelayCloseMediaLib();
1546 }
1547 
Release(CaptureSessionReleaseType type)1548 int32_t HCaptureSession::Release(CaptureSessionReleaseType type)
1549 {
1550     CAMERA_SYNC_TRACE;
1551     int32_t errorCode = CAMERA_OK;
1552     MEDIA_INFO_LOG("HCaptureSession::Release prepare execute, release type is:%{public}d pid(%{public}d)", type, pid_);
1553     //Check release without lock first
1554     if (stateMachine_.IsStateNoLock(CaptureSessionState::SESSION_RELEASED)) {
1555         MEDIA_ERR_LOG("HCaptureSession::Release error, session is already released!");
1556         return CAMERA_INVALID_STATE;
1557     }
1558 
1559     stateMachine_.StateGuard([&errorCode, this, type](CaptureSessionState currentState) {
1560         MEDIA_INFO_LOG("HCaptureSession::Release pid(%{public}d). release type is:%{public}d", pid_, type);
1561         bool isTransferSupport = stateMachine_.CheckTransfer(CaptureSessionState::SESSION_RELEASED);
1562         if (!isTransferSupport) {
1563             MEDIA_ERR_LOG("HCaptureSession::Release error, this session is already released!");
1564             errorCode = CAMERA_INVALID_STATE;
1565             return;
1566         }
1567         // stop movingPhoto
1568         StopMovingPhoto();
1569 
1570         // Clear outputs
1571         ReleaseStreams();
1572 
1573         // Clear inputs
1574         auto cameraDevice = GetCameraDevice();
1575         if (cameraDevice != nullptr) {
1576             cameraDevice->Release();
1577             SetCameraDevice(nullptr);
1578         }
1579 
1580         // Clear current session
1581         TotalSessionErase(pid_);
1582         MEDIA_DEBUG_LOG("HCaptureSession::Release clear pid left services(%{public}zu).", TotalSessionSize());
1583 
1584         sptr<ICaptureSessionCallback> emptyCallback = nullptr;
1585         SetCallback(emptyCallback);
1586         #ifdef CAMERA_USE_SENSOR
1587         if (isSetMotionPhoto_) {
1588             UnRegisterSensorCallback();
1589         }
1590         #endif
1591         stateMachine_.Transfer(CaptureSessionState::SESSION_RELEASED);
1592         isSessionStarted_ = false;
1593         if (displayListener_) {
1594             OHOS::Rosen::DisplayManager::GetInstance().UnregisterDisplayListener(displayListener_);
1595             displayListener_ = nullptr;
1596         }
1597         std::lock_guard<std::mutex> lock(movingPhotoStatusLock_);
1598         livephotoListener_ = nullptr;
1599         videoCache_ = nullptr;
1600         if (taskManager_) {
1601             taskManager_->ClearTaskResource();
1602             taskManager_ = nullptr;
1603         }
1604         HCaptureSession::DelayCloseMediaLib();
1605     });
1606     MEDIA_INFO_LOG("HCaptureSession::Release execute success");
1607     return errorCode;
1608 }
1609 
Release()1610 int32_t HCaptureSession::Release()
1611 {
1612     MEDIA_INFO_LOG("HCaptureSession::Release()");
1613     CameraReportUtils::GetInstance().SetModeChangePerfStartInfo(opMode_, CameraReportUtils::GetCallerInfo());
1614     return Release(CaptureSessionReleaseType::RELEASE_TYPE_CLIENT);
1615 }
1616 
OperatePermissionCheck(uint32_t interfaceCode)1617 int32_t HCaptureSession::OperatePermissionCheck(uint32_t interfaceCode)
1618 {
1619     if (stateMachine_.GetCurrentState() == CaptureSessionState::SESSION_RELEASED) {
1620         MEDIA_ERR_LOG("HCaptureSession::OperatePermissionCheck session is released");
1621         return CAMERA_INVALID_STATE;
1622     }
1623     switch (static_cast<CaptureSessionInterfaceCode>(interfaceCode)) {
1624         case CAMERA_CAPTURE_SESSION_START: {
1625             auto callerToken = IPCSkeleton::GetCallingTokenID();
1626             if (callerToken_ != callerToken) {
1627                 MEDIA_ERR_LOG("HCaptureSession::OperatePermissionCheck fail, callerToken not legal");
1628                 return CAMERA_OPERATION_NOT_ALLOWED;
1629             }
1630             break;
1631         }
1632         default:
1633             break;
1634     }
1635     return CAMERA_OK;
1636 }
1637 
DestroyStubObjectForPid(pid_t pid)1638 void HCaptureSession::DestroyStubObjectForPid(pid_t pid)
1639 {
1640     MEDIA_DEBUG_LOG("camera stub services(%{public}zu) pid(%{public}d).", TotalSessionSize(), pid);
1641     sptr<HCaptureSession> session = TotalSessionsGet(pid);
1642     if (session != nullptr) {
1643         session->Release(CaptureSessionReleaseType::RELEASE_TYPE_CLIENT_DIED);
1644     }
1645     MEDIA_DEBUG_LOG("camera stub services(%{public}zu).", TotalSessionSize());
1646 }
1647 
SetCallback(sptr<ICaptureSessionCallback> & callback)1648 int32_t HCaptureSession::SetCallback(sptr<ICaptureSessionCallback>& callback)
1649 {
1650     if (callback == nullptr) {
1651         MEDIA_WARNING_LOG("HCaptureSession::SetCallback callback is null, we should clear the callback");
1652     }
1653 
1654     // Not implement yet.
1655     return CAMERA_OK;
1656 }
1657 
GetSessionState()1658 std::string HCaptureSession::GetSessionState()
1659 {
1660     auto currentState = stateMachine_.GetCurrentState();
1661     std::map<CaptureSessionState, std::string>::const_iterator iter = SESSION_STATE_STRING_MAP.find(currentState);
1662     if (iter != SESSION_STATE_STRING_MAP.end()) {
1663         return iter->second;
1664     }
1665     return std::to_string(static_cast<uint32_t>(currentState));
1666 }
1667 
DumpCameraSessionSummary(CameraInfoDumper & infoDumper)1668 void HCaptureSession::DumpCameraSessionSummary(CameraInfoDumper& infoDumper)
1669 {
1670     infoDumper.Msg("Number of Camera clients:[" + std::to_string(TotalSessionSize()) + "]");
1671 }
1672 
DumpSessions(CameraInfoDumper & infoDumper)1673 void HCaptureSession::DumpSessions(CameraInfoDumper& infoDumper)
1674 {
1675     auto totalSession = TotalSessionsCopy();
1676     uint32_t index = 0;
1677     for (auto it = totalSession.begin(); it != totalSession.end(); it++) {
1678         if (it->second != nullptr) {
1679             sptr<HCaptureSession> session = it->second;
1680             infoDumper.Title("Camera Sessions[" + std::to_string(index++) + "] Info:");
1681             session->DumpSessionInfo(infoDumper);
1682         }
1683     }
1684 }
1685 
DumpSessionInfo(CameraInfoDumper & infoDumper)1686 void HCaptureSession::DumpSessionInfo(CameraInfoDumper& infoDumper)
1687 {
1688     infoDumper.Msg("Client pid:[" + std::to_string(pid_)+ "]    Client uid:[" + std::to_string(uid_) + "]");
1689     infoDumper.Msg("session state:[" + GetSessionState() + "]");
1690     for (auto& stream : streamContainer_.GetAllStreams()) {
1691         infoDumper.Push();
1692         stream->DumpStreamInfo(infoDumper);
1693         infoDumper.Pop();
1694     }
1695 }
1696 
EnableMovingPhotoMirror(bool isMirror)1697 int32_t HCaptureSession::EnableMovingPhotoMirror(bool isMirror)
1698 {
1699     if (!isSetMotionPhoto_ || isMirror == isMovingPhotoMirror_) {
1700         return CAMERA_OK;
1701     }
1702     if (isMirror != isMovingPhotoMirror_) {
1703         auto repeatStreams = streamContainer_.GetStreams(StreamType::REPEAT);
1704         for (auto& stream : repeatStreams) {
1705             if (stream == nullptr) {
1706                 continue;
1707             }
1708             auto streamRepeat = CastStream<HStreamRepeat>(stream);
1709             if (streamRepeat->GetRepeatStreamType() == RepeatStreamType::LIVEPHOTO) {
1710                 MEDIA_INFO_LOG("restart movingphoto stream.");
1711                 streamRepeat->SetMirrorForLivePhoto(isMirror, opMode_);
1712                 // set clear cache flag
1713                 std::lock_guard<std::mutex> lock(movingPhotoStatusLock_);
1714                 livephotoListener_->SetClearFlag();
1715                 break;
1716             }
1717         }
1718         isMovingPhotoMirror_ = isMirror;
1719     }
1720     return CAMERA_OK;
1721 }
1722 
GetOutputStatus(int32_t & status)1723 void HCaptureSession::GetOutputStatus(int32_t &status)
1724 {
1725     auto repeatStreams = streamContainer_.GetStreams(StreamType::REPEAT);
1726     for (auto& stream : repeatStreams) {
1727         if (stream == nullptr) {
1728             continue;
1729         }
1730         auto streamRepeat = CastStream<HStreamRepeat>(stream);
1731         if (streamRepeat->GetRepeatStreamType() == RepeatStreamType::VIDEO) {
1732             if (streamRepeat->GetPreparedCaptureId() != CAPTURE_ID_UNSET) {
1733                 const int32_t videoStartStatus = 2;
1734                 status = videoStartStatus;
1735             }
1736         }
1737     }
1738 }
1739 
1740 #ifdef CAMERA_USE_SENSOR
RegisterSensorCallback()1741 void HCaptureSession::RegisterSensorCallback()
1742 {
1743     std::lock_guard<std::mutex> lock(sensorLock_);
1744     if (isRegisterSensorSuccess_) {
1745         MEDIA_INFO_LOG("HCaptureSession::RegisterSensorCallback isRegisterSensorSuccess return");
1746         return;
1747     }
1748     MEDIA_INFO_LOG("HCaptureSession::RegisterSensorCallback start");
1749     user.callback = GravityDataCallbackImpl;
1750     int32_t subscribeRet = SubscribeSensor(SENSOR_TYPE_ID_GRAVITY, &user);
1751     MEDIA_INFO_LOG("RegisterSensorCallback, subscribeRet: %{public}d", subscribeRet);
1752     int32_t setBatchRet = SetBatch(SENSOR_TYPE_ID_GRAVITY, &user, POSTURE_INTERVAL, 0);
1753     MEDIA_INFO_LOG("RegisterSensorCallback, setBatchRet: %{public}d", setBatchRet);
1754     int32_t activateRet = ActivateSensor(SENSOR_TYPE_ID_GRAVITY, &user);
1755     MEDIA_INFO_LOG("RegisterSensorCallback, activateRet: %{public}d", activateRet);
1756     if (subscribeRet != CAMERA_OK || setBatchRet != CAMERA_OK || activateRet != CAMERA_OK) {
1757         isRegisterSensorSuccess_ = false;
1758         MEDIA_INFO_LOG("RegisterSensorCallback failed.");
1759     } else {
1760         isRegisterSensorSuccess_ = true;
1761     }
1762 }
1763 
UnRegisterSensorCallback()1764 void HCaptureSession::UnRegisterSensorCallback()
1765 {
1766     std::lock_guard<std::mutex> lock(sensorLock_);
1767     int32_t deactivateRet = DeactivateSensor(SENSOR_TYPE_ID_GRAVITY, &user);
1768     int32_t unsubscribeRet = UnsubscribeSensor(SENSOR_TYPE_ID_GRAVITY, &user);
1769     if (deactivateRet == CAMERA_OK && unsubscribeRet == CAMERA_OK) {
1770         MEDIA_INFO_LOG("HCameraService.UnRegisterSensorCallback success.");
1771         isRegisterSensorSuccess_ = false;
1772     } else {
1773         MEDIA_INFO_LOG("HCameraService.UnRegisterSensorCallback failed.");
1774     }
1775 }
1776 
GravityDataCallbackImpl(SensorEvent * event)1777 void HCaptureSession::GravityDataCallbackImpl(SensorEvent* event)
1778 {
1779     MEDIA_DEBUG_LOG("GravityDataCallbackImpl prepare execute");
1780     CHECK_ERROR_RETURN_LOG(event == nullptr, "SensorEvent is nullptr.");
1781     CHECK_ERROR_RETURN_LOG(event[0].data == nullptr, "SensorEvent[0].data is nullptr.");
1782     CHECK_ERROR_RETURN_LOG(event->sensorTypeId != SENSOR_TYPE_ID_GRAVITY, "SensorCallback error type.");
1783     // this data will be delete when callback execute finish
1784     GravityData* nowGravityData = reinterpret_cast<GravityData*>(event->data);
1785     gravityData = { nowGravityData->x, nowGravityData->y, nowGravityData->z };
1786 }
1787 
CalcSensorRotation(int32_t sensorDegree)1788 int32_t HCaptureSession::CalcSensorRotation(int32_t sensorDegree)
1789 {
1790     // Use ROTATION_0 when degree range is [0, 30]∪[330, 359]
1791     if (sensorDegree >= 0 && (sensorDegree <= 30 || sensorDegree >= 330)) {
1792         return STREAM_ROTATE_0;
1793     } else if (sensorDegree >= 60 && sensorDegree <= 120) { // Use ROTATION_90 when degree range is [60, 120]
1794         return STREAM_ROTATE_90;
1795     } else if (sensorDegree >= 150 && sensorDegree <= 210) { // Use ROTATION_180 when degree range is [150, 210]
1796         return STREAM_ROTATE_180;
1797     } else if (sensorDegree >= 240 && sensorDegree <= 300) { // Use ROTATION_270 when degree range is [240, 300]
1798         return STREAM_ROTATE_270;
1799     } else {
1800         return 0;
1801     }
1802 }
1803 
CalcRotationDegree(GravityData data)1804 int32_t HCaptureSession::CalcRotationDegree(GravityData data)
1805 {
1806     float x = data.x;
1807     float y = data.y;
1808     float z = data.z;
1809     int degree = -1;
1810     if ((x * x + y * y) * VALID_INCLINATION_ANGLE_THRESHOLD_COEFFICIENT < z * z) {
1811         return degree;
1812     }
1813     // arccotx = pi / 2 - arctanx, 90 is used to calculate acot(in degree); degree = rad / pi * 180
1814     degree = 90 - static_cast<int>(round(atan2(y, -x) / M_PI * 180));
1815     // Normalize the degree to the range of 0~360
1816     return degree >= 0 ? degree % 360 : degree % 360 + 360;
1817 }
1818 #endif
1819 
StartMovingPhotoEncode(int32_t rotation,uint64_t timestamp,int32_t format,int32_t captureId)1820 void HCaptureSession::StartMovingPhotoEncode(int32_t rotation, uint64_t timestamp, int32_t format, int32_t captureId)
1821 {
1822     if (!isSetMotionPhoto_) {
1823         return;
1824     }
1825     int32_t addMirrorRotation = 0;
1826     #ifdef CAMERA_USE_SENSOR
1827     sensorRotation = CalcSensorRotation(CalcRotationDegree(gravityData));
1828     #endif
1829     MEDIA_INFO_LOG("sensorRotation is %{public}d", sensorRotation);
1830     if ((sensorRotation == STREAM_ROTATE_0 || sensorRotation == STREAM_ROTATE_180) && isMovingPhotoMirror_) {
1831         addMirrorRotation = STREAM_ROTATE_180;
1832     }
1833     int32_t realRotation = GetSensorOritation() + rotation + addMirrorRotation;
1834     realRotation = realRotation % ROTATION_360;
1835     StartRecord(timestamp, realRotation, captureId);
1836 }
1837 
CreateDisplayName(const std::string & suffix)1838 std::string HCaptureSession::CreateDisplayName(const std::string& suffix)
1839 {
1840     struct tm currentTime;
1841     std::string formattedTime = "";
1842     if (GetSystemCurrentTime(&currentTime)) {
1843         std::stringstream ss;
1844         ss << prefix << std::setw(yearWidth) << std::setfill(placeholder) << currentTime.tm_year + startYear
1845            << std::setw(otherWidth) << std::setfill(placeholder) << (currentTime.tm_mon + 1)
1846            << std::setw(otherWidth) << std::setfill(placeholder) << currentTime.tm_mday
1847            << connector << std::setw(otherWidth) << std::setfill(placeholder) << currentTime.tm_hour
1848            << std::setw(otherWidth) << std::setfill(placeholder) << currentTime.tm_min
1849            << std::setw(otherWidth) << std::setfill(placeholder) << currentTime.tm_sec;
1850         formattedTime = ss.str();
1851     } else {
1852         MEDIA_ERR_LOG("Failed to get current time.");
1853     }
1854     if (lastDisplayName_ == formattedTime) {
1855         saveIndex++;
1856         formattedTime = formattedTime + connector + std::to_string(saveIndex);
1857         MEDIA_INFO_LOG("CreateDisplayName is %{private}s", formattedTime.c_str());
1858         return formattedTime;
1859     }
1860     lastDisplayName_ = formattedTime;
1861     saveIndex = 0;
1862     MEDIA_INFO_LOG("CreateDisplayName is %{private}s", formattedTime.c_str());
1863     return formattedTime;
1864 }
1865 
CreateBurstDisplayName(int32_t seqId)1866 std::string HCaptureSession::CreateBurstDisplayName(int32_t seqId)
1867 {
1868     struct tm currentTime;
1869     std::string formattedTime = "";
1870     std::stringstream ss;
1871     if (seqId == 1) {
1872         if (!GetSystemCurrentTime(&currentTime)) {
1873             MEDIA_ERR_LOG("Failed to get current time.");
1874             return formattedTime;
1875         }
1876         ss << prefix << std::setw(yearWidth) << std::setfill(placeholder) << currentTime.tm_year + startYear
1877             << std::setw(otherWidth) << std::setfill(placeholder) << (currentTime.tm_mon + 1)
1878             << std::setw(otherWidth) << std::setfill(placeholder) << currentTime.tm_mday << connector
1879             << std::setw(otherWidth) << std::setfill(placeholder) << currentTime.tm_hour
1880             << std::setw(otherWidth) << std::setfill(placeholder) << currentTime.tm_min
1881             << std::setw(otherWidth) << std::setfill(placeholder) << currentTime.tm_sec
1882             << connector << burstTag;
1883         lastBurstPrefix_ = ss.str();
1884         MEDIA_DEBUG_LOG("burst prefix is %{private}s", lastBurstPrefix_.c_str());
1885         ss  << std::setw(burstWidth) << std::setfill(placeholder) << seqId
1886             << coverTag;
1887     } else {
1888         ss << lastBurstPrefix_ << std::setw(burstWidth) << std::setfill(placeholder) << seqId;
1889     }
1890     formattedTime = ss.str();
1891     MEDIA_INFO_LOG("CreateBurstDisplayName is %{private}s", formattedTime.c_str());
1892     return formattedTime;
1893 }
1894 
1895 typedef PhotoAssetIntf* (*GetPhotoAssetProxy)(int32_t);
1896 
CreateMediaLibrary(sptr<CameraPhotoProxy> & photoProxy,std::string & uri,int32_t & cameraShotType,std::string & burstKey,int64_t timestamp)1897 int32_t HCaptureSession::CreateMediaLibrary(sptr<CameraPhotoProxy> &photoProxy,
1898     std::string &uri, int32_t &cameraShotType, std::string &burstKey, int64_t timestamp)
1899 {
1900     CAMERA_SYNC_TRACE;
1901     constexpr int32_t movingPhotoShotType = 2;
1902     constexpr int32_t imageShotType = 0;
1903     cameraShotType = isSetMotionPhoto_ ? movingPhotoShotType : imageShotType;
1904     MessageParcel data;
1905     photoProxy->WriteToParcel(data);
1906     photoProxy->CameraFreeBufferHandle();
1907     sptr<CameraServerPhotoProxy> cameraPhotoProxy = new CameraServerPhotoProxy();
1908     cameraPhotoProxy->ReadFromParcel(data);
1909     cameraPhotoProxy->SetDisplayName(CreateDisplayName(suffixJpeg));
1910     cameraPhotoProxy->SetShootingMode(opMode_);
1911     int32_t captureId = cameraPhotoProxy->GetCaptureId();
1912     std::string imageId = cameraPhotoProxy->GetPhotoId();
1913     bool isBursting = false;
1914     bool isCoverPhoto = false;
1915     auto captureStreams = streamContainer_.GetStreams(StreamType::CAPTURE);
1916     for (auto& stream : captureStreams) {
1917         CHECK_AND_CONTINUE_LOG(stream != nullptr, "stream is null");
1918         MEDIA_INFO_LOG("CreateMediaLibrary get captureStream");
1919         auto streamCapture = CastStream<HStreamCapture>(stream);
1920         isBursting = streamCapture->IsBurstCapture(captureId);
1921         if (isBursting) {
1922             burstKey = streamCapture->GetBurstKey(captureId);
1923             streamCapture->SetBurstImages(captureId, imageId);
1924             isCoverPhoto = streamCapture->IsBurstCover(captureId);
1925             int32_t imageSeq = streamCapture->GetCurBurstSeq(captureId);
1926             cameraPhotoProxy->SetDisplayName(CreateBurstDisplayName(imageSeq));
1927             streamCapture->CheckResetBurstKey(captureId);
1928             MEDIA_INFO_LOG("isBursting burstKey:%{public}s isCoverPhoto:%{public}d", burstKey.c_str(), isCoverPhoto);
1929             int32_t burstShotType = 3;
1930             cameraShotType = burstShotType;
1931             cameraPhotoProxy->SetBurstInfo(burstKey, isCoverPhoto);
1932             break;
1933         }
1934     }
1935     MEDIA_INFO_LOG("GetLocation latitude:%{public}f, quality:%{public}d, format:%{public}d,",
1936         cameraPhotoProxy->GetLatitude(), cameraPhotoProxy->GetPhotoQuality(), cameraPhotoProxy->GetFormat());
1937     GetPhotoAssetProxy getPhotoAssetProxy = (GetPhotoAssetProxy)dynamicLoader_->GetFuntion(
1938         MEDIA_LIB_SO, "createPhotoAssetIntf");
1939     PhotoAssetIntf* photoAssetProxy = getPhotoAssetProxy(cameraShotType);
1940     photoAssetProxy->AddPhotoProxy((sptr<PhotoProxy>&)cameraPhotoProxy);
1941     uri = photoAssetProxy->GetPhotoAssetUri();
1942     if (!isBursting && isSetMotionPhoto_ && taskManager_) {
1943         MEDIA_INFO_LOG("taskManager setVideoFd start");
1944         taskManager_->SetVideoFd(timestamp, photoAssetProxy);
1945     } else {
1946         delete photoAssetProxy;
1947     }
1948     return CAMERA_OK;
1949 }
1950 
CreateMediaLibrary(std::unique_ptr<Media::Picture> picture,sptr<CameraPhotoProxy> & photoProxy,std::string & uri,int32_t & cameraShotType,std::string & burstKey,int64_t timestamp)1951 int32_t HCaptureSession::CreateMediaLibrary(std::unique_ptr<Media::Picture> picture, sptr<CameraPhotoProxy> &photoProxy,
1952     std::string &uri, int32_t &cameraShotType, std::string &burstKey, int64_t timestamp)
1953 {
1954     constexpr int32_t movingPhotoShotType = 2;
1955     constexpr int32_t imageShotType = 0;
1956     cameraShotType = isSetMotionPhoto_ ? movingPhotoShotType : imageShotType;
1957     MessageParcel data;
1958     photoProxy->WriteToParcel(data);
1959     photoProxy->CameraFreeBufferHandle();
1960     sptr<CameraServerPhotoProxy> cameraPhotoProxy = new CameraServerPhotoProxy();
1961     cameraPhotoProxy->ReadFromParcel(data);
1962     PhotoFormat photoFormat = cameraPhotoProxy->GetFormat();
1963     std::string formatSuffix = photoFormat == PhotoFormat::HEIF ? suffixHeif : suffixJpeg;
1964     cameraPhotoProxy->SetDisplayName(CreateDisplayName(formatSuffix));
1965     cameraPhotoProxy->SetShootingMode(opMode_);
1966     MEDIA_INFO_LOG("GetLocation latitude:%{public}f, longitude:%{public}f",
1967         cameraPhotoProxy->GetLatitude(), cameraPhotoProxy->GetLongitude());
1968 
1969     GetPhotoAssetProxy getPhotoAssetProxy = (GetPhotoAssetProxy)dynamicLoader_->GetFuntion(
1970         MEDIA_LIB_SO, "createPhotoAssetIntf");
1971     PhotoAssetIntf* photoAssetProxy = getPhotoAssetProxy(cameraShotType);
1972     photoAssetProxy->AddPhotoProxy((sptr<PhotoProxy>&)cameraPhotoProxy);
1973     std::shared_ptr<Media::Picture> picturePtr(picture.release());
1974     uri = photoAssetProxy->GetPhotoAssetUri();
1975     DeferredProcessing::DeferredProcessingService::GetInstance().
1976         NotifyLowQualityImage(photoAssetProxy->GetUserId(), uri, picturePtr);
1977     if (isSetMotionPhoto_) {
1978         int32_t videoFd = photoAssetProxy->GetVideoFd();
1979         MEDIA_DEBUG_LOG("videFd:%{public}d", videoFd);
1980         if (taskManager_) {
1981             taskManager_->SetVideoFd(timestamp, photoAssetProxy);
1982         }
1983     } else {
1984         delete photoAssetProxy;
1985     }
1986     return CAMERA_OK;
1987 }
1988 
SetFeatureMode(int32_t featureMode)1989 int32_t HCaptureSession::SetFeatureMode(int32_t featureMode)
1990 {
1991     MEDIA_INFO_LOG("SetFeatureMode is called!");
1992     featureMode_ = featureMode;
1993     return CAMERA_OK;
1994 }
1995 
OnCaptureStarted(int32_t captureId,const std::vector<int32_t> & streamIds)1996 int32_t StreamOperatorCallback::OnCaptureStarted(int32_t captureId, const std::vector<int32_t>& streamIds)
1997 {
1998     MEDIA_INFO_LOG("StreamOperatorCallback::OnCaptureStarted captureId:%{public}d, streamIds:%{public}s", captureId,
1999         Container2String(streamIds.begin(), streamIds.end()).c_str());
2000     std::lock_guard<std::mutex> lock(cbMutex_);
2001     for (auto& streamId : streamIds) {
2002         sptr<HStreamCommon> curStream = GetHdiStreamByStreamID(streamId);
2003         if (curStream == nullptr) {
2004             MEDIA_ERR_LOG("StreamOperatorCallback::OnCaptureStarted StreamId: %{public}d not found", streamId);
2005             return CAMERA_INVALID_ARG;
2006         } else if (curStream->GetStreamType() == StreamType::REPEAT) {
2007             CastStream<HStreamRepeat>(curStream)->OnFrameStarted();
2008             CameraReportUtils::GetInstance().SetOpenCamPerfEndInfo();
2009             CameraReportUtils::GetInstance().SetModeChangePerfEndInfo();
2010             CameraReportUtils::GetInstance().SetSwitchCamPerfEndInfo();
2011         } else if (curStream->GetStreamType() == StreamType::CAPTURE) {
2012             CastStream<HStreamCapture>(curStream)->OnCaptureStarted(captureId);
2013         }
2014     }
2015     return CAMERA_OK;
2016 }
2017 
StartRecord(uint64_t timestamp,int32_t rotation,int32_t captureId)2018 void HCaptureSession::StartRecord(uint64_t timestamp, int32_t rotation, int32_t captureId)
2019 {
2020     if (isSetMotionPhoto_) {
2021         taskManager_->SubmitTask([this, timestamp, rotation, captureId]() {
2022             this->StartOnceRecord(timestamp, rotation, captureId);
2023         });
2024     }
2025 }
2026 
SessionDrainImageCallback(std::vector<sptr<FrameRecord>> & frameCacheList,wptr<MovingPhotoListener> listener,wptr<MovingPhotoVideoCache> cache,uint64_t timestamp,int32_t rotation,int32_t captureId)2027 SessionDrainImageCallback::SessionDrainImageCallback(std::vector<sptr<FrameRecord>>& frameCacheList,
2028                                                      wptr<MovingPhotoListener> listener,
2029                                                      wptr<MovingPhotoVideoCache> cache,
2030                                                      uint64_t timestamp,
2031                                                      int32_t rotation,
2032                                                      int32_t captureId)
2033     : frameCacheList_(frameCacheList), listener_(listener), videoCache_(cache), timestamp_(timestamp),
2034       rotation_(rotation), captureId_(captureId)
2035 {
2036 }
2037 
~SessionDrainImageCallback()2038 SessionDrainImageCallback::~SessionDrainImageCallback()
2039 {
2040     MEDIA_INFO_LOG("~SessionDrainImageCallback enter");
2041 }
2042 
OnDrainImage(sptr<FrameRecord> frame)2043 void SessionDrainImageCallback::OnDrainImage(sptr<FrameRecord> frame)
2044 {
2045     MEDIA_INFO_LOG("OnDrainImage enter");
2046     {
2047         std::lock_guard<std::mutex> lock(mutex_);
2048         frameCacheList_.push_back(frame);
2049     }
2050     auto videoCache = videoCache_.promote();
2051     if (frame->IsIdle() && videoCache) {
2052         videoCache->CacheFrame(frame);
2053     } else if (frame->IsFinishCache() && videoCache) {
2054         videoCache->OnImageEncoded(frame, true);
2055     } else {
2056         MEDIA_INFO_LOG("videoCache and frame is not useful");
2057     }
2058 }
2059 
OnDrainImageFinish(bool isFinished)2060 void SessionDrainImageCallback::OnDrainImageFinish(bool isFinished)
2061 {
2062     MEDIA_INFO_LOG("OnDrainImageFinish enter");
2063     auto videoCache = videoCache_.promote();
2064     if (videoCache) {
2065         std::lock_guard<std::mutex> lock(mutex_);
2066         videoCache_->GetFrameCachedResult(
2067             frameCacheList_,
2068             [videoCache](const std::vector<sptr<FrameRecord>>& frameRecords,
2069                          uint64_t timestamp,
2070                          int32_t rotation,
2071                         int32_t captureId) { videoCache->DoMuxerVideo(frameRecords, timestamp, rotation, captureId); },
2072             timestamp_,
2073             rotation_,
2074             captureId_);
2075     }
2076     auto listener = listener_.promote();
2077     if (listener && isFinished) {
2078         listener->RemoveDrainImageManager(this);
2079     }
2080 }
2081 
StartOnceRecord(uint64_t timestamp,int32_t rotation,int32_t captureId)2082 void HCaptureSession::StartOnceRecord(uint64_t timestamp, int32_t rotation, int32_t captureId)
2083 {
2084     MEDIA_INFO_LOG("StartOnceRecord enter");
2085     // frameCacheList only used by now thread
2086     std::lock_guard<std::mutex> lock(movingPhotoStatusLock_);
2087     std::vector<sptr<FrameRecord>> frameCacheList;
2088     sptr<SessionDrainImageCallback> imageCallback = new SessionDrainImageCallback(frameCacheList,
2089         livephotoListener_, videoCache_, timestamp, rotation, captureId);
2090     livephotoListener_->ClearCache(timestamp);
2091     livephotoListener_->DrainOutImage(imageCallback);
2092     MEDIA_INFO_LOG("StartOnceRecord end");
2093 }
2094 
OnCaptureStarted_V1_2(int32_t captureId,const std::vector<OHOS::HDI::Camera::V1_2::CaptureStartedInfo> & infos)2095 int32_t StreamOperatorCallback::OnCaptureStarted_V1_2(
2096     int32_t captureId, const std::vector<OHOS::HDI::Camera::V1_2::CaptureStartedInfo>& infos)
2097 {
2098     MEDIA_INFO_LOG("StreamOperatorCallback::OnCaptureStarted_V1_2 captureId:%{public}d", captureId);
2099     std::lock_guard<std::mutex> lock(cbMutex_);
2100     for (auto& captureInfo : infos) {
2101         sptr<HStreamCommon> curStream = GetHdiStreamByStreamID(captureInfo.streamId_);
2102         if (curStream == nullptr) {
2103             MEDIA_ERR_LOG("StreamOperatorCallback::OnCaptureStarted_V1_2 StreamId: %{public}d not found."
2104                           " exposureTime: %{public}u",
2105                 captureInfo.streamId_, captureInfo.exposureTime_);
2106             return CAMERA_INVALID_ARG;
2107         } else if (curStream->GetStreamType() == StreamType::CAPTURE) {
2108             MEDIA_DEBUG_LOG("StreamOperatorCallback::OnCaptureStarted_V1_2 StreamId: %{public}d."
2109                             " exposureTime: %{public}u",
2110                 captureInfo.streamId_, captureInfo.exposureTime_);
2111             CastStream<HStreamCapture>(curStream)->OnCaptureStarted(captureId, captureInfo.exposureTime_);
2112         }
2113     }
2114     return CAMERA_OK;
2115 }
2116 
OnCaptureEnded(int32_t captureId,const std::vector<CaptureEndedInfo> & infos)2117 int32_t StreamOperatorCallback::OnCaptureEnded(int32_t captureId, const std::vector<CaptureEndedInfo>& infos)
2118 {
2119     MEDIA_INFO_LOG("StreamOperatorCallback::OnCaptureEnded");
2120     std::lock_guard<std::mutex> lock(cbMutex_);
2121     for (auto& captureInfo : infos) {
2122         sptr<HStreamCommon> curStream = GetHdiStreamByStreamID(captureInfo.streamId_);
2123         if (curStream == nullptr) {
2124             MEDIA_ERR_LOG("StreamOperatorCallback::OnCaptureEnded StreamId: %{public}d not found."
2125                           " Framecount: %{public}d",
2126                 captureInfo.streamId_, captureInfo.frameCount_);
2127             return CAMERA_INVALID_ARG;
2128         } else if (curStream->GetStreamType() == StreamType::REPEAT) {
2129             CastStream<HStreamRepeat>(curStream)->OnFrameEnded(captureInfo.frameCount_);
2130         } else if (curStream->GetStreamType() == StreamType::CAPTURE) {
2131             CastStream<HStreamCapture>(curStream)->OnCaptureEnded(captureId, captureInfo.frameCount_);
2132         }
2133     }
2134     return CAMERA_OK;
2135 }
2136 
OnCaptureEndedExt(int32_t captureId,const std::vector<OHOS::HDI::Camera::V1_3::CaptureEndedInfoExt> & infos)2137 int32_t StreamOperatorCallback::OnCaptureEndedExt(int32_t captureId,
2138     const std::vector<OHOS::HDI::Camera::V1_3::CaptureEndedInfoExt>& infos)
2139 {
2140     MEDIA_INFO_LOG("StreamOperatorCallback::OnCaptureEndedExt captureId:%{public}d", captureId);
2141     std::lock_guard<std::mutex> lock(cbMutex_);
2142     for (auto& captureInfo : infos) {
2143         sptr<HStreamCommon> curStream = GetHdiStreamByStreamID(captureInfo.streamId_);
2144         if (curStream == nullptr) {
2145             MEDIA_ERR_LOG("StreamOperatorCallback::OnCaptureEndedExt StreamId: %{public}d not found."
2146                           " Framecount: %{public}d",
2147                 captureInfo.streamId_, captureInfo.frameCount_);
2148             return CAMERA_INVALID_ARG;
2149         } else if (curStream->GetStreamType() == StreamType::REPEAT) {
2150             CastStream<HStreamRepeat>(curStream)->OnFrameEnded(captureInfo.frameCount_);
2151             CaptureEndedInfoExt extInfo;
2152             extInfo.streamId = captureInfo.streamId_;
2153             extInfo.frameCount = captureInfo.frameCount_;
2154             extInfo.isDeferredVideoEnhancementAvailable = captureInfo.isDeferredVideoEnhancementAvailable_;
2155             extInfo.videoId = captureInfo.videoId_;
2156             MEDIA_INFO_LOG("StreamOperatorCallback::OnCaptureEndedExt captureId:%{public}d videoId:%{public}s "
2157                            "isDeferredVideo:%{public}d",
2158                 captureId, extInfo.videoId.c_str(), extInfo.isDeferredVideoEnhancementAvailable);
2159             CastStream<HStreamRepeat>(curStream)->OnDeferredVideoEnhancementInfo(extInfo);
2160         }
2161     }
2162     return CAMERA_OK;
2163 }
2164 
OnCaptureError(int32_t captureId,const std::vector<CaptureErrorInfo> & infos)2165 int32_t StreamOperatorCallback::OnCaptureError(int32_t captureId, const std::vector<CaptureErrorInfo>& infos)
2166 {
2167     MEDIA_INFO_LOG("StreamOperatorCallback::OnCaptureError");
2168     std::lock_guard<std::mutex> lock(cbMutex_);
2169     for (auto& errInfo : infos) {
2170         sptr<HStreamCommon> curStream = GetHdiStreamByStreamID(errInfo.streamId_);
2171         if (curStream == nullptr) {
2172             MEDIA_ERR_LOG("StreamOperatorCallback::OnCaptureError StreamId: %{public}d not found."
2173                           " Error: %{public}d",
2174                 errInfo.streamId_, errInfo.error_);
2175             return CAMERA_INVALID_ARG;
2176         } else if (curStream->GetStreamType() == StreamType::REPEAT) {
2177             CastStream<HStreamRepeat>(curStream)->OnFrameError(errInfo.error_);
2178         } else if (curStream->GetStreamType() == StreamType::CAPTURE) {
2179             auto captureStream = CastStream<HStreamCapture>(curStream);
2180             captureStream->rotationMap_.Erase(captureId);
2181             captureStream->OnCaptureError(captureId, errInfo.error_);
2182         }
2183     }
2184     return CAMERA_OK;
2185 }
2186 
OnFrameShutter(int32_t captureId,const std::vector<int32_t> & streamIds,uint64_t timestamp)2187 int32_t StreamOperatorCallback::OnFrameShutter(
2188     int32_t captureId, const std::vector<int32_t>& streamIds, uint64_t timestamp)
2189 {
2190     MEDIA_INFO_LOG("StreamOperatorCallback::OnFrameShutter ts is:%{public}" PRId64, timestamp);
2191     std::lock_guard<std::mutex> lock(cbMutex_);
2192     for (auto& streamId : streamIds) {
2193         sptr<HStreamCommon> curStream = GetHdiStreamByStreamID(streamId);
2194         if ((curStream != nullptr) && (curStream->GetStreamType() == StreamType::CAPTURE)) {
2195             auto captureStream = CastStream<HStreamCapture>(curStream);
2196             int32_t rotation = 0;
2197             captureStream->rotationMap_.Find(captureId, rotation);
2198             StartMovingPhotoEncode(rotation, timestamp, captureStream->format_, captureId);
2199             captureStream->OnFrameShutter(captureId, timestamp);
2200         } else {
2201             MEDIA_ERR_LOG("StreamOperatorCallback::OnFrameShutter StreamId: %{public}d not found", streamId);
2202             return CAMERA_INVALID_ARG;
2203         }
2204     }
2205     return CAMERA_OK;
2206 }
2207 
OnFrameShutterEnd(int32_t captureId,const std::vector<int32_t> & streamIds,uint64_t timestamp)2208 int32_t StreamOperatorCallback::OnFrameShutterEnd(
2209     int32_t captureId, const std::vector<int32_t>& streamIds, uint64_t timestamp)
2210 {
2211     MEDIA_INFO_LOG("StreamOperatorCallback::OnFrameShutterEnd ts is:%{public}" PRId64, timestamp);
2212     std::lock_guard<std::mutex> lock(cbMutex_);
2213     for (auto& streamId : streamIds) {
2214         sptr<HStreamCommon> curStream = GetHdiStreamByStreamID(streamId);
2215         if ((curStream != nullptr) && (curStream->GetStreamType() == StreamType::CAPTURE)) {
2216             auto captureStream = CastStream<HStreamCapture>(curStream);
2217             captureStream->rotationMap_.Erase(captureId);
2218             captureStream->OnFrameShutterEnd(captureId, timestamp);
2219         } else {
2220             MEDIA_ERR_LOG("StreamOperatorCallback::OnFrameShutterEnd StreamId: %{public}d not found", streamId);
2221             return CAMERA_INVALID_ARG;
2222         }
2223     }
2224     return CAMERA_OK;
2225 }
2226 
OnCaptureReady(int32_t captureId,const std::vector<int32_t> & streamIds,uint64_t timestamp)2227 int32_t StreamOperatorCallback::OnCaptureReady(
2228     int32_t captureId, const std::vector<int32_t>& streamIds, uint64_t timestamp)
2229 {
2230     MEDIA_DEBUG_LOG("StreamOperatorCallback::OnCaptureReady");
2231     std::lock_guard<std::mutex> lock(cbMutex_);
2232     for (auto& streamId : streamIds) {
2233         sptr<HStreamCommon> curStream = GetHdiStreamByStreamID(streamId);
2234         if ((curStream != nullptr) && (curStream->GetStreamType() == StreamType::CAPTURE)) {
2235             CastStream<HStreamCapture>(curStream)->OnCaptureReady(captureId, timestamp);
2236         } else {
2237             MEDIA_ERR_LOG("StreamOperatorCallback::OnCaptureReady StreamId: %{public}d not found", streamId);
2238             return CAMERA_INVALID_ARG;
2239         }
2240     }
2241     return CAMERA_OK;
2242 }
2243 
OnResult(int32_t streamId,const std::vector<uint8_t> & result)2244 int32_t StreamOperatorCallback::OnResult(int32_t streamId, const std::vector<uint8_t>& result)
2245 {
2246     MEDIA_DEBUG_LOG("StreamOperatorCallback::OnResult");
2247     sptr<HStreamCommon> curStream;
2248     const int32_t metaStreamId = -1;
2249     if (streamId == metaStreamId) {
2250         curStream = GetStreamByStreamID(streamId);
2251     } else {
2252         curStream = GetHdiStreamByStreamID(streamId);
2253     }
2254     if ((curStream != nullptr) && (curStream->GetStreamType() == StreamType::METADATA)) {
2255         CastStream<HStreamMetadata>(curStream)->OnMetaResult(streamId, result);
2256     } else {
2257         MEDIA_ERR_LOG("StreamOperatorCallback::OnResult StreamId: %{public}d is null or not Not adapted", streamId);
2258         return CAMERA_INVALID_ARG;
2259     }
2260     return CAMERA_OK;
2261 }
2262 
StateMachine()2263 StateMachine::StateMachine()
2264 {
2265     stateTransferMap_[static_cast<uint32_t>(CaptureSessionState::SESSION_INIT)] = {
2266         CaptureSessionState::SESSION_CONFIG_INPROGRESS, CaptureSessionState::SESSION_RELEASED
2267     };
2268 
2269     stateTransferMap_[static_cast<uint32_t>(CaptureSessionState::SESSION_CONFIG_INPROGRESS)] = {
2270         CaptureSessionState::SESSION_CONFIG_COMMITTED, CaptureSessionState::SESSION_RELEASED
2271     };
2272 
2273     stateTransferMap_[static_cast<uint32_t>(CaptureSessionState::SESSION_CONFIG_COMMITTED)] = {
2274         CaptureSessionState::SESSION_CONFIG_INPROGRESS, CaptureSessionState::SESSION_STARTED,
2275         CaptureSessionState::SESSION_RELEASED
2276     };
2277 
2278     stateTransferMap_[static_cast<uint32_t>(CaptureSessionState::SESSION_STARTED)] = {
2279         CaptureSessionState::SESSION_CONFIG_INPROGRESS, CaptureSessionState::SESSION_CONFIG_COMMITTED,
2280         CaptureSessionState::SESSION_RELEASED
2281     };
2282 
2283     stateTransferMap_[static_cast<uint32_t>(CaptureSessionState::SESSION_RELEASED)] = {};
2284 }
2285 
CheckTransfer(CaptureSessionState targetState)2286 bool StateMachine::CheckTransfer(CaptureSessionState targetState)
2287 {
2288     std::lock_guard<std::recursive_mutex> lock(sessionStateLock_);
2289     return any_of(stateTransferMap_[static_cast<uint32_t>(currentState_)].begin(),
2290         stateTransferMap_[static_cast<uint32_t>(currentState_)].end(),
2291         [&targetState](const auto& state) {return state == targetState; });
2292 }
2293 
Transfer(CaptureSessionState targetState)2294 bool StateMachine::Transfer(CaptureSessionState targetState)
2295 {
2296     std::lock_guard<std::recursive_mutex> lock(sessionStateLock_);
2297     if (CheckTransfer(targetState)) {
2298         currentState_ = targetState;
2299         return true;
2300     }
2301     return false;
2302 }
2303 
AddStream(sptr<HStreamCommon> stream)2304 bool StreamContainer::AddStream(sptr<HStreamCommon> stream)
2305 {
2306     std::lock_guard<std::mutex> lock(streamsLock_);
2307     auto& list = streams_[stream->GetStreamType()];
2308     auto it = std::find_if(list.begin(), list.end(), [stream](auto item) { return item == stream; });
2309     if (it == list.end()) {
2310         list.emplace_back(stream);
2311         return true;
2312     }
2313     return false;
2314 }
2315 
RemoveStream(sptr<HStreamCommon> stream)2316 bool StreamContainer::RemoveStream(sptr<HStreamCommon> stream)
2317 {
2318     std::lock_guard<std::mutex> lock(streamsLock_);
2319     auto& list = streams_[stream->GetStreamType()];
2320     auto it = std::find_if(list.begin(), list.end(), [stream](auto item) { return item == stream; });
2321     if (it == list.end()) {
2322         return false;
2323     }
2324     list.erase(it);
2325     return true;
2326 }
2327 
GetStream(int32_t streamId)2328 sptr<HStreamCommon> StreamContainer::GetStream(int32_t streamId)
2329 {
2330     std::lock_guard<std::mutex> lock(streamsLock_);
2331     for (auto& pair : streams_) {
2332         for (auto& stream : pair.second) {
2333             if (stream->GetFwkStreamId() == streamId) {
2334                 return stream;
2335             }
2336         }
2337     }
2338     return nullptr;
2339 }
2340 
GetHdiStream(int32_t streamId)2341 sptr<HStreamCommon> StreamContainer::GetHdiStream(int32_t streamId)
2342 {
2343     std::lock_guard<std::mutex> lock(streamsLock_);
2344     for (auto& pair : streams_) {
2345         for (auto& stream : pair.second) {
2346             if (stream->GetHdiStreamId() == streamId) {
2347                 return stream;
2348             }
2349         }
2350     }
2351     return nullptr;
2352 }
2353 
Clear()2354 void StreamContainer::Clear()
2355 {
2356     std::lock_guard<std::mutex> lock(streamsLock_);
2357     streams_.clear();
2358 }
2359 
Size()2360 size_t StreamContainer::Size()
2361 {
2362     std::lock_guard<std::mutex> lock(streamsLock_);
2363     size_t totalSize = 0;
2364     for (auto& pair : streams_) {
2365         totalSize += pair.second.size();
2366     }
2367     return totalSize;
2368 }
2369 
GetStreams(const StreamType streamType)2370 std::list<sptr<HStreamCommon>> StreamContainer::GetStreams(const StreamType streamType)
2371 {
2372     std::lock_guard<std::mutex> lock(streamsLock_);
2373     std::list<sptr<HStreamCommon>> totalOrderedStreams;
2374     for (auto& stream : streams_[streamType]) {
2375         auto insertPos = std::find_if(totalOrderedStreams.begin(), totalOrderedStreams.end(),
2376             [&stream](auto& it) { return stream->GetFwkStreamId() <= it->GetFwkStreamId(); });
2377         totalOrderedStreams.emplace(insertPos, stream);
2378     }
2379     return totalOrderedStreams;
2380 }
2381 
GetAllStreams()2382 std::list<sptr<HStreamCommon>> StreamContainer::GetAllStreams()
2383 {
2384     std::lock_guard<std::mutex> lock(streamsLock_);
2385     std::list<sptr<HStreamCommon>> totalOrderedStreams;
2386     for (auto& pair : streams_) {
2387         for (auto& stream : pair.second) {
2388             auto insertPos = std::find_if(totalOrderedStreams.begin(), totalOrderedStreams.end(),
2389                 [&stream](auto& it) { return stream->GetFwkStreamId() <= it->GetFwkStreamId(); });
2390             totalOrderedStreams.emplace(insertPos, stream);
2391         }
2392     }
2393     return totalOrderedStreams;
2394 }
2395 
MovingPhotoListener(sptr<MovingPhotoSurfaceWrapper> surfaceWrapper,sptr<Surface> metaSurface,shared_ptr<FixedSizeList<MetaElementType>> metaCache,uint32_t preCacheFrameCount,uint32_t postCacheFrameCount)2396 MovingPhotoListener::MovingPhotoListener(sptr<MovingPhotoSurfaceWrapper> surfaceWrapper, sptr<Surface> metaSurface,
2397     shared_ptr<FixedSizeList<MetaElementType>> metaCache, uint32_t preCacheFrameCount, uint32_t postCacheFrameCount)
2398     : movingPhotoSurfaceWrapper_(surfaceWrapper),
2399       metaSurface_(metaSurface),
2400       metaCache_(metaCache),
2401       recorderBufferQueue_("videoBuffer", preCacheFrameCount),
2402       postCacheFrameCount_(postCacheFrameCount)
2403 {
2404     shutterTime_ = 0;
2405 }
2406 
~MovingPhotoListener()2407 MovingPhotoListener::~MovingPhotoListener()
2408 {
2409     recorderBufferQueue_.SetActive(false);
2410     metaCache_->clear();
2411     recorderBufferQueue_.Clear();
2412     MEDIA_ERR_LOG("HStreamRepeat::LivePhotoListener ~ end");
2413 }
2414 
RemoveDrainImageManager(sptr<SessionDrainImageCallback> callback)2415 void MovingPhotoListener::RemoveDrainImageManager(sptr<SessionDrainImageCallback> callback)
2416 {
2417     callbackMap_.Erase(callback);
2418     MEDIA_INFO_LOG("RemoveDrainImageManager drainImageManagerVec_ Start %d", callbackMap_.Size());
2419 }
2420 
ClearCache(uint64_t timestamp)2421 void MovingPhotoListener::ClearCache(uint64_t timestamp)
2422 {
2423     if (!isNeededClear_.load()) {
2424         return;
2425     }
2426     MEDIA_INFO_LOG("ClearCache enter");
2427     shutterTime_ = static_cast<int64_t>(timestamp);
2428     while (!recorderBufferQueue_.Empty()) {
2429         sptr<FrameRecord> popFrame = recorderBufferQueue_.Front();
2430         MEDIA_DEBUG_LOG("surface_ release surface buffer %{public}llu, timestamp %{public}llu",
2431             (long long unsigned)popFrame->GetTimeStamp(), (long long unsigned)timestamp);
2432         if (popFrame->GetTimeStamp() > shutterTime_) {
2433             isNeededClear_ = false;
2434             MEDIA_INFO_LOG("ClearCache end");
2435             return;
2436         }
2437         recorderBufferQueue_.Pop();
2438         popFrame->ReleaseSurfaceBuffer(movingPhotoSurfaceWrapper_);
2439     }
2440     isNeededPop_ = true;
2441 }
2442 
SetClearFlag()2443 void MovingPhotoListener::SetClearFlag()
2444 {
2445     MEDIA_INFO_LOG("need clear cache!");
2446     isNeededClear_ = true;
2447 }
2448 
StopDrainOut()2449 void MovingPhotoListener::StopDrainOut()
2450 {
2451     MEDIA_INFO_LOG("StopDrainOut drainImageManagerVec_ Start %d", callbackMap_.Size());
2452     callbackMap_.Iterate([](const sptr<SessionDrainImageCallback> callback, sptr<DrainImageManager> manager) {
2453         manager->DrainFinish(false);
2454     });
2455     callbackMap_.Clear();
2456 }
2457 
OnBufferArrival(sptr<SurfaceBuffer> buffer,int64_t timestamp,GraphicTransformType transform)2458 void MovingPhotoListener::OnBufferArrival(sptr<SurfaceBuffer> buffer, int64_t timestamp, GraphicTransformType transform)
2459 {
2460     MEDIA_DEBUG_LOG("OnBufferArrival timestamp %{public}llu", (long long unsigned)timestamp);
2461     if (recorderBufferQueue_.Full()) {
2462         MEDIA_DEBUG_LOG("surface_ release surface buffer");
2463         sptr<FrameRecord> popFrame = recorderBufferQueue_.Pop();
2464         popFrame->ReleaseSurfaceBuffer(movingPhotoSurfaceWrapper_);
2465         popFrame->ReleaseMetaBuffer(metaSurface_, true);
2466         MEDIA_DEBUG_LOG("surface_ release surface buffer: %{public}s, refCount: %{public}d",
2467             popFrame->GetFrameId().c_str(), popFrame->GetSptrRefCount());
2468     }
2469     MEDIA_DEBUG_LOG("surface_ push buffer %{public}d x %{public}d, stride is %{public}d",
2470         buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight(), buffer->GetStride());
2471     sptr<FrameRecord> frameRecord = new (std::nothrow) FrameRecord(buffer, timestamp, transform);
2472     CHECK_AND_RETURN_LOG(frameRecord != nullptr, "MovingPhotoListener::OnBufferAvailable create FrameRecord fail!");
2473     if (isNeededClear_ && isNeededPop_) {
2474         if (timestamp < shutterTime_) {
2475             frameRecord->ReleaseSurfaceBuffer(movingPhotoSurfaceWrapper_);
2476             MEDIA_INFO_LOG("Drop this frame in cache");
2477             return;
2478         } else {
2479             isNeededClear_ = false;
2480             isNeededPop_ = false;
2481             MEDIA_INFO_LOG("ClearCache end");
2482         }
2483     }
2484     recorderBufferQueue_.Push(frameRecord);
2485     auto metaPair = metaCache_->find_if([timestamp](const MetaElementType& value) {
2486         return value.first == timestamp;
2487     });
2488     if (metaPair.has_value()) {
2489         MEDIA_DEBUG_LOG("frame has meta");
2490         frameRecord->SetMetaBuffer(metaPair.value().second);
2491     }
2492     vector<sptr<SessionDrainImageCallback>> callbacks;
2493     callbackMap_.Iterate([frameRecord, &callbacks](const sptr<SessionDrainImageCallback> callback,
2494         sptr<DrainImageManager> manager) {
2495         callbacks.push_back(callback);
2496     });
2497     for (sptr<SessionDrainImageCallback> drainImageCallback : callbacks) {
2498         sptr<DrainImageManager> drainImageManager;
2499         if (callbackMap_.Find(drainImageCallback, drainImageManager)) {
2500             std::lock_guard<std::mutex> lock(drainImageManager->drainImageLock_);
2501             drainImageManager->DrainImage(frameRecord);
2502         }
2503     }
2504 }
2505 
DrainOutImage(sptr<SessionDrainImageCallback> drainImageCallback)2506 void MovingPhotoListener::DrainOutImage(sptr<SessionDrainImageCallback> drainImageCallback)
2507 {
2508     sptr<DrainImageManager> drainImageManager =
2509         new DrainImageManager(drainImageCallback, recorderBufferQueue_.Size() + postCacheFrameCount_);
2510     {
2511         MEDIA_INFO_LOG("DrainOutImage enter %{public}zu", recorderBufferQueue_.Size());
2512         callbackMap_.Insert(drainImageCallback, drainImageManager);
2513     }
2514     // Convert recorderBufferQueue_ to a vector
2515     std::vector<sptr<FrameRecord>> frameList = recorderBufferQueue_.GetAllElements();
2516     if (!frameList.empty()) {
2517         frameList.back()->SetCoverFrame();
2518     }
2519     std::lock_guard<std::mutex> lock(drainImageManager->drainImageLock_);
2520     for (const auto& frame : frameList) {
2521         MEDIA_DEBUG_LOG("DrainOutImage enter DrainImage");
2522         drainImageManager->DrainImage(frame);
2523     }
2524 }
2525 
OnBufferAvailable()2526 void MovingPhotoMetaListener::OnBufferAvailable()
2527 {
2528     MEDIA_DEBUG_LOG("metaSurface_ OnBufferAvailable %{public}u", surface_->GetQueueSize());
2529     if (!surface_) {
2530         MEDIA_ERR_LOG("streamRepeat surface is null");
2531         return;
2532     }
2533     int64_t timestamp;
2534     OHOS::Rect damage;
2535     sptr<SurfaceBuffer> buffer;
2536     sptr<SyncFence> syncFence = SyncFence::INVALID_FENCE;
2537     SurfaceError surfaceRet = surface_->AcquireBuffer(buffer, syncFence, timestamp, damage);
2538     if (surfaceRet != SURFACE_ERROR_OK) {
2539         MEDIA_ERR_LOG("Failed to acquire meta surface buffer");
2540         return;
2541     }
2542     surfaceRet = surface_->DetachBufferFromQueue(buffer);
2543     if (surfaceRet != SURFACE_ERROR_OK) {
2544         MEDIA_ERR_LOG("Failed to detach meta buffer. %{public}d", surfaceRet);
2545         return;
2546     }
2547     metaCache_->add({timestamp, buffer});
2548 }
2549 
MovingPhotoMetaListener(sptr<Surface> surface,shared_ptr<FixedSizeList<MetaElementType>> metaCache)2550 MovingPhotoMetaListener::MovingPhotoMetaListener(sptr<Surface> surface,
2551     shared_ptr<FixedSizeList<MetaElementType>> metaCache)
2552     : surface_(surface), metaCache_(metaCache)
2553 {
2554 }
2555 
~MovingPhotoMetaListener()2556 MovingPhotoMetaListener::~MovingPhotoMetaListener()
2557 {
2558     MEDIA_ERR_LOG("HStreamRepeat::MovingPhotoMetaListener ~ end");
2559 }
2560 } // namespace CameraStandard
2561 } // namespace OHOS
2562