From 411f8012a0950a5ba5b8f7ddb8b2735d2080931e Mon Sep 17 00:00:00 2001 From: liyuhang Date: Tue, 30 Apr 2024 03:38:18 +0000 Subject: [PATCH] Bluetooth low latency Signed-off-by: liyuhang Change-Id: I72d1ef205dde0266cd892d9c838a70d8abb86868 --- .../audiocapturer/src/audio_capturer.cpp | 5 +- .../include/audio_policy_manager.h | 4 + .../audiorenderer/src/audio_renderer.cpp | 11 +- .../audiostream/include/i_audio_stream.h | 1 - .../bluetooth/bluetooth_renderer_sink.cpp | 97 ++++++++++++++++- .../sink/bluetooth/bluetooth_renderer_sink.h | 3 +- .../sink/common/i_audio_renderer_sink.h | 1 + .../sink/fast/fast_audio_renderer_sink.cpp | 15 ++- .../sink/fast/fast_audio_renderer_sink.h | 3 +- .../source/common/i_audio_capturer_source.h | 1 + .../fast/fast_audio_capturer_source.cpp | 13 ++- .../source/fast/fast_audio_capturer_source.h | 1 + .../native/toneplayer/src/toneplayer.cpp | 1 - .../audiocommon/include/audio_device_info.h | 8 +- .../native/audiocommon/include/audio_info.h | 7 +- services/audio_policy/BUILD.gn | 1 + .../client/include/audio_policy_base.h | 4 + .../include/audio_policy_manager_stub.h | 4 + .../client/include/audio_policy_proxy.h | 4 + .../client/src/audio_policy_manager.cpp | 14 +++ .../client/src/audio_policy_proxy.cpp | 38 +++++++ .../include/audio_policy_ipc_interface_code.h | 2 + .../server/include/audio_policy_server.h | 4 + .../server/include/audio_service_dump.h | 2 +- .../include/service/audio_policy_service.h | 16 ++- .../service/common/audio_adapter_info.h | 6 ++ .../service/config/audio_policy_parser.h | 3 +- .../service/interface/iport_observer.h | 2 +- .../server/src/audio_policy_manager_stub.cpp | 16 +++ .../server/src/audio_policy_server.cpp | 10 ++ .../src/service/audio_policy_service.cpp | 100 +++++++++++++++++- .../src/service/config/audio_adapter_info.cpp | 46 ++++++++ .../service/config/audio_policy_parser.cpp | 26 +++++ services/audio_service/BUILD.gn | 1 + .../client/src/audio_process_in_client.cpp | 16 ++- .../client/src/fast_audio_stream.cpp | 2 +- .../client/src/i_audio_stream.cpp | 3 + .../server/include/audio_endpoint.h | 3 +- .../server/include/audio_service.h | 3 +- .../server/include/policy_handler.h | 2 + .../server/src/audio_endpoint.cpp | 52 ++++++++- .../server/src/audio_service.cpp | 17 ++- .../server/src/policy_handler.cpp | 16 ++- .../audio_policy_another_fuzzer.cpp | 24 +++++ 44 files changed, 556 insertions(+), 52 deletions(-) create mode 100644 services/audio_policy/server/src/service/config/audio_adapter_info.cpp diff --git a/frameworks/native/audiocapturer/src/audio_capturer.cpp b/frameworks/native/audiocapturer/src/audio_capturer.cpp index c859d044cb..0e79bf37dc 100644 --- a/frameworks/native/audiocapturer/src/audio_capturer.cpp +++ b/frameworks/native/audiocapturer/src/audio_capturer.cpp @@ -205,7 +205,10 @@ int32_t AudioCapturerPrivate::SetParams(const AudioCapturerParams params) AudioStreamParams audioStreamParams = ConvertToAudioStreamParams(params); IAudioStream::StreamClass streamClass = IAudioStream::PA_STREAM; - if (capturerInfo_.capturerFlags == STREAM_FLAG_FAST) { + if (capturerInfo_.capturerFlags == STREAM_FLAG_FAST && + IAudioStream::IsStreamSupported(capturerInfo_.capturerFlags, audioStreamParams) && + AudioPolicyManager::GetInstance().GetPreferredInputStreamType(capturerInfo_) == AUDIO_FLAG_MMAP) { + AUDIO_INFO_LOG("Create stream with flag AUDIO_FLAG_MMAP"); streamClass = IAudioStream::FAST_STREAM; } diff --git a/frameworks/native/audiopolicy/include/audio_policy_manager.h b/frameworks/native/audiopolicy/include/audio_policy_manager.h index f99f0e2de2..ab8c265b2f 100644 --- a/frameworks/native/audiopolicy/include/audio_policy_manager.h +++ b/frameworks/native/audiopolicy/include/audio_policy_manager.h @@ -161,6 +161,10 @@ public: uint32_t GetSinkLatencyFromXml(); + int32_t GetPreferredOutputStreamType(AudioRendererInfo &rendererInfo); + + int32_t GetPreferredInputStreamType(AudioCapturerInfo &capturerInfo); + int32_t RegisterAudioRendererEventListener(const int32_t clientPid, const std::shared_ptr &callback); diff --git a/frameworks/native/audiorenderer/src/audio_renderer.cpp b/frameworks/native/audiorenderer/src/audio_renderer.cpp index ed9a4f1537..3949c78306 100644 --- a/frameworks/native/audiorenderer/src/audio_renderer.cpp +++ b/frameworks/native/audiorenderer/src/audio_renderer.cpp @@ -332,14 +332,11 @@ int32_t AudioRendererPrivate::SetParams(const AudioRendererParams params) AudioStreamType audioStreamType = IAudioStream::GetStreamType(rendererInfo_.contentType, rendererInfo_.streamUsage); IAudioStream::StreamClass streamClass = IAudioStream::PA_STREAM; - if (rendererInfo_.rendererFlags == STREAM_FLAG_FORCED_NORMAL) { - streamClass = IAudioStream::FORCED_PA_STREAM; - } else if (rendererInfo_.rendererFlags == STREAM_FLAG_FAST && - IAudioStream::IsStreamSupported(rendererInfo_.rendererFlags, audioStreamParams)) { + if (rendererInfo_.rendererFlags == STREAM_FLAG_FAST && + IAudioStream::IsStreamSupported(rendererInfo_.rendererFlags, audioStreamParams) && + AudioPolicyManager::GetInstance().GetPreferredOutputStreamType(rendererInfo_) == AUDIO_FLAG_MMAP) { isFastRenderer_ = true; - if (AudioPolicyManager::GetInstance().GetActiveOutputDevice() != DEVICE_TYPE_BLUETOOTH_A2DP) { - streamClass = IAudioStream::FAST_STREAM; - } + streamClass = IAudioStream::FAST_STREAM; } else { streamClass = IAudioStream::PA_STREAM; } diff --git a/frameworks/native/audiostream/include/i_audio_stream.h b/frameworks/native/audiostream/include/i_audio_stream.h index 1c48226dae..0c36ffc61e 100644 --- a/frameworks/native/audiostream/include/i_audio_stream.h +++ b/frameworks/native/audiostream/include/i_audio_stream.h @@ -53,7 +53,6 @@ public: enum StreamClass : uint32_t { PA_STREAM = 0, FAST_STREAM, - FORCED_PA_STREAM, }; struct SwitchInfo { diff --git a/frameworks/native/hdiadapter/sink/bluetooth/bluetooth_renderer_sink.cpp b/frameworks/native/hdiadapter/sink/bluetooth/bluetooth_renderer_sink.cpp index 3c2393430c..280a4174aa 100644 --- a/frameworks/native/hdiadapter/sink/bluetooth/bluetooth_renderer_sink.cpp +++ b/frameworks/native/hdiadapter/sink/bluetooth/bluetooth_renderer_sink.cpp @@ -27,6 +27,7 @@ #include #include "audio_proxy_manager.h" +#include "audio_attribute.h" #ifdef FEATURE_POWER_MANAGER #include "running_lock.h" #include "power_mgr_client.h" @@ -50,6 +51,8 @@ const uint32_t AUDIO_CHANNELCOUNT = 2; const uint32_t AUDIO_SAMPLE_RATE_48K = 48000; const uint32_t DEEP_BUFFER_RENDER_PERIOD_SIZE = 4096; const uint32_t RENDER_FRAME_INTERVAL_IN_MICROSECONDS = 10000; +const uint32_t SECOND_TO_NANOSECOND = 1000000000; +const uint32_t SECOND_TO_MILLISECOND = 1000; const uint32_t INT_32_MAX = 0x7fffffff; const uint32_t PCM_8_BIT = 8; const uint32_t PCM_16_BIT = 16; @@ -104,7 +107,7 @@ public: bool GetAudioMonoState(); float GetAudioBalanceValue(); - BluetoothRendererSinkInner(); + explicit BluetoothRendererSinkInner(bool isBluetoothLowLatency = false); ~BluetoothRendererSinkInner(); private: BluetoothSinkAttr attr_; @@ -123,6 +126,19 @@ private: float leftBalanceCoef_ = 1.0f; float rightBalanceCoef_ = 1.0f; + // Low latency + int32_t PrepareMmapBuffer(); + int32_t GetMmapBufferInfo(int &fd, uint32_t &totalSizeInframe, uint32_t &spanSizeInframe, + uint32_t &byteSizePerFrame) override; + int32_t GetMmapHandlePosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanosec) override; + + bool isBluetoothLowLatency_ = false; + uint32_t bufferTotalFrameSize_ = 0; + int32_t bufferFd_ = INVALID_FD; + uint32_t frameSizeInByte_ = 1; + uint32_t eachReadFrameSize_ = 0; + size_t bufferSize_ = 0; + // for get amplitude float maxAmplitude_ = 0; int64_t lastGetMaxAmplitudeTime_ = 0; @@ -150,10 +166,10 @@ private: FILE *dumpFile_ = nullptr; }; -BluetoothRendererSinkInner::BluetoothRendererSinkInner() +BluetoothRendererSinkInner::BluetoothRendererSinkInner(bool isBluetoothLowLatency) : rendererInited_(false), started_(false), paused_(false), leftVolume_(DEFAULT_VOLUME_LEVEL), rightVolume_(DEFAULT_VOLUME_LEVEL), audioManager_(nullptr), audioAdapter_(nullptr), - audioRender_(nullptr), handle_(nullptr) + audioRender_(nullptr), handle_(nullptr), isBluetoothLowLatency_(isBluetoothLowLatency) { attr_ = {}; } @@ -170,6 +186,13 @@ BluetoothRendererSink *BluetoothRendererSink::GetInstance() return &audioRenderer; } +IMmapAudioRendererSink *BluetoothRendererSink::GetMmapInstance() +{ + static BluetoothRendererSinkInner audioRenderer(true); + + return &audioRenderer; +} + bool BluetoothRendererSinkInner::IsInited(void) { return rendererInited_; @@ -249,6 +272,7 @@ void InitAttrs(struct AudioSampleAttributes &attrs) attrs.frameSize = PCM_16_BIT * attrs.channelCount / PCM_8_BIT; attrs.sampleRate = AUDIO_SAMPLE_RATE_48K; attrs.interleaved = 0; + // Bluetooth HDI use adapterNameCase to choose lowLatency / normal attrs.type = AUDIO_IN_MEDIA; attrs.period = DEEP_BUFFER_RENDER_PERIOD_SIZE; attrs.isBigEndian = false; @@ -388,7 +412,7 @@ int32_t BluetoothRendererSinkInner::Init(const IAudioSinkAttr &attr) attr_.channel = attr.channel; attr_.volume = attr.volume; - string adapterNameCase = "bt_a2dp"; // Set sound card information + string adapterNameCase = isBluetoothLowLatency_ ? "bt_a2dp_fast" : "bt_a2dp"; // Set sound card information enum AudioPortDirection port = PORT_OUT; // Set port information CHECK_AND_RETURN_RET_LOG(InitAudioManager() == 0, ERR_NOT_STARTED, @@ -416,6 +440,11 @@ int32_t BluetoothRendererSinkInner::Init(const IAudioSinkAttr &attr) int32_t result = CreateRender(audioPort); CHECK_AND_RETURN_RET_LOG(result == 0, ERR_NOT_STARTED, "Create render failed"); + if (isBluetoothLowLatency_) { + result = PrepareMmapBuffer(); + CHECK_AND_RETURN_RET_LOG(result == 0, ERR_NOT_STARTED, "Prepare mmap buffer failed"); + } + rendererInited_ = true; return SUCCESS; @@ -854,6 +883,66 @@ int64_t BluetoothRendererSinkInner::BytesToNanoTime(size_t lens) return res; } +int32_t BluetoothRendererSinkInner::PrepareMmapBuffer() +{ + uint32_t totalBifferInMs = 40; // 5 * (6 + 2 * (1)) = 40ms, the buffer size, not latency. + frameSizeInByte_ = PcmFormatToBits(attr_.format) * attr_.channel / PCM_8_BIT; + uint32_t reqBufferFrameSize = totalBifferInMs * (attr_.sampleRate / SECOND_TO_MILLISECOND); + + struct AudioMmapBufferDescriptor desc = {0}; + // reqBufferFrameSize means frames in total, for example, 40ms * 48K = 1920 + // transferFrameSize means frames in one block, for example 5ms per block, 5ms * 48K = 240 + int32_t ret = audioRender_->attr.ReqMmapBuffer(audioRender_, reqBufferFrameSize, &desc); + CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED, "ReqMmapBuffer failed, ret:%{public}d", ret); + AUDIO_INFO_LOG("AudioMmapBufferDescriptor memoryAddress[%{private}p] memoryFd[%{public}d] totalBufferFrames" + "[%{public}d] transferFrameSize[%{public}d] isShareable[%{public}d] offset[%{public}d]", desc.memoryAddress, + desc.memoryFd, desc.totalBufferFrames, desc.transferFrameSize, desc.isShareable, desc.offset); + + bufferFd_ = desc.memoryFd; // fcntl(fd, 1030,3) after dup? + int32_t periodFrameMaxSize = 1920000; // 192khz * 10s + CHECK_AND_RETURN_RET_LOG(desc.totalBufferFrames >= 0 && desc.transferFrameSize >= 0 && + desc.transferFrameSize <= periodFrameMaxSize, ERR_OPERATION_FAILED, + "ReqMmapBuffer invalid values: totalBufferFrames[%{public}d] transferFrameSize[%{public}d]", + desc.totalBufferFrames, desc.transferFrameSize); + bufferTotalFrameSize_ = desc.totalBufferFrames; // 1440 ~ 3840 + eachReadFrameSize_ = desc.transferFrameSize; // 240 + + CHECK_AND_RETURN_RET_LOG(frameSizeInByte_ <= ULLONG_MAX / bufferTotalFrameSize_, ERR_OPERATION_FAILED, + "BufferSize will overflow!"); + bufferSize_ = bufferTotalFrameSize_ * frameSizeInByte_; + return SUCCESS; +} + +int32_t BluetoothRendererSinkInner::GetMmapBufferInfo(int &fd, uint32_t &totalSizeInframe, uint32_t &spanSizeInframe, + uint32_t &byteSizePerFrame) +{ + CHECK_AND_RETURN_RET_LOG(bufferFd_ != INVALID_FD, ERR_INVALID_HANDLE, "buffer fd has been released!"); + fd = bufferFd_; + totalSizeInframe = bufferTotalFrameSize_; + spanSizeInframe = eachReadFrameSize_; + byteSizePerFrame = PcmFormatToBits(attr_.format) * attr_.channel / PCM_8_BIT; + return SUCCESS; +} + +int32_t BluetoothRendererSinkInner::GetMmapHandlePosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec) +{ + CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "Audio render is null!"); + + struct AudioTimeStamp timestamp = {}; + int32_t ret = audioRender_->attr.GetMmapPosition(audioRender_, &frames, ×tamp); + CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED, "Hdi GetMmapPosition filed, ret:%{public}d!", ret); + + int64_t maxSec = 9223372036; // (9223372036 + 1) * 10^9 > INT64_MAX, seconds should not bigger than it. + CHECK_AND_RETURN_RET_LOG(timestamp.tvSec >= 0 && timestamp.tvSec <= maxSec && timestamp.tvNSec >= 0 && + timestamp.tvNSec <= SECOND_TO_NANOSECOND, ERR_OPERATION_FAILED, + "Hdi GetMmapPosition get invaild second:%{public}" PRId64 " or nanosecond:%{public}" PRId64 " !", + timestamp.tvSec, timestamp.tvNSec); + timeSec = timestamp.tvSec; + timeNanoSec = timestamp.tvNSec; + + return SUCCESS; +} + void BluetoothRendererSinkInner::InitLatencyMeasurement() { if (!AudioLatencyMeasurement::CheckIfEnabled()) { diff --git a/frameworks/native/hdiadapter/sink/bluetooth/bluetooth_renderer_sink.h b/frameworks/native/hdiadapter/sink/bluetooth/bluetooth_renderer_sink.h index 17a32a0850..d4876fcba7 100644 --- a/frameworks/native/hdiadapter/sink/bluetooth/bluetooth_renderer_sink.h +++ b/frameworks/native/hdiadapter/sink/bluetooth/bluetooth_renderer_sink.h @@ -21,9 +21,10 @@ namespace OHOS { namespace AudioStandard { -class BluetoothRendererSink : public IAudioRendererSink { +class BluetoothRendererSink : public IMmapAudioRendererSink { public: static BluetoothRendererSink *GetInstance(void); + static IMmapAudioRendererSink *GetMmapInstance(void); BluetoothRendererSink() = default; ~BluetoothRendererSink() = default; diff --git a/frameworks/native/hdiadapter/sink/common/i_audio_renderer_sink.h b/frameworks/native/hdiadapter/sink/common/i_audio_renderer_sink.h index f93f7feb78..fa0b3b7ffa 100644 --- a/frameworks/native/hdiadapter/sink/common/i_audio_renderer_sink.h +++ b/frameworks/native/hdiadapter/sink/common/i_audio_renderer_sink.h @@ -33,6 +33,7 @@ typedef struct { const char *deviceNetworkId; int32_t deviceType; uint64_t channelLayout; + int32_t audioStreamFlag; } IAudioSinkAttr; class IAudioSinkCallback { diff --git a/frameworks/native/hdiadapter/sink/fast/fast_audio_renderer_sink.cpp b/frameworks/native/hdiadapter/sink/fast/fast_audio_renderer_sink.cpp index b4c808f4ca..6b630f728b 100644 --- a/frameworks/native/hdiadapter/sink/fast/fast_audio_renderer_sink.cpp +++ b/frameworks/native/hdiadapter/sink/fast/fast_audio_renderer_sink.cpp @@ -47,7 +47,6 @@ const int32_t HALF_FACTOR = 2; const uint32_t MAX_AUDIO_ADAPTER_NUM = 5; const float DEFAULT_VOLUME_LEVEL = 1.0f; const uint32_t AUDIO_CHANNELCOUNT = 2; -const uint32_t AUDIO_SAMPLE_RATE_48K = 48000; const uint32_t DEEP_BUFFER_RENDER_PERIOD_SIZE = 3840; const uint32_t INT_32_MAX = 0x7fffffff; const uint32_t PCM_8_BIT = 8; @@ -173,6 +172,13 @@ IMmapAudioRendererSink *FastAudioRendererSink::GetInstance() return &audioRenderer; } +IMmapAudioRendererSink *FastAudioRendererSink::GetVoipInstance() +{ + static FastAudioRendererSinkInner audioVoipRenderer; + + return &audioVoipRenderer; +} + std::shared_ptr FastAudioRendererSink::CreateFastRendererSink() { std::shared_ptr audioRenderer = std::make_shared(); @@ -216,10 +222,8 @@ void InitAttrs(struct AudioSampleAttributes &attrs) { /* Initialization of audio parameters for playback */ attrs.channelCount = AUDIO_CHANNELCOUNT; - attrs.sampleRate = AUDIO_SAMPLE_RATE_48K; attrs.interleaved = true; attrs.streamId = FAST_OUTPUT_STREAM_ID; - attrs.type = AUDIO_MMAP_NOIRQ; // enable mmap! attrs.period = DEEP_BUFFER_RENDER_PERIOD_SIZE; attrs.isBigEndian = false; attrs.isSignedData = true; @@ -407,6 +411,7 @@ int32_t FastAudioRendererSinkInner::CreateRender(const struct AudioPort &renderP int32_t ret; struct AudioSampleAttributes param; InitAttrs(param); + param.type = attr_.audioStreamFlag == AUDIO_FLAG_VOIP_FAST ? AUDIO_MMAP_VOIP : AUDIO_MMAP_NOIRQ; param.sampleRate = attr_.sampleRate; param.channelCount = attr_.channel; if (param.channelCount == MONO) { @@ -417,8 +422,8 @@ int32_t FastAudioRendererSinkInner::CreateRender(const struct AudioPort &renderP param.format = ConvertToHdiFormat(attr_.format); param.frameSize = PcmFormatToBits(attr_.format) * param.channelCount / PCM_8_BIT; param.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (param.frameSize); // not passed in hdi - AUDIO_INFO_LOG("FastAudioRendererSink Create render format: %{public}d and device:%{public}d", param.format, - attr_.deviceType); + AUDIO_INFO_LOG("Type: %{public}d, sampleRate: %{public}u, channel: %{public}d, format: %{public}d, " + "device:%{public}d", param.type, param.sampleRate, param.channelCount, param.format, attr_.deviceType); struct AudioDeviceDescriptor deviceDesc; deviceDesc.portId = renderPort.portId; switch (static_cast(attr_.deviceType)) { diff --git a/frameworks/native/hdiadapter/sink/fast/fast_audio_renderer_sink.h b/frameworks/native/hdiadapter/sink/fast/fast_audio_renderer_sink.h index b8aa0ce9ed..3a453699d9 100644 --- a/frameworks/native/hdiadapter/sink/fast/fast_audio_renderer_sink.h +++ b/frameworks/native/hdiadapter/sink/fast/fast_audio_renderer_sink.h @@ -23,7 +23,8 @@ namespace OHOS { namespace AudioStandard { class FastAudioRendererSink : public IMmapAudioRendererSink { public: - static IMmapAudioRendererSink *GetInstance(void); + static IMmapAudioRendererSink *GetInstance(); + static IMmapAudioRendererSink *GetVoipInstance(); static std::shared_ptr CreateFastRendererSink(void); FastAudioRendererSink() = default; ~FastAudioRendererSink() = default; diff --git a/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.h b/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.h index 470ae9bf76..6f82c3eb1b 100644 --- a/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.h +++ b/frameworks/native/hdiadapter/source/common/i_audio_capturer_source.h @@ -37,6 +37,7 @@ typedef struct { int32_t deviceType; int32_t sourceType; uint64_t channelLayout; + int32_t audioStreamFlag; } IAudioSourceAttr; class IAudioSourceCallback { diff --git a/frameworks/native/hdiadapter/source/fast/fast_audio_capturer_source.cpp b/frameworks/native/hdiadapter/source/fast/fast_audio_capturer_source.cpp index 70d8932bc8..2990850f56 100644 --- a/frameworks/native/hdiadapter/source/fast/fast_audio_capturer_source.cpp +++ b/frameworks/native/hdiadapter/source/fast/fast_audio_capturer_source.cpp @@ -131,12 +131,19 @@ FastAudioCapturerSourceInner::~FastAudioCapturerSourceInner() { AUDIO_DEBUG_LOG("~FastAudioCapturerSourceInner"); } + FastAudioCapturerSource *FastAudioCapturerSource::GetInstance() { static FastAudioCapturerSourceInner audioCapturer; return &audioCapturer; } +FastAudioCapturerSource *FastAudioCapturerSource::GetVoipInstance() +{ + static FastAudioCapturerSourceInner audioCapturer; + return &audioCapturer; +} + bool FastAudioCapturerSourceInner::IsInited(void) { return capturerInited_; @@ -164,10 +171,8 @@ void FastAudioCapturerSourceInner::InitAttrsCapture(struct AudioSampleAttributes /* Initialization of audio parameters for playback */ attrs.format = AUDIO_FORMAT_TYPE_PCM_16_BIT; attrs.channelCount = AUDIO_CHANNELCOUNT; - attrs.sampleRate = AUDIO_SAMPLE_RATE_48K; attrs.interleaved = true; attrs.streamId = FAST_INPUT_STREAM_ID; - attrs.type = AUDIO_MMAP_NOIRQ; // enable mmap! attrs.period = 0; attrs.frameSize = PCM_16_BIT * attrs.channelCount / PCM_8_BIT; attrs.isBigEndian = false; @@ -247,6 +252,7 @@ int32_t FastAudioCapturerSourceInner::CreateCapture(const struct AudioPort &capt struct AudioSampleAttributes param; // User needs to set InitAttrsCapture(param); + param.type = attr_.audioStreamFlag == AUDIO_FLAG_VOIP_FAST ? AUDIO_MMAP_VOIP : AUDIO_MMAP_NOIRQ; // enable mmap! param.sampleRate = attr_.sampleRate; param.format = ConvertToHdiFormat(attr_.format); param.isBigEndian = attr_.isBigEndian; @@ -259,7 +265,8 @@ int32_t FastAudioCapturerSourceInner::CreateCapture(const struct AudioPort &capt param.silenceThreshold = attr_.bufferSize; param.frameSize = param.format * param.channelCount; param.startThreshold = 0; - + AUDIO_INFO_LOG("Type: %{public}d, sampleRate: %{public}u, channel: %{public}d, format: %{public}d, " + "device:%{public}d", param.type, param.sampleRate, param.channelCount, param.format, attr_.deviceType); struct AudioDeviceDescriptor deviceDesc; deviceDesc.portId = capturePort.portId; char desc[] = ""; diff --git a/frameworks/native/hdiadapter/source/fast/fast_audio_capturer_source.h b/frameworks/native/hdiadapter/source/fast/fast_audio_capturer_source.h index 91e920b852..90a6c7308e 100644 --- a/frameworks/native/hdiadapter/source/fast/fast_audio_capturer_source.h +++ b/frameworks/native/hdiadapter/source/fast/fast_audio_capturer_source.h @@ -26,6 +26,7 @@ namespace AudioStandard { class FastAudioCapturerSource : public IMmapAudioCapturerSource { public: static FastAudioCapturerSource *GetInstance(); + static FastAudioCapturerSource *GetVoipInstance(); FastAudioCapturerSource() = default; virtual ~FastAudioCapturerSource() = default; }; diff --git a/frameworks/native/toneplayer/src/toneplayer.cpp b/frameworks/native/toneplayer/src/toneplayer.cpp index 709faa7ea5..3205016efb 100644 --- a/frameworks/native/toneplayer/src/toneplayer.cpp +++ b/frameworks/native/toneplayer/src/toneplayer.cpp @@ -69,7 +69,6 @@ TonePlayerPrivate::TonePlayerPrivate(const std::string cachePath, const AudioRen // streamUsage::STREAM_USAGE_MEDIA; rendererOptions.rendererInfo.streamUsage = rendereInfo.streamUsage; - rendererOptions.rendererInfo.rendererFlags = STREAM_FLAG_FORCED_NORMAL; supportedTones_ = AudioPolicyManager::GetInstance().GetSupportedTones(); volume_ = TRACK_VOLUME; toneInfo_ = NULL; diff --git a/interfaces/inner_api/native/audiocommon/include/audio_device_info.h b/interfaces/inner_api/native/audiocommon/include/audio_device_info.h index 96f0f54c32..577c63534d 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_device_info.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_device_info.h @@ -376,6 +376,7 @@ public: int32_t interruptGroupId; int32_t volumeGroupId; bool isLowLatencyDevice; + int32_t a2dpOffloadFlag; ConnectState connectState = CONNECTED; DeviceInfo() = default; @@ -394,7 +395,8 @@ public: && parcel.WriteString(displayName) && parcel.WriteInt32(interruptGroupId) && parcel.WriteInt32(volumeGroupId) - && parcel.WriteBool(isLowLatencyDevice); + && parcel.WriteBool(isLowLatencyDevice) + && parcel.WriteInt32(a2dpOffloadFlag); } bool Marshalling(Parcel &parcel, bool hasBTPermission, bool hasSystemPermission, int32_t apiVersion) const { @@ -437,7 +439,8 @@ public: && parcel.WriteString(displayName) && parcel.WriteInt32(hasSystemPermission ? interruptGroupId : INVALID_GROUP_ID) && parcel.WriteInt32(hasSystemPermission ? volumeGroupId : INVALID_GROUP_ID) - && parcel.WriteBool(isLowLatencyDevice); + && parcel.WriteBool(isLowLatencyDevice) + && parcel.WriteInt32(a2dpOffloadFlag); } void Unmarshalling(Parcel &parcel) { @@ -454,6 +457,7 @@ public: interruptGroupId = parcel.ReadInt32(); volumeGroupId = parcel.ReadInt32(); isLowLatencyDevice = parcel.ReadBool(); + a2dpOffloadFlag = parcel.ReadInt32(); } }; diff --git a/interfaces/inner_api/native/audiocommon/include/audio_info.h b/interfaces/inner_api/native/audiocommon/include/audio_info.h index 5a553037ce..8a4a39a27e 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_info.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_info.h @@ -45,7 +45,12 @@ constexpr int32_t INTELL_VOICE_SERVICR_UID = 1042; constexpr int32_t NETWORK_ID_SIZE = 80; constexpr int32_t DEFAULT_VOLUME_GROUP_ID = 1; constexpr int32_t DEFAULT_VOLUME_INTERRUPT_ID = 1; -constexpr uint32_t STREAM_FLAG_FORCED_NORMAL = 2; +constexpr int32_t AUDIO_FLAG_INVALID = -1; +constexpr int32_t AUDIO_FLAG_NORMAL = 0; +constexpr int32_t AUDIO_FLAG_MMAP = 1; +constexpr int32_t AUDIO_FLAG_VOIP_FAST = 2; +constexpr int32_t AUDIO_USAGE_NORMAL = 0; +constexpr int32_t AUDIO_USAGE_VOIP = 1; constexpr uint32_t STREAM_FLAG_FAST = 1; constexpr uint32_t STREAM_FLAG_NORMAL = 0; constexpr float MAX_STREAM_SPEED_LEVEL = 4.0f; diff --git a/services/audio_policy/BUILD.gn b/services/audio_policy/BUILD.gn index 3a95c1b0ad..e88a4158de 100644 --- a/services/audio_policy/BUILD.gn +++ b/services/audio_policy/BUILD.gn @@ -151,6 +151,7 @@ ohos_shared_library("audio_policy_service") { "server/src/service/audio_device_manager.cpp", "server/src/service/audio_policy_service.cpp", "server/src/service/audio_state_manager.cpp", + "server/src/service/config/audio_adapter_info.cpp", "server/src/service/config/audio_converter_parser.cpp", "server/src/service/config/audio_device_parser.cpp", "server/src/service/config/audio_focus_parser.cpp", diff --git a/services/audio_policy/client/include/audio_policy_base.h b/services/audio_policy/client/include/audio_policy_base.h index 263e99ccdf..61c4be723a 100644 --- a/services/audio_policy/client/include/audio_policy_base.h +++ b/services/audio_policy/client/include/audio_policy_base.h @@ -125,6 +125,10 @@ public: virtual uint32_t GetSinkLatencyFromXml() = 0; + virtual int32_t GetPreferredOutputStreamType(AudioRendererInfo &rendererInfo) = 0; + + virtual int32_t GetPreferredInputStreamType(AudioCapturerInfo &capturerInfo) = 0; + virtual int32_t RegisterTracker(AudioMode &mode, AudioStreamChangeInfo &streamChangeInfo, const sptr &object) = 0; diff --git a/services/audio_policy/client/include/audio_policy_manager_stub.h b/services/audio_policy/client/include/audio_policy_manager_stub.h index c0be4ca8bb..cc558159b2 100644 --- a/services/audio_policy/client/include/audio_policy_manager_stub.h +++ b/services/audio_policy/client/include/audio_policy_manager_stub.h @@ -63,6 +63,8 @@ private: void ReconfigureAudioChannelInternal(MessageParcel &data, MessageParcel &reply); void GetAudioLatencyFromXmlInternal(MessageParcel &data, MessageParcel &reply); void GetSinkLatencyFromXmlInternal(MessageParcel &data, MessageParcel &reply); + void GetPerferredOutputStreamTypeInternal(MessageParcel &data, MessageParcel &reply); + void GetPerferredInputStreamTypeInternal(MessageParcel &data, MessageParcel &reply); void RegisterTrackerInternal(MessageParcel &data, MessageParcel &reply); void UpdateTrackerInternal(MessageParcel &data, MessageParcel &reply); void GetRendererChangeInfosInternal(MessageParcel &data, MessageParcel &reply); @@ -185,6 +187,8 @@ private: &AudioPolicyManagerStub::ReconfigureAudioChannelInternal, &AudioPolicyManagerStub::GetAudioLatencyFromXmlInternal, &AudioPolicyManagerStub::GetSinkLatencyFromXmlInternal, + &AudioPolicyManagerStub::GetPerferredOutputStreamTypeInternal, + &AudioPolicyManagerStub::GetPerferredInputStreamTypeInternal, &AudioPolicyManagerStub::RegisterTrackerInternal, &AudioPolicyManagerStub::UpdateTrackerInternal, &AudioPolicyManagerStub::GetRendererChangeInfosInternal, diff --git a/services/audio_policy/client/include/audio_policy_proxy.h b/services/audio_policy/client/include/audio_policy_proxy.h index e51ed2390d..4ae26f800a 100644 --- a/services/audio_policy/client/include/audio_policy_proxy.h +++ b/services/audio_policy/client/include/audio_policy_proxy.h @@ -131,6 +131,10 @@ public: uint32_t GetSinkLatencyFromXml() override; + int32_t GetPreferredOutputStreamType(AudioRendererInfo &rendererInfo) override; + + int32_t GetPreferredInputStreamType(AudioCapturerInfo &capturerInfo) override; + int32_t RegisterTracker(AudioMode &mode, AudioStreamChangeInfo &streamChangeInfo, const sptr &object) override; diff --git a/services/audio_policy/client/src/audio_policy_manager.cpp b/services/audio_policy/client/src/audio_policy_manager.cpp index f95677bb5b..2734fdda71 100644 --- a/services/audio_policy/client/src/audio_policy_manager.cpp +++ b/services/audio_policy/client/src/audio_policy_manager.cpp @@ -888,6 +888,20 @@ uint32_t AudioPolicyManager::GetSinkLatencyFromXml() return gsp->GetSinkLatencyFromXml(); } +int32_t AudioPolicyManager::GetPreferredOutputStreamType(AudioRendererInfo &rendererInfo) +{ + const sptr gsp = GetAudioPolicyManagerProxy(); + CHECK_AND_RETURN_RET_LOG(gsp != nullptr, AUDIO_FLAG_INVALID, "audio policy manager proxy is NULL."); + return gsp->GetPreferredOutputStreamType(rendererInfo); +} + +int32_t AudioPolicyManager::GetPreferredInputStreamType(AudioCapturerInfo &capturerInfo) +{ + const sptr gsp = GetAudioPolicyManagerProxy(); + CHECK_AND_RETURN_RET_LOG(gsp != nullptr, AUDIO_FLAG_INVALID, "audio policy manager proxy is NULL."); + return gsp->GetPreferredInputStreamType(capturerInfo); +} + int32_t AudioPolicyManager::GetCurrentRendererChangeInfos( vector> &audioRendererChangeInfos) { diff --git a/services/audio_policy/client/src/audio_policy_proxy.cpp b/services/audio_policy/client/src/audio_policy_proxy.cpp index ce4bbac88a..6dcf96106d 100644 --- a/services/audio_policy/client/src/audio_policy_proxy.cpp +++ b/services/audio_policy/client/src/audio_policy_proxy.cpp @@ -937,6 +937,44 @@ uint32_t AudioPolicyProxy::GetSinkLatencyFromXml() return reply.ReadUint32(); } +int32_t AudioPolicyProxy::GetPreferredOutputStreamType(AudioRendererInfo &rendererInfo) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + bool ret = data.WriteInterfaceToken(GetDescriptor()); + CHECK_AND_RETURN_RET_LOG(ret, AUDIO_FLAG_INVALID, "WriteInterfaceToken failed"); + + ret = rendererInfo.Marshalling(data); + CHECK_AND_RETURN_RET_LOG(ret, AUDIO_FLAG_INVALID, "Marshalling rendererInfo failed"); + + int32_t error = Remote()->SendRequest( + static_cast(AudioPolicyInterfaceCode::GET_PREFERRED_OUTPUT_STREAM_TYPE), data, reply, option); + CHECK_AND_RETURN_RET_LOG(error == ERR_NONE, AUDIO_FLAG_INVALID, "Failed to send request, error: %{public}d", error); + + return reply.ReadInt32(); +} + +int32_t AudioPolicyProxy::GetPreferredInputStreamType(AudioCapturerInfo &capturerInfo) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + bool ret = data.WriteInterfaceToken(GetDescriptor()); + CHECK_AND_RETURN_RET_LOG(ret, AUDIO_FLAG_INVALID, "WriteInterfaceToken failed"); + + ret = capturerInfo.Marshalling(data); + CHECK_AND_RETURN_RET_LOG(ret, AUDIO_FLAG_INVALID, "Marshalling capturerInfo failed"); + + int32_t error = Remote()->SendRequest( + static_cast(AudioPolicyInterfaceCode::GET_PREFERRED_INPUT_STREAM_TYPE), data, reply, option); + CHECK_AND_RETURN_RET_LOG(error == ERR_NONE, AUDIO_FLAG_INVALID, "Failed to send request, error: %{public}d", error); + + return reply.ReadInt32(); +} + int32_t AudioPolicyProxy::RegisterTracker(AudioMode &mode, AudioStreamChangeInfo &streamChangeInfo, const sptr &object) { diff --git a/services/audio_policy/common/include/audio_policy_ipc_interface_code.h b/services/audio_policy/common/include/audio_policy_ipc_interface_code.h index c0bcd4639e..531cf8882b 100644 --- a/services/audio_policy/common/include/audio_policy_ipc_interface_code.h +++ b/services/audio_policy/common/include/audio_policy_ipc_interface_code.h @@ -57,6 +57,8 @@ enum class AudioPolicyInterfaceCode { RECONFIGURE_CHANNEL, GET_AUDIO_LATENCY, GET_SINK_LATENCY, + GET_PREFERRED_OUTPUT_STREAM_TYPE, + GET_PREFERRED_INPUT_STREAM_TYPE, REGISTER_TRACKER, UPDATE_TRACKER, GET_RENDERER_CHANGE_INFOS, diff --git a/services/audio_policy/server/include/audio_policy_server.h b/services/audio_policy/server/include/audio_policy_server.h index 19aa548641..d8bdf871e0 100644 --- a/services/audio_policy/server/include/audio_policy_server.h +++ b/services/audio_policy/server/include/audio_policy_server.h @@ -212,6 +212,10 @@ public: uint32_t GetSinkLatencyFromXml() override; + int32_t GetPreferredOutputStreamType(AudioRendererInfo &rendererInfo) override; + + int32_t GetPreferredInputStreamType(AudioCapturerInfo &capturerInfo) override; + int32_t RegisterTracker(AudioMode &mode, AudioStreamChangeInfo &streamChangeInfo, const sptr &object) override; diff --git a/services/audio_policy/server/include/audio_service_dump.h b/services/audio_policy/server/include/audio_service_dump.h index 38f0534057..7ed5dd0fd4 100644 --- a/services/audio_policy/server/include/audio_service_dump.h +++ b/services/audio_policy/server/include/audio_service_dump.h @@ -100,7 +100,7 @@ typedef struct { StreamVolumeInfoMap streamVolumeInfos; std::vector> availableMicrophones; std::unordered_map> audioInterruptZonesMapDump; - std::map adapterInfoMap; + std::unordered_map adapterInfoMap; std::unordered_map volumeGroupData; std::unordered_map interruptGroupData; std::unordered_map> deviceClassInfo; diff --git a/services/audio_policy/server/include/service/audio_policy_service.h b/services/audio_policy/server/include/service/audio_policy_service.h index 213a680526..01a7f76aec 100644 --- a/services/audio_policy/server/include/service/audio_policy_service.h +++ b/services/audio_policy/server/include/service/audio_policy_service.h @@ -160,13 +160,17 @@ public: uint32_t GetSinkLatencyFromXml() const; + int32_t GetPreferredOutputStreamType(AudioRendererInfo &rendererInfo); + + int32_t GetPreferredInputStreamType(AudioCapturerInfo &capturerInfo); + int32_t SetSystemSoundUri(const std::string &key, const std::string &uri); std::string GetSystemSoundUri(const std::string &key); bool IsSessionIdValid(int32_t callerUid, int32_t sessionId); - void GetAudioAdapterInfos(std::map &adapterInfoMap); + void GetAudioAdapterInfos(std::unordered_map &adapterInfoMap); void GetVolumeGroupData(std::unordered_map& volumeGroupData); @@ -177,7 +181,7 @@ public: void GetGlobalConfigs(GlobalConfigs &globalConfigs); // Audio Policy Parser callbacks - void OnAudioPolicyXmlParsingCompleted(const std::map adapterInfoMap); + void OnAudioPolicyXmlParsingCompleted(const std::unordered_map adapterInfoMap); // Parser callbacks void OnXmlParsingCompleted(const std::unordered_map> &xmldata); @@ -717,6 +721,12 @@ private: void ClearScoDeviceSuspendState(string macAddress = ""); + PipeInfo& GetPipeInfoByPipeName(std::string &supportPipe, AudioAdapterInfo &adapterInfo); + + int32_t CheckDeviceCapability(AudioAdapterInfo &adapterInfo, int32_t flag, DeviceType deviceType); + + bool IsConfigInfoHasAttribute(std::list &configInfos, std::string value); + AudioIOHandle OpenPortAndInsertIOHandle(const std::string &moduleName, const AudioModuleInfo &moduleInfo); int32_t ClosePortAndEraseIOHandle(const std::string &moduleName); @@ -796,7 +806,7 @@ private: AudioScene audioScene_ = AUDIO_SCENE_DEFAULT; std::unordered_map> deviceClassInfo_ = {}; - std::map adapterInfoMap_ {}; + std::unordered_map adapterInfoMap_ {}; std::mutex ioHandlesMutex_; std::unordered_map IOHandles_ = {}; diff --git a/services/audio_policy/server/include/service/common/audio_adapter_info.h b/services/audio_policy/server/include/service/common/audio_adapter_info.h index b0dd13fc85..76956e84c8 100644 --- a/services/audio_policy/server/include/service/common/audio_adapter_info.h +++ b/services/audio_policy/server/include/service/common/audio_adapter_info.h @@ -186,6 +186,9 @@ public: std::string fixedLatency_ = STR_INIT; std::string renderInIdleState_ = STR_INIT; + int32_t audioFlag_ = AUDIO_FLAG_NORMAL; + int32_t audioUsage_ = AUDIO_USAGE_NORMAL; + std::list streamPropInfos_ {}; std::list sampleRates_ {}; std::list channelLayouts_ {}; @@ -229,6 +232,9 @@ public: AudioAdapterInfo() = default; virtual ~AudioAdapterInfo() = default; + PipeInfo *GetPipeByName(std::string &pipeName); + AudioPipeDeviceInfo *GetDeviceInfoByDeviceType(DeviceType deviceType); + std::string adapterName_ = STR_INIT; std::string adaptersupportScene_ = STR_INIT; std::list deviceInfos_ {}; diff --git a/services/audio_policy/server/include/service/config/audio_policy_parser.h b/services/audio_policy/server/include/service/config/audio_policy_parser.h index 4778850198..75d568e8e7 100644 --- a/services/audio_policy/server/include/service/config/audio_policy_parser.h +++ b/services/audio_policy/server/include/service/config/audio_policy_parser.h @@ -66,6 +66,7 @@ private: void ParsePipeInfos(xmlNode &node, PipeInfo &pipeInfo); void ParseStreamProps(xmlNode &node, PipeInfo &pipeInfo); void ParseConfigs(xmlNode &node, PipeInfo &pipeInfo); + void HandleConfigFlagAndUsage(ConfigInfo &configInfo, PipeInfo &pipeInfo); void ParseDevices(xmlNode &node, AudioAdapterInfo &adapterInfo); void ParseGroups(xmlNode& node, XmlNodeType type); void ParseGroup(xmlNode& node, XmlNodeType type); @@ -97,7 +98,7 @@ private: IPortObserver &portObserver_; xmlDoc *doc_; - std::map adapterInfoMap_ {}; + std::unordered_map adapterInfoMap_ {}; std::unordered_map> xmlParsedDataMap_ {}; std::unordered_map volumeGroupMap_; std::unordered_map interruptGroupMap_; diff --git a/services/audio_policy/server/include/service/interface/iport_observer.h b/services/audio_policy/server/include/service/interface/iport_observer.h index 0dc0678a6c..e4c901f114 100644 --- a/services/audio_policy/server/include/service/interface/iport_observer.h +++ b/services/audio_policy/server/include/service/interface/iport_observer.h @@ -23,7 +23,7 @@ namespace OHOS { namespace AudioStandard { class IPortObserver { public: - virtual void OnAudioPolicyXmlParsingCompleted(const std::map + virtual void OnAudioPolicyXmlParsingCompleted(const std::unordered_map adapterInfoMap) = 0; virtual void OnXmlParsingCompleted(const std::unordered_map> &xmldata) = 0; virtual void OnUpdateRouteSupport(bool isSupported) = 0; 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 77927416af..a4819c18ec 100644 --- a/services/audio_policy/server/src/audio_policy_manager_stub.cpp +++ b/services/audio_policy/server/src/audio_policy_manager_stub.cpp @@ -491,6 +491,22 @@ void AudioPolicyManagerStub::GetSinkLatencyFromXmlInternal(MessageParcel &data, reply.WriteUint32(ret); } +void AudioPolicyManagerStub::GetPerferredOutputStreamTypeInternal(MessageParcel &data, MessageParcel &reply) +{ + AudioRendererInfo rendererInfo; + rendererInfo.Unmarshalling(data); + int32_t result = GetPreferredOutputStreamType(rendererInfo); + reply.WriteInt32(result); +} + +void AudioPolicyManagerStub::GetPerferredInputStreamTypeInternal(MessageParcel &data, MessageParcel &reply) +{ + AudioCapturerInfo capturerInfo; + capturerInfo.Unmarshalling(data); + int32_t result = GetPreferredInputStreamType(capturerInfo); + reply.WriteInt32(result); +} + void AudioPolicyManagerStub::ReconfigureAudioChannelInternal(MessageParcel &data, MessageParcel &reply) { uint32_t count = data.ReadUint32(); diff --git a/services/audio_policy/server/src/audio_policy_server.cpp b/services/audio_policy/server/src/audio_policy_server.cpp index ebe9c5398f..4fed6cb050 100644 --- a/services/audio_policy/server/src/audio_policy_server.cpp +++ b/services/audio_policy/server/src/audio_policy_server.cpp @@ -1436,6 +1436,16 @@ uint32_t AudioPolicyServer::GetSinkLatencyFromXml() return audioPolicyService_.GetSinkLatencyFromXml(); } +int32_t AudioPolicyServer::GetPreferredOutputStreamType(AudioRendererInfo &rendererInfo) +{ + return audioPolicyService_.GetPreferredOutputStreamType(rendererInfo); +} + +int32_t AudioPolicyServer::GetPreferredInputStreamType(AudioCapturerInfo &capturerInfo) +{ + return audioPolicyService_.GetPreferredInputStreamType(capturerInfo); +} + int32_t AudioPolicyServer::RegisterTracker(AudioMode &mode, AudioStreamChangeInfo &streamChangeInfo, const sptr &object) { 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 9207322435..c4c0e468b1 100644 --- a/services/audio_policy/server/src/service/audio_policy_service.cpp +++ b/services/audio_policy/server/src/service/audio_policy_service.cpp @@ -49,7 +49,22 @@ using namespace std; static const std::string INNER_CAPTURER_SINK_LEGACY = "InnerCapturer"; static const std::string RECEIVER_SINK_NAME = "Receiver"; static const std::string SINK_NAME_FOR_CAPTURE_SUFFIX = "_CAP"; -static const std::string EARPIECE_TYPE_NAME = "DEVICE_TYPE_EARPIECE"; +static const std::string PIPE_PRIMARY_OUTPUT = "primary_output"; +static const std::string PIPE_FAST_OUTPUT = "fast_output"; +static const std::string PIPE_OFFLOAD_OUTPUT = "offload_output"; +static const std::string PIPE_VOIP_OUTPUT = "voip_output"; +static const std::string PIPE_PRIMARY_INPUT = "primary_input"; +static const std::string PIPE_FAST_INPUT = "fast_input"; +static const std::string PIPE_OFFLOAD_INPUT = "offload_input"; +static const std::string PIPE_VOIP_INPUT = "voip_input"; +static const std::string PIPE_A2DP_OUTPUT = "a2dp_output"; +static const std::string PIPE_FAST_A2DP_OUTPUT = "fast_a2dp_output"; +static const std::string PIPE_USB_ARM_OUTPUT = "usb_arm_output"; +static const std::string PIPE_USB_ARM_INPUT = "usb_arm_input"; +static const std::string PIPE_DISTRIBUTED_OUTPUT = "distributed_output"; +static const std::string PIPE_FAST_DISTRIBUTED_OUTPUT = "fast_distributed_output"; +static const std::string PIPE_DISTRIBUTED_INPUT = "distributed_input"; +static const std::string PIPE_FAST_DISTRIBUTED_INPUT = "fast_distributed_input"; static const std::vector VOLUME_TYPE_LIST = { STREAM_VOICE_CALL, @@ -86,6 +101,9 @@ static const std::string SETTINGS_DATA_EXT_URI = "datashare:///com.ohos.settings static const std::string SETTINGS_DATA_FIELD_KEYWORD = "KEYWORD"; static const std::string SETTINGS_DATA_FIELD_VALUE = "VALUE"; static const std::string PREDICATES_STRING = "settings.general.device_name"; +static const std::string EARPIECE_TYPE_NAME = "Earpiece_Out"; +static const std::string FLAG_MMAP_STRING = "AUDIO_FLAG_MMAP"; +static const std::string USAGE_VOIP_STRING = "AUDIO_USAGE_VOIP"; const uint32_t PCM_8_BIT = 8; const uint32_t PCM_16_BIT = 16; const uint32_t PCM_24_BIT = 24; @@ -3810,7 +3828,7 @@ void AudioPolicyService::AddAudioDevice(AudioModuleInfo& moduleInfo, InternalDev } void AudioPolicyService::OnAudioPolicyXmlParsingCompleted( - const std::map adapterInfoMap) + const std::unordered_map adapterInfoMap) { AUDIO_INFO_LOG("adapterInfo num [%{public}zu]", adapterInfoMap.size()); CHECK_AND_RETURN_LOG(!adapterInfoMap.empty(), "failed to parse audiopolicy xml file. Received data is empty"); @@ -3861,7 +3879,7 @@ void AudioPolicyService::OnGlobalConfigsParsed(GlobalConfigs &globalConfigs) globalConfigs_ = globalConfigs; } -void AudioPolicyService::GetAudioAdapterInfos(std::map &adapterInfoMap) +void AudioPolicyService::GetAudioAdapterInfos(std::unordered_map &adapterInfoMap) { adapterInfoMap = adapterInfoMap_; } @@ -4769,6 +4787,81 @@ uint32_t AudioPolicyService::GetSinkLatencyFromXml() const return sinkLatencyInMsec_; } +int32_t AudioPolicyService::GetPreferredOutputStreamType(AudioRendererInfo &rendererInfo) +{ + // Use GetPreferredOutputDeviceDescriptors instead of currentActiveDevice, if prefer != current, recreate stream + std::vector> preferredDeviceList = GetPreferredOutputDeviceDescriptors(rendererInfo); + if (preferredDeviceList.size() == 0) { + return AUDIO_FLAG_INVALID; + } + std::string sinkPortName = GetSinkPortName(preferredDeviceList[0]->deviceType_); + if (adapterInfoMap_.find(static_cast(classStrToEnum[sinkPortName])) == adapterInfoMap_.end()) { + return AUDIO_FLAG_INVALID; + } + AudioAdapterInfo adapterInfo; + auto it = adapterInfoMap_.find(static_cast(classStrToEnum[sinkPortName])); + if (it != adapterInfoMap_.end()) { + adapterInfo = it->second; + } else { + AUDIO_ERR_LOG("Invalid adapter"); + return AUDIO_FLAG_INVALID; + } + + AudioPipeDeviceInfo* deviceInfo = adapterInfo.GetDeviceInfoByDeviceType(preferredDeviceList[0]->deviceType_); + CHECK_AND_RETURN_RET_LOG(deviceInfo != nullptr, AUDIO_FLAG_INVALID, "Device type is not supported"); + for (auto &supportPipe : deviceInfo->supportPipes_) { + PipeInfo* pipeInfo = adapterInfo.GetPipeByName(supportPipe); + if (pipeInfo == nullptr) { + continue; + } + if (rendererInfo.rendererFlags == AUDIO_FLAG_MMAP && pipeInfo->audioFlag_ == AUDIO_FLAG_MMAP) { + return AUDIO_FLAG_MMAP; + } + if (rendererInfo.rendererFlags == AUDIO_FLAG_VOIP_FAST && pipeInfo->audioUsage_ == AUDIO_USAGE_VOIP && + pipeInfo->audioFlag_ == AUDIO_FLAG_MMAP) { + return AUDIO_FLAG_VOIP_FAST; + } + } + return AUDIO_FLAG_NORMAL; +} + +int32_t AudioPolicyService::GetPreferredInputStreamType(AudioCapturerInfo &capturerInfo) +{ + // Use GetPreferredInputDeviceDescriptors instead of currentActiveDevice, if prefer != current, recreate stream + std::vector> preferredDeviceList = GetPreferredInputDeviceDescriptors(capturerInfo); + if (preferredDeviceList.size() == 0) { + return AUDIO_FLAG_INVALID; + } + std::string sourcePortName = GetSourcePortName(preferredDeviceList[0]->deviceType_); + if (adapterInfoMap_.find(static_cast(classStrToEnum[sourcePortName])) == adapterInfoMap_.end()) { + return AUDIO_FLAG_INVALID; + } + AudioAdapterInfo adapterInfo; + auto it = adapterInfoMap_.find(static_cast(classStrToEnum[sourcePortName])); + if (it != adapterInfoMap_.end()) { + adapterInfo = it->second; + } else { + AUDIO_ERR_LOG("Invalid adapter"); + return AUDIO_FLAG_INVALID; + } + AudioPipeDeviceInfo* deviceInfo = adapterInfo.GetDeviceInfoByDeviceType(preferredDeviceList[0]->deviceType_); + CHECK_AND_RETURN_RET_LOG(deviceInfo != nullptr, AUDIO_FLAG_INVALID, "Device type is not supported"); + for (auto &supportPipe : deviceInfo->supportPipes_) { + PipeInfo* pipeInfo = adapterInfo.GetPipeByName(supportPipe); + if (pipeInfo == nullptr) { + continue; + } + if (capturerInfo.capturerFlags == AUDIO_FLAG_MMAP && pipeInfo->audioFlag_ == AUDIO_FLAG_MMAP) { + return AUDIO_FLAG_MMAP; + } + if (capturerInfo.capturerFlags == AUDIO_FLAG_VOIP_FAST && pipeInfo->audioUsage_ == AUDIO_USAGE_VOIP && + pipeInfo->audioFlag_ == AUDIO_FLAG_MMAP) { + return AUDIO_FLAG_VOIP_FAST; + } + } + return AUDIO_FLAG_NORMAL; +} + void AudioPolicyService::UpdateInputDeviceInfo(DeviceType deviceType) { AUDIO_DEBUG_LOG("Current input device is %{public}d", currentActiveInputDevice_.deviceType_); @@ -4910,6 +5003,7 @@ int32_t AudioPolicyService::GetProcessDeviceInfo(const AudioProcessConfig &confi deviceInfo.networkId = fastRouterMap_[config.appInfo.appUid].first; AUDIO_INFO_LOG("use networkid in fastRouterMap_ :%{public}s ", deviceInfo.networkId.c_str()); } + deviceInfo.a2dpOffloadFlag = a2dpOffloadFlag_; return SUCCESS; } diff --git a/services/audio_policy/server/src/service/config/audio_adapter_info.cpp b/services/audio_policy/server/src/service/config/audio_adapter_info.cpp new file mode 100644 index 0000000000..5008f8c31e --- /dev/null +++ b/services/audio_policy/server/src/service/config/audio_adapter_info.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#undef LOG_TAG +#define LOG_TAG "AudioAdapterInfo" + +#include "audio_adapter_info.h" +#include "audio_effect.h" +#include "audio_log.h" + +namespace OHOS { +namespace AudioStandard { +PipeInfo* AudioAdapterInfo::GetPipeByName(std::string &pipeName) +{ + for (auto &pipeInfo : pipeInfos_) { + if (pipeInfo.name_ == pipeName) { + return &pipeInfo; + } + } + return nullptr; +} + +AudioPipeDeviceInfo* AudioAdapterInfo::GetDeviceInfoByDeviceType(DeviceType deviceType) +{ + for (auto &deviceInfo : deviceInfos_) { + auto device = SUPPORTED_DEVICE_TYPE.find(deviceType); + if (device != SUPPORTED_DEVICE_TYPE.end()) { + return &deviceInfo; + } + } + return nullptr; +} +} // namespace AudioStandard +} // namespace OHOS diff --git a/services/audio_policy/server/src/service/config/audio_policy_parser.cpp b/services/audio_policy/server/src/service/config/audio_policy_parser.cpp index 51d89beda0..eb17ae7e3d 100644 --- a/services/audio_policy/server/src/service/config/audio_policy_parser.cpp +++ b/services/audio_policy/server/src/service/config/audio_policy_parser.cpp @@ -45,6 +45,16 @@ static std::map formatStrToEnum = { {"s32le", S32LE_TO_BYTE}, }; +static std::map audioFlagStrToEnum = { + {"AUDIO_FLAG_NORMAL", AUDIO_FLAG_NORMAL}, + {"AUDIO_FLAG_MMAP", AUDIO_FLAG_MMAP}, +}; + +static std::map audioUsageStrToEnum = { + {"AUDIO_USAGE_NORMAL", AUDIO_USAGE_NORMAL}, + {"AUDIO_USAGE_VOIP", AUDIO_USAGE_VOIP}, +}; + bool AudioPolicyParser::LoadConfiguration() { doc_ = xmlReadFile(CHIP_PROD_CONFIG_FILE, nullptr, 0); @@ -450,12 +460,28 @@ void AudioPolicyParser::ParseConfigs(xmlNode &node, PipeInfo &pipeInfo) configInfo.name_ = ExtractPropertyValue("name", *configNode); configInfo.value_ = ExtractPropertyValue("value", *configNode); configInfos.push_back(configInfo); + HandleConfigFlagAndUsage(configInfo, pipeInfo); } configNode = configNode->next; } pipeInfo.configInfos_ = configInfos; } +void AudioPolicyParser::HandleConfigFlagAndUsage(ConfigInfo &configInfo, PipeInfo &pipeInfo) +{ + if (configInfo.name_ == "flag") { + auto it = audioFlagStrToEnum.find(configInfo.value_); + if (it != audioFlagStrToEnum.end()) { + pipeInfo.audioFlag_ = it->second; + } + } else if (configInfo.name_ == "usage") { + auto it = audioUsageStrToEnum.find(configInfo.value_); + if (it != audioUsageStrToEnum.end()) { + pipeInfo.audioUsage_ = it->second; + } + } +} + void AudioPolicyParser::ParseDevices(xmlNode &node, AudioAdapterInfo &adapterInfo) { xmlNode *currNode = nullptr; diff --git a/services/audio_service/BUILD.gn b/services/audio_service/BUILD.gn index cd979aa35c..ab74e1ad75 100644 --- a/services/audio_service/BUILD.gn +++ b/services/audio_service/BUILD.gn @@ -299,6 +299,7 @@ ohos_shared_library("audio_process_service") { "../../frameworks/native/audioeffect:audio_effect", "../../frameworks/native/audioschedule:audio_schedule", "../../frameworks/native/audioutils:audio_utils", + "../../frameworks/native/hdiadapter/sink:bluetooth_renderer_sink", "../../frameworks/native/hdiadapter/sink:fast_audio_renderer_sink", "../../frameworks/native/hdiadapter/sink:remote_audio_renderer_sink", "../../frameworks/native/hdiadapter/sink:remote_fast_audio_renderer_sink", 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 d7871a3d35..bb9ad31077 100644 --- a/services/audio_service/client/src/audio_process_in_client.cpp +++ b/services/audio_service/client/src/audio_process_in_client.cpp @@ -149,6 +149,7 @@ private: int32_t ProcessData(const BufferDesc &srcDesc, const BufferDesc &dstDesc) const; private: + static constexpr int64_t MILLISECOND_PER_SECOND = 1000; // 1000ms static constexpr int64_t ONE_MILLISECOND_DURATION = 1000000; // 1ms static constexpr int64_t THREE_MILLISECOND_DURATION = 3000000; // 3ms static constexpr int64_t MAX_WRITE_COST_DURATION_NANO = 5000000; // 5ms @@ -176,6 +177,7 @@ private: uint32_t totalSizeInFrame_ = 0; uint32_t spanSizeInFrame_ = 0; uint32_t byteSizePerFrame_ = 0; + uint32_t spanSizeInMs_ = 0; size_t spanSizeInByte_ = 0; std::weak_ptr audioDataCallback_; std::weak_ptr underrunCallback_; @@ -479,16 +481,20 @@ bool AudioProcessInClientInner::InitAudioBuffer() audioBuffer_->GetSizeParameter(totalSizeInFrame_, spanSizeInFrame_, byteSizePerFrame_); spanSizeInByte_ = spanSizeInFrame_ * byteSizePerFrame_; + spanSizeInMs_ = spanSizeInFrame_ * MILLISECOND_PER_SECOND / processConfig_.streamInfo.samplingRate; if (processConfig_.audioMode == AUDIO_MODE_PLAYBACK && clientByteSizePerFrame_ != 0) { clientSpanSizeInByte_ = spanSizeInFrame_ * clientByteSizePerFrame_; + if (clientSpanSizeInFrame_ != spanSizeInFrame_) { + clientSpanSizeInFrame_ = spanSizeInFrame_; + } } else { clientSpanSizeInByte_ = spanSizeInByte_; } AUDIO_INFO_LOG("Using totalSizeInFrame_ %{public}d spanSizeInFrame_ %{public}d byteSizePerFrame_ %{public}d " - "spanSizeInByte_ %{public}zu", totalSizeInFrame_, spanSizeInFrame_, - byteSizePerFrame_, spanSizeInByte_); + "spanSizeInByte_ %{public}zu, spanSizeInMs_ %{public}u", totalSizeInFrame_, spanSizeInFrame_, + byteSizePerFrame_, spanSizeInByte_, spanSizeInMs_); callbackBuffer_ = std::make_unique(clientSpanSizeInByte_); CHECK_AND_RETURN_RET_LOG(callbackBuffer_ != nullptr, false, "Init callbackBuffer_ failed."); @@ -1242,12 +1248,12 @@ void AudioProcessInClientInner::RecordProcessCallbackFuc() threadStatus_ = SLEEPING; curTime = ClockTime::GetCurNano(); - if (wakeUpTime > curTime && wakeUpTime - curTime < MAX_READ_COST_DURATION_NANO + clientReadCost) { + if (wakeUpTime > curTime && wakeUpTime - curTime < spanSizeInMs_ * ONE_MILLISECOND_DURATION + clientReadCost) { ClockTime::AbsoluteSleep(wakeUpTime); } else { Trace trace("RecordBigWakeUpTime"); AUDIO_WARNING_LOG("%{public}s wakeUpTime is too late...", __func__); - ClockTime::RelativeSleep(MAX_READ_COST_DURATION_NANO); + ClockTime::RelativeSleep(spanSizeInMs_ * ONE_MILLISECOND_DURATION); } } } @@ -1452,7 +1458,7 @@ void AudioProcessInClientInner::ProcessCallbackFuc() // start safe sleep threadStatus_ = SLEEPING; curTime = ClockTime::GetCurNano(); - if (wakeUpTime - curTime > MAX_WRITE_COST_DURATION_NANO + clientWriteCost) { + if (wakeUpTime - curTime > spanSizeInMs_ * ONE_MILLISECOND_DURATION + clientWriteCost) { Trace trace("BigWakeUpTime curTime[" + std::to_string(curTime) + "] target[" + std::to_string(wakeUpTime) + "] delay " + std::to_string(wakeUpTime - curTime) + "ns"); AUDIO_WARNING_LOG("wakeUpTime is too late..."); diff --git a/services/audio_service/client/src/fast_audio_stream.cpp b/services/audio_service/client/src/fast_audio_stream.cpp index 2b5f063637..2baa1dfe4b 100644 --- a/services/audio_service/client/src/fast_audio_stream.cpp +++ b/services/audio_service/client/src/fast_audio_stream.cpp @@ -37,7 +37,7 @@ FastAudioStream::FastAudioStream(AudioStreamType eStreamType, AudioMode eMode, i captureMode_(CAPTURE_MODE_CALLBACK) { AUDIO_INFO_LOG("FastAudioStream ctor, appUID = %{public}d", appUid); - audioStreamTracker_ = std::make_unique(eMode, appUid); + audioStreamTracker_ = std::make_unique(eMode, appUid); AUDIO_DEBUG_LOG("AudioStreamTracker created"); } diff --git a/services/audio_service/client/src/i_audio_stream.cpp b/services/audio_service/client/src/i_audio_stream.cpp index 16ad2470c1..afc9efc289 100644 --- a/services/audio_service/client/src/i_audio_stream.cpp +++ b/services/audio_service/client/src/i_audio_stream.cpp @@ -178,6 +178,7 @@ bool IAudioStream::IsStreamSupported(int32_t streamFlags, const AudioStreamParam auto rateItem = std::find(AUDIO_FAST_STREAM_SUPPORTED_SAMPLING_RATES.begin(), AUDIO_FAST_STREAM_SUPPORTED_SAMPLING_RATES.end(), samplingRate); if (rateItem == AUDIO_FAST_STREAM_SUPPORTED_SAMPLING_RATES.end()) { + AUDIO_WARNING_LOG("Sampling rate %{public}d does not meet the requirements", samplingRate); return false; } @@ -186,6 +187,7 @@ bool IAudioStream::IsStreamSupported(int32_t streamFlags, const AudioStreamParam auto channelItem = std::find(AUDIO_FAST_STREAM_SUPPORTED_CHANNELS.begin(), AUDIO_FAST_STREAM_SUPPORTED_CHANNELS.end(), channels); if (channelItem == AUDIO_FAST_STREAM_SUPPORTED_CHANNELS.end()) { + AUDIO_WARNING_LOG("Audio channel %{public}d does not meet the requirements", channels); return false; } @@ -194,6 +196,7 @@ bool IAudioStream::IsStreamSupported(int32_t streamFlags, const AudioStreamParam auto formatItem = std::find(AUDIO_FAST_STREAM_SUPPORTED_FORMATS.begin(), AUDIO_FAST_STREAM_SUPPORTED_FORMATS.end(), format); if (formatItem == AUDIO_FAST_STREAM_SUPPORTED_FORMATS.end()) { + AUDIO_WARNING_LOG("Audio sample format %{public}d does not meet the requirements", format); return false; } } diff --git a/services/audio_service/server/include/audio_endpoint.h b/services/audio_service/server/include/audio_endpoint.h index c2c9a87546..bdc42ad57d 100644 --- a/services/audio_service/server/include/audio_endpoint.h +++ b/services/audio_service/server/include/audio_endpoint.h @@ -47,7 +47,8 @@ public: enum EndpointType : uint32_t { TYPE_MMAP = 0, TYPE_INVALID, - TYPE_INDEPENDENT + TYPE_INDEPENDENT, + TYPE_VOIP_MMAP }; enum EndpointStatus : uint32_t { diff --git a/services/audio_service/server/include/audio_service.h b/services/audio_service/server/include/audio_service.h index 7deb340ac3..41c0380e68 100644 --- a/services/audio_service/server/include/audio_service.h +++ b/services/audio_service/server/include/audio_service.h @@ -54,7 +54,8 @@ public: int32_t OnProcessRelease(IAudioProcessStream *process) override; DeviceInfo GetDeviceInfoForProcess(const AudioProcessConfig &config); - std::shared_ptr GetAudioEndpointForDevice(DeviceInfo &deviceInfo, AudioStreamType streamType); + std::shared_ptr GetAudioEndpointForDevice(DeviceInfo &deviceInfo, AudioStreamType streamType, + bool isVoipStream); int32_t NotifyStreamVolumeChanged(AudioStreamType streamType, float volume); int32_t LinkProcessToEndpoint(sptr process, std::shared_ptr endpoint); diff --git a/services/audio_service/server/include/policy_handler.h b/services/audio_service/server/include/policy_handler.h index 3382e00e1f..70c53fe650 100644 --- a/services/audio_service/server/include/policy_handler.h +++ b/services/audio_service/server/include/policy_handler.h @@ -44,6 +44,8 @@ public: // keep same with AudioPolicyServer AudioVolumeType GetVolumeTypeFromStreamType(AudioStreamType streamType); + DeviceType GetDeviceTypeForVolumeVector(DeviceType deviceType); + bool GetSharedVolume(AudioVolumeType streamType, DeviceType deviceType, Volume &vol); void SetActiveOutputDevice(DeviceType deviceType); diff --git a/services/audio_service/server/src/audio_endpoint.cpp b/services/audio_service/server/src/audio_endpoint.cpp index cbdd21dac8..45dae72d9a 100644 --- a/services/audio_service/server/src/audio_endpoint.cpp +++ b/services/audio_service/server/src/audio_endpoint.cpp @@ -30,6 +30,7 @@ #include "audio_log.h" #include "audio_schedule.h" #include "audio_utils.h" +#include "bluetooth_renderer_sink.h" #include "fast_audio_renderer_sink.h" #include "fast_audio_capturer_source.h" #include "i_audio_capturer_source.h" @@ -193,6 +194,9 @@ private: void AsyncGetPosTime(); bool DelayStopDevice(); + IMmapAudioRendererSink *GetFastSink(const DeviceInfo &deviceInfo, EndpointType type); + IMmapAudioCapturerSource *GetFastSource(const std::string &networkId, EndpointType type, IAudioSourceAttr &attr); + void InitLatencyMeasurement(); void DeinitLatencyMeasurement(); void CheckPlaySignal(uint8_t *buffer, size_t bufferSize); @@ -564,6 +568,9 @@ bool AudioEndpointInner::ConfigInputPoint(const DeviceInfo &deviceInfo) attr.format = ConvertToHdiAdapterFormat(dstStreamInfo_.format); attr.deviceNetworkId = deviceInfo.networkId.c_str(); attr.deviceType = deviceInfo.deviceType; + attr.audioStreamFlag = endpointType_ == TYPE_VOIP_MMAP ? AUDIO_FLAG_VOIP_FAST : AUDIO_FLAG_MMAP; + + fastSource_ = GetFastSource(deviceInfo.networkId, endpointType_, attr); if (deviceInfo.networkId == LOCAL_NETWORK_ID) { attr.adapterName = "primary"; @@ -601,6 +608,25 @@ bool AudioEndpointInner::ConfigInputPoint(const DeviceInfo &deviceInfo) return true; } +IMmapAudioCapturerSource *AudioEndpointInner::GetFastSource(const std::string &networkId, EndpointType type, + IAudioSourceAttr &attr) +{ + AUDIO_INFO_LOG("Network id %{public}s, endpoint type %{public}d", networkId.c_str(), type); + if (networkId == LOCAL_NETWORK_ID) { + attr.adapterName = "primary"; + if (type == AudioEndpoint::TYPE_MMAP) { + return FastAudioCapturerSource::GetInstance(); + } else if (type == AudioEndpoint::TYPE_VOIP_MMAP) { + return FastAudioCapturerSource::GetVoipInstance(); + } + } else { + attr.adapterName = "remote"; + // Distributed only requires a singleton because there won't be both voip and regular fast simultaneously + return RemoteFastAudioCapturerSource::GetInstance(networkId); + } + return nullptr; +} + bool AudioEndpointInner::Config(const DeviceInfo &deviceInfo) { AUDIO_INFO_LOG("Config enter, deviceRole %{public}d.", deviceInfo.deviceRole); @@ -620,8 +646,9 @@ bool AudioEndpointInner::Config(const DeviceInfo &deviceInfo) return ConfigInputPoint(deviceInfo); } - fastSink_ = deviceInfo.networkId != LOCAL_NETWORK_ID ? - RemoteFastAudioRendererSink::GetInstance(deviceInfo.networkId) : FastAudioRendererSink::GetInstance(); + fastSink_ = GetFastSink(deviceInfo, endpointType_); + CHECK_AND_RETURN_RET_LOG(fastSink_ != nullptr, false, "Get fastSink instance failed"); + IAudioSinkAttr attr = {}; attr.adapterName = "primary"; attr.sampleRate = dstStreamInfo_.samplingRate; // 48000hz @@ -629,6 +656,7 @@ bool AudioEndpointInner::Config(const DeviceInfo &deviceInfo) attr.format = ConvertToHdiAdapterFormat(dstStreamInfo_.format); // SAMPLE_S16LE = 1 attr.deviceNetworkId = deviceInfo.networkId.c_str(); attr.deviceType = static_cast(deviceInfo.deviceType); + attr.audioStreamFlag = endpointType_ == TYPE_VOIP_MMAP ? AUDIO_FLAG_VOIP_FAST : AUDIO_FLAG_MMAP; fastSink_->Init(attr); if (!fastSink_->IsInited()) { @@ -660,6 +688,26 @@ bool AudioEndpointInner::Config(const DeviceInfo &deviceInfo) return true; } +IMmapAudioRendererSink *AudioEndpointInner::GetFastSink(const DeviceInfo &deviceInfo, EndpointType type) +{ + AUDIO_INFO_LOG("Network id %{public}s, endpoint type %{public}d", deviceInfo.networkId.c_str(), type); + if (deviceInfo.networkId != LOCAL_NETWORK_ID) { + // Distributed only requires a singleton because there won't be both voip and regular fast simultaneously + return RemoteFastAudioRendererSink::GetInstance(deviceInfo.networkId); + } + + if (deviceInfo.deviceType == DEVICE_TYPE_BLUETOOTH_A2DP && deviceInfo.a2dpOffloadFlag == A2DP_NOT_OFFLOAD) { + return BluetoothRendererSink::GetMmapInstance(); + } + + if (type == AudioEndpoint::TYPE_MMAP) { + return FastAudioRendererSink::GetInstance(); + } else if (type == AudioEndpoint::TYPE_VOIP_MMAP) { + return FastAudioRendererSink::GetVoipInstance(); + } + return nullptr; +} + int32_t AudioEndpointInner::GetAdapterBufferInfo(const DeviceInfo &deviceInfo) { int32_t ret = 0; diff --git a/services/audio_service/server/src/audio_service.cpp b/services/audio_service/server/src/audio_service.cpp index 748b4264e8..617e9065a8 100644 --- a/services/audio_service/server/src/audio_service.cpp +++ b/services/audio_service/server/src/audio_service.cpp @@ -324,7 +324,9 @@ sptr AudioService::GetAudioProcess(const AudioProcessConfi Trace trace("AudioService::GetAudioProcess for " + std::to_string(config.appInfo.appPid)); AUDIO_INFO_LOG("GetAudioProcess dump %{public}s", ProcessConfig::DumpProcessConfig(config).c_str()); DeviceInfo deviceInfo = GetDeviceInfoForProcess(config); - std::shared_ptr audioEndpoint = GetAudioEndpointForDevice(deviceInfo, config.streamType); + std::shared_ptr audioEndpoint = GetAudioEndpointForDevice(deviceInfo, config.streamType, + config.rendererInfo.streamUsage == STREAM_USAGE_VOICE_COMMUNICATION || + config.capturerInfo.sourceType == SOURCE_TYPE_VOICE_COMMUNICATION); CHECK_AND_RETURN_RET_LOG(audioEndpoint != nullptr, nullptr, "no endpoint found for the process"); uint32_t totalSizeInframe = 0; @@ -473,18 +475,23 @@ DeviceInfo AudioService::GetDeviceInfoForProcess(const AudioProcessConfig &confi } std::shared_ptr AudioService::GetAudioEndpointForDevice(DeviceInfo &deviceInfo, - AudioStreamType streamType) + AudioStreamType streamType, bool isVoipStream) { if (deviceInfo.deviceRole == INPUT_DEVICE || deviceInfo.networkId != LOCAL_NETWORK_ID || deviceInfo.deviceRole == OUTPUT_DEVICE) { // Create shared stream. - std::string deviceKey = deviceInfo.networkId + std::to_string(deviceInfo.deviceId) + "_0"; + int32_t endpointFlag = AUDIO_FLAG_MMAP; + if (isVoipStream) { + endpointFlag = AUDIO_FLAG_VOIP_FAST; + } + std::string deviceKey = deviceInfo.networkId + std::to_string(deviceInfo.deviceId) + "_" + + std::to_string(endpointFlag); if (endpointList_.find(deviceKey) != endpointList_.end()) { AUDIO_INFO_LOG("AudioService find endpoint already exist for deviceKey:%{public}s", deviceKey.c_str()); return endpointList_[deviceKey]; } else { - std::shared_ptr endpoint = AudioEndpoint::CreateEndpoint(AudioEndpoint::TYPE_MMAP, - 0, streamType, deviceInfo); + std::shared_ptr endpoint = AudioEndpoint::CreateEndpoint(isVoipStream ? + AudioEndpoint::TYPE_VOIP_MMAP : AudioEndpoint::TYPE_MMAP, endpointFlag, streamType, deviceInfo); CHECK_AND_RETURN_RET_LOG(endpoint != nullptr, nullptr, "Create mmap AudioEndpoint failed."); endpointList_[deviceKey] = endpoint; return endpoint; diff --git a/services/audio_service/server/src/policy_handler.cpp b/services/audio_service/server/src/policy_handler.cpp index 7d4062fbfe..9a2a840578 100644 --- a/services/audio_service/server/src/policy_handler.cpp +++ b/services/audio_service/server/src/policy_handler.cpp @@ -145,12 +145,26 @@ AudioVolumeType PolicyHandler::GetVolumeTypeFromStreamType(AudioStreamType strea } } +DeviceType PolicyHandler::GetDeviceTypeForVolumeVector(DeviceType deviceType) +{ + DeviceType deviceTypeInVector = DEVICE_TYPE_NONE; + switch (deviceType) { + case DEVICE_TYPE_EARPIECE : + case DEVICE_TYPE_SPEAKER : + deviceTypeInVector = DEVICE_TYPE_SPEAKER; + break; + default: + AUDIO_ERR_LOG("Device type %{public}d is invalid, for volume vector", deviceType); + } + return deviceTypeInVector; +} + bool PolicyHandler::GetSharedVolume(AudioVolumeType streamType, DeviceType deviceType, Volume &vol) { CHECK_AND_RETURN_RET_LOG((iPolicyProvider_ != nullptr && volumeVector_ != nullptr), false, "GetSharedVolume failed not configed"); size_t index = 0; - if (!IPolicyProvider::GetVolumeIndex(streamType, deviceType, index) || + if (!IPolicyProvider::GetVolumeIndex(streamType, GetDeviceTypeForVolumeVector(deviceType), index) || index >= IPolicyProvider::GetVolumeVectorSize()) { return false; } diff --git a/test/fuzztest/audiopolicyanother_fuzzer/audio_policy_another_fuzzer.cpp b/test/fuzztest/audiopolicyanother_fuzzer/audio_policy_another_fuzzer.cpp index 986e60fd73..1c1c9bffd4 100644 --- a/test/fuzztest/audiopolicyanother_fuzzer/audio_policy_another_fuzzer.cpp +++ b/test/fuzztest/audiopolicyanother_fuzzer/audio_policy_another_fuzzer.cpp @@ -51,6 +51,30 @@ void AudioVolumeFuzzTest(const uint8_t *rawData, size_t size) AudioPolicyServerPtr->SetStreamMute(streamType, mute); AudioPolicyServerPtr->GetStreamMute(streamType); AudioPolicyServerPtr->IsStreamActive(streamType); + + ContentType contentType = *reinterpret_cast(rawData); + StreamUsage streamUsage = *reinterpret_cast(rawData); + int32_t rendererFlags = *reinterpret_cast(rawData); + std::string sceneType(reinterpret_cast(rawData), size - 1); + bool spatializationEnabled = *reinterpret_cast(rawData); + bool headTrackingEnabled = *reinterpret_cast(rawData); + AudioRendererInfo rendererInfo = { + contentType, + streamUsage, + rendererFlags, + sceneType, + spatializationEnabled, + headTrackingEnabled + }; + AudioPolicyServerPtr->GetPreferredOutputStreamType(rendererInfo); + + SourceType sourceType = *reinterpret_cast(rawData); + int32_t capturerFlags = *reinterpret_cast(rawData); + AudioCapturerInfo capturerInfo = { + sourceType, + capturerFlags + }; + AudioPolicyServerPtr->GetPreferredInputStreamType(capturerInfo); } void AudioDeviceFuzzTest(const uint8_t *rawData, size_t size) -- Gitee