summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/media/AudioTrack.h4
-rw-r--r--include/private/media/AudioTrackShared.h29
-rw-r--r--media/libmedia/AudioRecord.cpp8
-rw-r--r--media/libmedia/AudioTrack.cpp102
-rw-r--r--services/audioflinger/AudioFlinger.cpp35
-rw-r--r--services/audioflinger/AudioFlinger.h2
6 files changed, 100 insertions, 80 deletions
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index f1b26b5..61214ec 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -510,7 +510,9 @@ protected:
float mVolume[2];
float mSendLevel;
- uint32_t mFrameCount;
+ size_t mFrameCount; // corresponds to current IAudioTrack
+ size_t mReqFrameCount; // frame count to request the next time a new
+ // IAudioTrack is needed
audio_track_cblk_t* mCblk; // re-load after mLock.unlock()
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index bbc5e26..48b6b21 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -55,7 +55,10 @@ struct audio_track_cblk_t
int mPad1; // unused, but preserves cache line alignment
- uint32_t frameCount;
+ size_t frameCount_; // used during creation to pass actual track buffer size
+ // from AudioFlinger to client, and not referenced again
+ // FIXME remove here and replace by createTrack() in/out parameter
+ // renamed to "_" to detect incorrect use
// Cache line boundary (32 bytes)
@@ -97,19 +100,23 @@ public:
// called by client only, where client includes regular
// AudioTrack and AudioFlinger::PlaybackThread::OutputTrack
- uint32_t stepUserIn(uint32_t frameCount) { return stepUser(frameCount, false); }
- uint32_t stepUserOut(uint32_t frameCount) { return stepUser(frameCount, true); }
+ uint32_t stepUserIn(size_t stepCount, size_t frameCount) { return stepUser(stepCount, frameCount, false); }
+ uint32_t stepUserOut(size_t stepCount, size_t frameCount) { return stepUser(stepCount, frameCount, true); }
- bool stepServer(uint32_t frameCount, bool isOut);
+ bool stepServer(size_t stepCount, size_t frameCount, bool isOut);
// if there is a shared buffer, "buffers" is the value of pointer() for the shared
// buffer, otherwise "buffers" points immediately after the control block
void* buffer(void *buffers, uint32_t frameSize, uint32_t offset) const;
- uint32_t framesAvailableIn() { return framesAvailable(false); }
- uint32_t framesAvailableOut() { return framesAvailable(true); }
- uint32_t framesAvailableIn_l() { return framesAvailable_l(false); }
- uint32_t framesAvailableOut_l() { return framesAvailable_l(true); }
+ uint32_t framesAvailableIn(size_t frameCount)
+ { return framesAvailable(frameCount, false); }
+ uint32_t framesAvailableOut(size_t frameCount)
+ { return framesAvailable(frameCount, true); }
+ uint32_t framesAvailableIn_l(size_t frameCount)
+ { return framesAvailable_l(frameCount, false); }
+ uint32_t framesAvailableOut_l(size_t frameCount)
+ { return framesAvailable_l(frameCount, true); }
uint32_t framesReadyIn() { return framesReady(false); }
uint32_t framesReadyOut() { return framesReady(true); }
@@ -140,9 +147,9 @@ public:
private:
// isOut == true means AudioTrack, isOut == false means AudioRecord
- uint32_t stepUser(uint32_t frameCount, bool isOut);
- uint32_t framesAvailable(bool isOut);
- uint32_t framesAvailable_l(bool isOut);
+ uint32_t stepUser(size_t stepCount, size_t frameCount, bool isOut);
+ uint32_t framesAvailable(size_t frameCount, bool isOut);
+ uint32_t framesAvailable_l(size_t frameCount, bool isOut);
uint32_t framesReady(bool isOut);
};
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 0587651..0731f00 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -216,7 +216,7 @@ status_t AudioRecord::set(
mFormat = format;
// Update buffer size in case it has been limited by AudioFlinger during track creation
- mFrameCount = mCblk->frameCount;
+ mFrameCount = mCblk->frameCount_;
mChannelCount = (uint8_t)channelCount;
mChannelMask = channelMask;
@@ -568,7 +568,7 @@ create_new_record:
}
uint32_t u = cblk->user;
- uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
+ uint32_t bufferEnd = cblk->userBase + mFrameCount;
if (framesReq > bufferEnd - u) {
framesReq = bufferEnd - u;
@@ -584,7 +584,7 @@ create_new_record:
void AudioRecord::releaseBuffer(Buffer* audioBuffer)
{
AutoMutex lock(mLock);
- mCblk->stepUserIn(audioBuffer->frameCount);
+ mCblk->stepUserIn(audioBuffer->frameCount, mFrameCount);
}
audio_io_handle_t AudioRecord::getInput() const
@@ -746,7 +746,7 @@ bool AudioRecord::processAudioBuffer(const sp<AudioRecordThread>& thread)
// Manage overrun callback
- if (active && (cblk->framesAvailableIn() == 0)) {
+ if (active && (cblk->framesAvailableIn(mFrameCount) == 0)) {
// The value of active is stale, but we are almost sure to be active here because
// otherwise we would have exited when obtainBuffer returned STOPPED earlier.
ALOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags);
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 979ee37..0be5534 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -257,6 +257,7 @@ status_t AudioTrack::set(
mVolume[RIGHT] = 1.0f;
mSendLevel = 0.0f;
mFrameCount = frameCount;
+ mReqFrameCount = frameCount;
mNotificationFramesReq = notificationFrames;
mSessionId = sessionId;
mAuxEffectId = 0;
@@ -344,7 +345,7 @@ int AudioTrack::channelCount() const
size_t AudioTrack::frameCount() const
{
- return mCblk->frameCount;
+ return mFrameCount;
}
sp<IMemory>& AudioTrack::sharedBuffer()
@@ -596,17 +597,17 @@ status_t AudioTrack::setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCou
}
if (loopStart >= loopEnd ||
- loopEnd - loopStart > cblk->frameCount ||
+ loopEnd - loopStart > mFrameCount ||
cblk->server > loopStart) {
ALOGE("setLoop invalid value: loopStart %d, loopEnd %d, loopCount %d, framecount %d, "
- "user %d", loopStart, loopEnd, loopCount, cblk->frameCount, cblk->user);
+ "user %d", loopStart, loopEnd, loopCount, mFrameCount, cblk->user);
return BAD_VALUE;
}
- if ((mSharedBuffer != 0) && (loopEnd > cblk->frameCount)) {
+ if ((mSharedBuffer != 0) && (loopEnd > mFrameCount)) {
ALOGE("setLoop invalid value: loop markers beyond data: loopStart %d, loopEnd %d, "
"framecount %d",
- loopStart, loopEnd, cblk->frameCount);
+ loopStart, loopEnd, mFrameCount);
return BAD_VALUE;
}
@@ -695,7 +696,7 @@ status_t AudioTrack::reload()
flush_l();
audio_track_cblk_t* cblk = mCblk;
- cblk->stepUserOut(cblk->frameCount);
+ cblk->stepUserOut(mFrameCount, mFrameCount);
return NO_ERROR;
}
@@ -889,17 +890,25 @@ status_t AudioTrack::createTrack_l(
mCblkMemory = iMem;
audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMem->pointer());
mCblk = cblk;
+ size_t temp = cblk->frameCount_;
+ if (temp < frameCount || (frameCount == 0 && temp == 0)) {
+ // In current design, AudioTrack client checks and ensures frame count validity before
+ // passing it to AudioFlinger so AudioFlinger should not return a different value except
+ // for fast track as it uses a special method of assigning frame count.
+ ALOGW("Requested frameCount %u but received frameCount %u", frameCount, temp);
+ }
+ frameCount = temp;
if (flags & AUDIO_OUTPUT_FLAG_FAST) {
if (trackFlags & IAudioFlinger::TRACK_FAST) {
- ALOGV("AUDIO_OUTPUT_FLAG_FAST successful; frameCount %u", cblk->frameCount);
+ ALOGV("AUDIO_OUTPUT_FLAG_FAST successful; frameCount %u", frameCount);
} else {
- ALOGV("AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount %u", cblk->frameCount);
+ ALOGV("AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount %u", frameCount);
// once denied, do not request again if IAudioTrack is re-created
flags = (audio_output_flags_t) (flags & ~AUDIO_OUTPUT_FLAG_FAST);
mFlags = flags;
}
if (sharedBuffer == 0) {
- mNotificationFramesAct = cblk->frameCount/2;
+ mNotificationFramesAct = frameCount/2;
}
}
if (sharedBuffer == 0) {
@@ -907,7 +916,7 @@ status_t AudioTrack::createTrack_l(
} else {
mBuffers = sharedBuffer->pointer();
// Force buffer full condition as data is already present in shared memory
- cblk->stepUserOut(cblk->frameCount);
+ cblk->stepUserOut(frameCount, frameCount);
}
cblk->setVolumeLR((uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) |
@@ -918,11 +927,12 @@ status_t AudioTrack::createTrack_l(
cblk->waitTimeMs = 0;
mRemainingFrames = mNotificationFramesAct;
// FIXME don't believe this lie
- mLatency = afLatency + (1000*cblk->frameCount) / sampleRate;
+ mLatency = afLatency + (1000*frameCount) / sampleRate;
+ mFrameCount = frameCount;
// If IAudioTrack is re-created, don't let the requested frameCount
// decrease. This can confuse clients that cache frameCount().
- if (cblk->frameCount > mFrameCount) {
- mFrameCount = cblk->frameCount;
+ if (frameCount > mReqFrameCount) {
+ mReqFrameCount = frameCount;
}
return NO_ERROR;
}
@@ -939,7 +949,7 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
audioBuffer->frameCount = 0;
audioBuffer->size = 0;
- uint32_t framesAvail = cblk->framesAvailableOut();
+ uint32_t framesAvail = cblk->framesAvailableOut(mFrameCount);
cblk->lock.lock();
if (cblk->flags & CBLK_INVALID) {
@@ -1015,7 +1025,7 @@ create_new_track:
}
// read the server count again
start_loop_here:
- framesAvail = cblk->framesAvailableOut_l();
+ framesAvail = cblk->framesAvailableOut_l(mFrameCount);
}
cblk->lock.unlock();
}
@@ -1027,7 +1037,7 @@ create_new_track:
}
uint32_t u = cblk->user;
- uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
+ uint32_t bufferEnd = cblk->userBase + mFrameCount;
if (framesReq > bufferEnd - u) {
framesReq = bufferEnd - u;
@@ -1044,7 +1054,7 @@ void AudioTrack::releaseBuffer(Buffer* audioBuffer)
{
AutoMutex lock(mLock);
audio_track_cblk_t* cblk = mCblk;
- cblk->stepUserOut(audioBuffer->frameCount);
+ cblk->stepUserOut(audioBuffer->frameCount, mFrameCount);
if (audioBuffer->frameCount > 0) {
// restart track if it was disabled by audioflinger due to previous underrun
if (mActive && (cblk->flags & CBLK_DISABLED)) {
@@ -1211,11 +1221,11 @@ bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
// so all cblk references might still refer to old shared memory, but that should be benign
// Manage underrun callback
- if (active && (cblk->framesAvailableOut() == cblk->frameCount)) {
+ if (active && (cblk->framesAvailableOut(mFrameCount) == mFrameCount)) {
ALOGV("Underrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags);
if (!(android_atomic_or(CBLK_UNDERRUN, &cblk->flags) & CBLK_UNDERRUN)) {
mCbf(EVENT_UNDERRUN, mUserData, 0);
- if (cblk->server == cblk->frameCount) {
+ if (cblk->server == mFrameCount) {
mCbf(EVENT_BUFFER_END, mUserData, 0);
}
if (mSharedBuffer != 0) return false;
@@ -1355,7 +1365,7 @@ status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& refCblk, bool fromStart
cblk->sampleRate,
mFormat,
mChannelMask,
- mFrameCount,
+ mReqFrameCount, // so that frame count never goes down
mFlags,
mSharedBuffer,
getOutput_l());
@@ -1379,19 +1389,19 @@ status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& refCblk, bool fromStart
if (mSharedBuffer == 0) {
uint32_t frames = 0;
if (user > server) {
- frames = ((user - server) > newCblk->frameCount) ?
- newCblk->frameCount : (user - server);
+ frames = ((user - server) > mFrameCount) ?
+ mFrameCount : (user - server);
memset(mBuffers, 0, frames * mFrameSizeAF);
}
// restart playback even if buffer is not completely filled.
android_atomic_or(CBLK_FORCEREADY, &newCblk->flags);
// stepUser() clears CBLK_UNDERRUN flag enabling underrun callbacks to
// the client
- newCblk->stepUserOut(frames);
+ newCblk->stepUserOut(frames, mFrameCount);
}
}
if (mSharedBuffer != 0) {
- newCblk->stepUserOut(newCblk->frameCount);
+ newCblk->stepUserOut(mFrameCount, mFrameCount);
}
if (mActive) {
result = mAudioTrack->start();
@@ -1429,7 +1439,7 @@ status_t AudioTrack::dump(int fd, const Vector<String16>& args) const
mVolume[0], mVolume[1]);
result.append(buffer);
snprintf(buffer, 255, " format(%d), channel count(%d), frame count(%d)\n", mFormat,
- mChannelCount, cblk->frameCount);
+ mChannelCount, mFrameCount);
result.append(buffer);
snprintf(buffer, 255, " sample rate(%u), status(%d), muted(%d)\n",
(cblk == 0) ? 0 : cblk->sampleRate, mStatus, mMuted);
@@ -1494,18 +1504,18 @@ void AudioTrack::AudioTrackThread::resume()
audio_track_cblk_t::audio_track_cblk_t()
: lock(Mutex::SHARED), cv(Condition::SHARED), user(0), server(0),
- userBase(0), serverBase(0), frameCount(0),
+ userBase(0), serverBase(0), frameCount_(0),
loopStart(UINT_MAX), loopEnd(UINT_MAX), loopCount(0), mVolumeLR(0x10001000),
mSendLevel(0), flags(0)
{
}
-uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount, bool isOut)
+uint32_t audio_track_cblk_t::stepUser(size_t stepCount, size_t frameCount, bool isOut)
{
- ALOGV("stepuser %08x %08x %d", user, server, frameCount);
+ ALOGV("stepuser %08x %08x %d", user, server, stepCount);
uint32_t u = user;
- u += frameCount;
+ u += stepCount;
// Ensure that user is never ahead of server for AudioRecord
if (isOut) {
// If stepServer() has been called once, switch to normal obtainBuffer() timeout period
@@ -1517,15 +1527,14 @@ uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount, bool isOut)
u = server;
}
- uint32_t fc = this->frameCount;
- if (u >= fc) {
+ if (u >= frameCount) {
// common case, user didn't just wrap
- if (u - fc >= userBase ) {
- userBase += fc;
+ if (u - frameCount >= userBase ) {
+ userBase += frameCount;
}
- } else if (u >= userBase + fc) {
+ } else if (u >= userBase + frameCount) {
// user just wrapped
- userBase += fc;
+ userBase += frameCount;
}
user = u;
@@ -1538,9 +1547,9 @@ uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount, bool isOut)
return u;
}
-bool audio_track_cblk_t::stepServer(uint32_t frameCount, bool isOut)
+bool audio_track_cblk_t::stepServer(size_t stepCount, size_t frameCount, bool isOut)
{
- ALOGV("stepserver %08x %08x %d", user, server, frameCount);
+ ALOGV("stepserver %08x %08x %d", user, server, stepCount);
if (!tryLock()) {
ALOGW("stepServer() could not lock cblk");
@@ -1550,7 +1559,7 @@ bool audio_track_cblk_t::stepServer(uint32_t frameCount, bool isOut)
uint32_t s = server;
bool flushed = (s == user);
- s += frameCount;
+ s += stepCount;
if (isOut) {
// Mark that we have read the first buffer so that next time stepUser() is called
// we switch to normal obtainBuffer() timeout period
@@ -1576,15 +1585,14 @@ bool audio_track_cblk_t::stepServer(uint32_t frameCount, bool isOut)
}
}
- uint32_t fc = this->frameCount;
- if (s >= fc) {
+ if (s >= frameCount) {
// common case, server didn't just wrap
- if (s - fc >= serverBase ) {
- serverBase += fc;
+ if (s - frameCount >= serverBase ) {
+ serverBase += frameCount;
}
- } else if (s >= serverBase + fc) {
+ } else if (s >= serverBase + frameCount) {
// server just wrapped
- serverBase += fc;
+ serverBase += frameCount;
}
server = s;
@@ -1601,13 +1609,13 @@ void* audio_track_cblk_t::buffer(void *buffers, size_t frameSize, uint32_t offse
return (int8_t *)buffers + (offset - userBase) * frameSize;
}
-uint32_t audio_track_cblk_t::framesAvailable(bool isOut)
+uint32_t audio_track_cblk_t::framesAvailable(size_t frameCount, bool isOut)
{
Mutex::Autolock _l(lock);
- return framesAvailable_l(isOut);
+ return framesAvailable_l(frameCount, isOut);
}
-uint32_t audio_track_cblk_t::framesAvailable_l(bool isOut)
+uint32_t audio_track_cblk_t::framesAvailable_l(size_t frameCount, bool isOut)
{
uint32_t u = user;
uint32_t s = server;
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 384f268..97bbd97 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1757,7 +1757,7 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
(
(tid != -1) &&
((frameCount == 0) ||
- (frameCount >= (int) (mFrameCount * kFastTrackMultiplier)))
+ (frameCount >= (mFrameCount * kFastTrackMultiplier)))
)
) &&
// PCM data
@@ -4202,6 +4202,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase(
mChannelCount(popcount(channelMask)),
mFrameSize(audio_is_linear_pcm(format) ?
mChannelCount * audio_bytes_per_sample(format) : sizeof(int8_t)),
+ mFrameCount(frameCount),
mStepServerFailed(false),
mSessionId(sessionId)
{
@@ -4237,7 +4238,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase(
if (mCblk != NULL) {
new(mCblk) audio_track_cblk_t();
// clear all buffers
- mCblk->frameCount = frameCount;
+ mCblk->frameCount_ = frameCount;
mCblk->sampleRate = sampleRate;
// uncomment the following lines to quickly test 32-bit wraparound
// mCblk->user = 0xffff0000;
@@ -4293,7 +4294,7 @@ bool AudioFlinger::ThreadBase::TrackBase::step() {
bool result;
audio_track_cblk_t* cblk = this->cblk();
- result = cblk->stepServer(mStepCount, isOut());
+ result = cblk->stepServer(mStepCount, mFrameCount, isOut());
if (!result) {
ALOGV("stepServer failed acquiring cblk mutex");
mStepServerFailed = true;
@@ -4508,7 +4509,7 @@ void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size)
mChannelMask,
mSessionId,
mStepCount,
- mCblk->frameCount,
+ mFrameCount,
stateChar,
mMute,
mFillingUpStatus,
@@ -4551,7 +4552,7 @@ status_t AudioFlinger::PlaybackThread::Track::getNextBuffer(
if (CC_LIKELY(framesReady)) {
uint32_t s = cblk->server;
- uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
+ uint32_t bufferEnd = cblk->serverBase + mFrameCount;
bufferEnd = (cblk->loopEnd < bufferEnd) ? cblk->loopEnd : bufferEnd;
if (framesReq > framesReady) {
@@ -4589,7 +4590,7 @@ size_t AudioFlinger::PlaybackThread::Track::framesReady() const {
bool AudioFlinger::PlaybackThread::Track::isReady() const {
if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing()) return true;
- if (framesReady() >= mCblk->frameCount ||
+ if (framesReady() >= mFrameCount ||
(mCblk->flags & CBLK_FORCEREADY)) {
mFillingUpStatus = FS_FILLED;
android_atomic_and(~CBLK_FORCEREADY, &mCblk->flags);
@@ -5435,11 +5436,11 @@ status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvi
}
// FIXME lock is not actually held, so overrun is possible
- framesAvail = cblk->framesAvailableIn_l();
+ framesAvail = cblk->framesAvailableIn_l(mFrameCount);
if (CC_LIKELY(framesAvail)) {
uint32_t s = cblk->server;
- uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
+ uint32_t bufferEnd = cblk->serverBase + mFrameCount;
if (framesReq > framesAvail) {
framesReq = framesAvail;
@@ -5508,7 +5509,7 @@ void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size)
mCblk->sampleRate,
mCblk->server,
mCblk->user,
- mCblk->frameCount);
+ mFrameCount);
}
bool AudioFlinger::RecordThread::RecordTrack::isOut() const
@@ -5585,9 +5586,9 @@ bool AudioFlinger::PlaybackThread::OutputTrack::write(int16_t* data, uint32_t fr
sp<ThreadBase> thread = mThread.promote();
if (thread != 0) {
MixerThread *mixerThread = (MixerThread *)thread.get();
- if (mCblk->frameCount > frames){
+ if (mFrameCount > frames){
if (mBufferQueue.size() < kMaxOverFlowBuffers) {
- uint32_t startFrames = (mCblk->frameCount - frames);
+ uint32_t startFrames = (mFrameCount - frames);
pInBuffer = new Buffer;
pInBuffer->mBuffer = new int16_t[startFrames * channelCount];
pInBuffer->frameCount = startFrames;
@@ -5633,7 +5634,7 @@ bool AudioFlinger::PlaybackThread::OutputTrack::write(int16_t* data, uint32_t fr
uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount :
pInBuffer->frameCount;
memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * channelCount * sizeof(int16_t));
- mCblk->stepUserOut(outFrames);
+ mCblk->stepUserOut(outFrames, mFrameCount);
pInBuffer->frameCount -= outFrames;
pInBuffer->i16 += outFrames * channelCount;
mOutBuffer.frameCount -= outFrames;
@@ -5677,8 +5678,8 @@ bool AudioFlinger::PlaybackThread::OutputTrack::write(int16_t* data, uint32_t fr
// If no more buffers are pending, fill output track buffer to make sure it is started
// by output mixer.
if (frames == 0 && mBufferQueue.size() == 0) {
- if (mCblk->user < mCblk->frameCount) {
- frames = mCblk->frameCount - mCblk->user;
+ if (mCblk->user < mFrameCount) {
+ frames = mFrameCount - mCblk->user;
pInBuffer = new Buffer;
pInBuffer->mBuffer = new int16_t[frames * channelCount];
pInBuffer->frameCount = frames;
@@ -5704,7 +5705,7 @@ status_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(
ALOGVV("OutputTrack::obtainBuffer user %d, server %d", cblk->user, cblk->server);
buffer->frameCount = 0;
- uint32_t framesAvail = cblk->framesAvailableOut();
+ uint32_t framesAvail = cblk->framesAvailableOut(mFrameCount);
if (framesAvail == 0) {
@@ -5722,7 +5723,7 @@ status_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(
}
// read the server count again
start_loop_here:
- framesAvail = cblk->framesAvailableOut_l();
+ framesAvail = cblk->framesAvailableOut_l(mFrameCount);
}
}
@@ -5735,7 +5736,7 @@ status_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(
}
uint32_t u = cblk->user;
- uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
+ uint32_t bufferEnd = cblk->userBase + mFrameCount;
if (framesReq > bufferEnd - u) {
framesReq = bufferEnd - u;
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 830dfe9..75bfcfe 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -478,6 +478,8 @@ private:
const size_t mFrameSize; // AudioFlinger's view of frame size in shared memory,
// where for AudioTrack (but not AudioRecord),
// 8-bit PCM samples are stored as 16-bit
+ const size_t mFrameCount;// size of track buffer given at createTrack() or
+ // openRecord(), and then adjusted as needed
bool mStepServerFailed;
const int mSessionId;
Vector < sp<SyncEvent> >mSyncEvents;