bool AudioFlinger::PlaybackThread::threadLoop()
{
Vector< sp<Track> > tracksToRemove;
standbyTime = systemTime();
// MIXER
nsecs_t lastWarning = 0;
// DUPLICATING
// FIXME could this be made local to while loop?
writeFrames = 0;
int lastGeneration = 0;
cacheParameters_l();
sleepTime = idleSleepTime;
if (mType == MIXER) {
sleepTimeShift = 0;
}
CpuStats cpuStats;
const String8 myName(String8::format("thread %p type %d TID %d", this, mType, gettid()));
acquireWakeLock();
// mNBLogWriter->log can only be called while thread mutex mLock is held.
// So if you need to log when mutex is unlocked, set logString to a non-NULL string,
// and then that string will be logged at the next convenient opportunity.
const char *logString = NULL;
checkSilentMode_l();
while (!exitPending())
{
cpuStats.sample(myName);
Vector< sp<EffectChain> > effectChains;
processConfigEvents();
{ // scope for mLock
Mutex::Autolock _l(mLock);
if (logString != NULL) {
mNBLogWriter->logTimestamp();
mNBLogWriter->log(logString);
logString = NULL;
}
if (mLatchDValid) {
mLatchQ = mLatchD;
mLatchDValid = false;
mLatchQValid = true;
}
//检查客户端设置的更新,客户端通过setParameters进行设置
if (checkForNewParameters_l()) {
cacheParameters_l();
}
saveOutputTracks();
//判断是否有track加入
if (mSignalPending) {
// A signal was raised while we were unlocked
mSignalPending = false;
} else if (waitingAsyncCallback_l()) {//offload时返回true
if (exitPending()) {
break;
}
releaseWakeLock_l();
mWakeLockUids.clear();
mActiveTracksGeneration++;
ALOGV("wait async completion");
mWaitWorkCV.wait(mLock);
ALOGV("async completion/wake");
acquireWakeLock_l();
standbyTime = systemTime() + standbyDelay;
sleepTime = 0;
continue;
}
//两种情况需要硬件进入standby
//第一:没有活跃音轨而且standbyTime过期
//第二:需要Suspend
if ((!mActiveTracks.size() && systemTime() > standbyTime) ||
isSuspended()) {
// put audio hardware into standby after short delay
if (shouldStandby_l()) {
threadLoop_standby();
mStandby = true;
}
//如果当前config event也为空,则进入阻塞状态
if (!mActiveTracks.size() && mConfigEvents.isEmpty()) {
// we're about to wait, flush the binder command buffer
IPCThreadState::self()->flushCommands();
clearOutputTracks();
if (exitPending()) {
break;
}
releaseWakeLock_l();
mWakeLockUids.clear();
mActiveTracksGeneration++;
// wait until we have something to do...
// 当前没有可供使用的active track,进程进入阻塞状态,
// 等待广播消息唤醒,包括配置参数、活跃音轨添加等消息
ALOGV("%s going to sleep", myName.string());
mWaitWorkCV.wait(mLock);
ALOGV("%s waking up", myName.string());
acquireWakeLock_l();
mMixerStatus = MIXER_IDLE;
mMixerStatusIgnoringFastTracks = MIXER_IDLE;
mBytesWritten = 0;
mBytesRemaining = 0;
checkSilentMode_l();
standbyTime = systemTime() + standbyDelay;
sleepTime = idleSleepTime;
if (mType == MIXER) {
sleepTimeShift = 0;
}
continue;
}
}
// mMixerStatusIgnoringFastTracks is also updated internally
// 准备音轨,为混音做准备
mMixerStatus = prepareTracks_l(&tracksToRemove);
// compare with previously applied list
if (lastGeneration != mActiveTracksGeneration) {
// update wakelock
updateWakeLockUids_l(mWakeLockUids);
lastGeneration = mActiveTracksGeneration;
}
// prevent any changes in effect chain list and in each effect chain
// during mixin
Audio笔记之PlaybackThread::threadLoop
最新推荐文章于 2024-06-26 18:13:05 发布
本文详细介绍了AudioFlinger的PlaybackThread::threadLoop函数,涉及音频线程的循环处理,包括混音、音效处理、硬件standby状态、线程休眠和唤醒策略等关键步骤,揭示了Android音频系统的内部工作原理。
摘要由CSDN通过智能技术生成