@@ -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
131139void 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
430468void PrefetchedSource::onPrefetcherStopped () {
0 commit comments