diff --git a/services/cameraservice/cameraoperator/client/include/dcamera_client.h b/services/cameraservice/cameraoperator/client/include/dcamera_client.h index 9fe39811bb6f2d9a8f9bb550d53e8f51637b558c..1df19c7b12cc643a9d4ab797ea0c095b6d78ed35 100644 --- a/services/cameraservice/cameraoperator/client/include/dcamera_client.h +++ b/services/cameraservice/cameraoperator/client/include/dcamera_client.h @@ -49,6 +49,7 @@ public: int32_t SetResultCallback(std::shared_ptr& callback) override; int32_t PauseCapture() override; int32_t ResumeCapture() override; + int32_t PrelaunchCamera() override; private: int32_t ConfigCaptureSession(std::vector>& captureInfos, int32_t sceneMode); diff --git a/services/cameraservice/cameraoperator/client/include/icamera_operator.h b/services/cameraservice/cameraoperator/client/include/icamera_operator.h index 97309ff73f91c035fd566fc5e465e6a35c792fe3..90daa089d4f0084af5a70fe942c5311045e1b863 100644 --- a/services/cameraservice/cameraoperator/client/include/icamera_operator.h +++ b/services/cameraservice/cameraoperator/client/include/icamera_operator.h @@ -64,6 +64,7 @@ public: virtual int32_t SetResultCallback(std::shared_ptr& callback) = 0; virtual int32_t PauseCapture() = 0; virtual int32_t ResumeCapture() = 0; + virtual int32_t PrelaunchCamera() = 0; }; } // namespace DistributedHardware } // namespace OHOS diff --git a/services/cameraservice/cameraoperator/client/src/dcamera_client.cpp b/services/cameraservice/cameraoperator/client/src/dcamera_client.cpp index 78851383b43a990d28ba773d53e6f0ebe31af427..099cf53a91c9acbf4d678b085604cb7c7f6774ff 100644 --- a/services/cameraservice/cameraoperator/client/src/dcamera_client.cpp +++ b/services/cameraservice/cameraoperator/client/src/dcamera_client.cpp @@ -665,5 +665,19 @@ int32_t DCameraClient::ResumeCapture() } return ret; } + +int32_t DCameraClient::PrelaunchCamera() +{ + if (cameraManager_ == nullptr) { + DHLOGE("DCameraClient cameraManager_ is nullptr."); + return DCAMERA_BAD_VALUE; + } + int32_t ret = cameraManager_->PrelaunchCamera(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraClient PrelaunchCamera Start failed, cameraId: %{public}s, ret: %{public}d", + GetAnonyString(cameraId_).c_str(), ret); + } + return ret; +} } // namespace DistributedHardware } // namespace OHOS diff --git a/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_controller.cpp b/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_controller.cpp index 3e83e217cde12b67af14aa2d8b150eda92755a32..8462e787a15126bdc868e6c7cbdfec441d1a0b30 100644 --- a/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_controller.cpp +++ b/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_controller.cpp @@ -540,6 +540,14 @@ void DCameraSinkController::OnSessionState(int32_t state, std::string networkId) break; } srcDevId_ = networkId; + if (operator_ == nullptr) { + DHLOGE("operator_ is nullptr"); + break; + } + int32_t ret = operator_->PrelaunchCamera(); + if (ret != DCAMERA_OK) { + DHLOGE("operator_ PrelaunchCamera error. ret %{public}d.", ret); + } break; } case DCAMERA_CHANNEL_STATE_DISCONNECTED: diff --git a/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_output_test.cpp b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_output_test.cpp index 82a001b0a06442c4cc131b987d26d1a56776f729..1adafec195029917a97ec564c08cf04264cd14ad 100644 --- a/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_output_test.cpp +++ b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_output_test.cpp @@ -289,5 +289,17 @@ HWTEST_F(DCameraSinkOutputTest, dcamera_sink_output_test_008, TestSize.Level1) ret = output_->GetProperty(name, propertyCarrier); EXPECT_NE(DCAMERA_OK, ret); } + +/** + * @tc.name: dcamera_sink_output_test_009 + * @tc.desc: Verify the PrelaunchCamera function. + * @tc.type: FUNC + * @tc.require: I5N1JI + */ +HWTEST_F(DCameraSinkOutputTest, dcamera_sink_output_test_009, TestSize.Level1) +{ + int32_t ret = operator_->PrelaunchCamera(); + EXPECT_EQ(DCAMERA_OK, ret); +} } // namespace DistributedHardware } // namespace OHOS diff --git a/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_camera_operator.h b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_camera_operator.h index 67fc84e97d4ca9121b40bd106a6813065136f306..2a712d6af2937495e90ad5c70b45a6ab8a6bb0d5 100644 --- a/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_camera_operator.h +++ b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_camera_operator.h @@ -110,6 +110,11 @@ public: } return DCAMERA_OK; } + + int32_t PrelaunchCamera() + { + return DCAMERA_OK; + } }; } // namespace DistributedHardware } // namespace OHOS diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_source_input.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_source_input.h index 6fa3b270903d2fbbe7a4026833446791d3e7c583..4acc984f5a4af106d1ce6b7dc242ffae30a34bfd 100644 --- a/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_source_input.h +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_source_input.h @@ -52,6 +52,7 @@ private: void PostChannelDisconnectedEvent(); int32_t EstablishContinuousFrameSession(std::vector& indexs); int32_t EstablishSnapshotFrameSession(std::vector& indexs); + void WaitForOpenChannelCompletion(bool needWait); private: std::map> channels_; @@ -68,6 +69,11 @@ private: std::atomic isChannelConnected_ = false; std::mutex channelMtx_; std::condition_variable channelCond_; + + static constexpr std::chrono::seconds TIMEOUT_3_SEC = std::chrono::seconds(3); + std::atomic isOpenChannelFinished_ = false; + std::mutex isOpenChannelMtx_; + std::condition_variable isOpenChannelCond_; }; } // namespace DistributedHardware } // namespace OHOS diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcameracontrol/dcamera_source_controller.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameracontrol/dcamera_source_controller.cpp index f482d766b85037b14d7243edda5fb34a5ec959bc..03a477862d33c0b1bb43470641e1802bf40fbca3 100644 --- a/services/cameraservice/sourceservice/src/distributedcameramgr/dcameracontrol/dcamera_source_controller.cpp +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameracontrol/dcamera_source_controller.cpp @@ -65,7 +65,7 @@ DCameraSourceController::~DCameraSourceController() int32_t DCameraSourceController::StartCapture(std::vector>& captureInfos, int32_t sceneMode) { - if (indexs_.size() > DCAMERA_MAX_NUM) { + if (indexs_.empty() || indexs_.size() > DCAMERA_MAX_NUM) { DHLOGE("StartCapture not support operate %{public}zu camera", indexs_.size()); return DCAMERA_BAD_OPERATE; } @@ -111,7 +111,7 @@ int32_t DCameraSourceController::StartCapture(std::vector DCAMERA_MAX_NUM) { + if (indexs_.empty() || indexs_.size() > DCAMERA_MAX_NUM) { DHLOGE("StopCapture not support operate %{public}zu camera", indexs_.size()); return DCAMERA_BAD_OPERATE; } @@ -163,7 +163,7 @@ int32_t DCameraSourceController::StopCapture() int32_t DCameraSourceController::ChannelNeg(std::shared_ptr& info) { if (!ManageSelectChannel::GetInstance().GetSrcConnect()) { - if (indexs_.size() > DCAMERA_MAX_NUM) { + if (indexs_.empty() || indexs_.size() > DCAMERA_MAX_NUM) { DHLOGE("ChannelNeg not support operate %{public}zu camera", indexs_.size()); return DCAMERA_BAD_OPERATE; } @@ -243,7 +243,7 @@ int32_t DCameraSourceController::DCameraNotify(std::shared_ptr& ev int32_t DCameraSourceController::UpdateSettings(std::vector>& settings) { - if (indexs_.size() > DCAMERA_MAX_NUM) { + if (indexs_.empty() || indexs_.size() > DCAMERA_MAX_NUM) { DHLOGE("UpdateSettings not support operate %{public}zu camera", indexs_.size()); return DCAMERA_BAD_OPERATE; } @@ -287,7 +287,7 @@ int32_t DCameraSourceController::UpdateSettings(std::vector& camInfo) { if (!ManageSelectChannel::GetInstance().GetSrcConnect()) { - if (indexs_.size() > DCAMERA_MAX_NUM) { + if (indexs_.empty() || indexs_.size() > DCAMERA_MAX_NUM) { DHLOGE("GetCameraInfo not support operate %{public}zu camera", indexs_.size()); return DCAMERA_BAD_OPERATE; } @@ -321,7 +321,7 @@ int32_t DCameraSourceController::GetCameraInfo(std::shared_ptr& cam int32_t DCameraSourceController::OpenChannel(std::shared_ptr& openInfo) { - if (indexs_.size() > DCAMERA_MAX_NUM) { + if (indexs_.empty() || indexs_.size() > DCAMERA_MAX_NUM) { DHLOGE("OpenChannel not support operate %{public}zu camera", indexs_.size()); return DCAMERA_BAD_OPERATE; } @@ -369,7 +369,7 @@ int32_t DCameraSourceController::OpenChannel(std::shared_ptr& o int32_t DCameraSourceController::CloseChannel() { - if (indexs_.size() > DCAMERA_MAX_NUM) { + if (indexs_.empty() || indexs_.size() > DCAMERA_MAX_NUM) { DHLOGE("CloseChannel not support operate %{public}zu camera", indexs_.size()); return DCAMERA_BAD_OPERATE; } diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_source_input.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_source_input.cpp index 85a23569074348b0e5515670fb3f499abf1bed90..4da56dc0d3c8cbce1c0f6658b7d55e75864e0d4a 100644 --- a/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_source_input.cpp +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_source_input.cpp @@ -175,28 +175,58 @@ int32_t DCameraSourceInput::StopCapture(std::vector& streamIds, bool& isAll return DCAMERA_OK; } +void DCameraSourceInput::WaitForOpenChannelCompletion(bool needWait) +{ + DHLOGI("openChannel needWait: %{public}s", needWait ? "true" : "false"); + if (needWait) { + std::unique_lock lock(isOpenChannelMtx_); + bool timeOut = !isOpenChannelCond_.wait_for(lock, TIMEOUT_3_SEC, [this] { + return isOpenChannelFinished_.load(); + }); + if (timeOut) { + DHLOGE("openChannel timed out after 3 seconds."); + } + } + DHLOGI("DCameraSourceInput OpenChannel finish devId %{public}s dhId %{public}s continue " + "state: %{public}d, snapshot state: %{public}d", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str(), channelState_[CONTINUOUS_FRAME], channelState_[SNAPSHOT_FRAME]); +} + int32_t DCameraSourceInput::OpenChannel(std::vector& indexs) { DHLOGI("DCameraSourceInput OpenChannel devId %{public}s dhId %{public}s continue state: %{public}d, snapshot " "state: %{public}d", GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), channelState_[CONTINUOUS_FRAME], channelState_[SNAPSHOT_FRAME]); + std::shared_ptr runner = AppExecFwk::EventRunner::Create(true); + auto handler = std::make_shared(runner); + bool needWait = false; if (channelState_[CONTINUOUS_FRAME] == DCAMERA_CHANNEL_STATE_DISCONNECTED) { - int32_t ret = EstablishContinuousFrameSession(indexs); - if (ret != DCAMERA_OK) { - DHLOGE("esdablish continuous frame failed ret: %{public}d, devId: %{public}s, dhId: %{public}s", ret, - GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); - return ret; - } + needWait = true; + DHLOGI("openChannel starting continuous frame session establishment"); + auto task = [&]() { + DHLOGI("openChannel continuous frame task started"); + int32_t ret = EstablishContinuousFrameSession(indexs); + if (ret != DCAMERA_OK) { + DHLOGE("esdablish continuous frame failed ret: %{public}d, devId: %{public}s, dhId: %{public}s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + } + std::unique_lock lock(isOpenChannelMtx_); + isOpenChannelFinished_.store(true); + isOpenChannelCond_.notify_one(); + DHLOGI("openChannel continuous frame task completed"); + }; + handler->PostTask(task, "DCameraSourceInput:OpenChannel", 0, AppExecFwk::EventQueue::Priority::HIGH); } if (channelState_[SNAPSHOT_FRAME] == DCAMERA_CHANNEL_STATE_DISCONNECTED) { + DHLOGI("openChannel starting snapshot frame session establishment"); int32_t ret = EstablishSnapshotFrameSession(indexs); if (ret != DCAMERA_OK) { DHLOGE("esdablish snapshot frame failed ret: %{public}d," "devId: %{public}s, dhId: %{public}s", ret, GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); - return ret; } } + WaitForOpenChannelCompletion(needWait); return DCAMERA_OK; } @@ -219,6 +249,7 @@ int32_t DCameraSourceInput::CloseChannel() DHLOGI("DCameraSourceInput release continue session failed: %{public}d devId %{public}s dhId %{public}s", ret, GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); } + isOpenChannelFinished_.store(false); } if (channelState_[SNAPSHOT_FRAME] != DCAMERA_CHANNEL_STATE_DISCONNECTED) { @@ -235,6 +266,7 @@ int32_t DCameraSourceInput::CloseChannel() DHLOGI("DCameraSourceInput release snapshot session failed: %{public}d devId %{public}s dhId %{public}s", ret, GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); } + isOpenChannelFinished_.store(false); } return DCAMERA_OK; } diff --git a/services/cameraservice/sourceservice/test/unittest/common/distributedcameramgr/dcamera_source_input_test.cpp b/services/cameraservice/sourceservice/test/unittest/common/distributedcameramgr/dcamera_source_input_test.cpp index 9b396a48692f7fe95c562c73f181fcf4ac2a489b..2998be001c4b90927059e23b87b56e130e14bf4a 100644 --- a/services/cameraservice/sourceservice/test/unittest/common/distributedcameramgr/dcamera_source_input_test.cpp +++ b/services/cameraservice/sourceservice/test/unittest/common/distributedcameramgr/dcamera_source_input_test.cpp @@ -329,7 +329,7 @@ HWTEST_F(DCameraSourceInputTest, dcamera_source_input_test_009, TestSize.Level1) EXPECT_EQ(rc, DCAMERA_OK); rc = testInput_->OpenChannel(g_camIndexs); - EXPECT_NE(rc, DCAMERA_OK); + EXPECT_EQ(rc, DCAMERA_OK); rc = testInput_->UnInit(); EXPECT_EQ(rc, DCAMERA_OK); } @@ -351,7 +351,7 @@ HWTEST_F(DCameraSourceInputTest, dcamera_source_input_test_010, TestSize.Level1) EXPECT_EQ(rc, DCAMERA_OK); rc = testInput_->OpenChannel(g_camIndexs); - EXPECT_NE(rc, DCAMERA_OK); + EXPECT_EQ(rc, DCAMERA_OK); rc = testInput_->CloseChannel(); EXPECT_EQ(rc, DCAMERA_OK); diff --git a/services/channel/src/dcamera_channel_source_impl.cpp b/services/channel/src/dcamera_channel_source_impl.cpp index f190ad32ec537980e22a0bdbcfdb5310cdb1d08b..21fb4c388e1acc993cbfc3dab4a27eef509b5b49 100644 --- a/services/channel/src/dcamera_channel_source_impl.cpp +++ b/services/channel/src/dcamera_channel_source_impl.cpp @@ -78,7 +78,7 @@ int32_t DCameraChannelSourceImpl::CreateSession(std::vector& camIn mode_ = sessionMode; DHLOGI("DCameraChannelSourceImpl CreateSession Start, name: %{public}s devId: %{public}s", GetAnonyString(mySessionName_).c_str(), GetAnonyString(myDevId).c_str()); - for (auto iter = camIndexs.begin(); iter != camIndexs.end(); iter++) { + for (auto iter = camIndexs_.begin(); iter != camIndexs_.end(); iter++) { std::string peerDevId = (*iter).devId_; std::string peerSessionName = SESSION_HEAD + (*iter).dhId_ + std::string("_") + sessionFlag; // source_bind diff --git a/services/data_process/include/pipeline_node/multimedia_codec/encoder/encode_data_process.h b/services/data_process/include/pipeline_node/multimedia_codec/encoder/encode_data_process.h index bf90e19e4b9b30fa6a7c9426a5b232e9cee78f58..44ae5ee40fe4204674ab29c352c28f8236a93eba 100644 --- a/services/data_process/include/pipeline_node/multimedia_codec/encoder/encode_data_process.h +++ b/services/data_process/include/pipeline_node/multimedia_codec/encoder/encode_data_process.h @@ -120,6 +120,7 @@ private: const static std::map ENCODER_BITRATE_TABLE; constexpr static uint64_t S2NS = 1000000000; constexpr static uint32_t US2NS = 1000; + constexpr static std::chrono::seconds TIMEOUT_3_SEC = std::chrono::seconds(3); std::weak_ptr callbackPipelineSink_; std::mutex mtxEncoderState_; @@ -132,6 +133,8 @@ private: sptr encodeProducerSurface_ = nullptr; std::atomic isEncoderProcess_ = false; + std::mutex isEncoderProcessMtx_; + std::condition_variable isEncoderProcessCond_; int32_t waitEncoderOutputCount_ = 0; int64_t lastFeedEncoderInputBufferTimeUs_ = 0; diff --git a/services/data_process/src/pipeline_node/multimedia_codec/encoder/encode_data_process.cpp b/services/data_process/src/pipeline_node/multimedia_codec/encoder/encode_data_process.cpp index 88428ecece11bf5b1b56e5ac0db5fb1b6e03b9a6..2cd494c919eb08dfdf6da5bf2dfe4c1a7394fbd2 100644 --- a/services/data_process/src/pipeline_node/multimedia_codec/encoder/encode_data_process.cpp +++ b/services/data_process/src/pipeline_node/multimedia_codec/encoder/encode_data_process.cpp @@ -74,7 +74,9 @@ int32_t EncodeDataProcess::InitNode(const VideoConfigParams& sourceConfig, const "%{public}d.", sourceConfig_.GetVideoCodecType(), targetConfig_.GetVideoCodecType()); processedConfig_ = sourceConfig; processedConfig = processedConfig_; + std::unique_lock lock(isEncoderProcessMtx_); isEncoderProcess_.store(true); + isEncoderProcessCond_.notify_one(); return DCAMERA_OK; } @@ -85,7 +87,9 @@ int32_t EncodeDataProcess::InitNode(const VideoConfigParams& sourceConfig, const return err; } processedConfig = processedConfig_; + std::unique_lock lock(isEncoderProcessMtx_); isEncoderProcess_.store(true); + isEncoderProcessCond_.notify_one(); return DCAMERA_OK; } @@ -542,8 +546,13 @@ void EncodeDataProcess::OnOutputFormatChanged(const Media::Format &format) void EncodeDataProcess::OnOutputBufferAvailable(uint32_t index, MediaAVCodec::AVCodecBufferInfo info, MediaAVCodec::AVCodecBufferFlag flag, std::shared_ptr buffer) { - if (!isEncoderProcess_.load()) { - DHLOGE("EncodeNode occurred error or start release."); + DHLOGI("Waiting for encoder process to become available..."); + std::unique_lock lock(isEncoderProcessMtx_); + bool timeOut = !isEncoderProcessCond_.wait_for(lock, TIMEOUT_3_SEC, [this] { + return isEncoderProcess_.load(); + }); + if (timeOut) { + DHLOGE("Timed out waiting for encoder process after 3 second."); return; } DHLOGD("Video encode buffer info: presentation TimeUs %{public}" PRId64", size %{public}d, offset %{public}d, " diff --git a/services/data_process/test/unittest/common/pipeline_node/encode_data_process_test.cpp b/services/data_process/test/unittest/common/pipeline_node/encode_data_process_test.cpp index 161a4534a717e10ba89be3000e69b010c01dc4f0..694c21591922f31eaf5aeefb5ac2fe4b0d4b8980 100644 --- a/services/data_process/test/unittest/common/pipeline_node/encode_data_process_test.cpp +++ b/services/data_process/test/unittest/common/pipeline_node/encode_data_process_test.cpp @@ -465,11 +465,11 @@ HWTEST_F(EncodeDataProcessTest, encode_data_process_test_014, TestSize.Level1) MediaAVCodec::AVCodecBufferFlag flag = MediaAVCodec::AVCODEC_BUFFER_FLAG_CODEC_DATA; std::shared_ptr buffer = nullptr; testEncodeDataProcess_->OnOutputBufferAvailable(index, info, flag, buffer); - testEncodeDataProcess_->OnError(); testEncodeDataProcess_->OnInputBufferAvailable(index, buffer); Media::Format format; testEncodeDataProcess_->OnOutputFormatChanged(format); testEncodeDataProcess_->OnOutputBufferAvailable(index, info, flag, buffer); + testEncodeDataProcess_->OnError(); EXPECT_EQ(rc, DCAMERA_OK); }