The audio track was accidentally not participating in the prefetch since it wasn't started at the time prepare() was called. Also, properly report the cached duration even near the end when the source has no more data to fetch.

Change-Id: I66a92fec24c9bfb25f1c186f1c877127bae2b4f9
related-to-bug: 2444425
diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h
index ea15a5c..9af5871 100644
--- a/include/media/stagefright/AudioPlayer.h
+++ b/include/media/stagefright/AudioPlayer.h
@@ -44,7 +44,7 @@
     // Return time in us.
     virtual int64_t getRealTimeUs();
 
-    status_t start();
+    status_t start(bool sourceAlreadyStarted = false);
 
     void pause();
     void resume();
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index 5e6e0da..005c64a 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -55,14 +55,17 @@
     mSource = source;
 }
 
-status_t AudioPlayer::start() {
+status_t AudioPlayer::start(bool sourceAlreadyStarted) {
     CHECK(!mStarted);
     CHECK(mSource != NULL);
 
-    status_t err = mSource->start();
+    status_t err;
+    if (!sourceAlreadyStarted) {
+        err = mSource->start();
 
-    if (err != OK) {
-        return err;
+        if (err != OK) {
+            return err;
+        }
     }
 
     sp<MetaData> format = mSource->getFormat();
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index b8a50bf..e00ba470 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -410,6 +410,9 @@
 
     if (mDurationUs >= 0) {
         int64_t cachedDurationUs = mPrefetcher->getCachedDurationUs();
+
+        LOGV("cache holds %.2f secs worth of data.", cachedDurationUs / 1E6);
+
         int64_t positionUs = 0;
         if (mVideoSource != NULL) {
             positionUs = mVideoTimeUs;
@@ -486,7 +489,11 @@
             if (mAudioSink != NULL) {
                 mAudioPlayer = new AudioPlayer(mAudioSink);
                 mAudioPlayer->setSource(mAudioSource);
-                status_t err = mAudioPlayer->start();
+
+                // We've already started the MediaSource in order to enable
+                // the prefetcher to read its data.
+                status_t err = mAudioPlayer->start(
+                        true /* sourceAlreadyStarted */);
 
                 if (err != OK) {
                     delete mAudioPlayer;
@@ -734,6 +741,8 @@
         }
     }
 
+    mAudioSource->start();
+
     return mAudioSource != NULL ? OK : UNKNOWN_ERROR;
 }
 
diff --git a/media/libstagefright/Prefetcher.cpp b/media/libstagefright/Prefetcher.cpp
index 493570a..debb60d 100644
--- a/media/libstagefright/Prefetcher.cpp
+++ b/media/libstagefright/Prefetcher.cpp
@@ -195,6 +195,7 @@
 
     int64_t minCacheDurationUs = -1;
     ssize_t minIndex = -1;
+    bool anySourceActive = false;
     for (size_t i = 0; i < mSources.size(); ++i) {
         int64_t cacheDurationUs;
         sp<PrefetchedSource> source = mSources[i].promote();
@@ -202,8 +203,8 @@
             continue;
         }
 
-        if (!source->getCacheDurationUs(&cacheDurationUs)) {
-            continue;
+        if (source->getCacheDurationUs(&cacheDurationUs)) {
+            anySourceActive = true;
         }
 
         if (minIndex < 0 || cacheDurationUs < minCacheDurationUs) {
@@ -213,7 +214,7 @@
     }
 
     if (noMoreData) {
-        *noMoreData = minCacheDurationUs < 0;
+        *noMoreData = !anySourceActive;
     }
 
     return minCacheDurationUs < 0 ? 0 : minCacheDurationUs;
@@ -226,7 +227,7 @@
     bool noMoreData;
     do {
         duration = getCachedDurationUs(&noMoreData);
-    } while (!noMoreData && duration < kMaxCacheDurationUs);
+    } while (!noMoreData && duration < 2000000ll);
 
     return OK;
 }
@@ -326,14 +327,12 @@
 bool PrefetchedSource::getCacheDurationUs(int64_t *durationUs) {
     Mutex::Autolock autoLock(mLock);
 
-    if (!mStarted || mReachedEOS) {
-        *durationUs = 0;
+    *durationUs = mCacheDurationUs;
 
+    if (!mStarted || mReachedEOS) {
         return false;
     }
 
-    *durationUs = mCacheDurationUs;
-
     return true;
 }