Merge "Changes to the prefetcher to allow for bursts of data to be transferred, hopefully allowing the radio to go to low-power mode while idle." into froyo

This commit is contained in:
Andreas Huber
2010-06-03 15:28:13 -07:00
committed by Android (Google) Code Review

View File

@@ -58,13 +58,14 @@ private:
status_t mFinalStatus; status_t mFinalStatus;
int64_t mSeekTimeUs; int64_t mSeekTimeUs;
int64_t mCacheDurationUs; int64_t mCacheDurationUs;
size_t mCacheSizeBytes;
bool mPrefetcherStopped; bool mPrefetcherStopped;
bool mCurrentlyPrefetching; bool mCurrentlyPrefetching;
List<MediaBuffer *> mCachedBuffers; List<MediaBuffer *> mCachedBuffers;
// Returns true iff source is currently caching. // Returns true iff source is currently caching.
bool getCacheDurationUs(int64_t *durationUs); bool getCacheDurationUs(int64_t *durationUs, size_t *totalSize = NULL);
void updateCacheDuration_l(); void updateCacheDuration_l();
void clearCache_l(); void clearCache_l();
@@ -125,21 +126,31 @@ int Prefetcher::ThreadWrapper(void *me) {
return 0; return 0;
} }
// Cache about 10secs for each source. // Cache at most 1 min for each source.
static int64_t kMaxCacheDurationUs = 10000000ll; static int64_t kMaxCacheDurationUs = 60 * 1000000ll;
// At the same time cache at most 5MB per source.
static size_t kMaxCacheSizeBytes = 5 * 1024 * 1024;
// If the amount of cached data drops below this,
// fill the cache up to the max duration again.
static int64_t kLowWaterDurationUs = 5000000ll;
void Prefetcher::threadFunc() { void Prefetcher::threadFunc() {
bool fillingCache = false;
for (;;) { for (;;) {
sp<PrefetchedSource> minSource; sp<PrefetchedSource> minSource;
int64_t minCacheDurationUs = -1;
{ {
Mutex::Autolock autoLock(mLock); Mutex::Autolock autoLock(mLock);
if (mDone) { if (mDone) {
break; break;
} }
mCondition.waitRelative(mLock, 10000000ll); mCondition.waitRelative(
mLock, fillingCache ? 10000000ll : 1000000000ll);
int64_t minCacheDurationUs = -1;
ssize_t minIndex = -1; ssize_t minIndex = -1;
for (size_t i = 0; i < mSources.size(); ++i) { for (size_t i = 0; i < mSources.size(); ++i) {
sp<PrefetchedSource> source = mSources[i].promote(); sp<PrefetchedSource> source = mSources[i].promote();
@@ -149,11 +160,18 @@ void Prefetcher::threadFunc() {
} }
int64_t cacheDurationUs; int64_t cacheDurationUs;
if (!source->getCacheDurationUs(&cacheDurationUs)) { size_t cacheSizeBytes;
if (!source->getCacheDurationUs(&cacheDurationUs, &cacheSizeBytes)) {
continue; continue;
} }
if (cacheDurationUs >= kMaxCacheDurationUs) { if (cacheSizeBytes > kMaxCacheSizeBytes) {
LOGI("max cache size reached");
continue;
}
if (mSources.size() > 1 && cacheDurationUs >= kMaxCacheDurationUs) {
LOGI("max duration reached, size = %d bytes", cacheSizeBytes);
continue; continue;
} }
@@ -165,14 +183,26 @@ void Prefetcher::threadFunc() {
} }
if (minIndex < 0) { if (minIndex < 0) {
if (fillingCache) {
LOGV("[%p] done filling the cache, above high water mark.",
this);
fillingCache = false;
}
continue; continue;
} }
} }
// Make sure not to hold the lock while calling into the source. if (!fillingCache && minCacheDurationUs < kLowWaterDurationUs) {
// The lock guards the list of sources, not the individual sources LOGI("[%p] cache below low water mark, filling cache.", this);
// themselves. fillingCache = true;
minSource->cacheMore(); }
if (fillingCache) {
// Make sure not to hold the lock while calling into the source.
// The lock guards the list of sources, not the individual sources
// themselves.
minSource->cacheMore();
}
} }
Mutex::Autolock autoLock(mLock); Mutex::Autolock autoLock(mLock);
@@ -250,6 +280,7 @@ PrefetchedSource::PrefetchedSource(
mReachedEOS(false), mReachedEOS(false),
mSeekTimeUs(0), mSeekTimeUs(0),
mCacheDurationUs(0), mCacheDurationUs(0),
mCacheSizeBytes(0),
mPrefetcherStopped(false), mPrefetcherStopped(false),
mCurrentlyPrefetching(false) { mCurrentlyPrefetching(false) {
} }
@@ -323,6 +354,7 @@ status_t PrefetchedSource::read(
*out = *mCachedBuffers.begin(); *out = *mCachedBuffers.begin();
mCachedBuffers.erase(mCachedBuffers.begin()); mCachedBuffers.erase(mCachedBuffers.begin());
updateCacheDuration_l(); updateCacheDuration_l();
mCacheSizeBytes -= (*out)->size();
return OK; return OK;
} }
@@ -331,10 +363,14 @@ sp<MetaData> PrefetchedSource::getFormat() {
return mSource->getFormat(); return mSource->getFormat();
} }
bool PrefetchedSource::getCacheDurationUs(int64_t *durationUs) { bool PrefetchedSource::getCacheDurationUs(
int64_t *durationUs, size_t *totalSize) {
Mutex::Autolock autoLock(mLock); Mutex::Autolock autoLock(mLock);
*durationUs = mCacheDurationUs; *durationUs = mCacheDurationUs;
if (totalSize != NULL) {
*totalSize = mCacheSizeBytes;
}
if (!mStarted || mReachedEOS) { if (!mStarted || mReachedEOS) {
return false; return false;
@@ -397,6 +433,7 @@ void PrefetchedSource::cacheMore() {
mCachedBuffers.push_back(copy); mCachedBuffers.push_back(copy);
updateCacheDuration_l(); updateCacheDuration_l();
mCacheSizeBytes += copy->size();
mCurrentlyPrefetching = false; mCurrentlyPrefetching = false;
mCondition.signal(); mCondition.signal();
@@ -425,6 +462,7 @@ void PrefetchedSource::clearCache_l() {
} }
updateCacheDuration_l(); updateCacheDuration_l();
mCacheSizeBytes = 0;
} }
void PrefetchedSource::onPrefetcherStopped() { void PrefetchedSource::onPrefetcherStopped() {