Bug 1487797 - P1. Move sample index from FrameHeader to Frame. r=jya
authorChun-Min Chang <chun.m.chang@gmail.com>
Mon, 22 Oct 2018 22:51:21 +0000
changeset 502664 e8ea25fee7b2a1dd7b620ef1204a8bbcbf6d220c
parent 502663 d3cb2102af01b8954fd2362f054f82a2b030fc8f
child 502665 b50e31d758b1a25273650b23ce0074093d21cd39
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1487797
milestone65.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 1487797 - P1. Move sample index from FrameHeader to Frame. r=jya Differential Revision: https://phabricator.services.mozilla.com/D9043
dom/media/flac/FlacDemuxer.cpp
--- a/dom/media/flac/FlacDemuxer.cpp
+++ b/dom/media/flac/FlacDemuxer.cpp
@@ -31,19 +31,16 @@ class FrameHeader
 {
 public:
   const AudioInfo& Info() const { return mInfo; }
 
   uint32_t Size() const { return mSize; }
 
   bool IsValid() const { return mValid; }
 
-  // Return the index (in samples) from the beginning of the track.
-  int64_t Index() const { return mIndex; }
-
   // Parse the current packet and check that it made a valid flac frame header.
   // From https://xiph.org/flac/format.html#frame_header
   // A valid header is one that can be decoded without error and that has a
   // valid CRC.
   bool Parse(const uint8_t* aPacket, size_t aBytes)
   {
     BitReader br(aPacket, aBytes * 8);
 
@@ -82,41 +79,34 @@ public:
 
     // Reserved bit, must be 0.
     if (br.ReadBit()) {
       // Broken stream, invalid padding.
       return false;
     }
 
     // Sample or frame count.
-    int64_t frame_or_sample_num = br.ReadUTF8();
-    if (frame_or_sample_num < 0) {
-      // Sample/frame number invalid.
+    int64_t frameOrSampleNum = br.ReadUTF8();
+    if (frameOrSampleNum < 0) {
       return false;
     }
+    mFrameOrSampleNum = frameOrSampleNum;
 
     // Blocksize
     if (bs_code == 0) {
       // reserved blocksize code
       return false;
     } else if (bs_code == 6) {
       mBlocksize = br.ReadBits(8) + 1;
     } else if (bs_code == 7) {
       mBlocksize = br.ReadBits(16) + 1;
     } else {
       mBlocksize = FlacBlocksizeTable[bs_code];
     }
 
-    // The sample index is either:
-    // 1- coded sample number if blocksize is variable or
-    // 2- coded frame number if blocksize is known.
-    // A frame is made of Blocksize sample.
-    mIndex = mVariableBlockSize ? frame_or_sample_num
-                                : frame_or_sample_num * mBlocksize;
-
     // Sample rate.
     if (sr_code < 12) {
       mInfo.mRate = FlacSampleRateTable[sr_code];
     } else if (sr_code == 12) {
       mInfo.mRate = br.ReadBits(8) * 1000;
     } else if (sr_code == 13) {
       mInfo.mRate = br.ReadBits(16);
     } else if (sr_code == 14) {
@@ -147,18 +137,21 @@ private:
   enum
   {
     FLAC_CHMODE_INDEPENDENT = 0,
     FLAC_CHMODE_LEFT_SIDE,
     FLAC_CHMODE_RIGHT_SIDE,
     FLAC_CHMODE_MID_SIDE,
   };
   AudioInfo mInfo;
-  // Index in samples from start;
-  int64_t mIndex = 0;
+  // mFrameOrSampleNum is either:
+  // 1- coded sample number if blocksize is variable or
+  // 2- coded frame number if blocksize is fixed.
+  // A frame is made of Blocksize sample.
+  uint64_t mFrameOrSampleNum = 0;
   bool mVariableBlockSize = false;
   uint32_t mBlocksize = 0;;
   uint32_t mSize = 0;
   bool mValid = false;
 
   static const int FlacSampleRateTable[16];
   static const int32_t FlacBlocksizeTable[16];
   static const uint8_t FlacSampleSizeTable[8];
@@ -285,16 +278,17 @@ public:
       }
 
       const size_t bufSize = read + innerOffset;
       int64_t foundOffset =
         FindNext(reinterpret_cast<uint8_t*>(buffer.Elements()), bufSize);
 
       if (foundOffset >= 0) {
         SetOffset(aResource, foundOffset + offset);
+        SetIndex();
         return true;
       }
 
       if (read < BUFFER_SIZE) {
         // Nothing more to try on as we had reached EOS during the previous
         // read.
         mEOS = true;
         return false;
@@ -313,32 +307,35 @@ public:
   }
 
   int64_t Offset() const { return mOffset; }
 
   const AudioInfo& Info() const { return Header().Info(); }
 
   void SetEndOffset(int64_t aOffset) { mSize = aOffset - mOffset; }
 
-  void SetEndTime(int64_t aIndex)
+  // Return the index (in samples) from the beginning of the track.
+  uint64_t Index() const { return mIndex; }
+
+  void SetEndTime(uint64_t aIndex)
   {
-    if (aIndex > Header().mIndex) {
-      mDuration = aIndex - Header().mIndex;
+    if (aIndex > Index()) {
+      mDuration = aIndex - Index();
     }
   }
 
   uint32_t Size() const { return mSize; }
 
   TimeUnit Time() const
   {
     if (!IsValid()) {
       return TimeUnit::Invalid();
     }
     MOZ_ASSERT(Header().Info().mRate, "Invalid Frame. Need Header");
-    return FramesToTimeUnit(Header().mIndex, Header().Info().mRate);
+    return FramesToTimeUnit(Index(), Header().Info().mRate);
   }
 
   TimeUnit Duration() const
   {
     if (!IsValid()) {
       return TimeUnit();
     }
     MOZ_ASSERT(Header().Info().mRate, "Invalid Frame. Need Header");
@@ -363,16 +360,28 @@ public:
 
 private:
   void SetOffset(MediaResourceIndex& aResource, int64_t aOffset)
   {
     mOffset = aOffset;
     aResource.Seek(SEEK_SET, mOffset);
   }
 
+  void SetIndex()
+  {
+    // Make sure the header has been parsed.
+    MOZ_ASSERT(Header().mBlocksize);
+
+    mIndex = Header().mVariableBlockSize
+      ? Header().mFrameOrSampleNum
+      : Header().mFrameOrSampleNum * Header().mBlocksize;
+  }
+
+  // The index in samples from start.
+  uint64_t mIndex = 0;
   // The offset to the start of the header.
   int64_t mOffset = 0;
   uint32_t mSize = 0;
   uint32_t mDuration = 0;
   bool mEOS = false;
 
   // The currently parsed frame header.
   FrameHeader mHeader;
@@ -408,17 +417,17 @@ public:
       }
     }
 
     if (mFrame.IsValid()) {
       if (mNextFrame.EOS()) {
         mFrame.SetEndOffset(aResource.Tell());
       } else if (mNextFrame.IsValid()) {
         mFrame.SetEndOffset(mNextFrame.Offset());
-        mFrame.SetEndTime(mNextFrame.Header().Index());
+        mFrame.SetEndTime(mNextFrame.Index());
       }
     }
 
     if (!mFirstFrame.IsValid()) {
       mFirstFrame = mFrame;
     }
     return mFrame.IsValid();
   }