Bug 1284399. Part 1 - add GetSeekTarget() to remove direct access to mSeekJob. r=kaku
authorJW Wang <jwwang@mozilla.com>
Thu, 30 Jun 2016 13:37:20 +0800
changeset 305175 cb07471f5f37f8ac9b43db93dce0e890c9e6925b
parent 305174 12217312864daca0109a1e8f6c87fb79a2703934
child 305176 2c43a873bb1c79626bef8ad73912157e8b58ec6a
push id79518
push usercbook@mozilla.com
push dateSun, 17 Jul 2016 08:09:59 +0000
treeherdermozilla-inbound@711963e8daa3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskaku
bugs1284399
milestone50.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 1284399. Part 1 - add GetSeekTarget() to remove direct access to mSeekJob. r=kaku MozReview-Commit-ID: 60wIW9gHYKt
dom/media/AccurateSeekTask.cpp
dom/media/MediaDecoderStateMachine.cpp
dom/media/NextFrameSeekTask.cpp
dom/media/SeekTask.cpp
dom/media/SeekTask.h
--- a/dom/media/AccurateSeekTask.cpp
+++ b/dom/media/AccurateSeekTask.cpp
@@ -47,18 +47,17 @@ AccurateSeekTask::AccurateSeekTask(const
   , mAudioRate(aInfo.mAudio.mRate)
   , mDoneAudioSeeking(!aInfo.HasAudio() || mSeekJob.mTarget.IsVideoOnly())
   , mDoneVideoSeeking(!aInfo.HasVideo())
 {
   AssertOwnerThread();
 
   // Bound the seek time to be inside the media range.
   NS_ASSERTION(aEnd.ToMicroseconds() != -1, "Should know end time by now");
-  mSeekJob.mTarget.SetTime(
-    std::max(media::TimeUnit(), std::min(mSeekJob.mTarget.GetTime(), aEnd)));
+  mTarget.SetTime(std::max(media::TimeUnit(), std::min(mTarget.GetTime(), aEnd)));
 
   // Configure MediaDecoderReaderWrapper.
   SetCallbacks();
 }
 
 AccurateSeekTask::~AccurateSeekTask()
 {
   AssertOwnerThread();
@@ -91,17 +90,17 @@ AccurateSeekTask::NeedToResetMDSM() cons
 }
 
 RefPtr<AccurateSeekTask::SeekTaskPromise>
 AccurateSeekTask::Seek(const media::TimeUnit& aDuration)
 {
   AssertOwnerThread();
 
   // Do the seek.
-  mSeekRequest.Begin(mReader->Seek(mSeekJob.mTarget, aDuration)
+  mSeekRequest.Begin(mReader->Seek(mTarget, aDuration)
     ->Then(OwnerThread(), __func__, this,
            &AccurateSeekTask::OnSeekResolved, &AccurateSeekTask::OnSeekRejected));
 
   return mSeekTaskPromise.Ensure(__func__);
 }
 
 void
 AccurateSeekTask::RequestAudioData()
@@ -124,53 +123,53 @@ AccurateSeekTask::RequestVideoData()
 }
 
 nsresult
 AccurateSeekTask::DropAudioUpToSeekTarget(MediaData* aSample)
 {
   AssertOwnerThread();
 
   RefPtr<AudioData> audio(aSample->As<AudioData>());
-  MOZ_ASSERT(audio && mSeekJob.Exists() && mSeekJob.mTarget.IsAccurate());
+  MOZ_ASSERT(audio && mSeekJob.Exists() && mTarget.IsAccurate());
 
   CheckedInt64 sampleDuration = FramesToUsecs(audio->mFrames, mAudioRate);
   if (!sampleDuration.isValid()) {
     return NS_ERROR_FAILURE;
   }
 
-  if (audio->mTime + sampleDuration.value() <= mSeekJob.mTarget.GetTime().ToMicroseconds()) {
+  if (audio->mTime + sampleDuration.value() <= mTarget.GetTime().ToMicroseconds()) {
     // Our seek target lies after the frames in this AudioData. Don't
     // push it onto the audio queue, and keep decoding forwards.
     return NS_OK;
   }
 
-  if (audio->mTime > mSeekJob.mTarget.GetTime().ToMicroseconds()) {
+  if (audio->mTime > mTarget.GetTime().ToMicroseconds()) {
     // The seek target doesn't lie in the audio block just after the last
     // audio frames we've seen which were before the seek target. This
     // could have been the first audio data we've seen after seek, i.e. the
     // seek terminated after the seek target in the audio stream. Just
     // abort the audio decode-to-target, the state machine will play
     // silence to cover the gap. Typically this happens in poorly muxed
     // files.
     DECODER_WARN("Audio not synced after seek, maybe a poorly muxed file?");
     mSeekedAudioData = audio;
     mDoneAudioSeeking = true;
     return NS_OK;
   }
 
   // The seek target lies somewhere in this AudioData's frames, strip off
   // any frames which lie before the seek target, so we'll begin playback
   // exactly at the seek target.
-  NS_ASSERTION(mSeekJob.mTarget.GetTime().ToMicroseconds() >= audio->mTime,
+  NS_ASSERTION(mTarget.GetTime().ToMicroseconds() >= audio->mTime,
                "Target must at or be after data start.");
-  NS_ASSERTION(mSeekJob.mTarget.GetTime().ToMicroseconds() < audio->mTime + sampleDuration.value(),
+  NS_ASSERTION(mTarget.GetTime().ToMicroseconds() < audio->mTime + sampleDuration.value(),
                "Data must end after target.");
 
   CheckedInt64 framesToPrune =
-    UsecsToFrames(mSeekJob.mTarget.GetTime().ToMicroseconds() - audio->mTime, mAudioRate);
+    UsecsToFrames(mTarget.GetTime().ToMicroseconds() - audio->mTime, mAudioRate);
   if (!framesToPrune.isValid()) {
     return NS_ERROR_FAILURE;
   }
   if (framesToPrune.value() > audio->mFrames) {
     // We've messed up somehow. Don't try to trim frames, the |frames|
     // variable below will overflow.
     DECODER_WARN("Can't prune more frames that we have!");
     return NS_ERROR_FAILURE;
@@ -185,17 +184,17 @@ AccurateSeekTask::DropAudioUpToSeekTarge
   memcpy(audioData.get(),
          audio->mAudioData.get() + (framesToPrune.value() * channels),
          frames * channels * sizeof(AudioDataValue));
   CheckedInt64 duration = FramesToUsecs(frames, mAudioRate);
   if (!duration.isValid()) {
     return NS_ERROR_FAILURE;
   }
   RefPtr<AudioData> data(new AudioData(audio->mOffset,
-                                       mSeekJob.mTarget.GetTime().ToMicroseconds(),
+                                       mTarget.GetTime().ToMicroseconds(),
                                        duration.value(),
                                        frames,
                                        Move(audioData),
                                        channels,
                                        audio->mRate));
   MOZ_ASSERT(!mSeekedAudioData, "Should be the 1st sample after seeking");
   mSeekedAudioData = data;
   mDoneAudioSeeking = true;
@@ -208,17 +207,17 @@ AccurateSeekTask::DropVideoUpToSeekTarge
 {
   AssertOwnerThread();
 
   RefPtr<VideoData> video(aSample->As<VideoData>());
   MOZ_ASSERT(video);
   DECODER_LOG("DropVideoUpToSeekTarget() frame [%lld, %lld]",
               video->mTime, video->GetEndTime());
   MOZ_ASSERT(mSeekJob.Exists());
-  const int64_t target = mSeekJob.mTarget.GetTime().ToMicroseconds();
+  const int64_t target = mTarget.GetTime().ToMicroseconds();
 
   // If the frame end time is less than the seek target, we won't want
   // to display this frame after the seek, so discard it.
   if (target >= video->GetEndTime()) {
     DECODER_LOG("DropVideoUpToSeekTarget() pop video frame [%lld, %lld] target=%lld",
                 video->mTime, video->GetEndTime(), target);
     mFirstVideoFrameAfterSeek = video;
   } else {
@@ -276,26 +275,26 @@ AccurateSeekTask::OnSeekRejected(nsresul
   MOZ_ASSERT(NS_FAILED(aResult), "Cancels should also disconnect mSeekRequest");
   RejectIfExist(__func__);
 }
 
 void
 AccurateSeekTask::AdjustFastSeekIfNeeded(MediaData* aSample)
 {
   AssertOwnerThread();
-  if (mSeekJob.mTarget.IsFast() &&
-      mSeekJob.mTarget.GetTime() > mCurrentTimeBeforeSeek &&
+  if (mTarget.IsFast() &&
+      mTarget.GetTime() > mCurrentTimeBeforeSeek &&
       aSample->mTime < mCurrentTimeBeforeSeek.ToMicroseconds()) {
     // We are doing a fastSeek, but we ended up *before* the previous
     // playback position. This is surprising UX, so switch to an accurate
     // seek and decode to the seek target. This is not conformant to the
     // spec, fastSeek should always be fast, but until we get the time to
     // change all Readers to seek to the keyframe after the currentTime
     // in this case, we'll just decode forward. Bug 1026330.
-    mSeekJob.mTarget.SetType(SeekTarget::Accurate);
+    mTarget.SetType(SeekTarget::Accurate);
   }
 }
 
 void
 AccurateSeekTask::OnAudioDecoded(MediaData* aAudioSample)
 {
   AssertOwnerThread();
   MOZ_ASSERT(!mSeekTaskPromise.IsEmpty(), "Seek shouldn't be finished");
@@ -319,17 +318,17 @@ AccurateSeekTask::OnAudioDecoded(MediaDa
 
   if (mFirstAudioSample) {
     mFirstAudioSample = false;
     MOZ_ASSERT(audio->mDiscontinuity);
   }
 
   AdjustFastSeekIfNeeded(audio);
 
-  if (mSeekJob.mTarget.IsFast()) {
+  if (mTarget.IsFast()) {
     // Non-precise seek; we can stop the seek at the first sample.
     mSeekedAudioData = audio;
     mDoneAudioSeeking = true;
   } else if (NS_FAILED(DropAudioUpToSeekTarget(audio))) {
     RejectIfExist(__func__);
     return;
   }
 
@@ -410,17 +409,17 @@ AccurateSeekTask::OnVideoDecoded(MediaDa
 
   if (mFirstVideoSample) {
     mFirstVideoSample = false;
     MOZ_ASSERT(video->mDiscontinuity);
   }
 
   AdjustFastSeekIfNeeded(video);
 
-  if (mSeekJob.mTarget.IsFast()) {
+  if (mTarget.IsFast()) {
     // Non-precise seek. We can stop the seek at the first sample.
     mSeekedVideoData = video;
     mDoneVideoSeeking = true;
   } else if (NS_FAILED(DropVideoUpToSeekTarget(video.get()))) {
     RejectIfExist(__func__);
     return;
   }
 
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -1156,18 +1156,18 @@ MediaDecoderStateMachine::SetDormant(boo
     if (mState == DECODER_STATE_SEEKING) {
       if (mQueuedSeek.Exists()) {
         // Keep latest seek target
       } else if (mSeekTask && mSeekTask->Exists()) {
         // Because both audio and video decoders are going to be reset in this
         // method later, we treat a VideoOnly seek task as a normal Accurate
         // seek task so that while it is resumed, both audio and video playback
         // are handled.
-        if (mSeekTask->GetSeekJob().mTarget.IsVideoOnly()) {
-          mSeekTask->GetSeekJob().mTarget.SetType(SeekTarget::Accurate);
+        if (mSeekTask->GetSeekTarget().IsVideoOnly()) {
+          mSeekTask->GetSeekTarget().SetType(SeekTarget::Accurate);
         }
         mQueuedSeek = Move(mSeekTask->GetSeekJob());
         mSeekTaskRequest.DisconnectIfExists();
       } else {
         mQueuedSeek.mTarget = SeekTarget(mCurrentPosition,
                                          SeekTarget::Accurate,
                                          MediaDecoderEventVisibility::Suppressed);
         // XXXbholley - Nobody is listening to this promise. Do we need to pass it
@@ -1643,19 +1643,19 @@ MediaDecoderStateMachine::InitiateSeek(S
   } else {
     MOZ_DIAGNOSTIC_ASSERT(false, "Cannot handle this seek task.");
   }
 
   // Stop playback now to ensure that while we're outside the monitor
   // dispatching SeekingStarted, playback doesn't advance and mess with
   // mCurrentPosition that we've setting to seekTime here.
   StopPlayback();
-  UpdatePlaybackPositionInternal(mSeekTask->GetSeekJob().mTarget.GetTime().ToMicroseconds());
-
-  mOnSeekingStart.Notify(mSeekTask->GetSeekJob().mTarget.mEventVisibility);
+  UpdatePlaybackPositionInternal(mSeekTask->GetSeekTarget().GetTime().ToMicroseconds());
+
+  mOnSeekingStart.Notify(mSeekTask->GetSeekTarget().mEventVisibility);
 
   // Reset our state machine and decoding pipeline before seeking.
   if (mSeekTask->NeedToResetMDSM()) { Reset(); }
 
   // Do the seek.
   mSeekTaskRequest.Begin(mSeekTask->Seek(Duration())
     ->Then(OwnerThread(), __func__, this,
            &MediaDecoderStateMachine::OnSeekTaskResolved,
@@ -2131,17 +2131,17 @@ MediaDecoderStateMachine::FinishDecodeFi
 }
 
 void
 MediaDecoderStateMachine::SeekCompleted()
 {
   MOZ_ASSERT(OnTaskQueue());
   MOZ_ASSERT(mState == DECODER_STATE_SEEKING);
 
-  int64_t seekTime = mSeekTask->GetSeekJob().mTarget.GetTime().ToMicroseconds();
+  int64_t seekTime = mSeekTask->GetSeekTarget().GetTime().ToMicroseconds();
   int64_t newCurrentTime = seekTime;
 
   // Setup timestamp state.
   RefPtr<MediaData> video = VideoQueue().PeekFront();
   if (seekTime == Duration().ToMicroseconds()) {
     newCurrentTime = seekTime;
   } else if (HasAudio()) {
     RefPtr<MediaData> audio = AudioQueue().PeekFront();
--- a/dom/media/NextFrameSeekTask.cpp
+++ b/dom/media/NextFrameSeekTask.cpp
@@ -151,17 +151,17 @@ NextFrameSeekTask::IsVideoSeekComplete()
 
 void
 NextFrameSeekTask::MaybeFinishSeek()
 {
   AssertOwnerThread();
   if (IsAudioSeekComplete() && IsVideoSeekComplete()) {
     UpdateSeekTargetTime();
 
-    auto time = mSeekJob.mTarget.GetTime().ToMicroseconds();
+    auto time = mTarget.GetTime().ToMicroseconds();
     DiscardFrames(mAudioQueue, [time] (int64_t aSampleTime) {
       return aSampleTime < time;
     });
 
     Resolve(__func__); // Call to MDSM::SeekCompleted();
   }
 }
 
@@ -328,19 +328,19 @@ NextFrameSeekTask::CancelCallbacks()
 
 void
 NextFrameSeekTask::UpdateSeekTargetTime()
 {
   AssertOwnerThread();
 
   RefPtr<MediaData> data = mVideoQueue.PeekFront();
   if (data) {
-    mSeekJob.mTarget.SetTime(TimeUnit::FromMicroseconds(data->mTime));
+    mTarget.SetTime(TimeUnit::FromMicroseconds(data->mTime));
   } else if (mSeekedVideoData) {
-    mSeekJob.mTarget.SetTime(TimeUnit::FromMicroseconds(mSeekedVideoData->mTime));
+    mTarget.SetTime(TimeUnit::FromMicroseconds(mSeekedVideoData->mTime));
   } else if (mIsVideoQueueFinished || mVideoQueue.AtEndOfStream()) {
-    mSeekJob.mTarget.SetTime(mDuration);
+    mTarget.SetTime(mDuration);
   } else {
     MOZ_ASSERT(false, "No data!");
   }
 }
 } // namespace media
 } // namespace mozilla
--- a/dom/media/SeekTask.cpp
+++ b/dom/media/SeekTask.cpp
@@ -13,16 +13,17 @@ namespace mozilla {
 SeekTask::SeekTask(const void* aDecoderID,
                    AbstractThread* aThread,
                    MediaDecoderReaderWrapper* aReader,
                    SeekJob&& aSeekJob)
   : mDecoderID(aDecoderID)
   , mOwnerThread(aThread)
   , mReader(aReader)
   , mSeekJob(Move(aSeekJob))
+  , mTarget(mSeekJob.mTarget)
   , mIsDiscarded(false)
   , mIsAudioQueueFinished(false)
   , mIsVideoQueueFinished(false)
   , mNeedToStopPrerollingAudio(false)
   , mNeedToStopPrerollingVideo(false)
 {
   AssertOwnerThread();
 }
@@ -78,16 +79,23 @@ SeekTask::OwnerThread() const
 
 SeekJob&
 SeekTask::GetSeekJob()
 {
   AssertOwnerThread();
   return mSeekJob;
 }
 
+SeekTarget&
+SeekTask::GetSeekTarget()
+{
+  AssertOwnerThread();
+  return mTarget;
+}
+
 bool
 SeekTask::Exists() const
 {
   AssertOwnerThread();
 
   // mSeekTaskPromise communicates SeekTask and MDSM;
   // mSeekJob communicates MDSM and MediaDecoder;
   // Either one exists means the current seek task has yet finished.
--- a/dom/media/SeekTask.h
+++ b/dom/media/SeekTask.h
@@ -53,16 +53,18 @@ public:
   virtual void Discard() = 0;
 
   virtual RefPtr<SeekTaskPromise> Seek(const media::TimeUnit& aDuration) = 0;
 
   virtual bool NeedToResetMDSM() const = 0;
 
   SeekJob& GetSeekJob();
 
+  SeekTarget& GetSeekTarget();
+
   bool Exists() const;
 
 protected:
   SeekTask(const void* aDecoderID,
            AbstractThread* aThread,
            MediaDecoderReaderWrapper* aReader,
            SeekJob&& aSeekJob);
 
@@ -82,16 +84,17 @@ protected:
   const void* mDecoderID; // For logging.
   const RefPtr<AbstractThread> mOwnerThread;
   const RefPtr<MediaDecoderReaderWrapper> mReader;
 
   /*
    * Internal state.
    */
   SeekJob mSeekJob;
+  SeekTarget& mTarget;
   MozPromiseHolder<SeekTaskPromise> mSeekTaskPromise;
   bool mIsDiscarded;
 
   /*
    * Information which are going to be returned to MDSM.
    */
   RefPtr<MediaData> mSeekedAudioData;
   RefPtr<MediaData> mSeekedVideoData;