summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/private/media/AudioTrackShared.h2
-rw-r--r--media/libmedia/AudioTrack.cpp67
-rw-r--r--media/libmedia/AudioTrackShared.cpp7
3 files changed, 37 insertions, 39 deletions
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index ad7409d..fe258ad 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -383,8 +383,6 @@ public:
protected:
size_t mAvailToClient; // estimated frames available to client prior to releaseBuffer()
int32_t mFlush; // our copy of cblk->u.mStreaming.mFlush, for streaming output only
-private:
- bool mDeferWake; // whether another releaseBuffer() is expected soon
};
// Proxy used by AudioFlinger for servicing AudioTrack
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 744faee..15249a4 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -815,12 +815,29 @@ status_t AudioTrack::createTrack_l(
return NO_INIT;
}
+ // Not all of these values are needed under all conditions, but it is easier to get them all
+
uint32_t afLatency;
- if ((status = AudioSystem::getLatency(output, streamType, &afLatency)) != NO_ERROR) {
+ status = AudioSystem::getLatency(output, streamType, &afLatency);
+ if (status != NO_ERROR) {
ALOGE("getLatency(%d) failed status %d", output, status);
return NO_INIT;
}
+ size_t afFrameCount;
+ status = AudioSystem::getFrameCount(output, streamType, &afFrameCount);
+ if (status != NO_ERROR) {
+ ALOGE("getFrameCount(output=%d, streamType=%d) status %d", output, streamType, status);
+ return NO_INIT;
+ }
+
+ uint32_t afSampleRate;
+ status = AudioSystem::getSamplingRate(output, streamType, &afSampleRate);
+ if (status != NO_ERROR) {
+ ALOGE("getSamplingRate(output=%d, streamType=%d) status %d", output, streamType, status);
+ return NO_INIT;
+ }
+
// Client decides whether the track is TIMED (see below), but can only express a preference
// for FAST. Server will perform additional tests.
if ((flags & AUDIO_OUTPUT_FLAG_FAST) && !(
@@ -836,6 +853,14 @@ status_t AudioTrack::createTrack_l(
}
ALOGV("createTrack_l() output %d afLatency %d", output, afLatency);
+ // The client's AudioTrack buffer is divided into n parts for purpose of wakeup by server, where
+ // n = 1 fast track; nBuffering is ignored
+ // n = 2 normal track, no sample rate conversion
+ // n = 3 normal track, with sample rate conversion
+ // (pessimistic; some non-1:1 conversion ratios don't actually need triple-buffering)
+ // n > 3 very high latency or very small notification interval; nBuffering is ignored
+ const uint32_t nBuffering = (sampleRate == afSampleRate) ? 2 : 3;
+
mNotificationFramesAct = mNotificationFramesReq;
if (!audio_is_linear_pcm(format)) {
@@ -844,13 +869,6 @@ status_t AudioTrack::createTrack_l(
// Same comment as below about ignoring frameCount parameter for set()
frameCount = sharedBuffer->size();
} else if (frameCount == 0) {
- size_t afFrameCount;
- status = AudioSystem::getFrameCount(output, streamType, &afFrameCount);
- if (status != NO_ERROR) {
- ALOGE("getFrameCount(output=%d, streamType=%d) status %d", output, streamType,
- status);
- return NO_INIT;
- }
frameCount = afFrameCount;
}
if (mNotificationFramesAct != frameCount) {
@@ -880,26 +898,13 @@ status_t AudioTrack::createTrack_l(
} else if (!(flags & AUDIO_OUTPUT_FLAG_FAST)) {
// FIXME move these calculations and associated checks to server
- uint32_t afSampleRate;
- status = AudioSystem::getSamplingRate(output, streamType, &afSampleRate);
- if (status != NO_ERROR) {
- ALOGE("getSamplingRate(output=%d, streamType=%d) status %d", output, streamType,
- status);
- return NO_INIT;
- }
- size_t afFrameCount;
- status = AudioSystem::getFrameCount(output, streamType, &afFrameCount);
- if (status != NO_ERROR) {
- ALOGE("getFrameCount(output=%d, streamType=%d) status %d", output, streamType, status);
- return NO_INIT;
- }
// Ensure that buffer depth covers at least audio hardware latency
uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate);
ALOGV("afFrameCount=%d, minBufCount=%d, afSampleRate=%u, afLatency=%d",
afFrameCount, minBufCount, afSampleRate, afLatency);
- if (minBufCount <= 2) {
- minBufCount = sampleRate == afSampleRate ? 2 : 3;
+ if (minBufCount <= nBuffering) {
+ minBufCount = nBuffering;
}
size_t minFrameCount = (afFrameCount*sampleRate*minBufCount)/afSampleRate;
@@ -909,18 +914,16 @@ status_t AudioTrack::createTrack_l(
if (frameCount == 0) {
frameCount = minFrameCount;
- }
- // Make sure that application is notified with sufficient margin
- // before underrun
- if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount/2) {
- mNotificationFramesAct = frameCount/2;
- }
- if (frameCount < minFrameCount) {
+ } else if (frameCount < minFrameCount) {
// not ALOGW because it happens all the time when playing key clicks over A2DP
ALOGV("Minimum buffer size corrected from %d to %d",
frameCount, minFrameCount);
frameCount = minFrameCount;
}
+ // Make sure that application is notified with sufficient margin before underrun
+ if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount/nBuffering) {
+ mNotificationFramesAct = frameCount/nBuffering;
+ }
} else {
// For fast tracks, the frame count calculations and checks are done by server
@@ -1001,8 +1004,8 @@ status_t AudioTrack::createTrack_l(
flags = (audio_output_flags_t) (flags & ~AUDIO_OUTPUT_FLAG_FAST);
mFlags = flags;
if (sharedBuffer == 0) {
- if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount/2) {
- mNotificationFramesAct = frameCount/2;
+ if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount/nBuffering) {
+ mNotificationFramesAct = frameCount/nBuffering;
}
}
}
diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp
index e7abb40..4fd92b2 100644
--- a/media/libmedia/AudioTrackShared.cpp
+++ b/media/libmedia/AudioTrackShared.cpp
@@ -481,7 +481,7 @@ size_t StaticAudioTrackClientProxy::getBufferPosition()
ServerProxy::ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
size_t frameSize, bool isOut, bool clientInServer)
: Proxy(cblk, buffers, frameCount, frameSize, isOut, clientInServer),
- mAvailToClient(0), mFlush(0), mDeferWake(false)
+ mAvailToClient(0), mFlush(0)
{
}
@@ -559,9 +559,6 @@ status_t ServerProxy::obtainBuffer(Buffer* buffer)
&((char *) mBuffers)[(mIsOut ? front : rear) * mFrameSize] : NULL;
buffer->mNonContig = availToServer - part1;
mUnreleased = part1;
- // optimization to avoid waking up the client too early
- // FIXME need to test for recording
- mDeferWake = part1 < ask && availToServer >= ask;
return part1 > 0 ? NO_ERROR : WOULD_BLOCK;
}
no_init:
@@ -607,7 +604,7 @@ void ServerProxy::releaseBuffer(Buffer* buffer)
minimum = half;
}
// FIXME AudioRecord wakeup needs to be optimized; it currently wakes up client every time
- if (!mIsOut || (!mDeferWake && mAvailToClient + stepCount >= minimum)) {
+ if (!mIsOut || (mAvailToClient + stepCount >= minimum)) {
ALOGV("mAvailToClient=%u stepCount=%u minimum=%u", mAvailToClient, stepCount, minimum);
int32_t old = android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);
if (!(old & CBLK_FUTEX_WAKE)) {