08.音频系统:第004课_Android音频系统详解:第007节_AudioPolicyManager堪误与回顾

上小节我们对AudioTrack创建作了一些概述,知道其大概会做如下事情:
1 使用AudioTrack的属性, 根据AudioPolicy找到对应的output、playbackThread
2 在playbackThread中创建对应的track
3 APP的AudioTrack 和 playbackThread的mTracks中的track之间建立共享内存

第一点

我们先来讲解第一点,应用程序在创建AudioTrack时,会指定声音的某些参数,如声音的类型,那么他是怎么找到对应的硬件进行播放的呢?或者说他怎么去选择一个output,这就是该小节要讲解的内容。在讲解之前,我们需要纠正一个错误,只之前的08.音频系统:第004课_Android音频系统详解:第003节_所涉及文件形象讲解,章节说:
08.音频系统:第004课_Android音频系统详解:第007节_AudioPolicyManager堪误与回顾_第1张图片
厂家也可以参与策略,其实通过AudioPolicyManagerBase这个基类派生出来厂家的代码AudioPolicyManager.cpp。我们要进行纠正,其实老的方法,那么新的方法是怎么样的呢?其文件为frameworks\av\services\audiopolicy\managerdefault\AudioPolicyManager
系统已经实现了该文件,厂家不需要参与策略。即为新方法。打开AudioPolicyService.cpp:

void AudioPolicyService::onFirstRef()
/*可以看到如下宏:使用旧的策略*/
#ifdef USE_LEGACY_AUDIO_POLICY	
	......
#else//新策略
        mAudioPolicyClient = new AudioPolicyClient(this);
        mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
#endif

其使用createAudioPolicyManager创建管理者,我们搜索该函数,可以找到android in AudioPolicyFactory.cpp(经过试验证明,我们使用的是该文件):

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

现在我们回顾一下创建AudioFlinger与AudioPolicyService中所作的工作,其所作的工作,是AudioTrack选择output的基础。怎么进行回顾呢?根据上上面我们找到AudioPolicyManager.cpp文件,进入其构造函数(他做的工作与AudioPolicyManagerBase基本一致):

AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
	/*加载配置文件,构造mHwmodule*/
	ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, config)
	/*根据名字加载mHwmodule对应的so文件,该文件由参加提供*/
	mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->getName());
	/*从mHwmodule获得outProfile */
	const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j];
	/*根据outProfile 得到一个描述符,设置mpClientInterface*/
	sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,mpClientInterface);
	/*打开output设备,同时会创建playbackthread,其会得到一个output整数(该函数的参数),这个整数会对应播放线程,也可以对应SwAudioOutputDescriptor*/
	status_t status = mpClientInterface->openOutput(outProfile->getModuleHandle(),&output,&config,&outputDesc->mDevice,address,&outputDesc->mLatency,outputDesc->mFlags);
	/*根据output添加outputDesc描述符*/
	addOutput(output, outputDesc);
		outputDesc->setIoHandle(output);
	    mOutputs.add(output, outputDesc);
	    updateMono(output); // update mono status when adding to output list
	    nextAudioPortGeneration();

08.音频系统:第004课_Android音频系统详解:第007节_AudioPolicyManager堪误与回顾_第2张图片

1.在AudioPolicyService中存在一个mHwModules数组,其中有多个mHwModule,每个mHwModule包含.mName,.mOutputProfiles(对应一个output结点配置:IOProfiles类),.mInputProfiles(对应一个或者多个input结点配置:IOProfiles类).等成员。
2.由AudioFlinger实现,根据mHwModules数组中每个mHwModule的名字,打开厂家提供的so文件。然后构建硬件封装的对象mAudioHwDevice放入mAudioHwDevices数组中。mAudioHwDevice中含有audio_hw_device结构体,audio_hw_device又包含了厂家提供的AudioHardWare对象。
3.打开module中的output创建playbackTraad线程(由AudioFlinger实现,但是由AudioPolicyService调用):对每一个module中的每一个output Profiles,如果flog不是特殊的,则调用status_t status = outHwDev->openOutputStream(&outputStream,*output,devices,flags,config,address.string())。然后创建线程thread = new DirectOutputThread,在通过mPlaybackThreads.add(*output, thread)添加到mPlaybackThreads线程数组之中。所以,没一个Output都对应一个线程(猜测input也是如此)。
4.把outputDesc放入AudioPolicyManager中的.mOutputs中,以后可以根据一个整数(Output),找到对应的线程,找到对应的outputDesc。outputDesc中含有配置文件的信息。mOutputs表示的是已经打开的mOutput。

你可能感兴趣的:(RK3399移植)