Bug 1367128: P2. Add methods to trim index. r=gerald

The MoofParser's used by the MP4Demuxer, can grow very large as it keeps adding new tables and is never reset.

Once we have demuxed all data present in the MP4 media segment, we no longer require the samples table for that media segment and we can drop it from the index.

Unfortunately. some websites (in particular some using live video) use media segments containing a single sample in order to (incorrectly) reduce latency. While this is a very bad approach from a performance perspective it does happen in the wild.

MozReview-Commit-ID: I66jxcScmKM

--HG--
extra : rebase_source : d0029b74df94b92dc0a115c77f6e560b30e5ed5c
This commit is contained in:
Jean-Yves Avenard 2017-06-02 21:15:10 +02:00
Родитель 1e3d2193d7
Коммит fe9bd75acb
4 изменённых файлов: 75 добавлений и 5 удалений

Просмотреть файл

@ -83,6 +83,12 @@ SampleIterator::SampleIterator(Index* aIndex)
, mCurrentMoof(0)
, mCurrentSample(0)
{
mIndex->RegisterIterator(this);
}
SampleIterator::~SampleIterator()
{
mIndex->UnregisterIterator(this);
}
already_AddRefed<MediaRawData> 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);
}
}

Просмотреть файл

@ -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)
{

Просмотреть файл

@ -27,10 +27,10 @@ class SampleIterator
{
public:
explicit SampleIterator(Index* aIndex);
~SampleIterator();
already_AddRefed<mozilla::MediaRawData> GetNext();
void Seek(Microseconds aTime);
Microseconds GetNextKeyframeTime();
private:
Sample* Get();
@ -38,6 +38,7 @@ private:
void Next();
RefPtr<Index> 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<Sample> mIndex;
FallibleTArray<MP4DataOffset> mDataOffset;
nsAutoPtr<MoofParser> mMoofParser;
nsTArray<SampleIterator*> mIterators;
// ConvertByteRangesToTimeRanges cache
mozilla::MediaByteRangeSet mLastCachedRanges;

Просмотреть файл

@ -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<Microseconds> GetCompositionRange(
const mozilla::MediaByteRangeSet& aByteRanges);