summaryrefslogtreecommitdiffstats
path: root/services/audioflinger/Threads.cpp
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2014-02-22 00:45:23 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-02-22 00:45:24 +0000
commit323da1015a758243c2c43017b026a01c6cf0c6f2 (patch)
tree232f6e026dc93462d88d3d92512c47d78b2c5e37 /services/audioflinger/Threads.cpp
parentd0e0cfa58a35508c14818b88804845194b5d80e1 (diff)
parent607fa3e928de696eba49f198af72d68e4591ca1b (diff)
downloadframeworks_av-323da1015a758243c2c43017b026a01c6cf0c6f2.zip
frameworks_av-323da1015a758243c2c43017b026a01c6cf0c6f2.tar.gz
frameworks_av-323da1015a758243c2c43017b026a01c6cf0c6f2.tar.bz2
Merge "Account for unreleased frames when predicting resampler needs"
Diffstat (limited to 'services/audioflinger/Threads.cpp')
-rw-r--r--services/audioflinger/Threads.cpp48
1 files changed, 28 insertions, 20 deletions
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 9145a0e..3e8c133 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -4694,12 +4694,12 @@ reacquire_wakelock:
framesIn = 0;
activeTrack->mRsmpInFront = rear;
overrun = OVERRUN_TRUE;
- } else if ((size_t) filled <= mRsmpInFramesP2) {
+ } else if ((size_t) filled <= mRsmpInFrames) {
framesIn = (size_t) filled;
} else {
// client is not keeping up with server, but give it latest data
- framesIn = mRsmpInFramesP2;
- activeTrack->mRsmpInFront = rear - framesIn;
+ framesIn = mRsmpInFrames;
+ activeTrack->mRsmpInFront = front = rear - framesIn;
overrun = OVERRUN_TRUE;
}
@@ -4747,32 +4747,38 @@ reacquire_wakelock:
double inOverOut = (double) mSampleRate / activeTrack->mSampleRate;
double outOverIn = (double) activeTrack->mSampleRate / mSampleRate;
framesInNeeded = ceil(framesOut * inOverOut) + 1;
+ ALOGV("need %u frames in to produce %u out given in/out ratio of %.4g",
+ framesInNeeded, framesOut, inOverOut);
+ // Although we theoretically have framesIn in circular buffer, some of those are
+ // unreleased frames, and thus must be discounted for purpose of budgeting.
+ size_t unreleased = activeTrack->mRsmpInUnrel;
+ framesIn = framesIn > unreleased ? framesIn - unreleased : 0;
if (framesIn < framesInNeeded) {
- ALOGV("not enough to resample: have %u but need %u to produce %u "
- "given in/out ratio of %.4g",
+ ALOGV("not enough to resample: have %u frames in but need %u in to "
+ "produce %u out given in/out ratio of %.4g",
framesIn, framesInNeeded, framesOut, inOverOut);
size_t newFramesOut = framesIn > 0 ? floor((framesIn - 1) * outOverIn) : 0;
- size_t newFramesInNeeded = ceil(newFramesOut * inOverOut) + 1;
- ALOGV("now need %u frames to produce %u given out/in ratio of %.4g",
- newFramesInNeeded, newFramesOut, outOverIn);
- if (framesIn < newFramesInNeeded) {
- ALOGE("failure: have %u but need %u", framesIn, newFramesInNeeded);
- framesOut = 0;
- } else {
- ALOGV("success 2: have %u and need %u to produce %u "
- "given in/out ratio of %.4g",
- framesIn, newFramesInNeeded, newFramesOut, inOverOut);
- LOG_ALWAYS_FATAL_IF(newFramesOut > framesOut);
- framesOut = newFramesOut;
+ LOG_ALWAYS_FATAL_IF(newFramesOut >= framesOut);
+ if (newFramesOut == 0) {
+ break;
}
+ framesInNeeded = ceil(newFramesOut * inOverOut) + 1;
+ ALOGV("now need %u frames in to produce %u out given out/in ratio of %.4g",
+ framesInNeeded, newFramesOut, outOverIn);
+ LOG_ALWAYS_FATAL_IF(framesIn < framesInNeeded);
+ ALOGV("success 2: have %u frames in and need %u in to produce %u out "
+ "given in/out ratio of %.4g",
+ framesIn, framesInNeeded, newFramesOut, inOverOut);
+ framesOut = newFramesOut;
} else {
- ALOGI("success 1: have %u and need %u to produce %u "
+ ALOGV("success 1: have %u in and need %u in to produce %u out "
"given in/out ratio of %.4g",
framesIn, framesInNeeded, framesOut, inOverOut);
}
// reallocate mRsmpOutBuffer as needed; we will grow but never shrink
if (activeTrack->mRsmpOutFrameCount < framesOut) {
+ // FIXME why does each track need it's own mRsmpOutBuffer? can't they share?
delete[] activeTrack->mRsmpOutBuffer;
// resampler always outputs stereo
activeTrack->mRsmpOutBuffer = new int32_t[framesOut * FCC_2];
@@ -4782,6 +4788,7 @@ reacquire_wakelock:
// resampler accumulates, but we only have one source track
memset(activeTrack->mRsmpOutBuffer, 0, framesOut * FCC_2 * sizeof(int32_t));
activeTrack->mResampler->resample(activeTrack->mRsmpOutBuffer, framesOut,
+ // FIXME how about having activeTrack implement this interface itself?
activeTrack->mResamplerBufferProvider
/*this*/ /* AudioBufferProvider* */);
// ditherAndClamp() works as long as all buffers returned by
@@ -5245,6 +5252,7 @@ status_t AudioFlinger::RecordThread::ResamplerBufferProvider::getNextBuffer(
sp<ThreadBase> threadBase = activeTrack->mThread.promote();
if (threadBase == 0) {
buffer->frameCount = 0;
+ buffer->raw = NULL;
return NOT_ENOUGH_DATA;
}
RecordThread *recordThread = (RecordThread *) threadBase.get();
@@ -5253,7 +5261,7 @@ status_t AudioFlinger::RecordThread::ResamplerBufferProvider::getNextBuffer(
ssize_t filled = rear - front;
// FIXME should not be P2 (don't want to increase latency)
// FIXME if client not keeping up, discard
- ALOG_ASSERT(0 <= filled && (size_t) filled <= recordThread->mRsmpInFramesP2);
+ LOG_ALWAYS_FATAL_IF(!(0 <= filled && (size_t) filled <= recordThread->mRsmpInFrames));
// 'filled' may be non-contiguous, so return only the first contiguous chunk
front &= recordThread->mRsmpInFramesP2 - 1;
size_t part1 = recordThread->mRsmpInFramesP2 - front;
@@ -5267,7 +5275,7 @@ status_t AudioFlinger::RecordThread::ResamplerBufferProvider::getNextBuffer(
}
if (part1 == 0) {
// Higher-level should keep mRsmpInBuffer full, and not call resampler if empty
- LOG_FATAL("RecordThread::getNextBuffer() starved");
+ LOG_ALWAYS_FATAL("RecordThread::getNextBuffer() starved");
buffer->raw = NULL;
buffer->frameCount = 0;
activeTrack->mRsmpInUnrel = 0;