- Revision
- 198646
- Author
- [email protected]
- Date
- 2016-03-24 15:27:45 -0700 (Thu, 24 Mar 2016)
Log Message
[MSE] Make calling HTMLMediaElement.buffered less expensive
https://bugs.webkit.org/show_bug.cgi?id=155846
Reviewed by Eric Carlson.
The MSE specification requires a new TimeRanges object be returned when calling
HTMLMediaElement.buffered. Additionally, the requirements for generating the buffered time
ranges for MediaSource and its constituent SourceBuffers are specific and expensive. Rather
than perform all these steps each time HTMLMediaElement.buffered is queried, cache the final
result and only regenerate the cached value if the buffered ranges of the consituent
SourceBuffers has changed.
Also, make copying a PlatformTimeRanges more efficient by doing a straight vector-to-vector
copy of the PlatformTimeRange's data.
* Modules/mediasource/MediaSource.cpp:
(WebCore::MediaSource::buffered):
(WebCore::MediaSource::regenerateActiveSourceBuffers):
* Modules/mediasource/MediaSource.h:
* Modules/mediasource/SourceBuffer.cpp:
(WebCore::SourceBuffer::removeCodedFrames):
(WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample):
* Modules/mediasource/SourceBuffer.h:
* platform/graphics/PlatformTimeRanges.cpp:
(WebCore::PlatformTimeRanges::PlatformTimeRanges): Deleted.
(WebCore::PlatformTimeRanges::operator=): Deleted.
(WebCore::PlatformTimeRanges::copy): Deleted.
* platform/graphics/PlatformTimeRanges.h:
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (198645 => 198646)
--- trunk/Source/WebCore/ChangeLog 2016-03-24 22:20:52 UTC (rev 198645)
+++ trunk/Source/WebCore/ChangeLog 2016-03-24 22:27:45 UTC (rev 198646)
@@ -1,5 +1,36 @@
2016-03-24 Jer Noble <[email protected]>
+ [MSE] Make calling HTMLMediaElement.buffered less expensive
+ https://bugs.webkit.org/show_bug.cgi?id=155846
+
+ Reviewed by Eric Carlson.
+
+ The MSE specification requires a new TimeRanges object be returned when calling
+ HTMLMediaElement.buffered. Additionally, the requirements for generating the buffered time
+ ranges for MediaSource and its constituent SourceBuffers are specific and expensive. Rather
+ than perform all these steps each time HTMLMediaElement.buffered is queried, cache the final
+ result and only regenerate the cached value if the buffered ranges of the consituent
+ SourceBuffers has changed.
+
+ Also, make copying a PlatformTimeRanges more efficient by doing a straight vector-to-vector
+ copy of the PlatformTimeRange's data.
+
+ * Modules/mediasource/MediaSource.cpp:
+ (WebCore::MediaSource::buffered):
+ (WebCore::MediaSource::regenerateActiveSourceBuffers):
+ * Modules/mediasource/MediaSource.h:
+ * Modules/mediasource/SourceBuffer.cpp:
+ (WebCore::SourceBuffer::removeCodedFrames):
+ (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample):
+ * Modules/mediasource/SourceBuffer.h:
+ * platform/graphics/PlatformTimeRanges.cpp:
+ (WebCore::PlatformTimeRanges::PlatformTimeRanges): Deleted.
+ (WebCore::PlatformTimeRanges::operator=): Deleted.
+ (WebCore::PlatformTimeRanges::copy): Deleted.
+ * platform/graphics/PlatformTimeRanges.h:
+
+2016-03-24 Jer Noble <[email protected]>
+
REGRESSION(r189129): <audio> elements do not have playback controls on iOS.
https://bugs.webkit.org/show_bug.cgi?id=155808
<rdar://problem/23822457>
Modified: trunk/Source/WebCore/Modules/mediasource/MediaSource.cpp (198645 => 198646)
--- trunk/Source/WebCore/Modules/mediasource/MediaSource.cpp 2016-03-24 22:20:52 UTC (rev 198645)
+++ trunk/Source/WebCore/Modules/mediasource/MediaSource.cpp 2016-03-24 22:27:45 UTC (rev 198646)
@@ -141,13 +141,20 @@
std::unique_ptr<PlatformTimeRanges> MediaSource::buffered() const
{
+ if (m_buffered && m_activeSourceBuffers->length() && std::all_of(m_activeSourceBuffers->begin(), m_activeSourceBuffers->end(), [] (RefPtr<SourceBuffer>& buffer) { return !buffer->isBufferedDirty(); }))
+ return std::make_unique<PlatformTimeRanges>(*m_buffered);
+
+ m_buffered = std::make_unique<PlatformTimeRanges>();
+ for (auto& sourceBuffer : *m_activeSourceBuffers)
+ sourceBuffer->setBufferedDirty(false);
+
// Implements MediaSource algorithm for HTMLMediaElement.buffered.
// https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#htmlmediaelement-extensions
Vector<PlatformTimeRanges> activeRanges = this->activeRanges();
// 1. If activeSourceBuffers.length equals 0 then return an empty TimeRanges object and abort these steps.
if (activeRanges.isEmpty())
- return std::make_unique<PlatformTimeRanges>();
+ return std::make_unique<PlatformTimeRanges>(*m_buffered);
// 2. Let active ranges be the ranges returned by buffered for each SourceBuffer object in activeSourceBuffers.
// 3. Let highest end time be the largest range end time in the active ranges.
@@ -160,10 +167,10 @@
// Return an empty range if all ranges are empty.
if (!highestEndTime)
- return std::make_unique<PlatformTimeRanges>();
+ return std::make_unique<PlatformTimeRanges>(*m_buffered);
// 4. Let intersection ranges equal a TimeRange object containing a single range from 0 to highest end time.
- PlatformTimeRanges intersectionRanges(MediaTime::zeroTime(), highestEndTime);
+ m_buffered->add(MediaTime::zeroTime(), highestEndTime);
// 5. For each SourceBuffer object in activeSourceBuffers run the following steps:
bool ended = readyState() == endedKeyword();
@@ -175,10 +182,10 @@
// 5.3 Let new intersection ranges equal the the intersection between the intersection ranges and the source ranges.
// 5.4 Replace the ranges in intersection ranges with the new intersection ranges.
- intersectionRanges.intersectWith(sourceRanges);
+ m_buffered->intersectWith(sourceRanges);
}
- return std::make_unique<PlatformTimeRanges>(intersectionRanges);
+ return std::make_unique<PlatformTimeRanges>(*m_buffered);
}
void MediaSource::seekToTime(const MediaTime& time)
@@ -914,6 +921,8 @@
newList.append(sourceBuffer);
}
m_activeSourceBuffers->swap(newList);
+ for (auto& sourceBuffer : *m_activeSourceBuffers)
+ sourceBuffer->setBufferedDirty(true);
}
}
Modified: trunk/Source/WebCore/Modules/mediasource/MediaSource.h (198645 => 198646)
--- trunk/Source/WebCore/Modules/mediasource/MediaSource.h 2016-03-24 22:20:52 UTC (rev 198645)
+++ trunk/Source/WebCore/Modules/mediasource/MediaSource.h 2016-03-24 22:27:45 UTC (rev 198646)
@@ -136,6 +136,7 @@
RefPtr<MediaSourcePrivate> m_private;
RefPtr<SourceBufferList> m_sourceBuffers;
RefPtr<SourceBufferList> m_activeSourceBuffers;
+ mutable std::unique_ptr<PlatformTimeRanges> m_buffered;
HTMLMediaElement* m_mediaElement;
MediaTime m_duration;
MediaTime m_pendingSeekTime;
Modified: trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp (198645 => 198646)
--- trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp 2016-03-24 22:20:52 UTC (rev 198645)
+++ trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp 2016-03-24 22:27:45 UTC (rev 198646)
@@ -795,6 +795,7 @@
erasedRanges->invert();
m_buffered->intersectWith(*erasedRanges);
+ setBufferedDirty(true);
// 3.4 If this object is in activeSourceBuffers, the current playback position is greater than or equal to start
// and less than the remove end timestamp, and HTMLMediaElement.readyState is greater than HAVE_METADATA, then set
@@ -1605,6 +1606,7 @@
erasedRanges->invert();
m_buffered->intersectWith(*erasedRanges);
+ setBufferedDirty(true);
}
// 1.17 If spliced audio frame is set:
@@ -1645,6 +1647,7 @@
m_buffered->add(presentationTimestamp.toDouble(), (presentationTimestamp + frameDuration + microsecond).toDouble());
m_bufferedSinceLastMonitor += frameDuration.toDouble();
+ setBufferedDirty(true);
break;
} while (1);
Modified: trunk/Source/WebCore/Modules/mediasource/SourceBuffer.h (198645 => 198646)
--- trunk/Source/WebCore/Modules/mediasource/SourceBuffer.h 2016-03-24 22:20:52 UTC (rev 198645)
+++ trunk/Source/WebCore/Modules/mediasource/SourceBuffer.h 2016-03-24 22:27:45 UTC (rev 198646)
@@ -125,6 +125,9 @@
void rangeRemoval(const MediaTime&, const MediaTime&);
+ bool isBufferedDirty() const { return m_bufferedDirty; }
+ void setBufferedDirty(bool flag) { m_bufferedDirty = flag; }
+
// ActiveDOMObject API.
bool hasPendingActivity() const override;
@@ -225,6 +228,7 @@
HashMap<AtomicString, TrackBuffer> m_trackBufferMap;
RefPtr<TimeRanges> m_buffered;
+ bool m_bufferedDirty { true };
enum AppendStateType { WaitingForSegment, ParsingInitSegment, ParsingMediaSegment };
AppendStateType m_appendState;
Modified: trunk/Source/WebCore/platform/graphics/PlatformTimeRanges.cpp (198645 => 198646)
--- trunk/Source/WebCore/platform/graphics/PlatformTimeRanges.cpp 2016-03-24 22:20:52 UTC (rev 198645)
+++ trunk/Source/WebCore/platform/graphics/PlatformTimeRanges.cpp 2016-03-24 22:27:45 UTC (rev 198646)
@@ -36,25 +36,6 @@
add(start, end);
}
-PlatformTimeRanges::PlatformTimeRanges(const PlatformTimeRanges& other)
-{
- copy(other);
-}
-
-PlatformTimeRanges& PlatformTimeRanges::operator=(const PlatformTimeRanges& other)
-{
- return copy(other);
-}
-
-PlatformTimeRanges& PlatformTimeRanges::copy(const PlatformTimeRanges& other)
-{
- unsigned size = other.m_ranges.size();
- for (unsigned i = 0; i < size; i++)
- add(other.m_ranges[i].m_start, other.m_ranges[i].m_end);
-
- return *this;
-}
-
void PlatformTimeRanges::invert()
{
PlatformTimeRanges inverted;
Modified: trunk/Source/WebCore/platform/graphics/PlatformTimeRanges.h (198645 => 198646)
--- trunk/Source/WebCore/platform/graphics/PlatformTimeRanges.h 2016-03-24 22:20:52 UTC (rev 198645)
+++ trunk/Source/WebCore/platform/graphics/PlatformTimeRanges.h 2016-03-24 22:27:45 UTC (rev 198646)
@@ -42,10 +42,7 @@
public:
explicit PlatformTimeRanges() { }
PlatformTimeRanges(const MediaTime& start, const MediaTime& end);
- PlatformTimeRanges(const PlatformTimeRanges&);
- PlatformTimeRanges& operator=(const PlatformTimeRanges&);
-
MediaTime start(unsigned index) const;
MediaTime start(unsigned index, bool& valid) const;
MediaTime end(unsigned index) const;
@@ -72,8 +69,6 @@
void dump(WTF::PrintStream&) const;
private:
- PlatformTimeRanges& copy(const PlatformTimeRanges&);
-
// We consider all the Ranges to be semi-bounded as follow: [start, end[
struct Range {
Range() { }