Bug 1284399. Part 6 - store a copy of SeekTarget instead of its reference in SeekTask so it's life cycle can be independent from the client. r=kaku draft
authorJW Wang <jwwang@mozilla.com>
Tue, 05 Jul 2016 14:12:42 +0800
changeset 386930 2eb997b9a13a7b9a3390700aceef9fbfb77268a2
parent 386929 7bec5865ef850beaaed12e7f55c4dd0888939675
child 525247 3040ec3e31aea271a9ac3403ab340ea238936ceb
push id22850
push userjwwang@mozilla.com
push dateWed, 13 Jul 2016 02:19:16 +0000
reviewerskaku
bugs1284399
milestone50.0a1
Bug 1284399. Part 6 - store a copy of SeekTarget instead of its reference in SeekTask so it's life cycle can be independent from the client. r=kaku MozReview-Commit-ID: BWrutqvsj29
dom/media/AccurateSeekTask.cpp
dom/media/AccurateSeekTask.h
dom/media/MediaDecoderStateMachine.cpp
dom/media/NextFrameSeekTask.cpp
dom/media/NextFrameSeekTask.h
dom/media/SeekTask.cpp
dom/media/SeekTask.h
--- a/dom/media/AccurateSeekTask.cpp
+++ b/dom/media/AccurateSeekTask.cpp
@@ -33,24 +33,24 @@ extern LazyLogModule gMediaSampleLog;
 // when __VA_ARGS__ expands to nothing. This is a workaround for it.
 #define DECODER_WARN_HELPER(a, b) NS_WARNING b
 #define DECODER_WARN(x, ...) \
   DECODER_WARN_HELPER(0, (nsPrintfCString("Decoder=%p " x, mDecoderID, ##__VA_ARGS__).get()))
 
 AccurateSeekTask::AccurateSeekTask(const void* aDecoderID,
                                    AbstractThread* aThread,
                                    MediaDecoderReaderWrapper* aReader,
-                                   SeekJob& aSeekJob,
+                                   const SeekTarget& aTarget,
                                    const MediaInfo& aInfo,
                                    const media::TimeUnit& aEnd,
                                    int64_t aCurrentMediaTime)
-  : SeekTask(aDecoderID, aThread, aReader, aSeekJob)
+  : SeekTask(aDecoderID, aThread, aReader, aTarget)
   , mCurrentTimeBeforeSeek(media::TimeUnit::FromMicroseconds(aCurrentMediaTime))
   , mAudioRate(aInfo.mAudio.mRate)
-  , mDoneAudioSeeking(!aInfo.HasAudio() || mTarget.IsVideoOnly())
+  , mDoneAudioSeeking(!aInfo.HasAudio() || aTarget.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");
   mTarget.SetTime(std::max(media::TimeUnit(), std::min(mTarget.GetTime(), aEnd)));
 
--- a/dom/media/AccurateSeekTask.h
+++ b/dom/media/AccurateSeekTask.h
@@ -14,17 +14,17 @@
 
 namespace mozilla {
 
 class AccurateSeekTask final : public SeekTask {
 public:
   AccurateSeekTask(const void* aDecoderID,
                    AbstractThread* aThread,
                    MediaDecoderReaderWrapper* aReader,
-                   SeekJob& aSeekJob,
+                   const SeekTarget& aTarget,
                    const MediaInfo& aInfo,
                    const media::TimeUnit& aEnd,
                    int64_t aCurrentMediaTime);
 
   void Discard() override;
 
   RefPtr<SeekTaskPromise> Seek(const media::TimeUnit& aDuration) override;
 
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -1437,17 +1437,17 @@ void MediaDecoderStateMachine::InitiateD
 
   // SeekTask will register its callbacks to MediaDecoderReaderWrapper.
   CancelMediaDecoderReaderWrapperCallback();
 
   MOZ_ASSERT(!mCurrentSeek.Exists());
   mCurrentSeek = Move(seekJob);
   // Create a new SeekTask instance for the incoming seek task.
   mSeekTask = new AccurateSeekTask(mDecoderID, OwnerThread(),
-                                   mReader.get(), mCurrentSeek,
+                                   mReader.get(), mCurrentSeek.mTarget,
                                    mInfo, Duration(), GetMediaTime());
 
   mOnSeekingStart.Notify(MediaDecoderEventVisibility::Suppressed);
 
   // Reset our state machine and decoding pipeline before seeking.
   if (mSeekTask->NeedToResetMDSM()) {
     Reset(aTracks);
   }
@@ -1642,33 +1642,38 @@ MediaDecoderStateMachine::InitiateSeek(S
   // SeekTask will register its callbacks to MediaDecoderReaderWrapper.
   CancelMediaDecoderReaderWrapperCallback();
 
   // Create a new SeekTask instance for the incoming seek task.
   MOZ_ASSERT(!mCurrentSeek.Exists());
   mCurrentSeek = Move(aSeekJob);
   if (mCurrentSeek.mTarget.IsAccurate() || mCurrentSeek.mTarget.IsFast()) {
     mSeekTask = new AccurateSeekTask(mDecoderID, OwnerThread(),
-                                     mReader.get(), mCurrentSeek,
+                                     mReader.get(), mCurrentSeek.mTarget,
                                      mInfo, Duration(), GetMediaTime());
   } else if (mCurrentSeek.mTarget.IsNextFrame()) {
     mSeekTask = new NextFrameSeekTask(mDecoderID, OwnerThread(), mReader.get(),
-                                      mCurrentSeek, mInfo, Duration(),
+                                      mCurrentSeek.mTarget, mInfo, Duration(),
                                       GetMediaTime(), AudioQueue(), VideoQueue());
   } 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();
+
+  // mCurrentSeek.mTarget.mTime might be different from
+  // mSeekTask->GetSeekTarget().mTime because the seek task might clamp the seek
+  // target to [0, duration]. We want to update the playback position to the
+  // clamped value.
   UpdatePlaybackPositionInternal(mSeekTask->GetSeekTarget().GetTime().ToMicroseconds());
 
-  mOnSeekingStart.Notify(mSeekTask->GetSeekTarget().mEventVisibility);
+  mOnSeekingStart.Notify(mCurrentSeek.mTarget.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,
--- a/dom/media/NextFrameSeekTask.cpp
+++ b/dom/media/NextFrameSeekTask.cpp
@@ -17,23 +17,23 @@ extern LazyLogModule gMediaSampleLog;
 #define SAMPLE_LOG(x, ...) MOZ_LOG(gMediaSampleLog, LogLevel::Debug, \
   ("[NextFrameSeekTask] Decoder=%p " x, mDecoderID, ##__VA_ARGS__))
 
 namespace media {
 
 NextFrameSeekTask::NextFrameSeekTask(const void* aDecoderID,
                                      AbstractThread* aThread,
                                      MediaDecoderReaderWrapper* aReader,
-                                     SeekJob& aSeekJob,
+                                     const SeekTarget& aTarget,
                                      const MediaInfo& aInfo,
                                      const media::TimeUnit& aDuration,
                                      int64_t aCurrentTime,
                                      MediaQueue<MediaData>& aAudioQueue,
                                      MediaQueue<MediaData>& aVideoQueue)
-  : SeekTask(aDecoderID, aThread, aReader, aSeekJob)
+  : SeekTask(aDecoderID, aThread, aReader, aTarget)
   , mAudioQueue(aAudioQueue)
   , mVideoQueue(aVideoQueue)
   , mCurrentTime(aCurrentTime)
   , mDuration(aDuration)
 {
   AssertOwnerThread();
   MOZ_ASSERT(aInfo.HasVideo());
 
--- a/dom/media/NextFrameSeekTask.h
+++ b/dom/media/NextFrameSeekTask.h
@@ -22,17 +22,17 @@ namespace media {
  * so that the MDSM will be able to update the media element's position.
  */
 
 class NextFrameSeekTask final : public SeekTask {
 public:
   NextFrameSeekTask(const void* aDecoderID,
                    AbstractThread* aThread,
                    MediaDecoderReaderWrapper* aReader,
-                   SeekJob& aSeekJob,
+                   const SeekTarget& aTarget,
                    const MediaInfo& aInfo,
                    const media::TimeUnit& aDuration,
                    int64_t aCurrentTime,
                    MediaQueue<MediaData>& aAudioQueue,
                    MediaQueue<MediaData>& aVideoQueue);
 
   void Discard() override;
 
--- a/dom/media/SeekTask.cpp
+++ b/dom/media/SeekTask.cpp
@@ -8,21 +8,21 @@
 #include "MediaDecoderReaderWrapper.h"
 #include "mozilla/AbstractThread.h"
 
 namespace mozilla {
 
 SeekTask::SeekTask(const void* aDecoderID,
                    AbstractThread* aThread,
                    MediaDecoderReaderWrapper* aReader,
-                   SeekJob& aSeekJob)
+                   const SeekTarget& aTarget)
   : mDecoderID(aDecoderID)
   , mOwnerThread(aThread)
   , mReader(aReader)
-  , mTarget(aSeekJob.mTarget)
+  , mTarget(aTarget)
   , mIsDiscarded(false)
   , mIsAudioQueueFinished(false)
   , mIsVideoQueueFinished(false)
   , mNeedToStopPrerollingAudio(false)
   , mNeedToStopPrerollingVideo(false)
 {
   AssertOwnerThread();
 }
@@ -71,16 +71,16 @@ SeekTask::AssertOwnerThread() const
 
 AbstractThread*
 SeekTask::OwnerThread() const
 {
   AssertOwnerThread();
   return mOwnerThread;
 }
 
-SeekTarget&
+const SeekTarget&
 SeekTask::GetSeekTarget()
 {
   AssertOwnerThread();
   return mTarget;
 }
 
 } // namespace mozilla
--- a/dom/media/SeekTask.h
+++ b/dom/media/SeekTask.h
@@ -51,23 +51,23 @@ public:
     MozPromise<SeekTaskResolveValue, SeekTaskRejectValue, IsExclusive>;
 
   virtual void Discard() = 0;
 
   virtual RefPtr<SeekTaskPromise> Seek(const media::TimeUnit& aDuration) = 0;
 
   virtual bool NeedToResetMDSM() const = 0;
 
-  SeekTarget& GetSeekTarget();
+  const SeekTarget& GetSeekTarget();
 
 protected:
   SeekTask(const void* aDecoderID,
            AbstractThread* aThread,
            MediaDecoderReaderWrapper* aReader,
-           SeekJob& aSeekJob);
+           const SeekTarget& aTarget);
 
   virtual ~SeekTask();
 
   void Resolve(const char* aCallSite);
 
   void RejectIfExist(const char* aCallSite);
 
   void AssertOwnerThread() const;
@@ -79,17 +79,17 @@ protected:
    */
   const void* mDecoderID; // For logging.
   const RefPtr<AbstractThread> mOwnerThread;
   const RefPtr<MediaDecoderReaderWrapper> mReader;
 
   /*
    * Internal state.
    */
-  SeekTarget& mTarget;
+  SeekTarget mTarget;
   MozPromiseHolder<SeekTaskPromise> mSeekTaskPromise;
   bool mIsDiscarded;
 
   /*
    * Information which are going to be returned to MDSM.
    */
   RefPtr<MediaData> mSeekedAudioData;
   RefPtr<MediaData> mSeekedVideoData;