am fd0eed00: am a2511da9: Merge "Better support for buffered streaming of rtsp content, if buffer drops below a certain threshold we will temporarily pause playback until we have sufficient data." into gingerbread

Merge commit 'fd0eed007d99178092ede56ec2c4799046615f70'

* commit 'fd0eed007d99178092ede56ec2c4799046615f70':
  Better support for buffered streaming of rtsp content, if buffer drops below a certain threshold we will temporarily pause playback until we have sufficient data.
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 183874c..e78a616 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -460,6 +460,33 @@
     }
     mBufferingEventPending = false;
 
+    int kLowWaterMarkSecs = 2;
+    int kHighWaterMarkSecs = 10;
+
+    if (mRTSPController != NULL) {
+        bool eos;
+        int64_t queueDurationUs = mRTSPController->getQueueDurationUs(&eos);
+
+        LOGV("queueDurationUs = %.2f secs", queueDurationUs / 1E6);
+
+        if ((mFlags & PLAYING) && !eos
+                && (queueDurationUs < kLowWaterMarkSecs * 1000000ll)) {
+            LOGI("rtsp cache is running low, pausing.");
+            mFlags |= CACHE_UNDERRUN;
+            pause_l();
+            notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
+        } else if ((mFlags & CACHE_UNDERRUN)
+                && (eos || queueDurationUs > kHighWaterMarkSecs * 1000000ll)) {
+            LOGI("rtsp cache has filled up, resuming.");
+            mFlags &= ~CACHE_UNDERRUN;
+            play_l();
+            notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
+        }
+
+        postBufferingEvent_l();
+        return;
+    }
+
     if (mCachedSource == NULL) {
         return;
     }
@@ -487,8 +514,8 @@
 
             notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
 
-            lowWatermark = 2 * bitrate / 8;  // 2 secs
-            highWatermark = 10 * bitrate / 8;  // 10 secs
+            lowWatermark = kLowWaterMarkSecs * bitrate / 8;
+            highWatermark = kHighWaterMarkSecs * bitrate / 8;
         }
     }
 
diff --git a/media/libstagefright/include/ARTSPController.h b/media/libstagefright/include/ARTSPController.h
index 7016880..300d8f7 100644
--- a/media/libstagefright/include/ARTSPController.h
+++ b/media/libstagefright/include/ARTSPController.h
@@ -42,6 +42,7 @@
             size_t index, uint32_t flags);
 
     int64_t getNormalPlayTimeUs();
+    int64_t getQueueDurationUs(bool *eos);
 
     void onMessageReceived(const sp<AMessage> &msg);
 
diff --git a/media/libstagefright/rtsp/APacketSource.cpp b/media/libstagefright/rtsp/APacketSource.cpp
index 75b4571..b63798f 100644
--- a/media/libstagefright/rtsp/APacketSource.cpp
+++ b/media/libstagefright/rtsp/APacketSource.cpp
@@ -746,4 +746,27 @@
     mNormalPlayTimeBaseUs = normalPlayTimeUs;
 }
 
+int64_t APacketSource::getQueueDurationUs(bool *eos) {
+    Mutex::Autolock autoLock(mLock);
+
+    *eos = (mEOSResult != OK);
+
+    if (mBuffers.size() < 2) {
+        return 0;
+    }
+
+    const sp<ABuffer> first = *mBuffers.begin();
+    const sp<ABuffer> last = *--mBuffers.end();
+
+    int64_t firstTimeUs;
+    CHECK(first->meta()->findInt64("timeUs", &firstTimeUs));
+
+    int64_t lastTimeUs;
+    CHECK(last->meta()->findInt64("timeUs", &lastTimeUs));
+
+    CHECK_GE(lastTimeUs, firstTimeUs);
+
+    return lastTimeUs - firstTimeUs;
+}
+
 }  // namespace android
diff --git a/media/libstagefright/rtsp/APacketSource.h b/media/libstagefright/rtsp/APacketSource.h
index 3833ab1..076ddc4 100644
--- a/media/libstagefright/rtsp/APacketSource.h
+++ b/media/libstagefright/rtsp/APacketSource.h
@@ -50,6 +50,8 @@
     void setNormalPlayTimeMapping(
             uint32_t rtpTime, int64_t normalPlayTimeUs);
 
+    int64_t getQueueDurationUs(bool *eos);
+
 protected:
     virtual ~APacketSource();
 
diff --git a/media/libstagefright/rtsp/ARTSPController.cpp b/media/libstagefright/rtsp/ARTSPController.cpp
index a89946b..4c53639 100644
--- a/media/libstagefright/rtsp/ARTSPController.cpp
+++ b/media/libstagefright/rtsp/ARTSPController.cpp
@@ -143,4 +143,26 @@
     return mHandler->getNormalPlayTimeUs();
 }
 
+int64_t ARTSPController::getQueueDurationUs(bool *eos) {
+    *eos = true;
+
+    int64_t minQueuedDurationUs = 0;
+    for (size_t i = 0; i < mHandler->countTracks(); ++i) {
+        sp<APacketSource> source = mHandler->getPacketSource(i);
+
+        bool newEOS;
+        int64_t queuedDurationUs = source->getQueueDurationUs(&newEOS);
+
+        if (!newEOS) {
+            *eos = false;
+        }
+
+        if (i == 0 || queuedDurationUs < minQueuedDurationUs) {
+            minQueuedDurationUs = queuedDurationUs;
+        }
+    }
+
+    return minQueuedDurationUs;
+}
+
 }  // namespace android