Bug 1322070: P8. Remove unused methods and types. r?gerald draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Thu, 08 Dec 2016 08:38:04 -1000
changeset 448648 a56adbcccaaa675638ad6e277bcef3533870d80c
parent 448647 f2bf734c35553ceaad971c90d3259fc7ec051f03
child 448668 35e85720d99352b86eeb47dd1c1c843d6599ee85
push id38389
push userbmo:jyavenard@mozilla.com
push dateMon, 12 Dec 2016 05:01:11 +0000
reviewersgerald
bugs1322070
milestone53.0a1
Bug 1322070: P8. Remove unused methods and types. r?gerald MozReview-Commit-ID: 8azYJd98T5o
dom/media/ogg/OggCodecState.cpp
dom/media/ogg/OggCodecState.h
dom/media/ogg/OggDemuxer.cpp
dom/media/ogg/OggDemuxer.h
--- a/dom/media/ogg/OggCodecState.cpp
+++ b/dom/media/ogg/OggCodecState.cpp
@@ -381,17 +381,16 @@ TheoraState::Init()
     return mActive = false;
   }
 
   // Video track's frame sizes will not overflow. Activate the video track.
   mInfo.mMimeType = NS_LITERAL_CSTRING("video/theora");
   mInfo.mDisplay = display;
   mInfo.mImage = frame;
   mInfo.SetImageRect(picture);
-  mKeyframe_granule_shift = mTheoraInfo.keyframe_granule_shift;
 
   return mActive = SetCodecSpecificConfig(mInfo.mCodecSpecificConfig, mHeaders);
 }
 
 nsresult
 TheoraState::Reset()
 {
   mHeaders.Erase();
--- a/dom/media/ogg/OggCodecState.h
+++ b/dom/media/ogg/OggCodecState.h
@@ -205,16 +205,22 @@ public:
   // Extracts all packets from the page, and inserts them into the packet
   // queue. They can be extracted by calling PacketOut(). Packets from an
   // inactive stream are not buffered, i.e. this call has no effect for
   // inactive streams. Multiple pages may need to be inserted before
   // PacketOut() starts to return packets, as granulepos may need to be
   // captured.
   virtual nsresult PageIn(ogg_page* aPage);
 
+  // Returns the maximum number of microseconds which a keyframe can be offset
+  // from any given interframe.b
+  virtual int64_t MaxKeyframeOffset() { return 0; }
+  // Public access for mTheoraInfo.keyframe_granule_shift
+  virtual int32_t KeyFrameGranuleJobs() { return 0; }
+
   // Number of packets read.
   uint64_t mPacketCount;
 
   // Serial number of the bitstream.
   uint32_t mSerial;
 
   // Ogg specific state.
   ogg_stream_state mState;
@@ -362,22 +368,21 @@ public:
   int64_t StartTime(int64_t granulepos) override;
   int64_t PacketDuration(ogg_packet* aPacket) override;
   bool Init() override;
   nsresult Reset() override;
   bool IsHeader(ogg_packet* aPacket) override;
   bool IsKeyframe(ogg_packet* aPacket) override;
   nsresult PageIn(ogg_page* aPage) override;
   const TrackInfo* GetInfo() const override { return &mInfo; }
-
-  // Returns the maximum number of microseconds which a keyframe can be offset
-  // from any given interframe.
-  int64_t MaxKeyframeOffset();
-  // Public access for mTheoraInfo.keyframe_granule_shift
-  int32_t mKeyframe_granule_shift;
+  int64_t MaxKeyframeOffset() override;
+  int32_t KeyFrameGranuleJobs() override
+  {
+    return mTheoraInfo.keyframe_granule_shift;
+  }
 
 private:
   // Returns the end time that a granulepos represents.
   static int64_t Time(th_info* aInfo, int64_t aGranulePos);
 
   th_info mTheoraInfo;
   th_comment mComment;
   th_setup_info* mSetup;
--- a/dom/media/ogg/OggDemuxer.cpp
+++ b/dom/media/ogg/OggDemuxer.cpp
@@ -48,40 +48,16 @@ using media::TimeIntervals;
 static const uint32_t OGG_SEEK_FUZZ_USECS = 500000;
 
 // The number of microseconds of "pre-roll" we use for Opus streams.
 // The specification recommends 80 ms.
 static const int64_t OGG_SEEK_OPUS_PREROLL = 80 * USECS_PER_MS;
 
 static Atomic<uint32_t> sStreamSourceID(0u);
 
-class OggHeaders
-{
-public:
-  OggHeaders() {}
-  ~OggHeaders()
-  {
-    for (size_t i = 0; i < mHeaders.Length(); i++) {
-      delete[] mHeaders[i];
-    }
-  }
-
-  void AppendPacket(const ogg_packet* aPacket)
-  {
-    size_t packetSize = aPacket->bytes;
-    unsigned char* packetData = new unsigned char[packetSize];
-    memcpy(packetData, aPacket->packet, packetSize);
-    mHeaders.AppendElement(packetData);
-    mHeaderLens.AppendElement(packetSize);
-  }
-
-  nsTArray<const unsigned char*> mHeaders;
-  nsTArray<size_t> mHeaderLens;
-};
-
 // Return the corresponding category in aKind based on the following specs.
 // (https://www.whatwg.org/specs/web-apps/current-
 // work/multipage/embedded-content.html#dom-audiotrack-kind) &
 // (http://wiki.xiph.org/SkeletonHeaders)
 const nsString
 OggDemuxer::GetKind(const nsCString& aRole)
 {
   if (aRole.Find("audio/main") != -1 || aRole.Find("video/main") != -1) {
@@ -130,20 +106,16 @@ OggDemuxer::OggDemuxer(MediaResource* aR
   : mTheoraState(nullptr)
   , mVorbisState(nullptr)
   , mOpusState(nullptr)
   , mFlacState(nullptr)
   , mOpusEnabled(MediaDecoder::IsOpusEnabled())
   , mSkeletonState(nullptr)
   , mAudioOggState(aResource)
   , mVideoOggState(aResource)
-  , mVorbisSerial(0)
-  , mOpusSerial(0)
-  , mTheoraSerial(0)
-  , mFlacSerial(0)
   , mIsChained(false)
   , mTimedMetadataEvent(nullptr)
   , mOnSeekableEvent(nullptr)
 {
   MOZ_COUNT_CTOR(OggDemuxer);
 }
 
 OggDemuxer::~OggDemuxer()
@@ -322,32 +294,27 @@ OggDemuxer::Reset(TrackInfo::TrackType a
     return trackState->Reset();
   }
   OggState(aType).mNeedKeyframe = true;
   return NS_OK;
 }
 
 bool
 OggDemuxer::ReadHeaders(TrackInfo::TrackType aType,
-                        OggCodecState* aState,
-                        OggHeaders& aHeaders)
+                        OggCodecState* aState)
 {
   while (!aState->DoneReadingHeaders()) {
     DemuxUntilPacketAvailable(aType, aState);
     ogg_packet* packet = aState->PacketOut();
     if (!packet) {
       OGG_DEBUG("Ran out of header packets early; deactivating stream %ld", aState->mSerial);
       aState->Deactivate();
       return false;
     }
 
-    // Save a copy of the header packet for the decoder to use later;
-    // OggCodecState::DecodeHeader will free it when processing locally.
-    aHeaders.AppendPacket(packet);
-
     // Local OggCodecState needs to decode headers in order to process
     // packet granulepos -> time mappings, etc.
     if (!aState->DecodeHeader(packet)) {
       OGG_DEBUG("Failed to decode ogg header packet; deactivating stream %ld", aState->mSerial);
       aState->Deactivate();
       return false;
     }
   }
@@ -367,76 +334,42 @@ OggDemuxer::BuildSerialList(nsTArray<uin
       aTracks.AppendElement(mVorbisState->mSerial);
     } else if (mOpusState) {
       aTracks.AppendElement(mOpusState->mSerial);
     }
   }
 }
 
 void
-OggDemuxer::SetupTargetTheora(TheoraState* aTheoraState, OggHeaders& aHeaders)
+OggDemuxer::SetupTarget(OggCodecState** aSavedState, OggCodecState* aNewState)
 {
-  if (mTheoraState) {
-    mTheoraState->Reset();
-  }
-
-  mInfo.mVideo = *aTheoraState->GetInfo()->GetAsVideoInfo();
-  mTheoraState = aTheoraState;
-  mTheoraSerial = aTheoraState->mSerial;
-}
-
-void
-OggDemuxer::SetupTargetVorbis(VorbisState* aVorbisState, OggHeaders& aHeaders)
-{
-  if (mVorbisState) {
-    mVorbisState->Reset();
+  if (*aSavedState) {
+    (*aSavedState)->Reset();
   }
 
-  mInfo.mAudio = *aVorbisState->GetInfo()->GetAsAudioInfo();
-  mVorbisState = aVorbisState;
-  mVorbisSerial = aVorbisState->mSerial;
-}
-
-void
-OggDemuxer::SetupTargetOpus(OpusState* aOpusState, OggHeaders& aHeaders)
-{
-  if (mOpusState) {
-    mOpusState->Reset();
+  if (aNewState->GetInfo()->GetAsAudioInfo()) {
+    mInfo.mAudio = *aNewState->GetInfo()->GetAsAudioInfo();
+  } else {
+    mInfo.mVideo = *aNewState->GetInfo()->GetAsVideoInfo();
   }
-
-  mInfo.mAudio = *aOpusState->GetInfo()->GetAsAudioInfo();
-  mOpusState = aOpusState;
-  mOpusSerial = aOpusState->mSerial;
-}
-
-void
-OggDemuxer::SetupTargetFlac(FlacState* aFlacState, OggHeaders& aHeaders)
-{
-  if (mFlacState) {
-    mFlacState->Reset();
-  }
-
-  mInfo.mAudio = *aFlacState->GetInfo()->GetAsAudioInfo();
-  mFlacState = aFlacState;
-  mFlacSerial = aFlacState->mSerial;
+  *aSavedState = aNewState;
 }
 
 void
 OggDemuxer::SetupTargetSkeleton()
 {
   // Setup skeleton related information after mVorbisState & mTheroState
   // being set (if they exist).
   if (mSkeletonState) {
-    OggHeaders headers;
     if (!HasAudio() && !HasVideo()) {
       // We have a skeleton track, but no audio or video, may as well disable
       // the skeleton, we can't do anything useful with this media.
       OGG_DEBUG("Deactivating skeleton stream %ld", mSkeletonState->mSerial);
       mSkeletonState->Deactivate();
-    } else if (ReadHeaders(TrackInfo::kAudioTrack, mSkeletonState, headers) &&
+    } else if (ReadHeaders(TrackInfo::kAudioTrack, mSkeletonState) &&
                mSkeletonState->HasIndex()) {
       // We don't particularly care about which track we are currently using
       // as both MediaResource points to the same content.
       // Extract the duration info out of the index, so we don't need to seek to
       // the end of resource to get it.
       nsTArray<uint32_t> tracks;
       BuildSerialList(tracks);
       int64_t duration = 0;
@@ -460,66 +393,42 @@ OggDemuxer::SetupMediaTracksInfo(const n
     uint32_t serial = aSerials[i];
     OggCodecState* codecState = mCodecStore.Get(serial);
 
     MessageField* msgInfo = nullptr;
     if (mSkeletonState && mSkeletonState->mMsgFieldStore.Contains(serial)) {
       mSkeletonState->mMsgFieldStore.Get(serial, &msgInfo);
     }
 
-    if (codecState->GetType() == OggCodecState::TYPE_THEORA) {
-      TheoraState* theoraState = static_cast<TheoraState*>(codecState);
-      if (!(mTheoraState && mTheoraState->mSerial == theoraState->mSerial)) {
-        continue;
-      }
-
-      mInfo.mVideo = *theoraState->GetInfo()->GetAsVideoInfo();
-
+    OggCodecState* primeState = nullptr;
+    switch (codecState->GetType()) {
+      case OggCodecState::TYPE_THEORA:
+        primeState = mTheoraState;
+        break;
+      case OggCodecState::TYPE_VORBIS:
+        primeState = mVorbisState;
+        break;
+      case OggCodecState::TYPE_OPUS:
+        primeState = mOpusState;
+        break;
+      case OggCodecState::TYPE_FLAC:
+        primeState = mFlacState;
+        break;
+      default:
+        break;
+    }
+    if (primeState && primeState == codecState) {
+      bool isAudio = primeState->GetInfo()->GetAsAudioInfo();
       if (msgInfo) {
-        InitTrack(msgInfo, &mInfo.mVideo, mTheoraState == theoraState);
-      }
-    } else if (codecState->GetType() == OggCodecState::TYPE_VORBIS) {
-      VorbisState* vorbisState = static_cast<VorbisState*>(codecState);
-      if (!(mVorbisState && mVorbisState->mSerial == vorbisState->mSerial)) {
-        continue;
-      }
-
-      mInfo.mAudio = *vorbisState->GetInfo()->GetAsAudioInfo();
-
-      if (msgInfo) {
-        InitTrack(msgInfo, &mInfo.mAudio, mVorbisState == vorbisState);
+        InitTrack(msgInfo, isAudio ? static_cast<TrackInfo*>(&mInfo.mAudio)
+                                   : &mInfo.mVideo,
+                  true);
       }
-
-      FillTags(&mInfo.mAudio, vorbisState->GetTags());
-    } else if (codecState->GetType() == OggCodecState::TYPE_OPUS) {
-      OpusState* opusState = static_cast<OpusState*>(codecState);
-      if (!(mOpusState && mOpusState->mSerial == opusState->mSerial)) {
-        continue;
-      }
-
-      mInfo.mAudio = *opusState->GetInfo()->GetAsAudioInfo();
-
-      if (msgInfo) {
-        InitTrack(msgInfo, &mInfo.mAudio, mOpusState == opusState);
-      }
-
-      FillTags(&mInfo.mAudio, opusState->GetTags());
-    } else if (codecState->GetType() == OggCodecState::TYPE_FLAC) {
-      FlacState* flacState = static_cast<FlacState*>(codecState);
-      if (!(mFlacState && mFlacState->mSerial == flacState->mSerial)) {
-        continue;
-      }
-
-      mInfo.mAudio = *flacState->GetInfo()->GetAsAudioInfo();
-
-      if (msgInfo) {
-        InitTrack(msgInfo, &mInfo.mAudio, mFlacState == flacState);
-      }
-
-      FillTags(&mInfo.mAudio, flacState->GetTags());
+      FillTags(isAudio ? static_cast<TrackInfo*>(&mInfo.mAudio) : &mInfo.mVideo,
+               primeState->GetTags());
     }
   }
 }
 
 void
 OggDemuxer::FillTags(TrackInfo* aInfo, MetadataTags* aTags)
 {
   if (!aTags) {
@@ -585,52 +494,47 @@ OggDemuxer::ReadMetadata()
   // We've read all BOS pages, so we know the streams contained in the media.
   // 1. Find the first encountered Theora/Vorbis/Opus bitstream, and configure
   //    it as the target A/V bitstream.
   // 2. Deactivate the rest of bitstreams for now, until we have MediaInfo
   //    support multiple track infos.
   for (uint32_t i = 0; i < bitstreams.Length(); ++i) {
     OggCodecState* s = bitstreams[i];
     if (s) {
-      OggHeaders headers;
       if (s->GetType() == OggCodecState::TYPE_THEORA &&
-          ReadHeaders(TrackInfo::kVideoTrack, s, headers)) {
+          ReadHeaders(TrackInfo::kVideoTrack, s)) {
         if (!mTheoraState) {
-          TheoraState* theoraState = static_cast<TheoraState*>(s);
-          SetupTargetTheora(theoraState, headers);
+          SetupTarget(&mTheoraState, s);
         } else {
           s->Deactivate();
         }
       } else if (s->GetType() == OggCodecState::TYPE_VORBIS &&
-                 ReadHeaders(TrackInfo::kAudioTrack, s, headers)) {
+                 ReadHeaders(TrackInfo::kAudioTrack, s)) {
         if (!mVorbisState) {
-          VorbisState* vorbisState = static_cast<VorbisState*>(s);
-          SetupTargetVorbis(vorbisState, headers);
+          SetupTarget(&mVorbisState, s);
         } else {
           s->Deactivate();
         }
       } else if (s->GetType() == OggCodecState::TYPE_OPUS &&
-                 ReadHeaders(TrackInfo::kAudioTrack, s, headers)) {
+                 ReadHeaders(TrackInfo::kAudioTrack, s)) {
         if (mOpusEnabled) {
           if (!mOpusState) {
-            OpusState* opusState = static_cast<OpusState*>(s);
-            SetupTargetOpus(opusState, headers);
+            SetupTarget(&mOpusState, s);
           } else {
             s->Deactivate();
           }
         } else {
           NS_WARNING("Opus decoding disabled."
                      " See media.opus.enabled in about:config");
         }
       } else if (MediaPrefs::FlacInOgg() &&
                  s->GetType() == OggCodecState::TYPE_FLAC &&
-                 ReadHeaders(TrackInfo::kAudioTrack, s, headers)) {
+                 ReadHeaders(TrackInfo::kAudioTrack, s)) {
         if (!mFlacState) {
-          FlacState* flacState = static_cast<FlacState*>(s);
-          SetupTargetFlac(flacState, headers);
+          SetupTarget(&mFlacState, s);
         } else {
           s->Deactivate();
         }
       } else if (s->GetType() == OggCodecState::TYPE_SKELETON && !mSkeletonState) {
         mSkeletonState = static_cast<SkeletonState*>(s);
       } else {
         // Deactivate any non-primary bitstreams.
         s->Deactivate();
@@ -747,63 +651,62 @@ OggDemuxer::ReadOggChain(const media::Ti
     return false;
   }
 
   MessageField* msgInfo = nullptr;
   if (mSkeletonState && mSkeletonState->mMsgFieldStore.Contains(serial)) {
     mSkeletonState->mMsgFieldStore.Get(serial, &msgInfo);
   }
 
-  OggHeaders vorbisHeaders;
   if ((newVorbisState &&
-       ReadHeaders(TrackInfo::kAudioTrack, newVorbisState, vorbisHeaders)) &&
+       ReadHeaders(TrackInfo::kAudioTrack, newVorbisState)) &&
       (mVorbisState->GetInfo()->GetAsAudioInfo()->mRate ==
        newVorbisState->GetInfo()->GetAsAudioInfo()->mRate) &&
       (mVorbisState->GetInfo()->GetAsAudioInfo()->mChannels ==
        newVorbisState->GetInfo()->GetAsAudioInfo()->mChannels)) {
 
-    SetupTargetVorbis(newVorbisState, vorbisHeaders);
-    LOG(LogLevel::Debug, ("New vorbis ogg link, serial=%d\n", mVorbisSerial));
+    SetupTarget(&mVorbisState, newVorbisState);
+    LOG(LogLevel::Debug,
+        ("New vorbis ogg link, serial=%d\n", mVorbisState->mSerial));
 
     if (msgInfo) {
       InitTrack(msgInfo, &mInfo.mAudio, true);
     }
 
     chained = true;
     tags = newVorbisState->GetTags();
   }
 
-  OggHeaders opusHeaders;
   if ((newOpusState &&
-       ReadHeaders(TrackInfo::kAudioTrack, newOpusState, opusHeaders)) &&
+       ReadHeaders(TrackInfo::kAudioTrack, newOpusState)) &&
       (mOpusState->GetInfo()->GetAsAudioInfo()->mRate ==
        newOpusState->GetInfo()->GetAsAudioInfo()->mRate) &&
       (mOpusState->GetInfo()->GetAsAudioInfo()->mChannels ==
        newOpusState->GetInfo()->GetAsAudioInfo()->mChannels)) {
 
-    SetupTargetOpus(newOpusState, opusHeaders);
+    SetupTarget(&mOpusState, newOpusState);
 
     if (msgInfo) {
       InitTrack(msgInfo, &mInfo.mAudio, true);
     }
 
     chained = true;
     tags = newOpusState->GetTags();
   }
 
-  OggHeaders flacHeaders;
   if ((newFlacState &&
-       ReadHeaders(TrackInfo::kAudioTrack, newFlacState, flacHeaders)) &&
+       ReadHeaders(TrackInfo::kAudioTrack, newFlacState)) &&
       (mFlacState->GetInfo()->GetAsAudioInfo()->mRate ==
        newFlacState->GetInfo()->GetAsAudioInfo()->mRate) &&
       (mFlacState->GetInfo()->GetAsAudioInfo()->mChannels ==
        newFlacState->GetInfo()->GetAsAudioInfo()->mChannels)) {
 
-    SetupTargetFlac(newFlacState, flacHeaders);
-    LOG(LogLevel::Debug, ("New flac ogg link, serial=%d\n", mFlacSerial));
+    SetupTarget(&mFlacState, newFlacState);
+    LOG(LogLevel::Debug,
+        ("New flac ogg link, serial=%d\n", mFlacState->mSerial));
 
     if (msgInfo) {
       InitTrack(msgInfo, &mInfo.mAudio, true);
     }
 
     chained = true;
     tags = newFlacState->GetTags();
   }
@@ -1035,29 +938,29 @@ OggDemuxer::GetBuffered(TrackInfo::Track
         // Page doesn't have an end time, advance to the next page
         // until we find one.
         startOffset += page.header_len + page.body_len;
         continue;
       }
 
       uint32_t serial = ogg_page_serialno(&page);
       if (aType == TrackInfo::kAudioTrack && mVorbisState &&
-          serial == mVorbisSerial) {
+          serial == mVorbisState->mSerial) {
         startTime = mVorbisState->Time(granulepos);
         NS_ASSERTION(startTime > 0, "Must have positive start time");
       } else if (aType == TrackInfo::kAudioTrack && mOpusState &&
-                 serial == mOpusSerial) {
+                 serial == mOpusState->mSerial) {
         startTime = mOpusState->Time(granulepos);
         NS_ASSERTION(startTime > 0, "Must have positive start time");
       } else if (aType == TrackInfo::kAudioTrack && mFlacState &&
-                 serial == mFlacSerial) {
+                 serial == mFlacState->mSerial) {
         startTime = mFlacState->Time(granulepos);
         NS_ASSERTION(startTime > 0, "Must have positive start time");
       } else if (aType == TrackInfo::kVideoTrack && mTheoraState &&
-                 serial == mTheoraSerial) {
+                 serial == mTheoraState->mSerial) {
         startTime = mTheoraState->Time(granulepos);
         NS_ASSERTION(startTime > 0, "Must have positive start time");
       } else if (mCodecStore.Contains(serial)) {
         // Stream is not the theora or vorbis stream we're playing,
         // but is one that we have header data for.
         startOffset += page.header_len + page.body_len;
         continue;
       } else {
@@ -1786,17 +1689,17 @@ OggDemuxer::SeekInBufferedRange(TrackInf
     // We have an active Theora bitstream. Peek the next Theora frame, and
     // extract its keyframe's time.
     DemuxUntilPacketAvailable(aType, mTheoraState);
     ogg_packet* packet = mTheoraState->PacketPeek();
     if (packet && !mTheoraState->IsKeyframe(packet)) {
       // First post-seek frame isn't a keyframe, seek back to previous keyframe,
       // otherwise we'll get visual artifacts.
       NS_ASSERTION(packet->granulepos != -1, "Must have a granulepos");
-      int shift = mTheoraState->mKeyframe_granule_shift;
+      int shift = mTheoraState->KeyFrameGranuleJobs();
       int64_t keyframeGranulepos = (packet->granulepos >> shift) << shift;
       int64_t keyframeTime = mTheoraState->StartTime(keyframeGranulepos);
       SEEK_LOG(LogLevel::Debug,
                ("Keyframe for %lld is at %lld, seeking back to it", frameTime,
                 keyframeTime));
       aAdjustedTarget = std::min(aAdjustedTarget, keyframeTime);
     }
   }
--- a/dom/media/ogg/OggDemuxer.h
+++ b/dom/media/ogg/OggDemuxer.h
@@ -10,17 +10,16 @@
 #include "MediaDataDemuxer.h"
 #include "OggCodecState.h"
 #include "OggCodecStore.h"
 #include "MediaMetadataManager.h"
 
 namespace mozilla {
 
 class OggTrackDemuxer;
-class OggHeaders;
 
 class OggDemuxer : public MediaDataDemuxer
 {
 public:
   explicit OggDemuxer(MediaResource* aResource);
 
   RefPtr<InitPromise> Init() override;
 
@@ -198,34 +197,31 @@ private:
 
   // Read data and demux until a packet is available on the given stream state
   void DemuxUntilPacketAvailable(TrackInfo::TrackType aType, OggCodecState* aState);
 
   // Reads and decodes header packets for aState, until either header decode
   // fails, or is complete. Initializes the codec state before returning.
   // Returns true if reading headers and initializtion of the stream
   // succeeds.
-  bool ReadHeaders(TrackInfo::TrackType aType, OggCodecState* aState, OggHeaders& aHeaders);
+  bool ReadHeaders(TrackInfo::TrackType aType, OggCodecState* aState);
 
   // Reads the next link in the chain.
   bool ReadOggChain(const media::TimeUnit& aLastEndTime);
 
   // Set this media as being a chain and notifies the state machine that the
   // media is no longer seekable.
   void SetChained();
 
   // Fills aTracks with the serial numbers of each active stream, for use by
   // various SkeletonState functions.
   void BuildSerialList(nsTArray<uint32_t>& aTracks);
 
   // Setup target bitstreams for decoding.
-  void SetupTargetTheora(TheoraState* aTheoraState, OggHeaders& aHeaders);
-  void SetupTargetVorbis(VorbisState* aVorbisState, OggHeaders& aHeaders);
-  void SetupTargetOpus(OpusState* aOpusState, OggHeaders& aHeaders);
-  void SetupTargetFlac(FlacState* aFlacState, OggHeaders& aHeaders);
+  void SetupTarget(OggCodecState** aSavedState, OggCodecState* aNewState);
   void SetupTargetSkeleton();
   void SetupMediaTracksInfo(const nsTArray<uint32_t>& aSerials);
   void FillTags(TrackInfo* aInfo, MetadataTags* aTags);
 
   // Compute an ogg page's checksum
   ogg_uint32_t GetPageChecksum(ogg_page* aPage);
 
   // Get the end time of aEndOffset. This is the playback position we'd reach
@@ -251,27 +247,27 @@ private:
 
   MediaInfo mInfo;
   nsTArray<RefPtr<OggTrackDemuxer>> mDemuxers;
 
   // Map of codec-specific bitstream states.
   OggCodecStore mCodecStore;
 
   // Decode state of the Theora bitstream we're decoding, if we have video.
-  TheoraState* mTheoraState;
+  OggCodecState* mTheoraState;
 
   // Decode state of the Vorbis bitstream we're decoding, if we have audio.
-  VorbisState* mVorbisState;
+  OggCodecState* mVorbisState;
 
   // Decode state of the Opus bitstream we're decoding, if we have one.
-  OpusState* mOpusState;
+  OggCodecState* mOpusState;
 
   // Get the bitstream decode state for the given track type
   // Decode state of the Flac bitstream we're decoding, if we have one.
-  FlacState* mFlacState;
+  OggCodecState* mFlacState;
 
   OggCodecState* GetTrackCodecState(TrackInfo::TrackType aType) const;
   TrackInfo::TrackType GetCodecStateType(OggCodecState* aState) const;
 
   // Represents the user pref media.opus.enabled at the time our
   // contructor was called. We can't check it dynamically because
   // we're not on the main thread;
   bool mOpusEnabled;
@@ -292,27 +288,16 @@ private:
 
   OggStateContext& OggState(TrackInfo::TrackType aType);
   ogg_sync_state* OggSyncState(TrackInfo::TrackType aType);
   MediaResourceIndex* Resource(TrackInfo::TrackType aType);
   MediaResourceIndex* CommonResource();
   OggStateContext mAudioOggState;
   OggStateContext mVideoOggState;
 
-  // Vorbis/Opus/Theora data used to compute timestamps. This is written on the
-  // decoder thread and read on the main thread. All reading on the main
-  // thread must be done after metadataloaded. We can't use the existing
-  // data in the codec states due to threading issues. You must check the
-  // associated mTheoraState or mVorbisState pointer is non-null before
-  // using this codec data.
-  uint32_t mVorbisSerial;
-  uint32_t mOpusSerial;
-  uint32_t mTheoraSerial;
-  uint32_t mFlacSerial;
-
   Maybe<int64_t> mStartTime;
 
   // Booleans to indicate if we have audio and/or video data
   bool HasVideo() const;
   bool HasAudio() const;
   bool HasSkeleton() const
   {
     return mSkeletonState != 0 && mSkeletonState->mActive;