此文章部分参考  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/audioserverclass mainuser 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_acctioprio rt 4writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasksonrestart restart audio-hal-2-0on property:vts.native_server.on=1stop audioserver
on property:vts.native_server.on=0start 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 fixedandroid::hardware::ProcessState::self()->startThreadPool();IPCThreadState::self()->joinThreadPool();}
}

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

void AudioPolicyService::onFirstRef()
{{Mutex::Autolock _l(mLock);// start tone playback threadmTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);// start audio commands threadmAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);// start output activity command threadmOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);mAudioPolicyClient = new AudioPolicyClient(this);mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);}// load audio processing modulessp<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.confConfigParsingUtils::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.是否已经加载过这个interfacefor (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 interfaceint 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 interfaceif (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 listselectOutputForMusicEffects();nextAudioPortGeneration();
}

总结1 {

        mOutputs  表示已经打开的output

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

                                              找到对应的播放线程mPlaybackThreads 

                                              找到输出描述符outputDesc

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

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

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

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

   IOProfile  来自配置的文件的参数

}

AudioPolicyService启动过程分析(android_audio)相关推荐

  1. 嵌入式linux启动过程分析,嵌入式Linux裸机开发(二)——S5PV210启动过程分析

    嵌入式Linux裸机开发(二)--S5PV210启动过程分析 一.iROM启动方式简介 友善之臂Smart210开发板的SoC为三星S5PV210,S5PV210采用iROM启动方式进行启动,通过查阅 ...

  2. OpenWrt启动过程分析+添加自启动脚本【转】

    一.OpenWrt启动过程分析 转自: http://www.eehello.com/?post=107 总结一下OpenWrt的启动流程:1.CFE->2.linux->3./etc/p ...

  3. pixhawk PX4FMU和PX4IO最底层启动过程分析

    摘要: pixhawk PX4FMU和PX4IO最底层启动过程分析1.1 主处理器和协处理器的固件烧写和运行流程首先,大体了解PX4IO 与PX4FMU各自的任务.PX4IO(STM32F100)为P ...

  4. linux 重定位arm,Arm linxu启动过程分析(一)

    本文着重分析 FS2410 平台 linux-2.6.14 内核启动的详细过程,主要包括: zImage 解压缩阶段. vmlinux 启动汇编阶段. startkernel 到创建第一个进程阶段三个 ...

  5. linxu 启动过程分析

    linxu 启动过程分析 Linux启动过程如下:当用户打开PC的电源,BIOS开机自检,按BIOS中设置的启动设备(通常是硬盘)启动,接着启动设备上安装的引导程序lilo或grub开始引导Linux ...

  6. 开机SystemServer到ActivityManagerService启动过程分析

    开机SystemServer到ActivityManagerService启动过程 一 从Systemserver到AMS zygote-> systemserver:java入层口: /*** ...

  7. AliOS Things的启动过程分析(一)

    AliOS Things的启动过程分析(一) 在本篇文章中,我们以developerkit开发板为例,介绍AliOS Things的启动过程.AliOS Things支持多种工具链进行编译链接的方式生 ...

  8. Chromium的GPU进程启动过程分析

    Chromium除了有Browser进程和Render进程,还有GPU进程.GPU进程负责Chromium的GPU操作,例如Render进程通过GPU进程离屏渲染网页,Browser进程也是通过GPU ...

  9. Android开发入门教程2-Android init 启动过程分析

    Android init 启动过程分析   分析android的启动过程,从内核之上,我们首先应该从文件系统的init开始,因为 init 是内核进入文件系统后第一个运行的程序,通常我们可以在linu ...

最新文章

  1. 肝了三天,万字长文教你玩转 tcpdump,从此抓包不用愁
  2. 马斯克脑洞破解谁是“中本聪”?
  3. 野指针和悬空指针的形成原因和如何避免!
  4. 《Python编程从入门到实践》记录之列表遍历
  5. C#编写程序监测某个文件夹内是否有文件进行了增,删,改的动作?
  6. linux的ftp指令发邮件,三种使用Linux命令发送邮件
  7. 使用mysqlimport导入包含主键自增长属性的表
  8. atitit.团队建设总结fx O622
  9. 【国产mcu填坑篇】------STC(宏晶)
  10. 判断对错。在java的多态调用中,new的是哪一个类就是调用的哪个类的方法。
  11. 矩阵对角化,SVD分解
  12. 医疗管理系统-预约管理
  13. CList 动态链表的学习笔记
  14. linux install jkd
  15. mit数据库 matlab,[zz]MIT-BIH开放数据库使用指南
  16. ElasticSearch查询实现全字段搜索
  17. 掌财社:非公开发行股票什么意思?
  18. 【教程】kiftd 为账户设置上传文件的最大体积限制
  19. C++11标准模板(STL)- 算法 - 集合操作(在已排序范围上)(std::set_difference)
  20. Vue实现pptx在线预览

热门文章

  1. 很牛的语文老师,很牛的分享!
  2. Microsoft Excel 教程:如何在 Excel 中更改列宽或行高?
  3. 哈勃望远镜修改太阳系第十大行星大小
  4. 省市县JSON数据ppca-code.json
  5. Go --- Marshal与Unmarshal基础用法
  6. 电脑开机提示CPU Fan Error处理方法
  7. Android让屏幕保持常亮的方法,亲测有效
  8. 台式电脑怎么调分辨率_电脑分辨率不能调整怎么办 电脑分辨率调多少最好
  9. OSChina 娱乐弹弹弹
  10. Unable to allocate 129792KB bitmaps for parallel garbage collection for the requested 4153344KB heap