Bug 1227396: P7. Replace nsTArray<MediaByteRange> with dedicated MediaByteRangeSet object. r=cpearce

This commit is contained in:
Jean-Yves Avenard 2015-11-24 20:16:52 +11:00
parent 15775bdad8
commit 8abd913bda
27 changed files with 72 additions and 74 deletions

View File

@ -99,9 +99,9 @@ private:
return NS_ERROR_FAILURE;
}
virtual nsresult GetCachedRanges(nsTArray<MediaByteRange>& aRanges) override
virtual nsresult GetCachedRanges(MediaByteRangeSet& aRanges) override
{
aRanges.AppendElement(MediaByteRange(0, mLength));
aRanges += MediaByteRange(0, mLength);
return NS_OK;
}

View File

@ -2442,7 +2442,7 @@ MediaCacheStream::InitAsClone(MediaCacheStream* aOriginal)
return NS_OK;
}
nsresult MediaCacheStream::GetCachedRanges(nsTArray<MediaByteRange>& aRanges)
nsresult MediaCacheStream::GetCachedRanges(MediaByteRangeSet& aRanges)
{
// Take the monitor, so that the cached data ranges can't grow while we're
// trying to loop over them.
@ -2457,7 +2457,7 @@ nsresult MediaCacheStream::GetCachedRanges(nsTArray<MediaByteRange>& aRanges)
int64_t endOffset = GetCachedDataEndInternal(startOffset);
NS_ASSERTION(startOffset < endOffset, "Buffered range must end after its start");
// Bytes [startOffset..endOffset] are cached.
aRanges.AppendElement(MediaByteRange(startOffset, endOffset));
aRanges += MediaByteRange(startOffset, endOffset);
startOffset = GetNextCachedDataInternal(endOffset);
NS_ASSERTION(startOffset == -1 || startOffset > endOffset,
"Must have advanced to start of next range, or hit end of stream");

View File

@ -11,13 +11,14 @@
#include "nsCOMPtr.h"
#include "nsHashKeys.h"
#include "nsTHashtable.h"
#include "Intervals.h"
class nsIPrincipal;
namespace mozilla {
// defined in MediaResource.h
class ChannelMediaResource;
class MediaByteRange;
typedef media::IntervalSet<int64_t> MediaByteRangeSet;
class MediaResource;
class ReentrantMonitorAutoEnter;
@ -300,7 +301,7 @@ public:
// 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<MediaByteRange>& aRanges);
nsresult GetCachedRanges(MediaByteRangeSet& 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

View File

@ -738,7 +738,7 @@ int64_t ChannelMediaResource::Tell()
return mCacheStream.Tell();
}
nsresult ChannelMediaResource::GetCachedRanges(nsTArray<MediaByteRange>& aRanges)
nsresult ChannelMediaResource::GetCachedRanges(MediaByteRangeSet& aRanges)
{
return mCacheStream.GetCachedRanges(aRanges);
}
@ -1202,7 +1202,7 @@ public:
virtual bool IsSuspended() override { return true; }
virtual bool IsTransportSeekable() override { return true; }
nsresult GetCachedRanges(nsTArray<MediaByteRange>& aRanges) override;
nsresult GetCachedRanges(MediaByteRangeSet& aRanges) override;
virtual size_t SizeOfExcludingThis(
MallocSizeOf aMallocSizeOf) const override
@ -1274,7 +1274,7 @@ void FileMediaResource::EnsureSizeInitialized()
}
}
nsresult FileMediaResource::GetCachedRanges(nsTArray<MediaByteRange>& aRanges)
nsresult FileMediaResource::GetCachedRanges(MediaByteRangeSet& aRanges)
{
MutexAutoLock lock(mLock);
@ -1282,7 +1282,7 @@ nsresult FileMediaResource::GetCachedRanges(nsTArray<MediaByteRange>& aRanges)
if (mSize == -1) {
return NS_ERROR_FAILURE;
}
aRanges.AppendElement(MediaByteRange(0, mSize));
aRanges += MediaByteRange(0, mSize);
return NS_OK;
}

View File

@ -153,6 +153,8 @@ public:
MediaByteRange() = default;
};
typedef media::IntervalSet<int64_t> MediaByteRangeSet;
class RtspMediaResource;
/**
@ -343,7 +345,7 @@ public:
* in the media cache. Stream should be pinned during call and while
* aRanges is being used.
*/
virtual nsresult GetCachedRanges(nsTArray<MediaByteRange>& aRanges) = 0;
virtual nsresult GetCachedRanges(MediaByteRangeSet& aRanges) = 0;
// Ensure that the media cache writes any data held in its partial block.
// Called on the main thread only.
@ -655,7 +657,7 @@ public:
};
friend class Listener;
virtual nsresult GetCachedRanges(nsTArray<MediaByteRange>& aRanges) override;
virtual nsresult GetCachedRanges(MediaByteRangeSet& aRanges) override;
protected:
// These are called on the main thread by Listener.

View File

@ -162,7 +162,7 @@ public:
return false;
}
// dummy
nsresult GetCachedRanges(nsTArray<MediaByteRange>& aRanges) override {
nsresult GetCachedRanges(MediaByteRangeSet& aRanges) override {
return NS_ERROR_FAILURE;
}

View File

@ -384,7 +384,7 @@ DirectShowReader::NotifyDataArrivedInternal()
}
AutoPinned<MediaResource> resource(mDecoder->GetResource());
nsTArray<MediaByteRange> byteRanges;
MediaByteRangeSet byteRanges;
nsresult rv = resource->GetCachedRanges(byteRanges);
if (NS_FAILED(rv)) {

View File

@ -264,7 +264,7 @@ MP4TrackDemuxer::EnsureUpToDateIndex()
return;
}
AutoPinned<MediaResource> resource(mParent->mResource);
nsTArray<MediaByteRange> byteRanges;
MediaByteRangeSet byteRanges;
nsresult rv = resource->GetCachedRanges(byteRanges);
if (NS_FAILED(rv)) {
return;
@ -413,7 +413,7 @@ MP4TrackDemuxer::GetBuffered()
{
EnsureUpToDateIndex();
AutoPinned<MediaResource> resource(mParent->mResource);
nsTArray<MediaByteRange> byteRanges;
MediaByteRangeSet byteRanges;
nsresult rv = resource->GetCachedRanges(byteRanges);
if (NS_FAILED(rv)) {

View File

@ -885,7 +885,7 @@ media::TimeIntervals GStreamerReader::GetBuffered()
GstFormat format = GST_FORMAT_TIME;
#endif
AutoPinned<MediaResource> resource(mDecoder->GetResource());
nsTArray<MediaByteRange> ranges;
MediaByteRangeSet ranges;
resource->GetCachedRanges(ranges);
if (resource->IsDataCachedToEndOfResource(0)) {
@ -1286,7 +1286,7 @@ void GStreamerReader::NotifyDataArrivedInternal()
}
AutoPinned<MediaResource> resource(mResource.GetResource());
nsTArray<MediaByteRange> byteRanges;
MediaByteRangeSet byteRanges;
nsresult rv = resource->GetCachedRanges(byteRanges);
if (NS_FAILED(rv)) {

View File

@ -77,7 +77,7 @@ MockMediaResource::MockClearBufferedRanges()
void
MockMediaResource::MockAddBufferedRange(int64_t aStart, int64_t aEnd)
{
mRanges.AppendElement(MediaByteRange(aStart, aEnd));
mRanges += MediaByteRange(aStart, aEnd);
}
int64_t
@ -107,10 +107,9 @@ MockMediaResource::GetCachedDataEnd(int64_t aOffset)
}
nsresult
MockMediaResource::GetCachedRanges(nsTArray<MediaByteRange>& aRanges)
MockMediaResource::GetCachedRanges(MediaByteRangeSet& aRanges)
{
aRanges.Clear();
aRanges.AppendElements(mRanges);
aRanges = mRanges;
return NS_OK;
}

View File

@ -58,7 +58,7 @@ public:
virtual bool IsTransportSeekable() override { return true; }
virtual nsresult Open(nsIStreamListener** aStreamListener) override;
virtual nsresult GetCachedRanges(nsTArray<MediaByteRange>& aRanges)
virtual nsresult GetCachedRanges(MediaByteRangeSet& aRanges)
override;
virtual const nsCString& GetContentType() const override
{
@ -74,7 +74,7 @@ protected:
private:
FILE* mFileHandle;
const char* mFileName;
nsTArray<MediaByteRange> mRanges;
MediaByteRangeSet mRanges;
Atomic<int> mEntry;
nsCString mContentType;
};

View File

@ -438,10 +438,9 @@ public:
}
mResource->AppendData(aData);
nsTArray<MediaByteRange> byteRanges;
MediaByteRange mbr =
MediaByteRangeSet byteRanges;
byteRanges +=
MediaByteRange(mParser->mOffset, mResource->GetLength());
byteRanges.AppendElement(mbr);
mParser->RebuildFragmentedIndex(byteRanges);
if (initSegment || !HasCompleteInitData()) {

View File

@ -54,10 +54,10 @@ public:
return RefPtr<nsIPrincipal>(mPrincipal).forget();
}
virtual nsresult GetCachedRanges(nsTArray<MediaByteRange>& aRanges) override
virtual nsresult GetCachedRanges(MediaByteRangeSet& aRanges) override
{
UNIMPLEMENTED();
aRanges.AppendElement(MediaByteRange(0, GetLength()));
aRanges += MediaByteRange(0, GetLength());
return NS_OK;
}

View File

@ -70,12 +70,12 @@ public:
virtual bool IsTransportSeekable() override { UNIMPLEMENTED(); return true; }
virtual nsresult Open(nsIStreamListener** aStreamListener) override { UNIMPLEMENTED(); return NS_ERROR_FAILURE; }
virtual nsresult GetCachedRanges(nsTArray<MediaByteRange>& aRanges) override
virtual nsresult GetCachedRanges(MediaByteRangeSet& aRanges) override
{
ReentrantMonitorAutoEnter mon(mMonitor);
if (mInputBuffer.GetLength()) {
aRanges.AppendElement(MediaByteRange(mInputBuffer.GetOffset(),
mInputBuffer.GetLength()));
aRanges += MediaByteRange(mInputBuffer.GetOffset(),
mInputBuffer.GetLength());
}
return NS_OK;
}

View File

@ -1160,12 +1160,12 @@ nsresult OggReader::GetSeekRanges(nsTArray<SeekRange>& aRanges)
{
MOZ_ASSERT(OnTaskQueue());
AutoPinned<MediaResource> resource(mDecoder->GetResource());
nsTArray<MediaByteRange> cached;
MediaByteRangeSet cached;
nsresult res = resource->GetCachedRanges(cached);
NS_ENSURE_SUCCESS(res, res);
for (uint32_t index = 0; index < cached.Length(); index++) {
MediaByteRange& range = cached[index];
auto& range = cached[index];
int64_t startTime = -1;
int64_t endTime = -1;
if (NS_FAILED(ResetDecode())) {
@ -1841,7 +1841,7 @@ media::TimeIntervals OggReader::GetBuffered()
}
AutoPinned<MediaResource> resource(mDecoder->GetResource());
nsTArray<MediaByteRange> ranges;
MediaByteRangeSet ranges;
nsresult res = resource->GetCachedRanges(ranges);
NS_ENSURE_SUCCESS(res, media::TimeIntervals::Invalid());

View File

@ -464,7 +464,7 @@ void MediaOmxReader::NotifyDataArrivedInternal()
}
AutoPinned<MediaResource> resource(mDecoder->GetResource());
nsTArray<MediaByteRange> byteRanges;
MediaByteRangeSet byteRanges;
nsresult rv = resource->GetCachedRanges(byteRanges);
if (NS_FAILED(rv)) {

View File

@ -383,7 +383,7 @@ void WebMBufferedState::Reset() {
mTimeMapping.Clear();
}
void WebMBufferedState::UpdateIndex(const nsTArray<MediaByteRange>& aRanges, MediaResource* aResource)
void WebMBufferedState::UpdateIndex(const MediaByteRangeSet& aRanges, MediaResource* aResource)
{
for (uint32_t index = 0; index < aRanges.Length(); index++) {
const MediaByteRange& range = aRanges[index];

View File

@ -266,7 +266,7 @@ public:
void NotifyDataArrived(const unsigned char* aBuffer, uint32_t aLength, int64_t aOffset);
void Reset();
void UpdateIndex(const nsTArray<MediaByteRange>& aRanges, MediaResource* aResource);
void UpdateIndex(const MediaByteRangeSet& aRanges, MediaResource* aResource);
bool CalculateBufferedForRange(int64_t aStartOffset, int64_t aEndOffset,
uint64_t* aStartTime, uint64_t* aEndTime);

View File

@ -439,7 +439,7 @@ WebMDemuxer::EnsureUpToDateIndex()
return;
}
AutoPinned<MediaResource> resource(mResource.GetResource());
nsTArray<MediaByteRange> byteRanges;
MediaByteRangeSet byteRanges;
nsresult rv = resource->GetCachedRanges(byteRanges);
if (NS_FAILED(rv) || !byteRanges.Length()) {
return;
@ -732,7 +732,7 @@ WebMDemuxer::GetBuffered()
media::TimeIntervals buffered;
nsTArray<MediaByteRange> ranges;
MediaByteRangeSet ranges;
nsresult rv = resource->GetCachedRanges(ranges);
if (NS_FAILED(rv)) {
return media::TimeIntervals();

View File

@ -749,7 +749,7 @@ media::TimeIntervals WebMReader::GetBuffered()
// Either we the file is not fully cached, or we couldn't find a duration in
// the WebM bitstream.
nsTArray<MediaByteRange> ranges;
MediaByteRangeSet ranges;
nsresult res = resource->GetCachedRanges(ranges);
NS_ENSURE_SUCCESS(res, media::TimeIntervals::Invalid());
@ -788,7 +788,7 @@ void WebMReader::NotifyDataArrivedInternal()
{
MOZ_ASSERT(OnTaskQueue());
AutoPinned<MediaResource> resource(mDecoder->GetResource());
nsTArray<MediaByteRange> byteRanges;
MediaByteRangeSet byteRanges;
nsresult rv = resource->GetCachedRanges(byteRanges);
if (NS_FAILED(rv)) {

View File

@ -56,7 +56,7 @@ Box::Box(BoxContext* aContext, uint64_t aOffset, const Box* aParent)
return;
}
byteRange = &mContext->mByteRanges[i];
byteRange = static_cast<const MediaByteRange*>(&mContext->mByteRanges[i]);
if (byteRange->Contains(headerRange)) {
break;
}
@ -88,7 +88,7 @@ Box::Box(BoxContext* aContext, uint64_t aOffset, const Box* aParent)
mBodyOffset = bigLengthRange.mEnd;
} else if (size == 0) {
// box extends to end of file.
size = mContext->mByteRanges.LastElement().mEnd - aOffset;
size = mContext->mByteRanges.LastInterval().mEnd - aOffset;
mBodyOffset = headerRange.mEnd;
} else {
mBodyOffset = headerRange.mEnd;

View File

@ -25,7 +25,7 @@ public:
// Given that we're processing this in order we don't use a binary search
// to find the apropriate time range. Instead we search linearly from the
// last used point.
explicit RangeFinder(const nsTArray<mozilla::MediaByteRange>& ranges)
explicit RangeFinder(const MediaByteRangeSet& ranges)
: mRanges(ranges), mIndex(0)
{
// Ranges must be normalised for this to work
@ -34,7 +34,7 @@ public:
bool Contains(MediaByteRange aByteRange);
private:
const nsTArray<MediaByteRange>& mRanges;
const MediaByteRangeSet& mRanges;
size_t mIndex;
};
@ -266,7 +266,7 @@ Index::Index(const nsTArray<Indice>& aIndex,
Index::~Index() {}
void
Index::UpdateMoofIndex(const nsTArray<MediaByteRange>& aByteRanges)
Index::UpdateMoofIndex(const MediaByteRangeSet& aByteRanges)
{
if (!mMoofParser) {
return;
@ -276,7 +276,7 @@ Index::UpdateMoofIndex(const nsTArray<MediaByteRange>& aByteRanges)
}
Microseconds
Index::GetEndCompositionIfBuffered(const nsTArray<MediaByteRange>& aByteRanges)
Index::GetEndCompositionIfBuffered(const MediaByteRangeSet& aByteRanges)
{
FallibleTArray<Sample>* index;
if (mMoofParser) {
@ -305,7 +305,7 @@ Index::GetEndCompositionIfBuffered(const nsTArray<MediaByteRange>& aByteRanges)
void
Index::ConvertByteRangesToTimeRanges(
const nsTArray<MediaByteRange>& aByteRanges,
const MediaByteRangeSet& aByteRanges,
nsTArray<Interval<Microseconds>>* aTimeRanges)
{
RangeFinder rangeFinder(aByteRanges);

View File

@ -28,7 +28,7 @@ using namespace mozilla;
bool
MoofParser::RebuildFragmentedIndex(
const nsTArray<mozilla::MediaByteRange>& aByteRanges)
const MediaByteRangeSet& aByteRanges)
{
BoxContext context(mSource, aByteRanges);
return RebuildFragmentedIndex(context);
@ -59,7 +59,7 @@ MoofParser::RebuildFragmentedIndex(BoxContext& aContext)
}
mMoofs.AppendElement(moof);
mMediaRanges.AppendElement(moof.mRange);
mMediaRanges += moof.mRange;
foundValidMoof = true;
} else if (box.IsType("mdat") && !Moofs().IsEmpty()) {
// Check if we have all our data from last moof.
@ -67,8 +67,8 @@ MoofParser::RebuildFragmentedIndex(BoxContext& aContext)
media::Interval<int64_t> datarange(moof.mMdatRange.mStart, moof.mMdatRange.mEnd, 0);
media::Interval<int64_t> mdat(box.Range().mStart, box.Range().mEnd, 0);
if (datarange.Intersects(mdat)) {
mMediaRanges.LastElement() =
mMediaRanges.LastElement().Span(box.Range());
mMediaRanges.LastInterval() =
mMediaRanges.LastInterval().Span(box.Range());
}
}
mOffset = box.NextOffset();
@ -128,15 +128,15 @@ MoofParser::BlockingReadNextMoof()
{
int64_t length = std::numeric_limits<int64_t>::max();
mSource->Length(&length);
nsTArray<MediaByteRange> byteRanges;
byteRanges.AppendElement(MediaByteRange(0, length));
MediaByteRangeSet byteRanges;
byteRanges += MediaByteRange(0, length);
RefPtr<mp4_demuxer::BlockingStream> stream = new BlockingStream(mSource);
BoxContext context(stream, byteRanges);
for (Box box(&context, mOffset); box.IsAvailable(); box = box.Next()) {
if (box.IsType("moof")) {
byteRanges.Clear();
byteRanges.AppendElement(MediaByteRange(mOffset, box.Range().mEnd));
byteRanges += MediaByteRange(mOffset, box.Range().mEnd);
return RebuildFragmentedIndex(context);
}
}
@ -149,8 +149,8 @@ MoofParser::ScanForMetadata(mozilla::MediaByteRange& aFtyp,
{
int64_t length = std::numeric_limits<int64_t>::max();
mSource->Length(&length);
nsTArray<MediaByteRange> byteRanges;
byteRanges.AppendElement(MediaByteRange(0, length));
MediaByteRangeSet byteRanges;
byteRanges += MediaByteRange(0, length);
RefPtr<mp4_demuxer::BlockingStream> stream = new BlockingStream(mSource);
BoxContext context(stream, byteRanges);
@ -207,7 +207,7 @@ MoofParser::Metadata()
}
Interval<Microseconds>
MoofParser::GetCompositionRange(const nsTArray<MediaByteRange>& aByteRanges)
MoofParser::GetCompositionRange(const MediaByteRangeSet& aByteRanges)
{
Interval<Microseconds> compositionRange;
BoxContext context(mSource, aByteRanges);

View File

@ -23,13 +23,13 @@ class Stream;
class BoxContext
{
public:
BoxContext(Stream* aSource, const nsTArray<MediaByteRange>& aByteRanges)
BoxContext(Stream* aSource, const MediaByteRangeSet& aByteRanges)
: mSource(aSource), mByteRanges(aByteRanges)
{
}
RefPtr<Stream> mSource;
const nsTArray<MediaByteRange>& mByteRanges;
const MediaByteRangeSet& mByteRanges;
};
class Box

View File

@ -60,11 +60,11 @@ public:
bool aIsAudio,
mozilla::Monitor* aMonitor);
void UpdateMoofIndex(const nsTArray<mozilla::MediaByteRange>& aByteRanges);
void UpdateMoofIndex(const mozilla::MediaByteRangeSet& aByteRanges);
Microseconds GetEndCompositionIfBuffered(
const nsTArray<mozilla::MediaByteRange>& aByteRanges);
const mozilla::MediaByteRangeSet& aByteRanges);
void ConvertByteRangesToTimeRanges(
const nsTArray<mozilla::MediaByteRange>& aByteRanges,
const mozilla::MediaByteRangeSet& aByteRanges,
nsTArray<Interval<Microseconds>>* aTimeRanges);
uint64_t GetEvictionOffset(Microseconds aTime);
bool IsFragmented() { return mMoofParser; }

View File

@ -165,7 +165,7 @@ public:
class AuxInfo {
public:
AuxInfo(int64_t aMoofOffset, Saiz& aSaiz, Saio& aSaio);
bool GetByteRanges(nsTArray<MediaByteRange>* aByteRanges);
bool GetByteRanges(MediaByteRangeSet* aByteRanges);
private:
int64_t mMoofOffset;
@ -212,10 +212,10 @@ public:
// the composition range for MSE. We need an array of tracks.
}
bool RebuildFragmentedIndex(
const nsTArray<mozilla::MediaByteRange>& aByteRanges);
const mozilla::MediaByteRangeSet& aByteRanges);
bool RebuildFragmentedIndex(BoxContext& aContext);
Interval<Microseconds> GetCompositionRange(
const nsTArray<mozilla::MediaByteRange>& aByteRanges);
const mozilla::MediaByteRangeSet& aByteRanges);
bool ReachedEnd();
void ParseMoov(Box& aBox);
void ParseTrak(Box& aBox);
@ -250,7 +250,7 @@ private:
void ScanForMetadata(mozilla::MediaByteRange& aFtyp,
mozilla::MediaByteRange& aMoov);
nsTArray<Moof> mMoofs;
nsTArray<MediaByteRange> mMediaRanges;
MediaByteRangeSet mMediaRanges;
bool mIsAudio;
};
}

View File

@ -102,8 +102,7 @@ TEST(stagefright_MoofParser, EmptyStream)
EXPECT_EQ(0u, parser.mOffset);
EXPECT_TRUE(parser.ReachedEnd());
nsTArray<MediaByteRange> byteRanges;
byteRanges.AppendElement(MediaByteRange(0, 0));
MediaByteRangeSet byteRanges;
EXPECT_FALSE(parser.RebuildFragmentedIndex(byteRanges));
EXPECT_TRUE(parser.GetCompositionRange(byteRanges).IsNull());
@ -292,8 +291,7 @@ TEST(stagefright_MoofParser, test_case_mp4)
EXPECT_EQ(0u, parser.mOffset);
EXPECT_FALSE(parser.ReachedEnd());
nsTArray<MediaByteRange> byteRanges;
byteRanges.AppendElement(MediaByteRange(0, 0));
MediaByteRangeSet byteRanges;
EXPECT_FALSE(parser.RebuildFragmentedIndex(byteRanges));
EXPECT_TRUE(parser.GetCompositionRange(byteRanges).IsNull());
@ -329,8 +327,7 @@ TEST(stagefright_MoofParser, test_case_mp4_subsets)
new TestStream(buffer.Elements() + offset, size);
MoofParser parser(stream, 0, false, &monitor);
nsTArray<MediaByteRange> byteRanges;
byteRanges.AppendElement(MediaByteRange(0, 0));
MediaByteRangeSet byteRanges;
EXPECT_FALSE(parser.RebuildFragmentedIndex(byteRanges));
parser.GetCompositionRange(byteRanges);
parser.HasMetadata();