音频输出设备与输入设备的切换
·
1.AudioPolicyService::SetAudioScene中,会调用FetchDevice去更改输出设备与输入设备,再调用SetAudioScene去修改音频场景,最后如果是通话则去修改音量为通话场景的音量。
int32_t AudioPolicyService::SetAudioScene(AudioScene audioScene)
{
...
// fetch input&output device
FetchDevice(true); // output
FetchDevice(false); // input
...
if (haveArmUsbDevice) {
result = gsp->SetAudioScene(audioScene, activeOutputDevices, DEVICE_TYPE_USB_ARM_HEADSET,
a2dpOffloadFlag_);
} else {
result = gsp->SetAudioScene(audioScene, activeOutputDevices, GetCurrentInputDeviceType(),
a2dpOffloadFlag_);
}
IPCSkeleton::SetCallingIdentity(identity);
CHECK_AND_RETURN_RET_LOG(result == SUCCESS, ERR_OPERATION_FAILED, "failed [%{public}d]", result);
if (audioScene_ == AUDIO_SCENE_PHONE_CALL) {
SetVoiceCallVolume(GetSystemVolumeLevel(STREAM_VOICE_CALL));
}
return SUCCESS;
}
2.AudioPolicyService::FetchDevice根据传入的参数判断是更改输入设备还是输出设备,isOutputDevice为true则为输出设备
void AudioPolicyService::FetchDevice(bool isOutputDevice, const AudioStreamDeviceChangeReasonExt reason)
{
Trace trace("AudioPolicyService::FetchDevice reason:" + std::to_string(static_cast<int>(reason)));
AUDIO_DEBUG_LOG("FetchDevice start");
if (isOutputDevice) {
vector<unique_ptr<AudioRendererChangeInfo>> rendererChangeInfos;
streamCollector_.GetCurrentRendererChangeInfos(rendererChangeInfos);
FetchOutputDevice(rendererChangeInfos, reason);
} else {
vector<unique_ptr<AudioCapturerChangeInfo>> capturerChangeInfos;
streamCollector_.GetCurrentCapturerChangeInfos(capturerChangeInfos);
FetchInputDevice(capturerChangeInfos, reason);
}
}
3.更改输入设备
void AudioPolicyService::FetchInputDevice(vector<unique_ptr<AudioCapturerChangeInfo>> &capturerChangeInfos,
const AudioStreamDeviceChangeReasonExt reason)
{
Trace trace("AudioPolicyService::FetchInputDevice");
AUDIO_INFO_LOG("Start for %{public}zu stream, connected %{public}s",
capturerChangeInfos.size(), audioDeviceManager_.GetConnDevicesStr().c_str());
bool needUpdateActiveDevice = true;
bool isUpdateActiveDevice = false;
int32_t runningStreamCount = 0;
// 遍历捕获流信息并处理
for (auto &capturerChangeInfo : capturerChangeInfos) {
SourceType sourceType = capturerChangeInfo->capturerInfo.sourceType;
// 判断是否需要跳过捕获流
if ((sourceType == SOURCE_TYPE_VIRTUAL_CAPTURE && audioScene_ != AUDIO_SCENE_PHONE_CALL) ||
(sourceType != SOURCE_TYPE_VIRTUAL_CAPTURE && capturerChangeInfo->capturerState != CAPTURER_RUNNING)) {
AUDIO_INFO_LOG("stream %{public}d not running, no need fetch device", capturerChangeInfo->sessionId);
continue;
}
runningStreamCount++;
// 获取输入设备描述符
unique_ptr<AudioDeviceDescriptor> desc = audioRouterCenter_.FetchInputDevice(sourceType,
capturerChangeInfo->clientUID);
DeviceInfo inputDeviceInfo = capturerChangeInfo->inputDeviceInfo;
// 设备变更处理
if (HandleDeviceChangeForFetchInputDevice(desc, capturerChangeInfo) == ERR_NEED_NOT_SWITCH_DEVICE) {
continue;
}
// 蓝牙设备处理
if (desc->deviceType_ == DEVICE_TYPE_BLUETOOTH_SCO) {
BluetoothScoFetch(desc, capturerChangeInfos, sourceType);
}
// 更新当前活跃输入设备
if (needUpdateActiveDevice) {
AudioDeviceDescriptor tempDesc = GetCurrentInputDevice();
if (!IsSameDevice(desc, tempDesc)) {
WriteInputRouteChangeEvent(desc, reason);
SetCurrenInputDevice(*desc); // 修改当前设备参数
AUDIO_DEBUG_LOG("currentActiveInputDevice update %{public}d", GetCurrentInputDeviceType());
isUpdateActiveDevice = true;
}
needUpdateActiveDevice = false;
}
if (NotifyRecreateCapturerStream(isUpdateActiveDevice, capturerChangeInfo, reason)) {continue;}
// 切换设备
MoveToNewInputDevice(capturerChangeInfo, desc);
// 更新音频捕获器的麦克风描述符
AddAudioCapturerMicrophoneDescriptor(capturerChangeInfo->sessionId, desc->deviceType_);
}
// 如果设备已更新,则更新系统中首选的输入设备
if (isUpdateActiveDevice) {
OnPreferredInputDeviceUpdated(GetCurrentInputDeviceType(), ""); // networkId is not used.
}
if (runningStreamCount == 0) {
FetchInputDeviceWhenNoRunningStream();
}
}
更多推荐

所有评论(0)