audio之 Available output/input devices如何确定

本文探讨Android系统如何识别可用的audio output和input设备。从audioserver启动开始,分析getHwModules、loadHwModule、OutputProfiles等关键步骤,揭示设备配置与物理设备的关系,以及如何通过Audio HAL确定设备支持的功能。
摘要由CSDN通过智能技术生成

对于Audio,系统是如何知道当前设备有哪些可用的output和input device?

首先:系统解析audio_policy_configuration.xml中的attachedDevices,mixPorts,devicePorts,routes字段来确定有哪些设备!

但是,在audio_policy_configuration.xml中配置了设备,就一定代表着物理设备也存在吗?
audio_policy_configuration.xml中的字段是如何与物理设备一一对应的?

上述问题是本章要厘清的事情。
一切的一切要从audioserver启动开始说起:

main_audioserver.cpp::main
 BinderService<AudioPolicyService>::publish
  AudioPolicyService::onFirstRef
   AudioPolicyService::createAudioPolicyManager
    AudioPolicyConfig::loadFromApmXml
    AudioPolicyManager::initialize
     AudioPolicyManager::onNewAudioModulesAvailableInt

主要关注onNewAudioModulesAvailableInt方法

void AudioPolicyManager::onNewAudioModulesAvailableInt(DeviceVector *newDevices)
{
    for (const auto& hwModule : mConfig->getHwModules()) {
        ......
        if (hwModule->getHandle() == AUDIO_MODULE_HANDLE_NONE) {
            if (audio_module_handle_t handle = mpClientInterface->loadHwModule(hwModule->getName());
                    handle != AUDIO_MODULE_HANDLE_NONE) {
                hwModule->setHandle(handle);
            } 
            ......
        }
        mHwModules.push_back(hwModule);
        // open all output streams needed to access attached devices.
        // direct outputs are closed immediately after checking the availability of attached devices
        // This also validates mAvailableOutputDevices list
        for (const auto& outProfile : hwModule->getOutputProfiles()) {
            ......
            const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
            DeviceVector availProfileDevices = supportedDevices.filter(mConfig->getOutputDevices());
            sp<DeviceDescriptor> supportedDevice = 0;
            if (supportedDevices.contains(mConfig->getDefaultOutputDevice())) {
                supportedDevice = mConfig->getDefaultOutputDevice();
            } else {
                ......
                supportedDevice = availProfileDevices.itemAt(0);
            }
            if (!mConfig->getOutputDevices().contains(supportedDevice)) {
                continue;
            }
            sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
                                                                                 mpClientInterface);
            audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
            status_t status = outputDesc->open(nullptr /* halConfig */, nullptr /* mixerConfig */,
                                               DeviceVector(supportedDevice),
                                               AUDIO_STREAM_DEFAULT,
                                               AUDIO_OUTPUT_FLAG_NONE, &output);
            
            for (const auto &device : availProfileDevices) {
                // give a valid ID to an attached device once confirmed it is reachable
                if (!device->isAttached()) {
                    device->attach(hwModule);
                    mAvailableOutputDevices.add(device);
                    device->setEncapsulationInfoFromHal(mpClientInterface);
                    if (newDevices) newDevices->add(device);
                    setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
                }
            }
            ......
        }
        // open input streams needed to access attached devices to validate
        // mAvailableInputDevices list
        for (const auto& inProfile : hwModule->getInputProfiles()) {
            ......
            // chose first device present in profile's SupportedDevices also part of
            // available input devices
            const DeviceVector &supportedDevices = inProfile->getSupportedDevices();
            DeviceVector availProfileDevices = supportedDevices.filter(mConfig->getInputDevices());
            
            sp<AudioInputDescriptor> inputDesc =
                    new AudioInputDescriptor(inProfile, mpClientInterface);
            ......
            audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
            status_t status = inputDesc->open(nullptr,
                                              availProfileDevices.itemAt(0),
                                              AUDIO_SOURCE_MIC,
                                              AUDIO_INPUT_FLAG_NONE,
                                              &input);
            
            for (const auto &device : availProfileDevices) {
                // give a valid ID to an attached device once confirmed it is reachable
                if (!device->isAttached()) {
                    device->attach(hwModule);
                    device->importAudioPortAndPickAudioProfile(inProfile, true);
                    mAvailableInputDevices.add(device);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值