Title: [171616] trunk/Source/WebCore
- Revision
- 171616
- Author
- [email protected]
- Date
- 2014-07-25 14:35:28 -0700 (Fri, 25 Jul 2014)
Log Message
[MSE] High CPU usage in SampleMap::findSamplesWithinPresentationRange() with a large number of buffered samples.
https://bugs.webkit.org/show_bug.cgi?id=135247
Reviewed by Geoffrey Garen.
Anchor our search for overlapping frames to the end of the search range when the overlap range is sufficiently
close to the end of the search range. The common case for this search is when a sample is about to be appended
to the end of the sample queue, so this should turn most searches into no-ops.
* Modules/mediasource/SampleMap.cpp:
(WebCore::PresentationOrderSampleMap::findSamplesWithinPresentationRangeFromEnd):
* Modules/mediasource/SampleMap.h:
* Modules/mediasource/SourceBuffer.cpp:
(WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (171615 => 171616)
--- trunk/Source/WebCore/ChangeLog 2014-07-25 21:31:07 UTC (rev 171615)
+++ trunk/Source/WebCore/ChangeLog 2014-07-25 21:35:28 UTC (rev 171616)
@@ -1,3 +1,20 @@
+2014-07-25 Jer Noble <[email protected]>
+
+ [MSE] High CPU usage in SampleMap::findSamplesWithinPresentationRange() with a large number of buffered samples.
+ https://bugs.webkit.org/show_bug.cgi?id=135247
+
+ Reviewed by Geoffrey Garen.
+
+ Anchor our search for overlapping frames to the end of the search range when the overlap range is sufficiently
+ close to the end of the search range. The common case for this search is when a sample is about to be appended
+ to the end of the sample queue, so this should turn most searches into no-ops.
+
+ * Modules/mediasource/SampleMap.cpp:
+ (WebCore::PresentationOrderSampleMap::findSamplesWithinPresentationRangeFromEnd):
+ * Modules/mediasource/SampleMap.h:
+ * Modules/mediasource/SourceBuffer.cpp:
+ (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample):
+
2014-07-25 Gavin Barraclough <[email protected]>
Yosemite version number is 101000
Modified: trunk/Source/WebCore/Modules/mediasource/SampleMap.cpp (171615 => 171616)
--- trunk/Source/WebCore/Modules/mediasource/SampleMap.cpp 2014-07-25 21:31:07 UTC (rev 171615)
+++ trunk/Source/WebCore/Modules/mediasource/SampleMap.cpp 2014-07-25 21:35:28 UTC (rev 171616)
@@ -238,6 +238,19 @@
return std::equal_range(begin(), end(), range, SamplePresentationTimeIsWithinRangeComparator());
}
+PresentationOrderSampleMap::iterator_range PresentationOrderSampleMap::findSamplesWithinPresentationRangeFromEnd(const MediaTime& beginTime, const MediaTime& endTime)
+{
+ reverse_iterator rangeEnd = std::find_if(rbegin(), rend(), [&beginTime] (PresentationOrderSampleMap::MapType::value_type value) {
+ return value.second->presentationTime() <= beginTime;
+ });
+
+ reverse_iterator rangeStart = std::find_if(rbegin(), rangeEnd, [&endTime] (PresentationOrderSampleMap::MapType::value_type value) {
+ return value.second->presentationTime() <= endTime;
+ });
+
+ return iterator_range(rangeStart.base(), rangeEnd.base());
+}
+
DecodeOrderSampleMap::reverse_iterator_range DecodeOrderSampleMap::findDependentSamples(MediaSample* sample)
{
ASSERT(sample);
Modified: trunk/Source/WebCore/Modules/mediasource/SampleMap.h (171615 => 171616)
--- trunk/Source/WebCore/Modules/mediasource/SampleMap.h 2014-07-25 21:31:07 UTC (rev 171615)
+++ trunk/Source/WebCore/Modules/mediasource/SampleMap.h 2014-07-25 21:35:28 UTC (rev 171616)
@@ -57,6 +57,7 @@
reverse_iterator reverseFindSampleBeforePresentationTime(const MediaTime&);
iterator_range findSamplesBetweenPresentationTimes(const MediaTime&, const MediaTime&);
iterator_range findSamplesWithinPresentationRange(const MediaTime&, const MediaTime&);
+ iterator_range findSamplesWithinPresentationRangeFromEnd(const MediaTime&, const MediaTime&);
private:
MapType m_samples;
Modified: trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp (171615 => 171616)
--- trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp 2014-07-25 21:31:07 UTC (rev 171615)
+++ trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp 2014-07-25 21:35:28 UTC (rev 171616)
@@ -1145,9 +1145,29 @@
if (trackBuffer.highestPresentationTimestamp.isValid() && trackBuffer.highestPresentationTimestamp <= presentationTimestamp) {
// Remove all coded frames from track buffer that have a presentation timestamp greater than highest
// presentation timestamp and less than or equal to frame end timestamp.
- auto iter_pair = trackBuffer.samples.presentationOrder().findSamplesWithinPresentationRange(trackBuffer.highestPresentationTimestamp, frameEndTimestamp);
- if (iter_pair.first != trackBuffer.samples.presentationOrder().end())
- erasedSamples.addRange(iter_pair.first, iter_pair.second);
+ do {
+ // NOTE: Searching from the end of the trackBuffer will be vastly more efficient if the search range is
+ // near the end of the buffered range. Use a linear-backwards search if the search range is within one
+ // frame duration of the end:
+ if (!m_buffered)
+ break;
+
+ unsigned bufferedLength = m_buffered->ranges().length();
+ if (!bufferedLength)
+ break;
+
+ bool ignoreValid;
+ MediaTime highestBufferedTime = m_buffered->ranges().end(bufferedLength - 1, ignoreValid);
+
+ PresentationOrderSampleMap::iterator_range range;
+ if (highestBufferedTime - trackBuffer.highestPresentationTimestamp < trackBuffer.lastFrameDuration)
+ range = trackBuffer.samples.presentationOrder().findSamplesWithinPresentationRangeFromEnd(trackBuffer.highestPresentationTimestamp, frameEndTimestamp);
+ else
+ range = trackBuffer.samples.presentationOrder().findSamplesWithinPresentationRange(trackBuffer.highestPresentationTimestamp, frameEndTimestamp);
+
+ if (range.first != trackBuffer.samples.presentationOrder().end())
+ erasedSamples.addRange(range.first, range.second);
+ } while(false);
}
// 1.16 Remove decoding dependencies of the coded frames removed in the previous step:
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes