diff options
Diffstat (limited to 'src')
-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 568350e..69ba9c0 100644 --- a/src/android/AudioPlayer_to_android.cpp +++ b/src/android/AudioPlayer_to_android.cpp @@ -1188,7 +1188,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; @@ -1197,6 +1196,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); @@ -1204,20 +1215,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]) @@ -1228,16 +1238,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 @@ -1277,9 +1278,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 |