Bug 1352319. P9 - let GetMediaTime() return a TimeUnit. draft
authorJW Wang <jwwang@mozilla.com>
Tue, 28 Mar 2017 16:16:56 +0800
changeset 554258 213b4b7990665925643ff2ae48f0a5dd38320ff3
parent 554257 a69e913e906c619f0f829b7829df21ee7d38eb77
child 554259 21c4c340c9bf7c112fb71e8cf78db5526a306466
push id51883
push userjwwang@mozilla.com
push dateFri, 31 Mar 2017 09:16:07 +0000
bugs1352319
milestone55.0a1
Bug 1352319. P9 - let GetMediaTime() return a TimeUnit. MozReview-Commit-ID: 7vrIzeMLP4Z
dom/media/MediaDecoderStateMachine.cpp
dom/media/MediaDecoderStateMachine.h
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -483,18 +483,18 @@ public:
 
   void Enter()
   {
     if (mMaster->IsPlaying()) {
       mMaster->StopPlayback();
     }
 
     // Calculate the position to seek to when exiting dormant.
-    auto t = mMaster->mMediaSink->IsStarted() ? mMaster->GetClock()
-                                              : mMaster->GetMediaTime();
+    auto t = mMaster->mMediaSink->IsStarted()
+      ? mMaster->GetClock() : mMaster->GetMediaTime().ToMicroseconds();
     mPendingSeek.mTarget.emplace(t, SeekTarget::Accurate);
     // SeekJob asserts |mTarget.IsValid() == !mPromise.IsEmpty()| so we
     // need to create the promise even it is not used at all.
     RefPtr<MediaDecoder::SeekPromise> x =
       mPendingSeek.mPromise.Ensure(__func__);
 
     mMaster->ResetDecode();
     mMaster->StopMediaSink();
@@ -722,18 +722,17 @@ public:
   void HandleAudioCanceled() override
   {
     mMaster->RequestAudioData();
   }
 
   void HandleVideoCanceled() override
   {
     mMaster->RequestVideoData(
-      NeedToSkipToNextKeyframe(),
-      media::TimeUnit::FromMicroseconds(mMaster->GetMediaTime()));
+      NeedToSkipToNextKeyframe(), mMaster->GetMediaTime());
   }
 
   void HandleEndOfAudio() override;
   void HandleEndOfVideo() override;
 
   void HandleWaitingForAudio() override
   {
     mMaster->WaitForData(MediaData::AUDIO_DATA);
@@ -749,18 +748,17 @@ public:
   void HandleAudioWaited(MediaData::Type aType) override
   {
     mMaster->RequestAudioData();
   }
 
   void HandleVideoWaited(MediaData::Type aType) override
   {
     mMaster->RequestVideoData(
-      NeedToSkipToNextKeyframe(),
-      media::TimeUnit::FromMicroseconds(mMaster->GetMediaTime()));
+      NeedToSkipToNextKeyframe(), mMaster->GetMediaTime());
   }
 
   void HandleAudioCaptured() override
   {
     MaybeStopPrerolling();
     // MediaSink is changed. Schedule Step() to check if we can start playback.
     mMaster->ScheduleStateMachine();
   }
@@ -1023,18 +1021,17 @@ public:
   explicit AccurateSeekingState(Master* aPtr) : SeekingState(aPtr)
   {
   }
 
   RefPtr<MediaDecoder::SeekPromise> Enter(SeekJob&& aSeekJob,
                                           EventVisibility aVisibility)
   {
     MOZ_ASSERT(aSeekJob.mTarget->IsAccurate() || aSeekJob.mTarget->IsFast());
-    mCurrentTimeBeforeSeek =
-      TimeUnit::FromMicroseconds(mMaster->GetMediaTime());
+    mCurrentTimeBeforeSeek = mMaster->GetMediaTime();
     return SeekingState::Enter(Move(aSeekJob), aVisibility);
   }
 
   void Exit() override
   {
     // Disconnect MediaDecoder.
     mSeekJob.RejectIfExists(__func__);
 
@@ -1482,17 +1479,17 @@ public:
   explicit NextFrameSeekingState(Master* aPtr) : SeekingState(aPtr)
   {
   }
 
   RefPtr<MediaDecoder::SeekPromise> Enter(SeekJob&& aSeekJob,
                                           EventVisibility aVisibility)
   {
     MOZ_ASSERT(aSeekJob.mTarget->IsNextFrame());
-    mCurrentTime = mMaster->GetMediaTime();
+    mCurrentTime = mMaster->GetMediaTime().ToMicroseconds();
     mDuration = mMaster->Duration();
     return SeekingState::Enter(Move(aSeekJob), aVisibility);
   }
 
   void Exit() override
   {
     // Disconnect my async seek operation.
     mAsyncSeekTask->Cancel();
@@ -2280,18 +2277,17 @@ MediaDecoderStateMachine::
 DecodingState::EnsureVideoDecodeTaskQueued()
 {
   if (!mMaster->IsVideoDecoding()
       || mMaster->IsRequestingVideoData()
       || mMaster->IsWaitingVideoData()) {
     return;
   }
   mMaster->RequestVideoData(
-    NeedToSkipToNextKeyframe(),
-    media::TimeUnit::FromMicroseconds(mMaster->GetMediaTime()));
+    NeedToSkipToNextKeyframe(), mMaster->GetMediaTime());
 }
 
 bool
 MediaDecoderStateMachine::
 DecodingState::NeedToSkipToNextKeyframe()
 {
   // Since GetClock() can only be called after starting MediaSink, we return
   // false quickly if it is not started because we won't fall behind playback
@@ -2722,17 +2718,17 @@ MediaDecoderStateMachine::AudioAudibleCh
 media::MediaSink*
 MediaDecoderStateMachine::CreateAudioSink()
 {
   RefPtr<MediaDecoderStateMachine> self = this;
   auto audioSinkCreator = [self] () {
     MOZ_ASSERT(self->OnTaskQueue());
     AudioSink* audioSink = new AudioSink(
       self->mTaskQueue, self->mAudioQueue,
-      TimeUnit::FromMicroseconds(self->GetMediaTime()),
+      self->GetMediaTime(),
       self->Info().mAudio, self->mAudioChannel);
 
     self->mAudibleListener = audioSink->AudibleEvent().Connect(
       self->mTaskQueue, self.get(),
       &MediaDecoderStateMachine::AudioAudibleChanged);
     return audioSink;
   };
   return new AudioSinkWrapper(mTaskQueue, audioSinkCreator);
@@ -2926,18 +2922,18 @@ MediaDecoderStateMachine::UpdatePlayback
 }
 
 void
 MediaDecoderStateMachine::UpdatePlaybackPosition(const TimeUnit& aTime)
 {
   MOZ_ASSERT(OnTaskQueue());
   UpdatePlaybackPositionInternal(aTime);
 
-  bool fragmentEnded =
-    mFragmentEndTime >= 0 && GetMediaTime() >= mFragmentEndTime;
+  bool fragmentEnded = mFragmentEndTime >= 0
+    && GetMediaTime().ToMicroseconds() >= mFragmentEndTime;
   mMetadataManager.DispatchMetadataIfNeeded(aTime);
 
   if (fragmentEnded) {
     StopPlayback();
   }
 }
 
 /* static */ const char*
@@ -3272,17 +3268,17 @@ MediaDecoderStateMachine::WaitForData(Me
 }
 
 void
 MediaDecoderStateMachine::StartMediaSink()
 {
   MOZ_ASSERT(OnTaskQueue());
   if (!mMediaSink->IsStarted()) {
     mAudioCompleted = false;
-    mMediaSink->Start(TimeUnit::FromMicroseconds(GetMediaTime()), Info());
+    mMediaSink->Start(GetMediaTime(), Info());
 
     auto videoPromise = mMediaSink->OnEnded(TrackInfo::kVideoTrack);
     auto audioPromise = mMediaSink->OnEnded(TrackInfo::kAudioTrack);
 
     if (audioPromise) {
       audioPromise->Then(
         OwnerThread(), __func__, this,
         &MediaDecoderStateMachine::OnMediaSinkAudioComplete,
@@ -3371,18 +3367,17 @@ MediaDecoderStateMachine::HasLowBuffered
   }
 
   if (endOfDecodedData.IsInfinite()) {
     // Have decoded all samples. No point buffering.
     return false;
   }
 
   auto start = endOfDecodedData;
-  auto end = std::min(
-    TimeUnit::FromMicroseconds(GetMediaTime()) + aThreshold, Duration());
+  auto end = std::min(GetMediaTime() + aThreshold, Duration());
   if (start >= end) {
     // Duration of decoded samples is greater than our threshold.
     return false;
   }
   media::TimeInterval interval(start, end);
   return !mBuffered.Ref().Contains(interval);
 }
 
@@ -3498,49 +3493,49 @@ MediaDecoderStateMachine::ResetDecode(Tr
 
   mReader->ResetDecode(aTracks);
 }
 
 int64_t
 MediaDecoderStateMachine::GetClock(TimeStamp* aTimeStamp) const
 {
   MOZ_ASSERT(OnTaskQueue());
-  int64_t clockTime = mMediaSink->GetPosition(aTimeStamp).ToMicroseconds();
+  auto clockTime = mMediaSink->GetPosition(aTimeStamp);
   NS_ASSERTION(GetMediaTime() <= clockTime, "Clock should go forwards.");
-  return clockTime;
+  return clockTime.ToMicroseconds();
 }
 
 void
 MediaDecoderStateMachine::UpdatePlaybackPositionPeriodically()
 {
   MOZ_ASSERT(OnTaskQueue());
 
   if (!IsPlaying()) {
     return;
   }
 
   // Cap the current time to the larger of the audio and video end time.
   // This ensures that if we're running off the system clock, we don't
   // advance the clock to after the media end time.
   if (VideoEndTime() > TimeUnit::Zero() || AudioEndTime() > TimeUnit::Zero()) {
 
-    const int64_t clockTime = GetClock();
+    const auto clockTime = TimeUnit::FromMicroseconds(GetClock());
     // Skip frames up to the frame at the playback position, and figure out
     // the time remaining until it's time to display the next frame and drop
     // the current frame.
-    NS_ASSERTION(clockTime >= 0, "Should have positive clock time.");
+    NS_ASSERTION(clockTime >= TimeUnit::Zero(), "Should have positive clock time.");
 
     // These will be non -1 if we've displayed a video frame, or played an audio
     // frame.
     auto maxEndTime = std::max(VideoEndTime(), AudioEndTime());
-    int64_t t = std::min(clockTime, maxEndTime.ToMicroseconds());
+    auto t = std::min(clockTime, maxEndTime);
     // FIXME: Bug 1091422 - chained ogg files hit this assertion.
     //MOZ_ASSERT(t >= GetMediaTime());
     if (t > GetMediaTime()) {
-      UpdatePlaybackPosition(TimeUnit::FromMicroseconds(t));
+      UpdatePlaybackPosition(t);
     }
   }
   // Note we have to update playback position before releasing the monitor.
   // Otherwise, MediaDecoder::AddOutputStream could kick in when we are outside
   // the monitor and get a staled value from GetCurrentTimeUs() which hits the
   // assertion in GetClock().
 
   int64_t delay = std::max<int64_t>(1, AUDIO_DURATION_USECS / mPlaybackRate);
@@ -3829,17 +3824,18 @@ MediaDecoderStateMachine::GetDebugInfo()
   MOZ_ASSERT(OnTaskQueue());
   return nsPrintfCString(
            "MediaDecoderStateMachine State: GetMediaTime=%" PRId64 " GetClock="
            "%" PRId64 " mMediaSink=%p state=%s mPlayState=%d "
            "mSentFirstFrameLoadedEvent=%d IsPlaying=%d mAudioStatus=%s "
            "mVideoStatus=%s mDecodedAudioEndTime=%" PRId64
            " mDecodedVideoEndTime=%" PRId64 "mAudioCompleted=%d "
            "mVideoCompleted=%d",
-           GetMediaTime(), mMediaSink->IsStarted() ? GetClock() : -1,
+           GetMediaTime().ToMicroseconds(),
+           mMediaSink->IsStarted() ? GetClock() : -1,
            mMediaSink.get(), ToStateStr(), mPlayState.Ref(),
            mSentFirstFrameLoadedEvent, IsPlaying(), AudioRequestStatus(),
            VideoRequestStatus(), mDecodedAudioEndTime, mDecodedVideoEndTime,
            mAudioCompleted, mVideoCompleted)
          + mStateObj->GetDebugInfo() + nsCString("\n")
          + mMediaSink->GetDebugInfo();
 }
 
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -443,20 +443,20 @@ protected:
   bool IsWaitingAudioData() const { return mAudioWaitRequest.Exists(); }
   bool IsWaitingVideoData() const { return mVideoWaitRequest.Exists(); }
 
   // Returns the "media time". This is the absolute time which the media
   // playback has reached. i.e. this returns values in the range
   // [mStartTime, mEndTime], and mStartTime will not be 0 if the media does
   // not start at 0. Note this is different than the "current playback position",
   // which is in the range [0,duration].
-  int64_t GetMediaTime() const
+  media::TimeUnit GetMediaTime() const
   {
     MOZ_ASSERT(OnTaskQueue());
-    return mCurrentPosition;
+    return media::TimeUnit::FromMicroseconds(mCurrentPosition.Ref());
   }
 
   // Returns an upper bound on the number of microseconds of audio that is
   // decoded and playable. This is the sum of the number of usecs of audio which
   // is decoded and in the reader's audio queue, and the usecs of unplayed audio
   // which has been pushed to the audio hardware for playback. Note that after
   // calling this, the audio hardware may play some of the audio pushed to
   // hardware, so this can only be used as a upper bound. The decoder monitor