mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-04 11:26:09 +00:00
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:
parent
1e3d2193d7
commit
fe9bd75acb
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user