diff --git a/media/libstagefright/binding/Index.cpp b/media/libstagefright/binding/Index.cpp index 910373b03ec0..3a2010d1f5b0 100644 --- a/media/libstagefright/binding/Index.cpp +++ b/media/libstagefright/binding/Index.cpp @@ -83,6 +83,12 @@ SampleIterator::SampleIterator(Index* aIndex) , mCurrentMoof(0) , mCurrentSample(0) { + mIndex->RegisterIterator(this); +} + +SampleIterator::~SampleIterator() +{ + mIndex->UnregisterIterator(this); } already_AddRefed SampleIterator::GetNext() @@ -386,12 +392,37 @@ Index::~Index() {} void Index::UpdateMoofIndex(const MediaByteRangeSet& aByteRanges) +{ + UpdateMoofIndex(aByteRanges, false); +} + +void +Index::UpdateMoofIndex(const MediaByteRangeSet& aByteRanges, bool aCanEvict) { if (!mMoofParser) { return; } - - mMoofParser->RebuildFragmentedIndex(aByteRanges); + size_t moofs = mMoofParser->Moofs().Length(); + bool canEvict = aCanEvict && moofs > 1; + if (canEvict) { + // Check that we can trim the mMoofParser. We can only do so if all + // iterators have demuxed all possible samples. + for (const SampleIterator* iterator : mIterators) { + if ((iterator->mCurrentSample == 0 && iterator->mCurrentMoof == moofs) || + iterator->mCurrentMoof == moofs - 1) { + continue; + } + canEvict = false; + break; + } + } + mMoofParser->RebuildFragmentedIndex(aByteRanges, &canEvict); + if (canEvict) { + // The moofparser got trimmed. Adjust all registered iterators. + for (SampleIterator* iterator : mIterators) { + iterator->mCurrentMoof -= moofs - 1; + } + } } Microseconds @@ -559,4 +590,17 @@ Index::GetEvictionOffset(Microseconds aTime) } return offset; } + +void +Index::RegisterIterator(SampleIterator* aIterator) +{ + mIterators.AppendElement(aIterator); +} + +void +Index::UnregisterIterator(SampleIterator* aIterator) +{ + mIterators.RemoveElement(aIterator); +} + } diff --git a/media/libstagefright/binding/MoofParser.cpp b/media/libstagefright/binding/MoofParser.cpp index e2fbefae4b0b..13ccde73252f 100644 --- a/media/libstagefright/binding/MoofParser.cpp +++ b/media/libstagefright/binding/MoofParser.cpp @@ -31,13 +31,28 @@ using namespace mozilla; const uint32_t kKeyIdSize = 16; bool -MoofParser::RebuildFragmentedIndex( - const MediaByteRangeSet& aByteRanges) +MoofParser::RebuildFragmentedIndex(const MediaByteRangeSet& aByteRanges) { BoxContext context(mSource, aByteRanges); return RebuildFragmentedIndex(context); } +bool +MoofParser::RebuildFragmentedIndex( + const MediaByteRangeSet& aByteRanges, bool* aCanEvict) +{ + MOZ_ASSERT(aCanEvict); + if (*aCanEvict && mMoofs.Length() > 1) { + MOZ_ASSERT(mMoofs.Length() == mMediaRanges.Length()); + mMoofs.RemoveElementsAt(0, mMoofs.Length() - 1); + mMediaRanges.RemoveElementsAt(0, mMediaRanges.Length() - 1); + *aCanEvict = true; + } else { + *aCanEvict = false; + } + return RebuildFragmentedIndex(aByteRanges); +} + bool MoofParser::RebuildFragmentedIndex(BoxContext& aContext) { diff --git a/media/libstagefright/binding/include/mp4_demuxer/Index.h b/media/libstagefright/binding/include/mp4_demuxer/Index.h index 8a18acdaaed1..1ae0cafa9206 100644 --- a/media/libstagefright/binding/include/mp4_demuxer/Index.h +++ b/media/libstagefright/binding/include/mp4_demuxer/Index.h @@ -27,10 +27,10 @@ class SampleIterator { public: explicit SampleIterator(Index* aIndex); + ~SampleIterator(); already_AddRefed GetNext(); void Seek(Microseconds aTime); Microseconds GetNextKeyframeTime(); - private: Sample* Get(); @@ -38,6 +38,7 @@ private: void Next(); RefPtr mIndex; + friend class Index; size_t mCurrentMoof; size_t mCurrentSample; }; @@ -98,6 +99,8 @@ public: uint32_t aTrackId, bool aIsAudio); + void UpdateMoofIndex(const mozilla::MediaByteRangeSet& aByteRanges, + bool aCanEvict); void UpdateMoofIndex(const mozilla::MediaByteRangeSet& aByteRanges); Microseconds GetEndCompositionIfBuffered( const mozilla::MediaByteRangeSet& aByteRanges); @@ -110,11 +113,14 @@ public: private: ~Index(); + void RegisterIterator(SampleIterator* aIterator); + void UnregisterIterator(SampleIterator* aIterator); Stream* mSource; FallibleTArray mIndex; FallibleTArray mDataOffset; nsAutoPtr mMoofParser; + nsTArray mIterators; // ConvertByteRangesToTimeRanges cache mozilla::MediaByteRangeSet mLastCachedRanges; diff --git a/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h b/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h index e83933ce44d3..bb895555c879 100644 --- a/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h +++ b/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h @@ -262,6 +262,11 @@ public: } bool RebuildFragmentedIndex( const mozilla::MediaByteRangeSet& aByteRanges); + // If *aCanEvict is set to true. then will remove all moofs already parsed + // from index then rebuild the index. *aCanEvict is set to true upon return if + // some moofs were removed. + bool RebuildFragmentedIndex( + const mozilla::MediaByteRangeSet& aByteRanges, bool* aCanEvict); bool RebuildFragmentedIndex(BoxContext& aContext); Interval GetCompositionRange( const mozilla::MediaByteRangeSet& aByteRanges);