From e8ec6a69ca8b88de1a8ed27a0528a527ac247b48 Mon Sep 17 00:00:00 2001 From: xuwentao Date: Tue, 26 Nov 2024 15:21:21 +0800 Subject: [PATCH 1/3] add stop flag for client Signed-off-by: xuwentao --- .../client/include/renderer_in_client_private.h | 2 ++ services/audio_service/client/src/renderer_in_client.cpp | 3 +++ .../client/src/renderer_in_client_public.cpp | 8 ++++++++ 3 files changed, 13 insertions(+) diff --git a/services/audio_service/client/include/renderer_in_client_private.h b/services/audio_service/client/include/renderer_in_client_private.h index 0376efa4f2..236b00c239 100644 --- a/services/audio_service/client/include/renderer_in_client_private.h +++ b/services/audio_service/client/include/renderer_in_client_private.h @@ -378,6 +378,8 @@ private: uint64_t lastFlushReadIndex_ = 0; bool isDataLinkConnected_ = false; + bool isStopDrain_ = false; + float lastSpeed_ = 0.0; uint64_t lastLatency_ = 0; uint64_t lastLatencyPosition_ = 0; diff --git a/services/audio_service/client/src/renderer_in_client.cpp b/services/audio_service/client/src/renderer_in_client.cpp index bc4209dd69..4b353598e0 100644 --- a/services/audio_service/client/src/renderer_in_client.cpp +++ b/services/audio_service/client/src/renderer_in_client.cpp @@ -633,6 +633,9 @@ int32_t RendererInClientInner::WriteInner(uint8_t *buffer, size_t bufferSize) CHECK_AND_RETURN_RET_PRELOG(state_ == RUNNING, ERR_ILLEGAL_STATE, "Write: Illegal state:%{public}u sessionid: %{public}u", state_.load(), sessionId_); + CHECK_AND_RETURN_RET_PRELOG(isStopDrain_ == false, ERR_ILLEGAL_STATE, + "Write: client is stopping sessionid: %{public}u", sessionId_); + // hold lock if (isBlendSet_) { audioBlend_.Process(buffer, bufferSize); diff --git a/services/audio_service/client/src/renderer_in_client_public.cpp b/services/audio_service/client/src/renderer_in_client_public.cpp index 256354a5c1..44a6345948 100644 --- a/services/audio_service/client/src/renderer_in_client_public.cpp +++ b/services/audio_service/client/src/renderer_in_client_public.cpp @@ -841,6 +841,7 @@ bool RendererInClientInner::StartAudioStream(StateChangeCmdType cmdType, { Trace trace("RendererInClientInner::StartAudioStream " + std::to_string(sessionId_)); std::unique_lock statusLock(statusMutex_); + isStopDrain_ = false; if (state_ != PREPARED && state_ != STOPPED && state_ != PAUSED) { AUDIO_ERR_LOG("Start failed Illegal state:%{public}d", state_.load()); return false; @@ -947,10 +948,12 @@ bool RendererInClientInner::StopAudioStream() if (state_ == STOPPED) { AUDIO_INFO_LOG("Renderer in client is already stopped"); + isStopDrain_ = false; return true; } if ((state_ != RUNNING) && (state_ != PAUSED)) { AUDIO_ERR_LOG("Stop failed. Illegal state:%{public}u", state_.load()); + isStopDrain_ = false; return false; } @@ -964,15 +967,18 @@ bool RendererInClientInner::StopAudioStream() int32_t ret = ipcStream_->Stop(); if (ret != SUCCESS) { AUDIO_ERR_LOG("Stop call server failed:%{public}u", ret); + isStopDrain_ = false; return false; } bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { + isStopDrain_ = false; return state_ == STOPPED; // will be false when got notified. }); if (!stopWaiting) { AUDIO_ERR_LOG("Stop failed: timeout"); state_ = INVALID; + isStopDrain_ = false; return false; } @@ -986,6 +992,7 @@ bool RendererInClientInner::StopAudioStream() AUDIO_INFO_LOG("Stop SUCCESS, sessionId: %{public}d, uid: %{public}d", sessionId_, clientUid_); UpdateTracker("STOPPED"); + isStopDrain_ = false; return true; } @@ -1097,6 +1104,7 @@ bool RendererInClientInner::DrainAudioStream(bool stopFlag) return false; } std::lock_guard lock(writeMutex_); + isStopDrain_ = true; CHECK_AND_RETURN_RET_LOG(WriteCacheData(true, stopFlag) == SUCCESS, false, "Drain cache failed"); CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!"); -- Gitee From 7b0f23447d4debf683ec0951830f4abb351bce7b Mon Sep 17 00:00:00 2001 From: xuwentao Date: Tue, 26 Nov 2024 21:22:37 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: xuwentao --- .../include/renderer_in_client_private.h | 4 +- .../client/src/renderer_in_client.cpp | 37 +++++++++++++++++-- .../client/src/renderer_in_client_public.cpp | 11 +----- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/services/audio_service/client/include/renderer_in_client_private.h b/services/audio_service/client/include/renderer_in_client_private.h index 236b00c239..a3b4094ec1 100644 --- a/services/audio_service/client/include/renderer_in_client_private.h +++ b/services/audio_service/client/include/renderer_in_client_private.h @@ -242,6 +242,8 @@ private: int32_t ProcessWriteInner(BufferDesc &bufferDesc); void InitDirectPipeType(); + + bool DrainAudioStreamInner(bool stopFlag = false); private: AudioStreamType eStreamType_ = AudioStreamType::STREAM_DEFAULT; int32_t appUid_ = 0; @@ -378,8 +380,6 @@ private: uint64_t lastFlushReadIndex_ = 0; bool isDataLinkConnected_ = false; - bool isStopDrain_ = false; - float lastSpeed_ = 0.0; uint64_t lastLatency_ = 0; uint64_t lastLatencyPosition_ = 0; diff --git a/services/audio_service/client/src/renderer_in_client.cpp b/services/audio_service/client/src/renderer_in_client.cpp index 4b353598e0..87306f2220 100644 --- a/services/audio_service/client/src/renderer_in_client.cpp +++ b/services/audio_service/client/src/renderer_in_client.cpp @@ -633,9 +633,6 @@ int32_t RendererInClientInner::WriteInner(uint8_t *buffer, size_t bufferSize) CHECK_AND_RETURN_RET_PRELOG(state_ == RUNNING, ERR_ILLEGAL_STATE, "Write: Illegal state:%{public}u sessionid: %{public}u", state_.load(), sessionId_); - CHECK_AND_RETURN_RET_PRELOG(isStopDrain_ == false, ERR_ILLEGAL_STATE, - "Write: client is stopping sessionid: %{public}u", sessionId_); - // hold lock if (isBlendSet_) { audioBlend_.Process(buffer, bufferSize); @@ -814,6 +811,40 @@ int32_t RendererInClientInner::UnregisterSpatializationStateEventListener(uint32 return SUCCESS; } +bool RendererInClientInner::DrainAudioStreamInner(bool stopFlag) +{ + Trace trace("RendererInClientInner::DrainAudioStreamInner " + std::to_string(sessionId_)); + std::lock_guard statusLock(statusMutex_); + if (state_ != RUNNING) { + AUDIO_ERR_LOG("Drain failed. Illegal state:%{public}u", state_.load()); + return false; + } + CHECK_AND_RETURN_RET_LOG(WriteCacheData(true, stopFlag) == SUCCESS, false, "Drain cache failed"); + + CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!"); + AUDIO_INFO_LOG("stopFlag:%{public}d", stopFlag); + int32_t ret = ipcStream_->Drain(stopFlag); + if (ret != SUCCESS) { + AUDIO_ERR_LOG("Drain call server failed:%{public}u", ret); + return false; + } + std::unique_lock waitLock(callServerMutex_); + bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { + return notifiedOperation_ == DRAIN_STREAM; // will be false when got notified. + }); + + if (notifiedOperation_ != DRAIN_STREAM || notifiedResult_ != SUCCESS) { + AUDIO_ERR_LOG("Drain failed: %{public}s Operation:%{public}d result:%{public}" PRId64".", + (!stopWaiting ? "timeout" : "no timeout"), notifiedOperation_, notifiedResult_); + notifiedOperation_ = MAX_OPERATION_CODE; + return false; + } + notifiedOperation_ = MAX_OPERATION_CODE; + waitLock.unlock(); + AUDIO_INFO_LOG("Drain stream SUCCESS, sessionId: %{public}d", sessionId_); + return true; +} + SpatializationStateChangeCallbackImpl::SpatializationStateChangeCallbackImpl() { AUDIO_INFO_LOG("Instance create"); diff --git a/services/audio_service/client/src/renderer_in_client_public.cpp b/services/audio_service/client/src/renderer_in_client_public.cpp index 44a6345948..5fdfee83b0 100644 --- a/services/audio_service/client/src/renderer_in_client_public.cpp +++ b/services/audio_service/client/src/renderer_in_client_public.cpp @@ -841,7 +841,6 @@ bool RendererInClientInner::StartAudioStream(StateChangeCmdType cmdType, { Trace trace("RendererInClientInner::StartAudioStream " + std::to_string(sessionId_)); std::unique_lock statusLock(statusMutex_); - isStopDrain_ = false; if (state_ != PREPARED && state_ != STOPPED && state_ != PAUSED) { AUDIO_ERR_LOG("Start failed Illegal state:%{public}d", state_.load()); return false; @@ -941,19 +940,18 @@ bool RendererInClientInner::StopAudioStream() { Trace trace("RendererInClientInner::StopAudioStream " + std::to_string(sessionId_)); AUDIO_INFO_LOG("Stop begin for sessionId %{public}d uid: %{public}d", sessionId_, clientUid_); + std::lock_guard lock(writeMutex_); if (!offloadEnable_) { - DrainAudioStream(true); + DrainAudioStreamInner(true); } std::unique_lock statusLock(statusMutex_); if (state_ == STOPPED) { AUDIO_INFO_LOG("Renderer in client is already stopped"); - isStopDrain_ = false; return true; } if ((state_ != RUNNING) && (state_ != PAUSED)) { AUDIO_ERR_LOG("Stop failed. Illegal state:%{public}u", state_.load()); - isStopDrain_ = false; return false; } @@ -967,18 +965,15 @@ bool RendererInClientInner::StopAudioStream() int32_t ret = ipcStream_->Stop(); if (ret != SUCCESS) { AUDIO_ERR_LOG("Stop call server failed:%{public}u", ret); - isStopDrain_ = false; return false; } bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { - isStopDrain_ = false; return state_ == STOPPED; // will be false when got notified. }); if (!stopWaiting) { AUDIO_ERR_LOG("Stop failed: timeout"); state_ = INVALID; - isStopDrain_ = false; return false; } @@ -992,7 +987,6 @@ bool RendererInClientInner::StopAudioStream() AUDIO_INFO_LOG("Stop SUCCESS, sessionId: %{public}d, uid: %{public}d", sessionId_, clientUid_); UpdateTracker("STOPPED"); - isStopDrain_ = false; return true; } @@ -1104,7 +1098,6 @@ bool RendererInClientInner::DrainAudioStream(bool stopFlag) return false; } std::lock_guard lock(writeMutex_); - isStopDrain_ = true; CHECK_AND_RETURN_RET_LOG(WriteCacheData(true, stopFlag) == SUCCESS, false, "Drain cache failed"); CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!"); -- Gitee From fb5a0815bc163b7c8cb5a7c6dce1c77efb514ae3 Mon Sep 17 00:00:00 2001 From: xuwentao Date: Wed, 27 Nov 2024 10:56:46 +0800 Subject: [PATCH 3/3] add DrainAudioStreamInner and move writeMutex fix1 Signed-off-by: xuwentao --- .../client/src/renderer_in_client.cpp | 1 - .../client/src/renderer_in_client_public.cpp | 33 ++----------------- 2 files changed, 3 insertions(+), 31 deletions(-) diff --git a/services/audio_service/client/src/renderer_in_client.cpp b/services/audio_service/client/src/renderer_in_client.cpp index 87306f2220..bf88ecfffe 100644 --- a/services/audio_service/client/src/renderer_in_client.cpp +++ b/services/audio_service/client/src/renderer_in_client.cpp @@ -814,7 +814,6 @@ int32_t RendererInClientInner::UnregisterSpatializationStateEventListener(uint32 bool RendererInClientInner::DrainAudioStreamInner(bool stopFlag) { Trace trace("RendererInClientInner::DrainAudioStreamInner " + std::to_string(sessionId_)); - std::lock_guard statusLock(statusMutex_); if (state_ != RUNNING) { AUDIO_ERR_LOG("Drain failed. Illegal state:%{public}u", state_.load()); return false; diff --git a/services/audio_service/client/src/renderer_in_client_public.cpp b/services/audio_service/client/src/renderer_in_client_public.cpp index 5fdfee83b0..1e7c717c94 100644 --- a/services/audio_service/client/src/renderer_in_client_public.cpp +++ b/services/audio_service/client/src/renderer_in_client_public.cpp @@ -940,11 +940,11 @@ bool RendererInClientInner::StopAudioStream() { Trace trace("RendererInClientInner::StopAudioStream " + std::to_string(sessionId_)); AUDIO_INFO_LOG("Stop begin for sessionId %{public}d uid: %{public}d", sessionId_, clientUid_); + std::unique_lock statusLock(statusMutex_); std::lock_guard lock(writeMutex_); if (!offloadEnable_) { DrainAudioStreamInner(true); } - std::unique_lock statusLock(statusMutex_); if (state_ == STOPPED) { AUDIO_INFO_LOG("Renderer in client is already stopped"); @@ -1091,37 +1091,10 @@ bool RendererInClientInner::FlushAudioStream() bool RendererInClientInner::DrainAudioStream(bool stopFlag) { - Trace trace("RendererInClientInner::DrainAudioStream " + std::to_string(sessionId_)); std::lock_guard statusLock(statusMutex_); - if (state_ != RUNNING) { - AUDIO_ERR_LOG("Drain failed. Illegal state:%{public}u", state_.load()); - return false; - } std::lock_guard lock(writeMutex_); - CHECK_AND_RETURN_RET_LOG(WriteCacheData(true, stopFlag) == SUCCESS, false, "Drain cache failed"); - - CHECK_AND_RETURN_RET_LOG(ipcStream_ != nullptr, false, "ipcStream is not inited!"); - AUDIO_INFO_LOG("stopFlag:%{public}d", stopFlag); - int32_t ret = ipcStream_->Drain(stopFlag); - if (ret != SUCCESS) { - AUDIO_ERR_LOG("Drain call server failed:%{public}u", ret); - return false; - } - std::unique_lock waitLock(callServerMutex_); - bool stopWaiting = callServerCV_.wait_for(waitLock, std::chrono::milliseconds(OPERATION_TIMEOUT_IN_MS), [this] { - return notifiedOperation_ == DRAIN_STREAM; // will be false when got notified. - }); - - if (notifiedOperation_ != DRAIN_STREAM || notifiedResult_ != SUCCESS) { - AUDIO_ERR_LOG("Drain failed: %{public}s Operation:%{public}d result:%{public}" PRId64".", - (!stopWaiting ? "timeout" : "no timeout"), notifiedOperation_, notifiedResult_); - notifiedOperation_ = MAX_OPERATION_CODE; - return false; - } - notifiedOperation_ = MAX_OPERATION_CODE; - waitLock.unlock(); - AUDIO_INFO_LOG("Drain stream SUCCESS, sessionId: %{public}d", sessionId_); - return true; + bool ret = DrainAudioStreamInner(stopFlag); + return ret; } int32_t RendererInClientInner::Write(uint8_t *pcmBuffer, size_t pcmBufferSize, uint8_t *metaBuffer, -- Gitee