Bug 1098126 - MoofParser forced moof read; r=mattwoodrow
☠☠ backed out by 225f36741b2f ☠ ☠
authorAnthony Jones <ajones@mozilla.com>
Thu, 11 Dec 2014 15:29:37 +1300
changeset 219139 4e7a358bdd20726b3d1a319a281c927e63ce718a
parent 219138 36f3e9c34b7088b3ab4af01dc9ba5e5174049584
child 219140 4b8bb6132ae1c9ec4205b214c51e510756c6f46c
push id52744
push userajones@mozilla.com
push dateThu, 11 Dec 2014 02:29:47 +0000
treeherdermozilla-inbound@81bdd9d3aa25 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1098126
milestone37.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 1098126 - MoofParser forced moof read; r=mattwoodrow
media/libstagefright/binding/Index.cpp
media/libstagefright/binding/MoofParser.cpp
media/libstagefright/binding/include/mp4_demuxer/MoofParser.h
--- a/media/libstagefright/binding/Index.cpp
+++ b/media/libstagefright/binding/Index.cpp
@@ -107,18 +107,21 @@ MP4Sample* SampleIterator::GetNext()
 MP4Sample* SampleIterator::Get()
 {
   if (!mIndex->mMoofParser) {
     return nullptr;
   }
 
   nsTArray<Moof>& moofs = mIndex->mMoofParser->mMoofs;
   while (true) {
-    if (mCurrentMoof >= moofs.Length()) {
-      return nsAutoPtr<MP4Sample>();
+    if (mCurrentMoof == moofs.Length()) {
+      if (!mIndex->mMoofParser->BlockingReadNextMoof()) {
+        return nsAutoPtr<MP4Sample>();
+      }
+      MOZ_ASSERT(mCurrentMoof < moofs.Length());
     }
     if (mCurrentSample < moofs[mCurrentMoof].mIndex.Length()) {
       break;
     }
     mCurrentSample = 0;
     ++mCurrentMoof;
   }
   Sample& s = moofs[mCurrentMoof].mIndex[mCurrentSample];
@@ -149,16 +152,19 @@ void SampleIterator::Seek(Microseconds a
     nsAutoPtr<MP4Sample> sample(Get());
     if (sample->composition_timestamp > aTime) {
       break;
     }
     if (sample->is_sync_point) {
       syncMoof = mCurrentMoof;
       syncSample = mCurrentSample;
     }
+    if (sample->composition_timestamp == aTime) {
+      break;
+    }
     Next();
   }
   mCurrentMoof = syncMoof;
   mCurrentSample = syncSample;
 }
 
 Index::Index(const stagefright::Vector<MediaSource::Indice>& aIndex,
              Stream* aSource, uint32_t aTrackId)
--- a/media/libstagefright/binding/MoofParser.cpp
+++ b/media/libstagefright/binding/MoofParser.cpp
@@ -7,22 +7,27 @@
 
 namespace mp4_demuxer
 {
 
 using namespace stagefright;
 using namespace mozilla;
 
 void
-MoofParser::RebuildFragmentedIndex(const nsTArray<MediaByteRange>& aByteRanges)
+MoofParser::RebuildFragmentedIndex(
+  const nsTArray<mozilla::MediaByteRange>& aByteRanges)
 {
   BoxContext context(mSource, aByteRanges);
+  RebuildFragmentedIndex(context);
+}
 
-  Box box(&context, mOffset);
-  for (; box.IsAvailable(); box = box.Next()) {
+void
+MoofParser::RebuildFragmentedIndex(BoxContext& aContext)
+{
+  for (Box box(&aContext, mOffset); box.IsAvailable(); box = box.Next()) {
     if (box.IsType("moov")) {
       mInitRange = MediaByteRange(0, box.Range().mEnd);
       ParseMoov(box);
     } else if (box.IsType("moof")) {
       Moof moof(box, mTrex, mMdhd, mEdts);
 
       if (!mMoofs.IsEmpty()) {
         // Stitch time ranges together in the case of a (hopefully small) time
@@ -31,16 +36,66 @@ MoofParser::RebuildFragmentedIndex(const
       }
 
       mMoofs.AppendElement(moof);
     }
     mOffset = box.NextOffset();
   }
 }
 
+class BlockingStream : public Stream {
+public:
+  BlockingStream(Stream* aStream) : mStream(aStream)
+  {
+  }
+
+  bool ReadAt(int64_t offset, void* data, size_t size, size_t* bytes_read)
+    MOZ_OVERRIDE
+  {
+    return mStream->ReadAt(offset, data, size, bytes_read);
+  }
+
+  bool CachedReadAt(int64_t offset, void* data, size_t size, size_t* bytes_read)
+    MOZ_OVERRIDE
+  {
+    return mStream->ReadAt(offset, data, size, bytes_read);
+  }
+
+  virtual bool Length(int64_t* size) MOZ_OVERRIDE
+  {
+    return mStream->Length(size);
+  }
+
+private:
+  nsRefPtr<Stream> mStream;
+};
+
+bool
+MoofParser::BlockingReadNextMoof()
+{
+  nsTArray<MediaByteRange> byteRanges;
+  int64_t size;
+  bool hasSize = mSource->Length(&size);
+  byteRanges.AppendElement(
+    MediaByteRange(0,hasSize ? size : std::numeric_limits<int64_t>::max()));
+  mp4_demuxer::BlockingStream* stream = new BlockingStream(mSource);
+
+  BoxContext context(stream, byteRanges);
+  for (Box box(&context, mOffset); box.IsAvailable(); box = box.Next()) {
+    if (box.IsType("moof")) {
+      byteRanges.Clear();
+      byteRanges.AppendElement(MediaByteRange(mOffset, box.Range().mEnd));
+      RebuildFragmentedIndex(context);
+      return true;
+    }
+  }
+  return false;
+}
+
+
 Interval<Microseconds>
 MoofParser::GetCompositionRange(const nsTArray<MediaByteRange>& aByteRanges)
 {
   Interval<Microseconds> compositionRange;
   BoxContext context(mSource, aByteRanges);
   for (size_t i = 0; i < mMoofs.Length(); i++) {
     Moof& moof = mMoofs[i];
     Box box(&context, moof.mRange.mStart);
--- a/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h
@@ -7,16 +7,17 @@
 
 #include "mp4_demuxer/mp4_demuxer.h"
 #include "MediaResource.h"
 
 namespace mp4_demuxer {
 
 class Stream;
 class Box;
+class BoxContext;
 class Moof;
 
 class Tkhd
 {
 public:
   Tkhd()
     : mCreationTime(0)
     , mModificationTime(0)
@@ -136,24 +137,27 @@ public:
   MoofParser(Stream* aSource, uint32_t aTrackId)
     : mSource(aSource), mOffset(0), mTrex(aTrackId)
   {
     // Setting the mTrex.mTrackId to 0 is a nasty work around for calculating
     // the composition range for MSE. We need an array of tracks.
   }
   void RebuildFragmentedIndex(
     const nsTArray<mozilla::MediaByteRange>& aByteRanges);
+  void RebuildFragmentedIndex(BoxContext& aContext);
   Interval<Microseconds> GetCompositionRange(
     const nsTArray<mozilla::MediaByteRange>& aByteRanges);
   bool ReachedEnd();
   void ParseMoov(Box& aBox);
   void ParseTrak(Box& aBox);
   void ParseMdia(Box& aBox, Tkhd& aTkhd);
   void ParseMvex(Box& aBox);
 
+  bool BlockingReadNextMoof();
+
   mozilla::MediaByteRange mInitRange;
   nsRefPtr<Stream> mSource;
   uint64_t mOffset;
   nsTArray<uint64_t> mMoofOffsets;
   Mdhd mMdhd;
   Trex mTrex;
   Tfdt mTfdt;
   Edts mEdts;