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:
committed by
Android (Google) Code Review
commit
2e3761ba43
@@ -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() {
|
||||||
|
|||||||
Reference in New Issue
Block a user