1.1.1 PlaybackThread的循环主体
当一个PlaybackThread进入主循环后(threadLoop),音频事务就正式开启了。仔细观察的话,我们会发现这个循环中会不断地调用以“threadLoop_”开头的若干接口,比如threadLoop_mix、threadLoop_sleepTime、threadLoop_standby等等。以这样的前缀开头,是因为这些函数都是在threadLoop这个主体里被调用的,可以说代表了这个PlaybackThread所需要完成的各个操作步骤。
从上一小节可以了解到,当程序执行到PlaybackThread::onFirstRef时会去真正启动一个线程承载运行threadLoop,接下来我们具体看下这个循环体的处理流程。
bool AudioFlinger::PlaybackThread::threadLoop()
{ …
while (!exitPending())/*Step1.*/
{ …
processConfigEvents();/*Step 2. */
{ /*把这段代码框起来的目的是限制自动锁变量_l的生命期,
从而灵活地实现了自动锁的控制范围*/
Mutex::Autolock _l(mLock);
…
/*Step 3. Standby判断*/
if(CC_UNLIKELY((!mActiveTracks.size() && systemTime() > standbyTime)|| mSuspended> 0)) {
if (!mStandby){
threadLoop_standby();//调用设备的
mStandby =true;
mBytesWritten = 0;
}
…
}
/*Step 4.*/
mMixerStatus =prepareTracks_l(&tracksToRemove);
…
}
/*Step5.*/
if(CC_LIKELY(mMixerStatus == MIXER_TRACKS_READY)) {
threadLoop_mix();
} else {
threadLoop_sleepTime();
}
…
/*Step 6.*/
if (sleepTime == 0) {
threadLoop_write(); //不需要休眠,有数据要写