Bug 687972. Don't count streams whose channel has ended when looking to see if there's any non-suspended stream for a resource. r=cpearce
--- a/content/media/nsMediaCache.cpp
+++ b/content/media/nsMediaCache.cpp
@@ -1346,16 +1346,17 @@ nsMediaCache::Update()
nsresult rv = NS_OK;
switch (actions[i]) {
case SEEK:
LOG(PR_LOG_DEBUG, ("Stream %p CacheSeek to %lld (resume=%d)", stream,
(long long)stream->mChannelOffset, stream->mCacheSuspended));
rv = stream->mClient->CacheClientSeek(stream->mChannelOffset,
stream->mCacheSuspended);
stream->mCacheSuspended = false;
+ stream->mChannelEnded = false;
break;
case RESUME:
LOG(PR_LOG_DEBUG, ("Stream %p Resumed", stream));
rv = stream->mClient->CacheClientResume();
stream->mCacheSuspended = false;
break;
@@ -1849,16 +1850,18 @@ nsMediaCacheStream::NotifyDataEnded(nsre
stream->mStreamLength = mChannelOffset;
}
NS_ASSERTION(!stream->mDidNotifyDataEnded, "Stream already ended!");
stream->mDidNotifyDataEnded = true;
stream->mNotifyDataEndedStatus = aStatus;
stream->mClient->CacheClientNotifyDataEnded(aStatus);
}
}
+
+ mChannelEnded = true;
}
nsMediaCacheStream::~nsMediaCacheStream()
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
NS_ASSERTION(!mPinCount, "Unbalanced Pin");
if (gMediaCache) {
@@ -1888,17 +1891,17 @@ nsMediaCacheStream::IsSeekable()
}
bool
nsMediaCacheStream::AreAllStreamsForResourceSuspended()
{
ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
nsMediaCache::ResourceStreamIterator iter(mResourceID);
while (nsMediaCacheStream* stream = iter.Next()) {
- if (!stream->mCacheSuspended)
+ if (!stream->mCacheSuspended && !stream->mChannelEnded)
return false;
}
return true;
}
void
nsMediaCacheStream::Close()
{
@@ -2307,16 +2310,17 @@ nsMediaCacheStream::InitAsClone(nsMediaC
mPrincipal = aOriginal->mPrincipal;
mStreamLength = aOriginal->mStreamLength;
mIsSeekable = aOriginal->mIsSeekable;
// Cloned streams are initially suspended, since there is no channel open
// initially for a clone.
mCacheSuspended = true;
+ mChannelEnded = true;
if (aOriginal->mDidNotifyDataEnded) {
mNotifyDataEndedStatus = aOriginal->mNotifyDataEndedStatus;
mDidNotifyDataEnded = true;
mClient->CacheClientNotifyDataEnded(mNotifyDataEndedStatus);
}
for (PRUint32 i = 0; i < aOriginal->mBlocks.Length(); ++i) {
--- a/content/media/nsMediaCache.h
+++ b/content/media/nsMediaCache.h
@@ -224,17 +224,17 @@ public:
};
// aClient provides the underlying transport that cache will use to read
// data for this stream.
nsMediaCacheStream(nsMediaChannelStream* aClient)
: mClient(aClient), mResourceID(0), mInitialized(false),
mHasHadUpdate(false),
mIsSeekable(false), mCacheSuspended(false),
- mDidNotifyDataEnded(false),
+ mChannelEnded(false), mDidNotifyDataEnded(false),
mUsingNullPrincipal(false),
mChannelOffset(0), mStreamLength(-1),
mStreamOffset(0), mPlaybackBytesPerSecond(10000),
mPinCount(0), mCurrentMode(MODE_PLAYBACK),
mMetadataInPartialBlockBuffer(false),
mClosed(false) {}
~nsMediaCacheStream();
@@ -347,17 +347,18 @@ public:
// This is the client's estimate of the playback rate assuming
// the media plays continuously. The cache can't guess this itself
// because it doesn't know when the decoder was paused, buffering, etc.
// Do not pass zero.
void SetPlaybackRate(PRUint32 aBytesPerSecond);
// Returns the last set value of SetSeekable.
bool IsSeekable();
- // Returns true when all streams for this resource are suspended.
+ // Returns true when all streams for this resource are suspended or their
+ // channel has ended.
bool AreAllStreamsForResourceSuspended();
// These methods must be called on a different thread from the main
// thread. They should always be called on the same thread for a given
// stream.
// This can fail when aWhence is NS_SEEK_END and no stream length
// is known.
nsresult Seek(PRInt32 aWhence, PRInt64 aOffset);
@@ -464,16 +465,18 @@ private:
// only written on the main thread.
// The last reported seekability state for the underlying channel
bool mIsSeekable;
// True if the cache has suspended our channel because the cache is
// full and the priority of the data that would be received is lower
// than the priority of the data already in the cache
bool mCacheSuspended;
+ // True if the channel ended and we haven't seeked it again.
+ bool mChannelEnded;
// True if CacheClientNotifyDataEnded has been called for this stream.
bool mDidNotifyDataEnded;
// True if mPrincipal is a null principal because we saw data from
// multiple origins
bool mUsingNullPrincipal;
// The offset where the next data from the channel will arrive
PRInt64 mChannelOffset;
// The reported or discovered length of the data, or -1 if nothing is