Android Audio 音频路由

一、在 AudioPolicyService 中,选择音频路由时会从当前音频流的类型获取音频的路由策略:

/frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp

routing_strategy AudioPolicyManager::getStrategy(audio_stream_type_t stream) const
{
    ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH");
    return mEngine->getStrategyForStream(stream);
}

/frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp

routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream)
{
    // stream to strategy mapping
    switch (stream) {
    case AUDIO_STREAM_VOICE_CALL:
    case AUDIO_STREAM_BLUETOOTH_SCO:
        return STRATEGY_PHONE;
    case AUDIO_STREAM_RING:
    case AUDIO_STREAM_ALARM:
        return STRATEGY_SONIFICATION;
    case AUDIO_STREAM_NOTIFICATION:
        return STRATEGY_SONIFICATION_RESPECTFUL;
    case AUDIO_STREAM_DTMF:
        return STRATEGY_DTMF;
    default:
        ALOGE("unknown stream type %d", stream);
    case AUDIO_STREAM_SYSTEM:
        // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
        // while key clicks are played produces a poor result
    case AUDIO_STREAM_MUSIC:
        return STRATEGY_MEDIA;
    case AUDIO_STREAM_ENFORCED_AUDIBLE:
        return STRATEGY_ENFORCED_AUDIBLE;
    case AUDIO_STREAM_TTS:
        return STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
    case AUDIO_STREAM_ACCESSIBILITY:
        return STRATEGY_ACCESSIBILITY;
    case AUDIO_STREAM_REROUTING:
        return STRATEGY_REROUTING;
    }
}

音频策略枚举: 

enum routing_strategy {
    STRATEGY_MEDIA, // 媒体策略
    STRATEGY_PHONE, // 电话策略
    STRATEGY_SONIFICATION, // 通知策略
    STRATEGY_SONIFICATION_RESPECTFUL,
    STRATEGY_DTMF, // DTMF 策略
    STRATEGY_ENFORCED_AUDIBLE, // 强制输出策略
    STRATEGY_TRANSMITTED_THROUGH_SPEAKER,
    STRATEGY_ACCESSIBILITY,
    STRATEGY_REROUTING,
    NUM_STRATEGIES
};

二、获取到音频路由策略类型后,通过调用 getDeviceForStrategy() 选择最终的输出设备

/frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp

audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const
{
    DeviceVector availableOutputDevices = mApmObserver->getAvailableOutputDevices();
    DeviceVector availableInputDevices = mApmObserver->getAvailableInputDevices();

    const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();

    return getDeviceForStrategyInt(strategy, availableOutputDevices,
                                   availableInputDevices, outputs, (uint32_t)AUDIO_DEVICE_NONE);
}
audio_devices_t Engine::getDeviceForStrategyInt(routing_strategy strategy,
        DeviceVector availableOutputDevices,
        DeviceVector availableInputDevices,
        const SwAudioOutputCollection &outputs,
        uint32_t outputDeviceTypesToIgnore) const
{
    uint32_t device = AUDIO_DEVICE_NONE;
    uint32_t availableOutputDevicesType =
            availableOutputDevices.types() & ~outputDeviceTypesToIgnore;

    switch (strategy) {

... ...

    case STRATEGY_MEDIA: {
        uint32_t device2 = AUDIO_DEVICE_NONE;
        if (strategy != STRATEGY_SONIFICATION) {
            // no sonification on remote submix (e.g. WFD)
            if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
                                                 String8("0")) != 0) {
                device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
            }
        }
        if (isInCall() && (strategy == STRATEGY_MEDIA)) {
            device = getDeviceForStrategyInt(
                    STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
                    outputDeviceTypesToIgnore);
            break;
        }
        if (device2 == AUDIO_DEVICE_NONE) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID;
        }
        if ((device2 == AUDIO_DEVICE_NONE) &&
                (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
                 outputs.isA2dpSupported()) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
            if (device2 == AUDIO_DEVICE_NONE) {
                device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
            }
            if (device2 == AUDIO_DEVICE_NONE) {
                device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
            }
        }
        if ((device2 == AUDIO_DEVICE_NONE) &&
            (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] == AUDIO_POLICY_FORCE_SPEAKER)) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
        }
        if (device2 == AUDIO_DEVICE_NONE) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
        }
        if (device2 == AUDIO_DEVICE_NONE) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
        }
        if (device2 == AUDIO_DEVICE_NONE) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
        }
        if (device2 == AUDIO_DEVICE_NONE) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_HEADSET;
        }
        if (device2 == AUDIO_DEVICE_NONE) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
        }
        if (device2 == AUDIO_DEVICE_NONE) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
        }
        if (device2 == AUDIO_DEVICE_NONE) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
        }
        if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {
            // no sonification on aux digital (e.g. HDMI)
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
        }
        if ((device2 == AUDIO_DEVICE_NONE) &&
                (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
        }
        if (device2 == AUDIO_DEVICE_NONE) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
        }
        int device3 = AUDIO_DEVICE_NONE;
        if (strategy == STRATEGY_MEDIA) {
            // ARC, SPDIF and AUX_LINE can co-exist with others.
            device3 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HDMI_ARC;
            device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPDIF);
            device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_LINE);
        }

        device2 |= device3;
        // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
        // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
        device |= device2;

        // If hdmi system audio mode is on, remove speaker out of output list.
        if ((strategy == STRATEGY_MEDIA) &&
            (mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] ==
                AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
            device &= ~AUDIO_DEVICE_OUT_SPEAKER;
        }

        // for STRATEGY_SONIFICATION:
        // if SPEAKER was selected, and SPEAKER_SAFE is available, use SPEAKER_SAFE instead
        if ((strategy == STRATEGY_SONIFICATION) &&
                (device & AUDIO_DEVICE_OUT_SPEAKER) &&
                (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
            device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
            device &= ~AUDIO_DEVICE_OUT_SPEAKER;
        }
        } break;

... ...
}

通过判断音频设备是否连接,及相关优先级进行添加设备或移除设备,这里可以通过自定义去完成音频输出的优先级。

常见设备的定义:

/system/media/audio/include/system/audio-base.h

enum {
    AUDIO_DEVICE_NONE                          = 0x0u,
    AUDIO_DEVICE_BIT_IN                        = 0x80000000u,
    AUDIO_DEVICE_BIT_DEFAULT                   = 0x40000000u,

    AUDIO_DEVICE_OUT_EARPIECE                  = 0x1u,
    AUDIO_DEVICE_OUT_SPEAKER                   = 0x2u,
    AUDIO_DEVICE_OUT_WIRED_HEADSET             = 0x4u,
    AUDIO_DEVICE_OUT_WIRED_HEADPHONE           = 0x8u,
    AUDIO_DEVICE_OUT_BLUETOOTH_SCO             = 0x10u,
    AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET     = 0x20u,
    AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT      = 0x40u,
    AUDIO_DEVICE_OUT_BLUETOOTH_A2DP            = 0x80u,
    AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100u,
    AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER    = 0x200u,
    AUDIO_DEVICE_OUT_AUX_DIGITAL               = 0x400u,
    AUDIO_DEVICE_OUT_HDMI                      = 0x400u,      // OUT_AUX_DIGITAL
    AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET         = 0x800u,
    AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET         = 0x1000u,
    AUDIO_DEVICE_OUT_USB_ACCESSORY             = 0x2000u,
    AUDIO_DEVICE_OUT_USB_DEVICE                = 0x4000u,
    AUDIO_DEVICE_OUT_REMOTE_SUBMIX             = 0x8000u,
    AUDIO_DEVICE_OUT_TELEPHONY_TX              = 0x10000u,
    AUDIO_DEVICE_OUT_LINE                      = 0x20000u,
    AUDIO_DEVICE_OUT_HDMI_ARC                  = 0x40000u,
    AUDIO_DEVICE_OUT_SPDIF                     = 0x80000u,
    AUDIO_DEVICE_OUT_FM                        = 0x100000u,
    AUDIO_DEVICE_OUT_AUX_LINE                  = 0x200000u,
    AUDIO_DEVICE_OUT_SPEAKER_SAFE              = 0x400000u,
    AUDIO_DEVICE_OUT_IP                        = 0x800000u,
    AUDIO_DEVICE_OUT_BUS                       = 0x1000000u,
    AUDIO_DEVICE_OUT_PROXY                     = 0x2000000u,
    AUDIO_DEVICE_OUT_USB_HEADSET               = 0x4000000u,
    AUDIO_DEVICE_OUT_HEARING_AID               = 0x8000000u,
    AUDIO_DEVICE_OUT_ECHO_CANCELLER            = 0x10000000u,
    AUDIO_DEVICE_OUT_DEFAULT                   = 0x40000000u, // BIT_DEFAULT

    AUDIO_DEVICE_IN_COMMUNICATION              = 0x80000001u, // BIT_IN | 0x1
    AUDIO_DEVICE_IN_AMBIENT                    = 0x80000002u, // BIT_IN | 0x2
    AUDIO_DEVICE_IN_BUILTIN_MIC                = 0x80000004u, // BIT_IN | 0x4
    AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET      = 0x80000008u, // BIT_IN | 0x8
    AUDIO_DEVICE_IN_WIRED_HEADSET              = 0x80000010u, // BIT_IN | 0x10
    AUDIO_DEVICE_IN_AUX_DIGITAL                = 0x80000020u, // BIT_IN | 0x20
    AUDIO_DEVICE_IN_HDMI                       = 0x80000020u, // IN_AUX_DIGITAL
    AUDIO_DEVICE_IN_VOICE_CALL                 = 0x80000040u, // BIT_IN | 0x40
    AUDIO_DEVICE_IN_TELEPHONY_RX               = 0x80000040u, // IN_VOICE_CALL
    AUDIO_DEVICE_IN_BACK_MIC                   = 0x80000080u, // BIT_IN | 0x80
    AUDIO_DEVICE_IN_REMOTE_SUBMIX              = 0x80000100u, // BIT_IN | 0x100
    AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET          = 0x80000200u, // BIT_IN | 0x200
    AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET          = 0x80000400u, // BIT_IN | 0x400
    AUDIO_DEVICE_IN_USB_ACCESSORY              = 0x80000800u, // BIT_IN | 0x800
    AUDIO_DEVICE_IN_USB_DEVICE                 = 0x80001000u, // BIT_IN | 0x1000
    AUDIO_DEVICE_IN_FM_TUNER                   = 0x80002000u, // BIT_IN | 0x2000
    AUDIO_DEVICE_IN_TV_TUNER                   = 0x80004000u, // BIT_IN | 0x4000
    AUDIO_DEVICE_IN_LINE                       = 0x80008000u, // BIT_IN | 0x8000
    AUDIO_DEVICE_IN_SPDIF                      = 0x80010000u, // BIT_IN | 0x10000
    AUDIO_DEVICE_IN_BLUETOOTH_A2DP             = 0x80020000u, // BIT_IN | 0x20000
    AUDIO_DEVICE_IN_LOOPBACK                   = 0x80040000u, // BIT_IN | 0x40000
    AUDIO_DEVICE_IN_IP                         = 0x80080000u, // BIT_IN | 0x80000
    AUDIO_DEVICE_IN_BUS                        = 0x80100000u, // BIT_IN | 0x100000
    AUDIO_DEVICE_IN_PROXY                      = 0x81000000u, // BIT_IN | 0x1000000
    AUDIO_DEVICE_IN_USB_HEADSET                = 0x82000000u, // BIT_IN | 0x2000000
    AUDIO_DEVICE_IN_BLUETOOTH_BLE              = 0x84000000u, // BIT_IN | 0x4000000
    AUDIO_DEVICE_IN_DEFAULT                    = 0xC0000000u, // BIT_IN | BIT_DEFAULT
};

音频输入类似,Android 9.0源码为例,不同版本会存在差异

你可能感兴趣的:(Android,音视频,android)