Bug 1129523 - Use ProxyMediaCall for video decode tasks. r=cpearce,r=mattwoodrow a=lhenry
authorBobby Holley <bobbyholley@gmail.com>
Wed, 04 Feb 2015 17:12:51 -0800
changeset 249791 c7855054fc6838f1e7f4207c170e70c72c0f47af
parent 249790 3339344d02a5da9e7216342cd093d6b083ac29e7
child 249792 dc9a1813588e6fc08321aa54ef59c83ee551e63f
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce, mattwoodrow, lhenry
bugs1129523
milestone37.0a2
Bug 1129523 - Use ProxyMediaCall for video decode tasks. r=cpearce,r=mattwoodrow a=lhenry
dom/media/MediaDecoderStateMachine.cpp
dom/media/MediaDecoderStateMachine.h
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -652,52 +652,16 @@ MediaDecoderStateMachine::NeedToSkipToNe
     DECODER_LOG("Skipping video decode to the next keyframe lowAudio=%d lowVideo=%d lowUndecoded=%d async=%d",
                 isLowOnDecodedAudio, isLowOnDecodedVideo, lowUndecoded, mReader->IsAsync());
     return true;
   }
 
   return false;
 }
 
-void
-MediaDecoderStateMachine::DecodeVideo()
-{
-  int64_t currentTime = 0;
-  bool skipToNextKeyFrame = false;
-  {
-    ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-    NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
-
-    if (mState != DECODER_STATE_DECODING &&
-        mState != DECODER_STATE_DECODING_FIRSTFRAME &&
-        mState != DECODER_STATE_BUFFERING &&
-        mState != DECODER_STATE_SEEKING) {
-      mVideoRequestStatus = RequestStatus::Idle;
-      DispatchDecodeTasksIfNeeded();
-      return;
-    }
-
-    skipToNextKeyFrame = NeedToSkipToNextKeyframe();
-    currentTime = mState == DECODER_STATE_SEEKING ? 0 : GetMediaTime();
-
-    // Time the video decode, so that if it's slow, we can increase our low
-    // audio threshold to reduce the chance of an audio underrun while we're
-    // waiting for a video decode to complete.
-    mVideoDecodeStartTime = TimeStamp::Now();
-  }
-
-  SAMPLE_LOG("DecodeVideo() queued=%i, decoder-queued=%o, skip=%i, time=%lld",
-             VideoQueue().GetSize(), mReader->SizeOfVideoQueueInFrames(), skipToNextKeyFrame, currentTime);
-
-  mReader->RequestVideoData(skipToNextKeyFrame, currentTime)
-         ->Then(DecodeTaskQueue(), __func__, this,
-                &MediaDecoderStateMachine::OnVideoDecoded,
-                &MediaDecoderStateMachine::OnVideoNotDecoded);
-}
-
 bool
 MediaDecoderStateMachine::NeedToDecodeAudio()
 {
   AssertCurrentThreadInMonitor();
   SAMPLE_LOG("NeedToDecodeAudio() isDec=%d decToTar=%d minPrl=%d seek=%d enufAud=%d",
              IsAudioDecoding(), mDecodeToSeekTarget, mMinimizePreroll,
              mState == DECODER_STATE_SEEKING,
              HaveEnoughDecodedAudio(mAmpleAudioThresholdUsecs * mPlaybackRate));
@@ -706,42 +670,16 @@ MediaDecoderStateMachine::NeedToDecodeAu
          ((mState == DECODER_STATE_SEEKING && mDecodeToSeekTarget) ||
           (mState == DECODER_STATE_DECODING_FIRSTFRAME &&
            IsAudioDecoding() && AudioQueue().GetSize() == 0) ||
           (!mMinimizePreroll &&
           !HaveEnoughDecodedAudio(mAmpleAudioThresholdUsecs * mPlaybackRate) &&
           (mState != DECODER_STATE_SEEKING || mDecodeToSeekTarget)));
 }
 
-void
-MediaDecoderStateMachine::DecodeAudio()
-{
-  {
-    ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-    NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
-
-    if (mState != DECODER_STATE_DECODING &&
-        mState != DECODER_STATE_DECODING_FIRSTFRAME &&
-        mState != DECODER_STATE_BUFFERING &&
-        mState != DECODER_STATE_SEEKING) {
-      mAudioRequestStatus = RequestStatus::Idle;
-      DispatchDecodeTasksIfNeeded();
-      mon.NotifyAll();
-      return;
-    }
-  }
-
-  SAMPLE_LOG("DecodeAudio() queued=%i, decoder-queued=%o",
-             AudioQueue().GetSize(), mReader->SizeOfAudioQueueInFrames());
-
-  mReader->RequestAudioData()->Then(DecodeTaskQueue(), __func__, this,
-                                    &MediaDecoderStateMachine::OnAudioDecoded,
-                                    &MediaDecoderStateMachine::OnAudioNotDecoded);
-}
-
 bool
 MediaDecoderStateMachine::IsAudioSeekComplete()
 {
   AssertCurrentThreadInMonitor();
   SAMPLE_LOG("IsAudioSeekComplete() curTarVal=%d mAudDis=%d aqFin=%d aqSz=%d",
     mCurrentSeekTarget.IsValid(), mDropAudioUntilNextDiscontinuity, AudioQueue().IsFinished(), AudioQueue().GetSize());
   return
     !HasAudio() ||
@@ -1984,32 +1922,35 @@ MediaDecoderStateMachine::EnsureAudioDec
 {
   AssertCurrentThreadInMonitor();
   NS_ASSERTION(OnStateMachineThread() || OnDecodeThread(),
                "Should be on state machine or decode thread.");
 
   SAMPLE_LOG("EnsureAudioDecodeTaskQueued isDecoding=%d status=%d",
               IsAudioDecoding(), mAudioRequestStatus);
 
-  if (mState >= DECODER_STATE_COMPLETED || mState == DECODER_STATE_DORMANT) {
+  if (mState != DECODER_STATE_DECODING &&
+      mState != DECODER_STATE_DECODING_FIRSTFRAME &&
+      mState != DECODER_STATE_BUFFERING &&
+      mState != DECODER_STATE_SEEKING) {
+    return NS_OK;
+  }
+
+  if (!IsAudioDecoding() || mAudioRequestStatus != RequestStatus::Idle || mWaitingForDecoderSeek) {
     return NS_OK;
   }
 
-  MOZ_ASSERT(mState >= DECODER_STATE_DECODING_FIRSTFRAME);
-
-  if (IsAudioDecoding() && mAudioRequestStatus == RequestStatus::Idle && !mWaitingForDecoderSeek) {
-    RefPtr<nsIRunnable> task(
-      NS_NewRunnableMethod(this, &MediaDecoderStateMachine::DecodeAudio));
-    nsresult rv = DecodeTaskQueue()->Dispatch(task);
-    if (NS_SUCCEEDED(rv)) {
-      mAudioRequestStatus = RequestStatus::Pending;
-    } else {
-      DECODER_WARN("Failed to dispatch task to decode audio");
-    }
-  }
+  SAMPLE_LOG("Queueing audio task - queued=%i, decoder-queued=%o",
+             AudioQueue().GetSize(), mReader->SizeOfAudioQueueInFrames());
+
+  mAudioRequestStatus = RequestStatus::Pending;
+  ProxyMediaCall(DecodeTaskQueue(), mReader.get(), __func__, &MediaDecoderReader::RequestAudioData)
+    ->Then(DecodeTaskQueue(), __func__, this,
+           &MediaDecoderStateMachine::OnAudioDecoded,
+           &MediaDecoderStateMachine::OnAudioNotDecoded);
 
   return NS_OK;
 }
 
 nsresult
 MediaDecoderStateMachine::DispatchVideoDecodeTaskIfNeeded()
 {
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
@@ -2029,32 +1970,45 @@ MediaDecoderStateMachine::EnsureVideoDec
   AssertCurrentThreadInMonitor();
 
   SAMPLE_LOG("EnsureVideoDecodeTaskQueued isDecoding=%d status=%d",
              IsVideoDecoding(), mVideoRequestStatus);
 
   NS_ASSERTION(OnStateMachineThread() || OnDecodeThread(),
                "Should be on state machine or decode thread.");
 
-  if (mState >= DECODER_STATE_COMPLETED || mState == DECODER_STATE_DORMANT) {
+  if (mState != DECODER_STATE_DECODING &&
+      mState != DECODER_STATE_DECODING_FIRSTFRAME &&
+      mState != DECODER_STATE_BUFFERING &&
+      mState != DECODER_STATE_SEEKING) {
+    return NS_OK;
+  }
+
+  if (!IsVideoDecoding() || mVideoRequestStatus != RequestStatus::Idle || mWaitingForDecoderSeek) {
     return NS_OK;
   }
 
-  MOZ_ASSERT(mState >= DECODER_STATE_DECODING_FIRSTFRAME);
-
-  if (IsVideoDecoding() && mVideoRequestStatus == RequestStatus::Idle && !mWaitingForDecoderSeek) {
-    RefPtr<nsIRunnable> task(
-      NS_NewRunnableMethod(this, &MediaDecoderStateMachine::DecodeVideo));
-    nsresult rv = DecodeTaskQueue()->Dispatch(task);
-    if (NS_SUCCEEDED(rv)) {
-      mVideoRequestStatus = RequestStatus::Pending;
-    } else {
-      DECODER_WARN("Failed to dispatch task to decode video");
-    }
-  }
+  bool skipToNextKeyFrame = NeedToSkipToNextKeyframe();
+  int64_t currentTime = mState == DECODER_STATE_SEEKING ? 0 : GetMediaTime();
+
+  // Time the video decode, so that if it's slow, we can increase our low
+  // audio threshold to reduce the chance of an audio underrun while we're
+  // waiting for a video decode to complete.
+  mVideoDecodeStartTime = TimeStamp::Now();
+
+  SAMPLE_LOG("Queueing video task - queued=%i, decoder-queued=%o, skip=%i, time=%lld",
+             VideoQueue().GetSize(), mReader->SizeOfVideoQueueInFrames(), skipToNextKeyFrame,
+             currentTime);
+
+  mVideoRequestStatus = RequestStatus::Pending;
+  ProxyMediaCall(DecodeTaskQueue(), mReader.get(), __func__,
+                 &MediaDecoderReader::RequestVideoData, skipToNextKeyFrame, currentTime)
+    ->Then(DecodeTaskQueue(), __func__, this,
+           &MediaDecoderStateMachine::OnVideoDecoded,
+           &MediaDecoderStateMachine::OnVideoNotDecoded);
 
   return NS_OK;
 }
 
 nsresult
 MediaDecoderStateMachine::StartAudioThread()
 {
   NS_ASSERTION(OnStateMachineThread() || OnDecodeThread(),
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -484,26 +484,20 @@ protected:
   nsresult FinishDecodeFirstFrame();
 
   nsAutoPtr<MetadataTags> mMetadataTags;
 
   // True if our buffers of decoded audio are not full, and we should
   // decode more.
   bool NeedToDecodeAudio();
 
-  // Decodes some audio. This should be run on the decode task queue.
-  void DecodeAudio();
-
   // True if our buffers of decoded video are not full, and we should
   // decode more.
   bool NeedToDecodeVideo();
 
-  // Decodes some video. This should be run on the decode task queue.
-  void DecodeVideo();
-
   // Returns true if we've got less than aAudioUsecs microseconds of decoded
   // and playable data. The decoder monitor must be held.
   //
   // May not be invoked when mReader->UseBufferingHeuristics() is false.
   bool HasLowDecodedData(int64_t aAudioUsecs);
 
   bool OutOfDecodedAudio()
   {