From e82c12ba7c31fa97eecb5d270b0b57fdaf3ef7fa Mon Sep 17 00:00:00 2001 From: "hezhiqiang19@huawei.com" Date: Wed, 16 Aug 2023 11:51:04 +0800 Subject: [PATCH 1/2] enable select device for fast stream Signed-off-by: hezhiqiang19@huawei.com Change-Id: I51358719241390b508ff34d76da67158e1fc7a97 --- .../include/service/audio_policy_service.h | 5 ++ .../src/service/audio_policy_service.cpp | 37 ++++++++++++ .../server/src/audio_endpoint.cpp | 2 +- .../example/audio_process_client_test.cpp | 56 +++++++++++++++++-- 4 files changed, 94 insertions(+), 6 deletions(-) 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 e0fcd52e80..2f140de1cc 100644 --- a/services/audio_policy/server/include/service/audio_policy_service.h +++ b/services/audio_policy/server/include/service/audio_policy_service.h @@ -90,6 +90,8 @@ public: int32_t SelectOutputDevice(sptr audioRendererFilter, std::vector> audioDeviceDescriptors); + int32_t SelectFastOutputDevice(sptr audioRendererFilter, + sptr deviceDescriptor); std::string GetSelectedDeviceInfo(int32_t uid, int32_t pid, AudioStreamType streamType); @@ -432,6 +434,8 @@ private: void RemoveDeviceInRouterMap(std::string networkId); + void RemoveDeviceInFastRouterMap(std::string networkId); + void UpdateDisplayName(sptr deviceDescriptor); void RegisterRemoteDevStatusCallback(); @@ -489,6 +493,7 @@ private: std::mutex routerMapMutex_; // unordered_map is not concurrently-secure std::mutex preferredInputMapMutex_; std::unordered_map> routerMap_; + std::unordered_map> fastRouterMap_; // key:uid value: IAudioPolicyInterface& audioPolicyManager_; Parser& configParser_; #ifdef FEATURE_DTMF_TONE 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 66a2d5b7c9..d7f3013865 100644 --- a/services/audio_policy/server/src/service/audio_policy_service.cpp +++ b/services/audio_policy/server/src/service/audio_policy_service.cpp @@ -499,6 +499,11 @@ int32_t AudioPolicyService::SelectOutputDevice(sptr audioRe int32_t res = DeviceParamsCheck(DeviceRole::OUTPUT_DEVICE, audioDeviceDescriptors); CHECK_AND_RETURN_RET_LOG(res == SUCCESS, res, "DeviceParamsCheck no success"); + if (audioRendererFilter->rendererInfo.rendererFlags == STREAM_FLAG_FAST) { + AUDIO_INFO_LOG("SelectOutputDevice for fast stream"); + return SelectFastOutputDevice(audioRendererFilter, audioDeviceDescriptors[0]); + } + std::string networkId = audioDeviceDescriptors[0]->networkId_; DeviceType deviceType = audioDeviceDescriptors[0]->deviceType_; @@ -555,6 +560,19 @@ int32_t AudioPolicyService::SelectOutputDevice(sptr audioRe return ret; } +int32_t AudioPolicyService::SelectFastOutputDevice(sptr audioRendererFilter, + sptr deviceDescriptor) +{ + // note: check if stream is already running + // if is running, call moveProcessToEndpoint. + + // otherwises, keep router info in the map + std::lock_guard lock(routerMapMutex_); + routerMap_[audioRendererFilter->uid] = std::pair(deviceDescriptor->networkId_, OUTPUT_DEVICE); + AUDIO_INFO_LOG("SelectFastOutputDevice for uid[%{public}d] device[%{public}s]", audioRendererFilter->uid, + deviceDescriptor->networkId_.c_str()); + return SUCCESS; +} int32_t AudioPolicyService::RememberRoutingInfo(sptr audioRendererFilter, sptr deviceDescriptor) @@ -2310,6 +2328,19 @@ void AudioPolicyService::RemoveDeviceInRouterMap(std::string networkId) } } +void AudioPolicyService::RemoveDeviceInFastRouterMap(std::string networkId) +{ + std::lock_guard lock(routerMapMutex_); + std::unordered_map>::iterator it; + for (it = fastRouterMap_.begin();it != fastRouterMap_.end();) { + if (it->second.first == networkId) { + fastRouterMap_.erase(it++); + } else { + it++; + } + } +} + void AudioPolicyService::SetDisplayName(const std::string &deviceName, bool isLocalDevice) { for (const auto& deviceInfo : connectedDevices_) { @@ -2461,6 +2492,7 @@ void AudioPolicyService::OnDeviceStatusUpdated(DStatusInfo statusInfo) IOHandles_.erase(moduleName); } RemoveDeviceInRouterMap(moduleName); + RemoveDeviceInFastRouterMap(networkId); } TriggerDeviceChangedCallback(deviceChangeDescriptor, statusInfo.isConnected); @@ -3703,6 +3735,11 @@ int32_t AudioPolicyService::GetProcessDeviceInfo(const AudioProcessConfig &confi AudioStreamInfo targetStreamInfo = {SAMPLE_RATE_48000, ENCODING_PCM, SAMPLE_S16LE, STEREO}; // note: read from xml deviceInfo.audioStreamInfo = targetStreamInfo; deviceInfo.deviceName = "mmap_device"; + std::lock_guard lock(routerMapMutex_); + if (fastRouterMap_.count(config.appInfo.appUid) && fastRouterMap_[config.appInfo.appUid].second == deviceInfo.deviceRole) { + deviceInfo.networkId = fastRouterMap_[config.appInfo.appUid].first; + AUDIO_INFO_LOG("use networkid in fastRouterMap_ :%{public}s ", deviceInfo.networkId.c_str()); + } return SUCCESS; } diff --git a/services/audio_service/server/src/audio_endpoint.cpp b/services/audio_service/server/src/audio_endpoint.cpp index 4dcab5deb1..0c0b866937 100644 --- a/services/audio_service/server/src/audio_endpoint.cpp +++ b/services/audio_service/server/src/audio_endpoint.cpp @@ -357,7 +357,7 @@ bool AudioEndpointInner::Config(const DeviceInfo &deviceInfo) return ConfigInputPoint(deviceInfo); } - fastSink_ = deviceInfo.networkId == REMOTE_NETWORK_ID ? + fastSink_ = deviceInfo.networkId != LOCAL_NETWORK_ID ? RemoteFastAudioRendererSink::GetInstance(deviceInfo.networkId) : FastAudioRendererSink::GetInstance(); IAudioSinkAttr attr = {}; attr.adapterName = "primary"; diff --git a/services/audio_service/test/example/audio_process_client_test.cpp b/services/audio_service/test/example/audio_process_client_test.cpp index fae3cce362..9562d75209 100644 --- a/services/audio_service/test/example/audio_process_client_test.cpp +++ b/services/audio_service/test/example/audio_process_client_test.cpp @@ -31,6 +31,7 @@ #include "audio_errors.h" #include "audio_utils.h" #include "audio_process_in_client.h" +#include "audio_system_manager.h" #include "parameter.h" #include "pcm2wav.h" @@ -291,6 +292,7 @@ public: bool StopMic(); bool ReleaseMic(); + void SelectDevice(DeviceRole deviceRole); private: std::shared_ptr spkProcessClient_ = nullptr; std::shared_ptr micProcessClient_ = nullptr; @@ -308,12 +310,14 @@ int32_t AudioProcessTestCallback::CaptureToFile(const BufferDesc &bufDesc) size_t cnt = fwrite(bufDesc.buffer, 1, bufDesc.bufLength, g_micPcmFile); CHECK_AND_RETURN_RET_LOG(cnt == bufDesc.bufLength, ERR_WRITE_FAILED, "%{public}s fwrite fail, cnt %{public}zu, bufLength %{public}zu.", __func__, cnt, bufDesc.bufLength); - int ret = memcpy_s(static_cast(g_cacheBuffer.buffer), bufDesc.bufLength, - static_cast(bufDesc.buffer), bufDesc.bufLength); - if (ret != EOK) { - AUDIO_WARNING_LOG("memcpy_s failed."); + if (g_testMode == RENDER_MIC_LOOP_DATA) { + int ret = memcpy_s(static_cast(g_cacheBuffer.buffer), bufDesc.bufLength, + static_cast(bufDesc.buffer), bufDesc.bufLength); + if (ret != EOK) { + AUDIO_WARNING_LOG("memcpy_s failed."); + } + g_stampTime = ClockTime::GetCurNano(); } - g_stampTime = ClockTime::GetCurNano(); return SUCCESS; } @@ -390,6 +394,45 @@ inline AudioSampleFormat GetSampleFormat(int32_t wavSampleFormat) } } +void AudioProcessTest::SelectDevice(DeviceRole deviceRole) { + AudioSystemManager *manager = AudioSystemManager::GetInstance(); + if (manager == nullptr) { + std::cout << "Get AudioSystemManager failed" << std::endl; + return; + } + + std::vector> devices; + if (deviceRole == OUTPUT_DEVICE) { + devices = manager->GetDevices(DISTRIBUTED_OUTPUT_DEVICES_FLAG); + } else { + devices = manager->GetDevices(DISTRIBUTED_INPUT_DEVICES_FLAG); + } + if (devices.size() != 1) { + std::cout << "GetDevices failed, unsupported size:" << devices.size() << std::endl; + return; + } + + std::cout << "using device:" << devices[0]->networkId_ << std::endl; + + int32_t ret = 0; + if (deviceRole == OUTPUT_DEVICE) { + sptr filter = new AudioRendererFilter(); + filter->uid = getuid(); + filter->rendererInfo.rendererFlags = STREAM_FLAG_FAST; + ret = manager->SelectOutputDevice(filter, devices); + } else { + sptr filter = new AudioCapturerFilter(); + filter->uid = getuid(); + ret = manager->SelectInputDevice(filter, devices); + } + + if (ret == SUCCESS) { + std::cout << "SelectDevice seccess" << std::endl; + } else { + std::cout << "SelectDevice failed, ret:" << ret << std::endl; + } +} + int32_t AudioProcessTest::InitSpk(int32_t loopCount, bool isRemote) { if (loopCount < 0) { @@ -399,6 +442,9 @@ int32_t AudioProcessTest::InitSpk(int32_t loopCount, bool isRemote) } else { loopCount_ = loopCount; } + if (isRemote) { + SelectDevice(OUTPUT_DEVICE); + } AudioProcessConfig config; config.appInfo.appPid = getpid(); -- Gitee From de83a0bdb5c675e8d74aa8318f09279d9e0a6ab5 Mon Sep 17 00:00:00 2001 From: "hezhiqiang19@huawei.com" Date: Tue, 22 Aug 2023 20:55:22 +0800 Subject: [PATCH 2/2] enable select fast input Signed-off-by: hezhiqiang19@huawei.com Change-Id: I584e973705a120f7c2d1d83fce7984404028ea56 --- .../include/audio_system_manager.h | 1 + .../include/service/audio_policy_service.h | 6 +- .../src/service/audio_policy_service.cpp | 80 ++++++++++++------- .../client/src/audio_device_descriptor.cpp | 6 +- .../example/audio_process_client_test.cpp | 9 ++- 5 files changed, 70 insertions(+), 32 deletions(-) diff --git a/interfaces/inner_api/native/audiomanager/include/audio_system_manager.h b/interfaces/inner_api/native/audiomanager/include/audio_system_manager.h index f36e181f9a..90808fafc1 100644 --- a/interfaces/inner_api/native/audiomanager/include/audio_system_manager.h +++ b/interfaces/inner_api/native/audiomanager/include/audio_system_manager.h @@ -171,6 +171,7 @@ public: virtual ~AudioCapturerFilter(); int32_t uid = -1; + AudioCapturerInfo capturerInfo = {SOURCE_TYPE_INVALID, 0}; bool Marshalling(Parcel &parcel) const override; static sptr Unmarshalling(Parcel &in); 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 2f140de1cc..32ed0aa51d 100644 --- a/services/audio_policy/server/include/service/audio_policy_service.h +++ b/services/audio_policy/server/include/service/audio_policy_service.h @@ -97,6 +97,8 @@ public: int32_t SelectInputDevice(sptr audioCapturerFilter, std::vector> audioDeviceDescriptors); + int32_t SelectFastInputDevice(sptr audioCapturerFilter, + sptr deviceDescriptor); std::vector> GetDevices(DeviceFlag deviceFlag); @@ -322,6 +324,8 @@ private: int32_t MoveToLocalOutputDevice(std::vector sinkInputIds, sptr localDeviceDescriptor); + std::vector FilterSinkInputs(sptr audioRendererFilter, bool moveAll); + int32_t MoveToRemoteOutputDevice(std::vector sinkInputIds, sptr remoteDeviceDescriptor); @@ -493,7 +497,7 @@ private: std::mutex routerMapMutex_; // unordered_map is not concurrently-secure std::mutex preferredInputMapMutex_; std::unordered_map> routerMap_; - std::unordered_map> fastRouterMap_; // key:uid value: + std::unordered_map> fastRouterMap_; // key:uid value: IAudioPolicyInterface& audioPolicyManager_; Parser& configParser_; #ifdef FEATURE_DTMF_TONE 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 d7f3013865..98781c6c53 100644 --- a/services/audio_policy/server/src/service/audio_policy_service.cpp +++ b/services/audio_policy/server/src/service/audio_policy_service.cpp @@ -500,7 +500,6 @@ int32_t AudioPolicyService::SelectOutputDevice(sptr audioRe CHECK_AND_RETURN_RET_LOG(res == SUCCESS, res, "DeviceParamsCheck no success"); if (audioRendererFilter->rendererInfo.rendererFlags == STREAM_FLAG_FAST) { - AUDIO_INFO_LOG("SelectOutputDevice for fast stream"); return SelectFastOutputDevice(audioRendererFilter, audioDeviceDescriptors[0]); } @@ -517,35 +516,15 @@ int32_t AudioPolicyService::SelectOutputDevice(sptr audioRe return SelectNewDevice(DeviceRole::OUTPUT_DEVICE, audioDeviceDescriptors[0]); } - int32_t targetUid = audioRendererFilter->uid; - AudioStreamType targetStreamType = audioRendererFilter->streamType; // move all sink-input. - bool moveAll = false; - if (targetUid == -1) { + bool moveAll = audioRendererFilter->uid == -1 ? true : false; + if (moveAll) { AUDIO_INFO_LOG("Move all sink inputs."); - moveAll = true; std::lock_guard lock(routerMapMutex_); routerMap_.clear(); } - // find sink-input id with audioRendererFilter - std::vector targetSinkInputs = {}; - vector sinkInputs = audioPolicyManager_.GetAllSinkInputs(); - - for (size_t i = 0; i < sinkInputs.size(); i++) { - if (sinkInputs[i].uid == dAudioClientUid) { - AUDIO_INFO_LOG("Find sink-input with daudio[%{public}d]", sinkInputs[i].pid); - continue; - } - if (sinkInputs[i].streamType == STREAM_DEFAULT) { - AUDIO_INFO_LOG("Sink-input[%{public}zu] of effect sink, don't move", i); - continue; - } - AUDIO_DEBUG_LOG("sinkinput[%{public}zu]:%{public}s", i, PrintSinkInput(sinkInputs[i]).c_str()); - if (moveAll || (targetUid == sinkInputs[i].uid && targetStreamType == sinkInputs[i].streamType)) { - targetSinkInputs.push_back(sinkInputs[i]); - } - } + std::vector targetSinkInputs = FilterSinkInputs(audioRendererFilter, moveAll); // move target uid, but no stream played yet, record the routing info for first start. if (!moveAll && targetSinkInputs.size() == 0) { @@ -563,17 +542,43 @@ int32_t AudioPolicyService::SelectOutputDevice(sptr audioRe int32_t AudioPolicyService::SelectFastOutputDevice(sptr audioRendererFilter, sptr deviceDescriptor) { + AUDIO_INFO_LOG("SelectFastOutputDevice for uid[%{public}d] device[%{public}s]", audioRendererFilter->uid, + deviceDescriptor->networkId_.c_str()); // note: check if stream is already running // if is running, call moveProcessToEndpoint. // otherwises, keep router info in the map std::lock_guard lock(routerMapMutex_); - routerMap_[audioRendererFilter->uid] = std::pair(deviceDescriptor->networkId_, OUTPUT_DEVICE); - AUDIO_INFO_LOG("SelectFastOutputDevice for uid[%{public}d] device[%{public}s]", audioRendererFilter->uid, - deviceDescriptor->networkId_.c_str()); + fastRouterMap_[audioRendererFilter->uid] = std::make_pair(deviceDescriptor->networkId_, OUTPUT_DEVICE); return SUCCESS; } +std::vector AudioPolicyService::FilterSinkInputs(sptr audioRendererFilter, + bool moveAll) +{ + int32_t targetUid = audioRendererFilter->uid; + AudioStreamType targetStreamType = audioRendererFilter->streamType; + // find sink-input id with audioRendererFilter + std::vector targetSinkInputs = {}; + std::vector sinkInputs = audioPolicyManager_.GetAllSinkInputs(); + + for (size_t i = 0; i < sinkInputs.size(); i++) { + if (sinkInputs[i].uid == dAudioClientUid) { + AUDIO_INFO_LOG("Find sink-input with daudio[%{public}d]", sinkInputs[i].pid); + continue; + } + if (sinkInputs[i].streamType == STREAM_DEFAULT) { + AUDIO_INFO_LOG("Sink-input[%{public}zu] of effect sink, don't move", i); + continue; + } + AUDIO_DEBUG_LOG("sinkinput[%{public}zu]:%{public}s", i, PrintSinkInput(sinkInputs[i]).c_str()); + if (moveAll || (targetUid == sinkInputs[i].uid && targetStreamType == sinkInputs[i].streamType)) { + targetSinkInputs.push_back(sinkInputs[i]); + } + } + return targetSinkInputs; +} + int32_t AudioPolicyService::RememberRoutingInfo(sptr audioRendererFilter, sptr deviceDescriptor) { @@ -721,6 +726,20 @@ inline std::string PrintSourceOutput(SourceOutput sourceOutput) return value.str(); } +int32_t AudioPolicyService::SelectFastInputDevice(sptr audioCapturerFilter, + sptr deviceDescriptor) +{ + // note: check if stream is already running + // if is running, call moveProcessToEndpoint. + + // otherwises, keep router info in the map + std::lock_guard lock(routerMapMutex_); + fastRouterMap_[audioCapturerFilter->uid] = std::make_pair(deviceDescriptor->networkId_, INPUT_DEVICE); + AUDIO_INFO_LOG("SelectFastInputDevice for uid[%{public}d] device[%{public}s]", audioCapturerFilter->uid, + deviceDescriptor->networkId_.c_str()); + return SUCCESS; +} + int32_t AudioPolicyService::SelectInputDevice(sptr audioCapturerFilter, std::vector> audioDeviceDescriptors) { @@ -731,6 +750,10 @@ int32_t AudioPolicyService::SelectInputDevice(sptr audioCap return res; } + if (audioCapturerFilter->capturerInfo.capturerFlags == STREAM_FLAG_FAST && audioDeviceDescriptors.size() == 1) { + return SelectFastInputDevice(audioCapturerFilter, audioDeviceDescriptors[0]); + } + std::string networkId = audioDeviceDescriptors[0]->networkId_; DeviceType deviceType = audioDeviceDescriptors[0]->deviceType_; @@ -3736,7 +3759,8 @@ int32_t AudioPolicyService::GetProcessDeviceInfo(const AudioProcessConfig &confi deviceInfo.audioStreamInfo = targetStreamInfo; deviceInfo.deviceName = "mmap_device"; std::lock_guard lock(routerMapMutex_); - if (fastRouterMap_.count(config.appInfo.appUid) && fastRouterMap_[config.appInfo.appUid].second == deviceInfo.deviceRole) { + if (fastRouterMap_.count(config.appInfo.appUid) && + fastRouterMap_[config.appInfo.appUid].second == deviceInfo.deviceRole) { deviceInfo.networkId = fastRouterMap_[config.appInfo.appUid].first; AUDIO_INFO_LOG("use networkid in fastRouterMap_ :%{public}s ", deviceInfo.networkId.c_str()); } diff --git a/services/audio_service/client/src/audio_device_descriptor.cpp b/services/audio_service/client/src/audio_device_descriptor.cpp index 54b59648b3..276aae79df 100644 --- a/services/audio_service/client/src/audio_device_descriptor.cpp +++ b/services/audio_service/client/src/audio_device_descriptor.cpp @@ -210,7 +210,9 @@ AudioCapturerFilter::~AudioCapturerFilter() bool AudioCapturerFilter::Marshalling(Parcel &parcel) const { - return parcel.WriteInt32(uid); + return parcel.WriteInt32(uid) + && parcel.WriteInt32(static_cast(capturerInfo.sourceType)) + && parcel.WriteInt32(capturerInfo.capturerFlags); } sptr AudioCapturerFilter::Unmarshalling(Parcel &in) @@ -221,6 +223,8 @@ sptr AudioCapturerFilter::Unmarshalling(Parcel &in) } audioCapturerFilter->uid = in.ReadInt32(); + audioCapturerFilter->capturerInfo.sourceType = static_cast(in.ReadInt32()); + audioCapturerFilter->capturerInfo.capturerFlags = in.ReadInt32(); return audioCapturerFilter; } diff --git a/services/audio_service/test/example/audio_process_client_test.cpp b/services/audio_service/test/example/audio_process_client_test.cpp index 9562d75209..4e5ab12af6 100644 --- a/services/audio_service/test/example/audio_process_client_test.cpp +++ b/services/audio_service/test/example/audio_process_client_test.cpp @@ -394,7 +394,8 @@ inline AudioSampleFormat GetSampleFormat(int32_t wavSampleFormat) } } -void AudioProcessTest::SelectDevice(DeviceRole deviceRole) { +void AudioProcessTest::SelectDevice(DeviceRole deviceRole) +{ AudioSystemManager *manager = AudioSystemManager::GetInstance(); if (manager == nullptr) { std::cout << "Get AudioSystemManager failed" << std::endl; @@ -423,6 +424,8 @@ void AudioProcessTest::SelectDevice(DeviceRole deviceRole) { } else { sptr filter = new AudioCapturerFilter(); filter->uid = getuid(); + filter->capturerInfo.sourceType = SOURCE_TYPE_MIC; + filter->capturerInfo.capturerFlags = STREAM_FLAG_FAST; ret = manager->SelectInputDevice(filter, devices); } @@ -564,7 +567,9 @@ int32_t AudioProcessTest::InitMic(bool isRemote) config.streamInfo.format = SAMPLE_S16LE; config.streamInfo.samplingRate = SAMPLE_RATE_48000; - (void)isRemote; + if (isRemote) { + SelectDevice(INPUT_DEVICE); + } micProcessClient_ = AudioProcessInClient::Create(config); CHECK_AND_RETURN_RET_LOG(micProcessClient_ != nullptr, ERR_INVALID_HANDLE, -- Gitee