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();
}