Android Audio 框架简读 <4>

本文从设备角度简述Android Audio框架的工作原理,重点解析AudioPolicyService如何启动、管理及调度Audio设备。通过分析AudioPolicyService与HAL的交互,揭示设备打开、操作的过程,以及AudioFlinger在其中的角色。
摘要由CSDN通过智能技术生成

android这个Audio部分还是非常大的一个模块,下面从设备的角度简读一下Audio设备是如何工作的.

假设:

<1> : 熟悉了AudioFlinger和AudioPolicyService的基本程序流程.

<2> : 知道HAL中hardware.h那三个结构体是干什么的:

typedef struct hw_module_t 
typedef struct hw_module_methods_t
typedef struct hw_device_t 

如果不知道这三个结构体的规范,就会出现AudioFlinger和AudioPolicyService两个核心和HAL的关联很难连上,代码流程交互衔接不上.


OK!

前面说了AudioFlinger和AudioPolicyService会随着系统启动而跟随启动,而这两个核心是差不多同时启动的,由于AudioPolicyService才是真正的设备管理者和调度者,所以从AudioPolicyService.cpp开始:

// ----------------------------------------------------------------------------

AudioPolicyService::AudioPolicyService()
    : BnAudioPolicyService() , mpAudioPolicyDev(NULL) , mpAudioPolicy(NULL)
{
    char value[PROPERTY_VALUE_MAX];
    const struct hw_module_t *module;
    int forced_val;
    int rc;

    Mutex::Autolock _l(mLock);

    // start tone playback thread
    mTonePlaybackThread = new AudioCommandThread(String8(""));
    // start audio commands thread
    mAudioCommandThread = new AudioCommandThread(String8("ApmCommand"));

    /* instantiate the audio policy manager */
    rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);
    if (rc)
        return;

    rc = audio_policy_dev_open(module, &mpAudioPolicyDev);
    ALOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc));
    if (rc)
        return;

    rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,
                                               &mpAudioPolicy);
    ALOGE_IF(rc, "couldn't create audio policy (%s)", strerror(-rc));
    if (rc)
        return;

    rc = mpAudioPolicy->init_check(mpAudioPolicy);
    ALOGE_IF(rc, "couldn't init_check the audio policy (%s)", strerror(-rc));
    if (rc)
        return;

    ALOGI("Loaded audio policy from %s (%s)", module->name, module->id);

    // load audio pre processing modules
    if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
        loadPreProcessorConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
    } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
        loadPreProcessorConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
    }
}

熟悉HAL三个结构,看了上面的程序,第一反应挑出两处:

 /* instantiate the audio policy manager */
    rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);
    if (rc)
        return;

    rc = audio_policy_dev_open(module, &mpAudioPolicyDev);
    ALOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc));

根据AUDIO_POLICY_HARDWARE_MODULE_ID获取设备module,然后将标为AUDIO_POLICY_HARDWARE_MODULE_ID这个设备打开.打开了设备节点后,反馈的mpAudioPolicyDev对象就可以用于操作各种设备输入输出等动作了.

那么这个设备是什么设备了,还好,根据linux的规范,任何一个节点都有独一无二的AUDIO_POLICY_HARDWARE_MODULE_ID号.搜索这个关键字(source insight中),

Audio_policy_hal.cpp (e:\liuzhibao\android\android\hardware\libhardware_legacy\audio)

就知道打开设备和操作设备都是在这里完成的了.那就理顺了,后面打开函数:

static inline int audio_policy_dev_open(const hw_module_t* module,
                                    struct audio_policy_device** device)
{
    return module->methods->open(module, AUDIO_POLICY_INTERFACE,
                                 (hw_device_t**)device);
}

这个open其实就是调用了Audio_policy_hal.cpp中的:

static int legacy_ap_dev_open(const hw_module_t* module, const char* name,
                                    hw_device_t** device)
{
    struct legacy_ap_device *dev;

    if (strcmp(name, AUDIO_POLICY_INTERFACE) != 0)
        return -EINVAL;

    dev = (struct legacy_ap_device *)calloc(1, sizeof(*dev));
    if (!dev)
        return -ENOMEM;

    dev->device.common.tag = HARDWARE_DEVICE_TAG;
    dev->device.common.version = 0;
    dev->device.common.module = const_cast<hw_module_t*>(module);
    dev->device.common.close = legacy_ap_dev_close;
    dev->device.create_audio_policy = create_legacy_ap;
    dev->device.destroy_audio_policy = destroy_legacy_ap;

    *device = &dev->device.common;

    return 0;
}


但是是谁要去打开了呢?AudioPolicyService.cpp构造函数中:

rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,
                                               &mpAudioPolicy);
    ALOGE_IF(rc, "couldn't create audio policy (%s)", strerror(-rc));


然后就调用了上面的hal层的:

static int create_legacy_ap(const struct audio_policy_device *device,
                            struct audio_policy_service_ops *aps_ops,
                            void *service,
                            struct audio_policy **ap)
{

这个函数中有几个地方:

lap->service_client =
        new AudioPolicyCompatClient(aps_ops, service);
    if (!lap->service_client) {
        ret = -ENOMEM;
        goto err_new_compat_client;
    }

    lap->apm = createAudioPolicyManager(lap->service_client);
    if (!lap->apm) {
        ret = -ENOMEM;
        goto err_create_apm;
    }

new了一个AudioPolicyCompatClient对象,暂时注意这个地方.

lap->apm = createAudioPolicyManager(lap->service_client);

这个返回一个AudioPolicyManager对象,继续查看,最终到AudioPolicyManagerBase中,前面大致介绍过这个类,其中参数就是上面提到的一个new对象

AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface)

结果我们发现这里开始打开设备:

mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName);
        if (mHwModules[i]->mHandle == 0) {
            ALOGW("could not open HW module %s", mHwModules[i]->mName);
            continue;
        }
        // open all output streams needed to access attached devices
        for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
        {
            const IOProfile *outProfile = mHwModules[i]->mOutputProfiles[j];

            if (outProfile->mSupportedDevices & mAttachedOutputDevices && !(outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT)) {
                AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(outProfile);
                outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice &
                                                            outProfile->mSupportedDevices);
                audio_io_handle_t output = mpClientInterface->openOutput(
                                                outProfile->mModule->mHandle,
                                                &outputDesc->mDevice,
                                                &outputDesc->mSamplingRate,
                                                &outputDesc->mFormat,
                                                &outputDesc->mChannelMask,
                                                &outputDesc->mLatency,
                                                outputDesc->mFlags);


开始是loadHwModule(...),然后下面是openOutput(...),这个时候我们在回头来看看AudioPolicyCompatClient这个类:

audio_module_handle_t AudioPolicyCompatClient::loadHwModule(const char *moduleName)
{
    return mServiceOps->load_hw_module(mService, moduleName);
}

audio_io_handle_t AudioPolicyCompatClient::openOutput(audio_module_handle_t module,
                                                      audio_devices_t *pDevices,
                                                      uint32_t *pSamplingRate,
                                                      audio_format_t *pFormat,
                                                      audio_channel_mask_t *pChannelMask,
                                                      uint32_t *pLatencyMs,
                                                      audio_output_flags_t flags)
{
    return mServiceOps->open_output_on_module(mService, module, pDevices, pSamplingRate,
                                              pFormat, pChannelMask, pLatencyMs,
                                              flags);
}

看了一下,发现还不是自己去load和open,还是让"别人"去搞定,这个mServiceOps又是谁了,这个是AudioPolicyService一级一级传递下来的aps_ops:

struct audio_policy_service_ops aps_ops = {
        open_output           : aps_open_output,
        open_duplicate_output : aps_open_dup_output,
        close_output          : aps_close_output,
        suspend_output        : aps_suspend_output,
        restore_output        : aps_restore_output,
        open_input            : aps_open_input,
        close_input           : aps_close_input,
        set_stream_volume     : aps_set_stream_volume,
        set_stream_output     : aps_set_stream_output,
        set_parameters        : aps_set_parameters,
        get_parameters        : aps_get_parameters,
        start_tone            : aps_start_tone,
        stop_tone             : aps_stop_tone,
        set_voice_volume      : aps_set_voice_volume,
        move_effects          : aps_move_effects,
        load_hw_module        : aps_load_hw_module,
        open_output_on_module : aps_open_output_on_module,
        open_input_on_module  : aps_open_input_on_module,
    };

这下爽了吧,一张函数映射表.open_output_on_module对应了aps_open_output_on_module函数,查看一下:

static audio_io_handle_t aps_open_output_on_module(void *service,
                                                   audio_module_handle_t module,
                                                   audio_devices_t *pDevices,
                                                   uint32_t *pSamplingRate,
                                                   audio_format_t *pFormat,
                                                   audio_channel_mask_t *pChannelMask,
                                                   uint32_t *pLatencyMs,
                                                   audio_output_flags_t flags)
{
    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    if (af == 0) {
        ALOGW("%s: could not get AudioFlinger", __func__);
        return 0;
    }
    return af->openOutput(module, pDevices, pSamplingRate, pFormat, pChannelMask,
                          pLatencyMs, flags);
}

这下好了,它是通过获取AudioFlinger核心模块来打开的,也就是绕了一个大弯,从AudioPolicyService那边到HAL,再到进程AudioFlinger中了,让AudioFlinger这个老实人来做事的.

audio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module,
                                           audio_devices_t *pDevices,
                                           uint32_t *pSamplingRate,
                                           audio_format_t *pFormat,
                                           audio_channel_mask_t *pChannelMask,
                                           uint32_t *pLatencyMs,
                                           audio_output_flags_t flags)
{
... ...


对照前面aps_ops那个结构体的映射表关系,就可以想象,AudioPolicyService让AudioFlinger做了多少事(当然可能还不全).

整个流程基本上就清楚很多了,

下面附一张调试日志logcat的信息证明以上说的:注意Tag标签信息顺序








































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值