3.3 MixerThread创建
通过图1和图2,应该对AF的几个主要成员有了认识。可惜啊,上面MixerThread中还有一个mOutputSink成员,没看到吧?它就和我们前面提到的NBAIO(Non-block Audio I/O )有重大关系。NBAIO的存在,是为了想实现非阻塞的音频输入输出操作。下面是这个类的注释:
NBAIO注释:
// This header file has the abstract interfaces only. Concrete implementation classes are declared
// elsewhere. Implementations _should_ be non-blocking for all methods, especially read() and
// write(), but this is not enforced. In general, implementations do not need to be multi-thread
// safe, and any exceptions are noted in the particular implementation.
NBAIO只是定义了一个接口,需要去实现具体的实现类。当然,它要求read/write函数是非阻塞的,真实实现到底是不是阻塞,由实现者去控制。
个人感觉这部分框架还没有完全成熟,但NBIO的引入,需要同学们小心,相对而言,难度也比较大。下面我们通过图3来看看NBAIO的一些内容。
图3 NBAIO相关内容
图3解释如下:
NBAIO包括三个主要类,一个是NBAIO_Port,代表I/O端点,其中定义了一个negotiate函数,用于调用者和I/O端点进行参数协调。注意,并不是为I/O端点设置参数。因为I/O端点往往和硬件相关,而硬件有些参数是不能像软件一般随意变化的。例如硬件只支持最多44.1KHZ的采样率,而调用者传递48KHz的采样率,这直接就需要一个协商和匹配的过程。这个函数的比较难用,主要是规则较多。同学们可以参考其注释说明。
NBAIO_Sink对应output端点,其定义了write和writeVia函数,writeVia函数需要传递一个回调函数via,其内部将调用这个via函数获取数据。类似数据的推/拉两种模式。
NBAIO_Source对应input端点,其定义了read和readVia函数。意义同NBAIO_Sink。
定义一个MonoPipe和MonoPipeReader。Pipe即管道,MonoPipe和LINUX中的IPC通信Pipe没毛关系,只不过借用了这个管道概念和思路。MonoPipe即只支持单个读者的Pipe(AF中,它是MonoPipeReader)。这两个Pipe,代表了Audio的Output和Input端点。
MT中由mOutputSink指向AudioStreamOutSink,此类用NBAIO_Sink派生,用于普通的mixer的输出。mPipeSink指向MonoPipe,本意是用于FastMixer的。另外,还有一个变量mNormalSink,它将根据FastMixer的情况,指向mPipeSink,或者是mOutputSink。这段控制的逻辑如下:
switch (kUseFastMixer) { //kUseFastMixer用于控制FastMixer的使用情况,一共4种:
case FastMixer_Never: //永远不使用FastMixer,这个选项用于调试,即关闭FastMixer的情况
case FastMixer_Dynamic: //根据情况,动态使用。根据注释,这个功能似乎还没有完全实现好
mNormalSink = mOutputSink;
break;
case FastMixer_Always: //永远使用FastMixer,调试用
mNormalSink = mPipeSink;
break;
case FastMixer_Static://静态。默认就是这个。但具体是否使用mPipeSink,将收到initFastMixer的控制
mNormalSink = initFastMixer ? mPipeSink : mOutputSink;
break;
}
由上所述,kUseFastMixer默认是FastMixer_Static,但mNormalSink是否指向mPipeSink,还由initFastMixer控制。这个变量本身又有mFrameCount和
mNormalFrameCount的大小决定,只有mFrameCount小于mNormalFrameCount时,initFastMixer才为真。晕了....这两个frameCount由PlaybackThread的
readOutputParameters得到。请同学们自己研究这段代码吧,就是一些简单的计算。想要搞明白的话,最好带着参数进去,把值都算出来。
好了,MixerThread的创建就分析到此,最好还是把这段代码多研究研究。了解几个兄弟对象是做什么的....