Bug 1509446 - part1 : update active cues list when cue's active state changed. r=jya
authorAlastor Wu <alwu@mozilla.com>
Fri, 08 Mar 2019 03:10:45 +0000
changeset 520962 3944dae3dabd
parent 520961 df1b1891f2f8
child 520963 fa26e1068b50
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1509446
milestone67.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 1509446 - part1 : update active cues list when cue's active state changed. r=jya According to spec [1], `activeCues` should represent a subset of the text track cues whose active flag was set when the script started. We should only depend on the `TimeMarchesOn` algorithm which will change cue's active state, and then add or remove cue to `activeCues`. [1] https://html.spec.whatwg.org/multipage/media.html#dom-texttrack-activecues Differential Revision: https://phabricator.services.mozilla.com/D22147
dom/html/TextTrackManager.cpp
dom/media/TextTrack.cpp
dom/media/TextTrack.h
dom/media/TextTrackCue.cpp
dom/media/TextTrackCue.h
--- a/dom/html/TextTrackManager.cpp
+++ b/dom/html/TextTrackManager.cpp
@@ -656,17 +656,16 @@ void TextTrackManager::TimeMarchesOn() {
   // 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?
-      ttrack->UpdateActiveCueList();
       TextTrackCueList* activeCueList = ttrack->GetActiveCues();
       if (activeCueList) {
         for (uint32_t i = 0; i < activeCueList->Length(); ++i) {
           currentCues->AddCue(*((*activeCueList)[i]));
         }
       }
     }
   }
--- a/dom/media/TextTrack.cpp
+++ b/dom/media/TextTrack.cpp
@@ -149,56 +149,16 @@ void TextTrack::RemoveCue(TextTrackCue& 
 }
 
 void TextTrack::SetCuesDirty() {
   for (uint32_t i = 0; i < mCueList->Length(); i++) {
     ((*mCueList)[i])->Reset();
   }
 }
 
-void TextTrack::UpdateActiveCueList() {
-  if (!mTextTrackList) {
-    return;
-  }
-
-  HTMLMediaElement* mediaElement = mTextTrackList->GetMediaElement();
-  if (!mediaElement) {
-    return;
-  }
-
-  // If we are dirty, i.e. an event happened that may cause the sorted mCueList
-  // to have changed like a seek or an insert for a cue, than we need to rebuild
-  // the active cue list from scratch.
-  if (mDirty) {
-    mCuePos = 0;
-    mDirty = false;
-    mActiveCueList->RemoveAll();
-  }
-
-  double playbackTime = mediaElement->CurrentTime();
-  // Remove all the cues from the active cue list whose end times now occur
-  // earlier then the current playback time.
-  for (uint32_t i = mActiveCueList->Length(); i > 0; i--) {
-    if ((*mActiveCueList)[i - 1]->EndTime() <= playbackTime) {
-      mActiveCueList->RemoveCueAt(i - 1);
-    }
-  }
-  // Add all the cues, starting from the position of the last cue that was
-  // added, that have valid start and end times for the current playback time.
-  // We can stop iterating safely once we encounter a cue that does not have
-  // a valid start time as the cue list is sorted.
-  for (; mCuePos < mCueList->Length() &&
-         (*mCueList)[mCuePos]->StartTime() <= playbackTime;
-       mCuePos++) {
-    if ((*mCueList)[mCuePos]->EndTime() > playbackTime) {
-      mActiveCueList->AddCue(*(*mCueList)[mCuePos]);
-    }
-  }
-}
-
 TextTrackCueList* TextTrack::GetActiveCues() {
   if (mMode != TextTrackMode::Disabled) {
     return mActiveCueList;
   }
   return nullptr;
 }
 
 void TextTrack::GetActiveCueArray(nsTArray<RefPtr<TextTrackCue> >& aCues) {
@@ -293,10 +253,21 @@ bool TextTrack::IsLoaded() {
     nsAutoString src;
     if (!(mTrackElement->GetAttr(kNameSpaceID_None, nsGkAtoms::src, src))) {
       return true;
     }
   }
   return (mReadyState >= Loaded);
 }
 
+void TextTrack::NotifyCueActiveStateChanged(TextTrackCue* aCue) {
+  MOZ_ASSERT(aCue);
+  if (aCue->GetActive()) {
+    MOZ_ASSERT(!mActiveCueList->IsCueExist(aCue));
+    mActiveCueList->AddCue(*aCue);
+  } else {
+    MOZ_ASSERT(mActiveCueList->IsCueExist(aCue));
+    mActiveCueList->RemoveCue(*aCue);
+  }
+}
+
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/media/TextTrack.h
+++ b/dom/media/TextTrack.h
@@ -64,17 +64,16 @@ class TextTrack final : public DOMEventT
   TextTrackCueList* GetCues() const {
     if (mMode == TextTrackMode::Disabled) {
       return nullptr;
     }
     return mCueList;
   }
 
   TextTrackCueList* GetActiveCues();
-  void UpdateActiveCueList();
   void GetActiveCueArray(nsTArray<RefPtr<TextTrackCue> >& aCues);
 
   TextTrackReadyState ReadyState() const;
   void SetReadyState(TextTrackReadyState aState);
   void SetReadyState(uint32_t aReadyState);
 
   void AddCue(TextTrackCue& aCue);
   void RemoveCue(TextTrackCue& aCue, ErrorResult& aRv);
@@ -94,16 +93,20 @@ class TextTrack final : public DOMEventT
   void SetCuesInactive();
 
   void NotifyCueUpdated(TextTrackCue* aCue);
 
   void DispatchAsyncTrustedEvent(const nsString& aEventName);
 
   bool IsLoaded();
 
+  // Called when associated cue's active flag has been changed, and then we
+  // would add or remove the cue to the active cue list.
+  void NotifyCueActiveStateChanged(TextTrackCue* aCue);
+
  private:
   ~TextTrack();
 
   RefPtr<TextTrackList> mTextTrackList;
 
   TextTrackKind mKind;
   nsString mLabel;
   nsString mLanguage;
--- a/dom/media/TextTrackCue.cpp
+++ b/dom/media/TextTrackCue.cpp
@@ -211,10 +211,22 @@ void TextTrackCue::NotifyDisplayStatesCh
     return;
   }
 
   mTrack->GetTextTrackList()
       ->GetMediaElement()
       ->NotifyCueDisplayStatesChanged();
 }
 
+void TextTrackCue::SetActive(bool aActive) {
+  if (mActive == aActive) {
+    return;
+  }
+
+  mActive = aActive;
+  mDisplayState = mActive ? mDisplayState : nullptr;
+  if (mTrack) {
+    mTrack->NotifyCueActiveStateChanged(this);
+  }
+}
+
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/media/TextTrackCue.h
+++ b/dom/media/TextTrackCue.h
@@ -275,24 +275,17 @@ class TextTrackCue final : public DOMEve
    *
    * Returns a DocumentFragment that is the head of the tree of anonymous
    * content.
    */
   already_AddRefed<DocumentFragment> GetCueAsHTML();
 
   void SetTrackElement(HTMLTrackElement* aTrackElement);
 
-  void SetActive(bool aActive) {
-    if (mActive == aActive) {
-      return;
-    }
-
-    mActive = aActive;
-    mDisplayState = mActive ? mDisplayState : nullptr;
-  }
+  void SetActive(bool aActive);
 
   bool GetActive() { return mActive; }
 
  private:
   ~TextTrackCue();
 
   void NotifyCueUpdated(TextTrackCue* aCue) {
     if (mTrack) {