bool AudioFlinger::RecordThread::threadLoop()
{
AudioBufferProvider::Buffer buffer;
- sp<RecordTrack> activeTrack;
nsecs_t lastWarning = 0;
// start recording
for (;;) {
+ sp<RecordTrack> activeTrack;
Vector< sp<EffectChain> > effectChains;
{ // scope for mLock
processConfigEvents_l();
// return value 'reconfig' is currently unused
bool reconfig = checkForNewParameters_l();
- if (mActiveTrack == 0) {
+ // make a stable copy of mActiveTrack
+ activeTrack = mActiveTrack;
+ if (activeTrack == 0) {
standby();
// exitPending() can't become true here
releaseWakeLock_l();
acquireWakeLock_l();
continue;
}
- if (mActiveTrack->isTerminated()) {
- removeTrack_l(mActiveTrack);
+ if (activeTrack->isTerminated()) {
+ removeTrack_l(activeTrack);
mActiveTrack.clear();
} else {
- switch (mActiveTrack->mState) {
+ switch (activeTrack->mState) {
case TrackBase::PAUSING:
standby();
mActiveTrack.clear();
break;
case TrackBase::RESUMING:
- if (mReqChannelCount != mActiveTrack->channelCount()) {
+ if (mReqChannelCount != activeTrack->channelCount()) {
mActiveTrack.clear();
mStartStopCond.broadcast();
} else if (readOnce) {
// record start succeeds only if first read from audio input
// succeeds
if (mBytesRead >= 0) {
- mActiveTrack->mState = TrackBase::ACTIVE;
+ activeTrack->mState = TrackBase::ACTIVE;
} else {
mActiveTrack.clear();
}
break;
default:
- LOG_FATAL("Unexpected mActiveTrack->mState %d", mActiveTrack->mState);
+ LOG_FATAL("Unexpected activeTrack->mState %d", activeTrack->mState);
}
}
lockEffectChains_l(effectChains);
}
- // thread mutex is now unlocked and mActiveTrack != 0
- // FIXME RecordThread::start assigns to mActiveTrack under lock, but we read without lock
+ // thread mutex is now unlocked, mActiveTrack unknown, activeTrack != 0, kept, immutable
// FIXME RecordThread::stop assigns to mState under lock, but we read without lock
- if (mActiveTrack->mState != TrackBase::ACTIVE &&
- mActiveTrack->mState != TrackBase::RESUMING) {
+ if (activeTrack->mState != TrackBase::ACTIVE &&
+ activeTrack->mState != TrackBase::RESUMING) {
unlockEffectChains(effectChains);
usleep(kRecordThreadSleepUs);
continue;
}
buffer.frameCount = mFrameCount;
- status_t status = mActiveTrack->getNextBuffer(&buffer);
+ status_t status = activeTrack->getNextBuffer(&buffer);
if (status == NO_ERROR) {
readOnce = true;
size_t framesOut = buffer.frameCount;
if (framesIn > 0) {
int8_t *src = (int8_t *)mRsmpInBuffer + mRsmpInIndex * mFrameSize;
int8_t *dst = buffer.i8 + (buffer.frameCount - framesOut) *
- mActiveTrack->mFrameSize;
+ activeTrack->mFrameSize;
if (framesIn > framesOut) {
framesIn = framesOut;
}
mBufferSize);
if (mBytesRead <= 0) {
// FIXME read mState without lock
- if ((mBytesRead < 0) && (mActiveTrack->mState == TrackBase::ACTIVE))
+ if ((mBytesRead < 0) && (activeTrack->mState == TrackBase::ACTIVE))
{
ALOGE("Error reading audio input");
// Force input into standby so that it tries to
mResampler->resample(mRsmpOutBuffer, framesOut,
this /* AudioBufferProvider* */);
// ditherAndClamp() works as long as all buffers returned by
- // mActiveTrack->getNextBuffer() are 32 bit aligned which should be always true.
+ // activeTrack->getNextBuffer() are 32 bit aligned which should be always true.
if (mChannelCount == 2 && mReqChannelCount == 1) {
// temporarily type pun mRsmpOutBuffer from Q19.12 to int16_t
ditherAndClamp(mRsmpOutBuffer, mRsmpOutBuffer, framesOut);
}
if (mFramestoDrop == 0) {
- mActiveTrack->releaseBuffer(&buffer);
+ activeTrack->releaseBuffer(&buffer);
} else {
if (mFramestoDrop > 0) {
mFramestoDrop -= buffer.frameCount;
mSyncStartEvent->isCancelled()) {
ALOGW("Synced record %s, session %d, trigger session %d",
(mFramestoDrop >= 0) ? "timed out" : "cancelled",
- mActiveTrack->sessionId(),
+ activeTrack->sessionId(),
(mSyncStartEvent != 0) ? mSyncStartEvent->triggerSession() : 0);
clearSyncStartEvent();
}
}
}
- mActiveTrack->clearOverflow();
+ activeTrack->clearOverflow();
}
// client isn't retrieving buffers fast enough
else {
- if (!mActiveTrack->setOverflow()) {
+ if (!activeTrack->setOverflow()) {
nsecs_t now = systemTime();
if ((now - lastWarning) > kWarningThrottleNs) {
ALOGW("RecordThread: buffer overflow");