Bug 1313449 - Refactor the condition for resolving the waiting promise. draft
authorKilik Kuo <kikuo@mozilla.com>
Tue, 14 Nov 2017 15:20:08 +0800
changeset 697541 119a7097e38c3273ddb38f56234e5241bf88f51f
parent 695307 e2f87726b6082db0ae8a0866f65bff6b7062a07c
child 740154 b166a3d8c1082dff75f93d4e5f7b7676632eadee
push id89040
push userkikuo@mozilla.com
push dateTue, 14 Nov 2017 07:20:33 +0000
bugs1313449
milestone58.0a1
Bug 1313449 - Refactor the condition for resolving the waiting promise. The WaitForDataPromise cannot be resolved even when key has been updated and decode request has be resolved. 2 ScheduleUpdate(NotifyTrackDemuxer, NotifyNewOutput) are merged into 1 so that only mReceivedNewData is set to false again but MFR will never have a chance to trigger another Update to call CancelWaitingForKey. By refactoring the condition to resolve the WaitForDataPromise, MDSM is able to request new data and MFR is able to cancel waitingforkey then continue the flow. MozReview-Commit-ID: 31brwzOoUvF
dom/media/MediaFormatReader.cpp
dom/media/MediaFormatReader.h
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -2049,17 +2049,18 @@ MediaFormatReader::UpdateReceivedNewData
     ScheduleSeek();
     return true;
   }
   if (decoder.HasInternalSeekPending() || decoder.HasWaitingPromise()) {
     if (decoder.HasInternalSeekPending()) {
       LOG("Attempting Internal Seek");
       InternalSeek(aTrack, decoder.mTimeThreshold.ref());
     }
-    if (decoder.HasWaitingPromise() && !decoder.IsWaiting()) {
+    if (decoder.HasWaitingPromise() && !decoder.IsWaitingForKey() &&
+        !decoder.IsWaitingForData()) {
       MOZ_ASSERT(!decoder.HasPromise());
       LOG("We have new data. Resolving WaitingPromise");
       decoder.mWaitingPromise.Resolve(decoder.mType, __func__);
     }
     return true;
   }
   return false;
 }
@@ -2555,19 +2556,19 @@ MediaFormatReader::Update(TrackType aTra
        IsDecoderWaitingForCDM(aTrack));
 
   if (IsWaitingOnCDMResource() || !ResolveSetCDMPromiseIfDone(aTrack)) {
     // If the content is encrypted, MFR won't start to create decoder until
     // CDMProxy is set.
     return;
   }
 
-  if ((decoder.mWaitingForData &&
+  if ((decoder.IsWaitingForData() &&
        (!decoder.mTimeThreshold || decoder.mTimeThreshold.ref().mWaiting)) ||
-      (decoder.mWaitingForKey && decoder.mDecodeRequest.Exists())) {
+      (decoder.IsWaitingForKey())) {
     // Nothing more we can do at present.
     LOGV("Still waiting for data or key. data(%d)/key(%d)",
          decoder.mWaitingForData,
          decoder.mWaitingForKey);
     return;
   }
 
   if (decoder.CancelWaitingForKey()) {
@@ -2652,17 +2653,17 @@ MediaFormatReader::SizeOfQueue(TrackType
 
 RefPtr<MediaFormatReader::WaitForDataPromise>
 MediaFormatReader::WaitForData(MediaData::Type aType)
 {
   MOZ_ASSERT(OnTaskQueue());
   TrackType trackType = aType == MediaData::VIDEO_DATA ?
     TrackType::kVideoTrack : TrackType::kAudioTrack;
   auto& decoder = GetDecoderData(trackType);
-  if (!decoder.IsWaiting()) {
+  if (!decoder.IsWaitingForData() && !decoder.IsWaitingForKey()) {
     // We aren't waiting for anything.
     return WaitForDataPromise::CreateAndResolve(decoder.mType, __func__);
   }
   RefPtr<WaitForDataPromise> p = decoder.mWaitingPromise.Ensure(__func__);
   ScheduleUpdate(trackType);
   return p;
 }
 
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -416,20 +416,27 @@ private:
     // A WaitingPromise is pending if the demuxer is waiting for data or
     // if the decoder is waiting for a key.
     MozPromiseHolder<WaitForDataPromise> mWaitingPromise;
     bool HasWaitingPromise() const
     {
       MOZ_ASSERT(mOwner->OnTaskQueue());
       return !mWaitingPromise.IsEmpty();
     }
-    bool IsWaiting() const
+
+    bool IsWaitingForData() const
     {
       MOZ_ASSERT(mOwner->OnTaskQueue());
-      return mWaitingForData || mWaitingForKey;
+      return mWaitingForData;
+    }
+
+    bool IsWaitingForKey() const
+    {
+      MOZ_ASSERT(mOwner->OnTaskQueue());
+      return mWaitingForKey && mDecodeRequest.Exists();
     }
 
     // MediaDataDecoder handler's variables.
     MozPromiseRequestHolder<MediaDataDecoder::DecodePromise> mDecodeRequest;
     bool mFlushing; // True if flush is in action.
     // Set to true if the last operation run on the decoder was a flush.
     bool mFlushed;
     RefPtr<SharedShutdownPromiseHolder> mShutdownPromise;
@@ -516,17 +523,17 @@ private:
     void Flush();
 
     bool CancelWaitingForKey()
     {
       if (!mWaitingForKey) {
         return false;
       }
       mWaitingForKey = false;
-      if (IsWaiting() || !HasWaitingPromise()) {
+      if (IsWaitingForData() || !HasWaitingPromise()) {
         return false;
       }
       mWaitingPromise.Resolve(mType, __func__);
       return true;
     }
 
     // Reset the state of the DecoderData, clearing all queued frames
     // (pending demuxed and decoded).