diff options
| author | Marco Nelissen <marcone@google.com> | 2012-03-30 14:36:54 -0700 |
|---|---|---|
| committer | Marco Nelissen <marcone@google.com> | 2012-03-30 21:21:36 -0700 |
| commit | a1472d9883e35edd280201c8be3191695007dfd4 (patch) | |
| tree | 22d33eed0e95560b5fe989ace6a2e0f53aff3790 | |
| parent | 40a1da57d21bbc883630e7a854a279685fe1fa61 (diff) | |
| download | frameworks_av-a1472d9883e35edd280201c8be3191695007dfd4.zip frameworks_av-a1472d9883e35edd280201c8be3191695007dfd4.tar.gz frameworks_av-a1472d9883e35edd280201c8be3191695007dfd4.tar.bz2 | |
Make AudioTrack/AudioRecord handle more than 2^32 frames
b/6160363
Change-Id: I471815012c6a113ec2c4dd7676e8fa288a70bc76
| -rw-r--r-- | media/libmedia/AudioRecord.cpp | 2 | ||||
| -rw-r--r-- | media/libmedia/AudioTrack.cpp | 35 | ||||
| -rw-r--r-- | services/audioflinger/AudioFlinger.cpp | 18 |
3 files changed, 42 insertions, 13 deletions
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index 444665a..1fdc536 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -577,7 +577,7 @@ create_new_record: uint32_t u = cblk->user; uint32_t bufferEnd = cblk->userBase + cblk->frameCount; - if (u + framesReq > bufferEnd) { + if (framesReq > bufferEnd - u) { framesReq = bufferEnd - u; } diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index bafde3a..d73eabd 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -952,7 +952,7 @@ create_new_track: uint32_t u = cblk->user; uint32_t bufferEnd = cblk->userBase + cblk->frameCount; - if (u + framesReq > bufferEnd) { + if (framesReq > bufferEnd - u) { framesReq = bufferEnd - u; } @@ -1382,8 +1382,9 @@ audio_track_cblk_t::audio_track_cblk_t() uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount) { - uint32_t u = user; + ALOGV("stepuser %08x %08x %d", user, server, frameCount); + uint32_t u = user; u += frameCount; // Ensure that user is never ahead of server for AudioRecord if (flags & CBLK_DIRECTION_MSK) { @@ -1392,12 +1393,19 @@ uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount) bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; } } else if (u > server) { - ALOGW("stepServer occurred after track reset"); + ALOGW("stepUser occurred after track reset"); u = server; } - if (u >= userBase + this->frameCount) { - userBase += this->frameCount; + uint32_t fc = this->frameCount; + if (u >= fc) { + // common case, user didn't just wrap + if (u - fc >= userBase ) { + userBase += fc; + } + } else if (u >= userBase + fc) { + // user just wrapped + userBase += fc; } user = u; @@ -1412,12 +1420,15 @@ uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount) bool audio_track_cblk_t::stepServer(uint32_t frameCount) { + ALOGV("stepserver %08x %08x %d", user, server, frameCount); + if (!tryLock()) { ALOGW("stepServer() could not lock cblk"); return false; } uint32_t s = server; + bool flushed = (s == user); s += frameCount; if (flags & CBLK_DIRECTION_MSK) { @@ -1430,7 +1441,7 @@ bool audio_track_cblk_t::stepServer(uint32_t frameCount) // while the mixer is processing a block: in this case, // stepServer() is called After the flush() has reset u & s and // we have s > u - if (s > user) { + if (flushed) { ALOGW("stepServer occurred after track reset"); s = user; } @@ -1444,8 +1455,16 @@ bool audio_track_cblk_t::stepServer(uint32_t frameCount) loopStart = UINT_MAX; } } - if (s >= serverBase + this->frameCount) { - serverBase += this->frameCount; + + uint32_t fc = this->frameCount; + if (s >= fc) { + // common case, server didn't just wrap + if (s - fc >= serverBase ) { + serverBase += fc; + } + } else if (s >= serverBase + fc) { + // server just wrapped + serverBase += fc; } server = s; diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 8662cb5..83af5f3 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -3409,6 +3409,11 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( // clear all buffers mCblk->frameCount = frameCount; mCblk->sampleRate = sampleRate; +// uncomment the following lines to quickly test 32-bit wraparound +// mCblk->user = 0xffff0000; +// mCblk->server = 0xffff0000; +// mCblk->userBase = 0xffff0000; +// mCblk->serverBase = 0xffff0000; mChannelCount = channelCount; mChannelMask = channelMask; if (sharedBuffer == 0) { @@ -3434,6 +3439,11 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( // clear all buffers mCblk->frameCount = frameCount; mCblk->sampleRate = sampleRate; +// uncomment the following lines to quickly test 32-bit wraparound +// mCblk->user = 0xffff0000; +// mCblk->server = 0xffff0000; +// mCblk->userBase = 0xffff0000; +// mCblk->serverBase = 0xffff0000; mChannelCount = channelCount; mChannelMask = channelMask; mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t); @@ -3513,7 +3523,7 @@ void* AudioFlinger::ThreadBase::TrackBase::getBuffer(uint32_t offset, uint32_t f if (bufferStart < mBuffer || bufferStart > bufferEnd || bufferEnd > mBufferEnd || ((unsigned long)bufferStart & (unsigned long)(frameSize - 1))) { ALOGE("TrackBase::getBuffer buffer out of range:\n start: %p, end %p , mBuffer %p mBufferEnd %p\n \ - server %d, serverBase %d, user %d, userBase %d", + server %u, serverBase %u, user %u, userBase %u", bufferStart, bufferEnd, mBuffer, mBufferEnd, cblk->server, cblk->serverBase, cblk->user, cblk->userBase); return NULL; @@ -3656,7 +3666,7 @@ status_t AudioFlinger::PlaybackThread::Track::getNextBuffer( if (framesReq > framesReady) { framesReq = framesReady; } - if (s + framesReq > bufferEnd) { + if (framesReq > bufferEnd - s) { framesReq = bufferEnd - s; } @@ -4323,7 +4333,7 @@ status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvi if (framesReq > framesAvail) { framesReq = framesAvail; } - if (s + framesReq > bufferEnd) { + if (framesReq > bufferEnd - s) { framesReq = bufferEnd - s; } @@ -4596,7 +4606,7 @@ status_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(AudioBufferProv uint32_t u = cblk->user; uint32_t bufferEnd = cblk->userBase + cblk->frameCount; - if (u + framesReq > bufferEnd) { + if (framesReq > bufferEnd - u) { framesReq = bufferEnd - u; } |
