From eb00d79d378fcc22a5f1d42d935e11c7c3631c28 Mon Sep 17 00:00:00 2001 From: linxinyu Date: Fri, 25 Jul 2025 15:02:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BF=AB=E9=80=9F=E5=BC=80=E5=85=B3=E9=BA=A6?= =?UTF-8?q?=E5=85=8B=E9=A3=8E=EF=BC=8C=E6=A6=82=E7=8E=87=E5=BC=95=E8=B5=B7?= =?UTF-8?q?=E5=86=85=E5=BD=95=E6=B5=81=E5=85=B3=E9=97=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: linxinyu --- .../server/screen_capture_server.cpp | 41 +++++++++++++++---- .../server/screen_capture_server_base.h | 3 ++ ...creen_capture_server_function_unittest.cpp | 34 +++++++++++++++ 3 files changed, 69 insertions(+), 9 deletions(-) diff --git a/services/services/screen_capture/server/screen_capture_server.cpp b/services/services/screen_capture/server/screen_capture_server.cpp index 38387f4ca..fc7b0e9dd 100644 --- a/services/services/screen_capture/server/screen_capture_server.cpp +++ b/services/services/screen_capture/server/screen_capture_server.cpp @@ -3515,10 +3515,16 @@ int32_t ScreenCaptureServer::SetMicrophoneOn() int32_t ScreenCaptureServer::SetMicrophoneOff() { int32_t ret = MSERR_UNKNOWN; - if (recorderFileAudioType_ == AVScreenCaptureMixMode::MIX_MODE && innerAudioCapture_ - && !IsInnerCaptureRunning()) { - ret = innerAudioCapture_->Start(appInfo_); // Resume - CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "innerAudioCapture Start failed"); + if (recorderFileAudioType_ == AVScreenCaptureMixMode::MIX_MODE && innerAudioCapture_) { + MEDIA_LOGI("Inner resume"); + if (IsInnerCaptureRunning() && audioSource_->GetIsAudioOnlyMic()) { + MEDIA_LOGD("SetMicrophoneOff SetAudioWithInner"); + audioSource_->SetAudioWithInner(); // Resume inner + } else { + MEDIA_LOGD("SetMicrophoneOff Inner start"); + ret = innerAudioCapture_->Start(appInfo_); + CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "innerAudioCapture Start failed"); + } } if (IsMicrophoneCaptureRunning()) { usleep(AUDIO_CHANGE_TIME); @@ -3535,6 +3541,7 @@ int32_t ScreenCaptureServer::OnSpeakerAliveStatusChanged(bool speakerAliveStatus CHECK_AND_RETURN_RET_LOG(innerAudioCapture_, MSERR_UNKNOWN, "innerAudioCapture_ is nullptr"); if (!speakerAliveStatus && recorderFileAudioType_ == AVScreenCaptureMixMode::MIX_MODE && innerAudioCapture_->GetAudioCapturerState() == CAPTURER_STOPED) { // back to headset + audioSource_->SetAudioWithInner(); ret = innerAudioCapture_->Start(appInfo_); // Resume CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "innerAudioCapture Resume failed"); } @@ -3569,6 +3576,7 @@ int32_t ScreenCaptureServer::OnVoIPStatusChanged(bool isInVoIPCall) CHECK_AND_RETURN_RET_LOG(innerAudioCapture_, MSERR_UNKNOWN, "innerAudioCapture is nullptr"); if (recorderFileAudioType_ == AVScreenCaptureMixMode::MIX_MODE && innerAudioCapture_->GetAudioCapturerState() == CAPTURER_STOPED) { + audioSource_->SetAudioWithInner(); int32_t ret = innerAudioCapture_->Start(appInfo_); // Resume CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "OnVoIPStatusChanged innerAudioCapture Resume failed"); } @@ -3617,6 +3625,7 @@ int32_t ScreenCaptureServer::OnTelCallStart() return ret; } if (recorderFileAudioType_ == AVScreenCaptureMixMode::MIX_MODE && innerAudioCapture_ && !IsInnerCaptureRunning()) { + audioSource_->SetAudioWithInner(); ret = innerAudioCapture_->Start(appInfo_); // Resume CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "tel innerAudioCapture Start failed"); } @@ -4772,6 +4781,11 @@ bool AudioDataSource::GetIsInVoIPCall() return isInVoIPCall_.load(); } +bool AudioDataSource::GetIsAudioOnlyMic() +{ + return isAudioOnlyMic_.load(); +} + bool AudioDataSource::IsInWaitMicSyncState() { return isInWaitMicSyncState_; @@ -4782,6 +4796,11 @@ bool AudioDataSource::GetSpeakerAliveStatus() return speakerAliveStatus_; } +void AudioDataSource::SetAudioWithInner() +{ + isAudioOnlyMic_.store(false); +} + void AudioDataSource::SetAppName(std::string appName) { appName_ = appName; @@ -5168,8 +5187,9 @@ void AudioDataSource::HandleSwitchToSpeakerOptimise(std::shared_ptr if (stableStopInnerSwitchCount_ > INNER_SWITCH_MIC_REQUIRE_COUNT) { // optimise inner while use speaker MEDIA_LOGI("ABuffer stop mix inner optimise cur:%{public}" PRId64 " last: %{public}" PRId64, innerAudioBuffer->timestamp, lastWriteAudioFramePts_.load()); + screenCaptureServer_->ReleaseInnerAudioBuffer(); // drop past inner data while use speaker + isAudioOnlyMic_.store(true); innerAudioBuffer = nullptr; - screenCaptureServer_->StopInnerAudioCapture(); stableStopInnerSwitchCount_ = 0; } else { stableStopInnerSwitchCount_++; @@ -5184,11 +5204,14 @@ void AudioDataSource::HandleBufferTimeStamp(std::shared_ptr &innerA HandlePastMicBuffer(micAudioBuffer); } if (innerAudioBuffer) { - if (innerAudioBuffer->timestamp < lastWriteAudioFramePts_.load() - && !GetIsInVoIPCall() && speakerAliveStatus_) { + bool isSpeakerJitter = innerAudioBuffer->timestamp < lastWriteAudioFramePts_.load() + && !GetIsInVoIPCall() && speakerAliveStatus_; + bool isAudioOnlyMic = isAudioOnlyMic_.load(); + if (isSpeakerJitter || isAudioOnlyMic) { screenCaptureServer_->ReleaseInnerAudioBuffer(); // drop past inner data while use speaker - MEDIA_LOGD("ABuffer drop mix inner error cur:%{public}" PRId64 " last: %{public}" PRId64, - innerAudioBuffer->timestamp, lastWriteAudioFramePts_.load()); + MEDIA_LOGD("ABuffer drop mix inner error cur: %{public}" PRId64 ", last: %{public}" PRId64 + ", speaker jitter: %{public}" PRIu32 ", only mic output: %{public}" PRIu32, + innerAudioBuffer->timestamp, lastWriteAudioFramePts_.load(), isSpeakerJitter, isAudioOnlyMic); innerAudioBuffer = nullptr; } } diff --git a/services/services/screen_capture/server/screen_capture_server_base.h b/services/services/screen_capture/server/screen_capture_server_base.h index b24ebe5f7..847028419 100644 --- a/services/services/screen_capture/server/screen_capture_server_base.h +++ b/services/services/screen_capture/server/screen_capture_server_base.h @@ -274,12 +274,14 @@ public: void SetAppName(std::string appName); int32_t GetAppPid(); bool GetIsInVoIPCall(); + bool GetIsAudioOnlyMic(); bool GetSpeakerAliveStatus(); bool IsInWaitMicSyncState(); #ifdef SUPPORT_CALL void TelCallAudioStateUpdate( const std::vector> &audioRendererChangeInfos); #endif + void SetAudioWithInner(); void SetVideoFirstFramePts(int64_t firstFramePts) override; void SetAudioFirstFramePts(int64_t firstFramePts); AudioDataSourceReadAtActionState MixModeBufferWrite(std::shared_ptr &innerAudioBuffer, @@ -296,6 +298,7 @@ private: int32_t appPid_ { 0 }; std::string appName_; bool speakerAliveStatus_ = true; + std::atomic isAudioOnlyMic_ = false; std::atomic isInVoIPCall_ = false; std::mutex voipStatusChangeMutex_; std::atomic firstAudioFramePts_{-1}; diff --git a/test/unittest/screen_capture_test/screen_capture_service_function_unittest/server/src/screen_capture_server_function_unittest.cpp b/test/unittest/screen_capture_test/screen_capture_service_function_unittest/server/src/screen_capture_server_function_unittest.cpp index bd66be007..e6109ddad 100644 --- a/test/unittest/screen_capture_test/screen_capture_service_function_unittest/server/src/screen_capture_server_function_unittest.cpp +++ b/test/unittest/screen_capture_test/screen_capture_service_function_unittest/server/src/screen_capture_server_function_unittest.cpp @@ -2014,6 +2014,40 @@ HWTEST_F(ScreenCaptureServerFunctionTest, MixModeBufferWrite_004, TestSize.Level ASSERT_EQ(ret, AudioDataSourceReadAtActionState::RETRY_SKIP); } +HWTEST_F(ScreenCaptureServerFunctionTest, MixModeBufferWrite_005, TestSize.Level2) +{ + screenCaptureServer_->audioSource_ = std::make_unique( + AVScreenCaptureMixMode::MIX_MODE, screenCaptureServer_.get()); + const int bufferSize = 10; + uint8_t *innerBuffer = (uint8_t *)malloc(sizeof(uint8_t) * bufferSize); + uint8_t *micBuffer = (uint8_t *)malloc(sizeof(uint8_t) * bufferSize); + std::shared_ptr innerAudioBuffer = std::make_shared(innerBuffer, bufferSize, 2, + SOURCE_DEFAULT); + std::shared_ptr micAudioBuffer = std::make_shared(micBuffer, bufferSize, 2, + SOURCE_DEFAULT); + uint8_t data[bufferSize]; + std::shared_ptr bufferMem = AVMemory::CreateAVMemory(data, bufferSize, bufferSize); + screenCaptureServer_->audioSource_->speakerAliveStatus_ = true; + screenCaptureServer_->audioSource_->isAudioOnlyMic_.store(true); + AudioDataSourceReadAtActionState ret = screenCaptureServer_->audioSource_->MixModeBufferWrite( + innerAudioBuffer, micAudioBuffer, bufferMem); + ASSERT_EQ(ret, AudioDataSourceReadAtActionState::OK); + + uint8_t *innerBuffer2 = (uint8_t *)malloc(sizeof(uint8_t) * bufferSize); + uint8_t *micBuffer2 = (uint8_t *)malloc(sizeof(uint8_t) * bufferSize); + std::shared_ptr innerAudioBuffer2 = std::make_shared(innerBuffer2, bufferSize, 0, + SOURCE_DEFAULT); + std::shared_ptr micAudioBuffer2 = std::make_shared(micBuffer2, bufferSize, 0, + SOURCE_DEFAULT); + uint8_t data2[bufferSize]; + std::shared_ptr bufferMem2 = AVMemory::CreateAVMemory(data2, bufferSize, bufferSize); + screenCaptureServer_->audioSource_->speakerAliveStatus_ = false; + screenCaptureServer_->audioSource_->isAudioOnlyMic_.store(true); + ret = screenCaptureServer_->audioSource_->MixModeBufferWrite( + innerAudioBuffer2, micAudioBuffer2, bufferMem2); + ASSERT_EQ(ret, AudioDataSourceReadAtActionState::OK); +} + HWTEST_F(ScreenCaptureServerFunctionTest, GetChoiceFromJson_001, TestSize.Level2) { Json::Value root; -- Gitee