diff --git a/services/audio_service/client/src/audio_process_in_client.cpp b/services/audio_service/client/src/audio_process_in_client.cpp index b907c057a8da4154572dad07a1f91450bbd624d8..1f13dd9a72e7a6c857f7af006c39089f8e9cfff7 100644 --- a/services/audio_service/client/src/audio_process_in_client.cpp +++ b/services/audio_service/client/src/audio_process_in_client.cpp @@ -56,7 +56,7 @@ static constexpr int32_t VOLUME_SHIFT_NUMBER = 16; // 1 >> 16 = 65536, max volum static const int64_t DELAY_RESYNC_TIME = 10000000000; // 10s constexpr int32_t RETRY_WAIT_TIME_MS = 500; // 500ms constexpr int32_t MAX_RETRY_COUNT = 8; -static constexpr int64_t FAST_WRITE_CACHE_TIMEOUT_IN_MS = 5; // 5ms +static constexpr int64_t FAST_WRITE_CACHE_TIMEOUT_IN_MS = 40; // 40ms static const uint32_t FAST_WAIT_FOR_NEXT_CB_US = 2500; // 2.5ms static const uint32_t VOIP_WAIT_FOR_NEXT_CB_US = 10000; // 10ms } @@ -200,6 +200,8 @@ private: bool WaitIfBufferEmpty(const BufferDesc &bufDesc); void ExitStandByIfNeed(); + + bool IsRestoreNeeded(); private: static constexpr int64_t MILLISECOND_PER_SECOND = 1000; // 1000ms static constexpr int64_t ONE_MILLISECOND_DURATION = 1000000; // 1ms @@ -1224,6 +1226,8 @@ int32_t AudioProcessInClientInner::Pause(bool isFlush) startFadeout_.store(false); streamStatus_->store(StreamStatus::STREAM_PAUSED); + audioBuffer_->WakeFutex(); + lastPausedTime_ = ClockTime::GetCurNano(); return SUCCESS; @@ -1302,6 +1306,9 @@ int32_t AudioProcessInClientInner::Stop(AudioProcessStage stage) } startFadeout_.store(false); streamStatus_->store(StreamStatus::STREAM_STOPPED); + + audioBuffer_->WakeFutex(); + AUDIO_INFO_LOG("Success stop proc client mode %{public}d form %{public}s.", processConfig_.audioMode, GetStatusInfo(oldStatus).c_str()); return SUCCESS; @@ -1315,6 +1322,7 @@ void AudioProcessInClientInner::JoinCallbackLoop() isCallbackLoopEnd_ = true; // change it with lock to break the loop threadStatusCV_.notify_all(); lock.unlock(); // should call unlock before join + audioBuffer_->WakeFutex(IS_PRE_EXIT); callbackLoop_.join(); } } @@ -1345,6 +1353,9 @@ int32_t AudioProcessInClientInner::Release(bool isSwitchStream) } streamStatus_->store(StreamStatus::STREAM_RELEASED); + + audioBuffer_->WakeFutex(); + AUDIO_INFO_LOG("Success release proc client mode %{public}d.", processConfig_.audioMode); isInited_ = false; @@ -1629,6 +1640,20 @@ void AudioProcessInClientInner::DoFadeInOut(const BufferDesc &buffDesc) } } +bool AudioProcessInClientInner::IsRestoreNeeded() +{ + RestoreStatus restoreStatus = audioBuffer_->GetRestoreStatus(); + if (restoreStatus == NEED_RESTORE) { + return true; + } + + if (restoreStatus == NEED_RESTORE_TO_NORMAL) { + return true; + } + + return false; +} + bool AudioProcessInClientInner::CheckAndWaitBufferReadyForPlayback() { FutexCode ret = audioBuffer_->WaitFor(FAST_WRITE_CACHE_TIMEOUT_IN_MS * AUDIO_US_PER_SECOND, [this] () { @@ -1636,6 +1661,10 @@ bool AudioProcessInClientInner::CheckAndWaitBufferReadyForPlayback() return true; } + if (IsRestoreNeeded()) { + return true; + } + int32_t writableSizeInFrame = audioBuffer_->GetWritableDataFrames(); if ((writableSizeInFrame > 0) && ((totalSizeInFrame_ - writableSizeInFrame) < spanSizeInFrame_)) { return true; @@ -1653,6 +1682,10 @@ bool AudioProcessInClientInner::CheckAndWaitBufferReadyForRecord() return true; } + if (IsRestoreNeeded()) { + return true; + } + int32_t writableSizeInFrame = audioBuffer_->GetWritableDataFrames(); if ((writableSizeInFrame > 0) && ((totalSizeInFrame_ - writableSizeInFrame) >= spanSizeInFrame_)) { return true; diff --git a/services/audio_service/common/include/oh_audio_buffer.h b/services/audio_service/common/include/oh_audio_buffer.h index 0e11a3a9b08e500812ccabc1c0501b87d9ff8535..6227de5afc3f119638313e1375ddbbef72694173 100644 --- a/services/audio_service/common/include/oh_audio_buffer.h +++ b/services/audio_service/common/include/oh_audio_buffer.h @@ -234,7 +234,7 @@ public: FutexCode WaitFor(int64_t timeoutInNs, const OnIndexChange &pred); - void WakeFutex(); + void WakeFutex(uint32_t wakeVal = IS_READY); RestoreStatus GetRestoreStatus(); private: @@ -248,7 +248,7 @@ private: void InitBasicBufferInfo(); - void WakeFutexIfNeed(); + void WakeFutexIfNeed(uint32_t wakeVal = IS_READY); uint32_t sessionId_ = 0; diff --git a/services/audio_service/common/src/oh_audio_buffer_base.cpp b/services/audio_service/common/src/oh_audio_buffer_base.cpp index c2ff6ba5502009ca97ed032a52cbc5df8b505e5a..c127079101ec3496464dcc71367e5ad61eba9f43 100644 --- a/services/audio_service/common/src/oh_audio_buffer_base.cpp +++ b/services/audio_service/common/src/oh_audio_buffer_base.cpp @@ -1084,16 +1084,16 @@ void OHAudioBufferBase::InitBasicBufferInfo() basicBufferInfo_->muteFactor.store(MAX_FLOAT_VOLUME); } -void OHAudioBufferBase::WakeFutexIfNeed() +void OHAudioBufferBase::WakeFutexIfNeed(uint32_t wakeVal) { if (basicBufferInfo_) { - FutexTool::FutexWake(&(basicBufferInfo_->futexObj)); + FutexTool::FutexWake(&(basicBufferInfo_->futexObj), wakeVal); } } -void OHAudioBufferBase::WakeFutex() +void OHAudioBufferBase::WakeFutex(uint32_t wakeVal) { - WakeFutexIfNeed(); + WakeFutexIfNeed(wakeVal); } } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/server/src/audio_process_in_server.cpp b/services/audio_service/server/src/audio_process_in_server.cpp index a50bc93fcef8bb393921f4cb298b78cc7e7c264e..db7ea44407d83a8517174b24cada715604699677 100644 --- a/services/audio_service/server/src/audio_process_in_server.cpp +++ b/services/audio_service/server/src/audio_process_in_server.cpp @@ -841,6 +841,7 @@ RestoreStatus AudioProcessInServer::RestoreSession(RestoreInfo restoreInfo) } processBuffer_->SetRestoreInfo(restoreInfo); + processBuffer_->WakeFutex(); } return restoreStatus; } diff --git a/services/audio_service/test/unittest/client/audio_process_in_client_unit_test.cpp b/services/audio_service/test/unittest/client/audio_process_in_client_unit_test.cpp index 8018c20b3221f55c1d71cd447e7df3ae62d7e9f4..396bbe56e0c521597564fc01c0100ae55772116f 100644 --- a/services/audio_service/test/unittest/client/audio_process_in_client_unit_test.cpp +++ b/services/audio_service/test/unittest/client/audio_process_in_client_unit_test.cpp @@ -3155,5 +3155,43 @@ HWTEST(AudioProcessInClientUnitTest, CallClientHandleCurrent_001, TestSize.Level EXPECT_NE(ptrAudioProcessInClientInner, nullptr); ptrAudioProcessInClientInner->CallClientHandleCurrent(); } + +/** + * @tc.name : Test IsRestoreNeeded API + * @tc.type : FUNC + * @tc.number: IsRestoreNeeded_001 + * @tc.desc : Test IsRestoreNeeded + */ +HWTEST(AudioProcessInClientUnitTest, IsRestoreNeeded_001, TestSize.Level1) +{ + AudioProcessConfig config = InitProcessConfig(); + AudioService *g_audioServicePtr = AudioService::GetInstance(); + sptr processStream = AudioProcessInServer::Create(config, g_audioServicePtr); + bool isVoipMmap = true; + AudioStreamInfo info = {SAMPLE_RATE_48000, ENCODING_PCM, SAMPLE_S16LE, STEREO}; + auto ptrAudioProcessInClientInner = std::make_shared(processStream, isVoipMmap, info); + ASSERT_TRUE(ptrAudioProcessInClientInner != nullptr); + + std::atomic streamStatus; + streamStatus.store(StreamStatus::STREAM_RUNNING); + ptrAudioProcessInClientInner->streamStatus_ = &streamStatus; + + // totalsize is 100 + uint32_t totalSizeInFrame = 100; + uint32_t byteSizePerFrame = 1; + ptrAudioProcessInClientInner->audioBuffer_ = OHAudioBufferBase::CreateFromLocal(totalSizeInFrame, byteSizePerFrame); + ptrAudioProcessInClientInner->audioBuffer_->basicBufferInfo_->restoreStatus.store(NO_NEED_FOR_RESTORE); + EXPECT_EQ(ptrAudioProcessInClientInner->IsRestoreNeeded(), false); + + ptrAudioProcessInClientInner->audioBuffer_->basicBufferInfo_->restoreStatus.store(NEED_RESTORE); + EXPECT_EQ(ptrAudioProcessInClientInner->CheckAndWaitBufferReadyForRecord(), true); + EXPECT_EQ(ptrAudioProcessInClientInner->CheckAndWaitBufferReadyForPlayback(), true); + EXPECT_EQ(ptrAudioProcessInClientInner->IsRestoreNeeded(), true); + + ptrAudioProcessInClientInner->audioBuffer_->basicBufferInfo_->restoreStatus.store(NEED_RESTORE_TO_NORMAL); + EXPECT_EQ(ptrAudioProcessInClientInner->CheckAndWaitBufferReadyForRecord(), true); + EXPECT_EQ(ptrAudioProcessInClientInner->CheckAndWaitBufferReadyForPlayback(), true); + EXPECT_EQ(ptrAudioProcessInClientInner->IsRestoreNeeded(), true); +} } // namespace AudioStandard } // namespace OHOS