Bug 1227396: P14. Reduce memory usage of sample index for audio tracks. r=cpearce
authorJean-Yves Avenard <jyavenard@mozilla.com>
Fri, 27 Nov 2015 15:51:58 +1100
changeset 274544 fd4d78b89cc0ee6f464c65b17b957e52572041ab
parent 274543 0d8e85b5983278ed9c7ed0cbd88c6b1c9d1b307a
child 274545 47075637410f4163f7855928ee557e218b7afef0
push id68621
push userjyavenard@mozilla.com
push dateMon, 30 Nov 2015 00:49:17 +0000
treeherdermozilla-inbound@fd4d78b89cc0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1227396
milestone45.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1227396: P14. Reduce memory usage of sample index for audio tracks. r=cpearce All samples in an audio track are keyframes. As such, use block on 128 samples instead.
media/libstagefright/binding/Index.cpp
media/libstagefright/binding/include/mp4_demuxer/Index.h
--- a/media/libstagefright/binding/Index.cpp
+++ b/media/libstagefright/binding/Index.cpp
@@ -233,30 +233,32 @@ SampleIterator::GetNextKeyframeTime()
   return -1;
 }
 
 Index::Index(const nsTArray<Indice>& aIndex,
              Stream* aSource,
              uint32_t aTrackId,
              bool aIsAudio)
   : mSource(aSource)
+  , mIsAudio(aIsAudio)
 {
   if (aIndex.IsEmpty()) {
     mMoofParser = new MoofParser(aSource, aTrackId, aIsAudio);
   } else {
     if (!mIndex.SetCapacity(aIndex.Length(), fallible)) {
       // OOM.
       return;
     }
     media::IntervalSet<int64_t> intervalTime;
     MediaByteRange intervalRange;
     bool haveSync = false;
     bool progressive = true;
     int64_t lastOffset = 0;
-    for (const Indice& indice : aIndex) {
+    for (size_t i = 0; i < aIndex.Length(); i++) {
+      const Indice& indice = aIndex[i];
       if (indice.sync) {
         haveSync = true;
       }
       if (!haveSync) {
         continue;
       }
 
       Sample sample;
@@ -269,17 +271,18 @@ Index::Index(const nsTArray<Indice>& aIn
       // FIXME: Make this infallible after bug 968520 is done.
       MOZ_ALWAYS_TRUE(mIndex.AppendElement(sample, fallible));
       if (indice.start_offset < lastOffset) {
         NS_WARNING("Chunks in MP4 out of order, expect slow down");
         progressive = false;
       }
       lastOffset = indice.end_offset;
 
-      if (sample.mSync && progressive) {
+      // Pack audio samples in group of 128.
+      if (sample.mSync && progressive && (!mIsAudio || !(i % 128))) {
         if (mDataOffset.Length()) {
           auto& last = mDataOffset.LastElement();
           last.mEndOffset = intervalRange.mEnd;
           NS_ASSERTION(intervalTime.Length() == 1, "Discontinuous samples between keyframes");
           last.mTime.start = intervalTime.GetStart();
           last.mTime.end = intervalTime.GetEnd();
         }
         if (!mDataOffset.AppendElement(MP4DataOffset(mIndex.Length() - 1,
@@ -353,23 +356,35 @@ Index::ConvertByteRangesToTimeRanges(con
     return mLastBufferedRanges;
   }
   mLastCachedRanges = aByteRanges;
 
   if (mDataOffset.Length()) {
     TimeIntervals timeRanges;
     for (const auto& range : aByteRanges) {
       uint32_t start = mDataOffset.IndexOfFirstElementGt(range.mStart - 1);
-      if (start == mDataOffset.Length()) {
+      if (!mIsAudio && start == mDataOffset.Length()) {
         continue;
       }
       uint32_t end = mDataOffset.IndexOfFirstElementGt(range.mEnd, MP4DataOffset::EndOffsetComparator());
-      if (end < start) {
+      if (!mIsAudio && end < start) {
         continue;
       }
+      if (mIsAudio && start &&
+          range.Intersects(MediaByteRange(mDataOffset[start-1].mStartOffset,
+                                          mDataOffset[start-1].mEndOffset))) {
+        // Check if previous audio data block contains some available samples.
+        for (size_t i = mDataOffset[start-1].mIndex; i < mIndex.Length(); i++) {
+          if (range.ContainsStrict(mIndex[i].mByteRange)) {
+            timeRanges +=
+              TimeInterval(TimeUnit::FromMicroseconds(mIndex[i].mCompositionRange.start),
+                           TimeUnit::FromMicroseconds(mIndex[i].mCompositionRange.end));
+          }
+        }
+      }
       if (end > start) {
         timeRanges +=
           TimeInterval(TimeUnit::FromMicroseconds(mDataOffset[start].mTime.start),
                        TimeUnit::FromMicroseconds(mDataOffset[end-1].mTime.end));
       }
       if (end < mDataOffset.Length()) {
         // Find samples in partial block contained in the byte range.
         for (size_t i = mDataOffset[end].mIndex;
--- a/media/libstagefright/binding/include/mp4_demuxer/Index.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/Index.h
@@ -110,12 +110,13 @@ private:
   Stream* mSource;
   FallibleTArray<Sample> mIndex;
   FallibleTArray<MP4DataOffset> mDataOffset;
   nsAutoPtr<MoofParser> mMoofParser;
 
   // ConvertByteRangesToTimeRanges cache
   mozilla::MediaByteRangeSet mLastCachedRanges;
   mozilla::media::TimeIntervals mLastBufferedRanges;
+  bool mIsAudio;
 };
 }
 
 #endif