Backed out changeset 3686da2395b9 (bug 1309516)
authorSebastian Hengst <archaeopteryx@coole-files.de>
Sat, 05 Nov 2016 11:00:08 +0100
changeset 321124 420731164890399f40d6e657533708ca46b5a657
parent 321123 5486a88515be99f38ae19d55f724cd0278b16eea
child 321125 7244d8f6c4f30d02b5d16c8e73513a457081a228
push id30919
push userphilringnalda@gmail.com
push dateSat, 05 Nov 2016 20:28:20 +0000
treeherdermozilla-central@572249b2ffb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1309516
milestone52.0a1
backs out3686da2395b994c0b2f42fb788f58211658dc0a9
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
Backed out changeset 3686da2395b9 (bug 1309516)
dom/media/MediaDecoderStateMachine.cpp
dom/media/MediaFormatReader.cpp
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -1567,35 +1567,40 @@ SeekingState::HandleSeek(SeekTarget aTar
   return SetState<SeekingState>(Move(seekJob));
 }
 
 void
 MediaDecoderStateMachine::
 SeekingState::SeekCompleted()
 {
   int64_t seekTime = mSeekTask->GetSeekTarget().GetTime().ToMicroseconds();
-  int64_t newCurrentTime;
-
-  // For the accurate seek, we always set the newCurrentTime = seekTime so that
-  // the updated HTMLMediaElement.currentTime will always be the seek target;
-  // we rely on the MediaSink to handles the gap between the newCurrentTime and
-  // the real decoded samples' start time.
-  // For the other seek types, we update the newCurrentTime with the decoded
-  // samples, set it to be the smallest start time of decoded samples.
-  if (mSeekTask->GetSeekTarget().IsAccurate()) {
+  int64_t newCurrentTime = seekTime;
+
+  // Setup timestamp state.
+  RefPtr<MediaData> video = mMaster->VideoQueue().PeekFront();
+  if (seekTime == mMaster->Duration().ToMicroseconds()) {
     newCurrentTime = seekTime;
-  } else {
+  } else if (mMaster->HasAudio()) {
     RefPtr<MediaData> audio = mMaster->AudioQueue().PeekFront();
-    RefPtr<MediaData> video = mMaster->VideoQueue().PeekFront();
-    const int64_t audioStart = audio ? audio->mTime : INT64_MAX;
-    const int64_t videoStart = video ? video->mTime : INT64_MAX;
-    newCurrentTime = std::min(audioStart, videoStart);
-    if (newCurrentTime == INT64_MAX) {
-      newCurrentTime = seekTime;
+    // Though we adjust the newCurrentTime in audio-based, and supplemented
+    // by video. For better UX, should NOT bind the slide position to
+    // the first audio data timestamp directly.
+    // While seeking to a position where there's only either audio or video, or
+    // seeking to a position lies before audio or video, we need to check if
+    // seekTime is bounded in suitable duration. See Bug 1112438.
+    int64_t audioStart = audio ? audio->mTime : seekTime;
+    // We only pin the seek time to the video start time if the video frame
+    // contains the seek time.
+    if (video && video->mTime <= seekTime && video->GetEndTime() > seekTime) {
+      newCurrentTime = std::min(audioStart, video->mTime);
+    } else {
+      newCurrentTime = audioStart;
     }
+  } else {
+    newCurrentTime = video ? video->mTime : seekTime;
   }
 
   // Change state to DECODING or COMPLETED now.
   bool isLiveStream = Resource()->IsLiveStream();
   State nextState;
   if (newCurrentTime == mMaster->Duration().ToMicroseconds() && !isLiveStream) {
     // Seeked to end of media, move to COMPLETED state. Note we don't do
     // this when playing a live stream, since the end of media will advance
@@ -1625,17 +1630,17 @@ SeekingState::SeekCompleted()
     // Otherwise we might have |newCurrentTime > mMediaSink->GetPosition()|
     // and fail the assertion in GetClock() since we didn't stop MediaSink.
     mMaster->UpdatePlaybackPositionInternal(newCurrentTime);
   }
 
   // Try to decode another frame to detect if we're at the end...
   SLOG("Seek completed, mCurrentPosition=%lld", mMaster->mCurrentPosition.Ref());
 
-  if (mMaster->VideoQueue().PeekFront()) {
+  if (video) {
     mMaster->mMediaSink->Redraw(Info().mVideo);
     mMaster->mOnPlaybackEvent.Notify(MediaEventType::Invalidate);
   }
 
   if (nextState == DECODER_STATE_COMPLETED) {
     SetState<CompletedState>();
   } else {
     SetState<DecodingState>();
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -1942,18 +1942,26 @@ MediaFormatReader::Seek(SeekTarget aTarg
   return p;
 }
 
 void
 MediaFormatReader::SetSeekTarget(const SeekTarget& aTarget)
 {
   MOZ_ASSERT(OnTaskQueue());
 
-  mOriginalSeekTarget = aTarget;
-  mFallbackSeekTime = mPendingSeekTime = Some(aTarget.GetTime());
+  SeekTarget target = aTarget;
+
+  // Transform the seek target time to the demuxer timeline.
+  if (!ForceZeroStartTime()) {
+    target.SetTime(aTarget.GetTime() - TimeUnit::FromMicroseconds(StartTime())
+                   + mInfo.mStartTime);
+  }
+
+  mOriginalSeekTarget = target;
+  mFallbackSeekTime = mPendingSeekTime = Some(target.GetTime());
 }
 
 void
 MediaFormatReader::ScheduleSeek()
 {
   if (mSeekScheduled) {
     return;
   }