Bug 1325003 - Remove NextFrameSeekTask again; r?jwwang draft
authorKaku Kuo <kaku@mozilla.com>
Wed, 21 Dec 2016 15:36:37 +0800 (2016-12-21)
changeset 452198 fbe133939aac67ffc8e523112783d932a032c1e3
parent 452146 c36fbe84042debef0a5d58b7fc88185b401762ce
child 540180 a8377962a515308cf5526d09d22d8ca0d62bb705
push id39352
push userbmo:kaku@mozilla.com
push dateWed, 21 Dec 2016 09:58:31 +0000 (2016-12-21)
reviewersjwwang
bugs1325003
milestone53.0a1
Bug 1325003 - Remove NextFrameSeekTask again; r?jwwang MozReview-Commit-ID: 9tdeCHJ2kxa
dom/media/NextFrameSeekTask.cpp
dom/media/NextFrameSeekTask.h
dom/media/SeekTask.h
deleted file mode 100644
--- a/dom/media/NextFrameSeekTask.cpp
+++ /dev/null
@@ -1,327 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "NextFrameSeekTask.h"
-#include "MediaDecoderReaderWrapper.h"
-#include "mozilla/AbstractThread.h"
-#include "mozilla/Assertions.h"
-#include "nsPrintfCString.h"
-
-namespace mozilla {
-
-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,
-                                     const SeekTarget& aTarget,
-                                     const MediaInfo& aInfo,
-                                     const media::TimeUnit& aDuration,
-                                     int64_t aCurrentTime,
-                                     MediaQueue<MediaData>& aAudioQueue,
-                                     MediaQueue<MediaData>& aVideoQueue)
-  : SeekTask(aDecoderID, aThread, aReader, aTarget)
-  , mAudioQueue(aAudioQueue)
-  , mVideoQueue(aVideoQueue)
-  , mCurrentTime(aCurrentTime)
-  , mDuration(aDuration)
-{
-  AssertOwnerThread();
-  MOZ_ASSERT(aInfo.HasVideo());
-}
-
-NextFrameSeekTask::~NextFrameSeekTask()
-{
-  AssertOwnerThread();
-  MOZ_ASSERT(mIsDiscarded);
-}
-
-void
-NextFrameSeekTask::Discard()
-{
-  AssertOwnerThread();
-
-  // Disconnect MDSM.
-  RejectIfExist(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
-
-  mIsDiscarded = true;
-}
-
-int64_t
-NextFrameSeekTask::CalculateNewCurrentTime() const
-{
-  AssertOwnerThread();
-
-  // The HTMLMediaElement.currentTime should be updated to the seek target
-  // which has been updated to the next frame's time.
-  return mTarget.GetTime().ToMicroseconds();
-}
-
-void
-NextFrameSeekTask::HandleAudioDecoded(MediaData* aAudio)
-{
-  AssertOwnerThread();
-  MOZ_ASSERT(aAudio);
-  MOZ_ASSERT(!mSeekTaskPromise.IsEmpty(), "Seek shouldn't be finished");
-
-  // The MDSM::mDecodedAudioEndTime will be updated once the whole SeekTask is
-  // resolved.
-
-  SAMPLE_LOG("OnAudioDecoded [%lld,%lld]", aAudio->mTime, aAudio->GetEndTime());
-
-  // We accept any audio data here.
-  mSeekedAudioData = aAudio;
-
-  MaybeFinishSeek();
-}
-
-void
-NextFrameSeekTask::HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart)
-{
-  AssertOwnerThread();
-  MOZ_ASSERT(aVideo);
-  MOZ_ASSERT(!mSeekTaskPromise.IsEmpty(), "Seek shouldn't be finished");
-
-  // The MDSM::mDecodedVideoEndTime will be updated once the whole SeekTask is
-  // resolved.
-
-  SAMPLE_LOG("OnVideoDecoded [%lld,%lld]", aVideo->mTime, aVideo->GetEndTime());
-
-  if (aVideo->mTime > mCurrentTime) {
-    mSeekedVideoData = aVideo;
-  }
-
-  if (NeedMoreVideo()) {
-    RequestVideoData();
-    return;
-  }
-
-  MaybeFinishSeek();
-}
-
-void
-NextFrameSeekTask::HandleNotDecoded(MediaData::Type aType, const MediaResult& aError)
-{
-  AssertOwnerThread();
-  switch (aType) {
-  case MediaData::AUDIO_DATA:
-  {
-    MOZ_ASSERT(!mSeekTaskPromise.IsEmpty(), "Seek shouldn't be finished");
-
-    SAMPLE_LOG("OnAudioNotDecoded (aError=%u)", aError.Code());
-
-    // We don't really handle audio deocde error here. Let MDSM to trigger further
-    // audio decoding tasks if it needs to play audio, and MDSM will then receive
-    // the decoding state from MediaDecoderReader.
-
-    MaybeFinishSeek();
-    break;
-  }
-  case MediaData::VIDEO_DATA:
-  {
-    MOZ_ASSERT(!mSeekTaskPromise.IsEmpty(), "Seek shouldn't be finished");
-
-    SAMPLE_LOG("OnVideoNotDecoded (aError=%u)", aError.Code());
-
-    if (aError == NS_ERROR_DOM_MEDIA_END_OF_STREAM) {
-      mIsVideoQueueFinished = true;
-    }
-
-    // Video seek not finished.
-    if (NeedMoreVideo()) {
-      switch (aError.Code()) {
-        case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
-          mReader->WaitForData(MediaData::VIDEO_DATA);
-          break;
-        case NS_ERROR_DOM_MEDIA_CANCELED:
-          RequestVideoData();
-          break;
-        case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
-          MOZ_ASSERT(false, "Shouldn't want more data for ended video.");
-          break;
-        default:
-          // Reject the promise since we can't finish video seek anyway.
-          RejectIfExist(aError, __func__);
-          break;
-      }
-      return;
-    }
-
-    MaybeFinishSeek();
-    break;
-  }
-  default:
-    MOZ_ASSERT_UNREACHABLE("We cannot handle RAW_DATA or NULL_DATA here.");
-  }
-}
-
-void
-NextFrameSeekTask::HandleAudioWaited(MediaData::Type aType)
-{
-  AssertOwnerThread();
-
-  // We don't make an audio decode request here, instead, let MDSM to
-  // trigger further audio decode tasks if MDSM itself needs to play audio.
-  MaybeFinishSeek();
-}
-
-void
-NextFrameSeekTask::HandleVideoWaited(MediaData::Type aType)
-{
-  AssertOwnerThread();
-
-  if (NeedMoreVideo()) {
-    RequestVideoData();
-    return;
-  }
-  MaybeFinishSeek();
-}
-
-void
-NextFrameSeekTask::HandleNotWaited(const WaitForDataRejectValue& aRejection)
-{
-  AssertOwnerThread();
-
-  switch(aRejection.mType) {
-  case MediaData::AUDIO_DATA:
-  {
-    // We don't make an audio decode request here, instead, let MDSM to
-    // trigger further audio decode tasks if MDSM itself needs to play audio.
-    MaybeFinishSeek();
-    break;
-  }
-  case MediaData::VIDEO_DATA:
-  {
-    if (NeedMoreVideo()) {
-      // Reject if we can't finish video seeking.
-      RejectIfExist(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
-      return;
-    }
-    MaybeFinishSeek();
-    break;
-  }
-  default:
-    MOZ_ASSERT_UNREACHABLE("We cannot handle RAW_DATA or NULL_DATA here.");
-  }
-}
-
-/*
- * Remove samples from the queue until aCompare() returns false.
- * aCompare A function object with the signature bool(int64_t) which returns
- *          true for samples that should be removed.
- */
-template <typename Function> static void
-DiscardFrames(MediaQueue<MediaData>& aQueue, const Function& aCompare)
-{
-  while(aQueue.GetSize() > 0) {
-    if (aCompare(aQueue.PeekFront()->mTime)) {
-      RefPtr<MediaData> releaseMe = aQueue.PopFront();
-      continue;
-    }
-    break;
-  }
-}
-
-RefPtr<NextFrameSeekTask::SeekTaskPromise>
-NextFrameSeekTask::Seek()
-{
-  AssertOwnerThread();
-
-  auto currentTime = mCurrentTime;
-  DiscardFrames(mVideoQueue, [currentTime] (int64_t aSampleTime) {
-    return aSampleTime <= currentTime;
-  });
-
-  RefPtr<SeekTaskPromise> promise = mSeekTaskPromise.Ensure(__func__);
-  if (!IsVideoRequestPending() && NeedMoreVideo()) {
-    RequestVideoData();
-  }
-  MaybeFinishSeek(); // Might resolve mSeekTaskPromise and modify audio queue.
-  return promise;
-}
-
-void
-NextFrameSeekTask::RequestVideoData()
-{
-  AssertOwnerThread();
-  mReader->RequestVideoData(false, media::TimeUnit());
-}
-
-bool
-NextFrameSeekTask::NeedMoreVideo() const
-{
-  AssertOwnerThread();
-  // Need to request video when we have none and video queue is not finished.
-  return mVideoQueue.GetSize() == 0 &&
-         !mSeekedVideoData &&
-         !mVideoQueue.IsFinished() &&
-         !mIsVideoQueueFinished;
-}
-
-bool
-NextFrameSeekTask::IsVideoRequestPending() const
-{
-  AssertOwnerThread();
-  return mReader->IsRequestingVideoData() || mReader->IsWaitingVideoData();
-}
-
-bool
-NextFrameSeekTask::IsAudioSeekComplete() const
-{
-  AssertOwnerThread();
-  // Don't finish seek until there are no pending requests. Otherwise, we might
-  // lose audio samples for the promise is resolved asynchronously.
-  return !mReader->IsRequestingAudioData() && !mReader->IsWaitingAudioData();
-}
-
-bool
-NextFrameSeekTask::IsVideoSeekComplete() const
-{
-  AssertOwnerThread();
-  // Don't finish seek until there are no pending requests. Otherwise, we might
-  // lose video samples for the promise is resolved asynchronously.
-  return !IsVideoRequestPending() && !NeedMoreVideo();
-}
-
-void
-NextFrameSeekTask::MaybeFinishSeek()
-{
-  AssertOwnerThread();
-  if (IsAudioSeekComplete() && IsVideoSeekComplete()) {
-    UpdateSeekTargetTime();
-
-    auto time = mTarget.GetTime().ToMicroseconds();
-    DiscardFrames(mAudioQueue, [time] (int64_t aSampleTime) {
-      return aSampleTime < time;
-    });
-
-    Resolve(__func__); // Call to MDSM::SeekCompleted();
-  }
-}
-
-void
-NextFrameSeekTask::UpdateSeekTargetTime()
-{
-  AssertOwnerThread();
-
-  RefPtr<MediaData> data = mVideoQueue.PeekFront();
-  if (data) {
-    mTarget.SetTime(TimeUnit::FromMicroseconds(data->mTime));
-  } else if (mSeekedVideoData) {
-    mTarget.SetTime(TimeUnit::FromMicroseconds(mSeekedVideoData->mTime));
-  } else if (mIsVideoQueueFinished || mVideoQueue.AtEndOfStream()) {
-    mTarget.SetTime(mDuration);
-  } else {
-    MOZ_ASSERT(false, "No data!");
-  }
-}
-} // namespace media
-} // namespace mozilla
deleted file mode 100644
--- a/dom/media/NextFrameSeekTask.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef NEXTFRAME_SEEK_TASK_H
-#define NEXTFRAME_SEEK_TASK_H
-
-#include "SeekTask.h"
-#include "MediaDecoderReader.h"
-
-namespace mozilla {
-namespace media {
-
-/*
- * While invoking a NextFrameSeekTask, we don't know the seek target time, what
- * we know is the media's currant position. We use the media's currant position
- * to find out what the next frame is, by traversing through the video queue or
- * asking the decoder to decode more video frames. Once we confirm the next
- * frame, we then know the target time of the NextFrameSeekTask and we update it
- * 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,
-                   const SeekTarget& aTarget,
-                   const MediaInfo& aInfo,
-                   const media::TimeUnit& aDuration,
-                   int64_t aCurrentTime,
-                   MediaQueue<MediaData>& aAudioQueue,
-                   MediaQueue<MediaData>& aVideoQueue);
-
-  void Discard() override;
-
-  RefPtr<SeekTaskPromise> Seek() override;
-
-  int64_t CalculateNewCurrentTime() const override;
-
-  void HandleAudioDecoded(MediaData* aAudio) override;
-
-  void HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) override;
-
-  void HandleNotDecoded(MediaData::Type aType, const MediaResult& aError) override;
-
-  void HandleAudioWaited(MediaData::Type aType) override;
-
-  void HandleVideoWaited(MediaData::Type aType) override;
-
-  void HandleNotWaited(const WaitForDataRejectValue& aRejection) override;
-
-  ~NextFrameSeekTask();
-
-  void RequestVideoData();
-
-  bool NeedMoreVideo() const;
-
-  bool IsVideoRequestPending() const;
-
-  bool IsAudioSeekComplete() const;
-
-  bool IsVideoSeekComplete() const;
-
-  void MaybeFinishSeek();
-
-  // Update the seek target's time before resolving this seek task, the updated
-  // time will be used in the MDSM::SeekCompleted() to update the MDSM's position.
-  void UpdateSeekTargetTime();
-
-  /*
-   * Data shared with MDSM.
-   */
-  MediaQueue<MediaData>& mAudioQueue;
-  MediaQueue<MediaData>& mVideoQueue;
-
-  /*
-   * Internal state.
-   */
-  const int64_t mCurrentTime;
-  media::TimeUnit mDuration;
-};
-
-} // namespace media
-} // namespace mozilla
-
-#endif /* NEXTFRAME_SEEK_TASK_H */
deleted file mode 100644
--- a/dom/media/SeekTask.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef SEEK_TASK_H
-#define SEEK_TASK_H
-
-#include "mozilla/MozPromise.h"
-#include "MediaData.h"          // For MediaData::Type.
-#include "MediaDecoderReader.h" // For WaitForDataRejectValue.
-#include "MediaResult.h"
-#include "SeekTarget.h"
-
-namespace mozilla {
-
-class AbstractThread;
-class MediaData;
-class MediaDecoderReaderWrapper;
-
-namespace media {
-class TimeUnit;
-}
-
-struct SeekTaskResolveValue
-{
-  RefPtr<MediaData> mSeekedAudioData;
-  RefPtr<MediaData> mSeekedVideoData;
-  bool mIsAudioQueueFinished;
-  bool mIsVideoQueueFinished;
-};
-
-struct SeekTaskRejectValue
-{
-  SeekTaskRejectValue()
-    : mIsAudioQueueFinished(false)
-    , mIsVideoQueueFinished(false)
-    , mError(NS_ERROR_DOM_MEDIA_FATAL_ERR)
-  {
-  }
-  bool mIsAudioQueueFinished;
-  bool mIsVideoQueueFinished;
-  MediaResult mError;
-};
-
-class SeekTask {
-
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SeekTask)
-
-public:
-  static const bool IsExclusive = true;
-
-  using SeekTaskPromise =
-    MozPromise<SeekTaskResolveValue, SeekTaskRejectValue, IsExclusive>;
-
-  virtual void Discard() = 0;
-
-  virtual RefPtr<SeekTaskPromise> Seek() = 0;
-
-  virtual int64_t CalculateNewCurrentTime() const = 0;
-
-  virtual void HandleAudioDecoded(MediaData* aAudio) = 0;
-
-  virtual void HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) = 0;
-
-  virtual void HandleNotDecoded(MediaData::Type aType, const MediaResult& aError) = 0;
-
-  virtual void HandleAudioWaited(MediaData::Type aType) = 0;
-
-  virtual void HandleVideoWaited(MediaData::Type aType) = 0;
-
-  virtual void HandleNotWaited(const WaitForDataRejectValue& aRejection) = 0;
-
-protected:
-  SeekTask(const void* aDecoderID,
-           AbstractThread* aThread,
-           MediaDecoderReaderWrapper* aReader,
-           const SeekTarget& aTarget);
-
-  virtual ~SeekTask();
-
-public:
-  void Resolve(const char* aCallSite);
-
-  void RejectIfExist(const MediaResult& aError, const char* aCallSite);
-
-  void AssertOwnerThread() const;
-
-  AbstractThread* OwnerThread() const;
-
-  /*
-   * Data shared with MDSM.
-   */
-  const void* mDecoderID; // For logging.
-  const RefPtr<AbstractThread> mOwnerThread;
-  const RefPtr<MediaDecoderReaderWrapper> mReader;
-
-  /*
-   * Internal state.
-   */
-  SeekTarget mTarget;
-  MozPromiseHolder<SeekTaskPromise> mSeekTaskPromise;
-  bool mIsDiscarded;
-
-  /*
-   * Information which are going to be returned to MDSM.
-   */
-  RefPtr<MediaData> mSeekedAudioData;
-  RefPtr<MediaData> mSeekedVideoData;
-  bool mIsAudioQueueFinished;
-  bool mIsVideoQueueFinished;
-};
-
-} // namespace mozilla
-
-#endif /* SEEK_TASK_H */