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(¤tTime)) {
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(¤tTime)) {
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