From

AudioPolicyService是策略的制定者,比如什么时候打开音频接口设备、某种Stream类型的音频对应什么设备等等。而AudioFlinger则是策略的执行者,例如具体如何与音频设备通信,如何维护现有系统中的音频设备,以及多个音频流的混音如何处理等等都得由它来完成。AudioPolicyService根据用户配置来指导AudioFlinger加载设备接口,起到路由功能。

深入剖析Android音频之AudioPolicyService

AudioPolicyService启动过程

AudioPolicyService服务运行在mediaserver进程中,随着mediaserver进程启动而启动。

frameworks\av\media\mediaserver\ Main_mediaserver.cpp

[cpp] view plain copy

  1. int main(int argc, char** argv)  
  2. {  
  3.     sp<ProcessState> proc(ProcessState::self());  
  4.     sp<IServiceManager> sm = defaultServiceManager();  
  5.     ALOGI("ServiceManager: %p", sm.get());  
  6.     VolumeManager::instantiate(); // volumemanager have to be started before audioflinger  
  7.     AudioFlinger::instantiate();  
  8.     MediaPlayerService::instantiate();  
  9.     CameraService::instantiate();  
  10.     AudioPolicyService::instantiate();  
  11.     ProcessState::self()->startThreadPool();  
  12.     IPCThreadState::self()->joinThreadPool();  
  13. }  
 
  1. int main(int argc, char** argv)

  2. {

  3. sp<ProcessState> proc(ProcessState::self());

  4. sp<IServiceManager> sm = defaultServiceManager();

  5. ALOGI("ServiceManager: %p", sm.get());

  6. VolumeManager::instantiate(); // volumemanager have to be started before audioflinger

  7. AudioFlinger::instantiate();

  8. MediaPlayerService::instantiate();

  9. CameraService::instantiate();

  10. AudioPolicyService::instantiate();

  11. ProcessState::self()->startThreadPool();

  12. IPCThreadState::self()->joinThreadPool();

  13. }

AudioPolicyService继承了模板类BinderService,该类用于注册native service。

frameworks\native\include\binder\ BinderService.h

[cpp] view plain copy

  1. template<typename SERVICE>  
  2. class BinderService  
  3. {  
  4. public:  
  5.     static status_t publish(bool allowIsolated = false) {  
  6.         sp<IServiceManager> sm(defaultServiceManager());  
  7.         return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);  
  8.     }  
  9.     static void instantiate() { publish(); }  
  10. };  
 
  1. template<typename SERVICE>

  2. class BinderService

  3. {

  4. public:

  5. static status_t publish(bool allowIsolated = false) {

  6. sp<IServiceManager> sm(defaultServiceManager());

  7. return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);

  8. }

  9. static void instantiate() { publish(); }

  10. };

BinderService是一个模板类,该类的publish函数就是完成向ServiceManager注册服务。

[cpp] view plain copy

  1. static const char *getServiceName() { return "media.audio_policy"; }  
static const char *getServiceName() { return "media.audio_policy"; }

AudioPolicyService注册名为media.audio_policy的服务。

[cpp] view plain copy

  1. AudioPolicyService::AudioPolicyService()  
  2.     : BnAudioPolicyService() , mpAudioPolicyDev(NULL) , mpAudioPolicy(NULL)  
  3. {  
  4.     char value[PROPERTY_VALUE_MAX];  
  5.     const struct hw_module_t *module;  
  6.     int forced_val;  
  7.     int rc;  
  8.     Mutex::Autolock _l(mLock);  
  9.     // start tone playback thread  
  10.     mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);  
  11.     // start audio commands thread  
  12.     mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);  
  13.     // start output activity command thread  
  14.     mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);  
  15.     /* instantiate the audio policy manager */  
  16.     /* 加载audio_policy.default.so库得到audio_policy_module模块 */  
  17.     rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);  
  18.     if (rc)  
  19.         return;  
  20.     /* 通过audio_policy_module模块打开audio_policy_device设备 */  
  21.     rc = audio_policy_dev_open(module, &mpAudioPolicyDev);  
  22.     ALOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc));  
  23.     if (rc)  
  24.         return;  
  25.     //通过audio_policy_device设备创建audio_policy  
  26.     rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,  
  27.                                                &mpAudioPolicy);  
  28.     ALOGE_IF(rc, "couldn't create audio policy (%s)", strerror(-rc));  
  29.     if (rc)  
  30.         return;  
  31.     rc = mpAudioPolicy->init_check(mpAudioPolicy);  
  32.     ALOGE_IF(rc, "couldn't init_check the audio policy (%s)", strerror(-rc));  
  33.     if (rc)  
  34.         return;  
  35.     /* SPRD: maybe set this property better, but here just change the default value @{ */  
  36.     property_get("ro.camera.sound.forced", value, "1");  
  37.     forced_val = strtol(value, NULL, 0);  
  38.     ALOGV("setForceUse() !forced_val=%d ",!forced_val);  
  39.     mpAudioPolicy->set_can_mute_enforced_audible(mpAudioPolicy, !forced_val);  
  40.     ALOGI("Loaded audio policy from %s (%s)", module->name, module->id);  
  41.     // 读取audio_effects.conf文件  
  42.     if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {  
  43.         loadPreProcessorConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE);  
  44.     } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {  
  45.         loadPreProcessorConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);  
  46.     }  
  47. }  
 
  1. AudioPolicyService::AudioPolicyService()

  2. : BnAudioPolicyService() , mpAudioPolicyDev(NULL) , mpAudioPolicy(NULL)

  3. {

  4. char value[PROPERTY_VALUE_MAX];

  5. const struct hw_module_t *module;

  6. int forced_val;

  7. int rc;

  8. Mutex::Autolock _l(mLock);

  9. // start tone playback thread

  10. mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);

  11. // start audio commands thread

  12. mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);

  13. // start output activity command thread

  14. mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);

  15. /* instantiate the audio policy manager */

  16. /* 加载audio_policy.default.so库得到audio_policy_module模块 */

  17. rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);

  18. if (rc)

  19. return;

  20. /* 通过audio_policy_module模块打开audio_policy_device设备 */

  21. rc = audio_policy_dev_open(module, &mpAudioPolicyDev);

  22. ALOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc));

  23. if (rc)

  24. return;

  25. //通过audio_policy_device设备创建audio_policy

  26. rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,

  27. &mpAudioPolicy);

  28. ALOGE_IF(rc, "couldn't create audio policy (%s)", strerror(-rc));

  29. if (rc)

  30. return;

  31. rc = mpAudioPolicy->init_check(mpAudioPolicy);

  32. ALOGE_IF(rc, "couldn't init_check the audio policy (%s)", strerror(-rc));

  33. if (rc)

  34. return;

  35. /* SPRD: maybe set this property better, but here just change the default value @{ */

  36. property_get("ro.camera.sound.forced", value, "1");

  37. forced_val = strtol(value, NULL, 0);

  38. ALOGV("setForceUse() !forced_val=%d ",!forced_val);

  39. mpAudioPolicy->set_can_mute_enforced_audible(mpAudioPolicy, !forced_val);

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

  41. // 读取audio_effects.conf文件

  42. if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {

  43. loadPreProcessorConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE);

  44. } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {

  45. loadPreProcessorConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);

  46. }

  47. }

  1. 创建AudioCommandThread (ApmTone、ApmAudio、ApmOutput)
  2. 加载legacy_ap_module
  3. 打开legacy_ap_device
  4. 创建legacy_audio_policy
  5. 读取audio_effects.conf

深入剖析Android音频之AudioPolicyService

创建AudioCommandThread线程

在AudioPolicyService对象构造过程中,分别创建了ApmTone、ApmAudio、ApmOutput三个AudioCommandThread线程:

1、 ApmTone用于播放tone音;

2、 ApmAudio用于执行audio命令;

3、ApmOutput用于执行输出命令;

在第一次强引用AudioCommandThread线程对象时,AudioCommandThread的onFirstRef函数被回调,在此启动线程

[cpp] view plain copy

  1. void AudioPolicyService::AudioCommandThread::onFirstRef()  
  2. {  
  3.     run(mName.string(), ANDROID_PRIORITY_AUDIO);  
  4. }  
 
  1. void AudioPolicyService::AudioCommandThread::onFirstRef()

  2. {

  3. run(mName.string(), ANDROID_PRIORITY_AUDIO);

  4. }

这里采用异步方式来执行audio command,当需要执行上表中的命令时,首先将命令投递到AudioCommandThread的mAudioCommands命令向量表中,然后通过mWaitWorkCV.signal()唤醒AudioCommandThread线程,被唤醒的AudioCommandThread线程执行完command后,又通过mWaitWorkCV.waitRelative(mLock, waitTime)睡眠等待命令到来。

加载audio_policy_module模块

audio_policy硬件抽象层动态库位于/system/lib/hw/目录下,命名为:audio_policy.$(TARGET_BOARD_PLATFORM).so。audiopolicy的硬件抽象层定义在hardware\libhardware_legacy\audio\audio_policy_hal.cpp中,AUDIO_POLICY_HARDWARE_MODULE_ID硬件抽象模块定义如下:

hardware\libhardware_legacy\audio\ audio_policy_hal.cpp【audio_policy.scx15.so】

[cpp] view plain copy

  1. struct legacy_ap_module HAL_MODULE_INFO_SYM = {  
  2.     module: {  
  3.         common: {  
  4.             tag: HARDWARE_MODULE_TAG,  
  5.             version_major: 1,  
  6.             version_minor: 0,  
  7.             id: AUDIO_POLICY_HARDWARE_MODULE_ID,  
  8.             name: "LEGACY Audio Policy HAL",  
  9.             author: "The Android Open Source Project",  
  10.             methods: &legacy_ap_module_methods,  
  11.             dso : NULL,  
  12.             reserved : {0},  
  13.         },  
  14.     },  
  15. };  
 
  1. struct legacy_ap_module HAL_MODULE_INFO_SYM = {

  2. module: {

  3. common: {

  4. tag: HARDWARE_MODULE_TAG,

  5. version_major: 1,

  6. version_minor: 0,

  7. id: AUDIO_POLICY_HARDWARE_MODULE_ID,

  8. name: "LEGACY Audio Policy HAL",

  9. author: "The Android Open Source Project",

  10. methods: &legacy_ap_module_methods,

  11. dso : NULL,

  12. reserved : {0},

  13. },

  14. },

  15. };

legacy_ap_module继承于audio_policy_module。

深入剖析Android音频之AudioPolicyService

 

 

关于hw_get_module函数加载硬件抽象层模块的过程请参考Android硬件抽象Hardware库加载过程源码分析

打开audio_policy_device设备

hardware\libhardware\include\hardware\ audio_policy.h

[cpp] view plain copy

  1. static inline int audio_policy_dev_open(const hw_module_t* module,  
  2.                                     struct audio_policy_device** device)  
  3. {  
  4.     return module->methods->open(module, AUDIO_POLICY_INTERFACE,  
  5.                                  (hw_device_t**)device);  
  6. }  
 
  1. static inline int audio_policy_dev_open(const hw_module_t* module,

  2. struct audio_policy_device** device)

  3. {

  4. return module->methods->open(module, AUDIO_POLICY_INTERFACE,

  5. (hw_device_t**)device);

  6. }

通过legacy_ap_module模块的open方法来打开一个legacy_ap_device设备。

hardware\libhardware_legacy\audio\ audio_policy_hal.cpp

[cpp] view plain copy

  1. static int legacy_ap_dev_open(const hw_module_t* module, const char* name,  
  2.                                     hw_device_t** device)  
  3. {  
  4.     struct legacy_ap_device *dev;  
  5.     if (strcmp(name, AUDIO_POLICY_INTERFACE) != 0)  
  6.         return -EINVAL;  
  7.     dev = (struct legacy_ap_device *)calloc(1, sizeof(*dev));  
  8.     if (!dev)  
  9.         return -ENOMEM;  
  10.     dev->device.common.tag = HARDWARE_DEVICE_TAG;  
  11.     dev->device.common.version = 0;  
  12.     dev->device.common.module = const_cast<hw_module_t*>(module);  
  13.     dev->device.common.close = legacy_ap_dev_close;  
  14.     dev->device.create_audio_policy = create_legacy_ap;  
  15.     dev->device.destroy_audio_policy = destroy_legacy_ap;  
  16.     *device = &dev->device.common;  
  17.     return 0;  
  18. }  
 
  1. static int legacy_ap_dev_open(const hw_module_t* module, const char* name,

  2. hw_device_t** device)

  3. {

  4. struct legacy_ap_device *dev;

  5. if (strcmp(name, AUDIO_POLICY_INTERFACE) != 0)

  6. return -EINVAL;

  7. dev = (struct legacy_ap_device *)calloc(1, sizeof(*dev));

  8. if (!dev)

  9. return -ENOMEM;

  10. dev->device.common.tag = HARDWARE_DEVICE_TAG;

  11. dev->device.common.version = 0;

  12. dev->device.common.module = const_cast<hw_module_t*>(module);

  13. dev->device.common.close = legacy_ap_dev_close;

  14. dev->device.create_audio_policy = create_legacy_ap;

  15. dev->device.destroy_audio_policy = destroy_legacy_ap;

  16. *device = &dev->device.common;

  17. return 0;

  18. }

打开得到一个legacy_ap_device设备,通过该抽象设备可以创建一个audio_policy对象。

深入剖析Android音频之AudioPolicyService

创建audio_policy对象

在打开legacy_ap_device设备时,该设备的create_audio_policy成员初始化为create_legacy_ap函数指针,我们通过legacy_ap_device设备可以创建一个legacy_audio_policy对象。

[cpp] view plain copy

  1. rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,  
  2.                                                &mpAudioPolicy);  
 
  1. rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,

  2. &mpAudioPolicy);

这里通过audio_policy_device设备创建audio策略对象

深入剖析Android音频之AudioPolicyService

hardware\libhardware_legacy\audio\ audio_policy_hal.cpp

[cpp] view plain copy

  1. static int create_legacy_ap(const struct audio_policy_device *device,  
  2.                             struct audio_policy_service_ops *aps_ops,  
  3.                             void *service,  
  4.                             struct audio_policy **ap)  
  5. {  
  6.     struct legacy_audio_policy *lap;  
  7.     int ret;  
  8.     if (!service || !aps_ops)  
  9.         return -EINVAL;  
  10.     lap = (struct legacy_audio_policy *)calloc(1, sizeof(*lap));  
  11.     if (!lap)  
  12.         return -ENOMEM;  
  13. lap->policy.set_device_connection_state = ap_set_device_connection_state;  
  14. …  
  15.     lap->policy.dump = ap_dump;  
  16.     lap->policy.is_offload_supported = ap_is_offload_supported;  
  17.     lap->service = service;  
  18.     lap->aps_ops = aps_ops;  
  19.     lap->service_client = new AudioPolicyCompatClient(aps_ops, service);  
  20.     if (!lap->service_client) {  
  21.         ret = -ENOMEM;  
  22.         goto err_new_compat_client;  
  23.     }  
  24.     lap->apm = createAudioPolicyManager(lap->service_client);  
  25.     if (!lap->apm) {  
  26.         ret = -ENOMEM;  
  27.         goto err_create_apm;  
  28.     }  
  29.     *ap = &lap->policy;  
  30.     return 0;  
  31. err_create_apm:  
  32.     delete lap->service_client;  
  33. err_new_compat_client:  
  34.     free(lap);  
  35.     *ap = NULL;  
  36.     return ret;  
  37. }  
 
  1. static int create_legacy_ap(const struct audio_policy_device *device,

  2. struct audio_policy_service_ops *aps_ops,

  3. void *service,

  4. struct audio_policy **ap)

  5. {

  6. struct legacy_audio_policy *lap;

  7. int ret;

  8. if (!service || !aps_ops)

  9. return -EINVAL;

  10. lap = (struct legacy_audio_policy *)calloc(1, sizeof(*lap));

  11. if (!lap)

  12. return -ENOMEM;

  13. lap->policy.set_device_connection_state = ap_set_device_connection_state;

  14. lap->policy.dump = ap_dump;

  15. lap->policy.is_offload_supported = ap_is_offload_supported;

  16. lap->service = service;

  17. lap->aps_ops = aps_ops;

  18. lap->service_client = new AudioPolicyCompatClient(aps_ops, service);

  19. if (!lap->service_client) {

  20. ret = -ENOMEM;

  21. goto err_new_compat_client;

  22. }

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

  24. if (!lap->apm) {

  25. ret = -ENOMEM;

  26. goto err_create_apm;

  27. }

  28. *ap = &lap->policy;

  29. return 0;

  30. err_create_apm:

  31. delete lap->service_client;

  32. err_new_compat_client:

  33. free(lap);

  34. *ap = NULL;

  35. return ret;

  36. }

audio_policy实现在audio_policy_hal.cpp中,audio_policy_service_ops实现在AudioPolicyService.cpp中。create_audio_policy()函数就是创建并初始化一个legacy_audio_policy对象。

深入剖析Android音频之AudioPolicyService

深入剖析Android音频之AudioPolicyService

audio_policy与AudioPolicyService、AudioPolicyCompatClient之间的关系如下:

深入剖析Android音频之AudioPolicyService

AudioPolicyClient创建

hardware\libhardware_legacy\audio\ AudioPolicyCompatClient.h

[cpp] view plain copy

  1. AudioPolicyCompatClient(struct audio_policy_service_ops *serviceOps,void *service) :  
  2.         mServiceOps(serviceOps) , mService(service) {}  
 
  1. AudioPolicyCompatClient(struct audio_policy_service_ops *serviceOps,void *service) :

  2. mServiceOps(serviceOps) , mService(service) {}

AudioPolicyCompatClient是对audio_policy_service_ops的封装类,对外提供audio_policy_service_ops数据结构中定义的接口。

AudioPolicyManager创建

[cpp] view plain copy

  1. extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)  
  2. {  
  3.     ALOGI("SPRD policy manager created.");  
  4.     return new AudioPolicyManagerSPRD(clientInterface);  
  5. }  
 
  1. extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)

  2. {

  3. ALOGI("SPRD policy manager created.");

  4. return new AudioPolicyManagerSPRD(clientInterface);

  5. }

使用AudioPolicyClientInterface对象来构造AudioPolicyManagerSPRD对象,AudioPolicyManagerSPRD继承于AudioPolicyManagerBase,而AudioPolicyManagerBase又继承于AudioPolicyInterface。

深入剖析Android音频之AudioPolicyService

hardware\libhardware_legacy\audio\ AudioPolicyManagerBase.cpp

[cpp] view plain copy

  1. AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface)  
  2.     :  
  3. #ifdef AUDIO_POLICY_TEST  
  4.     Thread(false),  
  5. #endif //AUDIO_POLICY_TEST  
  6.     //变量初始化  
  7.     mPrimaryOutput((audio_io_handle_t)0),  
  8.     mAvailableOutputDevices(AUDIO_DEVICE_NONE),  
  9.     mPhoneState(AudioSystem::MODE_NORMAL),  
  10.     mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),  
  11.     mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0),  
  12.     mA2dpSuspended(false), mHasA2dp(false), mHasUsb(false), mHasRemoteSubmix(false),  
  13.     mSpeakerDrcEnabled(false), mFmOffGoing(false)  
  14. {  
  15.     //引用AudioPolicyCompatClient对象,这样音频管理器AudioPolicyManager就可以使用audio_policy_service_ops中的接口  
  16.     mpClientInterface = clientInterface;  
  17.     for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) {  
  18.         mForceUse[i] = AudioSystem::FORCE_NONE;  
  19.     }  
  20.     mA2dpDeviceAddress = String8("");  
  21.     mScoDeviceAddress = String8("");  
  22.     mUsbCardAndDevice = String8("");  
  23.     /** 
  24.      * 优先加载/vendor/etc/audio_policy.conf配置文件,如果该配置文件不存在,则 
  25.      * 加载/system/etc/audio_policy.conf配置文件,如果该文件还是不存在,则通过 
  26.      * 函数defaultAudioPolicyConfig()来设置默认音频接口 
  27.      */  
  28.     if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) {  
  29.         if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) {  
  30.             ALOGE("could not load audio policy configuration file, setting defaults");  
  31.             defaultAudioPolicyConfig();  
  32.         }  
  33.     }  
  34.     //设置各种音频流对应的音量调节点,must be done after reading the policy  
  35.     initializeVolumeCurves();  
  36.     // open all output streams needed to access attached devices  
  37.     for (size_t i = 0; i < mHwModules.size(); i++) {  
  38.         //通过名称打开对应的音频接口硬件抽象库  
  39.         mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName);  
  40.         if (mHwModules[i]->mHandle == 0) {  
  41.             ALOGW("could not open HW module %s", mHwModules[i]->mName);  
  42.             continue;  
  43.         }  
  44.         // open all output streams needed to access attached devices  
  45.         // except for direct output streams that are only opened when they are actually  
  46.         // required by an app.  
  47.         for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)  
  48.         {  
  49.             const IOProfile *outProfile = mHwModules[i]->mOutputProfiles[j];  
  50.             //打开mAttachedOutputDevices对应的输出  
  51.             if ((outProfile->mSupportedDevices & mAttachedOutputDevices) &&  
  52.                     ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0)) {  
  53.                 //将输出IOProfile封装为AudioOutputDescriptor对象  
  54.                 AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(outProfile);  
  55.                 //设置当前音频接口的默认输出设备  
  56.                 outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice & outProfile->mSupportedDevices);  
  57.                 //打开输出,在AudioFlinger中创建PlaybackThread线程,并返回该线程的id  
  58.                 audio_io_handle_t output = mpClientInterface->openOutput(  
  59.                                                 outProfile->mModule->mHandle,  
  60.                                                 &outputDesc->mDevice,  
  61.                                                 &outputDesc->mSamplingRate,  
  62.                                                 &outputDesc->mFormat,  
  63.                                                 &outputDesc->mChannelMask,  
  64.                                                 &outputDesc->mLatency,  
  65.                                                 outputDesc->mFlags);  
  66.                 if (output == 0) {  
  67.                     delete outputDesc;  
  68.                 } else {  
  69.                     //设置可以使用的输出设备为mAttachedOutputDevices  
  70.                     mAvailableOutputDevices =(audio_devices_t)(mAvailableOutputDevices | (outProfile->mSupportedDevices & mAttachedOutputDevices));  
  71.                     if (mPrimaryOutput == 0 && outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {  
  72.                         mPrimaryOutput = output;  
  73.                     }  
  74.                     //将输出描述符对象AudioOutputDescriptor及创建的PlaybackThread线程id以键值对形式保存  
  75.                     addOutput(output, outputDesc);  
  76.                     //设置默认输出设备  
  77.                     setOutputDevice(output,(audio_devices_t)(mDefaultOutputDevice & outProfile->mSupportedDevices),true);  
  78.                 }  
  79.             }  
  80.         }  
  81.     }  
  82.     ALOGE_IF((mAttachedOutputDevices & ~mAvailableOutputDevices),  
  83.              "Not output found for attached devices %08x",  
  84.              (mAttachedOutputDevices & ~mAvailableOutputDevices));  
  85.     ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output");  
  86.     updateDevicesAndOutputs();  
  87.   
  88.     //  add for bug158794 start  
  89.     char bootvalue[PROPERTY_VALUE_MAX];  
  90.     // prop sys.boot_completed will set 1 when system ready (ActivityManagerService.java)...  
  91.     property_get("sys.boot_completed", bootvalue, "");  
  92.     if (strncmp("1", bootvalue, 1) != 0) {  
  93.         startReadingThread();  
  94.     }  
  95.     // add for bug158794 end  
  96.   
  97. #ifdef AUDIO_POLICY_TEST  
  98.     ...  
  99. #endif //AUDIO_POLICY_TEST  
  100. }  
 
  1. AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface)

  2. :

  3. #ifdef AUDIO_POLICY_TEST

  4. Thread(false),

  5. #endif //AUDIO_POLICY_TEST

  6. //变量初始化

  7. mPrimaryOutput((audio_io_handle_t)0),

  8. mAvailableOutputDevices(AUDIO_DEVICE_NONE),

  9. mPhoneState(AudioSystem::MODE_NORMAL),

  10. mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),

  11. mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0),

  12. mA2dpSuspended(false), mHasA2dp(false), mHasUsb(false), mHasRemoteSubmix(false),

  13. mSpeakerDrcEnabled(false), mFmOffGoing(false)

  14. {

  15. //引用AudioPolicyCompatClient对象,这样音频管理器AudioPolicyManager就可以使用audio_policy_service_ops中的接口

  16. mpClientInterface = clientInterface;

  17. for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) {

  18. mForceUse[i] = AudioSystem::FORCE_NONE;

  19. }

  20. mA2dpDeviceAddress = String8("");

  21. mScoDeviceAddress = String8("");

  22. mUsbCardAndDevice = String8("");

  23. /**

  24. * 优先加载/vendor/etc/audio_policy.conf配置文件,如果该配置文件不存在,则

  25. * 加载/system/etc/audio_policy.conf配置文件,如果该文件还是不存在,则通过

  26. * 函数defaultAudioPolicyConfig()来设置默认音频接口

  27. */

  28. if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) {

  29. if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) {

  30. ALOGE("could not load audio policy configuration file, setting defaults");

  31. defaultAudioPolicyConfig();

  32. }

  33. }

  34. //设置各种音频流对应的音量调节点,must be done after reading the policy

  35. initializeVolumeCurves();

  36. // open all output streams needed to access attached devices

  37. for (size_t i = 0; i < mHwModules.size(); i++) {

  38. //通过名称打开对应的音频接口硬件抽象库

  39. mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName);

  40. if (mHwModules[i]->mHandle == 0) {

  41. ALOGW("could not open HW module %s", mHwModules[i]->mName);

  42. continue;

  43. }

  44. // open all output streams needed to access attached devices

  45. // except for direct output streams that are only opened when they are actually

  46. // required by an app.

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

  48. {

  49. const IOProfile *outProfile = mHwModules[i]->mOutputProfiles[j];

  50. //打开mAttachedOutputDevices对应的输出

  51. if ((outProfile->mSupportedDevices & mAttachedOutputDevices) &&

  52. ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0)) {

  53. //将输出IOProfile封装为AudioOutputDescriptor对象

  54. AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(outProfile);

  55. //设置当前音频接口的默认输出设备

  56. outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice & outProfile->mSupportedDevices);

  57. //打开输出,在AudioFlinger中创建PlaybackThread线程,并返回该线程的id

  58. audio_io_handle_t output = mpClientInterface->openOutput(

  59. outProfile->mModule->mHandle,

  60. &outputDesc->mDevice,

  61. &outputDesc->mSamplingRate,

  62. &outputDesc->mFormat,

  63. &outputDesc->mChannelMask,

  64. &outputDesc->mLatency,

  65. outputDesc->mFlags);

  66. if (output == 0) {

  67. delete outputDesc;

  68. } else {

  69. //设置可以使用的输出设备为mAttachedOutputDevices

  70. mAvailableOutputDevices =(audio_devices_t)(mAvailableOutputDevices | (outProfile->mSupportedDevices & mAttachedOutputDevices));

  71. if (mPrimaryOutput == 0 && outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {

  72. mPrimaryOutput = output;

  73. }

  74. //将输出描述符对象AudioOutputDescriptor及创建的PlaybackThread线程id以键值对形式保存

  75. addOutput(output, outputDesc);

  76. //设置默认输出设备

  77. setOutputDevice(output,(audio_devices_t)(mDefaultOutputDevice & outProfile->mSupportedDevices),true);

  78. }

  79. }

  80. }

  81. }

  82. ALOGE_IF((mAttachedOutputDevices & ~mAvailableOutputDevices),

  83. "Not output found for attached devices %08x",

  84. (mAttachedOutputDevices & ~mAvailableOutputDevices));

  85. ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output");

  86. updateDevicesAndOutputs();

  87.  
  88. // add for bug158794 start

  89. char bootvalue[PROPERTY_VALUE_MAX];

  90. // prop sys.boot_completed will set 1 when system ready (ActivityManagerService.java)...

  91. property_get("sys.boot_completed", bootvalue, "");

  92. if (strncmp("1", bootvalue, 1) != 0) {

  93. startReadingThread();

  94. }

  95. // add for bug158794 end

  96.  
  97. #ifdef AUDIO_POLICY_TEST

  98. ...

  99. #endif //AUDIO_POLICY_TEST

  100. }

AudioPolicyManagerBase对象构造过程中主要完成以下几个步骤:

1、  loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE)加载audio_policy.conf配置文件;

2、  initializeVolumeCurves()初始化各种音频流对应的音量调节点;

3、  加载audio policy硬件抽象库:mpClientInterface->loadHwModule(mHwModules[i]->mName)

4、  打开attached_output_devices输出:

mpClientInterface->openOutput();

5、  保存输出设备描述符对象:addOutput(output, outputDesc);

深入剖析Android音频之AudioPolicyService

读取audio_policy.conf文件

Android为每种音频接口定义了对应的硬件抽象层,且编译为单独的so库。

深入剖析Android音频之AudioPolicyService

每种音频接口定义了不同的输入输出,一个接口可以具有多个输入或者输出,每个输入输出有可以支持不同的音频设备。通过读取audio_policy.conf文件可以获取系统支持的音频接口参数。

audio_policy.conf文件定义了两种音频配置信息:

1、  当前系统支持的音频输入输出设备及默认输入输出设备;

深入剖析Android音频之AudioPolicyService

这些信息时通过global_configuration配置项来设置,在global_configuration中定义了三种音频设备信息:

attached_output_devices:已连接的输出设备;

default_output_device:默认输出设备;

attached_input_devices:已连接的输入设备;

 

1、  系统支持的音频接口信息;

audio_policy.conf定义了系统支持的所有音频接口参数信息,比如primary、a2dp、usb等,对于primary定义如下:

深入剖析Android音频之AudioPolicyService

a2dp定义:

深入剖析Android音频之AudioPolicyService

usb定义:

深入剖析Android音频之AudioPolicyService

每种音频接口包含输入输出,每种输入输出又包含多种输入输出配置,每种输入输出配置又支持多种音频设备。AudioPolicyManagerBase首先加载/vendor/etc/audio_policy.conf,如果该文件不存在,则加/system/etc/audio_policy.conf。

[cpp] view plain copy

  1. status_t AudioPolicyManagerBase::loadAudioPolicyConfig(const char *path)  
  2. {  
  3.     cnode *root;  
  4.     char *data;  
  5.     data = (char *)load_file(path, NULL);  
  6.     if (data == NULL) {  
  7.         return -ENODEV;  
  8.     }  
  9.     root = config_node("", "");  
  10.     //读取配置文件  
  11.     config_load(root, data);  
  12.     //解析global_configuration  
  13.     loadGlobalConfig(root);  
  14.     //解析audio_hw_modules  
  15.     loadHwModules(root);  
  16.     config_free(root);  
  17.     free(root);  
  18.     free(data);  
  19.     ALOGI("loadAudioPolicyConfig() loaded %s\n", path);  
  20.     return NO_ERROR;  
  21. }  
 
  1. status_t AudioPolicyManagerBase::loadAudioPolicyConfig(const char *path)

  2. {

  3. cnode *root;

  4. char *data;

  5. data = (char *)load_file(path, NULL);

  6. if (data == NULL) {

  7. return -ENODEV;

  8. }

  9. root = config_node("", "");

  10. //读取配置文件

  11. config_load(root, data);

  12. //解析global_configuration

  13. loadGlobalConfig(root);

  14. //解析audio_hw_modules

  15. loadHwModules(root);

  16. config_free(root);

  17. free(root);

  18. free(data);

  19. ALOGI("loadAudioPolicyConfig() loaded %s\n", path);

  20. return NO_ERROR;

  21. }

通过loadGlobalConfig(root)函数来读取这些全局配置信息。

[cpp] view plain copy

  1. void AudioPolicyManagerBase::loadGlobalConfig(cnode *root)  
  2. {  
  3.     cnode *node = config_find(root, GLOBAL_CONFIG_TAG);  
  4.     if (node == NULL) {  
  5.         return;  
  6.     }  
  7.     node = node->first_child;  
  8.     while (node) {  
  9.         //attached_output_devices AUDIO_DEVICE_OUT_EARPIECE  
  10.         if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) {  
  11.             mAttachedOutputDevices = parseDeviceNames((char *)node->value);  
  12.             ALOGW_IF(mAttachedOutputDevices == AUDIO_DEVICE_NONE,  
  13.                     "loadGlobalConfig() no attached output devices");  
  14.             ALOGV("loadGlobalConfig()mAttachedOutputDevices%04x", mAttachedOutputDevices);  
  15.         //default_output_device AUDIO_DEVICE_OUT_SPEAKER  
  16.         } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) {  
  17.             mDefaultOutputDevice= (audio_devices_t)stringToEnum(sDeviceNameToEnumTable,ARRAY_SIZE(sDeviceNameToEnumTable),(char *)node->value);  
  18.             ALOGW_IF(mDefaultOutputDevice == AUDIO_DEVICE_NONE,  
  19.                     "loadGlobalConfig() default device not specified");  
  20.             ALOGV("loadGlobalConfig() mDefaultOutputDevice %04x", mDefaultOutputDevice);  
  21.         //attached_input_devices AUDIO_DEVICE_IN_BUILTIN_MIC  
  22.         } else if (strcmp(ATTACHED_INPUT_DEVICES_TAG, node->name) == 0) {  
  23.             mAvailableInputDevices = parseDeviceNames((char *)node->value) & ~AUDIO_DEVICE_BIT_IN;  
  24.             ALOGV("loadGlobalConfig() mAvailableInputDevices %04x", mAvailableInputDevices);  
  25.         //speaker_drc_enabled   
  26.         } else if (strcmp(SPEAKER_DRC_ENABLED_TAG, node->name) == 0) {  
  27.             mSpeakerDrcEnabled = stringToBool((char *)node->value);  
  28.             ALOGV("loadGlobalConfig() mSpeakerDrcEnabled = %d", mSpeakerDrcEnabled);  
  29.         }  
  30.         node = node->next;  
  31.     }  
  32. }  
 
  1. void AudioPolicyManagerBase::loadGlobalConfig(cnode *root)

  2. {

  3. cnode *node = config_find(root, GLOBAL_CONFIG_TAG);

  4. if (node == NULL) {

  5. return;

  6. }

  7. node = node->first_child;

  8. while (node) {

  9. //attached_output_devices AUDIO_DEVICE_OUT_EARPIECE

  10. if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) {

  11. mAttachedOutputDevices = parseDeviceNames((char *)node->value);

  12. ALOGW_IF(mAttachedOutputDevices == AUDIO_DEVICE_NONE,

  13. "loadGlobalConfig() no attached output devices");

  14. ALOGV("loadGlobalConfig()mAttachedOutputDevices%04x", mAttachedOutputDevices);

  15. //default_output_device AUDIO_DEVICE_OUT_SPEAKER

  16. } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) {

  17. mDefaultOutputDevice= (audio_devices_t)stringToEnum(sDeviceNameToEnumTable,ARRAY_SIZE(sDeviceNameToEnumTable),(char *)node->value);

  18. ALOGW_IF(mDefaultOutputDevice == AUDIO_DEVICE_NONE,

  19. "loadGlobalConfig() default device not specified");

  20. ALOGV("loadGlobalConfig() mDefaultOutputDevice %04x", mDefaultOutputDevice);

  21. //attached_input_devices AUDIO_DEVICE_IN_BUILTIN_MIC

  22. } else if (strcmp(ATTACHED_INPUT_DEVICES_TAG, node->name) == 0) {

  23. mAvailableInputDevices = parseDeviceNames((char *)node->value) & ~AUDIO_DEVICE_BIT_IN;

  24. ALOGV("loadGlobalConfig() mAvailableInputDevices %04x", mAvailableInputDevices);

  25. //speaker_drc_enabled

  26. } else if (strcmp(SPEAKER_DRC_ENABLED_TAG, node->name) == 0) {

  27. mSpeakerDrcEnabled = stringToBool((char *)node->value);

  28. ALOGV("loadGlobalConfig() mSpeakerDrcEnabled = %d", mSpeakerDrcEnabled);

  29. }

  30. node = node->next;

  31. }

  32. }

audio_policy.conf同时定义了多个audio 接口,每一个audio 接口包含若干output和input,而每个output和input又同时支持多种输入输出模式,每种输入输出模式又支持若干种设备。

深入剖析Android音频之AudioPolicyService

通过loadHwModules ()函数来加载系统配置的所有audio 接口:

[cpp] view plain copy

  1. void AudioPolicyManagerBase::loadHwModules(cnode *root)  
  2. {  
  3.     //audio_hw_modules  
  4.     cnode *node = config_find(root, AUDIO_HW_MODULE_TAG);  
  5.     if (node == NULL) {  
  6.         return;  
  7.     }  
  8.     node = node->first_child;  
  9.     while (node) {  
  10.         ALOGV("loadHwModules() loading module %s", node->name);  
  11.         //加载音频接口  
  12.         loadHwModule(node);  
  13.         node = node->next;  
  14.     }  
  15. }  
 
  1. void AudioPolicyManagerBase::loadHwModules(cnode *root)

  2. {

  3. //audio_hw_modules

  4. cnode *node = config_find(root, AUDIO_HW_MODULE_TAG);

  5. if (node == NULL) {

  6. return;

  7. }

  8. node = node->first_child;

  9. while (node) {

  10. ALOGV("loadHwModules() loading module %s", node->name);

  11. //加载音频接口

  12. loadHwModule(node);

  13. node = node->next;

  14. }

  15. }

由于audio_policy.conf可以定义多个音频接口,因此该函数循环调用loadHwModule()来解析每个音频接口参数信息。Android定义HwModule类来描述每一个audio 接口参数,定义IOProfile类来描述输入输出模式配置。
 

深入剖析Android音频之AudioPolicyService

 

深入剖析Android音频之AudioPolicyService

到此就将audio_policy.conf文件中音频接口配置信息解析到了AudioPolicyManagerBase的成员变量mHwModules、mAttachedOutputDevices、mDefaultOutputDevice、mAvailableInputDevices中。

初始化音量调节点

音量调节点设置在Android4.1与Android4.4中的实现完全不同,在Android4.1中是通过VolumeManager服务来管理,通过devicevolume.xml文件来配置,但Android4.4取消了VolumeManager服务,将音量控制放到AudioPolicyManagerBase中。在AudioPolicyManagerBase中定义了音量调节对应的音频流描述符数组:

[cpp] view plain copy

  1. StreamDescriptor mStreams[AudioSystem::NUM_STREAM_TYPES];  
StreamDescriptor mStreams[AudioSystem::NUM_STREAM_TYPES];

initializeVolumeCurves()函数就是初始化该数组元素:

[cpp] view plain copy

  1. void AudioPolicyManagerBase::initializeVolumeCurves()  
  2. {  
  3.     for (int i = 0; i < AUDIO_STREAM_CNT; i++) {  
  4.         for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {  
  5.             mStreams[i].mVolumeCurve[j] =  
  6.                     sVolumeProfiles[i][j];  
  7.         }  
  8.     }  
  9.   
  10.     // Check availability of DRC on speaker path: if available, override some of the speaker curves  
  11.     if (mSpeakerDrcEnabled) {  
  12. mStreams[AUDIO_STREAM_SYSTEM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =  
  13.                 sDefaultSystemVolumeCurveDrc;  
  14. mStreams[AUDIO_STREAM_RING].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =  
  15.                 sSpeakerSonificationVolumeCurveDrc;  
  16. mStreams[AUDIO_STREAM_ALARM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =  
  17.                 sSpeakerSonificationVolumeCurveDrc;  
  18. mStreams[AUDIO_STREAM_NOTIFICATION].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =sSpeakerSonificationVolumeCurveDrc;  
  19.     }  
  20. }  
 
  1. void AudioPolicyManagerBase::initializeVolumeCurves()

  2. {

  3. for (int i = 0; i < AUDIO_STREAM_CNT; i++) {

  4. for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {

  5. mStreams[i].mVolumeCurve[j] =

  6. sVolumeProfiles[i][j];

  7. }

  8. }

  9.  
  10. // Check availability of DRC on speaker path: if available, override some of the speaker curves

  11. if (mSpeakerDrcEnabled) {

  12. mStreams[AUDIO_STREAM_SYSTEM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =

  13. sDefaultSystemVolumeCurveDrc;

  14. mStreams[AUDIO_STREAM_RING].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =

  15. sSpeakerSonificationVolumeCurveDrc;

  16. mStreams[AUDIO_STREAM_ALARM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =

  17. sSpeakerSonificationVolumeCurveDrc;

  18. mStreams[AUDIO_STREAM_NOTIFICATION].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =sSpeakerSonificationVolumeCurveDrc;

  19. }

  20. }

sVolumeProfiles数组定义了不同音频设备下不同音频流对应的音量调节档位,定义如下:

深入剖析Android音频之AudioPolicyService

数组元素为音量调节档位,每种模式下的音量调节都包含4个档位,定义如下:

深入剖析Android音频之AudioPolicyService

加载audio_module模块

AudioPolicyManager通过读取audio_policy.conf配置文件,可以知道系统当前支持那些音频接口以及attached的输入输出设备、默认输出设备。接下来就需要加载这些音频接口的硬件抽象库。

深入剖析Android音频之AudioPolicyService

这三中音频接口硬件抽象定义如下:

/vendor/sprd/open-source/libs/audio/audio_hw.c 【audio.primary.scx15.so】

[cpp] view plain copy

  1. struct audio_module HAL_MODULE_INFO_SYM = {  
  2.     .common = {  
  3.         .tag = HARDWARE_MODULE_TAG,  
  4.         .module_api_version = AUDIO_MODULE_API_VERSION_0_1,  
  5.         .hal_api_version = HARDWARE_HAL_API_VERSION,  
  6.         .id = AUDIO_HARDWARE_MODULE_ID,  
  7.         .name = "Spreadtrum Audio HW HAL",  
  8.         .author = "The Android Open Source Project",  
  9.         .methods = &hal_module_methods,  
  10.     },  
  11. };  
 
  1. struct audio_module HAL_MODULE_INFO_SYM = {

  2. .common = {

  3. .tag = HARDWARE_MODULE_TAG,

  4. .module_api_version = AUDIO_MODULE_API_VERSION_0_1,

  5. .hal_api_version = HARDWARE_HAL_API_VERSION,

  6. .id = AUDIO_HARDWARE_MODULE_ID,

  7. .name = "Spreadtrum Audio HW HAL",

  8. .author = "The Android Open Source Project",

  9. .methods = &hal_module_methods,

  10. },

  11. };

深入剖析Android音频之AudioPolicyService

 

external/bluetooth/bluedroid/audio_a2dp_hw/audio_a2dp_hw.c【audio.a2dp.default.so】

[cpp] view plain copy

  1. struct audio_module HAL_MODULE_INFO_SYM = {  
  2.     .common = {  
  3.         .tag = HARDWARE_MODULE_TAG,  
  4.         .version_major = 1,  
  5.         .version_minor = 0,  
  6.         .id = AUDIO_HARDWARE_MODULE_ID,  
  7.         .name = "A2DP Audio HW HAL",  
  8.         .author = "The Android Open Source Project",  
  9.         .methods = &hal_module_methods,  
  10.     },  
  11. };  
 
  1. struct audio_module HAL_MODULE_INFO_SYM = {

  2. .common = {

  3. .tag = HARDWARE_MODULE_TAG,

  4. .version_major = 1,

  5. .version_minor = 0,

  6. .id = AUDIO_HARDWARE_MODULE_ID,

  7. .name = "A2DP Audio HW HAL",

  8. .author = "The Android Open Source Project",

  9. .methods = &hal_module_methods,

  10. },

  11. };

hardware/libhardware/modules/usbaudio/audio_hw.c【audio. usb.default.so】

[cpp] view plain copy

  1. struct audio_module HAL_MODULE_INFO_SYM = {  
  2.     .common = {  
  3.         .tag = HARDWARE_MODULE_TAG,  
  4.         .module_api_version = AUDIO_MODULE_API_VERSION_0_1,  
  5.         .hal_api_version = HARDWARE_HAL_API_VERSION,  
  6.         .id = AUDIO_HARDWARE_MODULE_ID,  
  7.         .name = "USB audio HW HAL",  
  8.         .author = "The Android Open Source Project",  
  9.         .methods = &hal_module_methods,  
  10.     },  
  11. };  
 
  1. struct audio_module HAL_MODULE_INFO_SYM = {

  2. .common = {

  3. .tag = HARDWARE_MODULE_TAG,

  4. .module_api_version = AUDIO_MODULE_API_VERSION_0_1,

  5. .hal_api_version = HARDWARE_HAL_API_VERSION,

  6. .id = AUDIO_HARDWARE_MODULE_ID,

  7. .name = "USB audio HW HAL",

  8. .author = "The Android Open Source Project",

  9. .methods = &hal_module_methods,

  10. },

  11. };

AudioPolicyClientInterface提供了加载音频接口硬件抽象库的接口函数,通过前面的介绍,我们知道,AudioPolicyCompatClient通过代理audio_policy_service_ops实现AudioPolicyClientInterface接口。

hardware\libhardware_legacy\audio\ AudioPolicyCompatClient.cpp

[cpp] view plain copy

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

  2. {

  3. return mServiceOps->load_hw_module(mService, moduleName);

  4. }

AudioPolicyCompatClient将音频模块加载工作交给audio_policy_service_ops

frameworks\av\services\audioflinger\ AudioPolicyService.cpp

[cpp] view plain copy

  1. static audio_module_handle_t aps_load_hw_module(void *service,const char *name)  
  2. {  
  3.     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();  
  4.     if (af == 0) {  
  5.         ALOGW("%s: could not get AudioFlinger", __func__);  
  6.         return 0;  
  7.     }  
  8.     return af->loadHwModule(name);  
  9. }  
 
  1. static audio_module_handle_t aps_load_hw_module(void *service,const char *name)

  2. {

  3. sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();

  4. if (af == 0) {

  5. ALOGW("%s: could not get AudioFlinger", __func__);

  6. return 0;

  7. }

  8. return af->loadHwModule(name);

  9. }

AudioPolicyService又将其转交给AudioFlinger

frameworks\av\services\audioflinger\ AudioFlinger.cpp

[cpp] view plain copy

  1. audio_module_handle_t AudioFlinger::loadHwModule(const char *name)  
  2. {  
  3.     if (!settingsAllowed()) {  
  4.         return 0;  
  5.     }  
  6.     Mutex::Autolock _l(mLock);  
  7.     return loadHwModule_l(name);  
  8. }  
 
  1. audio_module_handle_t AudioFlinger::loadHwModule(const char *name)

  2. {

  3. if (!settingsAllowed()) {

  4. return 0;

  5. }

  6. Mutex::Autolock _l(mLock);

  7. return loadHwModule_l(name);

  8. }

深入剖析Android音频之AudioPolicyService

 

[cpp] view plain copy

  1. audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)  
  2. {  
  3.     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {  
  4.         if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {  
  5.             ALOGW("loadHwModule() module %s already loaded", name);  
  6.             return mAudioHwDevs.keyAt(i);  
  7.         }  
  8.     }  
  9. audio_hw_device_t *dev;   
  10. //加载音频接口对应的so库,得到对应的音频接口设备audio_hw_device_t  
  11.     int rc = load_audio_interface(name, &dev);  
  12.     if (rc) {  
  13.         ALOGI("loadHwModule() error %d loading module %s ", rc, name);  
  14.         return 0;  
  15.     }  
  16.     mHardwareStatus = AUDIO_HW_INIT;  
  17.     rc = dev->init_check(dev);  
  18.     mHardwareStatus = AUDIO_HW_IDLE;  
  19.     if (rc) {  
  20.         ALOGI("loadHwModule() init check error %d for module %s ", rc, name);  
  21.         return 0;  
  22.     }  
  23.     if ((mMasterVolumeSupportLvl != MVS_NONE) &&  
  24.         (NULL != dev->set_master_volume)) {  
  25.         AutoMutex lock(mHardwareLock);  
  26.         mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;  
  27.         dev->set_master_volume(dev, mMasterVolume);  
  28.         mHardwareStatus = AUDIO_HW_IDLE;  
  29.     }  
  30.     audio_module_handle_t handle = nextUniqueId();  
  31.     mAudioHwDevs.add(handle, new AudioHwDevice(name, dev));  
  32.     ALOGI("loadHwModule() Loaded %s audio interface from %s (%s) handle %d",  
  33.           name, dev->common.module->name, dev->common.module->id, handle);  
  34.     return handle;  
  35. }  
 
  1. audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)

  2. {

  3. for (size_t i = 0; i < mAudioHwDevs.size(); i++) {

  4. if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {

  5. ALOGW("loadHwModule() module %s already loaded", name);

  6. return mAudioHwDevs.keyAt(i);

  7. }

  8. }

  9. audio_hw_device_t *dev;

  10. //加载音频接口对应的so库,得到对应的音频接口设备audio_hw_device_t

  11. int rc = load_audio_interface(name, &dev);

  12. if (rc) {

  13. ALOGI("loadHwModule() error %d loading module %s ", rc, name);

  14. return 0;

  15. }

  16. mHardwareStatus = AUDIO_HW_INIT;

  17. rc = dev->init_check(dev);

  18. mHardwareStatus = AUDIO_HW_IDLE;

  19. if (rc) {

  20. ALOGI("loadHwModule() init check error %d for module %s ", rc, name);

  21. return 0;

  22. }

  23. if ((mMasterVolumeSupportLvl != MVS_NONE) &&

  24. (NULL != dev->set_master_volume)) {

  25. AutoMutex lock(mHardwareLock);

  26. mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;

  27. dev->set_master_volume(dev, mMasterVolume);

  28. mHardwareStatus = AUDIO_HW_IDLE;

  29. }

  30. audio_module_handle_t handle = nextUniqueId();

  31. mAudioHwDevs.add(handle, new AudioHwDevice(name, dev));

  32. ALOGI("loadHwModule() Loaded %s audio interface from %s (%s) handle %d",

  33. name, dev->common.module->name, dev->common.module->id, handle);

  34. return handle;

  35. }

函数首先加载系统定义的音频接口对应的so库,并打开该音频接口的抽象硬件设备audio_hw_device_t,为每个音频接口设备生成独一无二的ID号,同时将打开的音频接口设备封装为AudioHwDevice对象,将系统中所有的音频接口设备保存到AudioFlinger的成员变量mAudioHwDevs中。

深入剖析Android音频之AudioPolicyService

函数load_audio_interface根据音频接口名称来打开抽象的音频接口设备audio_hw_device_t。

[cpp] view plain copy

  1. static int load_audio_interface(const char *if_name, audio_hw_device_t **dev)  
  2. {  
  3.     const hw_module_t *mod;  
  4. int rc;  
  5. //根据名字加载audio_module模块  
  6.     rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);  
  7.     ALOGE_IF(rc, "%s couldn't load audio hw module %s.%s (%s)", __func__,  
  8.                  AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));  
  9.     if (rc) {  
  10.         goto out;  
  11. }  
  12. //打开audio_device设备  
  13.     rc = audio_hw_device_open(mod, dev);  
  14.     ALOGE_IF(rc, "%s couldn't open audio hw device in %s.%s (%s)", __func__,  
  15.                  AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));  
  16.     if (rc) {  
  17.         goto out;  
  18.     }  
  19.     if ((*dev)->common.version != AUDIO_DEVICE_API_VERSION_CURRENT) {  
  20.         ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);  
  21.         rc = BAD_VALUE;  
  22.         goto out;  
  23.     }  
  24.     return 0;  
  25. out:  
  26.     *dev = NULL;  
  27.     return rc;  
  28. }  
 
  1. static int load_audio_interface(const char *if_name, audio_hw_device_t **dev)

  2. {

  3. const hw_module_t *mod;

  4. int rc;

  5. //根据名字加载audio_module模块

  6. rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);

  7. ALOGE_IF(rc, "%s couldn't load audio hw module %s.%s (%s)", __func__,

  8. AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));

  9. if (rc) {

  10. goto out;

  11. }

  12. //打开audio_device设备

  13. rc = audio_hw_device_open(mod, dev);

  14. ALOGE_IF(rc, "%s couldn't open audio hw device in %s.%s (%s)", __func__,

  15. AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));

  16. if (rc) {

  17. goto out;

  18. }

  19. if ((*dev)->common.version != AUDIO_DEVICE_API_VERSION_CURRENT) {

  20. ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);

  21. rc = BAD_VALUE;

  22. goto out;

  23. }

  24. return 0;

  25. out:

  26. *dev = NULL;

  27. return rc;

  28. }

hardware\libhardware\include\hardware\ Audio.h

[cpp] view plain copy

  1. static inline int audio_hw_device_open(const struct hw_module_t* module,  
  2.                                        struct audio_hw_device** device)  
  3. {  
  4.     return module->methods->open(module, AUDIO_HARDWARE_INTERFACE,  
  5.                                  (struct hw_device_t**)device);  
  6. }  
 
  1. static inline int audio_hw_device_open(const struct hw_module_t* module,

  2. struct audio_hw_device** device)

  3. {

  4. return module->methods->open(module, AUDIO_HARDWARE_INTERFACE,

  5. (struct hw_device_t**)device);

  6. }

hardware\libhardware_legacy\audio\ audio_hw_hal.cpp

[cpp] view plain copy

  1. static int legacy_adev_open(const hw_module_t* module, const char* name,  
  2.                             hw_device_t** device)  
  3. {  
  4.     struct legacy_audio_device *ladev;  
  5.     int ret;  
  6.     if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)  
  7.         return -EINVAL;  
  8.     ladev = (struct legacy_audio_device *)calloc(1, sizeof(*ladev));  
  9.     if (!ladev)  
  10.         return -ENOMEM;  
  11.     ladev->device.common.tag = HARDWARE_DEVICE_TAG;  
  12.     ladev->device.common.version = AUDIO_DEVICE_API_VERSION_1_0;  
  13.     ladev->device.common.module = const_cast<hw_module_t*>(module);  
  14.     ladev->device.common.close = legacy_adev_close;  
  15.     ladev->device.get_supported_devices = adev_get_supported_devices;  
  16. …  
  17. ladev->device.dump = adev_dump;  
  18.     ladev->hwif = createAudioHardware();  
  19.     if (!ladev->hwif) {  
  20.         ret = -EIO;  
  21.         goto err_create_audio_hw;  
  22.     }  
  23.     *device = &ladev->device.common;  
  24.     return 0;  
  25. err_create_audio_hw:  
  26.     free(ladev);  
  27.     return ret;  
  28. }  
 
  1. static int legacy_adev_open(const hw_module_t* module, const char* name,

  2. hw_device_t** device)

  3. {

  4. struct legacy_audio_device *ladev;

  5. int ret;

  6. if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)

  7. return -EINVAL;

  8. ladev = (struct legacy_audio_device *)calloc(1, sizeof(*ladev));

  9. if (!ladev)

  10. return -ENOMEM;

  11. ladev->device.common.tag = HARDWARE_DEVICE_TAG;

  12. ladev->device.common.version = AUDIO_DEVICE_API_VERSION_1_0;

  13. ladev->device.common.module = const_cast<hw_module_t*>(module);

  14. ladev->device.common.close = legacy_adev_close;

  15. ladev->device.get_supported_devices = adev_get_supported_devices;

  16. ladev->device.dump = adev_dump;

  17. ladev->hwif = createAudioHardware();

  18. if (!ladev->hwif) {

  19. ret = -EIO;

  20. goto err_create_audio_hw;

  21. }

  22. *device = &ladev->device.common;

  23. return 0;

  24. err_create_audio_hw:

  25. free(ladev);

  26. return ret;

  27. }

打开音频接口设备过程其实就是构造并初始化legacy_audio_device对象过程,legacy_audio_device数据结构关系如下:

深入剖析Android音频之AudioPolicyService

 

legacy_adev_open函数就是创建并初始化一个legacy_audio_device对象:

深入剖析Android音频之AudioPolicyService

 

到此就加载完系统定义的所有音频接口,并生成相应的数据对象,如下图所示:

深入剖析Android音频之AudioPolicyService

打开音频输出

AudioPolicyService加载完所有音频接口后,就知道了系统支持的所有音频接口参数,可以为音频输出提供决策。

深入剖析Android音频之AudioPolicyService

为了能正常播放音频数据,需要创建抽象的音频输出接口对象,打开音频输出过程如下:

[cpp] view plain copy

  1. audio_io_handle_t AudioPolicyCompatClient::openOutput(audio_module_handle_t module,  
  2.                                               audio_devices_t *pDevices,  
  3.                                               uint32_t *pSamplingRate,  
  4.                                               audio_format_t *pFormat,  
  5.                                               audio_channel_mask_t *pChannelMask,    
  6.                                               uint32_t *pLatencyMs,  
  7.                                               audio_output_flags_t flags,  
  8.                                               const audio_offload_info_t *offloadInfo)  
  9. {  
  10.     return mServiceOps->open_output_on_module(mService,module, pDevices, pSamplingRate,  
  11.                                               pFormat, pChannelMask, pLatencyMs,  
  12.                                               flags, offloadInfo);  
  13. }  
 
  1. audio_io_handle_t AudioPolicyCompatClient::openOutput(audio_module_handle_t module,

  2. audio_devices_t *pDevices,

  3. uint32_t *pSamplingRate,

  4. audio_format_t *pFormat,

  5. audio_channel_mask_t *pChannelMask,

  6. uint32_t *pLatencyMs,

  7. audio_output_flags_t flags,

  8. const audio_offload_info_t *offloadInfo)

  9. {

  10. return mServiceOps->open_output_on_module(mService,module, pDevices, pSamplingRate,

  11. pFormat, pChannelMask, pLatencyMs,

  12. flags, offloadInfo);

  13. }

 

[cpp] view plain copy

  1. static audio_io_handle_t aps_open_output_on_module(void *service,  
  2.                                           audio_module_handle_t module,  
  3.                                           audio_devices_t *pDevices,  
  4.                                           uint32_t *pSamplingRate,  
  5.                                           audio_format_t *pFormat,  
  6.                                           audio_channel_mask_t *pChannelMask,  
  7.                                           uint32_t *pLatencyMs,  
  8.                                           audio_output_flags_t flags,  
  9.                                           const audio_offload_info_t *offloadInfo)  
  10. {  
  11.     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();  
  12.     if (af == 0) {  
  13.         ALOGW("%s: could not get AudioFlinger", __func__);  
  14.         return 0;  
  15.     }  
  16.     return af->openOutput(module, pDevices, pSamplingRate, pFormat, pChannelMask,  
  17.                           pLatencyMs, flags, offloadInfo);  
  18. }  
 
  1. static audio_io_handle_t aps_open_output_on_module(void *service,

  2. audio_module_handle_t module,

  3. audio_devices_t *pDevices,

  4. uint32_t *pSamplingRate,

  5. audio_format_t *pFormat,

  6. audio_channel_mask_t *pChannelMask,

  7. uint32_t *pLatencyMs,

  8. audio_output_flags_t flags,

  9. const audio_offload_info_t *offloadInfo)

  10. {

  11. sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();

  12. if (af == 0) {

  13. ALOGW("%s: could not get AudioFlinger", __func__);

  14. return 0;

  15. }

  16. return af->openOutput(module, pDevices, pSamplingRate, pFormat, pChannelMask,

  17. pLatencyMs, flags, offloadInfo);

  18. }

深入剖析Android音频之AudioPolicyService


 

[cpp] view plain copy

  1. audio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module,  
  2.                                            audio_devices_t *pDevices,  
  3.                                            uint32_t *pSamplingRate,  
  4.                                            audio_format_t *pFormat,  
  5.                                            audio_channel_mask_t *pChannelMask,  
  6.                                            uint32_t *pLatencyMs,  
  7.                                            audio_output_flags_t flags,  
  8.                                            const audio_offload_info_t *offloadInfo)  
  9. {  
  10.     PlaybackThread *thread = NULL;  
  11.     struct audio_config config;  
  12.     config.sample_rate = (pSamplingRate != NULL) ? *pSamplingRate : 0;  
  13.     config.channel_mask = (pChannelMask != NULL) ? *pChannelMask : 0;  
  14.     config.format = (pFormat != NULL) ? *pFormat : AUDIO_FORMAT_DEFAULT;  
  15.     if (offloadInfo) {  
  16.         config.offload_info = *offloadInfo;  
  17.     }  
  18.     //创建一个音频输出流对象audio_stream_out_t  
  19.     audio_stream_out_t *outStream = NULL;  
  20.     AudioHwDevice *outHwDev;  
  21.     ALOGV("openOutput(), module %d Device %x, SamplingRate %d, Format %#08x, Channels %x, flags %x",  
  22.               module,  
  23.               (pDevices != NULL) ? *pDevices : 0,  
  24.               config.sample_rate,  
  25.               config.format,  
  26.               config.channel_mask,  
  27.               flags);  
  28.     ALOGV("openOutput(), offloadInfo %p version 0x%04x",  
  29.           offloadInfo, offloadInfo == NULL ? -1 : offloadInfo->version );  
  30.     if (pDevices == NULL || *pDevices == 0) {  
  31.         return 0;  
  32.     }  
  33.     Mutex::Autolock _l(mLock);  
  34.     //从音频接口列表mAudioHwDevs中查找出对应的音频接口,如果找不到,则重新加载音频接口动态库  
  35.     outHwDev = findSuitableHwDev_l(module, *pDevices);  
  36.     if (outHwDev == NULL)  
  37.         return 0;  
  38.     //取出module对应的audio_hw_device_t设备  
  39.     audio_hw_device_t *hwDevHal = outHwDev->hwDevice();  
  40.     //为音频输出流生成一个独一无二的id号  
  41.     audio_io_handle_t id = nextUniqueId();  
  42.     mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;  
  43.     //打开音频输出流  
  44.     status_t status = hwDevHal->open_output_stream(hwDevHal,  
  45.                                           id,  
  46.                                           *pDevices,  
  47.                                           (audio_output_flags_t)flags,  
  48.                                           &config,  
  49.                                           &outStream);  
  50.     mHardwareStatus = AUDIO_HW_IDLE;  
  51.     ALOGV("openOutput() openOutputStream returned output %p, SamplingRate %d, Format %#08x, "  
  52.             "Channels %x, status %d",  
  53.             outStream,  
  54.             config.sample_rate,  
  55.             config.format,  
  56.             config.channel_mask,  
  57.             status);  
  58.     if (status == NO_ERROR && outStream != NULL) {  
  59.         //使用AudioStreamOut来封装音频输出流audio_stream_out_t  
  60.         AudioStreamOut *output = new AudioStreamOut(outHwDev, outStream, flags);  
  61.         //根据flag标志位,创建不同类型的线程  
  62.         if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {  
  63.             thread = new OffloadThread(this, output, id, *pDevices);  
  64.             ALOGV("openOutput() created offload output: ID %d thread %p", id, thread);  
  65.         } else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) ||  
  66.             (config.format != AUDIO_FORMAT_PCM_16_BIT) ||  
  67.             (config.channel_mask != AUDIO_CHANNEL_OUT_STEREO)) {  
  68.             thread = new DirectOutputThread(this, output, id, *pDevices);  
  69.             ALOGV("openOutput() created direct output: ID %d thread %p", id, thread);  
  70.         } else {  
  71.             thread = new MixerThread(this, output, id, *pDevices);  
  72.             ALOGV("openOutput() created mixer output: ID %d thread %p", id, thread);  
  73.         }  
  74.         //将创建的线程及id以键值对的形式保存在mPlaybackThreads中  
  75.         mPlaybackThreads.add(id, thread);  
  76.         if (pSamplingRate != NULL) {  
  77.             *pSamplingRate = config.sample_rate;  
  78.         }  
  79.         if (pFormat != NULL) {  
  80.             *pFormat = config.format;  
  81.         }  
  82.         if (pChannelMask != NULL) {  
  83.             *pChannelMask = config.channel_mask;  
  84.         }  
  85.         if (pLatencyMs != NULL) {  
  86.             *pLatencyMs = thread->latency();  
  87.         }  
  88.         // notify client processes of the new output creation  
  89.         thread->audioConfigChanged_l(AudioSystem::OUTPUT_OPENED);  
  90.         // the first primary output opened designates the primary hw device  
  91.         if ((mPrimaryHardwareDev == NULL) && (flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {  
  92.             ALOGI("Using module %d has the primary audio interface", module);  
  93.             mPrimaryHardwareDev = outHwDev;  
  94.             AutoMutex lock(mHardwareLock);  
  95.             mHardwareStatus = AUDIO_HW_SET_MODE;  
  96.             hwDevHal->set_mode(hwDevHal, mMode);  
  97.             mHardwareStatus = AUDIO_HW_IDLE;  
  98.         }  
  99.         return id;  
  100.     }  
  101.     return 0;  
  102. }  
 
  1. audio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module,

  2. audio_devices_t *pDevices,

  3. uint32_t *pSamplingRate,

  4. audio_format_t *pFormat,

  5. audio_channel_mask_t *pChannelMask,

  6. uint32_t *pLatencyMs,

  7. audio_output_flags_t flags,

  8. const audio_offload_info_t *offloadInfo)

  9. {

  10. PlaybackThread *thread = NULL;

  11. struct audio_config config;

  12. config.sample_rate = (pSamplingRate != NULL) ? *pSamplingRate : 0;

  13. config.channel_mask = (pChannelMask != NULL) ? *pChannelMask : 0;

  14. config.format = (pFormat != NULL) ? *pFormat : AUDIO_FORMAT_DEFAULT;

  15. if (offloadInfo) {

  16. config.offload_info = *offloadInfo;

  17. }

  18. //创建一个音频输出流对象audio_stream_out_t

  19. audio_stream_out_t *outStream = NULL;

  20. AudioHwDevice *outHwDev;

  21. ALOGV("openOutput(), module %d Device %x, SamplingRate %d, Format %#08x, Channels %x, flags %x",

  22. module,

  23. (pDevices != NULL) ? *pDevices : 0,

  24. config.sample_rate,

  25. config.format,

  26. config.channel_mask,

  27. flags);

  28. ALOGV("openOutput(), offloadInfo %p version 0x%04x",

  29. offloadInfo, offloadInfo == NULL ? -1 : offloadInfo->version );

  30. if (pDevices == NULL || *pDevices == 0) {

  31. return 0;

  32. }

  33. Mutex::Autolock _l(mLock);

  34. //从音频接口列表mAudioHwDevs中查找出对应的音频接口,如果找不到,则重新加载音频接口动态库

  35. outHwDev = findSuitableHwDev_l(module, *pDevices);

  36. if (outHwDev == NULL)

  37. return 0;

  38. //取出module对应的audio_hw_device_t设备

  39. audio_hw_device_t *hwDevHal = outHwDev->hwDevice();

  40. //为音频输出流生成一个独一无二的id号

  41. audio_io_handle_t id = nextUniqueId();

  42. mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;

  43. //打开音频输出流

  44. status_t status = hwDevHal->open_output_stream(hwDevHal,

  45. id,

  46. *pDevices,

  47. (audio_output_flags_t)flags,

  48. &config,

  49. &outStream);

  50. mHardwareStatus = AUDIO_HW_IDLE;

  51. ALOGV("openOutput() openOutputStream returned output %p, SamplingRate %d, Format %#08x, "

  52. "Channels %x, status %d",

  53. outStream,

  54. config.sample_rate,

  55. config.format,

  56. config.channel_mask,

  57. status);

  58. if (status == NO_ERROR && outStream != NULL) {

  59. //使用AudioStreamOut来封装音频输出流audio_stream_out_t

  60. AudioStreamOut *output = new AudioStreamOut(outHwDev, outStream, flags);

  61. //根据flag标志位,创建不同类型的线程

  62. if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {

  63. thread = new OffloadThread(this, output, id, *pDevices);

  64. ALOGV("openOutput() created offload output: ID %d thread %p", id, thread);

  65. } else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) ||

  66. (config.format != AUDIO_FORMAT_PCM_16_BIT) ||

  67. (config.channel_mask != AUDIO_CHANNEL_OUT_STEREO)) {

  68. thread = new DirectOutputThread(this, output, id, *pDevices);

  69. ALOGV("openOutput() created direct output: ID %d thread %p", id, thread);

  70. } else {

  71. thread = new MixerThread(this, output, id, *pDevices);

  72. ALOGV("openOutput() created mixer output: ID %d thread %p", id, thread);

  73. }

  74. //将创建的线程及id以键值对的形式保存在mPlaybackThreads中

  75. mPlaybackThreads.add(id, thread);

  76. if (pSamplingRate != NULL) {

  77. *pSamplingRate = config.sample_rate;

  78. }

  79. if (pFormat != NULL) {

  80. *pFormat = config.format;

  81. }

  82. if (pChannelMask != NULL) {

  83. *pChannelMask = config.channel_mask;

  84. }

  85. if (pLatencyMs != NULL) {

  86. *pLatencyMs = thread->latency();

  87. }

  88. // notify client processes of the new output creation

  89. thread->audioConfigChanged_l(AudioSystem::OUTPUT_OPENED);

  90. // the first primary output opened designates the primary hw device

  91. if ((mPrimaryHardwareDev == NULL) && (flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {

  92. ALOGI("Using module %d has the primary audio interface", module);

  93. mPrimaryHardwareDev = outHwDev;

  94. AutoMutex lock(mHardwareLock);

  95. mHardwareStatus = AUDIO_HW_SET_MODE;

  96. hwDevHal->set_mode(hwDevHal, mMode);

  97. mHardwareStatus = AUDIO_HW_IDLE;

  98. }

  99. return id;

  100. }

  101. return 0;

  102. }

深入剖析Android音频之AudioPolicyService

打开音频输出流过程其实就是创建AudioStreamOut对象及PlaybackThread线程过程。首先通过抽象的音频接口设备audio_hw_device_t来创建输出流对象legacy_stream_out。

深入剖析Android音频之AudioPolicyService

[cpp] view plain copy

  1. static int adev_open_output_stream(struct audio_hw_device *dev,  
  2.                                    audio_io_handle_t handle,  
  3.                                    audio_devices_t devices,  
  4.                                    audio_output_flags_t flags,  
  5.                                    struct audio_config *config,  
  6.                                    struct audio_stream_out **stream_out)  
  7. {  
  8.     struct legacy_audio_device *ladev = to_ladev(dev);  
  9.     status_t status;  
  10.     struct legacy_stream_out *out;  
  11. int ret;  
  12. //分配一个legacy_stream_out对象  
  13.     out = (struct legacy_stream_out *)calloc(1, sizeof(*out));  
  14.     if (!out)  
  15.         return -ENOMEM;  
  16. devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0);  
  17. //创建AudioStreamOut对象  
  18.     out->legacy_out = ladev->hwif->openOutputStream(devices, (int *) &config->format,  
  19.                                                     &config->channel_mask,  
  20.                                                     &config->sample_rate, &status);  
  21.     if (!out->legacy_out) {  
  22.         ret = status;  
  23.         goto err_open;  
  24. }  
  25. //初始化成员变量audio_stream  
  26.     out->stream.common.get_sample_rate = out_get_sample_rate;  
  27.     …  
  28.     *stream_out = &out->stream;  
  29.     return 0;  
  30. err_open:  
  31.     free(out);  
  32.     *stream_out = NULL;  
  33.     return ret;  
  34. }  
 
  1. static int adev_open_output_stream(struct audio_hw_device *dev,

  2. audio_io_handle_t handle,

  3. audio_devices_t devices,

  4. audio_output_flags_t flags,

  5. struct audio_config *config,

  6. struct audio_stream_out **stream_out)

  7. {

  8. struct legacy_audio_device *ladev = to_ladev(dev);

  9. status_t status;

  10. struct legacy_stream_out *out;

  11. int ret;

  12. //分配一个legacy_stream_out对象

  13. out = (struct legacy_stream_out *)calloc(1, sizeof(*out));

  14. if (!out)

  15. return -ENOMEM;

  16. devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0);

  17. //创建AudioStreamOut对象

  18. out->legacy_out = ladev->hwif->openOutputStream(devices, (int *) &config->format,

  19. &config->channel_mask,

  20. &config->sample_rate, &status);

  21. if (!out->legacy_out) {

  22. ret = status;

  23. goto err_open;

  24. }

  25. //初始化成员变量audio_stream

  26. out->stream.common.get_sample_rate = out_get_sample_rate;

  27. *stream_out = &out->stream;

  28. return 0;

  29. err_open:

  30. free(out);

  31. *stream_out = NULL;

  32. return ret;

  33. }

由于legacy_audio_device的成员变量hwif的类型为AudioHardwareInterface,因此通过调用AudioHardwareInterface的接口openOutputStream()来创建AudioStreamOut对象。

[cpp] view plain copy

  1. AudioStreamOut* AudioHardwareStub::openOutputStream(  
  2.         uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)  
  3. {  
  4.     AudioStreamOutStub* out = new AudioStreamOutStub();  
  5.     status_t lStatus = out->set(format, channels, sampleRate);  
  6.     if (status) {  
  7.         *status = lStatus;  
  8.     }  
  9.     if (lStatus == NO_ERROR)  
  10.         return out;  
  11.     delete out;  
  12.     return 0;  
  13. }  
 
  1. AudioStreamOut* AudioHardwareStub::openOutputStream(

  2. uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)

  3. {

  4. AudioStreamOutStub* out = new AudioStreamOutStub();

  5. status_t lStatus = out->set(format, channels, sampleRate);

  6. if (status) {

  7. *status = lStatus;

  8. }

  9. if (lStatus == NO_ERROR)

  10. return out;

  11. delete out;

  12. return 0;

  13. }

深入剖析Android音频之AudioPolicyService

 

打开音频输出后,在AudioFlinger与AudioPolicyService中的表现形式如下:

深入剖析Android音频之AudioPolicyService

 

打开音频输入

[cpp] view plain copy

  1. audio_io_handle_t AudioPolicyCompatClient::openInput(audio_module_handle_t module,  
  2.                                              audio_devices_t *pDevices,  
  3.                                              uint32_t *pSamplingRate,  
  4.                                              audio_format_t *pFormat,  
  5.                                              audio_channel_mask_t *pChannelMask)  
  6. {  
  7.     return mServiceOps->open_input_on_module(mService, module, pDevices,pSamplingRate, pFormat, pChannelMask);  
  8. }  
 
  1. audio_io_handle_t AudioPolicyCompatClient::openInput(audio_module_handle_t module,

  2. audio_devices_t *pDevices,

  3. uint32_t *pSamplingRate,

  4. audio_format_t *pFormat,

  5. audio_channel_mask_t *pChannelMask)

  6. {

  7. return mServiceOps->open_input_on_module(mService, module, pDevices,pSamplingRate, pFormat, pChannelMask);

  8. }


 

[cpp] view plain copy

  1. static audio_io_handle_t aps_open_input_on_module(void *service,  
  2.                                        audio_module_handle_t module,  
  3.                                        audio_devices_t *pDevices,  
  4.                                        uint32_t *pSamplingRate,  
  5.                                        audio_format_t *pFormat,  
  6.                                        audio_channel_mask_t *pChannelMask)  
  7. {  
  8.     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();  
  9.     if (af == 0) {  
  10.         ALOGW("%s: could not get AudioFlinger", __func__);  
  11.         return 0;  
  12.     }  
  13.     return af->openInput(module, pDevices, pSamplingRate, pFormat, pChannelMask);  
  14. }  
 
  1. static audio_io_handle_t aps_open_input_on_module(void *service,

  2. audio_module_handle_t module,

  3. audio_devices_t *pDevices,

  4. uint32_t *pSamplingRate,

  5. audio_format_t *pFormat,

  6. audio_channel_mask_t *pChannelMask)

  7. {

  8. sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();

  9. if (af == 0) {

  10. ALOGW("%s: could not get AudioFlinger", __func__);

  11. return 0;

  12. }

  13. return af->openInput(module, pDevices, pSamplingRate, pFormat, pChannelMask);

  14. }

深入剖析Android音频之AudioPolicyService

[cpp] view plain copy

  1. audio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module,  
  2.                                           audio_devices_t *pDevices,  
  3.                                           uint32_t *pSamplingRate,  
  4.                                           audio_format_t *pFormat,  
  5.                                           audio_channel_mask_t *pChannelMask)  
  6. {  
  7.     status_t status;  
  8.     RecordThread *thread = NULL;  
  9.     struct audio_config config;  
  10.     config.sample_rate = (pSamplingRate != NULL) ? *pSamplingRate : 0;  
  11.     config.channel_mask = (pChannelMask != NULL) ? *pChannelMask : 0;  
  12.     config.format = (pFormat != NULL) ? *pFormat : AUDIO_FORMAT_DEFAULT;  
  13.   
  14.     uint32_t reqSamplingRate = config.sample_rate;  
  15.     audio_format_t reqFormat = config.format;  
  16.     audio_channel_mask_t reqChannels = config.channel_mask;  
  17.     audio_stream_in_t *inStream = NULL;  
  18.     AudioHwDevice *inHwDev;  
  19.     if (pDevices == NULL || *pDevices == 0) {  
  20.         return 0;  
  21.     }  
  22.     Mutex::Autolock _l(mLock);  
  23.     inHwDev = findSuitableHwDev_l(module, *pDevices);  
  24.     if (inHwDev == NULL)  
  25.         return 0;  
  26.     audio_hw_device_t *inHwHal = inHwDev->hwDevice();  
  27.     audio_io_handle_t id = nextUniqueId();  
  28.     status = inHwHal->open_input_stream(inHwHal, id, *pDevices, &config,&inStream);  
  29.     ALOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %d, Channels %x, "  
  30.             "status %d",  
  31.             inStream,  
  32.             config.sample_rate,  
  33.             config.format,  
  34.             config.channel_mask,  
  35.             status);  
  36.   
  37.     // If the input could not be opened with the requested parameters and we can handle the  
  38.     // conversion internally, try to open again with the proposed parameters. The AudioFlinger can  
  39.     // resample the input and do mono to stereo or stereo to mono conversions on 16 bit PCM inputs.  
  40.     if (status == BAD_VALUE &&reqFormat == config.format && config.format == AUDIO_FORMAT_PCM_16_BIT && (config.sample_rate <= 2 * reqSamplingRate) &&  
  41.         (popcount(config.channel_mask) <= FCC_2) && (popcount(reqChannels) <= FCC_2)) {  
  42.         ALOGV("openInput() reopening with proposed sampling rate and channel mask");  
  43.         inStream = NULL;  
  44.         status = inHwHal->open_input_stream(inHwHal, id, *pDevices, &config, &inStream);  
  45.     }  
  46.   
  47.     if (status == NO_ERROR && inStream != NULL) {  
  48.   
  49. #ifdef TEE_SINK  
  50.         // Try to re-use most recently used Pipe to archive a copy of input for dumpsys,  
  51.         // or (re-)create if current Pipe is idle and does not match the new format  
  52.       ...  
  53. #endif  
  54.         AudioStreamIn *input = new AudioStreamIn(inHwDev, inStream);  
  55.         // Start record thread  
  56.         // RecordThread requires both input and output device indication to forward to audio  
  57.         // pre processing modules  
  58.         thread = new RecordThread(this,  
  59.                                   input,  
  60.                                   reqSamplingRate,  
  61.                                   reqChannels,  
  62.                                   id,  
  63.                                   primaryOutputDevice_l(),  
  64.                                   *pDevices  
  65. #ifdef TEE_SINK  
  66.                                   , teeSink  
  67. #endif  
  68.                                   );  
  69.         mRecordThreads.add(id, thread);  
  70.         ALOGV("openInput() created record thread: ID %d thread %p", id, thread);  
  71.         if (pSamplingRate != NULL) {  
  72.             *pSamplingRate = reqSamplingRate;  
  73.         }  
  74.         if (pFormat != NULL) {  
  75.             *pFormat = config.format;  
  76.         }  
  77.         if (pChannelMask != NULL) {  
  78.             *pChannelMask = reqChannels;  
  79.         }  
  80.         // notify client processes of the new input creation  
  81.         thread->audioConfigChanged_l(AudioSystem::INPUT_OPENED);  
  82.         return id;  
  83.     }  
  84.     return 0;  
  85. }  
 
  1. audio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module,

  2. audio_devices_t *pDevices,

  3. uint32_t *pSamplingRate,

  4. audio_format_t *pFormat,

  5. audio_channel_mask_t *pChannelMask)

  6. {

  7. status_t status;

  8. RecordThread *thread = NULL;

  9. struct audio_config config;

  10. config.sample_rate = (pSamplingRate != NULL) ? *pSamplingRate : 0;

  11. config.channel_mask = (pChannelMask != NULL) ? *pChannelMask : 0;

  12. config.format = (pFormat != NULL) ? *pFormat : AUDIO_FORMAT_DEFAULT;

  13.  
  14. uint32_t reqSamplingRate = config.sample_rate;

  15. audio_format_t reqFormat = config.format;

  16. audio_channel_mask_t reqChannels = config.channel_mask;

  17. audio_stream_in_t *inStream = NULL;

  18. AudioHwDevice *inHwDev;

  19. if (pDevices == NULL || *pDevices == 0) {

  20. return 0;

  21. }

  22. Mutex::Autolock _l(mLock);

  23. inHwDev = findSuitableHwDev_l(module, *pDevices);

  24. if (inHwDev == NULL)

  25. return 0;

  26. audio_hw_device_t *inHwHal = inHwDev->hwDevice();

  27. audio_io_handle_t id = nextUniqueId();

  28. status = inHwHal->open_input_stream(inHwHal, id, *pDevices, &config,&inStream);

  29. ALOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %d, Channels %x, "

  30. "status %d",

  31. inStream,

  32. config.sample_rate,

  33. config.format,

  34. config.channel_mask,

  35. status);

  36.  
  37. // If the input could not be opened with the requested parameters and we can handle the

  38. // conversion internally, try to open again with the proposed parameters. The AudioFlinger can

  39. // resample the input and do mono to stereo or stereo to mono conversions on 16 bit PCM inputs.

  40. if (status == BAD_VALUE &&reqFormat == config.format && config.format == AUDIO_FORMAT_PCM_16_BIT && (config.sample_rate <= 2 * reqSamplingRate) &&

  41. (popcount(config.channel_mask) <= FCC_2) && (popcount(reqChannels) <= FCC_2)) {

  42. ALOGV("openInput() reopening with proposed sampling rate and channel mask");

  43. inStream = NULL;

  44. status = inHwHal->open_input_stream(inHwHal, id, *pDevices, &config, &inStream);

  45. }

  46.  
  47. if (status == NO_ERROR && inStream != NULL) {

  48.  
  49. #ifdef TEE_SINK

  50. // Try to re-use most recently used Pipe to archive a copy of input for dumpsys,

  51. // or (re-)create if current Pipe is idle and does not match the new format

  52. ...

  53. #endif

  54. AudioStreamIn *input = new AudioStreamIn(inHwDev, inStream);

  55. // Start record thread

  56. // RecordThread requires both input and output device indication to forward to audio

  57. // pre processing modules

  58. thread = new RecordThread(this,

  59. input,

  60. reqSamplingRate,

  61. reqChannels,

  62. id,

  63. primaryOutputDevice_l(),

  64. *pDevices

  65. #ifdef TEE_SINK

  66. , teeSink

  67. #endif

  68. );

  69. mRecordThreads.add(id, thread);

  70. ALOGV("openInput() created record thread: ID %d thread %p", id, thread);

  71. if (pSamplingRate != NULL) {

  72. *pSamplingRate = reqSamplingRate;

  73. }

  74. if (pFormat != NULL) {

  75. *pFormat = config.format;

  76. }

  77. if (pChannelMask != NULL) {

  78. *pChannelMask = reqChannels;

  79. }

  80. // notify client processes of the new input creation

  81. thread->audioConfigChanged_l(AudioSystem::INPUT_OPENED);

  82. return id;

  83. }

  84. return 0;

  85. }

深入剖析Android音频之AudioPolicyService

打开音频输入流过程其实就是创建AudioStreamIn对象及RecordThread线程过程。首先通过抽象的音频接口设备audio_hw_device_t来创建输出流对象legacy_stream_in。

深入剖析Android音频之AudioPolicyService

[cpp] view plain copy

  1. static int adev_open_input_stream(struct audio_hw_device *dev,  
  2.                                   audio_io_handle_t handle,  
  3.                                   audio_devices_t devices,  
  4.                                   struct audio_config *config,  
  5.                                   struct audio_stream_in **stream_in)  
  6. {  
  7.     struct legacy_audio_device *ladev = to_ladev(dev);  
  8.     status_t status;  
  9.     struct legacy_stream_in *in;  
  10.     int ret;  
  11.     in = (struct legacy_stream_in *)calloc(1, sizeof(*in));  
  12.     if (!in)  
  13.         return -ENOMEM;  
  14.     devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0);  
  15.     in->legacy_in = ladev->hwif->openInputStream(devices, (int *) &config->format,  
  16.                                        &config->channel_mask,  
  17.                                        &config->sample_rate,  
  18.                                        &status, (AudioSystem::audio_in_acoustics)0);  
  19.     if (!in->legacy_in) {  
  20.         ret = status;  
  21.         goto err_open;  
  22.     }  
  23.     in->stream.common.get_sample_rate = in_get_sample_rate;  
  24.     …  
  25.     *stream_in = &in->stream;  
  26.     return 0;  
  27. err_open:  
  28.     free(in);  
  29.     *stream_in = NULL;  
  30.     return ret;  
  31. }  
 
  1. static int adev_open_input_stream(struct audio_hw_device *dev,

  2. audio_io_handle_t handle,

  3. audio_devices_t devices,

  4. struct audio_config *config,

  5. struct audio_stream_in **stream_in)

  6. {

  7. struct legacy_audio_device *ladev = to_ladev(dev);

  8. status_t status;

  9. struct legacy_stream_in *in;

  10. int ret;

  11. in = (struct legacy_stream_in *)calloc(1, sizeof(*in));

  12. if (!in)

  13. return -ENOMEM;

  14. devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0);

  15. in->legacy_in = ladev->hwif->openInputStream(devices, (int *) &config->format,

  16. &config->channel_mask,

  17. &config->sample_rate,

  18. &status, (AudioSystem::audio_in_acoustics)0);

  19. if (!in->legacy_in) {

  20. ret = status;

  21. goto err_open;

  22. }

  23. in->stream.common.get_sample_rate = in_get_sample_rate;

  24. *stream_in = &in->stream;

  25. return 0;

  26. err_open:

  27. free(in);

  28. *stream_in = NULL;

  29. return ret;

  30. }

 

[cpp] view plain copy

  1. AudioStreamIn* AudioHardwareStub::openInputStream(  
  2.         uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate,  
  3.         status_t *status, AudioSystem::audio_in_acoustics acoustics)  
  4. {  
  5.     // check for valid input source  
  6.     if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) {  
  7.         return 0;  
  8.     }  
  9.     AudioStreamInStub* in = new AudioStreamInStub();  
  10.     status_t lStatus = in->set(format, channels, sampleRate, acoustics);  
  11.     if (status) {  
  12.         *status = lStatus;  
  13.     }  
  14.     if (lStatus == NO_ERROR)  
  15.         return in;  
  16.     delete in;  
  17.     return 0;  
  18. }  
 
  1. AudioStreamIn* AudioHardwareStub::openInputStream(

  2. uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate,

  3. status_t *status, AudioSystem::audio_in_acoustics acoustics)

  4. {

  5. // check for valid input source

  6. if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) {

  7. return 0;

  8. }

  9. AudioStreamInStub* in = new AudioStreamInStub();

  10. status_t lStatus = in->set(format, channels, sampleRate, acoustics);

  11. if (status) {

  12. *status = lStatus;

  13. }

  14. if (lStatus == NO_ERROR)

  15. return in;

  16. delete in;

  17. return 0;

  18. }

打开音频输入创建了以下legacy_stream_in对象:

深入剖析Android音频之AudioPolicyService

打开音频输入后,在AudioFlinger与AudioPolicyService中的表现形式如下:

深入剖析Android音频之AudioPolicyService

当AudioPolicyManagerBase构造时,它会根据用户提供的audio_policy.conf来分析系统中有哪些audio接口(primary,a2dp以及usb),然后通过AudioFlinger::loadHwModule加载各audio接口对应的库文件,并依次打开其中的output(openOutput)和input(openInput):

->打开音频输出时创建一个audio_stream_out通道,并创建AudioStreamOut对象以及新建PlaybackThread播放线程。

-> 打开音频输入时创建一个audio_stream_in通道,并创建AudioStreamIn对象以及创建RecordThread录音线程。

深入剖析Android音频之AudioPolicyService

相关文章: