зеркало из https://github.com/mozilla/pjs.git
Bug 639391 - Make nsMediaStream responsible for determining cached media data in a threadsafe manner. r=roc
This commit is contained in:
Родитель
36d6e56061
Коммит
f709c45bea
|
@ -2293,3 +2293,26 @@ nsMediaCacheStream::InitAsClone(nsMediaCacheStream* aOriginal)
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMediaCacheStream::GetCachedRanges(nsTArray<nsByteRange>& aRanges)
|
||||
{
|
||||
// Take the monitor, so that the cached data ranges can't grow while we're
|
||||
// trying to loop over them.
|
||||
nsAutoMonitor mon(gMediaCache->Monitor());
|
||||
|
||||
// We must be pinned while running this, otherwise the cached data ranges may
|
||||
// shrink while we're trying to loop over them.
|
||||
NS_ASSERTION(mPinCount > 0, "Must be pinned");
|
||||
|
||||
PRInt64 startOffset = GetNextCachedData(0);
|
||||
while (startOffset >= 0) {
|
||||
PRInt64 endOffset = GetCachedDataEnd(startOffset);
|
||||
NS_ASSERTION(startOffset < endOffset, "Buffered range must end after its start");
|
||||
// Bytes [startOffset..endOffset] are cached.
|
||||
aRanges.AppendElement(nsByteRange(startOffset, endOffset));
|
||||
startOffset = GetNextCachedData(endOffset);
|
||||
NS_ASSERTION(startOffset == -1 || startOffset > endOffset,
|
||||
"Must have advanced to start of next range, or hit end of stream");
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
#include "nsIPrincipal.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsByteRange;
|
||||
|
||||
/**
|
||||
* Media applications want fast, "on demand" random access to media data,
|
||||
* for pausing, seeking, etc. But we are primarily interested
|
||||
|
@ -310,6 +312,11 @@ public:
|
|||
// Returns the offset of the first byte of cached data at or after aOffset,
|
||||
// or -1 if there is no such cached data.
|
||||
PRInt64 GetNextCachedData(PRInt64 aOffset);
|
||||
// Fills aRanges with the ByteRanges representing the data which is currently
|
||||
// cached. Locks the media cache while running, to prevent any ranges
|
||||
// growing. The stream should be pinned while this runs and while its results
|
||||
// are used, to ensure no data is evicted.
|
||||
nsresult GetCachedRanges(nsTArray<nsByteRange>& aRanges);
|
||||
|
||||
// Reads from buffered data only. Will fail if not all data to be read is
|
||||
// in the cache. Will not mark blocks as read. Can be called from the main
|
||||
|
|
|
@ -605,6 +605,11 @@ PRInt64 nsMediaChannelStream::Tell()
|
|||
return mCacheStream.Tell();
|
||||
}
|
||||
|
||||
nsresult nsMediaChannelStream::GetCachedRanges(nsTArray<nsByteRange>& aRanges)
|
||||
{
|
||||
return mCacheStream.GetCachedRanges(aRanges);
|
||||
}
|
||||
|
||||
void nsMediaChannelStream::Suspend(PRBool aCloseImmediately)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
|
||||
|
@ -919,6 +924,8 @@ public:
|
|||
virtual PRBool IsSuspendedByCache() { return PR_FALSE; }
|
||||
virtual PRBool IsSuspended() { return PR_FALSE; }
|
||||
|
||||
nsresult GetCachedRanges(nsTArray<nsByteRange>& aRanges);
|
||||
|
||||
private:
|
||||
// The file size, or -1 if not known. Immutable after Open().
|
||||
PRInt64 mSize;
|
||||
|
@ -961,6 +968,15 @@ private:
|
|||
nsRefPtr<nsMediaDecoder> mDecoder;
|
||||
};
|
||||
|
||||
nsresult nsMediaFileStream::GetCachedRanges(nsTArray<nsByteRange>& aRanges)
|
||||
{
|
||||
if (mSize == -1) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
aRanges.AppendElement(nsByteRange(0, mSize));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMediaFileStream::Open(nsIStreamListener** aStreamListener)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
||||
|
|
|
@ -127,6 +127,25 @@ private:
|
|||
PRPackedBool mIsStarted;
|
||||
};
|
||||
|
||||
// Represents a section of contiguous media, with a start and end offset.
|
||||
// Used to denote ranges of data which are cached.
|
||||
class nsByteRange {
|
||||
public:
|
||||
nsByteRange() : mStart(0), mEnd(0) {}
|
||||
|
||||
nsByteRange(PRInt64 aStart, PRInt64 aEnd)
|
||||
: mStart(aStart), mEnd(aEnd)
|
||||
{
|
||||
NS_ASSERTION(mStart < mEnd, "Range should end after start!");
|
||||
}
|
||||
|
||||
PRBool IsNull() const {
|
||||
return mStart == 0 && mEnd == 0;
|
||||
}
|
||||
|
||||
PRInt64 mStart, mEnd;
|
||||
};
|
||||
|
||||
/*
|
||||
Provides the ability to open, read and seek into a media stream
|
||||
(audio, video). Handles the underlying machinery to do range
|
||||
|
@ -275,6 +294,13 @@ public:
|
|||
*/
|
||||
virtual nsresult Open(nsIStreamListener** aStreamListener) = 0;
|
||||
|
||||
/**
|
||||
* Fills aRanges with ByteRanges representing the data which is cached
|
||||
* in the media cache. Stream should be pinned during call and while
|
||||
* aRanges is being used.
|
||||
*/
|
||||
virtual nsresult GetCachedRanges(nsTArray<nsByteRange>& aRanges) = 0;
|
||||
|
||||
protected:
|
||||
nsMediaStream(nsMediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI) :
|
||||
mDecoder(aDecoder),
|
||||
|
@ -395,6 +421,8 @@ public:
|
|||
};
|
||||
friend class Listener;
|
||||
|
||||
nsresult GetCachedRanges(nsTArray<nsByteRange>& aRanges);
|
||||
|
||||
protected:
|
||||
// These are called on the main thread by Listener.
|
||||
nsresult OnStartRequest(nsIRequest* aRequest);
|
||||
|
|
Загрузка…
Ссылка в новой задаче