Bug 1171629 - Use fallible array to store MP4 samples index. r=kentuckyfriedtakahe, a=lizzard
authorJean-Yves Avenard <jyavenard@mozilla.com>
Tue, 09 Jun 2015 19:22:39 +1000
changeset 266258 82b74e7dea64
parent 266257 1997f291fc30
child 266259 adb302d8d588
push id4804
push userryanvm@gmail.com
push date2015-06-15 15:02 +0000
treeherdermozilla-beta@05b522f50491 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskentuckyfriedtakahe, lizzard
bugs1171629
milestone39.0
Bug 1171629 - Use fallible array to store MP4 samples index. r=kentuckyfriedtakahe, a=lizzard
media/libstagefright/binding/Index.cpp
media/libstagefright/binding/MoofParser.cpp
media/libstagefright/binding/include/mp4_demuxer/Index.h
media/libstagefright/binding/include/mp4_demuxer/MoofParser.h
--- a/media/libstagefright/binding/Index.cpp
+++ b/media/libstagefright/binding/Index.cpp
@@ -230,25 +230,29 @@ SampleIterator::GetNextKeyframeTime()
 Index::Index(const stagefright::Vector<MediaSource::Indice>& aIndex,
              Stream* aSource, uint32_t aTrackId, bool aIsAudio, Monitor* aMonitor)
   : mSource(aSource)
   , mMonitor(aMonitor)
 {
   if (aIndex.isEmpty()) {
     mMoofParser = new MoofParser(aSource, aTrackId, aIsAudio, aMonitor);
   } else {
+    if (!mIndex.SetCapacity(aIndex.size())) {
+      // OOM.
+      return;
+    }
     for (size_t i = 0; i < aIndex.size(); i++) {
       const MediaSource::Indice& indice = aIndex[i];
       Sample sample;
       sample.mByteRange = MediaByteRange(indice.start_offset,
                                          indice.end_offset);
       sample.mCompositionRange = Interval<Microseconds>(indice.start_composition,
                                                         indice.end_composition);
       sample.mSync = indice.sync;
-      mIndex.AppendElement(sample);
+      MOZ_ALWAYS_TRUE(mIndex.AppendElement(sample));
     }
   }
 }
 
 Index::~Index() {}
 
 void
 Index::UpdateMoofIndex(const nsTArray<MediaByteRange>& aByteRanges)
@@ -258,17 +262,17 @@ Index::UpdateMoofIndex(const nsTArray<Me
   }
 
   mMoofParser->RebuildFragmentedIndex(aByteRanges);
 }
 
 Microseconds
 Index::GetEndCompositionIfBuffered(const nsTArray<MediaByteRange>& aByteRanges)
 {
-  nsTArray<Sample>* index;
+  FallibleTArray<Sample>* index;
   if (mMoofParser) {
     if (!mMoofParser->ReachedEnd() || mMoofParser->Moofs().IsEmpty()) {
       return 0;
     }
     index = &mMoofParser->Moofs().LastElement().mIndex;
   } else {
     index = &mIndex;
   }
@@ -291,17 +295,17 @@ Index::GetEndCompositionIfBuffered(const
 void
 Index::ConvertByteRangesToTimeRanges(
   const nsTArray<MediaByteRange>& aByteRanges,
   nsTArray<Interval<Microseconds>>* aTimeRanges)
 {
   RangeFinder rangeFinder(aByteRanges);
   nsTArray<Interval<Microseconds>> timeRanges;
 
-  nsTArray<nsTArray<Sample>*> indexes;
+  nsTArray<FallibleTArray<Sample>*> indexes;
   if (mMoofParser) {
     // We take the index out of the moof parser and move it into a local
     // variable so we don't get concurrency issues. It gets freed when we
     // exit this function.
     for (int i = 0; i < mMoofParser->Moofs().Length(); i++) {
       Moof& moof = mMoofParser->Moofs()[i];
 
       // We need the entire moof in order to play anything
@@ -314,17 +318,17 @@ Index::ConvertByteRangesToTimeRanges(
       }
     }
   } else {
     indexes.AppendElement(&mIndex);
   }
 
   bool hasSync = false;
   for (size_t i = 0; i < indexes.Length(); i++) {
-    nsTArray<Sample>* index = indexes[i];
+    FallibleTArray<Sample>* index = indexes[i];
     for (size_t j = 0; j < index->Length(); j++) {
       const Sample& sample = (*index)[j];
       if (!rangeFinder.Contains(sample.mByteRange)) {
         // We process the index in decode order so we clear hasSync when we hit
         // a range that isn't buffered.
         hasSync = false;
         continue;
       }
--- a/media/libstagefright/binding/MoofParser.cpp
+++ b/media/libstagefright/binding/MoofParser.cpp
@@ -425,16 +425,22 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, 
     return false;
   }
 
   uint64_t offset = aTfhd.mBaseDataOffset + (flags & 1 ? reader->ReadU32() : 0);
   bool hasFirstSampleFlags = flags & 4;
   uint32_t firstSampleFlags = hasFirstSampleFlags ? reader->ReadU32() : 0;
   uint64_t decodeTime = *aDecodeTime;
   nsTArray<Interval<Microseconds>> timeRanges;
+
+  if (!mIndex.SetCapacity(sampleCount)) {
+    LOG(Moof, "Out of Memory");
+    return false;
+  }
+
   for (size_t i = 0; i < sampleCount; i++) {
     uint32_t sampleDuration =
       flags & 0x100 ? reader->ReadU32() : aTfhd.mDefaultSampleDuration;
     uint32_t sampleSize =
       flags & 0x200 ? reader->ReadU32() : aTfhd.mDefaultSampleSize;
     uint32_t sampleFlags =
       flags & 0x400 ? reader->ReadU32() : hasFirstSampleFlags && i == 0
                                             ? firstSampleFlags
@@ -453,17 +459,17 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, 
       aMdhd.ToMicroseconds((int64_t)decodeTime + ctsOffset - aEdts.mMediaStart),
       aMdhd.ToMicroseconds((int64_t)decodeTime + ctsOffset + sampleDuration - aEdts.mMediaStart));
     decodeTime += sampleDuration;
 
     // Sometimes audio streams don't properly mark their samples as keyframes,
     // because every audio sample is a keyframe.
     sample.mSync = !(sampleFlags & 0x1010000) || aIsAudio;
 
-    mIndex.AppendElement(sample);
+    MOZ_ALWAYS_TRUE(mIndex.AppendElement(sample));
 
     mMdatRange = mMdatRange.Extents(sample.mByteRange);
   }
   mMaxRoundingError += aMdhd.ToMicroseconds(sampleCount);
 
   nsTArray<Sample*> ctsOrder;
   for (int i = 0; i < mIndex.Length(); i++) {
     ctsOrder.AppendElement(&mIndex[i]);
--- a/media/libstagefright/binding/include/mp4_demuxer/Index.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/Index.h
@@ -50,15 +50,15 @@ public:
   bool IsFragmented() { return mMoofParser; }
 
   friend class SampleIterator;
 
 private:
   ~Index();
 
   Stream* mSource;
-  nsTArray<Sample> mIndex;
+  FallibleTArray<Sample> mIndex;
   nsAutoPtr<MoofParser> mMoofParser;
   Monitor* mMonitor;
 };
 }
 
 #endif
--- a/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h
@@ -170,17 +170,17 @@ class Moof : public Atom
 public:
   Moof(Box& aBox, Trex& aTrex, Mdhd& aMdhd, Edts& aEdts, Sinf& aSinf, bool aIsAudio);
   bool GetAuxInfo(AtomType aType, nsTArray<MediaByteRange>* aByteRanges);
   void FixRounding(const Moof& aMoof);
 
   mozilla::MediaByteRange mRange;
   mozilla::MediaByteRange mMdatRange;
   Interval<Microseconds> mTimeRange;
-  nsTArray<Sample> mIndex;
+  FallibleTArray<Sample> mIndex;
 
   nsTArray<Saiz> mSaizs;
   nsTArray<Saio> mSaios;
 
 private:
   void ParseTraf(Box& aBox, Trex& aTrex, Mdhd& aMdhd, Edts& aEdts, Sinf& aSinf, bool aIsAudio);
   // aDecodeTime is updated to the end of the parsed TRUN on return.
   bool ParseTrun(Box& aBox, Tfhd& aTfhd, Mdhd& aMdhd, Edts& aEdts, uint64_t* aDecodeTime, bool aIsAudio);