Bug 882718 - triggerTimeMarchesOn. r=rillian
authorbechen <bechen@mozilla.com>
Wed, 01 Jun 2016 13:35:58 +0800
changeset 339134 639ff2d25ec31bfad97d636ec889bfbc49d84441
parent 339133 a12cd85eb79d0f93e62375f4731c6cbee82ce79e
child 339135 e130275a1db1bbdc0776e2a3a7d601b53cbdbc93
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrillian
bugs882718
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 882718 - triggerTimeMarchesOn. r=rillian MozReview-Commit-ID: 2OOqr1Z6X9
dom/html/HTMLMediaElement.h
dom/html/TextTrackManager.cpp
dom/html/TextTrackManager.h
dom/media/TextTrack.cpp
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -695,16 +695,21 @@ public:
     }
   }
 
   void AddCue(TextTrackCue& aCue) {
     if (mTextTrackManager) {
       mTextTrackManager->AddCue(aCue);
     }
   }
+  void NotifyCueRemoved(TextTrackCue& aCue) {
+    if (mTextTrackManager) {
+      mTextTrackManager->NotifyCueRemoved(aCue);
+    }
+  }
 
   /**
    * A public wrapper for FinishDecoderSetup()
    */
   nsresult FinishDecoderSetup(MediaDecoder* aDecoder, MediaResource* aStream) {
     return FinishDecoderSetup(aDecoder, aStream, nullptr);
   }
 
--- a/dom/html/TextTrackManager.cpp
+++ b/dom/html/TextTrackManager.cpp
@@ -167,32 +167,42 @@ TextTrackManager::AddCues(TextTrack* aTe
   }
 
   TextTrackCueList* cueList = aTextTrack->GetCues();
   if (cueList) {
     bool dummy;
     for (uint32_t i = 0; i < cueList->Length(); ++i) {
       mNewCues->AddCue(*cueList->IndexedGetter(i, dummy));
     }
+    DispatchTimeMarchesOn();
   }
 }
 
 void
 TextTrackManager::RemoveTextTrack(TextTrack* aTextTrack, bool aPendingListOnly)
 {
   if (!mPendingTextTracks || !mTextTracks) {
     return;
   }
 
   mPendingTextTracks->RemoveTextTrack(aTextTrack);
   if (aPendingListOnly) {
     return;
   }
 
   mTextTracks->RemoveTextTrack(aTextTrack);
+  // Remove the cues in mNewCues belong to aTextTrack.
+  TextTrackCueList* removeCueList = aTextTrack->GetCues();
+  if (removeCueList) {
+    for (uint32_t i = 0; i < removeCueList->Length(); ++i) {
+      ErrorResult dummyRv;
+      mNewCues->RemoveCue(*((*removeCueList)[i]), dummyRv);
+    }
+    DispatchTimeMarchesOn();
+  }
 }
 
 void
 TextTrackManager::DidSeek()
 {
   if (mTextTracks) {
     mTextTracks->DidSeek();
   }
@@ -230,24 +240,39 @@ TextTrackManager::UpdateCueDisplay()
 
     nsPIDOMWindowInner* window = mMediaElement->OwnerDoc()->GetInnerWindow();
     if (window) {
       sParserWrapper->ProcessCues(window, jsCues, overlay);
     }
   } else if (overlay->Length() > 0) {
     nsContentUtils::SetNodeTextContent(overlay, EmptyString(), true);
   }
+  // Call TimeMarchesOn() directly instead DispatchTimeMarchesOn()
+  // because we had render the new cue, so we must run
+  // TimeMarchesOn immediately.
+  TimeMarchesOn();
 }
 
 void
 TextTrackManager::AddCue(TextTrackCue& aCue)
 {
   if (mNewCues) {
     mNewCues->AddCue(aCue);
   }
+  DispatchTimeMarchesOn();
+}
+
+void
+TextTrackManager::NotifyCueRemoved(TextTrackCue& aCue)
+{
+  if (mNewCues) {
+    ErrorResult dummyRv;
+    mNewCues->RemoveCue(aCue, dummyRv);
+  }
+  DispatchTimeMarchesOn();
 }
 
 void
 TextTrackManager::PopulatePendingList()
 {
   if (!mTextTracks || !mPendingTextTracks || !mMediaElement) {
     return;
   }
@@ -502,30 +527,35 @@ TextTrackManager::TimeMarchesOn()
 
   nsISupports* parentObject =
     mMediaElement->OwnerDoc()->GetParentObject();
   if (NS_WARN_IF(!parentObject)) {
     return;
   }
   nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(parentObject);
 
+  if (mMediaElement && !(mMediaElement->GetPlayedOrSeeked())) {
+    return;
+  }
+
   // Step 3.
   double currentPlaybackTime = mMediaElement->CurrentTime();
   bool hasNormalPlayback = !mHasSeeked;
   mHasSeeked = false;
 
   // Step 1, 2.
   RefPtr<TextTrackCueList> currentCues =
     new TextTrackCueList(window);
   RefPtr<TextTrackCueList> otherCues =
     new TextTrackCueList(window);
   bool dummy;
   for (uint32_t index = 0; index < mTextTracks->Length(); ++index) {
     TextTrack* ttrack = mTextTracks->IndexedGetter(index, dummy);
     if (ttrack && dummy) {
+      // TODO: call GetCueListByTimeInterval on mNewCues?
       TextTrackCueList* activeCueList = ttrack->GetActiveCues();
       if (activeCueList) {
         for (uint32_t i = 0; i < activeCueList->Length(); ++i) {
           currentCues->AddCue(*((*activeCueList)[i]));
         }
       }
     }
   }
--- a/dom/html/TextTrackManager.h
+++ b/dom/html/TextTrackManager.h
@@ -52,17 +52,17 @@ public:
                                            TextTrackReadyState aReadyState,
                                            TextTrackSource aTextTrackSource);
   void AddTextTrack(TextTrack* aTextTrack);
   void RemoveTextTrack(TextTrack* aTextTrack, bool aPendingListOnly);
   void DidSeek();
 
   void AddCue(TextTrackCue& aCue);
   void AddCues(TextTrack* aTextTrack);
-
+  void NotifyCueRemoved(TextTrackCue& aCue);
   /**
    * Overview of WebVTT cuetext and anonymous content setup.
    *
    * WebVTT nodes are the parsed version of WebVTT cuetext. WebVTT cuetext is
    * the portion of a WebVTT cue that specifies what the caption will actually
    * show up as on screen.
    *
    * WebVTT cuetext can contain markup that loosely relates to HTML markup. It
--- a/dom/media/TextTrack.cpp
+++ b/dom/media/TextTrack.cpp
@@ -128,16 +128,20 @@ TextTrack::AddCue(TextTrackCue& aCue)
 
 void
 TextTrack::RemoveCue(TextTrackCue& aCue, ErrorResult& aRv)
 {
   //TODO: Apply the rules for text track cue rendering Bug 865407
   aCue.SetActive(false);
 
   mCueList->RemoveCue(aCue, aRv);
+  HTMLMediaElement* mediaElement = mTextTrackList->GetMediaElement();
+  if (mediaElement) {
+    mediaElement->NotifyCueRemoved(aCue);
+  }
   SetDirty();
 }
 
 void
 TextTrack::SetCuesDirty()
 {
   for (uint32_t i = 0; i < mCueList->Length(); i++) {
     ((*mCueList)[i])->Reset();