Bug 521176. Don't unnecessarily start an HTTP transaction when cloning a media resource. r=doublec

This commit is contained in:
Robert O'Callahan 2009-10-10 00:48:30 +13:00
parent c8bd80f5be
commit b786c847ff
2 changed files with 30 additions and 1 deletions

View File

@ -2149,6 +2149,10 @@ nsMediaCacheStream::InitAsClone(nsMediaCacheStream* aOriginal)
mStreamLength = aOriginal->mStreamLength;
mIsSeekable = aOriginal->mIsSeekable;
// Cloned streams are initially suspended, since there is no channel open
// initially for a clone.
mCacheSuspended = PR_TRUE;
for (PRUint32 i = 0; i < aOriginal->mBlocks.Length(); ++i) {
PRInt32 cacheBlockIndex = aOriginal->mBlocks[i];
if (cacheBlockIndex < 0)
@ -2157,6 +2161,8 @@ nsMediaCacheStream::InitAsClone(nsMediaCacheStream* aOriginal)
while (i >= mBlocks.Length()) {
mBlocks.AppendElement(-1);
}
// Every block is a readahead block for the clone because the clone's initial
// stream offset is zero
gMediaCache->AddBlockOwnerAsReadahead(cacheBlockIndex, this, i);
}

View File

@ -386,6 +386,15 @@ nsresult nsMediaChannelStream::Open(nsIStreamListener **aStreamListener)
if (NS_FAILED(rv))
return rv;
NS_ASSERTION(mOffset == 0, "Who set mOffset already?");
if (!mChannel) {
// When we're a clone, the decoder might ask us to Open even though
// we haven't established an mChannel (because we might not need one)
NS_ASSERTION(!aStreamListener,
"Should have already been given a channel if we're to return a stream listener");
return NS_OK;
}
return OpenChannel(aStreamListener);
}
@ -480,7 +489,14 @@ nsMediaStream* nsMediaChannelStream::CloneData(nsMediaDecoder* aDecoder)
nsMediaChannelStream* stream = new nsMediaChannelStream(aDecoder, nsnull, mURI);
if (stream) {
stream->RecreateChannel();
// Initially the clone is treated as suspended by the cache, because
// we don't have a channel. If the cache needs to read data from the clone
// it will call CacheClientResume (or CacheClientSeek with aResume true)
// which will recreate the channel. This way, if all of the media data
// is already in the cache we don't create an unneccesary HTTP channel
// and perform a useless HTTP transaction.
stream->mSuspendCount = 1;
stream->mCacheSuspendCount = 1;
stream->mCacheStream.InitAsClone(&mCacheStream);
}
return stream;
@ -578,6 +594,7 @@ void nsMediaChannelStream::Resume()
return;
}
NS_ASSERTION(mSuspendCount > 0, "Resume without previous Suspend!");
--mSuspendCount;
if (mSuspendCount == 0) {
if (mChannel) {
@ -688,6 +705,11 @@ nsMediaChannelStream::CacheClientSeek(PRInt64 aOffset, PRBool aResume)
NS_ASSERTION(mSuspendCount > 0, "Too many resumes!");
// No need to mess with the channel, since we're making a new one
--mSuspendCount;
{
nsAutoLock lock(mLock);
NS_ASSERTION(mCacheSuspendCount > 0, "CacheClientSeek(aResume=true) without previous CacheClientSuspend!");
--mCacheSuspendCount;
}
}
nsresult rv = RecreateChannel();
@ -717,6 +739,7 @@ nsMediaChannelStream::CacheClientResume()
Resume();
{
nsAutoLock lock(mLock);
NS_ASSERTION(mCacheSuspendCount > 0, "CacheClientResume without previous CacheClientSuspend!");
--mCacheSuspendCount;
}