diff options
author | Raph Levien <raph@google.com> | 2014-11-18 02:07:30 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-11-18 02:07:30 +0000 |
commit | fe44276c433864352d96a9bc2e9abf676b725a34 (patch) | |
tree | e703cb415c33513ffaee01da4b4eaa3d21052ca7 | |
parent | bdbcdf52bb5aa9fbd20d2e2d7877eb6549962c89 (diff) | |
parent | 0f6da1a299c8dd924d19714ee69d343915c32d2c (diff) | |
download | android_frameworks_wilhelm-fe44276c433864352d96a9bc2e9abf676b725a34.tar.gz android_frameworks_wilhelm-fe44276c433864352d96a9bc2e9abf676b725a34.tar.bz2 android_frameworks_wilhelm-fe44276c433864352d96a9bc2e9abf676b725a34.zip |
am 0f6da1a2: Reduce audio output latency
* commit '0f6da1a299c8dd924d19714ee69d343915c32d2c':
Reduce audio output latency
-rw-r--r-- | src/android/AudioPlayer_to_android.cpp | 48 | ||||
-rw-r--r-- | src/itf/IBufferQueue.c | 2 | ||||
-rw-r--r-- | src/itfstruct.h | 1 |
3 files changed, 26 insertions, 25 deletions
diff --git a/src/android/AudioPlayer_to_android.cpp b/src/android/AudioPlayer_to_android.cpp index c3244bb..d4927a4 100644 --- a/src/android/AudioPlayer_to_android.cpp +++ b/src/android/AudioPlayer_to_android.cpp @@ -1196,7 +1196,6 @@ static void audioTrack_callBack_pullFromBuffQueue(int event, void* user, void *i case android::AudioTrack::EVENT_MORE_DATA: { //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack TID=%d", gettid()); - slBufferQueueCallback callback = NULL; slPrefetchCallback prefetchCallback = NULL; void *prefetchContext = NULL; SLuint32 prefetchEvents = SL_PREFETCHEVENT_NONE; @@ -1205,6 +1204,18 @@ static void audioTrack_callBack_pullFromBuffQueue(int event, void* user, void *i // retrieve data from the buffer queue interface_lock_exclusive(&ap->mBufferQueue); + if (ap->mBufferQueue.mCallbackPending) { + // call callback with lock not held + slBufferQueueCallback callback = ap->mBufferQueue.mCallback; + if (NULL != callback) { + callbackPContext = ap->mBufferQueue.mContext; + interface_unlock_exclusive(&ap->mBufferQueue); + (*callback)(&ap->mBufferQueue.mItf, callbackPContext); + interface_lock_exclusive(&ap->mBufferQueue); + ap->mBufferQueue.mCallbackPending = false; + } + } + if (ap->mBufferQueue.mState.count != 0) { //SL_LOGV("nbBuffers in queue = %u",ap->mBufferQueue.mState.count); assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear); @@ -1212,20 +1223,19 @@ static void audioTrack_callBack_pullFromBuffQueue(int event, void* user, void *i BufferHeader *oldFront = ap->mBufferQueue.mFront; BufferHeader *newFront = &oldFront[1]; - // declared as void * because this code supports both 8-bit and 16-bit PCM data + size_t availSource = oldFront->mSize - ap->mBufferQueue.mSizeConsumed; + size_t availSink = pBuff->size; + size_t bytesToCopy = availSource < availSink ? availSource : availSink; void *pSrc = (char *)oldFront->mBuffer + ap->mBufferQueue.mSizeConsumed; - if (ap->mBufferQueue.mSizeConsumed + pBuff->size < oldFront->mSize) { - // can't consume the whole or rest of the buffer in one shot - ap->mBufferQueue.mSizeConsumed += pBuff->size; - // leave pBuff->size untouched - // consume data - // FIXME can we avoid holding the lock during the copy? - memcpy (pBuff->raw, pSrc, pBuff->size); + memcpy(pBuff->raw, pSrc, bytesToCopy); + + if (bytesToCopy < availSource) { + ap->mBufferQueue.mSizeConsumed += bytesToCopy; + // pBuff->size is already equal to bytesToCopy in this case } else { - // finish consuming the buffer or consume the buffer in one shot - pBuff->size = oldFront->mSize - ap->mBufferQueue.mSizeConsumed; + // consumed an entire buffer, dequeue + pBuff->size = bytesToCopy; ap->mBufferQueue.mSizeConsumed = 0; - if (newFront == &ap->mBufferQueue.mArray [ap->mBufferQueue.mNumBuffers + 1]) @@ -1236,16 +1246,7 @@ static void audioTrack_callBack_pullFromBuffQueue(int event, void* user, void *i ap->mBufferQueue.mState.count--; ap->mBufferQueue.mState.playIndex++; - - // consume data - // FIXME can we avoid holding the lock during the copy? - memcpy (pBuff->raw, pSrc, pBuff->size); - - // data has been consumed, and the buffer queue state has been updated - // we will notify the client if applicable - callback = ap->mBufferQueue.mCallback; - // save callback data - callbackPContext = ap->mBufferQueue.mContext; + ap->mBufferQueue.mCallbackPending = true; } } else { // empty queue // signal no data available @@ -1285,9 +1286,6 @@ static void audioTrack_callBack_pullFromBuffQueue(int event, void* user, void *i SL_PREFETCHEVENT_FILLLEVELCHANGE); } } - if (NULL != callback) { - (*callback)(&ap->mBufferQueue.mItf, callbackPContext); - } } break; diff --git a/src/itf/IBufferQueue.c b/src/itf/IBufferQueue.c index 9503694..4e310b7 100644 --- a/src/itf/IBufferQueue.c +++ b/src/itf/IBufferQueue.c @@ -96,6 +96,7 @@ SLresult IBufferQueue_Clear(SLBufferQueueItf self) thiz->mState.count = 0; thiz->mState.playIndex = 0; thiz->mSizeConsumed = 0; + thiz->mCallbackPending = false; } } #endif @@ -185,6 +186,7 @@ void IBufferQueue_init(void *self) thiz->mRear = NULL; #ifdef ANDROID thiz->mSizeConsumed = 0; + thiz->mCallbackPending = false; #endif BufferHeader *bufferHeader = thiz->mTypical; unsigned i; diff --git a/src/itfstruct.h b/src/itfstruct.h index 1712a87..537c12b 100644 --- a/src/itfstruct.h +++ b/src/itfstruct.h @@ -237,6 +237,7 @@ typedef struct BufferQueue_interface { BufferHeader *mFront, *mRear; #ifdef ANDROID SLuint32 mSizeConsumed; + bool mCallbackPending; #endif // saves a malloc in the typical case #define BUFFER_HEADER_TYPICAL 4 |