| Index: Source/core/html/HTMLMediaElement.cpp
|
| diff --git a/Source/core/html/HTMLMediaElement.cpp b/Source/core/html/HTMLMediaElement.cpp
|
| index d950813509f57be4ced709d0b6c95b819abd7b1e..ba07c0e0234aa84ca8e8590202484f47ab69df1b 100644
|
| --- a/Source/core/html/HTMLMediaElement.cpp
|
| +++ b/Source/core/html/HTMLMediaElement.cpp
|
| @@ -53,8 +53,8 @@
|
| #include "core/html/track/AudioTrack.h"
|
| #include "core/html/track/AudioTrackList.h"
|
| #include "core/html/track/AutomaticTrackSelection.h"
|
| +#include "core/html/track/CueTimeline.h"
|
| #include "core/html/track/InbandTextTrack.h"
|
| -#include "core/html/track/TextTrackCueList.h"
|
| #include "core/html/track/TextTrackList.h"
|
| #include "core/html/track/VideoTrack.h"
|
| #include "core/html/track/VideoTrackList.h"
|
| @@ -75,7 +75,6 @@
|
| #include "public/platform/WebInbandTextTrack.h"
|
| #include "wtf/CurrentTime.h"
|
| #include "wtf/MathExtras.h"
|
| -#include "wtf/NonCopyingSort.h"
|
| #include "wtf/text/CString.h"
|
| #include <limits>
|
|
|
| @@ -149,24 +148,6 @@ static void removeElementFromDocumentMap(HTMLMediaElement* element, Document* do
|
| map.add(document, set);
|
| }
|
|
|
| -class TrackDisplayUpdateScope {
|
| - STACK_ALLOCATED();
|
| -public:
|
| - TrackDisplayUpdateScope(HTMLMediaElement* mediaElement)
|
| - {
|
| - m_mediaElement = mediaElement;
|
| - m_mediaElement->beginIgnoringTrackDisplayUpdateRequests();
|
| - }
|
| - ~TrackDisplayUpdateScope()
|
| - {
|
| - ASSERT(m_mediaElement);
|
| - m_mediaElement->endIgnoringTrackDisplayUpdateRequests();
|
| - }
|
| -
|
| -private:
|
| - RawPtrWillBeMember<HTMLMediaElement> m_mediaElement;
|
| -};
|
| -
|
| class AudioSourceProviderClientLockScope {
|
| STACK_ALLOCATED();
|
| public:
|
| @@ -375,13 +356,11 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum
|
| , m_isFinalizing(false)
|
| , m_closeMediaSourceWhenFinalizing(false)
|
| #endif
|
| - , m_lastTextTrackUpdateTime(-1)
|
| , m_initialPlayWithoutUserGestures(false)
|
| , m_autoplayMediaCounted(false)
|
| , m_audioTracks(AudioTrackList::create(*this))
|
| , m_videoTracks(VideoTrackList::create(*this))
|
| , m_textTracks(nullptr)
|
| - , m_ignoreTrackDisplayUpdate(0)
|
| #if ENABLE(WEB_AUDIO)
|
| , m_audioSourceNode(nullptr)
|
| #endif
|
| @@ -818,7 +797,7 @@ void HTMLMediaElement::prepareForLoad()
|
|
|
|
|
| updateMediaController();
|
| - updateActiveTextTrackCues(0);
|
| + cueTimeline().updateActiveCues(0);
|
| }
|
|
|
| // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRate attribute.
|
| @@ -1140,262 +1119,6 @@ WebMediaPlayer::LoadType HTMLMediaElement::loadType() const
|
| return WebMediaPlayer::LoadTypeURL;
|
| }
|
|
|
| -static bool trackIndexCompare(TextTrack* a,
|
| - TextTrack* b)
|
| -{
|
| - return a->trackIndex() - b->trackIndex() < 0;
|
| -}
|
| -
|
| -static bool eventTimeCueCompare(const std::pair<double, TextTrackCue*>& a,
|
| - const std::pair<double, TextTrackCue*>& b)
|
| -{
|
| - // 12 - Sort the tasks in events in ascending time order (tasks with earlier
|
| - // times first).
|
| - if (a.first != b.first)
|
| - return a.first - b.first < 0;
|
| -
|
| - // If the cues belong to different text tracks, it doesn't make sense to
|
| - // compare the two tracks by the relative cue order, so return the relative
|
| - // track order.
|
| - if (a.second->track() != b.second->track())
|
| - return trackIndexCompare(a.second->track(), b.second->track());
|
| -
|
| - // 12 - Further sort tasks in events that have the same time by the
|
| - // relative text track cue order of the text track cues associated
|
| - // with these tasks.
|
| - return a.second->cueIndex() - b.second->cueIndex() < 0;
|
| -}
|
| -
|
| -
|
| -void HTMLMediaElement::updateActiveTextTrackCues(double movieTime)
|
| -{
|
| - // 4.8.10.8 Playing the media resource
|
| -
|
| - // If the current playback position changes while the steps are running,
|
| - // then the user agent must wait for the steps to complete, and then must
|
| - // immediately rerun the steps.
|
| - if (ignoreTrackDisplayUpdateRequests())
|
| - return;
|
| -
|
| - // 1 - Let current cues be a list of cues, initialized to contain all the
|
| - // cues of all the hidden, showing, or showing by default text tracks of the
|
| - // media element (not the disabled ones) whose start times are less than or
|
| - // equal to the current playback position and whose end times are greater
|
| - // than the current playback position.
|
| - CueList currentCues;
|
| -
|
| - // The user agent must synchronously unset [the text track cue active] flag
|
| - // whenever ... the media element's readyState is changed back to HAVE_NOTHING.
|
| - if (m_readyState != HAVE_NOTHING && m_player)
|
| - currentCues = m_cueTree.allOverlaps(m_cueTree.createInterval(movieTime, movieTime));
|
| -
|
| - CueList previousCues;
|
| - CueList missedCues;
|
| -
|
| - // 2 - Let other cues be a list of cues, initialized to contain all the cues
|
| - // of hidden, showing, and showing by default text tracks of the media
|
| - // element that are not present in current cues.
|
| - previousCues = m_currentlyActiveCues;
|
| -
|
| - // 3 - Let last time be the current playback position at the time this
|
| - // algorithm was last run for this media element, if this is not the first
|
| - // time it has run.
|
| - double lastTime = m_lastTextTrackUpdateTime;
|
| -
|
| - // 4 - If the current playback position has, since the last time this
|
| - // algorithm was run, only changed through its usual monotonic increase
|
| - // during normal playback, then let missed cues be the list of cues in other
|
| - // cues whose start times are greater than or equal to last time and whose
|
| - // end times are less than or equal to the current playback position.
|
| - // Otherwise, let missed cues be an empty list.
|
| - if (lastTime >= 0 && m_lastSeekTime < movieTime) {
|
| - CueList potentiallySkippedCues =
|
| - m_cueTree.allOverlaps(m_cueTree.createInterval(lastTime, movieTime));
|
| -
|
| - for (CueInterval cue : potentiallySkippedCues) {
|
| - // Consider cues that may have been missed since the last seek time.
|
| - if (cue.low() > std::max(m_lastSeekTime, lastTime) && cue.high() < movieTime)
|
| - missedCues.append(cue);
|
| - }
|
| - }
|
| -
|
| - m_lastTextTrackUpdateTime = movieTime;
|
| -
|
| - // 5 - If the time was reached through the usual monotonic increase of the
|
| - // current playback position during normal playback, and if the user agent
|
| - // has not fired a timeupdate event at the element in the past 15 to 250ms
|
| - // and is not still running event handlers for such an event, then the user
|
| - // agent must queue a task to fire a simple event named timeupdate at the
|
| - // element. (In the other cases, such as explicit seeks, relevant events get
|
| - // fired as part of the overall process of changing the current playback
|
| - // position.)
|
| - if (!m_seeking && m_lastSeekTime < lastTime)
|
| - scheduleTimeupdateEvent(true);
|
| -
|
| - // Explicitly cache vector sizes, as their content is constant from here.
|
| - size_t currentCuesSize = currentCues.size();
|
| - size_t missedCuesSize = missedCues.size();
|
| - size_t previousCuesSize = previousCues.size();
|
| -
|
| - // 6 - If all of the cues in current cues have their text track cue active
|
| - // flag set, none of the cues in other cues have their text track cue active
|
| - // flag set, and missed cues is empty, then abort these steps.
|
| - bool activeSetChanged = missedCuesSize;
|
| -
|
| - for (size_t i = 0; !activeSetChanged && i < previousCuesSize; ++i) {
|
| - if (!currentCues.contains(previousCues[i]) && previousCues[i].data()->isActive())
|
| - activeSetChanged = true;
|
| - }
|
| -
|
| - for (CueInterval currentCue : currentCues) {
|
| - currentCue.data()->updateDisplayTree(movieTime);
|
| -
|
| - if (!currentCue.data()->isActive())
|
| - activeSetChanged = true;
|
| - }
|
| -
|
| - if (!activeSetChanged)
|
| - return;
|
| -
|
| - // 7 - If the time was reached through the usual monotonic increase of the
|
| - // current playback position during normal playback, and there are cues in
|
| - // other cues that have their text track cue pause-on-exi flag set and that
|
| - // either have their text track cue active flag set or are also in missed
|
| - // cues, then immediately pause the media element.
|
| - for (size_t i = 0; !m_paused && i < previousCuesSize; ++i) {
|
| - if (previousCues[i].data()->pauseOnExit()
|
| - && previousCues[i].data()->isActive()
|
| - && !currentCues.contains(previousCues[i]))
|
| - pause();
|
| - }
|
| -
|
| - for (size_t i = 0; !m_paused && i < missedCuesSize; ++i) {
|
| - if (missedCues[i].data()->pauseOnExit())
|
| - pause();
|
| - }
|
| -
|
| - // 8 - Let events be a list of tasks, initially empty. Each task in this
|
| - // list will be associated with a text track, a text track cue, and a time,
|
| - // which are used to sort the list before the tasks are queued.
|
| - WillBeHeapVector<std::pair<double, RawPtrWillBeMember<TextTrackCue>>> eventTasks;
|
| -
|
| - // 8 - Let affected tracks be a list of text tracks, initially empty.
|
| - WillBeHeapVector<RawPtrWillBeMember<TextTrack>> affectedTracks;
|
| -
|
| - for (size_t i = 0; i < missedCuesSize; ++i) {
|
| - // 9 - For each text track cue in missed cues, prepare an event named enter
|
| - // for the TextTrackCue object with the text track cue start time.
|
| - eventTasks.append(std::make_pair(missedCues[i].data()->startTime(),
|
| - missedCues[i].data()));
|
| -
|
| - // 10 - For each text track [...] in missed cues, prepare an event
|
| - // named exit for the TextTrackCue object with the with the later of
|
| - // the text track cue end time and the text track cue start time.
|
| -
|
| - // Note: An explicit task is added only if the cue is NOT a zero or
|
| - // negative length cue. Otherwise, the need for an exit event is
|
| - // checked when these tasks are actually queued below. This doesn't
|
| - // affect sorting events before dispatch either, because the exit
|
| - // event has the same time as the enter event.
|
| - if (missedCues[i].data()->startTime() < missedCues[i].data()->endTime())
|
| - eventTasks.append(std::make_pair(missedCues[i].data()->endTime(),
|
| - missedCues[i].data()));
|
| - }
|
| -
|
| - for (size_t i = 0; i < previousCuesSize; ++i) {
|
| - // 10 - For each text track cue in other cues that has its text
|
| - // track cue active flag set prepare an event named exit for the
|
| - // TextTrackCue object with the text track cue end time.
|
| - if (!currentCues.contains(previousCues[i]))
|
| - eventTasks.append(std::make_pair(previousCues[i].data()->endTime(),
|
| - previousCues[i].data()));
|
| - }
|
| -
|
| - for (size_t i = 0; i < currentCuesSize; ++i) {
|
| - // 11 - For each text track cue in current cues that does not have its
|
| - // text track cue active flag set, prepare an event named enter for the
|
| - // TextTrackCue object with the text track cue start time.
|
| - if (!previousCues.contains(currentCues[i]))
|
| - eventTasks.append(std::make_pair(currentCues[i].data()->startTime(),
|
| - currentCues[i].data()));
|
| - }
|
| -
|
| - // 12 - Sort the tasks in events in ascending time order (tasks with earlier
|
| - // times first).
|
| - nonCopyingSort(eventTasks.begin(), eventTasks.end(), eventTimeCueCompare);
|
| -
|
| - for (size_t i = 0; i < eventTasks.size(); ++i) {
|
| - if (!affectedTracks.contains(eventTasks[i].second->track()))
|
| - affectedTracks.append(eventTasks[i].second->track());
|
| -
|
| - // 13 - Queue each task in events, in list order.
|
| - RefPtrWillBeRawPtr<Event> event = nullptr;
|
| -
|
| - // Each event in eventTasks may be either an enterEvent or an exitEvent,
|
| - // depending on the time that is associated with the event. This
|
| - // correctly identifies the type of the event, if the startTime is
|
| - // less than the endTime in the cue.
|
| - if (eventTasks[i].second->startTime() >= eventTasks[i].second->endTime()) {
|
| - event = Event::create(EventTypeNames::enter);
|
| - event->setTarget(eventTasks[i].second);
|
| - m_asyncEventQueue->enqueueEvent(event.release());
|
| -
|
| - event = Event::create(EventTypeNames::exit);
|
| - event->setTarget(eventTasks[i].second);
|
| - m_asyncEventQueue->enqueueEvent(event.release());
|
| - } else {
|
| - if (eventTasks[i].first == eventTasks[i].second->startTime())
|
| - event = Event::create(EventTypeNames::enter);
|
| - else
|
| - event = Event::create(EventTypeNames::exit);
|
| -
|
| - event->setTarget(eventTasks[i].second);
|
| - m_asyncEventQueue->enqueueEvent(event.release());
|
| - }
|
| - }
|
| -
|
| - // 14 - Sort affected tracks in the same order as the text tracks appear in
|
| - // the media element's list of text tracks, and remove duplicates.
|
| - nonCopyingSort(affectedTracks.begin(), affectedTracks.end(), trackIndexCompare);
|
| -
|
| - // 15 - For each text track in affected tracks, in the list order, queue a
|
| - // task to fire a simple event named cuechange at the TextTrack object, and, ...
|
| - for (size_t i = 0; i < affectedTracks.size(); ++i) {
|
| - RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::cuechange);
|
| - event->setTarget(affectedTracks[i]);
|
| -
|
| - m_asyncEventQueue->enqueueEvent(event.release());
|
| -
|
| - // ... if the text track has a corresponding track element, to then fire a
|
| - // simple event named cuechange at the track element as well.
|
| - if (affectedTracks[i]->trackType() == TextTrack::TrackElement) {
|
| - RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::cuechange);
|
| - HTMLTrackElement* trackElement = static_cast<LoadableTextTrack*>(affectedTracks[i].get())->trackElement();
|
| - ASSERT(trackElement);
|
| - event->setTarget(trackElement);
|
| -
|
| - m_asyncEventQueue->enqueueEvent(event.release());
|
| - }
|
| - }
|
| -
|
| - // 16 - Set the text track cue active flag of all the cues in the current
|
| - // cues, and unset the text track cue active flag of all the cues in the
|
| - // other cues.
|
| - for (size_t i = 0; i < currentCuesSize; ++i)
|
| - currentCues[i].data()->setIsActive(true);
|
| -
|
| - for (size_t i = 0; i < previousCuesSize; ++i) {
|
| - if (!currentCues.contains(previousCues[i]))
|
| - previousCues[i].data()->setIsActive(false);
|
| - }
|
| -
|
| - // Update the current active cues.
|
| - m_currentlyActiveCues = currentCues;
|
| -
|
| - if (activeSetChanged)
|
| - updateTextTrackDisplay();
|
| -}
|
| -
|
| bool HTMLMediaElement::textTracksAreReady() const
|
| {
|
| // 4.8.10.12.1 Text track model
|
| @@ -1443,7 +1166,7 @@ void HTMLMediaElement::textTrackModeChanged(TextTrack* track)
|
| track->setHasBeenConfigured(true);
|
| if (track->mode() != TextTrack::disabledKeyword()) {
|
| if (trackElement->readyState() == HTMLTrackElement::LOADED)
|
| - textTrackAddCues(track, track->cues());
|
| + cueTimeline().addCues(track, track->cues());
|
|
|
| // If this is the first added track, create the list of text tracks.
|
| if (!m_textTracks)
|
| @@ -1452,7 +1175,7 @@ void HTMLMediaElement::textTrackModeChanged(TextTrack* track)
|
| break;
|
| }
|
| } else if (track->trackType() == TextTrack::AddTrack && track->mode() != TextTrack::disabledKeyword()) {
|
| - textTrackAddCues(track, track->cues());
|
| + cueTimeline().addCues(track, track->cues());
|
| }
|
|
|
| configureTextTrackDisplay(AssumeVisibleChange);
|
| @@ -1467,78 +1190,6 @@ void HTMLMediaElement::textTrackKindChanged(TextTrack* track)
|
| track->setMode(TextTrack::hiddenKeyword());
|
| }
|
|
|
| -void HTMLMediaElement::beginIgnoringTrackDisplayUpdateRequests()
|
| -{
|
| - ++m_ignoreTrackDisplayUpdate;
|
| -}
|
| -
|
| -void HTMLMediaElement::endIgnoringTrackDisplayUpdateRequests()
|
| -{
|
| - ASSERT(m_ignoreTrackDisplayUpdate);
|
| - --m_ignoreTrackDisplayUpdate;
|
| - if (!m_ignoreTrackDisplayUpdate && inActiveDocument())
|
| - updateActiveTextTrackCues(currentTime());
|
| -}
|
| -
|
| -void HTMLMediaElement::textTrackAddCues(TextTrack* track, const TextTrackCueList* cues)
|
| -{
|
| - WTF_LOG(Media, "HTMLMediaElement::textTrackAddCues(%p)", this);
|
| - ASSERT(track->mode() != TextTrack::disabledKeyword());
|
| -
|
| - TrackDisplayUpdateScope scope(this);
|
| - for (size_t i = 0; i < cues->length(); ++i)
|
| - textTrackAddCue(cues->item(i)->track(), cues->item(i));
|
| -}
|
| -
|
| -void HTMLMediaElement::textTrackRemoveCues(TextTrack*, const TextTrackCueList* cues)
|
| -{
|
| - WTF_LOG(Media, "HTMLMediaElement::textTrackRemoveCues(%p)", this);
|
| -
|
| - TrackDisplayUpdateScope scope(this);
|
| - for (size_t i = 0; i < cues->length(); ++i)
|
| - textTrackRemoveCue(cues->item(i)->track(), cues->item(i));
|
| -}
|
| -
|
| -void HTMLMediaElement::textTrackAddCue(TextTrack* track, PassRefPtrWillBeRawPtr<TextTrackCue> cue)
|
| -{
|
| - ASSERT(track->mode() != TextTrack::disabledKeyword());
|
| -
|
| - // Negative duration cues need be treated in the interval tree as
|
| - // zero-length cues.
|
| - double endTime = std::max(cue->startTime(), cue->endTime());
|
| -
|
| - CueInterval interval = m_cueTree.createInterval(cue->startTime(), endTime, cue.get());
|
| - if (!m_cueTree.contains(interval))
|
| - m_cueTree.add(interval);
|
| - updateActiveTextTrackCues(currentTime());
|
| -}
|
| -
|
| -void HTMLMediaElement::textTrackRemoveCue(TextTrack*, PassRefPtrWillBeRawPtr<TextTrackCue> cue)
|
| -{
|
| - // Negative duration cues need to be treated in the interval tree as
|
| - // zero-length cues.
|
| - double endTime = std::max(cue->startTime(), cue->endTime());
|
| -
|
| - CueInterval interval = m_cueTree.createInterval(cue->startTime(), endTime, cue.get());
|
| - m_cueTree.remove(interval);
|
| -
|
| - // Since the cue will be removed from the media element and likely the
|
| - // TextTrack might also be destructed, notifying the region of the cue
|
| - // removal shouldn't be done.
|
| - cue->notifyRegionWhenRemovingDisplayTree(false);
|
| -
|
| - size_t index = m_currentlyActiveCues.find(interval);
|
| - if (index != kNotFound) {
|
| - m_currentlyActiveCues.remove(index);
|
| - cue->setIsActive(false);
|
| - }
|
| - cue->removeDisplayTree();
|
| - updateActiveTextTrackCues(currentTime());
|
| -
|
| - cue->notifyRegionWhenRemovingDisplayTree(true);
|
| -}
|
| -
|
| -
|
| bool HTMLMediaElement::isSafeToLoadURL(const KURL& url, InvalidURLAction actionIfInvalid)
|
| {
|
| if (!url.isValid()) {
|
| @@ -1929,7 +1580,7 @@ void HTMLMediaElement::setReadyState(ReadyState state)
|
|
|
| updatePlayState();
|
| updateMediaController();
|
| - updateActiveTextTrackCues(currentTime());
|
| + cueTimeline().updateActiveCues(currentTime());
|
| }
|
|
|
| void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*)
|
| @@ -2518,7 +2169,7 @@ void HTMLMediaElement::playbackProgressTimerFired(Timer<HTMLMediaElement>*)
|
| if (!m_paused && hasMediaControls())
|
| mediaControls()->playbackProgressed();
|
|
|
| - updateActiveTextTrackCues(currentTime());
|
| + cueTimeline().updateActiveCues(currentTime());
|
| }
|
|
|
| void HTMLMediaElement::scheduleTimeupdateEvent(bool periodicEvent)
|
| @@ -2728,7 +2379,7 @@ void HTMLMediaElement::addTextTrack(TextTrack* track)
|
|
|
| void HTMLMediaElement::removeTextTrack(TextTrack* track)
|
| {
|
| - TrackDisplayUpdateScope scope(this);
|
| + TrackDisplayUpdateScope scope(this->cueTimeline());
|
| m_textTracks->remove(track);
|
|
|
| textTracksChanged();
|
| @@ -2740,7 +2391,7 @@ void HTMLMediaElement::forgetResourceSpecificTracks()
|
| // The order is explicitly specified as text, then audio, and finally video. Also
|
| // 'removetrack' events should not be fired.
|
| if (m_textTracks) {
|
| - TrackDisplayUpdateScope scope(this);
|
| + TrackDisplayUpdateScope scope(this->cueTimeline());
|
| m_textTracks->removeAllInbandTracks();
|
| textTracksChanged();
|
| }
|
| @@ -3045,7 +2696,7 @@ void HTMLMediaElement::mediaPlayerTimeChanged()
|
| {
|
| WTF_LOG(Media, "HTMLMediaElement::mediaPlayerTimeChanged(%p)", this);
|
|
|
| - updateActiveTextTrackCues(currentTime());
|
| + cueTimeline().updateActiveCues(currentTime());
|
|
|
| invalidateCachedTime();
|
|
|
| @@ -3389,7 +3040,7 @@ void HTMLMediaElement::userCancelledLoad()
|
| m_readyState = HAVE_NOTHING;
|
| invalidateCachedTime();
|
| updateMediaController();
|
| - updateActiveTextTrackCues(0);
|
| + cueTimeline().updateActiveCues(0);
|
| }
|
|
|
| void HTMLMediaElement::clearMediaPlayerAndAudioSourceProviderClientWithoutLocking()
|
| @@ -3688,6 +3339,13 @@ void HTMLMediaElement::configureMediaControls()
|
| mediaControls()->hide();
|
| }
|
|
|
| +CueTimeline& HTMLMediaElement::cueTimeline()
|
| +{
|
| + if (!m_cueTimeline)
|
| + m_cueTimeline = adoptPtrWillBeNoop(new CueTimeline(*this));
|
| + return *m_cueTimeline;
|
| +}
|
| +
|
| void HTMLMediaElement::configureTextTrackDisplay(VisibilityChangeAssumption assumption)
|
| {
|
| ASSERT(m_textTracks);
|
| @@ -3706,7 +3364,7 @@ void HTMLMediaElement::configureTextTrackDisplay(VisibilityChangeAssumption assu
|
|
|
| if (assumption == AssumeNoVisibleChange
|
| && m_haveVisibleTextTrack == haveVisibleTextTrack) {
|
| - updateActiveTextTrackCues(currentTime());
|
| + cueTimeline().updateActiveCues(currentTime());
|
| return;
|
| }
|
| m_haveVisibleTextTrack = haveVisibleTextTrack;
|
| @@ -3718,7 +3376,7 @@ void HTMLMediaElement::configureTextTrackDisplay(VisibilityChangeAssumption assu
|
| ensureMediaControls();
|
| mediaControls()->changedClosedCaptionsVisibility();
|
|
|
| - updateActiveTextTrackCues(currentTime());
|
| + cueTimeline().updateActiveCues(currentTime());
|
| updateTextTrackDisplay();
|
| }
|
|
|
| @@ -3928,6 +3586,7 @@ void HTMLMediaElement::trace(Visitor* visitor)
|
| visitor->trace(m_mediaSource);
|
| visitor->trace(m_audioTracks);
|
| visitor->trace(m_videoTracks);
|
| + visitor->trace(m_cueTimeline);
|
| visitor->trace(m_textTracks);
|
| visitor->trace(m_textTracksWhenResourceSelectionBegan);
|
| visitor->trace(m_mediaController);
|
|
|