The prefetched source was unnecessarily holding a lock while receiving data from the network, sometimes blocking for seconds over 2G networks with corresponding drops in audio playback. Also, if the cache was full we'd report a cache duration of 0 instead of maximum size.

Change-Id: I46c8083f12f2dd728302095369197ca7e6b78bf8
related-to-bugs: 2492187, 2444425
diff --git a/media/libstagefright/Prefetcher.cpp b/media/libstagefright/Prefetcher.cpp
index 9c73f4a..89cd30e 100644
--- a/media/libstagefright/Prefetcher.cpp
+++ b/media/libstagefright/Prefetcher.cpp
@@ -59,6 +59,7 @@
     int64_t mSeekTimeUs;
     int64_t mCacheDurationUs;
     bool mPrefetcherStopped;
+    bool mCurrentlyPrefetching;
 
     List<MediaBuffer *> mCachedBuffers;
 
@@ -205,10 +206,6 @@
             continue;
         }
 
-        if (cacheDurationUs >= kMaxCacheDurationUs) {
-            continue;
-        }
-
         if (minIndex < 0 || cacheDurationUs < minCacheDurationUs) {
             minCacheDurationUs = cacheDurationUs;
             minIndex = i;
@@ -245,7 +242,8 @@
       mReachedEOS(false),
       mSeekTimeUs(0),
       mCacheDurationUs(0),
-      mPrefetcherStopped(false) {
+      mPrefetcherStopped(false),
+      mCurrentlyPrefetching(false) {
 }
 
 PrefetchedSource::~PrefetchedSource() {
@@ -275,6 +273,10 @@
 
     Mutex::Autolock autoLock(mLock);
 
+    while (mCurrentlyPrefetching) {
+        mCondition.wait(mLock);
+    }
+
     clearCache_l();
 
     status_t err = mSource->stop();
@@ -344,15 +346,24 @@
         return;
     }
 
+    mCurrentlyPrefetching = true;
+
     if (mSeekTimeUs >= 0) {
         options.setSeekTo(mSeekTimeUs);
         mSeekTimeUs = -1;
     }
 
+    // Ensure our object does not go away while we're not holding
+    // the lock.
+    sp<PrefetchedSource> me = this;
+
+    mLock.unlock();
     MediaBuffer *buffer;
     status_t err = mSource->read(&buffer, &options);
+    mLock.lock();
 
     if (err != OK) {
+        mCurrentlyPrefetching = false;
         mReachedEOS = true;
         mFinalStatus = err;
         mCondition.signal();
@@ -380,6 +391,8 @@
 
     mCachedBuffers.push_back(copy);
     updateCacheDuration_l();
+
+    mCurrentlyPrefetching = false;
     mCondition.signal();
 }