OSDN Git Service

Fix 5249076 Don't let the shared memory buffer drain
authorJean-Michel Trivi <jmtrivi@google.com>
Fri, 2 Sep 2011 02:21:23 +0000 (19:21 -0700)
committerJean-Michel Trivi <jmtrivi@google.com>
Tue, 6 Sep 2011 22:35:39 +0000 (15:35 -0700)
Whenever pushing data to the shared memory from the
 AndroidBufferQueue, post a message to do the same operation
 again if there is still room in the shared memory. This
 ensures the consumption of data will keep the
 shared memory buffer full, not the notification of space
 available in shared memory, which may happen while the
 Android Buffer Queue is empty (after a clear() for
 instance).

Change-Id: I397d70ebb927fa6a1d0fb97321a70db0440b96fe

wilhelm/src/android/AudioPlayer_to_android.cpp
wilhelm/src/android/MediaPlayer_to_android.cpp
wilhelm/src/android/android_StreamPlayer.cpp
wilhelm/src/android/android_StreamPlayer.h

index 38ebbe8..ad7e818 100644 (file)
@@ -2267,7 +2267,7 @@ void android_audioPlayer_androidBufferQueue_onRefilled_l(CAudioPlayer *ap) {
     case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:
       if (ap->mAPlayer != 0) {
         android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get());
-        splr->queueRefilled_l();
+        splr->queueRefilled();
       } break;
     case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
       // FIXME this may require waking up the decoder if it is currently starved and isn't polling
index 65e5e32..3156766 100644 (file)
@@ -668,7 +668,7 @@ void android_Player_androidBufferQueue_onRefilled_l(CMediaPlayer *mp) {
     if ((mp->mAndroidObjType == AUDIOVIDEOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE)
             && (mp->mAVPlayer != 0)) {
         android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(mp->mAVPlayer.get());
-        splr->queueRefilled_l();
+        splr->queueRefilled();
     }
 }
 
index f83b4dc..1943a06 100644 (file)
@@ -45,13 +45,15 @@ namespace android {
 
 StreamSourceAppProxy::StreamSourceAppProxy(
         const void* user, bool userIsAudioPlayer,
-        void *context, const void *caller, const sp<CallbackProtector> &callbackProtector) :
+        void *context, const void *caller, const sp<CallbackProtector> &callbackProtector,
+        const sp<StreamPlayer> &player) :
     mUser(user),
     mUserIsAudioPlayer(userIsAudioPlayer),
     mAndroidBufferQueue(NULL),
     mAppContext(context),
     mCaller(caller),
-    mCallbackProtector(callbackProtector)
+    mCallbackProtector(callbackProtector),
+    mPlayer(player)
 {
     SL_LOGV("StreamSourceAppProxy::StreamSourceAppProxy()");
 
@@ -115,7 +117,7 @@ void StreamSourceAppProxy::receivedBuffer_l(size_t buffIndex, size_t buffLength)
 }
 
 //--------------------------------------------------
-// consumption from ABQ
+// consumption from ABQ: pull from the ABQ, and push to shared memory (media server)
 void StreamSourceAppProxy::pullFromBuffQueue() {
 
   if (android::CallbackProtector::enterCbIfOk(mCallbackProtector)) {
@@ -221,8 +223,12 @@ void StreamSourceAppProxy::pullFromBuffQueue() {
                         //dataUsed     = oldFront->mDataSizeConsumed;
                     }
                 }
-                //SL_LOGD("onBufferAvailable() %d buffers available after enqueue",
-                //     mAvailableBuffers.size());
+                //SL_LOGD("%d buffers available after enqueue", mAvailableBuffers.size());
+                if (!mAvailableBuffers.empty()) {
+                    // there is still room in the shared memory, recheck later if we can pull
+                    // data from the buffer queue and write it to shared memory
+                    mPlayer->queueRefilled();
+                }
             }
         }
 
@@ -280,8 +286,8 @@ StreamPlayer::~StreamPlayer() {
 
 void StreamPlayer::onMessageReceived(const sp<AMessage> &msg) {
     switch (msg->what()) {
-        case kWhatQueueRefilled:
-            onQueueRefilled();
+        case kWhatPullFromAbq:
+            onPullFromAndroidBufferQueue();
             break;
 
         default:
@@ -300,7 +306,7 @@ void StreamPlayer::registerQueueCallback(
 
     mAppProxy = new StreamSourceAppProxy(
             user, userIsAudioPlayer,
-            context, caller, mCallbackProtector);
+            context, caller, mCallbackProtector, this);
 
     CHECK(mAppProxy != 0);
     SL_LOGD("StreamPlayer::registerQueueCallback end");
@@ -308,11 +314,12 @@ void StreamPlayer::registerQueueCallback(
 
 
 /**
- * Called with a lock on ABQ
+ * Asynchronously notify the player that the queue is ready to be pulled from.
  */
-void StreamPlayer::queueRefilled_l() {
-    // async notification that the ABQ was refilled
-    (new AMessage(kWhatQueueRefilled, id()))->post();
+void StreamPlayer::queueRefilled() {
+    // async notification that the ABQ was refilled: the player should pull from the ABQ, and
+    //    and push to shared memory (to the media server)
+    (new AMessage(kWhatPullFromAbq, id()))->post();
 }
 
 
@@ -351,13 +358,13 @@ void StreamPlayer::onPlay() {
     SL_LOGD("StreamPlayer::onPlay()");
     // enqueue a message that will cause StreamAppProxy to consume from the queue (again if the
     // player had starved the shared memory)
-    queueRefilled_l();
+    queueRefilled();
 
     GenericMediaPlayer::onPlay();
 }
 
 
-void StreamPlayer::onQueueRefilled() {
+void StreamPlayer::onPullFromAndroidBufferQueue() {
     //SL_LOGD("StreamPlayer::onQueueRefilled()");
     Mutex::Autolock _l(mAppProxyLock);
     if (mAppProxy != 0) {
index 2bd745c..b84a056 100644 (file)
 namespace android {
 
 //--------------------------------------------------------------------------------------------------
+class StreamPlayer;
+
 class StreamSourceAppProxy : public BnStreamSource {
 public:
     StreamSourceAppProxy(
             const void* user, bool userIsAudioPlayer,
             void *appContext,
             const void *caller,
-            const sp<CallbackProtector> &callbackProtector);
+            const sp<CallbackProtector> &callbackProtector,
+            const sp<StreamPlayer> &player);
     virtual ~StreamSourceAppProxy();
 
     // store an item structure to indicate a processed buffer
@@ -67,6 +70,7 @@ private:
     const void *mCaller;
 
     sp<CallbackProtector> mCallbackProtector;
+    const sp<StreamPlayer> mPlayer;
 
     DISALLOW_EVIL_CONSTRUCTORS(StreamSourceAppProxy);
 };
@@ -86,14 +90,18 @@ public:
             const void* user, bool userIsAudioPlayer,
             void *context,
             const void *caller);
-    void queueRefilled_l();
+    void queueRefilled();
     void appClear_l();
 
 protected:
 
     enum {
-        // message to asynchronously notify mAppProxy the Android Buffer Queue was refilled
-        kWhatQueueRefilled = 'qrfi'
+        // message to asynchronously notify mAppProxy it should try to pull from the Android
+        //    Buffer Queue and push to shared memory (media server), either because the buffer queue
+        //    was refilled, or because during playback, the shared memory buffers should remain
+        //    filled to prevent it from draining (this can happen if the ABQ is not ready
+        //    whenever a shared memory buffer becomes available)
+        kWhatPullFromAbq = 'plfq'
     };
 
     sp<StreamSourceAppProxy> mAppProxy; // application proxy for the android buffer queue source
@@ -102,7 +110,7 @@ protected:
     virtual void onPrepare();
     virtual void onPlay();
 
-    void onQueueRefilled();
+    void onPullFromAndroidBufferQueue();
 
     Mutex mAppProxyLock;