参考这两个文章:
Android 音频系统:从 AudioTrack 到 AudioFlinger
Android 音频数据传输流程图 - Playback过程
目录
一、AudioPolicyService
系统在启动的时候,AudioPolicyService 会读取,解析配置文件。AudioPolicyService根据配置文件的信息来打开默认的output,并且为output创建线程。
这个配置文件叫:audio_policy.conf 在系统 ./system/etc/下。
AudioPolicyService 启动过程 启动过程如下:
AudioPolicyClient 的作用是,AudioPolicyService 用来访问 audioflinger 里面的函数。
new AudioPolicyManager(clientInterface) 之后的动作,都是在用AudioPolicyClient 调用 audioflinger 的函数,比如openOutput。
loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) 就是加载配置文件,根据配置文件,先加载mpClientInterface->loadHwModule(mHwModules[i]->mName),再打开配置文件里面的默认output。
配置文件的结构如下:
loadAudioPolicyConfig ,定义如下,
status_t AudioPolicyManager::loadAudioPolicyConfig(const char *path)
{
cnode *root;
char *data;
data = (char *)load_file(path, NULL);
if (data == NULL) {
return -ENODEV;
}
root = config_node("", "");
config_load(root, data);
loadHwModules(root);
// legacy audio_policy.conf files have one global_configuration section
loadGlobalConfig(root, getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY));
config_free(root);
free(root);
free(data);
ALOGI("loadAudioPolicyConfig() loaded %s\n", path);
return NO_ERROR;
}
config_load 就是把文件解析出来,用来初始化参数等。比如loadHwModules(),loadGlobalConfig()函数就是在干这件事。
二、audioflinger
①loadHwModule
so的加载是被AudioPolicyService调用的,
loadHwModule 会根据解析出来的module的名字让audioflinger加载对应的so文件。
So 的名字获取:
名字从/system/etc/audio_policy.conf得到 : primary
所以so文件就是 : audio.primary.XXX.so, eg. audio.primary.tiny4412.so
audio模块对硬件的封装:
②openOutput :
怎么打开一个output呢,在调用openOutput 函数前会够着数据,通过outProfile构造一个sp<AudioOutputDescriptor> outputDesc 对象,这个outProfile里面装的就是
这些参数,调用openOutput 就是把这些参数设置下去。
openOutput 调用到openOutput_l 时,会返回一个线程 sp<PlaybackThread> thread = openOutput_l(module, output, config, *devices, address, flags); ,在open_output_stream执行成功后,会根据配置文件里面的flag去创建线程,但一般都是创建new MixerThread(this, outputStream, *output, devices); 最后把线程添加到mPlaybackThreads里面。