Bug 1062020 - Set video/audio sample discontinuity flag in MSE after seek - r=kinetik
authorChris Double <chris.double@double.co.nz>
Wed, 03 Sep 2014 21:56:22 +1200
changeset 203359 30a34467eec120cf8686101791aced71945ad484
parent 203358 a5b71fdd51f06bc584a1ca0c598aed77c8081af5
child 203360 7a721388e46b9df901d8401661156eb8488a8526
push id27425
push userryanvm@gmail.com
push dateWed, 03 Sep 2014 20:38:59 +0000
treeherdermozilla-central@acbdce59da2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik
bugs1062020
milestone35.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 1062020 - Set video/audio sample discontinuity flag in MSE after seek - r=kinetik
content/media/mediasource/MediaSourceReader.cpp
content/media/mediasource/MediaSourceReader.h
--- a/content/media/mediasource/MediaSourceReader.cpp
+++ b/content/media/mediasource/MediaSourceReader.cpp
@@ -36,16 +36,18 @@ extern PRLogModuleInfo* GetMediaSourceAP
 namespace mozilla {
 
 MediaSourceReader::MediaSourceReader(MediaSourceDecoder* aDecoder)
   : MediaDecoderReader(aDecoder)
   , mTimeThreshold(-1)
   , mDropAudioBeforeThreshold(false)
   , mDropVideoBeforeThreshold(false)
   , mEnded(false)
+  , mAudioIsSeeking(false)
+  , mVideoIsSeeking(false)
 {
 }
 
 bool
 MediaSourceReader::IsWaitingMediaResources()
 {
   return mDecoders.IsEmpty() && mPendingDecoders.IsEmpty();
 }
@@ -71,16 +73,24 @@ MediaSourceReader::OnAudioDecoded(AudioD
       MSE_DEBUG("MediaSourceReader(%p)::OnAudioDecoded mTime=%lld < mTimeThreshold=%lld",
                 this, aSample->mTime, mTimeThreshold);
       delete aSample;
       mAudioReader->RequestAudioData();
       return;
     }
     mDropAudioBeforeThreshold = false;
   }
+
+  // If we are seeking we need to make sure the first sample decoded after
+  // that seek has the mDiscontinuity field set to ensure the media decoder
+  // state machine picks up that the seek is complete.
+  if (mAudioIsSeeking) {
+    mAudioIsSeeking = false;
+    aSample->mDiscontinuity = true;
+  }
   GetCallback()->OnAudioDecoded(aSample);
 }
 
 void
 MediaSourceReader::OnAudioEOS()
 {
   MSE_DEBUG("MediaSourceReader(%p)::OnAudioEOS reader=%p (readers=%u)",
             this, mAudioReader.get(), mDecoders.Length());
@@ -117,16 +127,25 @@ MediaSourceReader::OnVideoDecoded(VideoD
       MSE_DEBUG("MediaSourceReader(%p)::OnVideoDecoded mTime=%lld < mTimeThreshold=%lld",
                 this, aSample->mTime, mTimeThreshold);
       delete aSample;
       mVideoReader->RequestVideoData(false, mTimeThreshold);
       return;
     }
     mDropVideoBeforeThreshold = false;
   }
+
+  // If we are seeking we need to make sure the first sample decoded after
+  // that seek has the mDiscontinuity field set to ensure the media decoder
+  // state machine picks up that the seek is complete.
+  if (mVideoIsSeeking) {
+    mVideoIsSeeking = false;
+    aSample->mDiscontinuity = true;
+  }
+
   GetCallback()->OnVideoDecoded(aSample);
 }
 
 void
 MediaSourceReader::OnVideoEOS()
 {
   // End of stream. See if we can switch to another video decoder.
   MSE_DEBUG("MediaSourceReader(%p)::OnVideoEOS reader=%p (readers=%u)",
@@ -433,23 +452,25 @@ MediaSourceReader::Seek(int64_t aTime, i
   }
 
   if (IsShutdown()) {
     return NS_ERROR_FAILURE;
   }
 
   ResetDecode();
   if (mAudioReader) {
+    mAudioIsSeeking = true;
     nsresult rv = mAudioReader->Seek(aTime, aStartTime, aEndTime, aCurrentTime);
     MSE_DEBUG("MediaSourceReader(%p)::Seek audio reader=%p rv=%x", this, mAudioReader.get(), rv);
     if (NS_FAILED(rv)) {
       return rv;
     }
   }
   if (mVideoReader) {
+    mVideoIsSeeking = true;
     nsresult rv = mVideoReader->Seek(aTime, aStartTime, aEndTime, aCurrentTime);
     MSE_DEBUG("MediaSourceReader(%p)::Seek video reader=%p rv=%x", this, mVideoReader.get(), rv);
     if (NS_FAILED(rv)) {
       return rv;
     }
   }
   return NS_OK;
 }
--- a/content/media/mediasource/MediaSourceReader.h
+++ b/content/media/mediasource/MediaSourceReader.h
@@ -111,13 +111,21 @@ private:
 
   nsTArray<nsRefPtr<SourceBufferDecoder>> mPendingDecoders;
   nsTArray<nsRefPtr<SourceBufferDecoder>> mDecoders;
 
   nsRefPtr<MediaDecoderReader> mAudioReader;
   nsRefPtr<MediaDecoderReader> mVideoReader;
 
   bool mEnded;
+
+  // For a seek to complete we need to send a sample with
+  // the mDiscontinuity field set to true once we have the
+  // first decoded sample. These flags are set during seeking
+  // so we can detect when we have the first decoded sample
+  // after a seek.
+  bool mAudioIsSeeking;
+  bool mVideoIsSeeking;
 };
 
 } // namespace mozilla
 
 #endif /* MOZILLA_MEDIASOURCEREADER_H_ */