Skip to content

Commit 3c460f3

Browse files
committed
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.
Change-Id: I03dbdac3cd250340059ea43b341129b30acce4e2 related-to-bug: 2736779
1 parent 6a29711 commit 3c460f3

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)