From 2043ad0b0c47de73ebd4db1d104f4d6fc4976da8 Mon Sep 17 00:00:00 2001 From: zhanhang Date: Sat, 15 Jul 2023 20:09:26 +0800 Subject: [PATCH 1/2] switch between fast stream and normal stream for fast audio renderer Signed-off-by: zhanhang Change-Id: I2137153ea01f75498a95f8f7b59efc61713d172a --- .../include/audio_renderer_private.h | 15 ++ .../audiorenderer/src/audio_renderer.cpp | 168 +++++++++++++++++- .../native/audiostream/include/audio_stream.h | 6 + .../audiostream/include/fast_audio_stream.h | 12 +- .../audiostream/include/i_audio_stream.h | 45 +++++ frameworks/native/ohaudio/OHAudioRenderer.cpp | 26 +++ frameworks/native/ohaudio/OHAudioRenderer.h | 17 ++ .../test/example/oh_audio_renderer_test.cpp | 13 +- .../native/audiocommon/include/audio_info.h | 1 + .../audiorenderer/include/audio_renderer.h | 22 +++ ...io_capturer_state_change_listener_stub.cpp | 1 + .../client/src/audio_policy_proxy.cpp | 2 + ...io_renderer_state_change_listener_stub.cpp | 1 + ...o_capturer_state_change_listener_proxy.cpp | 1 + .../server/src/audio_policy_manager_stub.cpp | 2 + ...o_renderer_state_change_listener_proxy.cpp | 1 + .../src/service/audio_policy_service.cpp | 26 +++ .../client/include/audio_service_client.h | 5 + .../client/src/audio_process_in_client.cpp | 3 +- .../client/src/audio_service_client.cpp | 29 +++ .../audio_service/client/src/audio_stream.cpp | 40 ++++- .../client/src/fast_audio_stream.cpp | 46 ++++- .../client/src/policy_provider_stub.cpp | 1 + .../server/src/policy_provider_proxy.cpp | 1 + 24 files changed, 461 insertions(+), 23 deletions(-) diff --git a/frameworks/native/audiorenderer/include/audio_renderer_private.h b/frameworks/native/audiorenderer/include/audio_renderer_private.h index 0417db5027..6c340ec0d4 100644 --- a/frameworks/native/audiorenderer/include/audio_renderer_private.h +++ b/frameworks/native/audiorenderer/include/audio_renderer_private.h @@ -89,6 +89,7 @@ public: AudioEffectMode GetAudioEffectMode() const override; int64_t GetFramesWritten() const override; int32_t SetAudioEffectMode(AudioEffectMode effectMode) const override; + void SetAudioRendererErrorCallback(std::shared_ptr errorCallback) override; static inline AudioStreamParams ConvertToAudioStreamParams(const AudioRendererParams params) { @@ -107,10 +108,21 @@ public: std::string cachePath_; explicit AudioRendererPrivate(AudioStreamType audioStreamType, const AppInfo &appInfo, bool createStream = true); + ~AudioRendererPrivate(); + friend class AudioRendererStateChangeCallbackImpl; + +protected: + // Method for switching between normal and low latency paths + void SwitchStream(bool isLowLatencyDevice); + private: int32_t InitAudioInterruptCallback(); + void SetSwitchInfo(IAudioStream::SwitchInfo info, std::shared_ptr audioStream); + bool SwitchToTargetStream(IAudioStream::StreamClass targetClass); + void SetSelfRendererStateCallback(); + std::shared_ptr audioStream_; std::shared_ptr audioInterruptCallback_ = nullptr; std::shared_ptr audioStreamCallback_ = nullptr; @@ -123,7 +135,10 @@ private: FILE *dcp_ = nullptr; #endif std::shared_ptr audioDeviceChangeCallback_ = nullptr; + std::shared_ptr audioRendererErrorCallback_ = nullptr; DeviceInfo currentDeviceInfo = {}; + bool isFastRenderer_ = false; + bool isSwitching_ = false; }; class AudioRendererInterruptCallbackImpl : public AudioInterruptCallback { diff --git a/frameworks/native/audiorenderer/src/audio_renderer.cpp b/frameworks/native/audiorenderer/src/audio_renderer.cpp index f722ad69c3..f2ca23bc90 100644 --- a/frameworks/native/audiorenderer/src/audio_renderer.cpp +++ b/frameworks/native/audiorenderer/src/audio_renderer.cpp @@ -283,7 +283,7 @@ int32_t AudioRendererPrivate::SetParams(const AudioRendererParams params) if (audioStream_ == nullptr) { audioStream_ = IAudioStream::GetPlaybackStream(streamClass, audioStreamParams, audioStreamType, appInfo_.appUid); - CHECK_AND_RETURN_RET_LOG(audioStream_ != nullptr, ERR_INVALID_PARAM, "SetParams GetPlayBackStream faied."); + CHECK_AND_RETURN_RET_LOG(audioStream_ != nullptr, ERR_INVALID_PARAM, "SetParams GetPlayBackStream failed."); AUDIO_INFO_LOG("IAudioStream::GetStream success"); audioStream_->SetApplicationCachePath(cachePath_); } @@ -319,6 +319,8 @@ int32_t AudioRendererPrivate::SetParams(const AudioRendererParams params) } #endif + SetSelfRendererStateCallback(); + return InitAudioInterruptCallback(); } @@ -441,6 +443,11 @@ bool AudioRendererPrivate::Start(StateChangeCmdType cmdType) const return false; } + if (isSwitching_) { + AUDIO_ERR_LOG("AudioRenderer::Start failed. Switching state: %{public}d", isSwitching_); + return false; + } + AUDIO_INFO_LOG("AudioRenderer::Start::interruptMode: %{public}d, streamType: %{public}d, sessionID: %{public}d", audioInterrupt_.mode, audioInterrupt_.audioFocusType.streamType, audioInterrupt_.sessionID); @@ -497,6 +504,11 @@ bool AudioRendererPrivate::Flush() const bool AudioRendererPrivate::Pause(StateChangeCmdType cmdType) const { AUDIO_INFO_LOG("AudioRenderer::Pause"); + if (isSwitching_) { + AUDIO_ERR_LOG("AudioRenderer::Pause failed. Switching state: %{public}d", isSwitching_); + return false; + } + if (audioInterrupt_.streamUsage == STREAM_USAGE_VOICE_MODEM_COMMUNICATION) { // When the cellular call stream is pausing, only need to deactivate audio interrupt. if (AudioPolicyManager::GetInstance().DeactivateAudioInterrupt(audioInterrupt_) != 0) { @@ -525,6 +537,10 @@ bool AudioRendererPrivate::Pause(StateChangeCmdType cmdType) const bool AudioRendererPrivate::Stop() const { AUDIO_INFO_LOG("AudioRenderer::Stop"); + if (isSwitching_) { + AUDIO_ERR_LOG("AudioRenderer::Stop failed. Switching state: %{public}d", isSwitching_); + return false; + } if (audioInterrupt_.streamUsage == STREAM_USAGE_VOICE_MODEM_COMMUNICATION) { // When the cellular call stream is stopping, only need to deactivate audio interrupt. if (AudioPolicyManager::GetInstance().DeactivateAudioInterrupt(audioInterrupt_) != 0) { @@ -551,6 +567,8 @@ bool AudioRendererPrivate::Release() const // Unregister the callaback in policy server (void)AudioPolicyManager::GetInstance().UnsetAudioInterruptCallback(sessionID_); + (void)AudioPolicyManager::GetInstance().UnregisterAudioRendererEventListener(appInfo_.appPid); + return audioStream_->ReleaseAudioStream(); } @@ -913,6 +931,12 @@ uint32_t AudioRendererPrivate::GetUnderflowCount() const return audioStream_->GetUnderflowCount(); } + +void AudioRendererPrivate::SetAudioRendererErrorCallback(std::shared_ptr errorCallback) +{ + audioRendererErrorCallback_ = errorCallback; +} + int32_t AudioRendererPrivate::RegisterAudioRendererEventListener(const int32_t clientPid, const std::shared_ptr &callback) { @@ -1008,6 +1032,112 @@ void AudioRendererStateChangeCallbackImpl::setAudioRendererObj(AudioRendererPriv renderer = rendererObj; } +void AudioRendererPrivate::SetSwitchInfo(IAudioStream::SwitchInfo info, std::shared_ptr audioStream) +{ + if (!audioStream) { + AUDIO_ERR_LOG("stream is nullptr"); + return; + } + audioStream->SetStreamTrackerState(info.streamTrackerRegistered); + audioStream->SetAudioStreamInfo(info.params, rendererProxyObj_); + audioStream->SetApplicationCachePath(info.cachePath); + audioStream->SetRenderMode(info.renderMode); + audioStream->SetRendererInfo(info.rendererInfo); + audioStream->SetCapturerInfo(info.capturerInfo); + audioStream->SetClientID(info.clientPid, info.clientUid); + audioStream->SetAudioEffectMode(info.effectMode); + audioStream->SetPrivacyType(info.privacyType); + audioStream->SetVolume(info.volume); + + // set callback + if ((info.renderPositionCb != nullptr) && (info.frameMarkPosition > 0)) { + audioStream->SetRendererPositionCallback(info.frameMarkPosition, info.renderPositionCb); + } + + if ((info.capturePositionCb != nullptr) && (info.frameMarkPosition > 0)) { + audioStream->SetCapturerPositionCallback(info.frameMarkPosition, info.capturePositionCb); + } + + if ((info.renderPeriodPositionCb != nullptr) && (info.framePeriodNumber > 0)) { + audioStream->SetRendererPeriodPositionCallback(info.framePeriodNumber, info.renderPeriodPositionCb); + } + + if ((info.capturePeriodPositionCb != nullptr) && (info.framePeriodNumber > 0)) { + audioStream->SetCapturerPeriodPositionCallback(info.framePeriodNumber, info.capturePeriodPositionCb); + } + + audioStream->SetStreamCallback(info.audioStreamCallback); + audioStream->SetRendererWriteCallback(info.rendererWriteCallback); +} + +bool AudioRendererPrivate::SwitchToTargetStream(IAudioStream::StreamClass targetClass) +{ + bool switchResult = false; + if (audioStream_) { + Trace trace("SwitchToTargetStream"); + isSwitching_ = true; + RendererState previousState = GetStatus(); + if (previousState == RENDERER_RUNNING) { + // stop old stream + switchResult = audioStream_->StopAudioStream(); + CHECK_AND_RETURN_RET_LOG(switchResult, false, "StopAudioStream failed."); + } + // switch new stream + IAudioStream::SwitchInfo info; + audioStream_->GetSwitchInfo(info); + std::shared_ptr newAudioStream = IAudioStream::GetPlaybackStream(targetClass, info.params, + info.eStreamType, appInfo_.appPid); + CHECK_AND_RETURN_RET_LOG(newAudioStream != nullptr, false, "SetParams GetPlayBackStream failed."); + AUDIO_INFO_LOG("Get new stream success!"); + + // set new stream info + SetSwitchInfo(info, newAudioStream); + + // release old stream and restart audio stream + switchResult = audioStream_->ReleaseAudioStream(); + CHECK_AND_RETURN_RET_LOG(switchResult, false, "release old stream failed."); + + if (previousState == RENDERER_RUNNING) { + // restart audio stream + switchResult = newAudioStream->StartAudioStream(); + CHECK_AND_RETURN_RET_LOG(switchResult, false, "start new stream failed."); + } + audioStream_ = newAudioStream; + isSwitching_ = false; + switchResult= true; + } + return switchResult; +} + +void AudioRendererPrivate::SwitchStream(bool isLowLatencyDevice) +{ + // switch stream for fast renderer only + if (audioStream_ != nullptr && isFastRenderer_ && !isSwitching_) { + bool needSwitch = false; + IAudioStream::StreamClass currentClass = audioStream_->GetStreamClass(); + IAudioStream::StreamClass targetClass = IAudioStream::PA_STREAM; + if (currentClass == IAudioStream::FAST_STREAM && !isLowLatencyDevice) { + needSwitch = true; + rendererInfo_.rendererFlags = 0; // Normal renderer type + } + if (currentClass == IAudioStream::PA_STREAM && isLowLatencyDevice) { + // Jumping from normal stream to low latency stream is not supported yet. + needSwitch = false; + rendererInfo_.rendererFlags = STREAM_FLAG_FAST; + targetClass = IAudioStream::FAST_STREAM; + } + if (needSwitch) { + if (!SwitchToTargetStream(targetClass) && !audioRendererErrorCallback_) { + audioRendererErrorCallback_->OnError(ERROR_SYSTEM); + } + } else { + AUDIO_ERR_LOG("need not SwitchStream!"); + } + } else { + AUDIO_INFO_LOG("Do not SwitchStream , is low latency renderer: %{public}d!", isFastRenderer_); + } +} + bool AudioRendererPrivate::IsDeviceChanged(DeviceInfo &newDeviceInfo) { bool deviceUpdated = false; @@ -1032,13 +1162,17 @@ void AudioRendererStateChangeCallbackImpl::OnRendererStateChange( const std::vector> &audioRendererChangeInfos) { std::shared_ptr cb = callback_.lock(); - if (cb == nullptr) { - AUDIO_ERR_LOG("AudioRendererStateChangeCallbackImpl::OnStateChange cb == nullptr."); - return; - } AUDIO_INFO_LOG("AudioRendererStateChangeCallbackImpl OnRendererStateChange"); DeviceInfo deviceInfo = {}; if (renderer->IsDeviceChanged(deviceInfo)) { + if (deviceInfo.deviceType != DEVICE_TYPE_NONE && deviceInfo.deviceType != DEVICE_TYPE_INVALID) { + // switch audio channel + renderer->SwitchStream(deviceInfo.isLowLatencyDevice); + } + if (cb == nullptr) { + AUDIO_ERR_LOG("AudioRendererStateChangeCallbackImpl::OnStateChange cb == nullptr."); + return; + } cb->OnStateChange(deviceInfo); } } @@ -1057,5 +1191,29 @@ int32_t AudioRendererPrivate::SetAudioEffectMode(AudioEffectMode effectMode) con { return audioStream_->SetAudioEffectMode(effectMode); } + +void AudioRendererPrivate::SetSelfRendererStateCallback() +{ + if (GetCurrentOutputDevices(currentDeviceInfo) != SUCCESS) { + AUDIO_ERR_LOG("get current device info failed"); + } + + int32_t clientPid = getpid(); + if (!audioDeviceChangeCallback_) { + audioDeviceChangeCallback_ = std::make_shared(); + if (!audioDeviceChangeCallback_) { + AUDIO_ERR_LOG("AudioRendererPrivate: Memory Allocation Failed !!"); + } + } + + int32_t ret = AudioPolicyManager::GetInstance().RegisterAudioRendererEventListener(clientPid, + audioDeviceChangeCallback_); + if (ret != 0) { + AUDIO_ERR_LOG("AudioRendererPrivate::RegisterAudioRendererEventListener failed"); + } + + audioDeviceChangeCallback_->setAudioRendererObj(this); + AUDIO_INFO_LOG("AudioRendererPrivate::RegisterAudioRendererEventListener successful!"); +} } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/audiostream/include/audio_stream.h b/frameworks/native/audiostream/include/audio_stream.h index 9889ba331b..92e994225c 100644 --- a/frameworks/native/audiostream/include/audio_stream.h +++ b/frameworks/native/audiostream/include/audio_stream.h @@ -94,7 +94,11 @@ public: // Recording related APIs int32_t Read(uint8_t &buffer, size_t userSize, bool isBlockingRead) override; + void SetStreamTrackerState(bool trackerRegisteredState) override; + void GetSwitchInfo(SwitchInfo& info) override; + private: + void RegisterTracker(const std::shared_ptr &proxyObj); AudioStreamType eStreamType_; AudioMode eMode_; State state_; @@ -123,6 +127,8 @@ private: std::mutex bufferQueueLock_; std::condition_variable bufferQueueCV_; + + bool streamTrackerRegistered_ = false; }; } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/audiostream/include/fast_audio_stream.h b/frameworks/native/audiostream/include/fast_audio_stream.h index 56c2376f74..7e9860288c 100644 --- a/frameworks/native/audiostream/include/fast_audio_stream.h +++ b/frameworks/native/audiostream/include/fast_audio_stream.h @@ -31,12 +31,14 @@ namespace AudioStandard { class FastAudioStreamRenderCallback : public AudioDataCallback { public: FastAudioStreamRenderCallback(const std::shared_ptr &callback) - : renderCallback_(callback) {}; + : rendererWriteCallback_(callback) {}; virtual ~FastAudioStreamRenderCallback() = default; void OnHandleData(size_t length) override; + std::shared_ptr GetRendererWriteCallback() const; + private: - std::shared_ptr renderCallback_ = nullptr; + std::shared_ptr rendererWriteCallback_ = nullptr; }; class FastAudioStreamCaptureCallback : public AudioDataCallback { @@ -133,6 +135,11 @@ public: int32_t SetBufferSizeInMsec(int32_t bufferSizeInMsec) override; void SetApplicationCachePath(const std::string cachePath) override; + void SetStreamTrackerState(bool trackerRegisteredState) override; + void GetSwitchInfo(IAudioStream::SwitchInfo& info) override; + + IAudioStream::StreamClass GetStreamClass() override; + private: AudioStreamType eStreamType_; AudioMode eMode_; @@ -153,6 +160,7 @@ private: AudioRendererRate renderRate_ = RENDER_RATE_NORMAL; int32_t clientPid_ = 0; int32_t clientUid_ = 0; + bool streamTrackerRegistered_ = false; }; } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/audiostream/include/i_audio_stream.h b/frameworks/native/audiostream/include/i_audio_stream.h index f0ff977957..fb6d440c72 100644 --- a/frameworks/native/audiostream/include/i_audio_stream.h +++ b/frameworks/native/audiostream/include/i_audio_stream.h @@ -43,6 +43,47 @@ public: FAST_STREAM, }; + struct SwitchInfo { + AudioStreamParams params; + AudioStreamType eStreamType; + int32_t appUid; + AudioRendererInfo rendererInfo; + AudioCapturerInfo capturerInfo; + State state; + uint32_t sessionId; + std::string cachePath = ""; + uint32_t rendererSampleRate; + uint32_t underFlowCount; + AudioEffectMode effectMode; + AudioRenderMode renderMode; + AudioCaptureMode captureMode; + AudioRendererRate renderRate; + int32_t clientPid = 0; + int32_t clientUid = 0; + std::shared_ptr proxyObj; + AudioPrivacyType privacyType; + float volume; + + bool streamTrackerRegistered = false; + + uint64_t frameMarkPosition = 0; + uint64_t framePeriodNumber = 0; + + uint64_t totalBytesWritten = 0; + uint64_t framePeriodWritten = 0; + std::shared_ptr renderPositionCb; + std::shared_ptr renderPeriodPositionCb; + + uint64_t totalBytesRead = 0; + uint64_t framePeriodRead = 0; + std::shared_ptr capturePositionCb; + std::shared_ptr capturePeriodPositionCb; + + // callback info + std::shared_ptr audioStreamCallback; + std::shared_ptr rendererWriteCallback; + }; + virtual ~IAudioStream() = default; static bool IsStreamSupported(int32_t streamFlags, const AudioStreamParams ¶ms); @@ -142,6 +183,10 @@ public: virtual uint32_t GetRendererSamplingRate() = 0; virtual int32_t SetBufferSizeInMsec(int32_t bufferSizeInMsec) = 0; virtual void SetApplicationCachePath(const std::string cachePath) = 0; + + virtual IAudioStream::StreamClass GetStreamClass() = 0; + virtual void SetStreamTrackerState(bool trackerRegisteredState) = 0; + virtual void GetSwitchInfo(SwitchInfo& info) = 0; }; } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/ohaudio/OHAudioRenderer.cpp b/frameworks/native/ohaudio/OHAudioRenderer.cpp index 63dea5ffe0..b6ddcf882b 100644 --- a/frameworks/native/ohaudio/OHAudioRenderer.cpp +++ b/frameworks/native/ohaudio/OHAudioRenderer.cpp @@ -353,6 +353,10 @@ void OHAudioRenderer::SetRendererCallback(OH_AudioRenderer_Callbacks callbacks, std::make_shared(callbacks, (OH_AudioRenderer*)this, userData); int32_t clientPid = getpid(); audioRenderer_->RegisterAudioPolicyServerDiedCb(clientPid, callback); + + std::shared_ptr errorCallback = + std::make_shared(callbacks, (OH_AudioRenderer*)this, userData); + audioRenderer_->SetAudioRendererErrorCallback(errorCallback); } else { AUDIO_ERR_LOG("audio error callback is nullptr"); } @@ -397,5 +401,27 @@ void OHServiceDiedCallback::OnAudioPolicyServiceDied() OH_AudioStream_Result error = AUDIOSTREAM_ERROR_SYSTEM; callbacks_.OH_AudioRenderer_OnError(ohAudioRenderer_, userData_, error); } + +OH_AudioStream_Result OHAudioRendererErrorCallback::GetErrorResult(AudioErrors errorCode) const +{ + switch (errorCode) { + case ERROR_ILLEGAL_STATE: + return AUDIOSTREAM_ERROR_ILLEGAL_STATE; + case ERROR_INVALID_PARAM: + return AUDIOSTREAM_ERROR_INVALID_PARAM; + case ERROR_SYSTEM: + return AUDIOSTREAM_ERROR_SYSTEM; + default: + return AUDIOSTREAM_ERROR_SYSTEM; + } +} + +void OHAudioRendererErrorCallback::OnError(AudioErrors errorCode) +{ + CHECK_AND_RETURN_LOG(ohAudioRenderer_ != nullptr && callbacks_.OH_AudioRenderer_OnError != nullptr, + "renderer client or error callback funtion is nullptr"); + OH_AudioStream_Result error = GetErrorResult(errorCode); + callbacks_.OH_AudioRenderer_OnError(ohAudioRenderer_, userData_, error); +} } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/ohaudio/OHAudioRenderer.h b/frameworks/native/ohaudio/OHAudioRenderer.h index c4c5693476..aed61a9a3c 100644 --- a/frameworks/native/ohaudio/OHAudioRenderer.h +++ b/frameworks/native/ohaudio/OHAudioRenderer.h @@ -79,6 +79,23 @@ public: void OnAudioPolicyServiceDied() override; +private: + OH_AudioRenderer_Callbacks callbacks_; + OH_AudioRenderer* ohAudioRenderer_; + void* userData_; +}; + +class OHAudioRendererErrorCallback : public AudioRendererErrorCallback { +public: + OHAudioRendererErrorCallback(OH_AudioRenderer_Callbacks callbacks, OH_AudioRenderer* audioRenderer, + void* userData) : callbacks_(callbacks), ohAudioRenderer_(audioRenderer), userData_(userData) + { + } + + void OnError(AudioErrors errorCode) override; + + OH_AudioStream_Result GetErrorResult(AudioErrors errorCode) const; + private: OH_AudioRenderer_Callbacks callbacks_; OH_AudioRenderer* ohAudioRenderer_; diff --git a/frameworks/native/ohaudio/test/example/oh_audio_renderer_test.cpp b/frameworks/native/ohaudio/test/example/oh_audio_renderer_test.cpp index fc8a5cd3fe..700703eb5a 100644 --- a/frameworks/native/ohaudio/test/example/oh_audio_renderer_test.cpp +++ b/frameworks/native/ohaudio/test/example/oh_audio_renderer_test.cpp @@ -30,6 +30,7 @@ namespace AudioTestConstants { constexpr int32_t FIRST_ARG_IDX = 1; constexpr int32_t SECOND_ARG_IDX = 2; constexpr int32_t THIRD_ARG_IDX = 3; + constexpr int32_t FOUR_ARG_IDX = 4; constexpr int32_t WAIT_INTERVAL = 1000; } @@ -38,6 +39,7 @@ FILE* g_file = nullptr; bool g_readEnd = false; int32_t g_samplingRate = 48000; int32_t g_channelCount = 2; +int32_t g_latencyMode = 0; static int32_t AudioRendererOnWriteData(OH_AudioRenderer* capturer, void* userData, @@ -70,6 +72,7 @@ void PlayerTest(char *argv[]) // 2. set params and callbacks OH_AudioStreamBuilder_SetSamplingRate(builder, g_samplingRate); OH_AudioStreamBuilder_SetChannelCount(builder, g_channelCount); + OH_AudioStreamBuilder_SetLatencyMode(builder, (OH_AudioStream_LatencyMode)g_channelCount); OH_AudioRenderer_Callbacks callbacks; callbacks.OH_AudioRenderer_OnWriteData = AudioRendererOnWriteData; @@ -93,11 +96,11 @@ void PlayerTest(char *argv[]) std::this_thread::sleep_for(std::chrono::milliseconds(AudioTestConstants::WAIT_INTERVAL)); int64_t frames; OH_AudioRenderer_GetFramesWritten(audioRenderer, &frames); - printf("Wait for the audio to finish playing.(..%d s) frames:%lld\n", ++timer, frames); + printf("Wait for the audio to finish playing.(..%d s) frames:%ld\n", ++timer, frames); int64_t framePosition; int64_t timestamp; OH_AudioRenderer_GetTimestamp(audioRenderer, CLOCK_MONOTONIC, &framePosition, ×tamp); - printf("framePosition %lld timestamp:%lld\n", framePosition, timestamp); + printf("framePosition %ld timestamp:%ld\n", framePosition, timestamp); } // 5. stop and release client ret = OH_AudioRenderer_Stop(audioRenderer); @@ -114,8 +117,8 @@ int main(int argc, char *argv[]) { printf("start \n"); if ((argv == nullptr) || (argc < AudioTestConstants::THIRD_ARG_IDX)) { - printf("input parms wrong. input format: filePath samplingRate channelCount \n"); - printf("input demo: ./oh_audio_renderer_test ./oh_test_audio.pcm 48000 2 \n"); + printf("input parms wrong. input format: filePath samplingRate channelCount latencyMode\n"); + printf("input demo: ./oh_audio_renderer_test ./oh_test_audio.pcm 48000 2 1 \n"); return 0; } printf("argc=%d ", argc); @@ -125,6 +128,8 @@ int main(int argc, char *argv[]) g_samplingRate = atoi(argv[AudioTestConstants::SECOND_ARG_IDX]); g_channelCount = atoi(argv[AudioTestConstants::THIRD_ARG_IDX]); + g_latencyMode = atoi(argv[AudioTestConstants::FOUR_ARG_IDX]); + g_filePath = argv[AudioTestConstants::FIRST_ARG_IDX]; printf("filePATH: %s \n", g_filePath.c_str()); diff --git a/interfaces/inner_api/native/audiocommon/include/audio_info.h b/interfaces/inner_api/native/audiocommon/include/audio_info.h index 587aa84309..92938d274b 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_info.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_info.h @@ -1026,6 +1026,7 @@ struct DeviceInfo { std::string displayName; int32_t interruptGroupId; int32_t volumeGroupId; + bool isLowLatencyDevice; }; enum StreamSetState { diff --git a/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h b/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h index bfcc9bc439..3f0baf3a4d 100644 --- a/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h +++ b/interfaces/inner_api/native/audiorenderer/include/audio_renderer.h @@ -118,6 +118,19 @@ public: virtual void RemoveAllCallbacks() = 0; }; +class AudioRendererErrorCallback { +public: + virtual ~AudioRendererErrorCallback() = default; + + /** + * Called when an unrecoverable exception occurs in the renderer + * + * @param errorCode Indicates error code of the exception. + * since 10 + */ + virtual void OnError(AudioErrors errorCode) = 0; +}; + /** * @brief Provides functions for applications to implement audio rendering. * @since 8 @@ -722,6 +735,14 @@ public: */ virtual int32_t SetAudioEffectMode(AudioEffectMode effectMode) const = 0; + /** + * @brief Registers the renderer error event callback listener. + * + * @param errorCallback Error callback pointer + * @since 10 + */ + virtual void SetAudioRendererErrorCallback(std::shared_ptr errorCallback) = 0; + /** * @brief Registers the renderer event callback listener. * @@ -769,6 +790,7 @@ public: * @since 10 */ virtual void DestroyAudioRendererStateCallback() = 0; + virtual ~AudioRenderer(); private: static std::mutex createRendererMutex_; diff --git a/services/audio_policy/client/src/audio_capturer_state_change_listener_stub.cpp b/services/audio_policy/client/src/audio_capturer_state_change_listener_stub.cpp index 9f0aff7d87..4d3017d162 100644 --- a/services/audio_policy/client/src/audio_capturer_state_change_listener_stub.cpp +++ b/services/audio_policy/client/src/audio_capturer_state_change_listener_stub.cpp @@ -59,6 +59,7 @@ void AudioCapturerStateChangeListenerStub::ReadAudioCapturerChangeInfo(MessagePa capturerChangeInfo->inputDeviceInfo.networkId = data.ReadString(); capturerChangeInfo->inputDeviceInfo.interruptGroupId = data.ReadInt32(); capturerChangeInfo->inputDeviceInfo.volumeGroupId = data.ReadInt32(); + capturerChangeInfo->inputDeviceInfo.isLowLatencyDevice = data.ReadBool(); AUDIO_DEBUG_LOG("AudioCapturerStateChangeListenerStub, sessionid = %{public}d", capturerChangeInfo->sessionId); AUDIO_DEBUG_LOG("AudioCapturerStateChangeListenerStub, capturerState = %{public}d", diff --git a/services/audio_policy/client/src/audio_policy_proxy.cpp b/services/audio_policy/client/src/audio_policy_proxy.cpp index 332d42e360..5e0c619e5a 100644 --- a/services/audio_policy/client/src/audio_policy_proxy.cpp +++ b/services/audio_policy/client/src/audio_policy_proxy.cpp @@ -1721,6 +1721,7 @@ void AudioPolicyProxy::ReadAudioRendererChangeInfo(MessageParcel &reply, rendererChangeInfo->outputDeviceInfo.networkId = reply.ReadString(); rendererChangeInfo->outputDeviceInfo.interruptGroupId = reply.ReadInt32(); rendererChangeInfo->outputDeviceInfo.volumeGroupId = reply.ReadInt32(); + rendererChangeInfo->outputDeviceInfo.isLowLatencyDevice = reply.ReadBool(); } void AudioPolicyProxy::ReadAudioCapturerChangeInfo(MessageParcel &reply, @@ -1748,6 +1749,7 @@ void AudioPolicyProxy::ReadAudioCapturerChangeInfo(MessageParcel &reply, capturerChangeInfo->inputDeviceInfo.networkId = reply.ReadString(); capturerChangeInfo->inputDeviceInfo.interruptGroupId = reply.ReadInt32(); capturerChangeInfo->inputDeviceInfo.volumeGroupId = reply.ReadInt32(); + capturerChangeInfo->inputDeviceInfo.isLowLatencyDevice = reply.ReadBool(); } int32_t AudioPolicyProxy::GetCurrentRendererChangeInfos( diff --git a/services/audio_policy/client/src/audio_renderer_state_change_listener_stub.cpp b/services/audio_policy/client/src/audio_renderer_state_change_listener_stub.cpp index 96016963b6..f209b88477 100644 --- a/services/audio_policy/client/src/audio_renderer_state_change_listener_stub.cpp +++ b/services/audio_policy/client/src/audio_renderer_state_change_listener_stub.cpp @@ -62,6 +62,7 @@ void AudioRendererStateChangeListenerStub::ReadAudioRendererChangeInfo(MessagePa rendererChangeInfo->outputDeviceInfo.networkId = data.ReadString(); rendererChangeInfo->outputDeviceInfo.interruptGroupId = data.ReadInt32(); rendererChangeInfo->outputDeviceInfo.volumeGroupId = data.ReadInt32(); + rendererChangeInfo->outputDeviceInfo.isLowLatencyDevice = data.ReadBool(); AUDIO_DEBUG_LOG("AudioRendererStateChangeListenerStub, sessionid = %{public}d", rendererChangeInfo->sessionId); AUDIO_DEBUG_LOG("AudioRendererStateChangeListenerStub, rendererState = %{public}d", diff --git a/services/audio_policy/server/src/audio_capturer_state_change_listener_proxy.cpp b/services/audio_policy/server/src/audio_capturer_state_change_listener_proxy.cpp index 4aef6e90a3..3c34e6e1a9 100644 --- a/services/audio_policy/server/src/audio_capturer_state_change_listener_proxy.cpp +++ b/services/audio_policy/server/src/audio_capturer_state_change_listener_proxy.cpp @@ -56,6 +56,7 @@ void AudioCapturerStateChangeListenerProxy::WriteCapturerChangeInfo(MessageParce data.WriteString(capturerChangeInfo->inputDeviceInfo.networkId); data.WriteInt32(capturerChangeInfo->inputDeviceInfo.interruptGroupId); data.WriteInt32(capturerChangeInfo->inputDeviceInfo.volumeGroupId); + data.WriteBool(capturerChangeInfo->inputDeviceInfo.isLowLatencyDevice); } void AudioCapturerStateChangeListenerProxy::OnCapturerStateChange( diff --git a/services/audio_policy/server/src/audio_policy_manager_stub.cpp b/services/audio_policy/server/src/audio_policy_manager_stub.cpp index 611ba010b0..d37c4064f4 100644 --- a/services/audio_policy/server/src/audio_policy_manager_stub.cpp +++ b/services/audio_policy/server/src/audio_policy_manager_stub.cpp @@ -800,6 +800,7 @@ void AudioPolicyManagerStub::GetRendererChangeInfosInternal(MessageParcel &data, reply.WriteString(rendererChangeInfo->outputDeviceInfo.networkId); reply.WriteInt32(rendererChangeInfo->outputDeviceInfo.interruptGroupId); reply.WriteInt32(rendererChangeInfo->outputDeviceInfo.volumeGroupId); + reply.WriteBool(rendererChangeInfo->outputDeviceInfo.isLowLatencyDevice); } AUDIO_DEBUG_LOG("AudioPolicyManagerStub:Renderer change info internal exit"); @@ -844,6 +845,7 @@ void AudioPolicyManagerStub::GetCapturerChangeInfosInternal(MessageParcel &data, reply.WriteString(capturerChangeInfo->inputDeviceInfo.networkId); reply.WriteInt32(capturerChangeInfo->inputDeviceInfo.interruptGroupId); reply.WriteInt32(capturerChangeInfo->inputDeviceInfo.volumeGroupId); + reply.WriteBool(capturerChangeInfo->inputDeviceInfo.isLowLatencyDevice); } AUDIO_DEBUG_LOG("AudioPolicyManagerStub:Capturer change info internal exit"); } diff --git a/services/audio_policy/server/src/audio_renderer_state_change_listener_proxy.cpp b/services/audio_policy/server/src/audio_renderer_state_change_listener_proxy.cpp index e60fe80eef..8d7a091520 100644 --- a/services/audio_policy/server/src/audio_renderer_state_change_listener_proxy.cpp +++ b/services/audio_policy/server/src/audio_renderer_state_change_listener_proxy.cpp @@ -59,6 +59,7 @@ void AudioRendererStateChangeListenerProxy::WriteRendererChangeInfo(MessageParce data.WriteString(rendererChangeInfo->outputDeviceInfo.networkId); data.WriteInt32(rendererChangeInfo->outputDeviceInfo.interruptGroupId); data.WriteInt32(rendererChangeInfo->outputDeviceInfo.volumeGroupId); + data.WriteBool(rendererChangeInfo->outputDeviceInfo.isLowLatencyDevice); } void AudioRendererStateChangeListenerProxy::OnRendererStateChange( diff --git a/services/audio_policy/server/src/service/audio_policy_service.cpp b/services/audio_policy/server/src/service/audio_policy_service.cpp index 821951e74e..424b80abc8 100644 --- a/services/audio_policy/server/src/service/audio_policy_service.cpp +++ b/services/audio_policy/server/src/service/audio_policy_service.cpp @@ -2589,6 +2589,29 @@ static void UpdateCapturerInfoWhenNoPermission(const unique_ptr &desc, bool hasBTPermission, bool hasSystemPermission) { @@ -2606,6 +2629,9 @@ static void UpdateDeviceInfo(DeviceInfo &deviceInfo, const sptrnetworkId_ != LOCAL_NETWORK_ID); + if (hasSystemPermission) { deviceInfo.networkId = desc->networkId_; deviceInfo.volumeGroupId = desc->volumeGroupId_; diff --git a/services/audio_service/client/include/audio_service_client.h b/services/audio_service/client/include/audio_service_client.h index d93e00c889..ac0cd6b34e 100644 --- a/services/audio_service/client/include/audio_service_client.h +++ b/services/audio_service/client/include/audio_service_client.h @@ -513,6 +513,9 @@ public: void SetClientID(int32_t clientPid, int32_t clientUid) override; + IAudioStream::StreamClass GetStreamClass() override; + void GetStreamSwitchInfo(SwitchInfo& info); + protected: virtual void ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) override; void SendWriteBufferRequestEvent(); @@ -619,6 +622,8 @@ private: std::map sourceOutputs; std::map clientInfo; + IAudioStream::StreamClass streamClass_; + ASClientType eAudioClientType; uint32_t underFlowCount; 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 865aecff5d..9013f64c32 100644 --- a/services/audio_service/client/src/audio_process_in_client.cpp +++ b/services/audio_service/client/src/audio_process_in_client.cpp @@ -280,7 +280,7 @@ int32_t AudioProcessInClientInner::OnEndpointChange(int32_t status) int32_t AudioProcessInClientInner::GetSessionID(uint32_t &sessionID) { // note: Get the session id from server. - int32_t pid = processConfig_.appInfo.appUid; + int32_t pid = processConfig_.appInfo.appPid; if (pid < 0) { AUDIO_ERR_LOG("GetSessionID failed:%{public}d", pid); return ERR_OPERATION_FAILED; @@ -383,6 +383,7 @@ void AudioProcessInClientInner::SetApplicationCachePath(const std::string &cache cachePath_ = cachePath; } + bool AudioProcessInClientInner::InitAudioBuffer() { CHECK_AND_RETURN_RET_LOG(processProxy_ != nullptr, false, "Init failed with null ipcProxy."); diff --git a/services/audio_service/client/src/audio_service_client.cpp b/services/audio_service/client/src/audio_service_client.cpp index 703f103c0d..564af5697b 100644 --- a/services/audio_service/client/src/audio_service_client.cpp +++ b/services/audio_service/client/src/audio_service_client.cpp @@ -1639,6 +1639,35 @@ void AudioServiceClient::SetClientID(int32_t clientPid, int32_t clientUid) clientUid_ = clientUid; } +IAudioStream::StreamClass AudioServiceClient::GetStreamClass() +{ + return streamClass_; +} + +void AudioServiceClient::GetStreamSwitchInfo(SwitchInfo& info) +{ + info.cachePath = cachePath_; + info.rendererSampleRate = rendererSampleRate; + info.underFlowCount = underFlowCount; + info.effectMode = effectMode; + info.renderMode = renderMode_; + info.captureMode = captureMode_; + info.renderRate = renderRate; + info.clientPid = clientPid_; + info.clientUid = clientUid_; + info.volume = mVolumeFactor; + + info.frameMarkPosition = mFrameMarkPosition; + info.renderPositionCb = mRenderPositionCb; + info.capturePositionCb = mCapturePositionCb; + + info.framePeriodNumber = mFramePeriodNumber; + info.renderPeriodPositionCb = mRenderPeriodPositionCb; + info.capturePeriodPositionCb = mCapturePeriodPositionCb; + + info.rendererWriteCallback = writeCallback_; +} + void AudioServiceClient::HandleCapturePositionCallbacks(size_t bytesRead) { mTotalBytesRead += bytesRead; diff --git a/services/audio_service/client/src/audio_stream.cpp b/services/audio_service/client/src/audio_stream.cpp index 88df7b2557..58aebd1991 100644 --- a/services/audio_service/client/src/audio_stream.cpp +++ b/services/audio_service/client/src/audio_stream.cpp @@ -237,11 +237,22 @@ int32_t AudioStream::GetAudioStreamInfo(AudioStreamParams &audioStreamInfo) return SUCCESS; } +void AudioStream::RegisterTracker(const std::shared_ptr &proxyObj) +{ + if (audioStreamTracker_ && audioStreamTracker_.get() && !streamTrackerRegistered_) { + (void)GetSessionID(sessionId_); + AUDIO_DEBUG_LOG("AudioStream:Calling register tracker, sessionid = %{public}d", sessionId_); + audioStreamTracker_->RegisterTracker(sessionId_, state_, rendererInfo_, capturerInfo_, proxyObj); + streamTrackerRegistered_ = true; + } +} + int32_t AudioStream::SetAudioStreamInfo(const AudioStreamParams info, const std::shared_ptr &proxyObj) { AUDIO_INFO_LOG("AudioStreamInfo, Sampling rate: %{public}d, channels: %{public}d, format: %{public}d," - " stream type: %{public}d", info.samplingRate, info.channels, info.format, eStreamType_); + " stream type: %{public}d, encoding type: %{public}d", info.samplingRate, info.channels, info.format, + eStreamType_, info.encoding); if (!IsFormatValid(info.format) || !IsSamplingRateValid(info.samplingRate) || !IsEncodingTypeValid(info.encoding)) { AUDIO_ERR_LOG("AudioStream: Unsupported audio parameter"); @@ -284,12 +295,7 @@ int32_t AudioStream::SetAudioStreamInfo(const AudioStreamParams info, } state_ = PREPARED; AUDIO_DEBUG_LOG("AudioStream:Set stream Info SUCCESS"); - - if (audioStreamTracker_ && audioStreamTracker_.get()) { - (void)GetSessionID(sessionId_); - AUDIO_DEBUG_LOG("AudioStream:Calling register tracker, sessionid = %{public}d", sessionId_); - audioStreamTracker_->RegisterTracker(sessionId_, state_, rendererInfo_, capturerInfo_, proxyObj); - } + RegisterTracker(proxyObj); return SUCCESS; } @@ -925,5 +931,25 @@ int64_t AudioStream::GetFramesRead() { return GetStreamFramesRead(); } + +void AudioStream::SetStreamTrackerState(bool trackerRegisteredState) +{ + streamTrackerRegistered_ = trackerRegisteredState; +} + +void AudioStream::GetSwitchInfo(SwitchInfo& info) +{ + GetAudioStreamParams(info.params); + + info.rendererInfo = rendererInfo_; + info.capturerInfo = capturerInfo_; + info.eStreamType = eStreamType_; + info.renderMode = renderMode_; + info.state = state_; + info.sessionId = sessionId_; + info.streamTrackerRegistered = streamTrackerRegistered_; + GetStreamSwitchInfo(info); +} + } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/client/src/fast_audio_stream.cpp b/services/audio_service/client/src/fast_audio_stream.cpp index 42429b9996..a427e78835 100644 --- a/services/audio_service/client/src/fast_audio_stream.cpp +++ b/services/audio_service/client/src/fast_audio_stream.cpp @@ -289,7 +289,7 @@ int32_t FastAudioStream::SetCapturerReadCallback(const std::shared_ptrGetRendererWriteCallback(); + } +} + void FastAudioStreamRenderCallback::OnHandleData(size_t length) { - CHECK_AND_RETURN_LOG(renderCallback_!= nullptr, "OnHandleData failed: renderCallback_ is null."); - renderCallback_->OnWriteData(length); + CHECK_AND_RETURN_LOG(rendererWriteCallback_!= nullptr, "OnHandleData failed: rendererWriteCallback_ is null."); + rendererWriteCallback_->OnWriteData(length); +} + +std::shared_ptr FastAudioStreamRenderCallback::GetRendererWriteCallback() const +{ + return rendererWriteCallback_; } void FastAudioStreamCaptureCallback::OnHandleData(size_t length) diff --git a/services/audio_service/client/src/policy_provider_stub.cpp b/services/audio_service/client/src/policy_provider_stub.cpp index eeb2791c09..2796af3366 100644 --- a/services/audio_service/client/src/policy_provider_stub.cpp +++ b/services/audio_service/client/src/policy_provider_stub.cpp @@ -69,6 +69,7 @@ int32_t PolicyProviderStub::HandleGetProcessDeviceInfo(MessageParcel &data, Mess reply.WriteString(deviceInfo.displayName); reply.WriteInt32(deviceInfo.interruptGroupId); reply.WriteInt32(deviceInfo.volumeGroupId); + reply.WriteBool(deviceInfo.isLowLatencyDevice); return AUDIO_OK; } diff --git a/services/audio_service/server/src/policy_provider_proxy.cpp b/services/audio_service/server/src/policy_provider_proxy.cpp index 7adbf39799..578fe0e24c 100644 --- a/services/audio_service/server/src/policy_provider_proxy.cpp +++ b/services/audio_service/server/src/policy_provider_proxy.cpp @@ -59,6 +59,7 @@ int32_t PolicyProviderProxy::GetProcessDeviceInfo(const AudioProcessConfig &conf deviceInfo.displayName = reply.ReadString(); deviceInfo.interruptGroupId = reply.ReadInt32(); deviceInfo.volumeGroupId = reply.ReadInt32(); + deviceInfo.isLowLatencyDevice = reply.ReadBool(); return SUCCESS; } -- Gitee From 3211806ffdafb92bb5f2246dce3a446f9686778a Mon Sep 17 00:00:00 2001 From: zhanhang Date: Mon, 31 Jul 2023 16:46:55 +0800 Subject: [PATCH 2/2] modify callback method Signed-off-by: zhanhang --- .../include/audio_policy_manager.h | 1 + .../include/audio_renderer_private.h | 1 + .../audiorenderer/src/audio_renderer.cpp | 18 +++++++++----- .../test/example/oh_audio_renderer_test.cpp | 11 +++++---- ...udio_renderer_state_change_listener_stub.h | 2 +- .../client/src/audio_policy_manager.cpp | 24 ++++++++++++++----- ...io_renderer_state_change_listener_stub.cpp | 16 +++++++------ 7 files changed, 48 insertions(+), 25 deletions(-) diff --git a/frameworks/native/audiopolicy/include/audio_policy_manager.h b/frameworks/native/audiopolicy/include/audio_policy_manager.h index 6a2189d557..073dbef926 100644 --- a/frameworks/native/audiopolicy/include/audio_policy_manager.h +++ b/frameworks/native/audiopolicy/include/audio_policy_manager.h @@ -253,6 +253,7 @@ private: sptr capturerStateChangelistenerStub_ = nullptr; sptr clientTrackerCbStub_ = nullptr; static std::unordered_map> rendererCBMap_; + bool rendererStateChangeRegistered = false; }; } // namespce AudioStandard } // namespace OHOS diff --git a/frameworks/native/audiorenderer/include/audio_renderer_private.h b/frameworks/native/audiorenderer/include/audio_renderer_private.h index 6c340ec0d4..9a914fb8f0 100644 --- a/frameworks/native/audiorenderer/include/audio_renderer_private.h +++ b/frameworks/native/audiorenderer/include/audio_renderer_private.h @@ -122,6 +122,7 @@ private: void SetSwitchInfo(IAudioStream::SwitchInfo info, std::shared_ptr audioStream); bool SwitchToTargetStream(IAudioStream::StreamClass targetClass); void SetSelfRendererStateCallback(); + void InitDumpInfo(); std::shared_ptr audioStream_; std::shared_ptr audioInterruptCallback_ = nullptr; diff --git a/frameworks/native/audiorenderer/src/audio_renderer.cpp b/frameworks/native/audiorenderer/src/audio_renderer.cpp index f2ca23bc90..25d829500a 100644 --- a/frameworks/native/audiorenderer/src/audio_renderer.cpp +++ b/frameworks/native/audiorenderer/src/audio_renderer.cpp @@ -66,6 +66,9 @@ AudioRendererPrivate::~AudioRendererPrivate() if (state != RENDERER_RELEASED && state != RENDERER_NEW) { Release(); } + + // Unregister the renderer event callaback in policy server + (void)AudioPolicyManager::GetInstance().UnregisterAudioRendererEventListener(appInfo_.appPid); #ifdef DUMP_CLIENT_PCM if (dcp_) { fclose(dcp_); @@ -273,6 +276,7 @@ int32_t AudioRendererPrivate::SetParams(const AudioRendererParams params) if (IAudioStream::IsStreamSupported(rendererInfo_.rendererFlags, audioStreamParams)) { AUDIO_INFO_LOG("Create stream with STREAM_FLAG_FAST"); streamClass = IAudioStream::FAST_STREAM; + isFastRenderer_ = true; } else { AUDIO_ERR_LOG("Unsupported parameter, try to create a normal stream"); streamClass = IAudioStream::PA_STREAM; @@ -303,6 +307,14 @@ int32_t AudioRendererPrivate::SetParams(const AudioRendererParams params) } AUDIO_INFO_LOG("AudioRendererPrivate::SetParams SetAudioStreamInfo Succeeded"); + SetSelfRendererStateCallback(); + InitDumpInfo(); + + return InitAudioInterruptCallback(); +} + +void AudioRendererPrivate::InitDumpInfo() +{ #ifdef DUMP_CLIENT_PCM uint32_t streamId = 0; GetAudioStreamId(streamId); @@ -318,10 +330,6 @@ int32_t AudioRendererPrivate::SetParams(const AudioRendererParams params) AUDIO_ERR_LOG("Error opening pcm test file!"); } #endif - - SetSelfRendererStateCallback(); - - return InitAudioInterruptCallback(); } int32_t AudioRendererPrivate::GetParams(AudioRendererParams ¶ms) const @@ -567,8 +575,6 @@ bool AudioRendererPrivate::Release() const // Unregister the callaback in policy server (void)AudioPolicyManager::GetInstance().UnsetAudioInterruptCallback(sessionID_); - (void)AudioPolicyManager::GetInstance().UnregisterAudioRendererEventListener(appInfo_.appPid); - return audioStream_->ReleaseAudioStream(); } diff --git a/frameworks/native/ohaudio/test/example/oh_audio_renderer_test.cpp b/frameworks/native/ohaudio/test/example/oh_audio_renderer_test.cpp index 700703eb5a..01cf8c790a 100644 --- a/frameworks/native/ohaudio/test/example/oh_audio_renderer_test.cpp +++ b/frameworks/native/ohaudio/test/example/oh_audio_renderer_test.cpp @@ -72,7 +72,7 @@ void PlayerTest(char *argv[]) // 2. set params and callbacks OH_AudioStreamBuilder_SetSamplingRate(builder, g_samplingRate); OH_AudioStreamBuilder_SetChannelCount(builder, g_channelCount); - OH_AudioStreamBuilder_SetLatencyMode(builder, (OH_AudioStream_LatencyMode)g_channelCount); + OH_AudioStreamBuilder_SetLatencyMode(builder, (OH_AudioStream_LatencyMode)g_latencyMode); OH_AudioRenderer_Callbacks callbacks; callbacks.OH_AudioRenderer_OnWriteData = AudioRendererOnWriteData; @@ -122,15 +122,16 @@ int main(int argc, char *argv[]) return 0; } printf("argc=%d ", argc); - printf("argv[1]=%s ", argv[AudioTestConstants::FIRST_ARG_IDX]); - printf("argv[2]=%s ", argv[AudioTestConstants::SECOND_ARG_IDX]); - printf("argv[3]=%s \n", argv[AudioTestConstants::THIRD_ARG_IDX]); + printf("file path =%s ", argv[AudioTestConstants::FIRST_ARG_IDX]); + printf("sample rate =%s ", argv[AudioTestConstants::SECOND_ARG_IDX]); + printf("channel count =%s \n", argv[AudioTestConstants::THIRD_ARG_IDX]); + printf("latency mode =%s \n", argv[AudioTestConstants::FOUR_ARG_IDX]); + g_filePath = argv[AudioTestConstants::FIRST_ARG_IDX]; g_samplingRate = atoi(argv[AudioTestConstants::SECOND_ARG_IDX]); g_channelCount = atoi(argv[AudioTestConstants::THIRD_ARG_IDX]); g_latencyMode = atoi(argv[AudioTestConstants::FOUR_ARG_IDX]); - g_filePath = argv[AudioTestConstants::FIRST_ARG_IDX]; printf("filePATH: %s \n", g_filePath.c_str()); g_file = fopen(g_filePath.c_str(), "rb"); diff --git a/services/audio_policy/client/include/audio_renderer_state_change_listener_stub.h b/services/audio_policy/client/include/audio_renderer_state_change_listener_stub.h index 989efa6ad5..a2a949bb0d 100644 --- a/services/audio_policy/client/include/audio_renderer_state_change_listener_stub.h +++ b/services/audio_policy/client/include/audio_renderer_state_change_listener_stub.h @@ -34,7 +34,7 @@ public: private: void ReadAudioRendererChangeInfo(MessageParcel &data, std::unique_ptr &rendererChangeInfo); - std::weak_ptr callback_; + std::vector> callbacks_; }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/client/src/audio_policy_manager.cpp b/services/audio_policy/client/src/audio_policy_manager.cpp index fe5c0c8f77..b83f8dee04 100644 --- a/services/audio_policy/client/src/audio_policy_manager.cpp +++ b/services/audio_policy/client/src/audio_policy_manager.cpp @@ -805,10 +805,12 @@ int32_t AudioPolicyManager::RegisterAudioRendererEventListener(const int32_t cli } std::unique_lock lock(stateChangelistenerStubMutex_); - rendererStateChangelistenerStub_ = new(std::nothrow) AudioRendererStateChangeListenerStub(); - if (rendererStateChangelistenerStub_ == nullptr) { - AUDIO_ERR_LOG("RegisterAudioRendererEventListener: object null"); - return ERROR; + if (!rendererStateChangelistenerStub_ && !rendererStateChangeRegistered) { + rendererStateChangelistenerStub_ = new(std::nothrow) AudioRendererStateChangeListenerStub(); + if (rendererStateChangelistenerStub_ == nullptr) { + AUDIO_ERR_LOG("RegisterAudioRendererEventListener: object null"); + return ERROR; + } } rendererStateChangelistenerStub_->SetCallback(callback); @@ -820,7 +822,11 @@ int32_t AudioPolicyManager::RegisterAudioRendererEventListener(const int32_t cli } lock.unlock(); - return gsp->RegisterAudioRendererEventListener(clientPid, object); + if (!rendererStateChangeRegistered) { + gsp->RegisterAudioRendererEventListener(clientPid, object); + rendererStateChangeRegistered = true; + } + return SUCCESS; } int32_t AudioPolicyManager::UnregisterAudioRendererEventListener(const int32_t clientPid) @@ -831,7 +837,13 @@ int32_t AudioPolicyManager::UnregisterAudioRendererEventListener(const int32_t c AUDIO_ERR_LOG("UnregisterAudioRendererEventListener: audio policy manager proxy is NULL."); return ERROR; } - return gsp->UnregisterAudioRendererEventListener(clientPid); + + int32_t ret = ERROR; + ret = gsp->UnregisterAudioRendererEventListener(clientPid); + if (ret == SUCCESS) { + rendererStateChangeRegistered = false; + } + return ret; } int32_t AudioPolicyManager::RegisterAudioCapturerEventListener(const int32_t clientPid, diff --git a/services/audio_policy/client/src/audio_renderer_state_change_listener_stub.cpp b/services/audio_policy/client/src/audio_renderer_state_change_listener_stub.cpp index f209b88477..be2f1ffed8 100644 --- a/services/audio_policy/client/src/audio_renderer_state_change_listener_stub.cpp +++ b/services/audio_policy/client/src/audio_renderer_state_change_listener_stub.cpp @@ -109,20 +109,22 @@ void AudioRendererStateChangeListenerStub::OnRendererStateChange( const vector> &audioRendererChangeInfos) { AUDIO_DEBUG_LOG("AudioRendererStateChangeListenerStub OnRendererStateChange"); - shared_ptr cb = callback_.lock(); - if (cb == nullptr) { - AUDIO_ERR_LOG("AudioRendererStateChangeListenerStub: callback_ is nullptr"); - return; - } - cb->OnRendererStateChange(audioRendererChangeInfos); + for (const auto& callback : callbacks_) { + shared_ptr cb = callback.lock(); + if (cb == nullptr) { + AUDIO_ERR_LOG("AudioRendererStateChangeListenerStub: callback_ is nullptr"); + } else { + cb->OnRendererStateChange(audioRendererChangeInfos); + } + } return; } void AudioRendererStateChangeListenerStub::SetCallback(const weak_ptr &callback) { AUDIO_DEBUG_LOG("AudioRendererStateChangeListenerStub SetCallback"); - callback_ = callback; + callbacks_.push_back(callback); } } // namespace AudioStandard } // namespace OHOS -- Gitee