From 2baaea4b5a12e2fffc0ec1afcdf19bc00d105c39 Mon Sep 17 00:00:00 2001 From: "eric.carlson@apple.com" Date: Wed, 15 Feb 2012 20:03:27 +0000 Subject: [PATCH] Unset the active flag when TextTrackCues go away https://bugs.webkit.org/show_bug.cgi?id=72552 Reviewed by Maciej Stachowiak. Source/WebCore: Test: media/track/track-active-cues.html * html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::loadTimerFired): Configure new text tracks before preparing to load so we know about all tracks when resource selection begins. (WebCore::HTMLMediaElement::prepareForLoad): Call updateActiveTextTrackCues after setting to m_readyState is HAVE_NOTHING so all cues get deactivated. Don't build list of available text tracks because resource selection won't actually start until after the load timer fires. (WebCore::HTMLMediaElement::loadInternal): Build list of non-disabled tracks. (WebCore::HTMLMediaElement::updateActiveTextTrackCues): Clear the active flag on all cues when m_readyState is HAVE_NOTHING or m_player is 0. (WebCore::HTMLMediaElement::setReadyState): Don't update m_readyState when tracks which haven't loaded yet will prevent events from firing. Call updateActiveTextTrackCues to ensure that the first cue(s) are shown as soon as possible. (WebCore::HTMLMediaElement::userCancelledLoad): Call updateActiveTextTrackCues when when m_readyState is HAVE_NOTHING so all cues get deactivated. LayoutTests: * media/track/track-active-cues-expected.txt: Added. * media/track/track-active-cues.html: Added. * track-cue-mutable-text.html: Update to not run test until track and video have both loaded. * media/video-test.js: (waitForEventsAndCall): New, call the specified function after the list of events has been seen. git-svn-id: http://svn.webkit.org/repository/webkit/trunk@107831 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- LayoutTests/ChangeLog | 15 +++++ .../media/track/track-active-cues-expected.txt | 19 ++++++ LayoutTests/media/track/track-active-cues.html | 53 +++++++++++++++ .../media/track/track-cue-mutable-text.html | 12 ++-- LayoutTests/media/video-test.js | 27 ++++++++ Source/WebCore/ChangeLog | 24 +++++++ Source/WebCore/html/HTMLMediaElement.cpp | 75 ++++++++++++++-------- 7 files changed, 196 insertions(+), 29 deletions(-) create mode 100644 LayoutTests/media/track/track-active-cues-expected.txt create mode 100644 LayoutTests/media/track/track-active-cues.html diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog index c44ea95..3113503 100644 --- a/LayoutTests/ChangeLog +++ b/LayoutTests/ChangeLog @@ -1,3 +1,18 @@ +2012-02-15 Eric Carlson + + Unset the active flag when TextTrackCues go away + https://bugs.webkit.org/show_bug.cgi?id=72552 + + Reviewed by Maciej Stachowiak. + + * media/track/track-active-cues-expected.txt: Added. + * media/track/track-active-cues.html: Added. + * track-cue-mutable-text.html: Update to not run test until track and video have + both loaded. + * media/video-test.js: + (waitForEventsAndCall): New, call the specified function after the list of events + has been seen. + 2012-02-15 Stephen White Unreviewed gardening. diff --git a/LayoutTests/media/track/track-active-cues-expected.txt b/LayoutTests/media/track/track-active-cues-expected.txt new file mode 100644 index 0000000..946a5f7 --- /dev/null +++ b/LayoutTests/media/track/track-active-cues-expected.txt @@ -0,0 +1,19 @@ +Test to ensure that a no text track cues are active after the video is unloaded. + + + +** Video and track loaded, one cue should be active ** +EXPECTED (trackElement.track.activeCues.length == '1') OK + +** Clear video 'src' and force reload ** +RUN(video.src = '') + +** 'error' event, no cues should be active **) +EXPECTED (event.target == '[object HTMLVideoElement]') OK +EXPECTED (video.error != 'null') OK +EXPECTED (video.error.code == '4') OK +EXPECTED (video.networkState == '3') OK +EXPECTED (trackElement.track.activeCues.length == '0') OK + +END OF TEST + diff --git a/LayoutTests/media/track/track-active-cues.html b/LayoutTests/media/track/track-active-cues.html new file mode 100644 index 0000000..1281cb0 --- /dev/null +++ b/LayoutTests/media/track/track-active-cues.html @@ -0,0 +1,53 @@ + + + + + + + + + + + +

Test to ensure that a no text track cues are active after the video is unloaded.

+ + + diff --git a/LayoutTests/media/track/track-cue-mutable-text.html b/LayoutTests/media/track/track-cue-mutable-text.html index 0e380f9..8ef8723 100644 --- a/LayoutTests/media/track/track-cue-mutable-text.html +++ b/LayoutTests/media/track/track-cue-mutable-text.html @@ -7,11 +7,12 @@ -

Test that cue text is mutable.

diff --git a/LayoutTests/media/video-test.js b/LayoutTests/media/video-test.js index 7f68b21..ebf0f43 100644 --- a/LayoutTests/media/video-test.js +++ b/LayoutTests/media/video-test.js @@ -294,3 +294,30 @@ function enableAllTextTracks() video.textTracks[i].mode = TextTrack.HIDDEN; } } + +var requiredEvents = []; + +function waitForEventsAndCall(eventList, func) +{ + function _eventCallback(event) + { + if (!requiredEvents.length) + return; + + var index = requiredEvents.indexOf(event.type); + if (index < 0) + return; + + requiredEvents.splice(index, 1); + if (requiredEvents.length) + return; + + func(); + } + + requiredEvents = []; + for (var i = 0; i < eventList.length; i++) { + requiredEvents[i] = eventList[i][1]; + eventList[i][0].addEventListener(requiredEvents[i], _eventCallback, true); + } +} diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index 1061cbe..be36e7f 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,27 @@ +2012-02-15 Eric Carlson + + Unset the active flag when TextTrackCues go away + https://bugs.webkit.org/show_bug.cgi?id=72552 + + Reviewed by Maciej Stachowiak. + + Test: media/track/track-active-cues.html + + * html/HTMLMediaElement.cpp: + (WebCore::HTMLMediaElement::loadTimerFired): Configure new text tracks before preparing to load + so we know about all tracks when resource selection begins. + (WebCore::HTMLMediaElement::prepareForLoad): Call updateActiveTextTrackCues after setting + to m_readyState is HAVE_NOTHING so all cues get deactivated. Don't build list of + available text tracks because resource selection won't actually start until after the load timer fires. + (WebCore::HTMLMediaElement::loadInternal): Build list of non-disabled tracks. + (WebCore::HTMLMediaElement::updateActiveTextTrackCues): Clear the active flag on all cues + when m_readyState is HAVE_NOTHING or m_player is 0. + (WebCore::HTMLMediaElement::setReadyState): Don't update m_readyState when tracks which haven't + loaded yet will prevent events from firing. Call updateActiveTextTrackCues to ensure that the + first cue(s) are shown as soon as possible. + (WebCore::HTMLMediaElement::userCancelledLoad): Call updateActiveTextTrackCues when when m_readyState + is HAVE_NOTHING so all cues get deactivated. + 2012-02-15 Jessie Berlin WebCore build exceeds address space on 32-bit Windows builders (again). diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp index 67ad1d9..cc6f6d4 100644 --- a/Source/WebCore/html/HTMLMediaElement.cpp +++ b/Source/WebCore/html/HTMLMediaElement.cpp @@ -555,6 +555,11 @@ void HTMLMediaElement::scheduleEvent(const AtomicString& eventName) void HTMLMediaElement::loadTimerFired(Timer*) { +#if ENABLE(VIDEO_TRACK) + if (m_pendingLoadFlags & TextTrackResource) + configureNewTextTracks(); +#endif + if (m_pendingLoadFlags & MediaResource) { if (m_loadState == LoadingFromSourceElement) loadNextSourceChild(); @@ -562,11 +567,6 @@ void HTMLMediaElement::loadTimerFired(Timer*) loadInternal(); } -#if ENABLE(VIDEO_TRACK) - if (m_pendingLoadFlags & TextTrackResource) - configureNewTextTracks(); -#endif - m_pendingLoadFlags = 0; } @@ -675,6 +675,9 @@ void HTMLMediaElement::prepareForLoad() invalidateCachedTime(); scheduleEvent(eventNames().emptiedEvent); updateMediaController(); +#if ENABLE(VIDEO_TRACK) + updateActiveTextTrackCues(0); +#endif } // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRate attribute. @@ -703,19 +706,6 @@ void HTMLMediaElement::prepareForLoad() // event may have already fired by then. setShouldDelayLoadEvent(true); -#if ENABLE(VIDEO_TRACK) - // HTMLMediaElement::textTracksAreReady will need "... the text tracks whose mode was not in the - // disabled state when the element's resource selection algorithm last started". - m_textTracksWhenResourceSelectionBegan.clear(); - if (m_textTracks) { - for (unsigned i = 0; i < m_textTracks->length(); ++i) { - TextTrack* track = m_textTracks->item(i); - if (track->mode() != TextTrack::DISABLED) - m_textTracksWhenResourceSelectionBegan.append(track); - } - } -#endif - configureMediaControls(); } @@ -736,6 +726,19 @@ void HTMLMediaElement::loadInternal() // put in the the background. removeBehaviorRestriction(RequirePageConsentToLoadMediaRestriction); +#if ENABLE(VIDEO_TRACK) + // HTMLMediaElement::textTracksAreReady will need "... the text tracks whose mode was not in the + // disabled state when the element's resource selection algorithm last started". + m_textTracksWhenResourceSelectionBegan.clear(); + if (m_textTracks) { + for (unsigned i = 0; i < m_textTracks->length(); ++i) { + TextTrack* track = m_textTracks->item(i); + if (track->mode() != TextTrack::DISABLED) + m_textTracksWhenResourceSelectionBegan.append(track); + } + } +#endif + selectMediaResource(); } @@ -942,11 +945,16 @@ void HTMLMediaElement::updateActiveTextTrackCues(float movieTime) { if (ignoreTrackDisplayUpdateRequests()) return; - + CueList previouslyActiveCues = m_currentlyActiveCues; bool activeSetChanged = false; - m_currentlyActiveCues = m_cueTree.allOverlaps(m_cueTree.createInterval(movieTime, movieTime)); + // 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) + m_currentlyActiveCues.shrink(0); + else + m_currentlyActiveCues = m_cueTree.allOverlaps(m_cueTree.createInterval(movieTime, movieTime)); // FIXME(72171): Events need to be sorted and filtered before dispatching. @@ -1314,21 +1322,32 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state) bool wasPotentiallyPlaying = potentiallyPlaying(); ReadyState oldState = m_readyState; - m_readyState = static_cast(state); + ReadyState newState = static_cast(state); #if ENABLE(VIDEO_TRACK) bool tracksAreReady = textTracksAreReady(); - if (m_readyState == oldState && m_tracksAreReady == tracksAreReady) + if (newState == oldState && m_tracksAreReady == tracksAreReady) return; m_tracksAreReady = tracksAreReady; #else - if (m_readyState == oldState) + if (newState == oldState) return; bool tracksAreReady = true; #endif + if (tracksAreReady) + m_readyState = newState; + else { + // If a media file has text tracks the readyState may not progress beyond HAVE_FUTURE_DATA until + // the text tracks are ready, regardless of the state of the media file. + if (newState <= HAVE_METADATA) + m_readyState = newState; + else + m_readyState = HAVE_CURRENT_DATA; + } + if (oldState > m_readyStateMaximum) m_readyStateMaximum = oldState; @@ -1351,7 +1370,7 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state) } } - if (m_readyState >= HAVE_METADATA && oldState < HAVE_METADATA && tracksAreReady) { + if (m_readyState >= HAVE_METADATA && oldState < HAVE_METADATA) { prepareMediaFragmentURI(); scheduleEvent(eventNames().durationchangeEvent); scheduleEvent(eventNames().loadedmetadataEvent); @@ -1363,7 +1382,7 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state) bool shouldUpdateDisplayState = false; - if (m_readyState >= HAVE_CURRENT_DATA && oldState < HAVE_CURRENT_DATA && !m_haveFiredLoadedData && tracksAreReady) { + if (m_readyState >= HAVE_CURRENT_DATA && oldState < HAVE_CURRENT_DATA && !m_haveFiredLoadedData) { m_haveFiredLoadedData = true; shouldUpdateDisplayState = true; scheduleEvent(eventNames().loadeddataEvent); @@ -1406,6 +1425,9 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state) updatePlayState(); updateMediaController(); +#if ENABLE(VIDEO_TRACK) + updateActiveTextTrackCues(currentTime()); +#endif } #if ENABLE(MEDIA_SOURCE) @@ -3144,6 +3166,9 @@ void HTMLMediaElement::userCancelledLoad() // Reset m_readyState since m_player is gone. m_readyState = HAVE_NOTHING; updateMediaController(); +#if ENABLE(VIDEO_TRACK) + updateActiveTextTrackCues(0); +#endif } bool HTMLMediaElement::canSuspend() const -- 2.7.4