Bug 1375772 - don't evict the block which is in the current cached range.
Evicting the block will result in a gap in the current cached range starting
from mStreamOffset to mChannelOffset. Then we have
|GetCachedDataEndInternal(mStreamOffset) < mChannelOffset| and MediaCache
will open a new channel to fill the gap which is bad.
This is exactly the issue described in
bug 1347174 where we limit the readahead
size to prevent the problem above from happening.
However
bug 1347174 is indeed a workaround instead of a fix. It works around
the issue by suspending the download before the cache is full and has to evict
some blocks to allow new data to come in.
We should let MediaCache suspend the channel if it is full or evict played
blocks if possible.
MozReview-Commit-ID: HuUsZLdHGuh
--- a/dom/media/MediaCache.cpp
+++ b/dom/media/MediaCache.cpp
@@ -1250,16 +1250,33 @@ MediaCache::Update()
FindReusableBlock(now, block->mOwners[0].mStream,
block->mOwners[0].mStreamBlock, maxBlocks);
if (destinationBlockIndex < 0) {
// Nowhere to place this overflow block. We won't be able to
// place any more overflow blocks.
break;
}
+ // Don't evict |destinationBlockIndex| if it is within [cur, end) otherwise
+ // a new channel will be opened to download this block again which is bad.
+ bool inCurrentCachedRange = false;
+ for (BlockOwner& owner : mIndex[destinationBlockIndex].mOwners) {
+ MediaCacheStream* stream = owner.mStream;
+ int64_t end = OffsetToBlockIndexUnchecked(
+ stream->GetCachedDataEndInternal(stream->mStreamOffset));
+ int64_t cur = OffsetToBlockIndexUnchecked(stream->mStreamOffset);
+ if (cur <= owner.mStreamBlock && owner.mStreamBlock < end) {
+ inCurrentCachedRange = true;
+ break;
+ }
+ }
+ if (inCurrentCachedRange) {
+ continue;
+ }
+
if (IsBlockFree(destinationBlockIndex) ||
PredictNextUse(now, destinationBlockIndex) > latestPredictedUseForOverflow) {
// Reuse blocks in the main part of the cache that are less useful than
// the least useful overflow blocks
nsresult rv = mBlockCache->MoveBlock(blockIndex, destinationBlockIndex);
if (NS_SUCCEEDED(rv)) {