Bug 1105066 - Chain seeks in MediaSourceReader so that we seek audio to the same time as video. r=kentuckyfriedtakahe, a=sledru
authorMatt Woodrow <mwoodrow@mozilla.com>
Mon, 12 Jan 2015 11:05:08 +1300
changeset 242855 154dac808616
parent 242854 e16f64387888
child 242856 a0ffac1b2851
push id4321
push userryanvm@gmail.com
push date2015-01-14 15:04 +0000
treeherdermozilla-beta@a78eb4dd84f0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskentuckyfriedtakahe, sledru
bugs1105066
milestone36.0
Bug 1105066 - Chain seeks in MediaSourceReader so that we seek audio to the same time as video. r=kentuckyfriedtakahe, a=sledru
dom/media/mediasource/MediaSourceReader.cpp
dom/media/mediasource/MediaSourceReader.h
--- a/dom/media/mediasource/MediaSourceReader.cpp
+++ b/dom/media/mediasource/MediaSourceReader.cpp
@@ -48,18 +48,16 @@ MediaSourceReader::MediaSourceReader(Med
   : MediaDecoderReader(aDecoder)
   , mLastAudioTime(-1)
   , mLastVideoTime(-1)
   , mPendingSeekTime(-1)
   , mPendingStartTime(-1)
   , mPendingEndTime(-1)
   , mPendingCurrentTime(-1)
   , mWaitingForSeekData(false)
-  , mPendingSeeks(0)
-  , mSeekResult(NS_OK)
   , mTimeThreshold(-1)
   , mDropAudioBeforeThreshold(false)
   , mDropVideoBeforeThreshold(false)
   , mEnded(false)
   , mAudioIsSeeking(false)
   , mVideoIsSeeking(false)
   , mHasEssentialTrackBuffers(false)
 #ifdef MOZ_FMP4
@@ -589,63 +587,58 @@ MediaSourceReader::Seek(int64_t aTime, i
   mPendingEndTime = aEndTime;
   mPendingCurrentTime = aCurrentTime;
 
   // Only increment the number of expected OnSeekCompleted
   // notifications if we weren't already waiting for AttemptSeek
   // to complete (and they would have been accounted for already).
   {
     ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-
-    if (!mWaitingForSeekData) {
-      mWaitingForSeekData = true;
-      if (mAudioTrack) {
-        mPendingSeeks++;
-      }
-      if (mVideoTrack) {
-        mPendingSeeks++;
-      }
-    }
+    mWaitingForSeekData = true;
   }
 
   AttemptSeek();
   return p;
 }
 
 void
-MediaSourceReader::OnSeekCompleted(int64_t aTime)
+MediaSourceReader::OnVideoSeekCompleted(int64_t aTime)
 {
-  mPendingSeeks--;
-  FinalizeSeek();
+  mPendingSeekTime = aTime;
+  if (mAudioTrack) {
+    mAudioIsSeeking = true;
+    SwitchAudioReader(mPendingSeekTime);
+    mAudioReader->Seek(mPendingSeekTime,
+                       mPendingStartTime,
+                       mPendingEndTime,
+                       mPendingCurrentTime)
+                ->Then(GetTaskQueue(), __func__, this,
+                       &MediaSourceReader::OnAudioSeekCompleted,
+                       &MediaSourceReader::OnSeekFailed);
+    MSE_DEBUG("MediaSourceReader(%p)::Seek audio reader=%p", this, mAudioReader.get());
+    return;
+  }
+  mSeekPromise.Resolve(mPendingSeekTime, __func__);
+}
+
+void
+MediaSourceReader::OnAudioSeekCompleted(int64_t aTime)
+{
+  mSeekPromise.Resolve(mPendingSeekTime, __func__);
 }
 
 void
 MediaSourceReader::OnSeekFailed(nsresult aResult)
 {
-  mPendingSeeks--;
   // Keep the most recent failed result (if any)
   if (NS_FAILED(aResult)) {
-    mSeekResult = aResult;
+    mSeekPromise.Reject(aResult, __func__);
+    return;
   }
-  FinalizeSeek();
-}
-
-void
-MediaSourceReader::FinalizeSeek()
-{
-  // Only dispatch the final event onto the state machine
-  // since it's only expecting one response.
-  if (!mPendingSeeks) {
-    if (NS_FAILED(mSeekResult)) {
-      mSeekPromise.Reject(mSeekResult, __func__);
-    } else {
-      mSeekPromise.Resolve(mPendingSeekTime, __func__);
-    }
-    mSeekResult = NS_OK;
-  }
+  mSeekPromise.Resolve(mPendingSeekTime, __func__);
 }
 
 void
 MediaSourceReader::AttemptSeek()
 {
   // Make sure we don't hold the monitor while calling into the reader
   // Seek methods since it can deadlock.
   {
@@ -659,40 +652,31 @@ MediaSourceReader::AttemptSeek()
   for (uint32_t i = 0; i < mTrackBuffers.Length(); ++i) {
     mTrackBuffers[i]->ResetDecode();
   }
 
   // Decoding discontinuity upon seek, reset last times to seek target.
   mLastAudioTime = mPendingSeekTime;
   mLastVideoTime = mPendingSeekTime;
 
-  if (mAudioTrack) {
-    mAudioIsSeeking = true;
-    SwitchAudioReader(mPendingSeekTime);
-    mAudioReader->Seek(mPendingSeekTime,
-                       mPendingStartTime,
-                       mPendingEndTime,
-                       mPendingCurrentTime)
-                ->Then(GetTaskQueue(), __func__, this,
-                       &MediaSourceReader::OnSeekCompleted,
-                       &MediaSourceReader::OnSeekFailed);
-    MSE_DEBUG("MediaSourceReader(%p)::Seek audio reader=%p", this, mAudioReader.get());
-  }
   if (mVideoTrack) {
     mVideoIsSeeking = true;
     SwitchVideoReader(mPendingSeekTime);
     mVideoReader->Seek(mPendingSeekTime,
                        mPendingStartTime,
                        mPendingEndTime,
                        mPendingCurrentTime)
                 ->Then(GetTaskQueue(), __func__, this,
-                       &MediaSourceReader::OnSeekCompleted,
+                       &MediaSourceReader::OnVideoSeekCompleted,
                        &MediaSourceReader::OnSeekFailed);
     MSE_DEBUG("MediaSourceReader(%p)::Seek video reader=%p", this, mVideoReader.get());
+  } else {
+    OnVideoSeekCompleted(mPendingSeekTime);
   }
+
   {
     ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
     mWaitingForSeekData = false;
   }
 }
 
 nsresult
 MediaSourceReader::GetBuffered(dom::TimeRanges* aBuffered)
--- a/dom/media/mediasource/MediaSourceReader.h
+++ b/dom/media/mediasource/MediaSourceReader.h
@@ -53,17 +53,18 @@ public:
   virtual size_t SizeOfVideoQueueInFrames() MOZ_OVERRIDE;
   virtual size_t SizeOfAudioQueueInFrames() MOZ_OVERRIDE;
 
   void OnAudioDecoded(AudioData* aSample);
   void OnAudioNotDecoded(NotDecodedReason aReason);
   void OnVideoDecoded(VideoData* aSample);
   void OnVideoNotDecoded(NotDecodedReason aReason);
 
-  void OnSeekCompleted(int64_t aTime);
+  void OnVideoSeekCompleted(int64_t aTime);
+  void OnAudioSeekCompleted(int64_t aTime);
   void OnSeekFailed(nsresult aResult);
 
   virtual bool IsWaitForDataSupported() MOZ_OVERRIDE { return true; }
   virtual nsRefPtr<WaitForDataPromise> WaitForData(MediaData::Type aType) MOZ_OVERRIDE;
   void MaybeNotifyHaveData();
 
   bool HasVideo() MOZ_OVERRIDE
   {
@@ -139,17 +140,16 @@ private:
   // Return a reader from the set available in aTrackDecoders that has data
   // available in the range requested by aTarget.
   already_AddRefed<MediaDecoderReader> SelectReader(int64_t aTarget,
                                                     int64_t aError,
                                                     const nsTArray<nsRefPtr<SourceBufferDecoder>>& aTrackDecoders);
   bool HaveData(int64_t aTarget, MediaData::Type aType);
 
   void AttemptSeek();
-  void FinalizeSeek();
 
   nsRefPtr<MediaDecoderReader> mAudioReader;
   nsRefPtr<MediaDecoderReader> mVideoReader;
 
   nsTArray<nsRefPtr<TrackBuffer>> mTrackBuffers;
   nsTArray<nsRefPtr<TrackBuffer>> mShutdownTrackBuffers;
   nsTArray<nsRefPtr<TrackBuffer>> mEssentialTrackBuffers;
   nsRefPtr<TrackBuffer> mAudioTrack;
@@ -177,22 +177,16 @@ private:
   // to be added to the track buffer.
   MediaPromiseHolder<SeekPromise> mSeekPromise;
   int64_t mPendingSeekTime;
   int64_t mPendingStartTime;
   int64_t mPendingEndTime;
   int64_t mPendingCurrentTime;
   bool mWaitingForSeekData;
 
-  // Number of outstanding OnSeekCompleted notifications
-  // we're expecting to get from child decoders, and the
-  // result we're going to forward onto our callback.
-  uint32_t mPendingSeeks;
-  nsresult mSeekResult;
-
   int64_t mTimeThreshold;
   bool mDropAudioBeforeThreshold;
   bool mDropVideoBeforeThreshold;
 
   bool mEnded;
 
   // For a seek to complete we need to send a sample with
   // the mDiscontinuity field set to true once we have the