当前位置: 首页 > news >正文

audio 核心服务AudioPolicyService 和AudioFlinger启动流程

目录

1、audioserver启动

2、AudioPolicyService启动

3、AudioFlinger启动


audio的核心服务有两个,AudioPolicyService 和AudioFlinger他们到在audioserver一个进程中


1、audioserver启动


设备开机,系统启动时将执行 /system/etc/init/audioserver.rc ,运行 /system/bin/ 目录下的 audioserver 服务。
机器上路径
console:/ # ls /system/etc/init/audioserver.rc 
/system/etc/init/audioserver.rc
源码上路径
frameworks/av/media/audioserver/audioserver.rc
内容如下:

1 service audioserver /system/bin/audioserver
2     class core
3     user audioserver
4     # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
5     group audio camera drmrpc media mediadrm net_bt net_bt_admin net_bw_acct wakelock
6     capabilities BLOCK_SUSPEND
7     ioprio rt 4
8     task_profiles ProcessCapacityHigh HighPerformance
9 
10     onrestart setprop sys.audio.restart.hal 1

audioserver 进程会依次对 AudioFlinger、AudioPolicyService、RadioService、SoundTriggerHwService 进行实例化。如果设备集成了杜比音效,杜比音效的内存管理服务 DolbyMemoryService 也会在这里进行实例化。


2、AudioPolicyService启动

AudioPolicyService服务运行在audioserver进程中, 随着audioserver进程启动而启动。
frameworks/av/media/audioserver/main_audioserver.cpp

int main(int argc __unused, char **argv){……sp<ProcessState> proc(ProcessState::self());sp<IServiceManager> sm = defaultServiceManager();ALOGI("ServiceManager: %p", sm.get());AudioFlinger::instantiate();//实例化AudioFlinger服务,AudioFlinger 的实例化先于AudioPolicyServiceAudioPolicyService::instantiate();//实例化AudioPlicyService服务
}

        其中,AudioPolicyService::instantiate()并不由AudioPolicyService实现,而是BinderService类的一个实现包括AudioFlinger,AudioPolicyservice等在内的几个服务都继承自这个统一的Binder的服务类,具体实现在BinderService.h中。如果后续我们需要自己开发一个基于binder的服务那么也可以继承binderservice来实现。

    static void instantiate() { publish(); }static status_t publish(bool allowIsolated = false,int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {sp<IServiceManager> sm(defaultServiceManager());return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,dumpFlags);//注册服务到servicemanager中}

publish()函数获取到ServiceManager的代理,然后new一个调用instantiate的service对象并把它添加到ServiceManager中。AudioPolicyService 开始构造并调用 AudioPolicyService::onFirstRef() 方法进行初始化,这个过程中会创建 AudioPolicyManager 对象
frameworks/av/services/audiopolicy/service/AudioPolicyService.cpp


void AudioPolicyService::onFirstRef()
{{Mutex::Autolock _l(mLock);// start audio commands threadmAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);//创建ApmAudio线程用于执行audio命令// start output activity command threadmOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);//创建ApmOutpur线程用于执行输出命令mAudioPolicyClient = new AudioPolicyClient(this);//创建AudioPolicyClient对象ALOGE("czhaudio AudioPolicyService createAudioPolicyManager");mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);// 创建 AudioPolicyManager 对象}// load audio processing modules//解析audio_effects.conf 文件,得到并加载系统支持的音效库。初始化各个音效对应的参数,将各音效和对应的输入和输出//流绑定在一起,这样,当上层要使用音效时,就会在对应的threadloop中调用process_l音效处理函数。sp<AudioPolicyEffects> audioPolicyEffects = new AudioPolicyEffects();//创建音效相关对象sp<UidPolicy> uidPolicy = new UidPolicy(this);sp<SensorPrivacyPolicy> sensorPrivacyPolicy = new SensorPrivacyPolicy(this);{Mutex::Autolock _l(mLock);mAudioPolicyEffects = audioPolicyEffects;mUidPolicy = uidPolicy;mSensorPrivacyPolicy = sensorPrivacyPolicy;}uidPolicy->registerSelf();sensorPrivacyPolicy->registerSelf();
}

这里audiopolicyservice为什么要起两个commandthread?audioflinger和audiopoliyservice是在同一个进程。如果audiopolicymanager直接调用audioflinger的接口就会阻塞住。(也就是同步的)。
而通过线程去调用audioflinger的话或者处理一些耗时的任务,audiopolicymanager就可以很快返回不需要阻塞住createAudioPolicyManager() 函数的实现位于 frameworks/av/services/audiopolicy/manager/AudioPolicyFactory.cpp文件中。
查看源码后我们会发现它实际上是直接调用了 AudioPolicyManager 的构造函数

extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
{AudioPolicyManager *apm = new AudioPolicyManager(clientInterface);  // 调用 AudioPolicyManager 的构造函数创建对象status_t status = apm->initialize(); //进行初始化硬件各个模块if (status != NO_ERROR) {delete apm;apm = nullptr;}return apm;
}

        AudioPolicyManager 的构造函数将解析音频策略配置文件,从而获取到设备所支持的音频设备信息(包括设备是否支持 Offload、Direct 模式输出,各输入输出 profile 所支持的采样率、通道数、数据格式等),加载全部 HwModule,为之创建所有非 direct 输出类型的 outputStream 和所有 inputStream,并创建相应的 playbackThread 或 recordThread 线程。需要注意的是,Android 7.0上的音频策略配置文件开始使用 XML 格式,其文件名为 audio_policy_configuration.xml,而在之前的版本上音频策略配置文件为 audio_policy.conf
frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp 中 AudioPolicyManager 构造函数的关键代码如下

AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface): AudioPolicyManager(clientInterface, false /*forTesting*/)
{loadConfig();
}

loadConfig:下片介绍 https://blog.csdn.net/niaohaoge/article/details/147394152

3、AudioFlinger启动


接1 节的publish,直接分析构造函数
AudioFlinger::instantiate();//实例化AudioFlinger服务,AudioFlinger 的实例化先于AudioPolicyService
 

AudioFlinger::AudioFlinger(): BnAudioFlinger(),mPrimaryHardwareDev(NULL),//...mGlobalEffectEnableTime(0),mPrimaryOutputSampleRate(0)
{getpid_cached = getpid();char value[PROPERTY_VALUE_MAX];//...
}

主要是一些变量的初始化,之后主要看onFirstRef的实现,代码如下:

void AudioFlinger::onFirstRef()
{int rc = 0;Mutex::Autolock _l(mLock);/* TODO: move all this work into an Init() function */char val_str[PROPERTY_VALUE_MAX] = { 0 };if (property_get("ro.audio.flinger_standbytime_ms", val_str, NULL) >= 0) {uint32_t int_val;if (1 == sscanf(val_str, "%u", &int_val)) {mStandbyTimeInNsecs = milliseconds(int_val);} else {mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;}}//这里将AudioFlinger传递给PatchPanel,其他并没有做什么mPatchPanel = new PatchPanel(this);mMode = AUDIO_MODE_NORMAL;
}

相关文章:

  • jsconfig.json文件的作用
  • 【SAP-CO】生产的成本流转和成本分析
  • Spark-Streaming
  • 【深度学习新浪潮】新视角生成的研究进展调研报告(2025年4月)
  • 软件测试之接口测试常见面试
  • 第48讲:空间大数据与智慧农业——时空大数据分析与农业物联网的融合实践
  • ecovadis评级范围,如何拿到ecovadis评级高分
  • 局域网内,将linux(Ubuntu)的硬盘映射成Windows上,像本地磁盘一样使用
  • 健康生活新指南
  • ESM 内功心法:化解 require 中的夺命一击!
  • Spring 中 @Component, @Repository, @Service 的区别及示例代码
  • 学习Docker遇到的问题
  • 广州市白云区粤荣职业培训学校副校长余智强获聘广州培训质量督导员
  • 高性能数据库集群:分库分表
  • LeetCode 热题 100_分割等和子集(89_416_中等_C++)(动态规划)
  • 如何通过证书认证安全登录堡垒机、防火墙和VPN?安当KSP密钥管理系统助力企业实现零信任身份验证
  • C++ linux打包运行方案(cmake)
  • postman工具
  • 全能 Sui 技术栈,构建 Web3 的未来
  • 掌握 Altium Designer:轻松定制“交换器件”工具栏
  • 汪东进卸任中海油董事长,深耕油气领域40余年、已临近退休
  • 土耳其发生6.2级地震,震源深度10千米
  • 央行副行长:上海国际金融中心建设是我国参与国际金融竞争的核心载体
  • 特朗普称或将“大幅降低”对华关税,外交部:打,奉陪到底;谈,大门敞开
  • 威廉·透纳诞辰250周年|他是现代艺术之父
  • 具身智能资本盛宴:3个月37笔融资,北上深争锋BAT下场,人形机器人最火