mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 513144. Make nsMediaChannelStream::CloneData clone the underlying cache stream, which adds the new stream as co-owner of all the nsMediaCache blocks currently cached for the original stream. Also, use NS_NEW_RUNNABLE_METHOD instead of the SuspendedStatusChanged class. r=doublec
--HG-- extra : rebase_source : 982c38bf513865033a2c51554ded3f3f365eeb3a
This commit is contained in:
parent
cc7de63946
commit
3f9249f428
@ -159,6 +159,9 @@ public:
|
||||
// call QueueUpdate().
|
||||
void NoteBlockUsage(nsMediaCacheStream* aStream, PRInt32 aBlockIndex,
|
||||
nsMediaCacheStream::ReadMode aMode, TimeStamp aNow);
|
||||
// Mark aStream as having the block, adding it as an owner.
|
||||
void AddBlockOwnerAsReadahead(PRInt32 aBlockIndex, nsMediaCacheStream* aStream,
|
||||
PRInt32 aStreamBlockIndex);
|
||||
|
||||
// This queues a call to Update() on the main thread.
|
||||
void QueueUpdate();
|
||||
@ -840,6 +843,23 @@ nsMediaCache::RemoveBlockOwner(PRInt32 aBlockIndex, nsMediaCacheStream* aStream)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsMediaCache::AddBlockOwnerAsReadahead(PRInt32 aBlockIndex,
|
||||
nsMediaCacheStream* aStream,
|
||||
PRInt32 aStreamBlockIndex)
|
||||
{
|
||||
Block* block = &mIndex[aBlockIndex];
|
||||
if (block->mOwners.IsEmpty()) {
|
||||
mFreeBlocks.RemoveBlock(aBlockIndex);
|
||||
}
|
||||
BlockOwner* bo = block->mOwners.AppendElement();
|
||||
bo->mStream = aStream;
|
||||
bo->mStreamBlock = aStreamBlockIndex;
|
||||
aStream->mBlocks[aStreamBlockIndex] = aBlockIndex;
|
||||
bo->mClass = READAHEAD_BLOCK;
|
||||
InsertReadaheadBlock(bo, aBlockIndex);
|
||||
}
|
||||
|
||||
void
|
||||
nsMediaCache::FreeBlock(PRInt32 aBlock)
|
||||
{
|
||||
@ -1996,9 +2016,44 @@ nsMediaCacheStream::Init()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
||||
|
||||
if (mInitialized)
|
||||
return NS_OK;
|
||||
|
||||
InitMediaCache();
|
||||
if (!gMediaCache)
|
||||
return NS_ERROR_FAILURE;
|
||||
gMediaCache->OpenStream(this);
|
||||
mInitialized = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMediaCacheStream::InitAsClone(nsMediaCacheStream* aOriginal)
|
||||
{
|
||||
if (mInitialized)
|
||||
return NS_OK;
|
||||
|
||||
nsresult rv = Init();
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// Grab cache blocks from aOriginal as readahead blocks for our stream
|
||||
nsAutoMonitor mon(gMediaCache->Monitor());
|
||||
|
||||
mPrincipal = aOriginal->mPrincipal;
|
||||
mStreamLength = aOriginal->mStreamLength;
|
||||
mIsSeekable = aOriginal->mIsSeekable;
|
||||
|
||||
for (PRUint32 i = 0; i < aOriginal->mBlocks.Length(); ++i) {
|
||||
PRInt32 cacheBlockIndex = aOriginal->mBlocks[i];
|
||||
if (cacheBlockIndex < 0)
|
||||
continue;
|
||||
|
||||
while (i >= mBlocks.Length()) {
|
||||
mBlocks.AppendElement(-1);
|
||||
}
|
||||
gMediaCache->AddBlockOwnerAsReadahead(cacheBlockIndex, this, i);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -222,17 +222,24 @@ public:
|
||||
nsMediaCacheStream(nsMediaChannelStream* aClient)
|
||||
: mClient(aClient), mChannelOffset(0),
|
||||
mStreamOffset(0), mStreamLength(-1), mPlaybackBytesPerSecond(10000),
|
||||
mPinCount(0), mCurrentMode(MODE_PLAYBACK), mClosed(PR_FALSE),
|
||||
mPinCount(0), mCurrentMode(MODE_PLAYBACK),
|
||||
mInitialized(PR_FALSE), mClosed(PR_FALSE),
|
||||
mIsSeekable(PR_FALSE), mCacheSuspended(PR_FALSE),
|
||||
mMetadataInPartialBlockBuffer(PR_FALSE),
|
||||
mUsingNullPrincipal(PR_FALSE) {}
|
||||
~nsMediaCacheStream();
|
||||
|
||||
// Set up this stream with the cache. Can fail on OOM. Must be called
|
||||
// before other methods on this object; no other methods may be called
|
||||
// if this fails.
|
||||
// Set up this stream with the cache. Can fail on OOM. One
|
||||
// of InitAsClone or Init must be called before any other method on
|
||||
// this class. Does nothing if already initialized.
|
||||
nsresult Init();
|
||||
|
||||
// Set up this stream with the cache, assuming it's for the same data
|
||||
// as the aOriginal stream. Can fail on OOM. Exactly one
|
||||
// of InitAsClone or Init must be called before any other method on
|
||||
// this class. Does nothing if already initialized.
|
||||
nsresult InitAsClone(nsMediaCacheStream* aOriginal);
|
||||
|
||||
// These are called on the main thread.
|
||||
// Tell us whether the stream is seekable or not. Non-seekable streams
|
||||
// will always pass 0 for aOffset to CacheClientSeek. This should only
|
||||
@ -447,6 +454,8 @@ private:
|
||||
PRUint32 mPinCount;
|
||||
// The last reported read mode
|
||||
ReadMode mCurrentMode;
|
||||
// Set to true when Init or InitAsClone has been called
|
||||
PRPackedBool mInitialized;
|
||||
// Set to true when the stream has been closed either explicitly or
|
||||
// due to an internal cache error
|
||||
PRPackedBool mClosed;
|
||||
|
@ -452,7 +452,7 @@ nsMediaStream* nsMediaChannelStream::CloneData(nsMediaDecoder* aDecoder)
|
||||
nsMediaChannelStream* stream = new nsMediaChannelStream(aDecoder, nsnull, mURI);
|
||||
if (stream) {
|
||||
stream->RecreateChannel();
|
||||
// XXXroc need to clone mCacheStream's data here
|
||||
stream->mCacheStream.InitAsClone(&mCacheStream);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
@ -614,28 +614,6 @@ nsMediaChannelStream::CacheClientSeek(PRInt64 aOffset, PRBool aResume)
|
||||
return OpenChannel(nsnull);
|
||||
}
|
||||
|
||||
class SuspendedStatusChanged : public nsRunnable
|
||||
{
|
||||
public:
|
||||
SuspendedStatusChanged(nsMediaDecoder* aDecoder) :
|
||||
mDecoder(aDecoder)
|
||||
{
|
||||
MOZ_COUNT_CTOR(SuspendedStatusChanged);
|
||||
}
|
||||
~SuspendedStatusChanged()
|
||||
{
|
||||
MOZ_COUNT_DTOR(SuspendedStatusChanged);
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
mDecoder->NotifySuspendedStatusChanged();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<nsMediaDecoder> mDecoder;
|
||||
};
|
||||
|
||||
nsresult
|
||||
nsMediaChannelStream::CacheClientSuspend()
|
||||
{
|
||||
@ -648,7 +626,8 @@ nsMediaChannelStream::CacheClientSuspend()
|
||||
// We have to spawn an event here since we're being called back from
|
||||
// a sensitive place in nsMediaCache, which doesn't want us to reenter
|
||||
// the decoder and cause deadlocks or other unpleasantness
|
||||
nsCOMPtr<nsIRunnable> event = new SuspendedStatusChanged(mDecoder);
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
NS_NEW_RUNNABLE_METHOD(nsMediaDecoder, mDecoder, NotifySuspendedStatusChanged);
|
||||
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -665,7 +644,8 @@ nsMediaChannelStream::CacheClientResume()
|
||||
// We have to spawn an event here since we're being called back from
|
||||
// a sensitive place in nsMediaCache, which doesn't want us to reenter
|
||||
// the decoder and cause deadlocks or other unpleasantness
|
||||
nsCOMPtr<nsIRunnable> event = new SuspendedStatusChanged(mDecoder);
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
NS_NEW_RUNNABLE_METHOD(nsMediaDecoder, mDecoder, NotifySuspendedStatusChanged);
|
||||
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user