Bug 1168674: [ogg] P5. Use common demuxing methods. r=brion+1012
authorJean-Yves Avenard <jyavenard@mozilla.com>
Mon, 25 Jul 2016 19:06:20 +1000
changeset 332473 3db6ca9dc9cd2801fb77225a169984259a5a422d
parent 332472 0152356f027f2be2cef08e97082ef21075f8428f
child 332474 864104ba08a648137660176cca3618ec183c31e8
push id9858
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 14:37:10 +0000
treeherdermozilla-aurora@203106ef6cb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbrion
bugs1168674
milestone50.0a1
Bug 1168674: [ogg] P5. Use common demuxing methods. r=brion+1012 This ensure that the first sample demuxed will be identical to the first one demuxed following a seek to the beginning. Also, only demux the next packet when none is queued rather than all the time. MozReview-Commit-ID: 5wtFVLiCAW
dom/media/ogg/OggDemuxer.cpp
dom/media/ogg/OggDemuxer.h
--- a/dom/media/ogg/OggDemuxer.cpp
+++ b/dom/media/ogg/OggDemuxer.cpp
@@ -853,46 +853,32 @@ OggDemuxer::IsSeekable() const
 }
 
 UniquePtr<EncryptionInfo>
 OggDemuxer::GetCrypto()
 {
   return nullptr;
 }
 
-RefPtr<MediaRawData>
+ogg_packet*
 OggDemuxer::GetNextPacket(TrackInfo::TrackType aType)
 {
   OggCodecState* state = GetTrackCodecState(aType);
   ogg_packet* packet = nullptr;
 
   do {
     if (packet) {
       OggCodecState::ReleasePacket(state->PacketOut());
     }
     DemuxUntilPacketAvailable(state);
 
     packet = state->PacketPeek();
   } while (packet && state->IsHeader(packet));
 
-  if (!packet) {
-    return nullptr;
-  }
-
-  // Check the eos state in case we need to look for chained streams.
-  bool eos = packet->e_o_s;
-
-  RefPtr<MediaRawData> data = state->PacketOutAsMediaRawData();;
-
-  if (eos) {
-    // We've encountered an end of bitstream packet; check for a chained
-    // bitstream following this one.
-    ReadOggChain();
-  }
-  return data;
+  return packet;
 }
 
 void
 OggDemuxer::DemuxUntilPacketAvailable(OggCodecState* aState)
 {
   while (!aState->IsPacketReady()) {
     OGG_DEBUG("no packet yet, reading some more");
     ogg_page page;
@@ -1024,34 +1010,27 @@ void
 OggDemuxer::FindStartTime(int64_t& aOutStartTime)
 {
   // Extract the start times of the bitstreams in order to calculate
   // the duration.
   int64_t videoStartTime = INT64_MAX;
   int64_t audioStartTime = INT64_MAX;
 
   if (HasVideo()) {
-    DemuxUntilPacketAvailable(mTheoraState);
-    ogg_packet* pkt = mTheoraState->PacketPeek();
+    ogg_packet* pkt = GetNextPacket(TrackInfo::kVideoTrack);
     if (pkt) {
       videoStartTime = mTheoraState->PacketStartTime(pkt);
       OGG_DEBUG("OggDemuxer::FindStartTime() video=%lld", videoStartTime);
     }
   }
   if (HasAudio()) {
-    OggCodecState* audioState;
-    if (mVorbisState) {
-      audioState = mVorbisState;
-    } else {
-      audioState = mOpusState;
-    }
-    DemuxUntilPacketAvailable(audioState);
-    ogg_packet* pkt = audioState->PacketPeek();
+    OggCodecState* state = GetTrackCodecState(TrackInfo::kAudioTrack);
+    ogg_packet* pkt = GetNextPacket(TrackInfo::kAudioTrack);
     if (pkt) {
-      audioStartTime = audioState->PacketStartTime(pkt);
+      audioStartTime = state->PacketStartTime(pkt);
       OGG_DEBUG("OggReader::FindStartTime() audio=%lld", audioStartTime);
     }
   }
 
   int64_t startTime = std::min(videoStartTime, audioStartTime);
   if (startTime != INT64_MAX) {
     aOutStartTime = startTime;
   }
@@ -1306,17 +1285,16 @@ OggTrackDemuxer::GetInfo() const
   return mInfo->Clone();
 }
 
 RefPtr<OggTrackDemuxer::SeekPromise>
 OggTrackDemuxer::Seek(TimeUnit aTime)
 {
   // Seeks to aTime. Upon success, SeekPromise will be resolved with the
   // actual time seeked to. Typically the random access point time
-
   mQueuedSample = nullptr;
   TimeUnit seekTime = aTime;
   if (mParent->SeekInternal(aTime) == NS_OK) {
     RefPtr<MediaRawData> sample(NextSample());
 
     // Check what time we actually seeked to.
     if (sample != nullptr) {
       seekTime = TimeUnit::FromMicroseconds(sample->mTime);
@@ -1328,24 +1306,35 @@ OggTrackDemuxer::Seek(TimeUnit aTime)
   } else {
     return SeekPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
   }
 }
 
 RefPtr<MediaRawData>
 OggTrackDemuxer::NextSample()
 {
-  RefPtr<MediaRawData> nextSample;
   if (mQueuedSample) {
-    nextSample = mQueuedSample;
-  } else {
-    nextSample = mParent->GetNextPacket(mType);
+    RefPtr<MediaRawData> nextSample = mQueuedSample;
+    mQueuedSample = nullptr;
+    return nextSample;
+  }
+  ogg_packet* packet = mParent->GetNextPacket(mType);
+  if (!packet) {
+    return nullptr;
   }
-  mQueuedSample = mParent->GetNextPacket(mType);
-  return nextSample;
+  // Check the eos state in case we need to look for chained streams.
+  bool eos = packet->e_o_s;
+  OggCodecState* state = mParent->GetTrackCodecState(mType);
+  RefPtr<MediaRawData> data = state->PacketOutAsMediaRawData();;
+  if (eos) {
+    // We've encountered an end of bitstream packet; check for a chained
+    // bitstream following this one.
+    mParent->ReadOggChain();
+  }
+  return data;
 }
 
 RefPtr<OggTrackDemuxer::SamplesPromise>
 OggTrackDemuxer::GetSamples(int32_t aNumSamples)
 {
   RefPtr<SamplesHolder> samples = new SamplesHolder;
   if (!aNumSamples) {
     return SamplesPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
--- a/dom/media/ogg/OggDemuxer.h
+++ b/dom/media/ogg/OggDemuxer.h
@@ -154,17 +154,17 @@ private:
                                  ogg_sync_state* aState,
                                  bool aCachedDataOnly,
                                  int64_t aOffset,
                                  int64_t aEndOffset,
                                  ogg_page* aPage,
                                  int& aSkippedBytes);
 
   // Demux next Ogg packet
-  RefPtr<MediaRawData> GetNextPacket(TrackInfo::TrackType aType);
+  ogg_packet* GetNextPacket(TrackInfo::TrackType aType);
 
   nsresult ResetTrackState(TrackInfo::TrackType aType);
 
   nsresult Reset();
 
   static const nsString GetKind(const nsCString& aRole);
   static void InitTrack(MessageField* aMsgInfo,
                       TrackInfo* aInfo,