AudioPolicyService启动过程分析(android_audio)

此文章部分参考  https://blog.csdn.net/marshal_zsx/article/details/81060100

AudioPolicyService是策略的制定者,
AudioFlinger是策略的执行者,
所以: AudioPolicyService根据配置文件使唤AudioFlinger来创建Thread

管理输入输出设备,包括设备的连接、断开状态,设备的选择和切换等

管理系统的音频策略,比如通话时播放音乐、或者播放音乐时来电话的一系列处理

管理系统的音量

上层的一些音频参数也可以通过AudioPolicyService设置到底层去

godv@godv-OptiPlex-7070:/dev/snd$ ls -la
总用量 0
drwxr-xr-x   3 root root      320 7月   1 21:26 .
drwxr-xr-x  21 root root     4320 7月   1 21:41 ..
drwxr-xr-x   2 root root       60 7月   1 21:26 by-path
crw-rw----+  1 root audio 116,  2 7月   1 21:26 controlC0
crw-rw----+  1 root audio 116, 11 7月   1 21:26 hwC0D0
crw-rw----+  1 root audio 116, 12 7月   1 21:26 hwC0D2
crw-rw----+  1 root audio 116,  4 7月   1 21:26 pcmC0D0c
crw-rw----+  1 root audio 116,  3 7月   1 21:39 pcmC0D0p
crw-rw----+  1 root audio 116, 10 7月   1 21:26 pcmC0D10p
crw-rw----+  1 root audio 116,  5 7月   1 21:26 pcmC0D2c
crw-rw----+  1 root audio 116,  6 7月   1 21:26 pcmC0D3p
crw-rw----+  1 root audio 116,  7 7月   1 21:26 pcmC0D7p
crw-rw----+  1 root audio 116,  8 7月   1 21:26 pcmC0D8p
crw-rw----+  1 root audio 116,  9 7月   1 21:26 pcmC0D9p
crw-rw----+  1 root audio 116,  1 7月   1 21:26 seq
crw-rw----+  1 root audio 116, 33 7月   1 21:26 timer

默认声卡  &  声卡上存在何种硬件资源(耳机孔/喇叭)  厂家通过配置文件声明

1.读取、解析配置文件

2.AudioPolicyService根据配置文件调用AudioFlinger服务创建线程,打开output


audioserver.rc    frameworks/av/media/audioserver/audioserver.rc

service audioserver /system/bin/audioserver
    class main
    user audioserver
    # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
    group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct
    ioprio rt 4
    writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
    onrestart restart audio-hal-2-0

on property:vts.native_server.on=1
    stop audioserver
on property:vts.native_server.on=0
    start audioserver

main_audioserver.cpp    frameworks/av/media/audioserver/main_audioserver.cpp

int main(int argc __unused, char **argv)
{
    signal(SIGPIPE, SIG_IGN);
    ...
        sp<ProcessState> proc(ProcessState::self());
        sp<IServiceManager> sm = defaultServiceManager();
        ALOGI("ServiceManager: %p", sm.get());
        AudioFlinger::instantiate();
        AudioPolicyService::instantiate();

...
        SoundTriggerHwService::instantiate();
        ProcessState::self()->startThreadPool();

// FIXME: remove when BUG 31748996 is fixed
        android::hardware::ProcessState::self()->startThreadPool();

        IPCThreadState::self()->joinThreadPool();
    }
}

frameworks/av/services/audiopolicy/service/AudioPolicyService.cpp

void AudioPolicyService::onFirstRef()
{
    {
        Mutex::Autolock _l(mLock);

        // start tone playback thread
        mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);
        // start audio commands thread
        mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
        // start output activity command thread
        mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);

        mAudioPolicyClient = new AudioPolicyClient(this);
        mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
    }
    // load audio processing modules
    sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects();
    {
        Mutex::Autolock _l(mLock);
        mAudioPolicyEffects = audioPolicyEffects;
    }
}

frameworks/av/services/audiopolicy/service/AudioPolicyService.h

class AudioPolicyClient : public AudioPolicyClientInterface
    {
     ...
     private:
        AudioPolicyService *mAudioPolicyService;
    };

AudioPolicyClient的实现文件frameworks/av/services/audiopolicy/service/AudioPolicyClientImpl.cpp


createAudioPolicyManager  frameworks/av/services/audiopolicy/AudioPolicyInterface.h

// Audio Policy client Interface
class AudioPolicyClientInterface
{
...
extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface);
extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface);
}; // namespace android

createAudioPolicyManager的实现frameworks/av/services/audiopolicy/manager/AudioPolicyFactory.cpp

直接new了一个AudioPolicyManager然后把刚才创建的AudioPolicyClient传了进去。

#include "managerdefault/AudioPolicyManager.h"

namespace android {

extern "C" AudioPolicyInterface* createAudioPolicyManager(
        AudioPolicyClientInterface *clientInterface)
{
    return new AudioPolicyManager(clientInterface);
}

extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
{
    delete interface;
}

}; // namespace android

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

 mEngine->setObserver(this)把mApmObserver绑定为AudioPolicyManager对象,所以在frameworks/ av/services/audiopolicy/enginedefault/Engine.cpp中调用mApmObserver->xxx()都是调用的AudioPolicyManager类中的成员函数。 Engine类里要用到AudioPolicyManager类里的成员函数就用mApmObserver->xxx(),AudioPolicyManager类里要使用Engine类的成员函数就用mEngine->xxx()

AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
{
    ......
    mEngine->setObserver(this);
    ......
}

先从  /vendor/etc/audio_policy.conf 加载 或者 /system/etc/audio_policy.conf 

关于音频配置  frameworks/av/services/audiopolicy/config/audio_policy_configuration.xml

参考  https://blog.csdn.net/qq_33750826/article/details/97757590

//frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface) :
    mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
    mA2dpSuspended(false),
    mAudioPortGeneration(1),
    mBeaconMuteRefCount(0),
    mBeaconPlayingRefCount(0),
    mBeaconMuted(false),
    mTtsOutputAvailable(false),
    mMasterMono(false),
    mMusicEffectOutput(AUDIO_IO_HANDLE_NONE)
{
    //1.加载audio_policy.conf配置文件 
    //配置文件路径:/vendor/etc/audio_policy.conf 或者 /system/etc/audio_policy.conf
    ConfigParsingUtils::loadConfig(....);
    //2.初始化各种音频流对应的音量调节点
    mVolumeCurves->initializeVolumeCurves(speakerDrcEnabled);
    //3.加载audio policy硬件抽象库
    mHwModules[i]->mHandle =  mpClientInterface->loadHwModule(mHwModules[i]->mName);
    //4.打开输出设备
    mpClientInterface->openOutput(....);
    //5.保存输出设备描述符对象
    addOutput(output, outputDesc);
    //6.设置输出设备
    setOutputDevice(....);
    //7.打开输入设备
    mpClientInterface->openInput(....);
    //8.更新输出设备
    updateDevicesAndOutputs();
}

ConfigParsingUtils::loadConfig(....);  解析配置文件

1.加载audio_policy.conf配置文件

frameworks/av/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp

解析配置文件放在这里面说   https://blog.csdn.net/we1less/article/details/118499349


mVolumeCurves->initializeVolumeCurves(mSpeakerDrcEnabled);

frameworks/av/services/audiopolicy/common/managerdefinitions/src/StreamDescriptor.cpp

2.初始化各种音频流对应的音量调节点

void StreamDescriptorCollection::initializeVolumeCurves(bool isSpeakerDrcEnabled)
{
    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
        for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
	        //设置音量
            setVolumeCurvePoint(static_cast<audio_stream_type_t>(i),
                                static_cast<device_category>(j),
                                Gains::sVolumeProfiles[i][j]);
        }
    }
	......
}

mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->getName());

 加载配置文件得到一个mHwModules

3.加载audio policy硬件抽象库

frameworks/av/services/audiopolicy/service/AudioPolicyClientImpl.cpp

audio_module_handle_t AudioPolicyService::AudioPolicyClient::loadHwModule(const char *name)
{
    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    if (af == 0) {
        ALOGW("%s: could not get AudioFlinger", __func__);
        return AUDIO_MODULE_HANDLE_NONE;
    }

    return af->loadHwModule(name);
}

这里直接调用了AudioFlinger::loadHwModule()。

frameworks/av/services/audioflinger/AudioFlinger.cpp

audio_module_handle_t AudioFlinger::loadHwModule(const char *name)
{
    if (name == NULL) {
        return AUDIO_MODULE_HANDLE_NONE;
    }
    if (!settingsAllowed()) {
        return AUDIO_MODULE_HANDLE_NONE;
    }
    Mutex::Autolock _l(mLock);
    return loadHwModule_l(name);
}
audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
{
	//1.是否已经加载过这个interface
    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
        if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {
            ALOGW("loadHwModule() module %s already loaded", name);
            return mAudioHwDevs.keyAt(i);
        }
    }
	//2.加载audio interface
	int rc = mDevicesFactoryHal->openDevice(name, &dev);
	//3.初始化
	rc = dev->initCheck();
	//4.添加到全局变量中
	audio_module_handle_t handle = (audio_module_handle_t) nextUniqueId(AUDIO_UNIQUE_ID_USE_MODULE);
    mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));
}

loadHwModule_l是通过调用openDevice方法来打开加载audio设备的,该方法的实现类是DevicesFactoryHalHybrid

frameworks/av/media/libaudiohal/DevicesFactoryHalHybrid.cpp

DevicesFactoryHalHybrid中提供了两种方式加载,本文将介绍hidl的方式加载

status_t DevicesFactoryHalHybrid::openDevice(const char *name, sp<DeviceHalInterface> *device) {
    if (mHidlFactory != 0 && strcmp(AUDIO_HARDWARE_MODULE_ID_A2DP, name) != 0) {
        return mHidlFactory->openDevice(name, device);  //Hidl方式加载
    }
    return mLocalFactory->openDevice(name, device);   //本地加载
}

 openDevice  frameworks/av/media/libaudiohal/DevicesFactoryHalHidl.cpp

status_t DevicesFactoryHalHidl::openDevice(const char *name, sp<DeviceHalInterface> *device) {
    if (mDevicesFactory == 0) return NO_INIT;
    IDevicesFactory::Device hidlDevice;
    status_t status = nameFromHal(name, &hidlDevice);
    if (status != OK) return status;
    Result retval = Result::NOT_INITIALIZED;
    Return<void> ret = mDevicesFactory->openDevice(
            hidlDevice,
            [&](Result r, const sp<IDevice>& result) {
                retval = r;
                if (retval == Result::OK) {
                    *device = new DeviceHalHidl(result);
                }
            });
    if (ret.isOk()) {
        if (retval == Result::OK) return OK;
        else if (retval == Result::INVALID_ARGUMENTS) return BAD_VALUE;
        else return NO_INIT;
    }
    return FAILED_TRANSACTION;
}

openDevice  hardware/interfaces/audio/2.0/default/DevicesFactory.cpp

总结2 {

  从mHwModules中取出每一个HwModule根据.name打开.so文件

}

  audio.primary.xxx.so

  audio.primary.goldfish.so

Return<void> DevicesFactory::openDevice(IDevicesFactory::Device device, openDevice_cb _hidl_cb)  {
    audio_hw_device_t *halDevice;
    Result retval(Result::INVALID_ARGUMENTS);
    sp<IDevice> result;
    const char* moduleName = deviceToString(device);
    if (moduleName != nullptr) {
        int halStatus = loadAudioInterface(moduleName, &halDevice);//加载audio interface
        if (halStatus == OK) {
            if (device == IDevicesFactory::Device::PRIMARY) {
                result = new PrimaryDevice(halDevice);
            } else {
                result = new ::android::hardware::audio::V2_0::implementation::
                    Device(halDevice);
            }
            retval = Result::OK;
        } else if (halStatus == -EINVAL) {
            retval = Result::NOT_INITIALIZED;
        }
    }
    _hidl_cb(retval, result);//将加载的设备通过回调匿名方法传递回去
    return Void();
}

int DevicesFactory::loadAudioInterface(const char *if_name, audio_hw_device_t **dev)
{
    const hw_module_t *mod;
    int rc;
	//在system/lib/hw/等目录下查找对应的动态库并加载
    rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
	//打开对应的device,并获取hw_device_t指针类型的设备对象
    rc = audio_hw_device_open(mod, dev);
    ......
}

  hw_get_module_by_class  hardware/libhardware/hardware.c

snprintf(prop_name, sizeof(prop_name), "ro.hardware.%s", name);
[ro.hardware.audio.primary]: [goldfish]

openOutput  frameworks/av/services/audiopolicy/service/AudioPolicyClientImpl.cpp

打开输出设备

status_t AudioPolicyService::AudioPolicyClient::openOutput(audio_module_handle_t module,
                                                           audio_io_handle_t *output,
                                                           audio_config_t *config,
                                                           audio_devices_t *devices,
                                                           const String8& address,
                                                           uint32_t *latencyMs,
                                                           audio_output_flags_t flags)
{
    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    if (af == 0) {
        ALOGW("%s: could not get AudioFlinger", __func__);
        return PERMISSION_DENIED;
    }
    return af->openOutput(module, output, config, devices, address, latencyMs, flags);
}

这里直接调用了AudioFlinger::openOutput()。

  frameworks/av/services/audioflinger/AudioFlinger.cpp

总结3 {

构造硬件封装对象

对象中含有  audio_hw_device_t  结构体

}

  AudioHwDevice参见 https://mp.csdn.net/mp_blog/creation/editor/118528729 3.对硬件的封装:

  MixerThread 表明声明来源是多种多样的混合播放  放入mPlaybackThreads数组中

  flags来源 /vendor/etc/audio_policy.conf 加载 或者 /system/etc/audio_policy.conf 中配置

status_t AudioFlinger::openOutput(audio_module_handle_t module,
                                  audio_io_handle_t *output,
                                  audio_config_t *config,
                                  audio_devices_t *devices,
                                  const String8& address,
                                  uint32_t *latencyMs,
                                  audio_output_flags_t flags)
{
	......
    sp<ThreadBase> thread = openOutput_l(module, output, config, *devices, address, flags);
	......
}

sp<AudioFlinger::ThreadBase> AudioFlinger::openOutput_l(audio_module_handle_t module,
                                                            audio_io_handle_t *output,
                                                            audio_config_t *config,
                                                            audio_devices_t devices,
                                                            const String8& address,
                                                            audio_output_flags_t flags)
{
	//查找合适的设备并打开
    //关于这个AudioHwDevice参见上方链接
    AudioHwDevice *outHwDev = findSuitableHwDev_l(module, devices);
	......
    AudioStreamOut *outputStream = NULL;
    //在硬件设备上打开一个输出流
    status_t status = outHwDev->openOutputStream(
            &outputStream,
            *output,
            devices,
            flags,
            config,
            address.string());

    mHardwareStatus = AUDIO_HW_IDLE;

    if (status == NO_ERROR) {
        if (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) {
            sp<MmapPlaybackThread> thread =
                    new MmapPlaybackThread(this, *output, outHwDev, outputStream,
                                          devices, AUDIO_DEVICE_NONE, mSystemReady);
            mMmapThreads.add(*output, thread);
            ALOGV("openOutput_l() created mmap playback thread: ID %d thread %p",
                  *output, thread.get());
            return thread;
        } else {
            sp<PlaybackThread> thread;
            if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
	            //AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD音频流,创建OffloadThread实例
                thread = new OffloadThread(this, outputStream, *output, devices, mSystemReady);
                ALOGV("openOutput_l() created offload output: ID %d thread %p",
                      *output, thread.get());
            } else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT)
                    || !isValidPcmSinkFormat(config->format)
                    || !isValidPcmSinkChannelMask(config->channel_mask)) {
                //若是AUDIO_OUTPUT_FLAG_DIRECT音频,则创建DirectOutputThread实例    
                thread = new DirectOutputThread(this, outputStream, *output, devices, mSystemReady);
                ALOGV("openOutput_l() created direct output: ID %d thread %p",
                      *output, thread.get());
            } else {
	            //其他音频流,则创建MixerThread实例  一般来说都创建这个线程
                thread = new MixerThread(this, outputStream, *output, devices, mSystemReady);
                ALOGV("openOutput_l() created mixer output: ID %d thread %p",
                      *output, thread.get());
            }
            mPlaybackThreads.add(*output, thread);
            return thread;
        }
    }

    return 0;
}

分析构造器

AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)

根据配置文件得到mHwModules后遍历这个数组 

for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)

在遍历中根据每个mOutputProfiles得到IOProfile配置文件参数

const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j];

 根据IOProfile得到硬件

audio_devices_t profileType = outProfile->getSupportedDevicesType();

 根据IOProfile得到输出描述符outputDesc

sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
                                                                                 mpClientInterface);

 打开output得到一个output整数

status_t status = mpClientInterface->openOutput(outProfile->getModuleHandle(),
                                                            &output,
                                                            &config,
                                                            &outputDesc->mDevice,
                                                            address,
                                                            &outputDesc->mLatency,
                                                            outputDesc->mFlags);

 把output整数和输出描述符outputDesc放在output数组中

addOutput(output, outputDesc);

void AudioPolicyManager::addOutput(audio_io_handle_t output, const sp<SwAudioOutputDescriptor>& outputDesc)
{
    outputDesc->setIoHandle(output);
    mOutputs.add(output, outputDesc);
    updateMono(output); // update mono status when adding to output list
    selectOutputForMusicEffects();
    nextAudioPortGeneration();
}

 总结1 {

        mOutputs  表示已经打开的output

        可以根据output整数     找到打开的output 

                                              找到对应的播放线程mPlaybackThreads 

                                              找到输出描述符outputDesc

        加载配置文件过后会得到一个mHwModules

  mHwModules --> HwModule(集合) -->  {   .name

                                                                     .mOutputProfiles(一个/多个Output配置 IOProfile)

                                                                     .mInputProfiles(一个/多个Input配置)         }

   IOProfile  来自配置的文件的参数

}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值