Bug 1312886: P4. Override MediaResource reporting if we have a pending promise. r?jwwang draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Thu, 27 Oct 2016 20:19:42 +1100
changeset 430761 dac3a29045f5ccb94e2f0aec9e3f7921b06945bc
parent 430760 0a04be673e532be63c8f8996371d6eb7cf2028b5
child 430762 bd3d1568275267cf97ec1b2d0a8ac1666e38b463
push id33879
push userbmo:jyavenard@mozilla.com
push dateFri, 28 Oct 2016 03:36:01 +0000
reviewersjwwang
bugs1312886
milestone52.0a1
Bug 1312886: P4. Override MediaResource reporting if we have a pending promise. r?jwwang A future use will see the MediaFormatReader using waiting promise to indicate that the decoders are waiting for an EME key. We should always enter buffering mode once we're low on data and we're waiting on a key. MozReview-Commit-ID: DFcT6YEK1Ke
dom/media/MediaDecoderStateMachine.cpp
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -225,16 +225,24 @@ public:
 
 protected:
   using Master = MediaDecoderStateMachine;
   explicit StateObject(Master* aPtr) : mMaster(aPtr) {}
   TaskQueue* OwnerThread() const { return mMaster->mTaskQueue; }
   MediaResource* Resource() const { return mMaster->mResource; }
   MediaDecoderReaderWrapper* Reader() const { return mMaster->mReader; }
   const MediaInfo& Info() const { return mMaster->Info(); }
+  bool IsExpectingMoreData() const
+  {
+    // We are expecting more data if either the resource states so, or if we
+    // have a waiting promise pending (such as with non-MSE EME).
+    return Resource()->IsExpectingMoreData() ||
+           (Reader()->IsWaitForDataSupported() &&
+            (Reader()->IsWaitingAudioData() || Reader()->IsWaitingVideoData()));
+  }
 
   // Note this function will delete the current state object.
   // Don't access members to avoid UAF after this call.
   template <class S, typename... Ts>
   auto SetState(Ts... aArgs)
     -> decltype(DeclVal<S>().Enter(Move(aArgs)...))
   {
     // keep mMaster in a local object because mMaster will become invalid after
@@ -1466,17 +1474,17 @@ DecodingState::MaybeStartBuffering()
   // Don't enter buffering while prerolling so that the decoder has a chance to
   // enqueue some decoded data before we give up and start buffering.
   if (!mMaster->IsPlaying()) {
     return;
   }
 
   bool shouldBuffer;
   if (Reader()->UseBufferingHeuristics()) {
-    shouldBuffer = Resource()->IsExpectingMoreData() &&
+    shouldBuffer = IsExpectingMoreData() &&
                    mMaster->HasLowDecodedData() &&
                    mMaster->HasLowBufferedData();
   } else {
     MOZ_ASSERT(Reader()->IsWaitForDataSupported());
     shouldBuffer =
       (mMaster->OutOfDecodedAudio() && Reader()->IsWaitingAudioData()) ||
       (mMaster->OutOfDecodedVideo() && Reader()->IsWaitingVideoData());
   }
@@ -1606,17 +1614,17 @@ BufferingState::Step()
   // we've not decoded enough data to begin playback, or if we've not
   // downloaded a reasonable amount of data inside our buffering time.
   if (Reader()->UseBufferingHeuristics()) {
     TimeDuration elapsed = now - mBufferingStart;
     bool isLiveStream = Resource()->IsLiveStream();
     if ((isLiveStream || !mMaster->CanPlayThrough()) &&
         elapsed < TimeDuration::FromSeconds(mBufferingWait * mMaster->mPlaybackRate) &&
         mMaster->HasLowBufferedData(mBufferingWait * USECS_PER_S) &&
-        Resource()->IsExpectingMoreData()) {
+        IsExpectingMoreData()) {
       SLOG("Buffering: wait %ds, timeout in %.3lfs",
            mBufferingWait, mBufferingWait - elapsed.ToSeconds());
       mMaster->ScheduleStateMachineIn(USECS_PER_S);
       return;
     }
   } else if (mMaster->OutOfDecodedAudio() || mMaster->OutOfDecodedVideo()) {
     MOZ_ASSERT(Reader()->IsWaitForDataSupported(),
                "Don't yet have a strategy for non-heuristic + non-WaitForData");