Skip to content

Commit 2e3761b

Browse files
theandi666Android (Google) Code Review
authored andcommitted
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
2 parents 85a1c57 + 3c460f3 commit 2e3761b

File tree

1 file changed

+50
-12
lines changed

1 file changed

+50
-12
lines changed

media/libstagefright/Prefetcher.cpp

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,14 @@ struct PrefetchedSource : public MediaSource {
5858
status_t mFinalStatus;
5959
int64_t mSeekTimeUs;
6060
int64_t mCacheDurationUs;
61+
size_t mCacheSizeBytes;
6162
bool mPrefetcherStopped;
6263
bool mCurrentlyPrefetching;
6364

6465
List<MediaBuffer *> mCachedBuffers;
6566

6667
// Returns true iff source is currently caching.
67-
bool getCacheDurationUs(int64_t *durationUs);
68+
bool getCacheDurationUs(int64_t *durationUs, size_t *totalSize = NULL);
6869

6970
void updateCacheDuration_l();
7071
void clearCache_l();
@@ -125,21 +126,31 @@ int Prefetcher::ThreadWrapper(void *me) {
125126
return 0;
126127
}
127128

128-
// Cache about 10secs for each source.
129-
static int64_t kMaxCacheDurationUs = 10000000ll;
129+
// Cache at most 1 min for each source.
130+
static int64_t kMaxCacheDurationUs = 60 * 1000000ll;
131+
132+
// At the same time cache at most 5MB per source.
133+
static size_t kMaxCacheSizeBytes = 5 * 1024 * 1024;
134+
135+
// If the amount of cached data drops below this,
136+
// fill the cache up to the max duration again.
137+
static int64_t kLowWaterDurationUs = 5000000ll;
130138

131139
void Prefetcher::threadFunc() {
140+
bool fillingCache = false;
141+
132142
for (;;) {
133143
sp<PrefetchedSource> minSource;
144+
int64_t minCacheDurationUs = -1;
134145

135146
{
136147
Mutex::Autolock autoLock(mLock);
137148
if (mDone) {
138149
break;
139150
}
140-
mCondition.waitRelative(mLock, 10000000ll);
151+
mCondition.waitRelative(
152+
mLock, fillingCache ? 10000000ll : 1000000000ll);
141153

142-
int64_t minCacheDurationUs = -1;
143154
ssize_t minIndex = -1;
144155
for (size_t i = 0; i < mSources.size(); ++i) {
145156
sp<PrefetchedSource> source = mSources[i].promote();
@@ -149,11 +160,18 @@ void Prefetcher::threadFunc() {
149160
}
150161

151162
int64_t cacheDurationUs;
152-
if (!source->getCacheDurationUs(&cacheDurationUs)) {
163+
size_t cacheSizeBytes;
164+
if (!source->getCacheDurationUs(&cacheDurationUs, &cacheSizeBytes)) {
165+
continue;
166+
}
167+
168+
if (cacheSizeBytes > kMaxCacheSizeBytes) {
169+
LOGI("max cache size reached");
153170
continue;
154171
}
155172

156-
if (cacheDurationUs >= kMaxCacheDurationUs) {
173+
if (mSources.size() > 1 && cacheDurationUs >= kMaxCacheDurationUs) {
174+
LOGI("max duration reached, size = %d bytes", cacheSizeBytes);
157175
continue;
158176
}
159177

@@ -165,14 +183,26 @@ void Prefetcher::threadFunc() {
165183
}
166184

167185
if (minIndex < 0) {
186+
if (fillingCache) {
187+
LOGV("[%p] done filling the cache, above high water mark.",
188+
this);
189+
fillingCache = false;
190+
}
168191
continue;
169192
}
170193
}
171194

172-
// Make sure not to hold the lock while calling into the source.
173-
// The lock guards the list of sources, not the individual sources
174-
// themselves.
175-
minSource->cacheMore();
195+
if (!fillingCache && minCacheDurationUs < kLowWaterDurationUs) {
196+
LOGI("[%p] cache below low water mark, filling cache.", this);
197+
fillingCache = true;
198+
}
199+
200+
if (fillingCache) {
201+
// Make sure not to hold the lock while calling into the source.
202+
// The lock guards the list of sources, not the individual sources
203+
// themselves.
204+
minSource->cacheMore();
205+
}
176206
}
177207

178208
Mutex::Autolock autoLock(mLock);
@@ -250,6 +280,7 @@ PrefetchedSource::PrefetchedSource(
250280
mReachedEOS(false),
251281
mSeekTimeUs(0),
252282
mCacheDurationUs(0),
283+
mCacheSizeBytes(0),
253284
mPrefetcherStopped(false),
254285
mCurrentlyPrefetching(false) {
255286
}
@@ -323,6 +354,7 @@ status_t PrefetchedSource::read(
323354
*out = *mCachedBuffers.begin();
324355
mCachedBuffers.erase(mCachedBuffers.begin());
325356
updateCacheDuration_l();
357+
mCacheSizeBytes -= (*out)->size();
326358

327359
return OK;
328360
}
@@ -331,10 +363,14 @@ sp<MetaData> PrefetchedSource::getFormat() {
331363
return mSource->getFormat();
332364
}
333365

334-
bool PrefetchedSource::getCacheDurationUs(int64_t *durationUs) {
366+
bool PrefetchedSource::getCacheDurationUs(
367+
int64_t *durationUs, size_t *totalSize) {
335368
Mutex::Autolock autoLock(mLock);
336369

337370
*durationUs = mCacheDurationUs;
371+
if (totalSize != NULL) {
372+
*totalSize = mCacheSizeBytes;
373+
}
338374

339375
if (!mStarted || mReachedEOS) {
340376
return false;
@@ -397,6 +433,7 @@ void PrefetchedSource::cacheMore() {
397433

398434
mCachedBuffers.push_back(copy);
399435
updateCacheDuration_l();
436+
mCacheSizeBytes += copy->size();
400437

401438
mCurrentlyPrefetching = false;
402439
mCondition.signal();
@@ -425,6 +462,7 @@ void PrefetchedSource::clearCache_l() {
425462
}
426463

427464
updateCacheDuration_l();
465+
mCacheSizeBytes = 0;
428466
}
429467

430468
void PrefetchedSource::onPrefetcherStopped() {

0 commit comments

Comments
 (0)