- Revision
- 275949
- Author
- [email protected]
- Date
- 2021-04-14 09:53:26 -0700 (Wed, 14 Apr 2021)
Log Message
Allow text tracks to purge cues outside of the buffered range
https://bugs.webkit.org/show_bug.cgi?id=224489
Reviewed by Jer Noble.
TextTrackCues associated in-band tracks live "forever" - until the video element
is deleted or reloaded. This is fine for relatively short files, but not so good
for long lived files (eg. a very long live stream), or for timed metadata where
the "cue" size can be much larger than a text sample.
Allow text tracks to opt in to purging cues who's time range does not intersect
with the `buffered` range, where audio and video data is also not available. Only
AVFoundation backed in-band tracks opt in at this time, because AVFoundation will
redeliver cues if a time range is played again.
Tested manually as the only way to test this currently would be with an HLS stream
that would have to play too long for a layout test, or with an MSE text track but
we won't support text tracks in MSE yet.
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::mediaPlayerBufferedTimeRangesChanged): Allow tracks
that support purging cues to do so.
* html/HTMLMediaElement.h:
* html/track/InbandDataTextTrack.h: Return true for shouldPurgeCuesFromUnbufferedRanges();
* html/track/InbandGenericTextTrack.h: Ditto.
* html/track/TextTrack.cpp:
(WebCore::TextTrack::removeCuesNotInTimeRanges): Remove all cues who's time range
does not intersect with the buffered range.
* html/track/TextTrack.h:
(WebCore::TextTrack::shouldPurgeCuesFromUnbufferedRanges const):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (275948 => 275949)
--- trunk/Source/WebCore/ChangeLog 2021-04-14 16:19:42 UTC (rev 275948)
+++ trunk/Source/WebCore/ChangeLog 2021-04-14 16:53:26 UTC (rev 275949)
@@ -1,3 +1,39 @@
+2021-04-14 Eric Carlson <[email protected]>
+
+ Allow text tracks to purge cues outside of the buffered range
+ https://bugs.webkit.org/show_bug.cgi?id=224489
+
+ Reviewed by Jer Noble.
+
+ TextTrackCues associated in-band tracks live "forever" - until the video element
+ is deleted or reloaded. This is fine for relatively short files, but not so good
+ for long lived files (eg. a very long live stream), or for timed metadata where
+ the "cue" size can be much larger than a text sample.
+
+ Allow text tracks to opt in to purging cues who's time range does not intersect
+ with the `buffered` range, where audio and video data is also not available. Only
+ AVFoundation backed in-band tracks opt in at this time, because AVFoundation will
+ redeliver cues if a time range is played again.
+
+ Tested manually as the only way to test this currently would be with an HLS stream
+ that would have to play too long for a layout test, or with an MSE text track but
+ we won't support text tracks in MSE yet.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::mediaPlayerBufferedTimeRangesChanged): Allow tracks
+ that support purging cues to do so.
+ * html/HTMLMediaElement.h:
+
+ * html/track/InbandDataTextTrack.h: Return true for shouldPurgeCuesFromUnbufferedRanges();
+
+ * html/track/InbandGenericTextTrack.h: Ditto.
+
+ * html/track/TextTrack.cpp:
+ (WebCore::TextTrack::removeCuesNotInTimeRanges): Remove all cues who's time range
+ does not intersect with the buffered range.
+ * html/track/TextTrack.h:
+ (WebCore::TextTrack::shouldPurgeCuesFromUnbufferedRanges const):
+
2021-04-14 Antti Koivisto <[email protected]>
Remove unused InlineBox::next/previousLeafOnLineIgnoringLineBreak()
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (275948 => 275949)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2021-04-14 16:19:42 UTC (rev 275948)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2021-04-14 16:53:26 UTC (rev 275949)
@@ -7088,6 +7088,39 @@
return true;
}
+void HTMLMediaElement::mediaPlayerBufferedTimeRangesChanged()
+{
+ if (!m_textTracks || m_bufferedTimeRangesChangedQueue.hasPendingTask())
+ return;
+
+ auto logSiteIdentifier = LOGIDENTIFIER;
+ ALWAYS_LOG(logSiteIdentifier, "task scheduled");
+ m_bufferedTimeRangesChangedQueue.scheduleTask([this, logSiteIdentifier] {
+ UNUSED_PARAM(logSiteIdentifier);
+ ALWAYS_LOG(logSiteIdentifier, "lambda(), task fired");
+ if (!m_player || !m_textTracks)
+ return;
+
+ std::unique_ptr<PlatformTimeRanges> buffered;
+ for (unsigned i = 0; i < m_textTracks->length(); ++i) {
+ auto& track = *m_textTracks->item(i);
+ if (!track.shouldPurgeCuesFromUnbufferedRanges())
+ continue;
+
+ if (!buffered) {
+#if ENABLE(MEDIA_SOURCE)
+ if (m_mediaSource)
+ buffered = m_mediaSource->buffered();
+ else
+#endif
+ buffered = m_player->buffered();
+
+ track.removeCuesNotInTimeRanges(*buffered);
+ }
+ }
+ });
+}
+
#if USE(GSTREAMER)
void HTMLMediaElement::requestInstallMissingPlugins(const String& details, const String& description, MediaPlayerRequestInstallMissingPluginsCallback& callback)
{
Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (275948 => 275949)
--- trunk/Source/WebCore/html/HTMLMediaElement.h 2021-04-14 16:19:42 UTC (rev 275948)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h 2021-04-14 16:53:26 UTC (rev 275949)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -739,6 +739,7 @@
bool mediaPlayerShouldDisableSleep() const final { return shouldDisableSleep() == SleepType::Display; }
bool mediaPlayerShouldCheckHardwareSupport() const final;
const Vector<ContentType>& mediaContentTypesRequiringHardwareSupport() const final;
+ void mediaPlayerBufferedTimeRangesChanged() final;
#if USE(GSTREAMER)
void requestInstallMissingPlugins(const String& details, const String& description, MediaPlayerRequestInstallMissingPluginsCallback&) final;
@@ -948,6 +949,7 @@
DeferrableTask<Timer> m_resumeTaskQueue;
DeferrableTask<Timer> m_seekTaskQueue;
DeferrableTask<Timer> m_playbackControlsManagerBehaviorRestrictionsQueue;
+ DeferrableTask<Timer> m_bufferedTimeRangesChangedQueue;
GenericTaskQueue<Timer> m_promiseTaskQueue;
GenericTaskQueue<Timer> m_pauseAfterDetachedTaskQueue;
GenericTaskQueue<Timer> m_resourceSelectionTaskQueue;
Modified: trunk/Source/WebCore/html/track/InbandDataTextTrack.h (275948 => 275949)
--- trunk/Source/WebCore/html/track/InbandDataTextTrack.h 2021-04-14 16:19:42 UTC (rev 275948)
+++ trunk/Source/WebCore/html/track/InbandDataTextTrack.h 2021-04-14 16:53:26 UTC (rev 275949)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 Cable Television Labs Inc. All rights reserved.
- * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -45,6 +45,8 @@
void addDataCue(const MediaTime& start, const MediaTime& end, const void*, unsigned) final;
+ bool shouldPurgeCuesFromUnbufferedRanges() const final { return true; }
+
#if !RELEASE_LOG_DISABLED
const char* logClassName() const final { return "DataCue"; }
#endif
Modified: trunk/Source/WebCore/html/track/InbandGenericTextTrack.h (275948 => 275949)
--- trunk/Source/WebCore/html/track/InbandGenericTextTrack.h 2021-04-14 16:19:42 UTC (rev 275948)
+++ trunk/Source/WebCore/html/track/InbandGenericTextTrack.h 2021-04-14 16:53:26 UTC (rev 275949)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -75,6 +75,8 @@
void newStyleSheetsParsed() final;
void fileFailedToParse() final;
+ bool shouldPurgeCuesFromUnbufferedRanges() const final { return true; }
+
#if !RELEASE_LOG_DISABLED
const char* logClassName() const final { return "InbandGenericTextTrack"; }
#endif
Modified: trunk/Source/WebCore/html/track/TextTrack.cpp (275948 => 275949)
--- trunk/Source/WebCore/html/track/TextTrack.cpp 2021-04-14 16:19:42 UTC (rev 275948)
+++ trunk/Source/WebCore/html/track/TextTrack.cpp 2021-04-14 16:53:26 UTC (rev 275949)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011, 2013 Google Inc. All rights reserved.
- * Copyright (C) 2011-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -370,6 +370,33 @@
return { };
}
+void TextTrack::removeCuesNotInTimeRanges(PlatformTimeRanges& buffered)
+{
+ ASSERT(shouldPurgeCuesFromUnbufferedRanges());
+
+ if (!m_cues)
+ return;
+
+ Vector<Ref<TextTrackCue>> toPurge;
+ for (size_t i = 0; i < m_cues->length(); ++i) {
+ auto cue = m_cues->item(i);
+ ASSERT(cue->track() == this);
+
+ PlatformTimeRanges activeCueRange { cue->startMediaTime(), cue->endMediaTime() };
+ activeCueRange.intersectWith(buffered);
+ if (!activeCueRange.length())
+ toPurge.append(*cue);
+ }
+
+ if (!toPurge.size())
+ return;
+
+ INFO_LOG(LOGIDENTIFIER, "purging ", toPurge.size());
+
+ for (auto& cue : toPurge)
+ removeCue(cue);
+}
+
VTTRegionList& TextTrack::ensureVTTRegionList()
{
if (!m_regions)
Modified: trunk/Source/WebCore/html/track/TextTrack.h (275948 => 275949)
--- trunk/Source/WebCore/html/track/TextTrack.h 2021-04-14 16:19:42 UTC (rev 275948)
+++ trunk/Source/WebCore/html/track/TextTrack.h 2021-04-14 16:53:26 UTC (rev 275949)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
- * Copyright (C) 2011-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,6 +29,7 @@
#if ENABLE(VIDEO)
#include "ContextDestructionObserver.h"
+#include "PlatformTimeRanges.h"
#include "TextTrackCue.h"
#include "TrackBase.h"
@@ -134,6 +135,9 @@
const Optional<Vector<String>>& styleSheets() const { return m_styleSheets; }
+ virtual bool shouldPurgeCuesFromUnbufferedRanges() const { return false; }
+ virtual void removeCuesNotInTimeRanges(PlatformTimeRanges&);
+
protected:
TextTrack(ScriptExecutionContext*, TextTrackClient*, const AtomString& kind, const AtomString& id, const AtomString& label, const AtomString& language, TextTrackType);