Diff
Added: trunk/LayoutTests/http/tests/media/hls/hls-webvtt-flashing-expected.txt (0 => 294854)
--- trunk/LayoutTests/http/tests/media/hls/hls-webvtt-flashing-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/media/hls/hls-webvtt-flashing-expected.txt 2022-05-26 00:47:32 UTC (rev 294854)
@@ -0,0 +1,10 @@
+
+EVENT(addtrack)
+EXPECTED (video.textTracks.length == '1') OK
+RUN(video.textTracks[0].mode = 'showing')
+EVENT(cuechange)
+EXPECTED (video.textTracks[0].activeCues.length == '1') OK
+EXPECTED (video.textTracks[0].activeCues[0].text == 'Subtitle Test') OK
+EXPECTED (video.textTracks[0].activeCues[0].endTime > '0.100') OK
+END OF TEST
+
Added: trunk/LayoutTests/http/tests/media/hls/hls-webvtt-flashing.html (0 => 294854)
--- trunk/LayoutTests/http/tests/media/hls/hls-webvtt-flashing.html (rev 0)
+++ trunk/LayoutTests/http/tests/media/hls/hls-webvtt-flashing.html 2022-05-26 00:47:32 UTC (rev 294854)
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src=""
+ <script>
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
+
+ function start() {
+ video = document.getElementById('video');
+ video.src = ""
+ video.play();
+ waitForEventOnceOn(video.textTracks, 'addtrack', trackAdded);
+ }
+
+ function trackAdded() {
+ testExpected("video.textTracks.length", "1");
+ run("video.textTracks[0].mode = 'showing'");
+ waitForEventOnceOn(video.textTracks[0], 'cuechange', cueChanged);
+ }
+
+ function cueChanged() {
+ testExpected("video.textTracks[0].activeCues.length", "1");
+ testExpected("video.textTracks[0].activeCues[0].text", "Subtitle Test");
+ testExpected("video.textTracks[0].activeCues[0].endTime", "0.100", ">");
+ endTest();
+ }
+ </script>
+</head>
+<body _onload_="start()">
+ <video id="video" muted loop></video>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/media/resources/hls/subtitles/flashSequence0.webvtt (0 => 294854)
--- trunk/LayoutTests/http/tests/media/resources/hls/subtitles/flashSequence0.webvtt (rev 0)
+++ trunk/LayoutTests/http/tests/media/resources/hls/subtitles/flashSequence0.webvtt 2022-05-26 00:47:32 UTC (rev 294854)
@@ -0,0 +1,8 @@
+WEBVTT
+X-TIMESTAMP-MAP=MPEGTS:900000,LOCAL:00:00:00.000
+
+00:00:00.000 --> 00:00:00.100
+Subtitle Test
+
+00:00:00.100 --> 00:00:01.000
+Subtitle Test
Added: trunk/LayoutTests/http/tests/media/resources/hls/subtitles/prog_flashing.m3u8 (0 => 294854)
--- trunk/LayoutTests/http/tests/media/resources/hls/subtitles/prog_flashing.m3u8 (rev 0)
+++ trunk/LayoutTests/http/tests/media/resources/hls/subtitles/prog_flashing.m3u8 2022-05-26 00:47:32 UTC (rev 294854)
@@ -0,0 +1,8 @@
+#EXTM3U
+#EXT-X-TARGETDURATION:30
+#EXT-X-VERSION:3
+#EXT-X-MEDIA-SEQUENCE:0
+#EXT-X-PLAYLIST-TYPE:VOD
+#EXTINF:10,
+flashSequence0.webvtt
+#EXT-X-ENDLIST
Added: trunk/LayoutTests/http/tests/media/resources/hls/test-webvtt-flashing.m3u8 (0 => 294854)
--- trunk/LayoutTests/http/tests/media/resources/hls/test-webvtt-flashing.m3u8 (rev 0)
+++ trunk/LayoutTests/http/tests/media/resources/hls/test-webvtt-flashing.m3u8 2022-05-26 00:47:32 UTC (rev 294854)
@@ -0,0 +1,6 @@
+#EXTM3U
+
+#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subtitles",LANGUAGE="en-US",NAME="English",AUTOSELECT=YES,DEFAULT=YES,URI="subtitles/prog_flashing.m3u8"
+
+#EXT-X-STREAM-INF:BANDWIDTH=634451,CODECS="mp4a.40.2, avc1.4d401e",RESOLUTION=640x480,SUBTITLES="subtitles"
+bipbop/prog_index.m3u8
Modified: trunk/LayoutTests/platform/glib/TestExpectations (294853 => 294854)
--- trunk/LayoutTests/platform/glib/TestExpectations 2022-05-26 00:23:12 UTC (rev 294853)
+++ trunk/LayoutTests/platform/glib/TestExpectations 2022-05-26 00:47:32 UTC (rev 294854)
@@ -2483,6 +2483,7 @@
webkit.org/b/168373 media/media-fullscreen-loop-inline.html [ Timeout ]
webkit.org/b/174242 media/media-fullscreen-pause-inline.html [ Skip ]
webkit.org/b/182108 http/tests/media/hls/hls-webvtt-tracks.html [ Timeout ]
+webkit.org/b/182108 http/tests/media/hls/hls-webvtt-flashing.html [ Timeout ]
webkit.org/b/137311 media/video-fullscreen-only-playback.html [ Timeout Crash ]
webkit.org/b/194044 imported/w3c/web-platform-tests/media-source/mediasource-addsourcebuffer.html [ Failure ]
Modified: trunk/Source/WebCore/html/track/InbandGenericTextTrack.cpp (294853 => 294854)
--- trunk/Source/WebCore/html/track/InbandGenericTextTrack.cpp 2022-05-26 00:23:12 UTC (rev 294853)
+++ trunk/Source/WebCore/html/track/InbandGenericTextTrack.cpp 2022-05-26 00:47:32 UTC (rev 294854)
@@ -190,12 +190,20 @@
{
for (auto& cueData : parser().takeCues()) {
auto cue = VTTCue::create(document(), cueData);
- if (hasCue(cue, TextTrackCue::IgnoreDuration)) {
+ auto existingCue = matchCue(cue, TextTrackCue::IgnoreDuration);
+ if (!existingCue) {
+ INFO_LOG(LOGIDENTIFIER, cue.get());
+ addCue(WTFMove(cue));
+ continue;
+ }
+
+ if (existingCue->endTime() >= cue->endTime()) {
INFO_LOG(LOGIDENTIFIER, "ignoring already added cue: ", cue.get());
- return;
+ continue;
}
- INFO_LOG(LOGIDENTIFIER, cue.get());
- addCue(WTFMove(cue));
+
+ ALWAYS_LOG(LOGIDENTIFIER, "extending endTime of existing cue: ", *existingCue, " to ", cue->endTime());
+ existingCue->setEndTime(cue->endTime());
}
}
Modified: trunk/Source/WebCore/html/track/InbandWebVTTTextTrack.cpp (294853 => 294854)
--- trunk/Source/WebCore/html/track/InbandWebVTTTextTrack.cpp 2022-05-26 00:23:12 UTC (rev 294853)
+++ trunk/Source/WebCore/html/track/InbandWebVTTTextTrack.cpp 2022-05-26 00:47:32 UTC (rev 294854)
@@ -74,12 +74,20 @@
{
for (auto& cueData : parser().takeCues()) {
auto cue = VTTCue::create(document(), cueData);
- if (hasCue(cue, TextTrackCue::IgnoreDuration)) {
+ auto existingCue = matchCue(cue, TextTrackCue::IgnoreDuration);
+ if (!existingCue) {
+ INFO_LOG(LOGIDENTIFIER, cue.get());
+ addCue(WTFMove(cue));
+ continue;
+ }
+
+ if (existingCue->endTime() >= cue->endTime()) {
INFO_LOG(LOGIDENTIFIER, "ignoring already added cue: ", cue.get());
- return;
+ continue;
}
- INFO_LOG(LOGIDENTIFIER, cue.get());
- addCue(WTFMove(cue));
+
+ ALWAYS_LOG(LOGIDENTIFIER, "extending endTime of existing cue: ", *existingCue, " to ", cue->endTime());
+ existingCue->setEndTime(cue->endTime());
}
}
Modified: trunk/Source/WebCore/html/track/TextTrack.cpp (294853 => 294854)
--- trunk/Source/WebCore/html/track/TextTrack.cpp 2022-05-26 00:23:12 UTC (rev 294853)
+++ trunk/Source/WebCore/html/track/TextTrack.cpp 2022-05-26 00:47:32 UTC (rev 294854)
@@ -526,13 +526,13 @@
return m_renderedTrackIndex.value();
}
-bool TextTrack::hasCue(TextTrackCue& cue, TextTrackCue::CueMatchRules match)
+RefPtr<TextTrackCue> TextTrack::matchCue(TextTrackCue& cue, TextTrackCue::CueMatchRules match)
{
if (cue.startMediaTime() < MediaTime::zeroTime() || cue.endMediaTime() < MediaTime::zeroTime())
- return false;
+ return nullptr;
if (!m_cues || !m_cues->length())
- return false;
+ return nullptr;
size_t searchStart = 0;
size_t searchEnd = m_cues->length();
@@ -546,7 +546,7 @@
// Cues in the TextTrackCueList are maintained in start time order.
if (searchStart == searchEnd) {
if (!searchStart)
- return false;
+ return nullptr;
// If there is more than one cue with the same start time, back up to first one so we
// consider all of them.
@@ -559,17 +559,17 @@
++searchStart;
firstCompare = false;
if (searchStart > m_cues->length())
- return false;
+ return nullptr;
existingCue = m_cues->item(searchStart - 1);
if (!existingCue)
- return false;
+ return nullptr;
if (cue.startMediaTime() > (existingCue->startMediaTime() + startTimeVariance()))
- return false;
+ return nullptr;
if (existingCue->isEqual(cue, match))
- return true;
+ return existingCue;
}
}
@@ -582,7 +582,7 @@
}
ASSERT_NOT_REACHED();
- return false;
+ return nullptr;
}
bool TextTrack::isMainProgramContent() const
Modified: trunk/Source/WebCore/html/track/TextTrack.h (294853 => 294854)
--- trunk/Source/WebCore/html/track/TextTrack.h 2022-05-26 00:23:12 UTC (rev 294853)
+++ trunk/Source/WebCore/html/track/TextTrack.h 2022-05-26 00:47:32 UTC (rev 294854)
@@ -138,7 +138,8 @@
Document& document() const;
- bool hasCue(TextTrackCue&, TextTrackCue::CueMatchRules = TextTrackCue::MatchAllFields);
+ RefPtr<TextTrackCue> matchCue(TextTrackCue&, TextTrackCue::CueMatchRules = TextTrackCue::MatchAllFields);
+ bool hasCue(TextTrackCue& cue, TextTrackCue::CueMatchRules rules = TextTrackCue::MatchAllFields) { return matchCue(cue, rules); }
void setKind(Kind);
void newCuesAvailable(const TextTrackCueList&);