From bbff2009697410947a0f26c1912f17bb89e0f2b9 Mon Sep 17 00:00:00 2001 From: dongyu_dy Date: Mon, 15 Jul 2024 13:42:43 +0000 Subject: [PATCH 1/5] optimize audio eos Signed-off-by: dongyu_dy --- interfaces/inner_api/native/audio_sink.h | 15 +++- .../filters/audio_sink_filter.cpp | 1 + .../media_engine/modules/sink/audio_sink.cpp | 78 ++++++++++++++++++- 3 files changed, 89 insertions(+), 5 deletions(-) diff --git a/interfaces/inner_api/native/audio_sink.h b/interfaces/inner_api/native/audio_sink.h index 36447fa68..13d39eb15 100644 --- a/interfaces/inner_api/native/audio_sink.h +++ b/interfaces/inner_api/native/audio_sink.h @@ -57,6 +57,7 @@ public: Status SetAudioEffectMode(int32_t effectMode); Status GetAudioEffectMode(int32_t &effectMode); int32_t SetVolumeWithRamp(float targetVolume, int32_t duration); + void SetThreadGroupId(const std::string& groupId); Status SetIsTransitent(bool isTransitent, bool isSeekCompleted); Status ChangeTrack(std::shared_ptr& meta, const std::shared_ptr& receiver); Status WaitSeekCompleted(); @@ -74,7 +75,8 @@ private: int64_t getPendingAudioPlayoutDurationUs(int64_t nowUs); int64_t getDurationUsPlayedAtSampleRate(uint32_t numFrames); void UpdateAudioWriteTimeMayWait(); - void ReportEosEventAndDrain(); + void DrainAndReportEosEvent(); + void HandleEosInner(); Status PauseSub(); std::shared_ptr plugin_ {}; std::shared_ptr playerEventReceiver_; @@ -99,6 +101,17 @@ private: bool isEos_ {false}; std::mutex pluginMutex_; float volume_ {-1.0f}; + std::unique_ptr eosTask_ {nullptr}; + enum class EosInterruptState : int { + NONE, + INITIAL, + PAUSE, + RESUME, + STOP, + }; + Mutex eosMutex_ {}; + std::atomic eosDraining_ {false}; + std::atomic eosInterruptType_ {EosInterruptState::NONE}; float speed_ {1.0f}; int32_t effectMode_ {-1}; bool isApe_ {false}; diff --git a/services/media_engine/filters/audio_sink_filter.cpp b/services/media_engine/filters/audio_sink_filter.cpp index ab47009e8..510d6211d 100644 --- a/services/media_engine/filters/audio_sink_filter.cpp +++ b/services/media_engine/filters/audio_sink_filter.cpp @@ -80,6 +80,7 @@ Status AudioSinkFilter::DoInitAfterLink() audioSink_->SetParameter(globalMeta_); Status ret = audioSink_->Init(trackMeta_, eventReceiver_); audioSink_->SetEventReceiver(eventReceiver_); + audioSink_->SetThreadGroupId(groupId_); return ret; } diff --git a/services/media_engine/modules/sink/audio_sink.cpp b/services/media_engine/modules/sink/audio_sink.cpp index ce1f18463..68df17e82 100644 --- a/services/media_engine/modules/sink/audio_sink.cpp +++ b/services/media_engine/modules/sink/audio_sink.cpp @@ -14,6 +14,7 @@ */ #include "audio_sink.h" +#include "osal/task/task.h" #include "syspara/parameters.h" #include "plugin/plugin_manager_v2.h" #include "common/log.h" @@ -21,6 +22,7 @@ namespace { constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_SYSTEM_PLAYER, "HiStreamer" }; constexpr int64_t MAX_BUFFER_DURATION_US = 200000; // Max buffer duration is 200 ms +constexpr int64_t EOS_DRAIN_INTERVAL_US = 200000; // try drain each 200ms } namespace OHOS { @@ -129,6 +131,10 @@ Status AudioSink::Prepare() return ret; } state_ = Pipeline::FilterState::READY; + { + AutoLock lock(eosMutex_); + eosInterruptType_ = EosInterruptState::NONE; + } return ret; } @@ -154,6 +160,10 @@ Status AudioSink::Stop() return ret; } state_ = Pipeline::FilterState::INITIALIZED; + AutoLock lock(eosMutex_); + if (eosInterruptType_ != EosInterruptState::NONE) { + eosInterruptType_ = EosInterruptState::STOP; + } return ret; } @@ -188,6 +198,10 @@ Status AudioSink::Pause() } else { ret = PauseSub(); } + AutoLock lock(eosMutex_); + if (eosInterruptType_ == EosInterruptState::INITIAL || eosInterruptType_ == EosInterruptState::RESUME) { + eosInterruptType_ = EosInterruptState::PAUSE; + } return ret; } @@ -199,6 +213,15 @@ Status AudioSink::Resume() return ret; } state_ = Pipeline::FilterState::RUNNING; + AutoLock lock(eosMutex_); + if (eosInterruptType_ == EosInterruptState::PAUSE) { + eosInterruptType_ = EosInterruptState::RESUME; + if (!eosDraining_ && eosTask_ != nullptr) { + eosTask_->SubmitJobOnce([this] { + HandleEosInner(); + }); + } + } return ret; } @@ -223,6 +246,10 @@ Status AudioSink::Flush() } else { ret = plugin_->Flush(); } + { + AutoLock lock(eosMutex_); + eosInterruptType_ = EosInterruptState::NONE; + } return ret; } @@ -304,8 +331,46 @@ void AudioSink::UpdateAudioWriteTimeMayWait() lastBufferWriteTime_ = timeNow; } -void AudioSink::ReportEosEventAndDrain() +void AudioSink::SetThreadGroupId(const std::string& groupId) { + eosTask_ = std::make_unique("OS_EOSa", groupId, TaskType::AUDIO, TaskPriority::HIGH, false); +} + +void AudioSink::HandleEosInner() +{ + AutoLock lock(eosMutex_); + eosDraining_ = true; + if (eosInterruptType_ != EosInterruptState::INITIAL && eosInterruptType_ != EosInterruptState::RESUME) { + MEDIA_LOG_W("drain audiosink interrupted"); + eosDraining_ = false; + return; + } + uint64_t latency = 0; + if (plugin_->GetLatency(latency) != Status::OK) { + MEDIA_LOG_W("failed to get latency, drain directly"); + DrainAndReportEosEvent(); + return; + } + if (latency < EOS_DRAIN_INTERVAL_US) { + MEDIA_LOG_I("Drain audiosink and report EOS"); + DrainAndReportEosEvent(); + return; + } + if (eosTask_ == nullptr) { + MEDIA_LOG_I("Drain audiosink, eosTask_ is nullptr"); + DrainAndReportEosEvent(); + return; + } + MEDIA_LOG_I("Drain audiosink wait next INTERVAL, latency = " PUBLIC_LOG_U64, latency); + eosTask_->SubmitJobOnce([this] { + HandleEosInner(); + }, EOS_DRAIN_INTERVAL_US, false); +} + +void AudioSink::DrainAndReportEosEvent() +{ + plugin_->Drain(); + plugin_->PauseTransitent(); isEos_ = true; auto syncCenter = syncCenter_.lock(); if (syncCenter) { @@ -317,8 +382,6 @@ void AudioSink::ReportEosEventAndDrain() }; FALSE_RETURN(playerEventReceiver_ != nullptr); playerEventReceiver_->OnEvent(event); - plugin_->Drain(); - plugin_->PauseTransitent(); } void AudioSink::DrainOutputBuffer() @@ -338,8 +401,15 @@ void AudioSink::DrainOutputBuffer() return; } if (filledOutputBuffer->flag_ & BUFFER_FLAG_EOS) { - ReportEosEventAndDrain(); inputBufferQueueConsumer_->ReleaseBuffer(filledOutputBuffer); + AutoLock lock(eosMutex_); + eosInterruptType_ = EosInterruptState::INITIAL; + if (eosTask_ == nullptr) { + return; + } + eosTask_->SubmitJobOnce([this] { + HandleEosInner(); + }); return; } UpdateAudioWriteTimeMayWait(); -- Gitee From e356a3439e0e297e938eb8f397ac9d5e52f6b3bb Mon Sep 17 00:00:00 2001 From: dongyu_dy Date: Mon, 15 Jul 2024 13:45:22 +0000 Subject: [PATCH 2/5] update services/media_engine/modules/sink/audio_sink.cpp. Signed-off-by: dongyu_dy --- services/media_engine/modules/sink/audio_sink.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/services/media_engine/modules/sink/audio_sink.cpp b/services/media_engine/modules/sink/audio_sink.cpp index 68df17e82..977235c7b 100644 --- a/services/media_engine/modules/sink/audio_sink.cpp +++ b/services/media_engine/modules/sink/audio_sink.cpp @@ -14,7 +14,6 @@ */ #include "audio_sink.h" -#include "osal/task/task.h" #include "syspara/parameters.h" #include "plugin/plugin_manager_v2.h" #include "common/log.h" -- Gitee From adc29bd5d0fc46a7f4d1cf0dea8574ebe236dfb4 Mon Sep 17 00:00:00 2001 From: dongyu_dy Date: Mon, 15 Jul 2024 13:53:24 +0000 Subject: [PATCH 3/5] update services/media_engine/modules/sink/audio_sink.cpp. Signed-off-by: dongyu_dy --- services/media_engine/modules/sink/audio_sink.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/media_engine/modules/sink/audio_sink.cpp b/services/media_engine/modules/sink/audio_sink.cpp index 977235c7b..f77b299a4 100644 --- a/services/media_engine/modules/sink/audio_sink.cpp +++ b/services/media_engine/modules/sink/audio_sink.cpp @@ -356,11 +356,11 @@ void AudioSink::HandleEosInner() return; } if (eosTask_ == nullptr) { - MEDIA_LOG_I("Drain audiosink, eosTask_ is nullptr"); + MEDIA_LOG_W("Drain audiosink, eosTask_ is nullptr"); DrainAndReportEosEvent(); return; } - MEDIA_LOG_I("Drain audiosink wait next INTERVAL, latency = " PUBLIC_LOG_U64, latency); + MEDIA_LOG_D("Drain audiosink wait next INTERVAL, latency = " PUBLIC_LOG_U64, latency); eosTask_->SubmitJobOnce([this] { HandleEosInner(); }, EOS_DRAIN_INTERVAL_US, false); -- Gitee From 825e8eb0551be94c6d7284405685edc1a4469aa7 Mon Sep 17 00:00:00 2001 From: dongyu_dy Date: Mon, 15 Jul 2024 13:54:46 +0000 Subject: [PATCH 4/5] update services/media_engine/modules/sink/audio_sink.cpp. Signed-off-by: dongyu_dy --- services/media_engine/modules/sink/audio_sink.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/media_engine/modules/sink/audio_sink.cpp b/services/media_engine/modules/sink/audio_sink.cpp index f77b299a4..58e3f9e93 100644 --- a/services/media_engine/modules/sink/audio_sink.cpp +++ b/services/media_engine/modules/sink/audio_sink.cpp @@ -370,6 +370,8 @@ void AudioSink::DrainAndReportEosEvent() { plugin_->Drain(); plugin_->PauseTransitent(); + eosInterruptType_ = EosInterruptState::NONE; + eosDraining_ = false; isEos_ = true; auto syncCenter = syncCenter_.lock(); if (syncCenter) { -- Gitee From d3f4f7b82190e9c1d1a05abc4752fec1047cff88 Mon Sep 17 00:00:00 2001 From: dongyu_dy Date: Mon, 15 Jul 2024 14:15:39 +0000 Subject: [PATCH 5/5] update services/media_engine/modules/sink/audio_sink.cpp. Signed-off-by: dongyu_dy --- services/media_engine/modules/sink/audio_sink.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/media_engine/modules/sink/audio_sink.cpp b/services/media_engine/modules/sink/audio_sink.cpp index 58e3f9e93..e422f46a4 100644 --- a/services/media_engine/modules/sink/audio_sink.cpp +++ b/services/media_engine/modules/sink/audio_sink.cpp @@ -403,7 +403,7 @@ void AudioSink::DrainOutputBuffer() } if (filledOutputBuffer->flag_ & BUFFER_FLAG_EOS) { inputBufferQueueConsumer_->ReleaseBuffer(filledOutputBuffer); - AutoLock lock(eosMutex_); + AutoLock eosLock(eosMutex_); eosInterruptType_ = EosInterruptState::INITIAL; if (eosTask_ == nullptr) { return; -- Gitee