Android 4.1 Audio系统变化说明(2)

三 AudioFlinger变化说明

我们将根据AF工作的主要流程来介绍下变化情况:

AF创建,包括其onFirstRef函数 openOutput函数及MixerThread对象的创建 AudioTrack调用createTrack函数 AudioTrack调用start函数 AF混音,然后输出

3.1 AF创建和onFirstRef

恩,没什么太大变化。有三个点:

现在对Primary设备的音量有了更为细致的控制,例如有些设备能设音量,有些不能设置音量,所以定义了一个master_volume_support(AudioFlinger.h)枚举,用来判断Primary设备的音量控制能力。 以前播放过程的standby时间(就是为了节电而用)是写死的,现在可由ro.audio.flinger_standbytime_ms控制,如果没有这个属性,则默认是3秒。AF还增加了其他变量控制,例如有一个gScreenState变量,用来表示屏幕是开还是关。可通过AudioSystem::setParameters来控制。另外还定义了一个和蓝牙SCO相关的mBtNrecIsOff变量,是用于控制蓝牙SCO(录音时用,蓝牙上的一个专业术语叫,NREC。不知道是什么,用懂的人告诉我一下)时禁止AEC和NS特效的。请参考AudioParameter.cpp

3.2 openOutput函数

openOutput函数比较关键,其中会见到以前的老朋友MixerThread,AudioStreamOutput等。整个流程包括加载Audio相关的硬件so。这部分工作在4.0的时候就有了,谈不上太多的变化。但物是人非,老朋友已经发生巨大变化了。先来看MixerThread家族。

Android 4.1 Audio系统变化说明

图1 PlaybackThread家族

图1稍加解释:

ThreadBase从Thread派生,所以它会运行在一个单独的线程中(啰嗦一句,线程和对象其实没有关系的,不懂多线程编程的码农们请务必认真学习多线程)。它定义了一个枚举type_t,用来表示子类的类型,这几个类型包括MIXER,DIRECT,RECORD,DUPLICATING等。这个应该比较好懂吧?

ThreadBase的内部类TrackBase从ExtendedAudioBufferProvider派生,这个应该是新增加的。TrackBase嘛,大家把它理解成一个Buffer Container就好了。

ThreadBase的内部类PMDeathRecipient用来监听PowerManagerService的死亡消息。这个设计有点搞,因为PMS运行在SystemService中,只有SS挂了,PMS才会挂。而SS挂了,mediaserver也会被init.rc的规则给弄死,所以AudioFlinger也会死。既然大家都一起死,速度很快。故,设置这个PMDeathRecipient有何大的意义呢?

再来看ThreadBase的一个重要子类PlaybackThread,这个类应该是做过大整容了。

其定义了一个枚举mixer_state,用来反映当前混音工作的状态,有MIXER_IDLE,MIXER_READY和MIXER_ENABLED

定义了几个虚函数,需要子类实现,包括threadLoop_mix,prepareTracks_l等。这几个函数的抽象工作做得还是可以。但变化之大让人防不胜防啊。

Track类增加了从VolumeProvider派生,这个VP是用来控制音量的。根据前面的介绍,在JB中,音量管理比以前来得细致

新增定义了TimedTrack。这个类的作用和前面提到的rtp aah有关。等同学们学完本篇,即可开展相应研究,打响歼灭战!

接下来看图2。

Android 4.1 Audio系统变化说明

图2 MixerThread和它的弟兄们

图2,简单介绍一下:

MixerThread从PlaybackThread派生,这个关系至始至终不会变化,相信以后也不会。

MT最大的变化是其中几个重要的成员变量。大家肯定认识其中的AudioMixer,它是用来混音的。

新增一个Soaker对象(由编译宏控制),它是一个线程。这个单词的前缀soak在webster词典(相信经历过,那些年,我们一起GRE的日子 的人知道什么是webster)中最贴切的一条解释是to cause to pay an exorbitant amount。还是不很明白是干嘛的?再一看代码。原来,soaker就是一个专职玩弄CPU的线程。它的工作就是不断得做运算,拉高CPU使用率。它的存在应该是为了测试新AF框架在多核CPU上的效率等等等的问题。所以,低端智能机们,你们不要玩JB了。

另外一条证明低端智能机不能随便玩JB的铁证就是:我们看到MT中新增了一个FastMixer,它也是一个线程。明白了?在JB中,多核智能机上,混音工作可以放到FastMixer所在的线程来做,当然速度,效率会高了。

FastMixer工作流程比较复杂,又牵扯到多线程同步。所以,这里定义了一个FastMixerStateQueue,它由typedef StateQueue<FastMixerState>得到。首先它是一个StateQueue(简单把它当做数组吧)。其数组元素的类型为FastMixerState。一个StateQueue通过mStats变量保存4个FasetMixerState成员。

FasetMixerState类似状态机,有一个enum Command,用来控制状态的。FastMixerState中含有一个八元组的FastTracks数组。FastTrack是用来完成FastMixer的一个功能类。

每个FastTrack都有一个mBufferProvider,该成员类型为SourceAudioBufferProvider。

以上的内容已经比较复杂了,下面来介绍下MixerThread对象创建中碰到的其他内容:

linux

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/pxwsd.html