diff --git a/frameworks/native/pulseaudio/modules/hdi/hdi_sink.c b/frameworks/native/pulseaudio/modules/hdi/hdi_sink.c index 741c301a853a409a6009c1a1a25353881c2ad248..a7b410829c33111ad12e96c0f5a1c0ae35338e7e 100644 --- a/frameworks/native/pulseaudio/modules/hdi/hdi_sink.c +++ b/frameworks/native/pulseaudio/modules/hdi/hdi_sink.c @@ -1103,8 +1103,9 @@ static void PreparePrimaryFading(pa_sink_input *sinkIn, pa_mix_info *infoIn, pa_ return; } - const char *sinkFadeoutPause = pa_proplist_gets(sinkIn->proplist, "fadeoutPause"); - if (pa_safe_streq(sinkFadeoutPause, "2") && (sinkIn->thread_info.state == PA_SINK_INPUT_RUNNING)) { + uint32_t streamIndex = sinkIn->index; + uint32_t sinkFadeoutPause = GetFadeoutState(streamIndex); + if (sinkFadeoutPause == DONE_FADE && (sinkIn->thread_info.state == PA_SINK_INPUT_RUNNING)) { silenceData(infoIn, si); AUDIO_PRERELEASE_LOGI("after pause fadeout done, silenceData"); return; @@ -1123,12 +1124,12 @@ static void PreparePrimaryFading(pa_sink_input *sinkIn, pa_mix_info *infoIn, pa_ u->primary.primaryFadingInDone = 1; pa_memblock_release(infoIn->chunk.memblock); } - if (pa_safe_streq(sinkFadeoutPause, "1")) { + if (sinkFadeoutPause == DO_FADE) { //do fading out pa_memchunk_make_writable(&infoIn->chunk, 0); void *data = pa_memblock_acquire_chunk(&infoIn->chunk); DoFading(data, infoIn->chunk.length, format, (uint32_t)u->ss.channels, 1); - pa_proplist_sets(sinkIn->proplist, "fadeoutPause", "2"); + SetFadeoutState(streamIndex, DONE_FADE); pa_memblock_release(infoIn->chunk.memblock); } } @@ -1250,8 +1251,8 @@ static void HandleFading(pa_sink *si, size_t length, pa_sink_input *sinkIn, pa_m PreparePrimaryFading(sinkIn, infoIn, si); CheckPrimaryFadeinIsDone(si, sinkIn); - const char *sinkFadeoutPause = pa_proplist_gets(sinkIn->proplist, "fadeoutPause"); - if (pa_safe_streq(sinkFadeoutPause, "0") && (length <= infoIn->chunk.length)) { + uint32_t sinkFadeoutPause = GetFadeoutState(sinkIn->index); + if (!sinkFadeoutPause && (length <= infoIn->chunk.length)) { u->streamAvailable++; } } @@ -1327,8 +1328,9 @@ static void PrepareMultiChannelFading(pa_sink_input *sinkIn, pa_mix_info *infoIn struct Userdata *u = si->userdata; CHECK_AND_RETURN_LOG(u != NULL, "u is NULL"); - const char *sinkFadeoutPause = pa_proplist_gets(sinkIn->proplist, "fadeoutPause"); - if (pa_safe_streq(sinkFadeoutPause, "2")) { + uint32_t streamIndex = sinkIn->index; + uint32_t sinkFadeoutPause = GetFadeoutState(streamIndex); + if (sinkFadeoutPause == DONE_FADE) { silenceData(infoIn, si); AUDIO_PRERELEASE_LOGI("silenceData."); return; @@ -1348,12 +1350,12 @@ static void PrepareMultiChannelFading(pa_sink_input *sinkIn, pa_mix_info *infoIn u->multiChannel.multiChannelFadingInDone = 1; pa_memblock_release(infoIn->chunk.memblock); } - if (pa_safe_streq(sinkFadeoutPause, "1")) { + if (sinkFadeoutPause == DO_FADE) { //do fading out pa_memchunk_make_writable(&infoIn->chunk, 0); void *data = pa_memblock_acquire_chunk(&infoIn->chunk); DoFading(data, infoIn->chunk.length, format, (uint32_t)u->ss.channels, 1); - pa_proplist_sets(sinkIn->proplist, "fadeoutPause", "2"); + SetFadeoutState(streamIndex, DONE_FADE); pa_memblock_release(infoIn->chunk.memblock); } } @@ -2659,8 +2661,7 @@ static int32_t ProcessRenderUseTimingOffload(struct Userdata *u, bool *wait, int } pa_sink_input *i = infoInputs[0].userdata; - const char *fadingFlag = pa_proplist_gets(i->proplist, "fadeoutPause"); - if ((fadingFlag != NULL) && (!strcmp(fadingFlag, "1"))) { + if (GetFadeoutState(i->index) != NO_FADE) { AUDIO_WARNING_LOG("stream is croked, do not need peek"); return 0; } @@ -2878,8 +2879,9 @@ static void PaInputStateChangeCbPrimary(struct Userdata *u, pa_sink_input *i, pa { const bool starting = i->thread_info.state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING; const bool corking = i->thread_info.state == PA_SINK_INPUT_RUNNING && state == PA_SINK_INPUT_CORKED; + uint32_t streamIndex = i->index; if (corking) { - pa_proplist_sets(i->proplist, "fadeoutPause", "0"); + SetFadeoutState(streamIndex, NO_FADE); } if (starting) { @@ -2887,7 +2889,7 @@ static void PaInputStateChangeCbPrimary(struct Userdata *u, pa_sink_input *i, pa if (pa_atomic_load(&u->primary.isHDISinkStarted) == 1) { pa_atomic_store(&u->primary.fadingFlagForPrimary, 1); AUDIO_INFO_LOG("store fadingFlagForPrimary for 1"); - pa_proplist_sets(i->proplist, "fadeoutPause", "0"); + SetFadeoutState(streamIndex, NO_FADE); u->primary.primaryFadingInDone = 0; u->primary.primarySinkInIndex = (int32_t)(i->index); AUDIO_INFO_LOG("PaInputStateChangeCb, HDI renderer already started"); @@ -2904,7 +2906,7 @@ static void PaInputStateChangeCbPrimary(struct Userdata *u, pa_sink_input *i, pa u->renderCount = 0; pa_atomic_store(&u->primary.fadingFlagForPrimary, 1); AUDIO_INFO_LOG("store fadingFlagForPrimary for 1"); - pa_proplist_sets(i->proplist, "fadeoutPause", "0"); + SetFadeoutState(streamIndex, NO_FADE); u->primary.primaryFadingInDone = 0; u->primary.primarySinkInIndex = (int32_t)(i->index); AUDIO_INFO_LOG("PaInputStateChangeCb, Successfully restarted HDI renderer"); @@ -2998,7 +3000,7 @@ static void PaInputStateChangeCbMultiChannel(struct Userdata *u, pa_sink_input * const bool starting = i->thread_info.state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING; const bool stopping = state == PA_SINK_INPUT_UNLINKED; if (corking) { - pa_proplist_sets(i->proplist, "fadeoutPause", "0"); + SetFadeoutState(i->index, NO_FADE); } if (starting) { u->multiChannel.timestamp = pa_rtclock_now(); @@ -3021,7 +3023,7 @@ static void ResetFadeoutPause(pa_sink_input *i, pa_sink_input_state_t state) bool starting = i->thread_info.state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING; if (corking || starting) { AUDIO_INFO_LOG("set fadeoutPause to 0"); - pa_proplist_sets(i->proplist, "fadeoutPause", "0"); + SetFadeoutState(i->index, NO_FADE); } } diff --git a/services/audio_service/common/include/audio_volume.h b/services/audio_service/common/include/audio_volume.h index f33c03877a0837f2ebd547c3e76fd662f33eb172..7108b98d9c1f788975aa12bbf997b2506042e730 100644 --- a/services/audio_service/common/include/audio_volume.h +++ b/services/audio_service/common/include/audio_volume.h @@ -24,6 +24,13 @@ namespace OHOS { namespace AudioStandard { class StreamVolume; class SystemVolume; +enum FadePauseState { + NO_FADE, + DO_FADE, + DONE_FADE, + INVALID_STATE +}; + class AudioVolume { public: static AudioVolume *GetInstance(); @@ -56,6 +63,10 @@ public: void Dump(std::string &dumpString); void Monitor(uint32_t sessionId, bool isOutput); + void SetFadeoutState(uint32_t streamIndex, uint32_t fadeoutState); + uint32_t GetFadeoutState(uint32_t streamIndex); + void RemoveFadeoutState(uint32_t streamIndex); + private: AudioVolume(); @@ -66,6 +77,9 @@ private: std::unordered_map> monitorVolume_ {}; std::shared_mutex volumeMutex_ {}; std::shared_mutex systemMutex_ {}; + + std::shared_mutex fadoutMutex_ {}; + std::unordered_map fadeoutState_{}; }; class StreamVolume { diff --git a/services/audio_service/common/include/audio_volume_c.h b/services/audio_service/common/include/audio_volume_c.h index 785dfd45bc6c957d350e12b2b7d69149988e9089..fc14aa32f0b51b927d1652bcc380c272d64cd747 100644 --- a/services/audio_service/common/include/audio_volume_c.h +++ b/services/audio_service/common/include/audio_volume_c.h @@ -22,6 +22,13 @@ extern "C" { #endif +enum FadePauseState { + NO_FADE, + DO_FADE, + DONE_FADE, + INVALID_STATE +}; + float GetCurVolume(uint32_t sessionId, const char *streamType, const char *deviceClass); float GetPreVolume(uint32_t sessionId); @@ -36,6 +43,10 @@ bool IsSameVolume(float volumeA, float volumeB); void MonitorVolume(uint32_t sessionId, bool isOutput); +void SetFadeoutState(uint32_t streamIndex, uint32_t fadeoutState); + +uint32_t GetFadeoutState(uint32_t streamIndex); + #ifdef __cplusplus } #endif diff --git a/services/audio_service/common/src/audio_volume.cpp b/services/audio_service/common/src/audio_volume.cpp index 3c1308a0bd27e963a8a213a897680bd6dc4fb142..446a8c74bd9b9de020bbe5d02d4092723c04eeb2 100644 --- a/services/audio_service/common/src/audio_volume.cpp +++ b/services/audio_service/common/src/audio_volume.cpp @@ -402,6 +402,27 @@ void AudioVolume::Monitor(uint32_t sessionId, bool isOutput) AUDIO_ERR_LOG("stream volume not exist, sessionId:%{public}u", sessionId); } } + +void AudioVolume::SetFadeoutState(uint32_t streamIndex, uint32_t fadeoutState) +{ + std::unique_lock lock(fadoutMutex_); + fadeoutState_.insert_or_assign(streamIndex, fadeoutState); +} + +uint32_t AudioVolume::GetFadeoutState(uint32_t streamIndex) +{ + std::shared_lock lock(fadoutMutex_); + auto it = fadeoutState_.find(streamIndex); + if (it != fadeoutState_.end()) { return it->second; } + AUDIO_WARNING_LOG("No such streamIndex in map!"); + return INVALID_STATE; +} + +void AudioVolume::RemoveFadeoutState(uint32_t streamIndex) +{ + std::unique_lock lock(fadoutMutex_); + fadeoutState_.erase(streamIndex); +} } // namespace AudioStandard } // namespace OHOS @@ -450,6 +471,16 @@ void MonitorVolume(uint32_t sessionId, bool isOutput) { AudioVolume::GetInstance()->Monitor(sessionId, isOutput); } + +void SetFadeoutState(uint32_t streamIndex, uint32_t fadeoutState) +{ + AudioVolume::GetInstance()->SetFadeoutState(streamIndex, fadeoutState); +} + +uint32_t GetFadeoutState(uint32_t streamIndex) +{ + return AudioVolume::GetInstance()->GetFadeoutState(streamIndex); +} #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/services/audio_service/server/src/pa_adapter_manager.cpp b/services/audio_service/server/src/pa_adapter_manager.cpp index 809e113c3ee06dea7caebd329cfdc2be2e2e6f99..cf4e6eca19bce0886570b9730918509c116ee619 100644 --- a/services/audio_service/server/src/pa_adapter_manager.cpp +++ b/services/audio_service/server/src/pa_adapter_manager.cpp @@ -546,7 +546,6 @@ int32_t PaAdapterManager::SetPaProplist(pa_proplist *propList, pa_channel_map &m : (managerType_ == DUAL_PLAYBACK ? DUAL_TONE_STREAM : NORMAL_STREAM); pa_proplist_sets(propList, "stream.mode", streamMode.c_str()); pa_proplist_sets(propList, "stream.flush", "false"); - pa_proplist_sets(propList, "fadeoutPause", "0"); pa_proplist_sets(propList, "stream.privacyType", std::to_string(processConfig.privacyType).c_str()); pa_proplist_sets(propList, "stream.usage", std::to_string(processConfig.rendererInfo.streamUsage).c_str()); pa_proplist_sets(propList, "scene.type", processConfig.rendererInfo.sceneType.c_str()); diff --git a/services/audio_service/server/src/pa_renderer_stream_impl.cpp b/services/audio_service/server/src/pa_renderer_stream_impl.cpp index 2960ef53163d9524e4e51a993c0fa2d1a592d720..9f41c69c68c55107805531c08bf1e0d70a6f1156 100644 --- a/services/audio_service/server/src/pa_renderer_stream_impl.cpp +++ b/services/audio_service/server/src/pa_renderer_stream_impl.cpp @@ -32,6 +32,7 @@ #include "audio_utils.h" #include "i_audio_renderer_sink.h" #include "policy_handler.h" +#include "audio_volume.h" namespace OHOS { namespace AudioStandard { @@ -83,7 +84,6 @@ PaRendererStreamImpl::~PaRendererStreamImpl() pa_stream_set_underflow_callback(paStream_, nullptr, nullptr); pa_stream_set_moved_callback(paStream_, nullptr, nullptr); pa_stream_set_started_callback(paStream_, nullptr, nullptr); - pa_stream_disconnect(paStream_); } pa_stream_unref(paStream_); @@ -95,9 +95,7 @@ int32_t PaRendererStreamImpl::InitParams() { PaLockGuard lock(mainloop_); rendererStreamInstanceMap_.Insert(this, weak_from_this()); - if (CheckReturnIfStreamInvalid(paStream_, ERR_ILLEGAL_STATE) < 0) { - return ERR_ILLEGAL_STATE; - } + if (CheckReturnIfStreamInvalid(paStream_, ERR_ILLEGAL_STATE) < 0) { return ERR_ILLEGAL_STATE; } sinkInputIndex_ = pa_stream_get_index(paStream_); pa_stream_set_moved_callback(paStream_, PAStreamMovedCb, @@ -144,6 +142,8 @@ int32_t PaRendererStreamImpl::InitParams() spanSizeInFrame_ = minBufferSize_ / byteSizePerFrame_; lock.Unlock(); + + AudioVolume::GetInstance()->SetFadeoutState(sinkInputIndex_, NO_FADE); // In plan: Get data from xml effectSceneName_ = processConfig_.rendererInfo.sceneType; @@ -196,13 +196,7 @@ int32_t PaRendererStreamImpl::Pause(bool isStandby) } pa_proplist *propList = pa_proplist_new(); if (propList != nullptr) { - pa_proplist_sets(propList, "fadeoutPause", "1"); - pa_operation *updatePropOperation = pa_stream_proplist_update(paStream_, PA_UPDATE_REPLACE, propList, - nullptr, nullptr); - pa_proplist_free(propList); - CHECK_AND_RETURN_RET_LOG(updatePropOperation != nullptr, ERR_OPERATION_FAILED, "updatePropOp is nullptr"); - pa_operation_unref(updatePropOperation); - AUDIO_INFO_LOG("pa_stream_proplist_update done"); + AudioVolume::GetInstance()->SetFadeoutState(sinkInputIndex_, DO_FADE); if (!offloadEnable_) { palock.Unlock(); { @@ -301,13 +295,7 @@ int32_t PaRendererStreamImpl::Stop() pa_proplist *propList = pa_proplist_new(); if (propList != nullptr) { - pa_proplist_sets(propList, "fadeoutPause", "1"); - pa_operation *updatePropOperation = pa_stream_proplist_update(paStream_, PA_UPDATE_REPLACE, propList, - nullptr, nullptr); - pa_proplist_free(propList); - CHECK_AND_RETURN_RET_LOG(updatePropOperation != nullptr, ERR_OPERATION_FAILED, "updatePropOp is nullptr"); - pa_operation_unref(updatePropOperation); - AUDIO_INFO_LOG("pa_stream_proplist_update done"); + AudioVolume::GetInstance()->SetFadeoutState(sinkInputIndex_, DO_FADE); if (!offloadEnable_) { palock.Unlock(); { @@ -373,6 +361,8 @@ int32_t PaRendererStreamImpl::Release() audioEffectVolume->StreamVolumeDelete(sessionIDTemp); } + AudioVolume::GetInstance()->RemoveFadeoutState(sinkInputIndex_); + PaLockGuard lock(mainloop_); if (paStream_) { pa_stream_set_state_callback(paStream_, nullptr, nullptr); @@ -385,7 +375,7 @@ int32_t PaRendererStreamImpl::Release() pa_stream_disconnect(paStream_); releasedFlag_ = true; } - + return SUCCESS; }