summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRicardo Cerqueira <ricardo@cyngn.com>2015-03-10 12:15:27 +0000
committerRicardo Cerqueira <ricardo@cyngn.com>2015-03-10 12:15:27 +0000
commit28cf945776a3cbf050e41ae801c3af81a9b4966d (patch)
treecefe35bf9d363433b18b45a1e8c6d351a54ce022
parent82637341b77a175882e43af8c1d942cca4e07bbc (diff)
parent0f6da1a299c8dd924d19714ee69d343915c32d2c (diff)
downloadandroid_frameworks_wilhelm-stable/cm-12.1-YOG4P.tar.gz
android_frameworks_wilhelm-stable/cm-12.1-YOG4P.tar.bz2
android_frameworks_wilhelm-stable/cm-12.1-YOG4P.zip
Android 5.1.0 release 1
-rw-r--r--src/android/AudioPlayer_to_android.cpp48
-rw-r--r--src/itf/IBufferQueue.c2
-rw-r--r--src/itfstruct.h1
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