- Revision
- 107831
- Author
- [email protected]
- Date
- 2012-02-15 12:03:27 -0800 (Wed, 15 Feb 2012)
Log Message
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.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (107830 => 107831)
--- trunk/LayoutTests/ChangeLog 2012-02-15 19:52:07 UTC (rev 107830)
+++ trunk/LayoutTests/ChangeLog 2012-02-15 20:03:27 UTC (rev 107831)
@@ -1,3 +1,18 @@
+2012-02-15 Eric Carlson <[email protected]>
+
+ 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 <[email protected]>
Unreviewed gardening.
Added: trunk/LayoutTests/media/track/track-active-cues-expected.txt (0 => 107831)
--- trunk/LayoutTests/media/track/track-active-cues-expected.txt (rev 0)
+++ trunk/LayoutTests/media/track/track-active-cues-expected.txt 2012-02-15 20:03:27 UTC (rev 107831)
@@ -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
+
Added: trunk/LayoutTests/media/track/track-active-cues.html (0 => 107831)
--- trunk/LayoutTests/media/track/track-active-cues.html (rev 0)
+++ trunk/LayoutTests/media/track/track-active-cues.html 2012-02-15 20:03:27 UTC (rev 107831)
@@ -0,0 +1,53 @@
+<!doctype html>
+<html>
+ <head>
+ <script src=""
+ <script src=""
+
+ <script>
+ function clearSrc()
+ {
+ consoleWrite("<br>** Video and track loaded, one cue should be active **");
+ testExpected("trackElement.track.activeCues.length", 1);
+
+ consoleWrite("<br>** Clear video 'src' and force reload **");
+ run("video.src = ''");
+ consoleWrite("");
+ }
+
+ function videoError()
+ {
+ consoleWrite("** 'error' event, no cues should be active **)");
+ testExpected("event.target", video);
+ testExpected("video.error", null, "!=");
+ testExpected("video.error.code", MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED);
+ testExpected("video.networkState", HTMLMediaElement.NETWORK_NO_SOURCE);
+ testExpected("trackElement.track.activeCues.length", 0);
+
+ consoleWrite("");
+ endTest();
+ }
+
+ function setup()
+ {
+ consoleWrite("");
+
+ findMediaElement();
+ trackElement = document.querySelector('track');
+
+ waitForEventsAndCall([[video, 'canplaythrough'], [trackElement, 'load'], [trackElement, 'cuechange']], clearSrc);
+
+ video.src = "" "../content/test");
+ }
+
+ </script>
+ </head>
+ <body _onload_="setup()">
+ <video controls _onerror_="videoError()">
+ <track src="" kind="captions" default>
+ </video>
+
+ <p>Test to ensure that a no text track cues are active after the video is unloaded.</p>
+
+ </body>
+</html>
Modified: trunk/LayoutTests/media/track/track-cue-mutable-text.html (107830 => 107831)
--- trunk/LayoutTests/media/track/track-cue-mutable-text.html 2012-02-15 19:52:07 UTC (rev 107830)
+++ trunk/LayoutTests/media/track/track-cue-mutable-text.html 2012-02-15 20:03:27 UTC (rev 107831)
@@ -7,11 +7,12 @@
<script src=""
<script src=""
- <script>
+ <script>
var testTrack;
var fragment;
- function test()
+
+ function testMutability()
{
consoleWrite("<br>** Test initial cue info");
@@ -67,14 +68,17 @@
{
findMediaElement();
testTrack = document.querySelector('track');
+
+ waitForEventsAndCall([[video, 'canplaythrough'], [testTrack, 'load']], testMutability);
+
video.src = "" '../content/counting');
}
-
+
</script>
</head>
<body _onload_="loaded()">
<video controls >
- <track src="" kind="captions" default _onload_="test()">
+ <track src="" kind="captions" default >
</video>
<p>Test that cue text is mutable.</p>
</body>
Modified: trunk/LayoutTests/media/video-test.js (107830 => 107831)
--- trunk/LayoutTests/media/video-test.js 2012-02-15 19:52:07 UTC (rev 107830)
+++ trunk/LayoutTests/media/video-test.js 2012-02-15 20:03:27 UTC (rev 107831)
@@ -294,3 +294,30 @@
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);
+ }
+}
Modified: trunk/Source/WebCore/ChangeLog (107830 => 107831)
--- trunk/Source/WebCore/ChangeLog 2012-02-15 19:52:07 UTC (rev 107830)
+++ trunk/Source/WebCore/ChangeLog 2012-02-15 20:03:27 UTC (rev 107831)
@@ -1,3 +1,27 @@
+2012-02-15 Eric Carlson <[email protected]>
+
+ 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 <[email protected]>
WebCore build exceeds address space on 32-bit Windows builders (again).
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (107830 => 107831)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2012-02-15 19:52:07 UTC (rev 107830)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2012-02-15 20:03:27 UTC (rev 107831)
@@ -555,6 +555,11 @@
void HTMLMediaElement::loadTimerFired(Timer<HTMLMediaElement>*)
{
+#if ENABLE(VIDEO_TRACK)
+ if (m_pendingLoadFlags & TextTrackResource)
+ configureNewTextTracks();
+#endif
+
if (m_pendingLoadFlags & MediaResource) {
if (m_loadState == LoadingFromSourceElement)
loadNextSourceChild();
@@ -562,11 +567,6 @@
loadInternal();
}
-#if ENABLE(VIDEO_TRACK)
- if (m_pendingLoadFlags & TextTrackResource)
- configureNewTextTracks();
-#endif
-
m_pendingLoadFlags = 0;
}
@@ -675,6 +675,9 @@
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 @@
// 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 @@
// 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 @@
{
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 @@
bool wasPotentiallyPlaying = potentiallyPlaying();
ReadyState oldState = m_readyState;
- m_readyState = static_cast<ReadyState>(state);
+ ReadyState newState = static_cast<ReadyState>(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 @@
}
}
- 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 @@
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 @@
updatePlayState();
updateMediaController();
+#if ENABLE(VIDEO_TRACK)
+ updateActiveTextTrackCues(currentTime());
+#endif
}
#if ENABLE(MEDIA_SOURCE)
@@ -3144,6 +3166,9 @@
// Reset m_readyState since m_player is gone.
m_readyState = HAVE_NOTHING;
updateMediaController();
+#if ENABLE(VIDEO_TRACK)
+ updateActiveTextTrackCues(0);
+#endif
}
bool HTMLMediaElement::canSuspend() const