<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[212057] branches/safari-603-branch</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/212057">212057</a></dd>
<dt>Author</dt> <dd>matthew_hanson@apple.com</dd>
<dt>Date</dt> <dd>2017-02-09 22:36:35 -0800 (Thu, 09 Feb 2017)</dd>
</dl>
<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/211746">r211746</a>. rdar://problem/30107622</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari603branchPerformanceTestsChangeLog">branches/safari-603-branch/PerformanceTests/ChangeLog</a></li>
<li><a href="#branchessafari603branchPerformanceTestsMediamediasourceloaderjs">branches/safari-603-branch/PerformanceTests/Media/media-source-loader.js</a></li>
<li><a href="#branchessafari603branchPerformanceTestsSkipped">branches/safari-603-branch/PerformanceTests/Skipped</a></li>
<li><a href="#branchessafari603branchSourceWTFChangeLog">branches/safari-603-branch/Source/WTF/ChangeLog</a></li>
<li><a href="#branchessafari603branchSourceWTFwtfMediaTimecpp">branches/safari-603-branch/Source/WTF/wtf/MediaTime.cpp</a></li>
<li><a href="#branchessafari603branchSourceWTFwtfMediaTimeh">branches/safari-603-branch/Source/WTF/wtf/MediaTime.h</a></li>
<li><a href="#branchessafari603branchSourceWebCoreChangeLog">branches/safari-603-branch/Source/WebCore/ChangeLog</a></li>
<li><a href="#branchessafari603branchSourceWebCoreModulesmediasourceSampleMapcpp">branches/safari-603-branch/Source/WebCore/Modules/mediasource/SampleMap.cpp</a></li>
<li><a href="#branchessafari603branchSourceWebCoreModulesmediasourceSampleMaph">branches/safari-603-branch/Source/WebCore/Modules/mediasource/SampleMap.h</a></li>
<li><a href="#branchessafari603branchSourceWebCoreModulesmediasourceSourceBuffercpp">branches/safari-603-branch/Source/WebCore/Modules/mediasource/SourceBuffer.cpp</a></li>
<li><a href="#branchessafari603branchSourceWebCoreWebCorexcodeprojprojectpbxproj">branches/safari-603-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#branchessafari603branchToolsChangeLog">branches/safari-603-branch/Tools/ChangeLog</a></li>
<li><a href="#branchessafari603branchToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj">branches/safari-603-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj</a></li>
<li><a href="#branchessafari603branchToolsTestWebKitAPITestsWTFMediaTimecpp">branches/safari-603-branch/Tools/TestWebKitAPI/Tests/WTF/MediaTime.cpp</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#branchessafari603branchPerformanceTestsMediaMSERemoveCodedFrameshtml">branches/safari-603-branch/PerformanceTests/Media/MSERemoveCodedFrames.html</a></li>
<li>branches/safari-603-branch/PerformanceTests/MediaTime/</li>
<li>branches/safari-603-branch/PerformanceTests/MediaTime/Configurations/</li>
<li><a href="#branchessafari603branchPerformanceTestsMediaTimeConfigurationsBasexcconfig">branches/safari-603-branch/PerformanceTests/MediaTime/Configurations/Base.xcconfig</a></li>
<li><a href="#branchessafari603branchPerformanceTestsMediaTimeConfigurationsDebugReleasexcconfig">branches/safari-603-branch/PerformanceTests/MediaTime/Configurations/DebugRelease.xcconfig</a></li>
<li><a href="#branchessafari603branchPerformanceTestsMediaTimeMakefile">branches/safari-603-branch/PerformanceTests/MediaTime/Makefile</a></li>
<li>branches/safari-603-branch/PerformanceTests/MediaTime/MediaTime.xcodeproj/</li>
<li><a href="#branchessafari603branchPerformanceTestsMediaTimeMediaTimexcodeprojprojectpbxproj">branches/safari-603-branch/PerformanceTests/MediaTime/MediaTime.xcodeproj/project.pbxproj</a></li>
<li><a href="#branchessafari603branchPerformanceTestsMediaTimemaincpp">branches/safari-603-branch/PerformanceTests/MediaTime/main.cpp</a></li>
<li><a href="#branchessafari603branchToolsTestWebKitAPITestsWebCoreSampleMapcpp">branches/safari-603-branch/Tools/TestWebKitAPI/Tests/WebCore/SampleMap.cpp</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari603branchPerformanceTestsChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/PerformanceTests/ChangeLog (212056 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/PerformanceTests/ChangeLog        2017-02-10 06:36:27 UTC (rev 212056)
+++ branches/safari-603-branch/PerformanceTests/ChangeLog        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -1,3 +1,34 @@
</span><ins>+2017-02-09 Matthew Hanson <matthew_hanson@apple.com>
+
+ Merge r211746. rdar://problem/30107622
+
+ 2017-02-06 Jer Noble <jer.noble@apple.com>
+
+ Playback stalls when a SourceBuffer append causes frame eviction
+ https://bugs.webkit.org/show_bug.cgi?id=167834
+
+ Reviewed by Eric Carlson.
+
+ Add an in-page performance test measuring the amount of time required
+ to append a large amount of media data to a SourceBuffer, and then to
+ completely remove that data 30s at a time.
+
+ Add a microbenchmark for MediaTime which measures the amount of time
+ required to create a 1M entry std::map and traverse the map 1M times.
+
+ * Media/MSERemoveCodedFrames.html: Added.
+ * Media/media-source-loader.js:
+ (MediaSourceLoader.prototype.get duration):
+ * MediaTime/Configurations/Base.xcconfig: Added.
+ * MediaTime/Configurations/DebugRelease.xcconfig: Added.
+ * MediaTime/Makefile: Added.
+ * MediaTime/MediaTime.xcodeproj/project.pbxproj: Added.
+ * MediaTime/main.cpp: Added.
+ (performTest):
+ (test):
+ (main):
+ * Skipped:
+
</ins><span class="cx"> 2016-12-13 Brady Eidson <beidson@apple.com>
</span><span class="cx">
</span><span class="cx"> Add a PerfTest targeting IDBObjectStore.get().
</span></span></pre></div>
<a id="branchessafari603branchPerformanceTestsMediaMSERemoveCodedFrameshtml"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/PerformanceTests/Media/MSERemoveCodedFrames.html (0 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/PerformanceTests/Media/MSERemoveCodedFrames.html         (rev 0)
+++ branches/safari-603-branch/PerformanceTests/Media/MSERemoveCodedFrames.html        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -0,0 +1,122 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<script src="media-source-loader.js"></script>
+<script src="../resources/runner.js"></script>
+<script>
+var loader;
+var video;
+var longMediaSegment;
+
+function concatArrayBuffers() {
+ var byteLength = 0;
+ Array.prototype.forEach.call(arguments, arrayBuffer => {
+ if (!arrayBuffer.byteLength)
+ throw "Not an ArrayBuffer!";
+ byteLength += arrayBuffer.byteLength;
+ });
+
+
+ var view = new Uint8Array(byteLength);
+ var offset = 0;
+ Array.prototype.forEach.call(arguments, arrayBuffer => {
+ view.set(new Uint8Array(arrayBuffer), offset);
+ offset += arrayBuffer.byteLength;
+ });
+ return view.buffer;
+}
+
+function concatMediaData() {
+ return new Promise((resolve, reject) => {
+ var segments = new Array(100);
+ segments.fill(loader.everyMediaSegment);
+ longMediaSegment = concatArrayBuffers.apply(this, segments);
+ resolve(longMediaSegment);
+ });
+}
+
+window.addEventListener('load', () => {
+ PerfTestRunner.prepareToMeasureValuesAsync({
+ unit: 'ms',
+ done: function () {
+ if (video) {
+ video.src = null;
+ video.load();
+ }
+ }
+ });
+
+ loader = new MediaSourceLoader('test-fragmented-video.json');
+ loader.loadMediaData().then(concatMediaData).then(runTest);
+});
+
+function remove30SecondsAtATimeTillEmpty(sourceBuffer) {
+ return new Promise(resolve => {
+ var removeNext30Seconds = () => {
+ var start = sourceBuffer.buffered.start(0);
+ sourceBuffer.remove(start, start + 30)
+ }
+ sourceBuffer.onupdate = () => {
+ if (sourceBuffer.buffered.length == 0 || sourceBuffer.buffered.start(0) - sourceBuffer.buffered.end(0) == 0) {
+ sourceBuffer.onupdate = null;
+ resolve();
+ return;
+ }
+
+ removeNext30Seconds();
+ };
+ removeNext30Seconds();
+ });
+}
+
+function runTest() {
+ video = document.createElement('video');
+
+ loadMediaDataIntoVideo(video).then(sourceBuffer => {
+ startTime = PerfTestRunner.now();
+ return remove30SecondsAtATimeTillEmpty(sourceBuffer);
+ }).then(() => {
+ if (PerfTestRunner.measureValueAsync(PerfTestRunner.now() - startTime))
+ setTimeout(runTest, 0);
+ });
+}
+
+function loadMediaDataIntoVideo(video, segmentCount) {
+ return new Promise((resolve, reject) => {
+ var source = new MediaSource();
+ source.onsourceopen = () => {
+ source.onsourceopen = null;
+ source.duration = loader.duration * 100;
+ var currentMediaSegment = 0;
+ var sourceBuffer = source.addSourceBuffer(loader.type);
+ sourceBuffer.mode = 'sequence';
+ sourceBuffer.appendBuffer(loader.initSegment);
+
+ var appendedMediaSegment = false;
+ sourceBuffer.onupdate = () => {
+
+ if (appendedMediaSegment) {
+ if (source.readyState !== 'ended') {
+ source.endOfStream();
+ sourceBuffer.onupdate = null;
+ sourceBuffer.onerror = null;
+ resolve(sourceBuffer);
+ }
+ return;
+ }
+
+ sourceBuffer.appendBuffer(longMediaSegment);
+ appendedMediaSegment = true;
+ };
+ sourceBuffer.onerror = error => {
+ reject(error);
+ };
+ };
+ video.src = URL.createObjectURL(source);
+ });
+}
+</script>
+</head>
+<body>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="branchessafari603branchPerformanceTestsMediamediasourceloaderjs"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/PerformanceTests/Media/media-source-loader.js (212056 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/PerformanceTests/Media/media-source-loader.js        2017-02-10 06:36:27 UTC (rev 212056)
+++ branches/safari-603-branch/PerformanceTests/Media/media-source-loader.js        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -87,7 +87,9 @@
</span><span class="cx">
</span><span class="cx"> get duration()
</span><span class="cx"> {
</span><del>- return this._manifest ? this._manifest.duration : 0
</del><ins>+ if (!this._manifest)
+ return 0;
+ return this._manifest.media.reduce((duration, media) => { return duration + media.duration }, 0);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> get initSegment()
</span></span></pre></div>
<a id="branchessafari603branchPerformanceTestsMediaTimeConfigurationsBasexcconfig"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/PerformanceTests/MediaTime/Configurations/Base.xcconfig (0 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/PerformanceTests/MediaTime/Configurations/Base.xcconfig         (rev 0)
+++ branches/safari-603-branch/PerformanceTests/MediaTime/Configurations/Base.xcconfig        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -0,0 +1,119 @@
</span><ins>+// Copyright (C) 2009, 2010, 2011, 2013 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 met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "../../../../Internal/Configurations/HaveInternalSDK.xcconfig"
+
+USE_INTERNAL_SDK = $(USE_INTERNAL_SDK_$(CONFIGURATION));
+USE_INTERNAL_SDK_Production = YES;
+USE_INTERNAL_SDK_Debug = $(HAVE_INTERNAL_SDK);
+USE_INTERNAL_SDK_Release = $(HAVE_INTERNAL_SDK);
+
+CLANG_CXX_LANGUAGE_STANDARD = gnu++14;
+CLANG_CXX_LIBRARY = libc++;
+CLANG_WARN_BOOL_CONVERSION = YES;
+CLANG_WARN_CONSTANT_CONVERSION = YES;
+CLANG_WARN_CXX0X_EXTENSIONS = NO;
+CLANG_WARN_EMPTY_BODY = YES;
+CLANG_WARN_ENUM_CONVERSION = YES;
+CLANG_WARN_INFINITE_RECURSION = YES;
+CLANG_WARN_INT_CONVERSION = YES;
+CLANG_WARN_SUSPICIOUS_MOVE = YES;
+CLANG_WARN_UNREACHABLE_CODE = YES;
+CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+COMBINE_HIDPI_IMAGES = NO;
+DEBUG_INFORMATION_FORMAT = dwarf-with-dsym;
+ENABLE_STRICT_OBJC_MSGSEND = YES;
+GCC_C_LANGUAGE_STANDARD = gnu99;
+GCC_DEBUGGING_SYMBOLS = default;
+GCC_DYNAMIC_NO_PIC = NO;
+GCC_ENABLE_CPP_EXCEPTIONS = NO;
+GCC_ENABLE_CPP_RTTI = NO;
+GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+GCC_ENABLE_SYMBOL_SEPARATION = NO;
+GCC_FAST_OBJC_DISPATCH = YES;
+GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
+GCC_NO_COMMON_BLOCKS = YES;
+GCC_OBJC_CALL_CXX_CDTORS = YES;
+GCC_PRECOMPILE_PREFIX_HEADER = YES;
+GCC_PREPROCESSOR_DEFINITIONS = $(DEBUG_DEFINES) $(inherited);
+GCC_STRICT_ALIASING = YES;
+GCC_THREADSAFE_STATICS = NO;
+GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+// FIXME: <http://webkit.org/b/107093> WTF should build with -Wshorten-64-to-32
+GCC_WARN_64_TO_32_BIT_CONVERSION = $(GCC_WARN_64_TO_32_BIT_CONVERSION_$(CURRENT_ARCH));
+GCC_WARN_64_TO_32_BIT_CONVERSION_ = YES;
+GCC_WARN_64_TO_32_BIT_CONVERSION_armv7 = YES;
+GCC_WARN_64_TO_32_BIT_CONVERSION_armv7k = YES;
+GCC_WARN_64_TO_32_BIT_CONVERSION_armv7s = YES;
+GCC_WARN_64_TO_32_BIT_CONVERSION_arm64 = NO;
+GCC_WARN_64_TO_32_BIT_CONVERSION_i386 = YES;
+GCC_WARN_64_TO_32_BIT_CONVERSION_x86_64 = NO;
+GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
+GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
+GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+GCC_WARN_ABOUT_RETURN_TYPE = YES;
+GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
+GCC_WARN_SIGN_COMPARE = YES;
+GCC_WARN_UNDECLARED_SELECTOR = YES;
+GCC_WARN_UNINITIALIZED_AUTOS = YES;
+GCC_WARN_UNUSED_FUNCTION = YES;
+GCC_WARN_UNUSED_VARIABLE = YES;
+PREBINDING = NO;
+WARNING_CFLAGS = -Wall -Wextra -Wcast-qual -Wchar-subscripts -Wextra-tokens -Wformat=2 -Winit-self -Wmissing-format-attribute -Wmissing-noreturn -Wpacked -Wpointer-arith -Wredundant-decls -Wundef -Wwrite-strings -Wexit-time-destructors -Wglobal-constructors -Wtautological-compare -Wimplicit-fallthrough;
+HEADER_SEARCH_PATHS = $(BUILT_PRODUCTS_DIR)/usr/local/include $(DSTROOT)/usr/local/include icu $(HEADER_SEARCH_PATHS);
+
+TARGET_MAC_OS_X_VERSION_MAJOR = $(TARGET_MAC_OS_X_VERSION_MAJOR$(MACOSX_DEPLOYMENT_TARGET:suffix:identifier));
+TARGET_MAC_OS_X_VERSION_MAJOR_10 = 101000;
+TARGET_MAC_OS_X_VERSION_MAJOR_11 = 101100;
+TARGET_MAC_OS_X_VERSION_MAJOR_12 = 101200;
+TARGET_MAC_OS_X_VERSION_MAJOR_13 = 101300;
+
+SUPPORTED_PLATFORMS = iphoneos iphonesimulator macosx appletvos appletvsimulator watchos watchsimulator;
+
+JAVASCRIPTCORE_FRAMEWORKS_DIR = $(SYSTEM_LIBRARY_DIR)/Frameworks;
+
+// DEBUG_DEFINES, GCC_OPTIMIZATION_LEVEL, STRIP_INSTALLED_PRODUCT and DEAD_CODE_STRIPPING vary between the debug and normal variants.
+// We set up the values for each variant here, and have the Debug configuration in the Xcode project use the _debug variant.
+DEBUG_DEFINES_debug = ;
+DEBUG_DEFINES_normal = NDEBUG;
+DEBUG_DEFINES = $(DEBUG_DEFINES_$(CURRENT_VARIANT));
+
+GCC_OPTIMIZATION_LEVEL = $(GCC_OPTIMIZATION_LEVEL_$(CURRENT_VARIANT));
+GCC_OPTIMIZATION_LEVEL_normal = 3;
+GCC_OPTIMIZATION_LEVEL_debug = 0;
+
+STRIP_INSTALLED_PRODUCT = $(STRIP_INSTALLED_PRODUCT_$(CURRENT_VARIANT));
+STRIP_INSTALLED_PRODUCT_normal = YES;
+STRIP_INSTALLED_PRODUCT_debug = NO;
+
+DEAD_CODE_STRIPPING_debug = NO;
+DEAD_CODE_STRIPPING_normal = YES;
+DEAD_CODE_STRIPPING = $(DEAD_CODE_STRIPPING_$(CURRENT_VARIANT));
+
+SDKROOT = macosx.internal;
+
+OTHER_CFLAGS = $(ASAN_OTHER_CFLAGS);
+OTHER_CPLUSPLUSFLAGS = $(ASAN_OTHER_CPLUSPLUSFLAGS);
+OTHER_LDFLAGS = $(ASAN_OTHER_LDFLAGS);
</ins></span></pre></div>
<a id="branchessafari603branchPerformanceTestsMediaTimeConfigurationsDebugReleasexcconfig"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/PerformanceTests/MediaTime/Configurations/DebugRelease.xcconfig (0 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/PerformanceTests/MediaTime/Configurations/DebugRelease.xcconfig         (rev 0)
+++ branches/safari-603-branch/PerformanceTests/MediaTime/Configurations/DebugRelease.xcconfig        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -0,0 +1,42 @@
</span><ins>+// Copyright (C) 2009, 2010, 2013 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 met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "Base.xcconfig"
+
+ARCHS = $(ARCHS_STANDARD_32_64_BIT);
+ONLY_ACTIVE_ARCH = YES;
+
+TARGET_MAC_OS_X_VERSION_MAJOR = $(MAC_OS_X_VERSION_MAJOR);
+
+MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(PLATFORM_NAME)_$(TARGET_MAC_OS_X_VERSION_MAJOR));
+MACOSX_DEPLOYMENT_TARGET_macosx_101000 = 10.10;
+MACOSX_DEPLOYMENT_TARGET_macosx_101100 = 10.11;
+MACOSX_DEPLOYMENT_TARGET_macosx_101200 = 10.12;
+MACOSX_DEPLOYMENT_TARGET_macosx_101300 = 10.13;
+
+GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
+DEBUG_INFORMATION_FORMAT = dwarf;
+
+SDKROOT = $(SDKROOT_$(USE_INTERNAL_SDK));
+SDKROOT_ = macosx;
+SDKROOT_YES = macosx.internal;
</ins></span></pre></div>
<a id="branchessafari603branchPerformanceTestsMediaTimeMakefile"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/PerformanceTests/MediaTime/Makefile (0 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/PerformanceTests/MediaTime/Makefile         (rev 0)
+++ branches/safari-603-branch/PerformanceTests/MediaTime/Makefile        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+SCRIPTS_PATH ?= ../../Tools/Scripts
+include ../../Makefile.shared
</ins></span></pre></div>
<a id="branchessafari603branchPerformanceTestsMediaTimeMediaTimexcodeprojprojectpbxproj"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/PerformanceTests/MediaTime/MediaTime.xcodeproj/project.pbxproj (0 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/PerformanceTests/MediaTime/MediaTime.xcodeproj/project.pbxproj         (rev 0)
+++ branches/safari-603-branch/PerformanceTests/MediaTime/MediaTime.xcodeproj/project.pbxproj        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -0,0 +1,256 @@
</span><ins>+// !$*UTF8*$!
+{
+        archiveVersion = 1;
+        classes = {
+        };
+        objectVersion = 46;
+        objects = {
+
+/* Begin PBXBuildFile section */
+                CDB099E11E4308470039E198 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDB099E01E4308470039E198 /* main.cpp */; };
+                CDB099E91E4308700039E198 /* libWTF.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CDB099E81E4308700039E198 /* libWTF.a */; };
+                CDB099EB1E430B250039E198 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CDB099EA1E430B250039E198 /* CoreFoundation.framework */; };
+                CDB099ED1E430B440039E198 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CDB099EC1E430B440039E198 /* Foundation.framework */; };
+                CDB099EF1E430B550039E198 /* libicucore.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = CDB099EE1E430B550039E198 /* libicucore.dylib */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+                CDB099DB1E4308470039E198 /* CopyFiles */ = {
+                        isa = PBXCopyFilesBuildPhase;
+                        buildActionMask = 2147483647;
+                        dstPath = /usr/share/man/man1/;
+                        dstSubfolderSpec = 0;
+                        files = (
+                        );
+                        runOnlyForDeploymentPostprocessing = 1;
+                };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+                CD836CFE1E43BDB4009F8091 /* Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Base.xcconfig; sourceTree = "<group>"; };
+                CD836D001E43BDB4009F8091 /* DebugRelease.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DebugRelease.xcconfig; sourceTree = "<group>"; };
+                CDB099DD1E4308470039E198 /* MediaTime */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = MediaTime; sourceTree = BUILT_PRODUCTS_DIR; };
+                CDB099E01E4308470039E198 /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = ../../../../Testcases/MediaTimeTestcase/MediaTime/main.cpp; sourceTree = "<group>"; };
+                CDB099E81E4308700039E198 /* libWTF.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libWTF.a; path = ../../WebKit.git/OpenSource/WebKitBuild/Debug/libWTF.a; sourceTree = "<group>"; };
+                CDB099EA1E430B250039E198 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
+                CDB099EC1E430B440039E198 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+                CDB099EE1E430B550039E198 /* libicucore.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libicucore.dylib; path = usr/lib/libicucore.dylib; sourceTree = SDKROOT; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+                CDB099DA1E4308470039E198 /* Frameworks */ = {
+                        isa = PBXFrameworksBuildPhase;
+                        buildActionMask = 2147483647;
+                        files = (
+                                CDB099EF1E430B550039E198 /* libicucore.dylib in Frameworks */,
+                                CDB099ED1E430B440039E198 /* Foundation.framework in Frameworks */,
+                                CDB099EB1E430B250039E198 /* CoreFoundation.framework in Frameworks */,
+                                CDB099E91E4308700039E198 /* libWTF.a in Frameworks */,
+                        );
+                        runOnlyForDeploymentPostprocessing = 0;
+                };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+                CD836CFD1E43BDB4009F8091 /* Configurations */ = {
+                        isa = PBXGroup;
+                        children = (
+                                CD836CFE1E43BDB4009F8091 /* Base.xcconfig */,
+                                CD836D001E43BDB4009F8091 /* DebugRelease.xcconfig */,
+                        );
+                        path = Configurations;
+                        sourceTree = "<group>";
+                };
+                CDB099D41E4308470039E198 = {
+                        isa = PBXGroup;
+                        children = (
+                                CDB099E01E4308470039E198 /* main.cpp */,
+                                CD836CFD1E43BDB4009F8091 /* Configurations */,
+                                CDB099DE1E4308470039E198 /* Products */,
+                                CDB099E71E43086F0039E198 /* Frameworks */,
+                        );
+                        sourceTree = "<group>";
+                };
+                CDB099DE1E4308470039E198 /* Products */ = {
+                        isa = PBXGroup;
+                        children = (
+                                CDB099DD1E4308470039E198 /* MediaTime */,
+                        );
+                        name = Products;
+                        sourceTree = "<group>";
+                };
+                CDB099E71E43086F0039E198 /* Frameworks */ = {
+                        isa = PBXGroup;
+                        children = (
+                                CDB099EE1E430B550039E198 /* libicucore.dylib */,
+                                CDB099EC1E430B440039E198 /* Foundation.framework */,
+                                CDB099EA1E430B250039E198 /* CoreFoundation.framework */,
+                                CDB099E81E4308700039E198 /* libWTF.a */,
+                        );
+                        name = Frameworks;
+                        sourceTree = "<group>";
+                };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+                CDB099DC1E4308470039E198 /* MediaTime */ = {
+                        isa = PBXNativeTarget;
+                        buildConfigurationList = CDB099E41E4308470039E198 /* Build configuration list for PBXNativeTarget "MediaTime" */;
+                        buildPhases = (
+                                CDB099D91E4308470039E198 /* Sources */,
+                                CDB099DA1E4308470039E198 /* Frameworks */,
+                                CDB099DB1E4308470039E198 /* CopyFiles */,
+                        );
+                        buildRules = (
+                        );
+                        dependencies = (
+                        );
+                        name = MediaTime;
+                        productName = MediaTimeTestcase;
+                        productReference = CDB099DD1E4308470039E198 /* MediaTime */;
+                        productType = "com.apple.product-type.tool";
+                };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+                CDB099D51E4308470039E198 /* Project object */ = {
+                        isa = PBXProject;
+                        attributes = {
+                                LastUpgradeCheck = 0830;
+                                ORGANIZATIONNAME = "Jeremy Noble";
+                                TargetAttributes = {
+                                        CDB099DC1E4308470039E198 = {
+                                                CreatedOnToolsVersion = 8.3;
+                                                DevelopmentTeam = G5UYP5CS7K;
+                                                ProvisioningStyle = Automatic;
+                                        };
+                                };
+                        };
+                        buildConfigurationList = CDB099D81E4308470039E198 /* Build configuration list for PBXProject "MediaTime" */;
+                        compatibilityVersion = "Xcode 3.2";
+                        developmentRegion = English;
+                        hasScannedForEncodings = 0;
+                        knownRegions = (
+                                en,
+                        );
+                        mainGroup = CDB099D41E4308470039E198;
+                        productRefGroup = CDB099DE1E4308470039E198 /* Products */;
+                        projectDirPath = "";
+                        projectRoot = "";
+                        targets = (
+                                CDB099DC1E4308470039E198 /* MediaTime */,
+                        );
+                };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+                CDB099D91E4308470039E198 /* Sources */ = {
+                        isa = PBXSourcesBuildPhase;
+                        buildActionMask = 2147483647;
+                        files = (
+                                CDB099E11E4308470039E198 /* main.cpp in Sources */,
+                        );
+                        runOnlyForDeploymentPostprocessing = 0;
+                };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+                CDB099E21E4308470039E198 /* Debug */ = {
+                        isa = XCBuildConfiguration;
+                        baseConfigurationReference = CD836D001E43BDB4009F8091 /* DebugRelease.xcconfig */;
+                        buildSettings = {
+                                ALWAYS_SEARCH_USER_PATHS = YES;
+                                CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
+                                CLANG_CXX_LIBRARY = "libc++";
+                                DEBUG_INFORMATION_FORMAT = dwarf;
+                                ENABLE_TESTABILITY = YES;
+                                GCC_DYNAMIC_NO_PIC = NO;
+                                GCC_NO_COMMON_BLOCKS = YES;
+                                GCC_OPTIMIZATION_LEVEL = 0;
+                                GCC_PREPROCESSOR_DEFINITIONS = (
+                                        "DEBUG=1",
+                                        "$(inherited)",
+                                );
+                                ONLY_ACTIVE_ARCH = YES;
+                        };
+                        name = Debug;
+                };
+                CDB099E31E4308470039E198 /* Release */ = {
+                        isa = XCBuildConfiguration;
+                        baseConfigurationReference = CD836D001E43BDB4009F8091 /* DebugRelease.xcconfig */;
+                        buildSettings = {
+                                ALWAYS_SEARCH_USER_PATHS = YES;
+                                CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
+                                CLANG_CXX_LIBRARY = "libc++";
+                                DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                                GCC_NO_COMMON_BLOCKS = YES;
+                        };
+                        name = Release;
+                };
+                CDB099E51E4308470039E198 /* Debug */ = {
+                        isa = XCBuildConfiguration;
+                        buildSettings = {
+                                CLANG_CXX_LANGUAGE_STANDARD = "c++14";
+                                DEVELOPMENT_TEAM = G5UYP5CS7K;
+                                PRODUCT_NAME = "$(TARGET_NAME)";
+                        };
+                        name = Debug;
+                };
+                CDB099E61E4308470039E198 /* Release */ = {
+                        isa = XCBuildConfiguration;
+                        buildSettings = {
+                                CLANG_CXX_LANGUAGE_STANDARD = "c++14";
+                                DEVELOPMENT_TEAM = G5UYP5CS7K;
+                                PRODUCT_NAME = "$(TARGET_NAME)";
+                        };
+                        name = Release;
+                };
+                CDB099F01E4394540039E198 /* Control */ = {
+                        isa = XCBuildConfiguration;
+                        buildSettings = {
+                                ALWAYS_SEARCH_USER_PATHS = YES;
+                                CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
+                                CLANG_CXX_LIBRARY = "libc++";
+                                DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                                GCC_NO_COMMON_BLOCKS = YES;
+                                HEADER_SEARCH_PATHS = /usr/local/include;
+                                LIBRARY_SEARCH_PATHS = /usr/local/lib;
+                        };
+                        name = Control;
+                };
+                CDB099F11E4394540039E198 /* Control */ = {
+                        isa = XCBuildConfiguration;
+                        buildSettings = {
+                                CLANG_CXX_LANGUAGE_STANDARD = "c++14";
+                                DEVELOPMENT_TEAM = G5UYP5CS7K;
+                                PRODUCT_NAME = "$(TARGET_NAME)";
+                        };
+                        name = Control;
+                };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+                CDB099D81E4308470039E198 /* Build configuration list for PBXProject "MediaTime" */ = {
+                        isa = XCConfigurationList;
+                        buildConfigurations = (
+                                CDB099E21E4308470039E198 /* Debug */,
+                                CDB099E31E4308470039E198 /* Release */,
+                                CDB099F01E4394540039E198 /* Control */,
+                        );
+                        defaultConfigurationIsVisible = 0;
+                        defaultConfigurationName = Release;
+                };
+                CDB099E41E4308470039E198 /* Build configuration list for PBXNativeTarget "MediaTime" */ = {
+                        isa = XCConfigurationList;
+                        buildConfigurations = (
+                                CDB099E51E4308470039E198 /* Debug */,
+                                CDB099E61E4308470039E198 /* Release */,
+                                CDB099F11E4394540039E198 /* Control */,
+                        );
+                        defaultConfigurationIsVisible = 0;
+                        defaultConfigurationName = Release;
+                };
+/* End XCConfigurationList section */
+        };
+        rootObject = CDB099D51E4308470039E198 /* Project object */;
+}
</ins></span></pre></div>
<a id="branchessafari603branchPerformanceTestsMediaTimemaincpp"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/PerformanceTests/MediaTime/main.cpp (0 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/PerformanceTests/MediaTime/main.cpp         (rev 0)
+++ branches/safari-603-branch/PerformanceTests/MediaTime/main.cpp        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -0,0 +1,94 @@
</span><ins>+/*
+ * Copyright (C) 2017 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 met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <chrono>
+#include <random>
+#include <set>
+#include <wtf/MediaTime.h>
+
+using namespace std;
+using namespace std::chrono;
+
+static const size_t setSize = 100000;
+
+void performTest(const char* name, function<void()> test)
+{
+ vector<double> runtimes(21);
+ for (auto& runtime : runtimes) {
+ auto start = steady_clock::now();
+ test();
+ runtime = duration_cast<milliseconds>(steady_clock::now() - start).count();
+ }
+ sort(runtimes.begin(), runtimes.end());
+ double sum = std::accumulate(runtimes.begin(), runtimes.end(), 0);
+ double mean = sum / runtimes.size();
+ double median = runtimes[(runtimes.size() + 1) / 2];
+ double min = runtimes.front();
+ double max = runtimes.back();
+ double sqSum = std::inner_product(runtimes.begin(), runtimes.end(), runtimes.begin(), 0);
+ double stdev = std::sqrt(sqSum / runtimes.size() - mean * mean);
+
+ printf("RESULT %s: Time= %g ms", name, sum);
+ printf("median= %g ms, stdev= %g ms, min= %g ms, max = %g ms", median, stdev, min, max);
+}
+
+void test(int32_t count, function<MediaTime(int32_t)> generator)
+{
+ set<MediaTime> times;
+
+ for (int32_t i = 0; i < count; ++i)
+ times.insert(generator(i));
+
+ for (int32_t i = 0; i < count; ++i)
+ times.upper_bound(generator(i));
+}
+
+int main(int argc, const char * argv[])
+{
+ performTest("Equal TimeScales", [] { test(setSize, [] (int32_t i) { return MediaTime(i, 1); }); });
+ performTest("Equal TimeValues", [] { test(setSize, [] (int32_t i) { return MediaTime(1, i + 1); }); });
+ performTest("Disparate TimeValues & TimeScales", [] { test(setSize, [] (int32_t i) { return MediaTime(i, i + 1); }); });
+ performTest("Non-uniform", [] {
+ test(setSize, [] (int32_t i) {
+ switch (i % 6) {
+ case 0:
+ return MediaTime::invalidTime();
+ case 1:
+ return MediaTime::positiveInfiniteTime();
+ case 2:
+ return MediaTime::negativeInfiniteTime();
+ case 3:
+ return MediaTime::indefiniteTime();
+ case 4:
+ return MediaTime(i, 1);
+ case 5:
+ default:
+ return MediaTime(i, i + 1);
+ }
+ });
+ });
+
+ return 0;
+}
</ins></span></pre></div>
<a id="branchessafari603branchPerformanceTestsSkipped"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/PerformanceTests/Skipped (212056 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/PerformanceTests/Skipped        2017-02-10 06:36:27 UTC (rev 212056)
+++ branches/safari-603-branch/PerformanceTests/Skipped        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -107,3 +107,4 @@
</span><span class="cx"> # Media tests take too long to run; require MSE, HLS which are not supported on all ports;
</span><span class="cx"> # and require a webserver (run-webkit-httpd) which is not part of normal performance testing.
</span><span class="cx"> Media/
</span><ins>+MediaTime/
</ins></span></pre></div>
<a id="branchessafari603branchSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WTF/ChangeLog (212056 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WTF/ChangeLog        2017-02-10 06:36:27 UTC (rev 212056)
+++ branches/safari-603-branch/Source/WTF/ChangeLog        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -1,5 +1,47 @@
</span><span class="cx"> 2017-02-09 Matthew Hanson <matthew_hanson@apple.com>
</span><span class="cx">
</span><ins>+ Merge r211746. rdar://problem/30107622
+
+ 2017-02-06 Jer Noble <jer.noble@apple.com>
+
+ Playback stalls when a SourceBuffer append causes frame eviction
+ https://bugs.webkit.org/show_bug.cgi?id=167834
+
+ Reviewed by Eric Carlson.
+
+ Optimize the MediaTime class; specifically the compare() method. The class only
+ needs 6 bits to store the TimeFlags, so make that a uint8_t rather than uint32_t.
+ The implementation is slightly simpler if the TimeScale is unsigned, so make that
+ a uint32_t rather than int32_t. Inline the comparison operators. Optimize the equality
+ comparison by bitwise-and'ing the flags together and masking the result. Optimize for
+ common comparison scenarios (equal timeScales, equal timeValues(), etc.). Attempt the
+ mathematically simpler simpler method for comparing ratios, and only fall back to the
+ complex method if the results of multiplying the timeScale by the timeValue overflows.
+
+ * wtf/MediaTime.cpp:
+ (WTF::greatestCommonDivisor):
+ (WTF::leastCommonMultiple):
+ (WTF::signum):
+ (WTF::MediaTime::MediaTime):
+ (WTF::MediaTime::createWithFloat):
+ (WTF::MediaTime::createWithDouble):
+ (WTF::MediaTime::operator+):
+ (WTF::MediaTime::operator-):
+ (WTF::MediaTime::operator!):
+ (WTF::MediaTime::operator bool):
+ (WTF::MediaTime::compare):
+ (WTF::MediaTime::setTimeScale):
+ (WTF::abs):
+ (WTF::MediaTime::operator<): Deleted.
+ (WTF::MediaTime::operator>): Deleted.
+ (WTF::MediaTime::operator!=): Deleted.
+ (WTF::MediaTime::operator==): Deleted.
+ (WTF::MediaTime::operator>=): Deleted.
+ (WTF::MediaTime::operator<=): Deleted.
+ * wtf/MediaTime.h:
+
+2017-02-09 Matthew Hanson <matthew_hanson@apple.com>
+
</ins><span class="cx"> Merge r211622. rdar://problem/30116072
</span><span class="cx">
</span><span class="cx"> 2017-02-02 Andreas Kling <akling@apple.com>
</span></span></pre></div>
<a id="branchessafari603branchSourceWTFwtfMediaTimecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WTF/wtf/MediaTime.cpp (212056 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WTF/wtf/MediaTime.cpp        2017-02-10 06:36:27 UTC (rev 212056)
+++ branches/safari-603-branch/Source/WTF/wtf/MediaTime.cpp        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #include "MediaTime.h"
</span><span class="cx">
</span><span class="cx"> #include <algorithm>
</span><ins>+#include <cstdlib>
</ins><span class="cx"> #include <wtf/CheckedArithmetic.h>
</span><span class="cx"> #include <wtf/MathExtras.h>
</span><span class="cx"> #include <wtf/PrintStream.h>
</span><span class="lines">@@ -36,10 +37,10 @@
</span><span class="cx">
</span><span class="cx"> namespace WTF {
</span><span class="cx">
</span><del>-static int32_t greatestCommonDivisor(int32_t a, int32_t b)
</del><ins>+static uint32_t greatestCommonDivisor(uint32_t a, uint32_t b)
</ins><span class="cx"> {
</span><span class="cx"> // Euclid's Algorithm
</span><del>- int32_t temp = 0;
</del><ins>+ uint32_t temp = 0;
</ins><span class="cx"> while (b) {
</span><span class="cx"> temp = b;
</span><span class="cx"> b = a % b;
</span><span class="lines">@@ -48,17 +49,17 @@
</span><span class="cx"> return a;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static int32_t leastCommonMultiple(int32_t a, int32_t b, int32_t &result)
</del><ins>+static uint32_t leastCommonMultiple(uint32_t a, uint32_t b, uint32_t &result)
</ins><span class="cx"> {
</span><span class="cx"> return safeMultiply(a, b / greatestCommonDivisor(a, b), result);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static int32_t signum(int64_t val)
</del><ins>+static int64_t signum(int64_t val)
</ins><span class="cx"> {
</span><span class="cx"> return (0 < val) - (val < 0);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-const int32_t MediaTime::MaximumTimeScale = 0x7fffffffL;
</del><ins>+const uint32_t MediaTime::MaximumTimeScale = 0x7fffffffL;
</ins><span class="cx">
</span><span class="cx"> MediaTime::MediaTime()
</span><span class="cx"> : m_timeValue(0)
</span><span class="lines">@@ -67,7 +68,7 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><del>-MediaTime::MediaTime(int64_t value, int32_t scale, uint32_t flags)
</del><ins>+MediaTime::MediaTime(int64_t value, uint32_t scale, uint8_t flags)
</ins><span class="cx"> : m_timeValue(value)
</span><span class="cx"> , m_timeScale(scale)
</span><span class="cx"> , m_timeFlags(flags)
</span><span class="lines">@@ -99,7 +100,7 @@
</span><span class="cx"> return value;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-MediaTime MediaTime::createWithFloat(float floatTime, int32_t timeScale)
</del><ins>+MediaTime MediaTime::createWithFloat(float floatTime, uint32_t timeScale)
</ins><span class="cx"> {
</span><span class="cx"> if (floatTime != floatTime)
</span><span class="cx"> return invalidTime();
</span><span class="lines">@@ -131,7 +132,7 @@
</span><span class="cx"> return value;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-MediaTime MediaTime::createWithDouble(double doubleTime, int32_t timeScale)
</del><ins>+MediaTime MediaTime::createWithDouble(double doubleTime, uint32_t timeScale)
</ins><span class="cx"> {
</span><span class="cx"> if (doubleTime != doubleTime)
</span><span class="cx"> return invalidTime();
</span><span class="lines">@@ -212,7 +213,7 @@
</span><span class="cx"> else if (b.hasDoubleValue())
</span><span class="cx"> b.setTimeScale(DefaultTimeScale);
</span><span class="cx">
</span><del>- int32_t commonTimeScale;
</del><ins>+ uint32_t commonTimeScale;
</ins><span class="cx"> if (!leastCommonMultiple(a.m_timeScale, b.m_timeScale, commonTimeScale) || commonTimeScale > MaximumTimeScale)
</span><span class="cx"> commonTimeScale = MaximumTimeScale;
</span><span class="cx"> a.setTimeScale(commonTimeScale);
</span><span class="lines">@@ -258,7 +259,7 @@
</span><span class="cx"> else if (b.hasDoubleValue())
</span><span class="cx"> b.setTimeScale(DefaultTimeScale);
</span><span class="cx">
</span><del>- int32_t commonTimeScale;
</del><ins>+ uint32_t commonTimeScale;
</ins><span class="cx"> if (!leastCommonMultiple(this->m_timeScale, rhs.m_timeScale, commonTimeScale) || commonTimeScale > MaximumTimeScale)
</span><span class="cx"> commonTimeScale = MaximumTimeScale;
</span><span class="cx"> a.setTimeScale(commonTimeScale);
</span><span class="lines">@@ -334,73 +335,41 @@
</span><span class="cx"> return a;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-bool MediaTime::operator<(const MediaTime& rhs) const
-{
- return compare(rhs) == LessThan;
-}
-
-bool MediaTime::operator>(const MediaTime& rhs) const
-{
- return compare(rhs) == GreaterThan;
-}
-
-bool MediaTime::operator!=(const MediaTime& rhs) const
-{
- return compare(rhs) != EqualTo;
-}
-
-bool MediaTime::operator==(const MediaTime& rhs) const
-{
- return compare(rhs) == EqualTo;
-}
-
-bool MediaTime::operator>=(const MediaTime& rhs) const
-{
- return compare(rhs) >= EqualTo;
-}
-
-bool MediaTime::operator<=(const MediaTime& rhs) const
-{
- return compare(rhs) <= EqualTo;
-}
-
</del><span class="cx"> bool MediaTime::operator!() const
</span><span class="cx"> {
</span><del>- return compare(zeroTime()) == EqualTo;
</del><ins>+ return (m_timeFlags == Valid && !m_timeValue)
+ || (m_timeFlags == (Valid | DoubleValue) && !m_timeValueAsDouble);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> MediaTime::operator bool() const
</span><span class="cx"> {
</span><del>- return compare(zeroTime()) != EqualTo;
</del><ins>+ return !(m_timeFlags == Valid && !m_timeValue)
+ && !(m_timeFlags == (Valid | DoubleValue) && !m_timeValueAsDouble);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> MediaTime::ComparisonFlags MediaTime::compare(const MediaTime& rhs) const
</span><span class="cx"> {
</span><del>- if ((isPositiveInfinite() && rhs.isPositiveInfinite())
- || (isNegativeInfinite() && rhs.isNegativeInfinite())
- || (isInvalid() && rhs.isInvalid())
- || (isIndefinite() && rhs.isIndefinite()))
</del><ins>+ auto andFlags = m_timeFlags & rhs.m_timeFlags;
+ if (andFlags & (PositiveInfinite | NegativeInfinite | Indefinite))
</ins><span class="cx"> return EqualTo;
</span><span class="cx">
</span><del>- if (isInvalid())
- return GreaterThan;
</del><ins>+ auto orFlags = m_timeFlags | rhs.m_timeFlags;
+ if (!(orFlags & Valid))
+ return EqualTo;
</ins><span class="cx">
</span><del>- if (rhs.isInvalid())
- return LessThan;
</del><ins>+ if (!(andFlags & Valid))
+ return isInvalid() ? GreaterThan : LessThan;
</ins><span class="cx">
</span><del>- if (rhs.isNegativeInfinite() || isPositiveInfinite())
- return GreaterThan;
</del><ins>+ if (orFlags & NegativeInfinite)
+ return isNegativeInfinite() ? LessThan : GreaterThan;
</ins><span class="cx">
</span><del>- if (rhs.isPositiveInfinite() || isNegativeInfinite())
- return LessThan;
</del><ins>+ if (orFlags & PositiveInfinite)
+ return isPositiveInfinite() ? GreaterThan : LessThan;
</ins><span class="cx">
</span><del>- if (isIndefinite())
- return GreaterThan;
</del><ins>+ if (orFlags & Indefinite)
+ return isIndefinite() ? GreaterThan : LessThan;
</ins><span class="cx">
</span><del>- if (rhs.isIndefinite())
- return LessThan;
-
- if (hasDoubleValue() && rhs.hasDoubleValue()) {
</del><ins>+ if (andFlags & DoubleValue) {
</ins><span class="cx"> if (m_timeValueAsDouble == rhs.m_timeValueAsDouble)
</span><span class="cx"> return EqualTo;
</span><span class="cx">
</span><span class="lines">@@ -407,7 +376,7 @@
</span><span class="cx"> return m_timeValueAsDouble < rhs.m_timeValueAsDouble ? LessThan : GreaterThan;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- if (hasDoubleValue() || rhs.hasDoubleValue()) {
</del><ins>+ if (orFlags & DoubleValue) {
</ins><span class="cx"> double a = toDouble();
</span><span class="cx"> double b = rhs.toDouble();
</span><span class="cx"> if (a > b)
</span><span class="lines">@@ -417,20 +386,47 @@
</span><span class="cx"> return EqualTo;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- MediaTime a = *this;
- MediaTime b = rhs;
</del><ins>+ if ((m_timeValue < 0) != (rhs.m_timeValue < 0))
+ return m_timeValue < 0 ? LessThan : GreaterThan;
</ins><span class="cx">
</span><del>- int64_t rhsWhole = b.m_timeValue / b.m_timeScale;
- int64_t lhsWhole = a.m_timeValue / a.m_timeScale;
</del><ins>+ if (!m_timeValue && !rhs.m_timeValue)
+ return EqualTo;
+
+ if (m_timeScale == rhs.m_timeScale) {
+ if (m_timeValue == rhs.m_timeValue)
+ return EqualTo;
+ return m_timeValue < rhs.m_timeValue ? LessThan : GreaterThan;
+ }
+
+ if (m_timeValue == rhs.m_timeValue)
+ return m_timeScale < rhs.m_timeScale ? GreaterThan : LessThan;
+
+ if (m_timeValue < rhs.m_timeValue && m_timeScale > rhs.m_timeScale)
+ return LessThan;
+
+ if (m_timeValue > rhs.m_timeValue && m_timeScale < rhs.m_timeScale)
+ return GreaterThan;
+
+ int64_t lhsFactor;
+ int64_t rhsFactor;
+ if (safeMultiply(m_timeValue, static_cast<int64_t>(rhs.m_timeScale), lhsFactor)
+ && safeMultiply(rhs.m_timeValue, static_cast<int64_t>(m_timeScale), rhsFactor)) {
+ if (lhsFactor == rhsFactor)
+ return EqualTo;
+ return lhsFactor < rhsFactor ? LessThan : GreaterThan;
+ }
+
+ int64_t rhsWhole = rhs.m_timeValue / rhs.m_timeScale;
+ int64_t lhsWhole = m_timeValue / m_timeScale;
</ins><span class="cx"> if (lhsWhole > rhsWhole)
</span><span class="cx"> return GreaterThan;
</span><span class="cx"> if (lhsWhole < rhsWhole)
</span><span class="cx"> return LessThan;
</span><span class="cx">
</span><del>- int64_t rhsRemain = b.m_timeValue % b.m_timeScale;
- int64_t lhsRemain = a.m_timeValue % a.m_timeScale;
- int64_t lhsFactor = lhsRemain * b.m_timeScale;
- int64_t rhsFactor = rhsRemain * a.m_timeScale;
</del><ins>+ int64_t rhsRemain = rhs.m_timeValue % rhs.m_timeScale;
+ int64_t lhsRemain = m_timeValue % m_timeScale;
+ lhsFactor = lhsRemain * rhs.m_timeScale;
+ rhsFactor = rhsRemain * m_timeScale;
</ins><span class="cx">
</span><span class="cx"> if (lhsFactor == rhsFactor)
</span><span class="cx"> return EqualTo;
</span><span class="lines">@@ -474,7 +470,7 @@
</span><span class="cx"> return *time;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void MediaTime::setTimeScale(int32_t timeScale)
</del><ins>+void MediaTime::setTimeScale(uint32_t timeScale)
</ins><span class="cx"> {
</span><span class="cx"> if (hasDoubleValue()) {
</span><span class="cx"> *this = MediaTime::createWithDouble(m_timeValueAsDouble, timeScale);
</span><span class="lines">@@ -490,7 +486,7 @@
</span><span class="cx"> // timescale by two until the number will fit, and round the
</span><span class="cx"> // result.
</span><span class="cx"> int64_t newWholePart;
</span><del>- while (!safeMultiply(wholePart, timeScale, newWholePart))
</del><ins>+ while (!safeMultiply(wholePart, static_cast<int64_t>(timeScale), newWholePart))
</ins><span class="cx"> timeScale /= 2;
</span><span class="cx">
</span><span class="cx"> int64_t remainder = m_timeValue % m_timeScale;
</span><span class="lines">@@ -513,7 +509,7 @@
</span><span class="cx"> return MediaTime::createWithDouble(fabs(rhs.m_timeValueAsDouble));
</span><span class="cx">
</span><span class="cx"> MediaTime val = rhs;
</span><del>- val.m_timeValue *= signum(rhs.m_timeScale) * signum(rhs.m_timeValue);
</del><ins>+ val.m_timeValue = std::abs(rhs.m_timeValue);
</ins><span class="cx"> return val;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="branchessafari603branchSourceWTFwtfMediaTimeh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WTF/wtf/MediaTime.h (212056 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WTF/wtf/MediaTime.h        2017-02-10 06:36:27 UTC (rev 212056)
+++ branches/safari-603-branch/Source/WTF/wtf/MediaTime.h        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -53,14 +53,14 @@
</span><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> MediaTime();
</span><del>- MediaTime(int64_t value, int32_t scale, uint32_t flags = Valid);
</del><ins>+ MediaTime(int64_t value, uint32_t scale, uint8_t flags = Valid);
</ins><span class="cx"> MediaTime(const MediaTime& rhs);
</span><span class="cx"> ~MediaTime();
</span><span class="cx">
</span><span class="cx"> static MediaTime createWithFloat(float floatTime);
</span><del>- static MediaTime createWithFloat(float floatTime, int32_t timeScale);
</del><ins>+ static MediaTime createWithFloat(float floatTime, uint32_t timeScale);
</ins><span class="cx"> static MediaTime createWithDouble(double doubleTime);
</span><del>- static MediaTime createWithDouble(double doubleTime, int32_t timeScale);
</del><ins>+ static MediaTime createWithDouble(double doubleTime, uint32_t timeScale);
</ins><span class="cx">
</span><span class="cx"> float toFloat() const;
</span><span class="cx"> double toDouble() const;
</span><span class="lines">@@ -72,12 +72,12 @@
</span><span class="cx"> MediaTime operator-(const MediaTime& rhs) const;
</span><span class="cx"> MediaTime operator-() const;
</span><span class="cx"> MediaTime operator*(int32_t) const;
</span><del>- bool operator<(const MediaTime& rhs) const;
- bool operator>(const MediaTime& rhs) const;
- bool operator!=(const MediaTime& rhs) const;
- bool operator==(const MediaTime& rhs) const;
- bool operator>=(const MediaTime& rhs) const;
- bool operator<=(const MediaTime& rhs) const;
</del><ins>+ bool operator<(const MediaTime& rhs) const { return compare(rhs) == LessThan; }
+ bool operator>(const MediaTime& rhs) const { return compare(rhs) == GreaterThan; }
+ bool operator!=(const MediaTime& rhs) const { return compare(rhs) != EqualTo; }
+ bool operator==(const MediaTime& rhs) const { return compare(rhs) == EqualTo; }
+ bool operator>=(const MediaTime& rhs) const { return compare(rhs) >= EqualTo; }
+ bool operator<=(const MediaTime& rhs) const { return compare(rhs) <= EqualTo; }
</ins><span class="cx"> bool operator!() const;
</span><span class="cx"> explicit operator bool() const;
</span><span class="cx">
</span><span class="lines">@@ -105,7 +105,7 @@
</span><span class="cx"> static const MediaTime& indefiniteTime();
</span><span class="cx">
</span><span class="cx"> const int64_t& timeValue() const { return m_timeValue; }
</span><del>- const int32_t& timeScale() const { return m_timeScale; }
</del><ins>+ const uint32_t& timeScale() const { return m_timeScale; }
</ins><span class="cx">
</span><span class="cx"> void dump(PrintStream& out) const;
</span><span class="cx">
</span><span class="lines">@@ -117,18 +117,18 @@
</span><span class="cx">
</span><span class="cx"> friend WTF_EXPORT_PRIVATE MediaTime abs(const MediaTime& rhs);
</span><span class="cx">
</span><del>- static const int32_t DefaultTimeScale = 10000000;
- static const int32_t MaximumTimeScale;
</del><ins>+ static const uint32_t DefaultTimeScale = 10000000;
+ static const uint32_t MaximumTimeScale;
</ins><span class="cx">
</span><span class="cx"> private:
</span><del>- void setTimeScale(int32_t);
</del><ins>+ void setTimeScale(uint32_t);
</ins><span class="cx">
</span><span class="cx"> union {
</span><span class="cx"> int64_t m_timeValue;
</span><span class="cx"> double m_timeValueAsDouble;
</span><span class="cx"> };
</span><del>- int32_t m_timeScale;
- uint32_t m_timeFlags;
</del><ins>+ uint32_t m_timeScale;
+ uint8_t m_timeFlags;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> inline MediaTime operator*(int32_t lhs, const MediaTime& rhs) { return rhs.operator*(lhs); }
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/ChangeLog (212056 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/ChangeLog        2017-02-10 06:36:27 UTC (rev 212056)
+++ branches/safari-603-branch/Source/WebCore/ChangeLog        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -1,5 +1,57 @@
</span><span class="cx"> 2017-02-09 Matthew Hanson <matthew_hanson@apple.com>
</span><span class="cx">
</span><ins>+ Merge r211746. rdar://problem/30107622
+
+ 2017-02-06 Jer Noble <jer.noble@apple.com>
+
+ Playback stalls when a SourceBuffer append causes frame eviction
+ https://bugs.webkit.org/show_bug.cgi?id=167834
+
+ Reviewed by Eric Carlson.
+
+ Test: PerformanceTests/Media/MSERemoveCodedFrames.html
+
+ Optimize searching through SampleMap by presentationTime.
+
+ Many of the methods exposed by PresentationOrderSampleMap used the bare std::equal_range,
+ lower_bound, or upper_bound methods. Unlike those methods exposed on std::map, the bare
+ search methods perform a linear O(n) search, rather than a the binary O(log(n)) search used
+ by std::map. Rewrite those methods using the bare methods in terms of the std::map search
+ methods.
+
+ Drive-by fix: rename findSampleOnOrAfterPresentationTime to
+ findSampleStartingOnOrAfterPresentationTime to make the behavior of the method more
+ explicit.
+
+ * Modules/mediasource/SampleMap.cpp:
+ (WebCore::PresentationOrderSampleMap::findSampleContainingPresentationTime):
+ (WebCore::PresentationOrderSampleMap::findSampleStartingOnOrAfterPresentationTime):
+ (WebCore::PresentationOrderSampleMap::reverseFindSampleBeforePresentationTime):
+ (WebCore::DecodeOrderSampleMap::findSyncSampleAfterPresentationTime):
+ (WebCore::PresentationOrderSampleMap::findSamplesBetweenPresentationTimes):
+ (WebCore::PresentationOrderSampleMap::findSamplesWithinPresentationRange):
+ (WebCore::PresentationOrderSampleMap::findSampleOnOrAfterPresentationTime): Deleted.
+ * Modules/mediasource/SampleMap.h:
+ (WebCore::PresentationOrderSampleMap::begin):
+ (WebCore::PresentationOrderSampleMap::end):
+ (WebCore::PresentationOrderSampleMap::rbegin):
+ (WebCore::PresentationOrderSampleMap::rend):
+ (WebCore::DecodeOrderSampleMap::begin):
+ (WebCore::DecodeOrderSampleMap::end):
+ (WebCore::DecodeOrderSampleMap::rbegin):
+ (WebCore::DecodeOrderSampleMap::rend):
+ (WebCore::SampleMap::SampleMap):
+ (WebCore::SampleMap::sizeInBytes):
+ (WebCore::SampleMap::decodeOrder):
+ (WebCore::SampleMap::presentationOrder):
+ * Modules/mediasource/SourceBuffer.cpp:
+ (WebCore::removeSamplesFromTrackBuffer):
+ (WebCore::SourceBuffer::removeCodedFrames):
+ (WebCore::SourceBuffer::reenqueueMediaForTime):
+ * WebCore.xcodeproj/project.pbxproj:
+
+2017-02-09 Matthew Hanson <matthew_hanson@apple.com>
+
</ins><span class="cx"> Merge r211730. rdar://problem/30251840
</span><span class="cx">
</span><span class="cx"> 2017-02-06 Antti Koivisto <antti@apple.com>
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoreModulesmediasourceSampleMapcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/Modules/mediasource/SampleMap.cpp (212056 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/Modules/mediasource/SampleMap.cpp        2017-02-10 06:36:27 UTC (rev 212056)
+++ branches/safari-603-branch/Source/WebCore/Modules/mediasource/SampleMap.cpp        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -142,13 +142,21 @@
</span><span class="cx">
</span><span class="cx"> PresentationOrderSampleMap::iterator PresentationOrderSampleMap::findSampleContainingPresentationTime(const MediaTime& time)
</span><span class="cx"> {
</span><del>- auto range = std::equal_range(begin(), end(), time, SampleIsLessThanMediaTimeComparator<MapType>());
- if (range.first == range.second)
</del><ins>+ // upper_bound will return the first sample whose presentation start time is greater than the search time.
+ // If this is the first sample, that means no sample in the map contains the requested time.
+ auto iter = m_samples.upper_bound(time);
+ if (iter == begin())
</ins><span class="cx"> return end();
</span><del>- return range.first;
</del><ins>+
+ // Look at the previous sample; does it contain the requested time?
+ --iter;
+ MediaSample& sample = *iter->second;
+ if (sample.presentationTime() + sample.duration() > time)
+ return iter;
+ return end();
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-PresentationOrderSampleMap::iterator PresentationOrderSampleMap::findSampleOnOrAfterPresentationTime(const MediaTime& time)
</del><ins>+PresentationOrderSampleMap::iterator PresentationOrderSampleMap::findSampleStartingOnOrAfterPresentationTime(const MediaTime& time)
</ins><span class="cx"> {
</span><span class="cx"> return m_samples.lower_bound(time);
</span><span class="cx"> }
</span><span class="lines">@@ -168,7 +176,22 @@
</span><span class="cx">
</span><span class="cx"> PresentationOrderSampleMap::reverse_iterator PresentationOrderSampleMap::reverseFindSampleBeforePresentationTime(const MediaTime& time)
</span><span class="cx"> {
</span><del>- return std::lower_bound(rbegin(), rend(), time, SampleIsGreaterThanMediaTimeComparator<MapType>());
</del><ins>+ if (m_samples.empty())
+ return rend();
+
+ // upper_bound will return the first sample whose presentation start time is greater than the search time.
+ auto found = m_samples.upper_bound(time);
+
+ // If no sample was found with a time greater than the search time, return the last sample.
+ if (found == end())
+ return rbegin();
+
+ // If the first sample has a time grater than the search time, no samples will have a presentation time before the search time.
+ if (found == begin())
+ return rend();
+
+ // Otherwise, return the sample immediately previous to the one found.
+ return --reverse_iterator(--found);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> DecodeOrderSampleMap::reverse_iterator DecodeOrderSampleMap::reverseFindSampleWithDecodeKey(const KeyType& key)
</span><span class="lines">@@ -203,7 +226,7 @@
</span><span class="cx">
</span><span class="cx"> DecodeOrderSampleMap::iterator DecodeOrderSampleMap::findSyncSampleAfterPresentationTime(const MediaTime& time, const MediaTime& threshold)
</span><span class="cx"> {
</span><del>- PresentationOrderSampleMap::iterator currentSamplePTS = m_presentationOrder.findSampleOnOrAfterPresentationTime(time);
</del><ins>+ PresentationOrderSampleMap::iterator currentSamplePTS = m_presentationOrder.findSampleStartingOnOrAfterPresentationTime(time);
</ins><span class="cx"> if (currentSamplePTS == m_presentationOrder.end())
</span><span class="cx"> return end();
</span><span class="cx">
</span><span class="lines">@@ -228,14 +251,24 @@
</span><span class="cx">
</span><span class="cx"> PresentationOrderSampleMap::iterator_range PresentationOrderSampleMap::findSamplesBetweenPresentationTimes(const MediaTime& beginTime, const MediaTime& endTime)
</span><span class="cx"> {
</span><del>- std::pair<MediaTime, MediaTime> range(beginTime, endTime);
- return std::equal_range(begin(), end(), range, SamplePresentationTimeIsInsideRangeComparator());
</del><ins>+ // startTime is inclusive, so use lower_bound to include samples wich start exactly at startTime.
+ // endTime is not inclusive, so use lower_bound to exclude samples which start exactly at endTime.
+ auto lower_bound = m_samples.lower_bound(beginTime);
+ auto upper_bound = m_samples.lower_bound(endTime);
+ if (lower_bound == upper_bound)
+ return { end(), end() };
+ return { lower_bound, upper_bound };
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> PresentationOrderSampleMap::iterator_range PresentationOrderSampleMap::findSamplesWithinPresentationRange(const MediaTime& beginTime, const MediaTime& endTime)
</span><span class="cx"> {
</span><del>- std::pair<MediaTime, MediaTime> range(beginTime, endTime);
- return std::equal_range(begin(), end(), range, SamplePresentationTimeIsWithinRangeComparator());
</del><ins>+ // startTime is not inclusive, so use upper_bound to exclude samples which start exactly at startTime.
+ // endTime is inclusive, so use upper_bound to include samples which start exactly at endTime.
+ auto lower_bound = m_samples.upper_bound(beginTime);
+ auto upper_bound = m_samples.upper_bound(endTime);
+ if (lower_bound == upper_bound)
+ return { end(), end() };
+ return { lower_bound, upper_bound };
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> PresentationOrderSampleMap::iterator_range PresentationOrderSampleMap::findSamplesWithinPresentationRangeFromEnd(const MediaTime& beginTime, const MediaTime& endTime)
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoreModulesmediasourceSampleMaph"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/Modules/mediasource/SampleMap.h (212056 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/Modules/mediasource/SampleMap.h        2017-02-10 06:36:27 UTC (rev 212056)
+++ branches/safari-603-branch/Source/WebCore/Modules/mediasource/SampleMap.h        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -46,23 +46,23 @@
</span><span class="cx"> typedef MapType::const_reverse_iterator const_reverse_iterator;
</span><span class="cx"> typedef std::pair<iterator, iterator> iterator_range;
</span><span class="cx">
</span><del>- iterator begin() { return m_samples.begin(); }
- const_iterator begin() const { return m_samples.begin(); }
- iterator end() { return m_samples.end(); }
- const_iterator end() const { return m_samples.end(); }
- reverse_iterator rbegin() { return m_samples.rbegin(); }
- const_reverse_iterator rbegin() const { return m_samples.rbegin(); }
- reverse_iterator rend() { return m_samples.rend(); }
- const_reverse_iterator rend() const { return m_samples.rend(); }
</del><ins>+ WEBCORE_EXPORT iterator begin() { return m_samples.begin(); }
+ WEBCORE_EXPORT const_iterator begin() const { return m_samples.begin(); }
+ WEBCORE_EXPORT iterator end() { return m_samples.end(); }
+ WEBCORE_EXPORT const_iterator end() const { return m_samples.end(); }
+ WEBCORE_EXPORT reverse_iterator rbegin() { return m_samples.rbegin(); }
+ WEBCORE_EXPORT const_reverse_iterator rbegin() const { return m_samples.rbegin(); }
+ WEBCORE_EXPORT reverse_iterator rend() { return m_samples.rend(); }
+ WEBCORE_EXPORT const_reverse_iterator rend() const { return m_samples.rend(); }
</ins><span class="cx">
</span><del>- iterator findSampleWithPresentationTime(const MediaTime&);
- iterator findSampleContainingPresentationTime(const MediaTime&);
- iterator findSampleOnOrAfterPresentationTime(const MediaTime&);
- reverse_iterator reverseFindSampleContainingPresentationTime(const MediaTime&);
- 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&);
</del><ins>+ WEBCORE_EXPORT iterator findSampleWithPresentationTime(const MediaTime&);
+ WEBCORE_EXPORT iterator findSampleContainingPresentationTime(const MediaTime&);
+ WEBCORE_EXPORT iterator findSampleStartingOnOrAfterPresentationTime(const MediaTime&);
+ WEBCORE_EXPORT reverse_iterator reverseFindSampleContainingPresentationTime(const MediaTime&);
+ WEBCORE_EXPORT reverse_iterator reverseFindSampleBeforePresentationTime(const MediaTime&);
+ WEBCORE_EXPORT iterator_range findSamplesBetweenPresentationTimes(const MediaTime&, const MediaTime&);
+ WEBCORE_EXPORT iterator_range findSamplesWithinPresentationRange(const MediaTime&, const MediaTime&);
+ WEBCORE_EXPORT iterator_range findSamplesWithinPresentationRangeFromEnd(const MediaTime&, const MediaTime&);
</ins><span class="cx">
</span><span class="cx"> private:
</span><span class="cx"> MapType m_samples;
</span><span class="lines">@@ -79,22 +79,22 @@
</span><span class="cx"> typedef MapType::const_reverse_iterator const_reverse_iterator;
</span><span class="cx"> typedef std::pair<reverse_iterator, reverse_iterator> reverse_iterator_range;
</span><span class="cx">
</span><del>- iterator begin() { return m_samples.begin(); }
- const_iterator begin() const { return m_samples.begin(); }
- iterator end() { return m_samples.end(); }
- const_iterator end() const { return m_samples.end(); }
- reverse_iterator rbegin() { return m_samples.rbegin(); }
- const_reverse_iterator rbegin() const { return m_samples.rbegin(); }
- reverse_iterator rend() { return m_samples.rend(); }
- const_reverse_iterator rend() const { return m_samples.rend(); }
</del><ins>+ WEBCORE_EXPORT iterator begin() { return m_samples.begin(); }
+ WEBCORE_EXPORT const_iterator begin() const { return m_samples.begin(); }
+ WEBCORE_EXPORT iterator end() { return m_samples.end(); }
+ WEBCORE_EXPORT const_iterator end() const { return m_samples.end(); }
+ WEBCORE_EXPORT reverse_iterator rbegin() { return m_samples.rbegin(); }
+ WEBCORE_EXPORT const_reverse_iterator rbegin() const { return m_samples.rbegin(); }
+ WEBCORE_EXPORT reverse_iterator rend() { return m_samples.rend(); }
+ WEBCORE_EXPORT const_reverse_iterator rend() const { return m_samples.rend(); }
</ins><span class="cx">
</span><del>- iterator findSampleWithDecodeKey(const KeyType&);
- reverse_iterator reverseFindSampleWithDecodeKey(const KeyType&);
- reverse_iterator findSyncSamplePriorToPresentationTime(const MediaTime&, const MediaTime& threshold = MediaTime::positiveInfiniteTime());
- reverse_iterator findSyncSamplePriorToDecodeIterator(reverse_iterator);
- iterator findSyncSampleAfterPresentationTime(const MediaTime&, const MediaTime& threshold = MediaTime::positiveInfiniteTime());
- iterator findSyncSampleAfterDecodeIterator(iterator);
- reverse_iterator_range findDependentSamples(MediaSample*);
</del><ins>+ WEBCORE_EXPORT iterator findSampleWithDecodeKey(const KeyType&);
+ WEBCORE_EXPORT reverse_iterator reverseFindSampleWithDecodeKey(const KeyType&);
+ WEBCORE_EXPORT reverse_iterator findSyncSamplePriorToPresentationTime(const MediaTime&, const MediaTime& threshold = MediaTime::positiveInfiniteTime());
+ WEBCORE_EXPORT reverse_iterator findSyncSamplePriorToDecodeIterator(reverse_iterator);
+ WEBCORE_EXPORT iterator findSyncSampleAfterPresentationTime(const MediaTime&, const MediaTime& threshold = MediaTime::positiveInfiniteTime());
+ WEBCORE_EXPORT iterator findSyncSampleAfterDecodeIterator(iterator);
+ WEBCORE_EXPORT reverse_iterator_range findDependentSamples(MediaSample*);
</ins><span class="cx">
</span><span class="cx"> private:
</span><span class="cx"> MapType m_samples;
</span><span class="lines">@@ -103,24 +103,24 @@
</span><span class="cx">
</span><span class="cx"> class SampleMap {
</span><span class="cx"> public:
</span><del>- SampleMap()
</del><ins>+ WEBCORE_EXPORT SampleMap()
</ins><span class="cx"> : m_totalSize(0)
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><del>- bool empty() const;
- void clear();
- void addSample(MediaSample&);
- void removeSample(MediaSample*);
- size_t sizeInBytes() const { return m_totalSize; }
</del><ins>+ WEBCORE_EXPORT bool empty() const;
+ WEBCORE_EXPORT void clear();
+ WEBCORE_EXPORT void addSample(MediaSample&);
+ WEBCORE_EXPORT void removeSample(MediaSample*);
+ WEBCORE_EXPORT size_t sizeInBytes() const { return m_totalSize; }
</ins><span class="cx">
</span><span class="cx"> template<typename I>
</span><span class="cx"> void addRange(I begin, I end);
</span><span class="cx">
</span><del>- DecodeOrderSampleMap& decodeOrder() { return m_decodeOrder; }
- const DecodeOrderSampleMap& decodeOrder() const { return m_decodeOrder; }
- PresentationOrderSampleMap& presentationOrder() { return m_decodeOrder.m_presentationOrder; }
- const PresentationOrderSampleMap& presentationOrder() const { return m_decodeOrder.m_presentationOrder; }
</del><ins>+ WEBCORE_EXPORT DecodeOrderSampleMap& decodeOrder() { return m_decodeOrder; }
+ WEBCORE_EXPORT const DecodeOrderSampleMap& decodeOrder() const { return m_decodeOrder; }
+ WEBCORE_EXPORT PresentationOrderSampleMap& presentationOrder() { return m_decodeOrder.m_presentationOrder; }
+ WEBCORE_EXPORT const PresentationOrderSampleMap& presentationOrder() const { return m_decodeOrder.m_presentationOrder; }
</ins><span class="cx">
</span><span class="cx"> private:
</span><span class="cx"> DecodeOrderSampleMap m_decodeOrder;
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoreModulesmediasourceSourceBuffercpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/Modules/mediasource/SourceBuffer.cpp (212056 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/Modules/mediasource/SourceBuffer.cpp        2017-02-10 06:36:27 UTC (rev 212056)
+++ branches/safari-603-branch/Source/WebCore/Modules/mediasource/SourceBuffer.cpp        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -708,7 +708,7 @@
</span><span class="cx"> additionalErasedRanges.add(previousSample.presentationTime() + previousSample.duration(), erasedStart);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- auto endIterator = trackBuffer.samples.presentationOrder().findSampleOnOrAfterPresentationTime(erasedEnd);
</del><ins>+ auto endIterator = trackBuffer.samples.presentationOrder().findSampleStartingOnOrAfterPresentationTime(erasedEnd);
</ins><span class="cx"> if (endIterator == trackBuffer.samples.presentationOrder().end())
</span><span class="cx"> additionalErasedRanges.add(erasedEnd, MediaTime::positiveInfiniteTime());
</span><span class="cx"> else {
</span><span class="lines">@@ -778,7 +778,7 @@
</span><span class="cx"> else
</span><span class="cx"> removePresentationEnd = trackBuffer.samples.presentationOrder().findSampleWithPresentationTime(removeDecodeEnd->second->presentationTime());
</span><span class="cx">
</span><del>- PresentationOrderSampleMap::iterator removePresentationStart = trackBuffer.samples.presentationOrder().findSampleOnOrAfterPresentationTime(start);
</del><ins>+ PresentationOrderSampleMap::iterator removePresentationStart = trackBuffer.samples.presentationOrder().findSampleStartingOnOrAfterPresentationTime(start);
</ins><span class="cx"> if (removePresentationStart == removePresentationEnd)
</span><span class="cx"> continue;
</span><span class="cx">
</span><span class="lines">@@ -1852,7 +1852,7 @@
</span><span class="cx"> auto currentSamplePTSIterator = trackBuffer.samples.presentationOrder().findSampleContainingPresentationTime(time);
</span><span class="cx">
</span><span class="cx"> if (currentSamplePTSIterator == trackBuffer.samples.presentationOrder().end())
</span><del>- currentSamplePTSIterator = trackBuffer.samples.presentationOrder().findSampleOnOrAfterPresentationTime(time);
</del><ins>+ currentSamplePTSIterator = trackBuffer.samples.presentationOrder().findSampleStartingOnOrAfterPresentationTime(time);
</ins><span class="cx">
</span><span class="cx"> if (currentSamplePTSIterator == trackBuffer.samples.presentationOrder().end()
</span><span class="cx"> || (currentSamplePTSIterator->first - time) > MediaSource::currentTimeFudgeFactor())
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj (212056 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2017-02-10 06:36:27 UTC (rev 212056)
+++ branches/safari-603-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -5894,7 +5894,7 @@
</span><span class="cx">                 CDCFABBE18C0AF84006F8450 /* SelectionSubtreeRoot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDCFABBC18C0AF19006F8450 /* SelectionSubtreeRoot.cpp */; };
</span><span class="cx">                 CDD525D7145B6DD0008D204D /* JSHTMLMediaElementCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDF65CCC145B6AFE00C4C7AA /* JSHTMLMediaElementCustom.cpp */; };
</span><span class="cx">                 CDD7089618359F6F002B3DC6 /* SampleMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDD7089418359F6E002B3DC6 /* SampleMap.cpp */; };
</span><del>-                CDD7089718359F6F002B3DC6 /* SampleMap.h in Headers */ = {isa = PBXBuildFile; fileRef = CDD7089518359F6F002B3DC6 /* SampleMap.h */; };
</del><ins>+                CDD7089718359F6F002B3DC6 /* SampleMap.h in Headers */ = {isa = PBXBuildFile; fileRef = CDD7089518359F6F002B3DC6 /* SampleMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 CDDC1E7A18A952F30027A9D4 /* MediaSourcePrivateClient.h in Headers */ = {isa = PBXBuildFile; fileRef = CDDC1E7918A952F30027A9D4 /* MediaSourcePrivateClient.h */; };
</span><span class="cx">                 CDDE02ED18B3ED6D00CF7FF1 /* CDMSessionAVFoundationObjC.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDDE02EB18B3ED6D00CF7FF1 /* CDMSessionAVFoundationObjC.mm */; };
</span><span class="cx">                 CDDE02F018B5651300CF7FF1 /* CDMSessionAVStreamSession.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDDE02EF18B5651200CF7FF1 /* CDMSessionAVStreamSession.mm */; };
</span></span></pre></div>
<a id="branchessafari603branchToolsChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Tools/ChangeLog (212056 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Tools/ChangeLog        2017-02-10 06:36:27 UTC (rev 212056)
+++ branches/safari-603-branch/Tools/ChangeLog        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -1,5 +1,28 @@
</span><span class="cx"> 2017-02-09 Matthew Hanson <matthew_hanson@apple.com>
</span><span class="cx">
</span><ins>+ Merge r211746. rdar://problem/30107622
+
+ 2017-02-06 Jer Noble <jer.noble@apple.com>
+
+ Playback stalls when a SourceBuffer append causes frame eviction
+ https://bugs.webkit.org/show_bug.cgi?id=167834
+
+ Reviewed by Eric Carlson.
+
+ Add new correctness tests for the Webcore::SampleMap class. Add additional subtests
+ for the WTF::MediaTime class.
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/WTF/MediaTime.cpp:
+ (TestWebKitAPI::TEST):
+ * TestWebKitAPI/Tests/WebCore/SampleMap.cpp: Added.
+ (WTF::operator<<):
+ (TestWebKitAPI::TestSample::create):
+ (TestWebKitAPI::TestSample::TestSample):
+ (TestWebKitAPI::TEST_F):
+
+2017-02-09 Matthew Hanson <matthew_hanson@apple.com>
+
</ins><span class="cx"> Merge r211663. rdar://problem/30343810
</span><span class="cx">
</span><span class="cx"> 2017-02-03 Jeremy Jones <jeremyj@apple.com>
</span></span></pre></div>
<a id="branchessafari603branchToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (212056 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2017-02-10 06:36:27 UTC (rev 212056)
+++ branches/safari-603-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -516,6 +516,7 @@
</span><span class="cx">                 CDC8E4951BC6F10800594FEC /* video-with-audio.mp4 in Copy Resources */ = {isa = PBXBuildFile; fileRef = CDC8E48A1BC5C96200594FEC /* video-with-audio.mp4 */; };
</span><span class="cx">                 CDC8E4961BC6F10800594FEC /* video-without-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CDC8E48B1BC5C96200594FEC /* video-without-audio.html */; };
</span><span class="cx">                 CDC8E4971BC6F10800594FEC /* video-without-audio.mp4 in Copy Resources */ = {isa = PBXBuildFile; fileRef = CDC8E48C1BC5C96200594FEC /* video-without-audio.mp4 */; };
</span><ins>+                CDCFA7AA1E45183200C2433D /* SampleMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDCFA7A91E45122F00C2433D /* SampleMap.cpp */; };
</ins><span class="cx">                 CDE195B51CFE0B880053D256 /* FullscreenTopContentInset.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CDE195B21CFE0ADE0053D256 /* FullscreenTopContentInset.html */; };
</span><span class="cx">                 CE14F1A4181873B0001C2705 /* WillPerformClientRedirectToURLCrash.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CE14F1A2181873B0001C2705 /* WillPerformClientRedirectToURLCrash.html */; };
</span><span class="cx">                 CE3524F81B1431F60028A7C5 /* TextFieldDidBeginAndEndEditing_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE3524F21B142B8D0028A7C5 /* TextFieldDidBeginAndEndEditing_Bundle.cpp */; };
</span><span class="lines">@@ -1289,6 +1290,7 @@
</span><span class="cx">                 CDC8E48A1BC5C96200594FEC /* video-with-audio.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "video-with-audio.mp4"; sourceTree = "<group>"; };
</span><span class="cx">                 CDC8E48B1BC5C96200594FEC /* video-without-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "video-without-audio.html"; sourceTree = "<group>"; };
</span><span class="cx">                 CDC8E48C1BC5C96200594FEC /* video-without-audio.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "video-without-audio.mp4"; sourceTree = "<group>"; };
</span><ins>+                CDCFA7A91E45122F00C2433D /* SampleMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SampleMap.cpp; sourceTree = "<group>"; };
</ins><span class="cx">                 CDE195B21CFE0ADE0053D256 /* FullscreenTopContentInset.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = FullscreenTopContentInset.html; sourceTree = "<group>"; };
</span><span class="cx">                 CDE195B31CFE0ADE0053D256 /* FullscreenTopContentInset.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FullscreenTopContentInset.mm; sourceTree = "<group>"; };
</span><span class="cx">                 CE14F1A2181873B0001C2705 /* WillPerformClientRedirectToURLCrash.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = WillPerformClientRedirectToURLCrash.html; sourceTree = "<group>"; };
</span><span class="lines">@@ -1580,6 +1582,7 @@
</span><span class="cx">                                 83B88A331C80056D00BB2418 /* HTMLParserIdioms.cpp */,
</span><span class="cx">                                 14464012167A8305000BD218 /* LayoutUnit.cpp */,
</span><span class="cx">                                 CD225C071C45A69200140761 /* ParsedContentRange.cpp */,
</span><ins>+                                CDCFA7A91E45122F00C2433D /* SampleMap.cpp */,
</ins><span class="cx">                                 41973B5C1AF22875006C7B36 /* SharedBuffer.cpp */,
</span><span class="cx">                                 CDC2C7141797089D00E627FB /* TimeRanges.cpp */,
</span><span class="cx">                                 7AD3FE8D1D75FB8D00B169A4 /* TransformationMatrix.cpp */,
</span><span class="lines">@@ -2688,6 +2691,7 @@
</span><span class="cx">                                 7CCE7F191A411AE600447C4C /* WebArchive.cpp in Sources */,
</span><span class="cx">                                 2D4CF8BD1D8360CC0001CE8D /* WKThumbnailView.mm in Sources */,
</span><span class="cx">                                 7C83E04C1D0A641800FEBCF3 /* WebCoreNSURLSession.mm in Sources */,
</span><ins>+                                CDCFA7AA1E45183200C2433D /* SampleMap.cpp in Sources */,
</ins><span class="cx">                                 7CCE7F1A1A411AE600447C4C /* WebCoreStatisticsWithNoWebProcess.cpp in Sources */,
</span><span class="cx">                                 7CCE7EAB1A411A2400447C4C /* WebKitAgnosticTest.mm in Sources */,
</span><span class="cx">                                 51714EB81CF8CA17004723C4 /* WebProcessKillIDBCleanup.mm in Sources */,
</span></span></pre></div>
<a id="branchessafari603branchToolsTestWebKitAPITestsWTFMediaTimecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Tools/TestWebKitAPI/Tests/WTF/MediaTime.cpp (212056 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Tools/TestWebKitAPI/Tests/WTF/MediaTime.cpp        2017-02-10 06:36:27 UTC (rev 212056)
+++ branches/safari-603-branch/Tools/TestWebKitAPI/Tests/WTF/MediaTime.cpp        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -85,6 +85,8 @@
</span><span class="cx"> EXPECT_EQ(MediaTime(1, 1) != MediaTime(2, 1), true);
</span><span class="cx"> EXPECT_EQ(MediaTime(2, 1) == MediaTime(2, 1), true);
</span><span class="cx"> EXPECT_EQ(MediaTime(2, 1) == MediaTime(4, 2), true);
</span><ins>+ EXPECT_TRUE((bool)MediaTime(1, 1));
+ EXPECT_TRUE(!MediaTime(0, 1));
</ins><span class="cx">
</span><span class="cx"> // Addition Operators
</span><span class="cx"> EXPECT_EQ(MediaTime::positiveInfiniteTime() + MediaTime::positiveInfiniteTime(), MediaTime::positiveInfiniteTime());
</span><span class="lines">@@ -158,8 +160,6 @@
</span><span class="cx"> EXPECT_EQ(abs(MediaTime::invalidTime()), MediaTime::invalidTime());
</span><span class="cx"> EXPECT_EQ(abs(MediaTime(1, 1)), MediaTime(1, 1));
</span><span class="cx"> EXPECT_EQ(abs(MediaTime(-1, 1)), MediaTime(1, 1));
</span><del>- EXPECT_EQ(abs(MediaTime(-1, -1)), MediaTime(-1, -1));
- EXPECT_EQ(abs(MediaTime(1, -1)), MediaTime(-1, -1));
</del><span class="cx">
</span><span class="cx"> // Floating Point Functions
</span><span class="cx"> EXPECT_EQ(MediaTime::createWithFloat(1.0f), MediaTime(1, 1));
</span><span class="lines">@@ -200,14 +200,14 @@
</span><span class="cx"> // Overflow Behavior
</span><span class="cx"> EXPECT_EQ(MediaTime::createWithFloat(pow(2.0f, 64.0f)), MediaTime::positiveInfiniteTime());
</span><span class="cx"> EXPECT_EQ(MediaTime::createWithFloat(-pow(2.0f, 64.0f)), MediaTime::negativeInfiniteTime());
</span><del>- EXPECT_EQ(MediaTime::createWithFloat(pow(2.0f, 63.0f), 2).timeScale(), 1);
- EXPECT_EQ(MediaTime::createWithFloat(pow(2.0f, 63.0f), 3).timeScale(), 1);
</del><ins>+ EXPECT_EQ(MediaTime::createWithFloat(pow(2.0f, 63.0f), 2).timeScale(), 1U);
+ EXPECT_EQ(MediaTime::createWithFloat(pow(2.0f, 63.0f), 3).timeScale(), 1U);
</ins><span class="cx"> EXPECT_EQ(MediaTime::createWithDouble(pow(2.0, 64.0)), MediaTime::positiveInfiniteTime());
</span><span class="cx"> EXPECT_EQ(MediaTime::createWithDouble(-pow(2.0, 64.0)), MediaTime::negativeInfiniteTime());
</span><del>- EXPECT_EQ(MediaTime::createWithDouble(pow(2.0, 63.0), 2).timeScale(), 1);
- EXPECT_EQ(MediaTime::createWithDouble(pow(2.0, 63.0), 3).timeScale(), 1);
- EXPECT_EQ((MediaTime(numeric_limits<int64_t>::max(), 2) + MediaTime(numeric_limits<int64_t>::max(), 2)).timeScale(), 1);
- EXPECT_EQ((MediaTime(numeric_limits<int64_t>::min(), 2) - MediaTime(numeric_limits<int64_t>::max(), 2)).timeScale(), 1);
</del><ins>+ EXPECT_EQ(MediaTime::createWithDouble(pow(2.0, 63.0), 2).timeScale(), 1U);
+ EXPECT_EQ(MediaTime::createWithDouble(pow(2.0, 63.0), 3).timeScale(), 1U);
+ EXPECT_EQ((MediaTime(numeric_limits<int64_t>::max(), 2) + MediaTime(numeric_limits<int64_t>::max(), 2)).timeScale(), 1U);
+ EXPECT_EQ((MediaTime(numeric_limits<int64_t>::min(), 2) - MediaTime(numeric_limits<int64_t>::max(), 2)).timeScale(), 1U);
</ins><span class="cx"> EXPECT_EQ(MediaTime(numeric_limits<int64_t>::max(), 1) + MediaTime(numeric_limits<int64_t>::max(), 1), MediaTime::positiveInfiniteTime());
</span><span class="cx"> EXPECT_EQ(MediaTime(numeric_limits<int64_t>::min(), 1) + MediaTime(numeric_limits<int64_t>::min(), 1), MediaTime::negativeInfiniteTime());
</span><span class="cx"> EXPECT_EQ(MediaTime(numeric_limits<int64_t>::min(), 1) - MediaTime(numeric_limits<int64_t>::max(), 1), MediaTime::negativeInfiniteTime());
</span></span></pre></div>
<a id="branchessafari603branchToolsTestWebKitAPITestsWebCoreSampleMapcpp"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/Tools/TestWebKitAPI/Tests/WebCore/SampleMap.cpp (0 => 212057)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Tools/TestWebKitAPI/Tests/WebCore/SampleMap.cpp         (rev 0)
+++ branches/safari-603-branch/Tools/TestWebKitAPI/Tests/WebCore/SampleMap.cpp        2017-02-10 06:36:35 UTC (rev 212057)
</span><span class="lines">@@ -0,0 +1,224 @@
</span><ins>+/*
+ * Copyright (C) 2017 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 met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(MEDIA_SOURCE)
+
+#include "Test.h"
+#include <WebCore/MediaSample.h>
+#include <WebCore/SampleMap.h>
+
+namespace WTF {
+inline std::ostream& operator<<(std::ostream& os, const MediaTime& time)
+{
+ if (time.hasDoubleValue())
+ os << "{ " << time.toDouble() << " }";
+ else
+ os << "{ " << time.timeValue() << " / " << time.timeScale() << ", " << time.toDouble() << " }";
+ return os;
+}
+}
+
+using namespace WebCore;
+
+namespace TestWebKitAPI {
+
+class TestSample : public MediaSample {
+public:
+ static Ref<TestSample> create(const MediaTime& presentationTime, const MediaTime& decodeTime, const MediaTime& duration, SampleFlags flags)
+ {
+ return adoptRef(*new TestSample(presentationTime, decodeTime, duration, flags));
+ }
+
+ MediaTime presentationTime() const final { return m_presentationTime; }
+ MediaTime decodeTime() const final { return m_decodeTime; }
+ MediaTime duration() const final { return m_duration; }
+ AtomicString trackID() const final { return m_trackID; }
+ void setTrackID(const String& trackID) final { m_trackID = trackID; }
+ size_t sizeInBytes() const final { return m_sizeInBytes; }
+ FloatSize presentationSize() const final { return m_presentationSize; }
+ void offsetTimestampsBy(const MediaTime& offset) final { m_presentationTime += offset; m_decodeTime += offset; }
+ void setTimestamps(const MediaTime& presentationTime, const MediaTime& decodeTime) final {
+ m_presentationTime = presentationTime;
+ m_decodeTime = decodeTime;
+ };
+ bool isDivisable() const final { return false; }
+ std::pair<RefPtr<MediaSample>, RefPtr<MediaSample>> divide(const MediaTime& presentationTime) final { return { }; }
+ Ref<MediaSample> createNonDisplayingCopy() const final {
+ return create(m_presentationTime, m_decodeTime, m_duration, static_cast<SampleFlags>(m_flags | IsNonDisplaying));
+ }
+ SampleFlags flags() const final { return m_flags; }
+ PlatformSample platformSample() final { return { PlatformSample::None, {nullptr}}; }
+ void dump(PrintStream&) const final { }
+
+private:
+ TestSample(const MediaTime& presentationTime, const MediaTime& decodeTime, const MediaTime& duration, SampleFlags flags)
+ : m_presentationTime(presentationTime)
+ , m_decodeTime(decodeTime)
+ , m_duration(duration)
+ , m_flags(flags)
+ {
+ }
+
+ MediaTime m_presentationTime;
+ MediaTime m_decodeTime;
+ MediaTime m_duration;
+ FloatSize m_presentationSize;
+ AtomicString m_trackID;
+ size_t m_sizeInBytes { 0 };
+ SampleFlags m_flags { None };
+};
+
+class SampleMapTest : public testing::Test {
+public:
+ void SetUp() final {
+ map.addSample(TestSample::create(MediaTime(0, 1), MediaTime(0, 1), MediaTime(1, 1), MediaSample::IsSync));
+ map.addSample(TestSample::create(MediaTime(1, 1), MediaTime(0, 1), MediaTime(1, 1), MediaSample::None));
+ map.addSample(TestSample::create(MediaTime(2, 1), MediaTime(0, 1), MediaTime(1, 1), MediaSample::None));
+ map.addSample(TestSample::create(MediaTime(3, 1), MediaTime(0, 1), MediaTime(1, 1), MediaSample::None));
+ map.addSample(TestSample::create(MediaTime(4, 1), MediaTime(0, 1), MediaTime(1, 1), MediaSample::None));
+ map.addSample(TestSample::create(MediaTime(5, 1), MediaTime(0, 1), MediaTime(1, 1), MediaSample::IsSync));
+ map.addSample(TestSample::create(MediaTime(6, 1), MediaTime(0, 1), MediaTime(1, 1), MediaSample::None));
+ map.addSample(TestSample::create(MediaTime(7, 1), MediaTime(0, 1), MediaTime(1, 1), MediaSample::None));
+ map.addSample(TestSample::create(MediaTime(8, 1), MediaTime(0, 1), MediaTime(1, 1), MediaSample::None));
+ map.addSample(TestSample::create(MediaTime(9, 1), MediaTime(0, 1), MediaTime(1, 1), MediaSample::None));
+ // Gap at MediaTime(10, 1) -> MediaTime(11, 1);
+ map.addSample(TestSample::create(MediaTime(11, 1), MediaTime(0, 1), MediaTime(1, 1), MediaSample::IsSync));
+ map.addSample(TestSample::create(MediaTime(12, 1), MediaTime(0, 1), MediaTime(1, 1), MediaSample::None));
+ map.addSample(TestSample::create(MediaTime(13, 1), MediaTime(0, 1), MediaTime(1, 1), MediaSample::None));
+ map.addSample(TestSample::create(MediaTime(14, 1), MediaTime(0, 1), MediaTime(1, 1), MediaSample::None));
+ map.addSample(TestSample::create(MediaTime(15, 1), MediaTime(0, 1), MediaTime(1, 1), MediaSample::IsSync));
+ map.addSample(TestSample::create(MediaTime(16, 1), MediaTime(0, 1), MediaTime(1, 1), MediaSample::None));
+ map.addSample(TestSample::create(MediaTime(17, 1), MediaTime(0, 1), MediaTime(1, 1), MediaSample::None));
+ map.addSample(TestSample::create(MediaTime(18, 1), MediaTime(0, 1), MediaTime(1, 1), MediaSample::None));
+ map.addSample(TestSample::create(MediaTime(19, 1), MediaTime(0, 1), MediaTime(1, 1), MediaSample::None));
+ }
+
+ SampleMap map;
+};
+
+TEST_F(SampleMapTest, findSampleWithPresentationTime)
+{
+ auto& presentationMap = map.presentationOrder();
+ EXPECT_EQ(MediaTime(0, 1), presentationMap.findSampleWithPresentationTime(MediaTime(0, 1))->second->presentationTime());
+ EXPECT_EQ(MediaTime(19, 1), presentationMap.findSampleWithPresentationTime(MediaTime(19, 1))->second->presentationTime());
+ EXPECT_TRUE(presentationMap.end() == presentationMap.findSampleWithPresentationTime(MediaTime(-1, 1)));
+ EXPECT_TRUE(presentationMap.end() == presentationMap.findSampleWithPresentationTime(MediaTime(10, 1)));
+ EXPECT_TRUE(presentationMap.end() == presentationMap.findSampleWithPresentationTime(MediaTime(20, 1)));
+ EXPECT_TRUE(presentationMap.end() == presentationMap.findSampleWithPresentationTime(MediaTime(1, 2)));
+}
+
+TEST_F(SampleMapTest, findSampleContainingPresentationTime)
+{
+ auto& presentationMap = map.presentationOrder();
+ EXPECT_EQ(MediaTime(0, 1), presentationMap.findSampleContainingPresentationTime(MediaTime(0, 1))->second->presentationTime());
+ EXPECT_EQ(MediaTime(19, 1), presentationMap.findSampleContainingPresentationTime(MediaTime(19, 1))->second->presentationTime());
+ EXPECT_EQ(MediaTime(0, 1), presentationMap.findSampleContainingPresentationTime(MediaTime(1, 2))->second->presentationTime());
+ EXPECT_TRUE(presentationMap.end() == presentationMap.findSampleContainingPresentationTime(MediaTime(-1, 1)));
+ EXPECT_TRUE(presentationMap.end() == presentationMap.findSampleContainingPresentationTime(MediaTime(10, 1)));
+ EXPECT_TRUE(presentationMap.end() == presentationMap.findSampleContainingPresentationTime(MediaTime(20, 1)));
+}
+
+TEST_F(SampleMapTest, findSampleStartingOnOrAfterPresentationTime)
+{
+ auto& presentationMap = map.presentationOrder();
+ EXPECT_EQ(MediaTime(0, 1), presentationMap.findSampleStartingOnOrAfterPresentationTime(MediaTime(0, 1))->second->presentationTime());
+ EXPECT_EQ(MediaTime(19, 1), presentationMap.findSampleStartingOnOrAfterPresentationTime(MediaTime(19, 1))->second->presentationTime());
+ EXPECT_EQ(MediaTime(1, 1), presentationMap.findSampleStartingOnOrAfterPresentationTime(MediaTime(1, 2))->second->presentationTime());
+ EXPECT_EQ(MediaTime(0, 1), presentationMap.findSampleStartingOnOrAfterPresentationTime(MediaTime(-1, 1))->second->presentationTime());
+ EXPECT_EQ(MediaTime(11, 1), presentationMap.findSampleStartingOnOrAfterPresentationTime(MediaTime(10, 1))->second->presentationTime());
+ EXPECT_TRUE(presentationMap.end() == presentationMap.findSampleContainingPresentationTime(MediaTime(20, 1)));
+}
+
+TEST_F(SampleMapTest, findSamplesBetweenPresentationTimes)
+{
+ auto& presentationMap = map.presentationOrder();
+ auto iterator_range = presentationMap.findSamplesBetweenPresentationTimes(MediaTime(0, 1), MediaTime(1, 1));
+ EXPECT_EQ(MediaTime(0, 1), iterator_range.first->second->presentationTime());
+ EXPECT_EQ(MediaTime(1, 1), iterator_range.second->second->presentationTime());
+
+ iterator_range = presentationMap.findSamplesBetweenPresentationTimes(MediaTime(1, 2), MediaTime(3, 2));
+ EXPECT_EQ(MediaTime(1, 1), iterator_range.first->second->presentationTime());
+ EXPECT_EQ(MediaTime(2, 1), iterator_range.second->second->presentationTime());
+
+ iterator_range = presentationMap.findSamplesBetweenPresentationTimes(MediaTime(9, 1), MediaTime(21, 1));
+ EXPECT_EQ(MediaTime(9, 1), iterator_range.first->second->presentationTime());
+ EXPECT_TRUE(presentationMap.end() == iterator_range.second);
+
+ iterator_range = presentationMap.findSamplesBetweenPresentationTimes(MediaTime(-1, 1), MediaTime(0, 1));
+ EXPECT_TRUE(presentationMap.end() == iterator_range.first);
+ EXPECT_TRUE(presentationMap.end() == iterator_range.second);
+
+ iterator_range = presentationMap.findSamplesBetweenPresentationTimes(MediaTime(19, 2), MediaTime(10, 1));
+ EXPECT_TRUE(presentationMap.end() == iterator_range.first);
+ EXPECT_TRUE(presentationMap.end() == iterator_range.second);
+
+ iterator_range = presentationMap.findSamplesBetweenPresentationTimes(MediaTime(20, 1), MediaTime(21, 1));
+ EXPECT_TRUE(presentationMap.end() == iterator_range.first);
+ EXPECT_TRUE(presentationMap.end() == iterator_range.second);
+}
+
+TEST_F(SampleMapTest, findSamplesWithinPresentationRange)
+{
+ auto& presentationMap = map.presentationOrder();
+ auto iterator_range = presentationMap.findSamplesWithinPresentationRange(MediaTime(0, 1), MediaTime(1, 1));
+ EXPECT_EQ(MediaTime(1, 1), iterator_range.first->second->presentationTime());
+ EXPECT_EQ(MediaTime(2, 1), iterator_range.second->second->presentationTime());
+
+ iterator_range = presentationMap.findSamplesWithinPresentationRange(MediaTime(1, 2), MediaTime(3, 2));
+ EXPECT_EQ(MediaTime(1, 1), iterator_range.first->second->presentationTime());
+ EXPECT_EQ(MediaTime(2, 1), iterator_range.second->second->presentationTime());
+
+ iterator_range = presentationMap.findSamplesWithinPresentationRange(MediaTime(9, 1), MediaTime(21, 1));
+ EXPECT_EQ(MediaTime(11, 1), iterator_range.first->second->presentationTime());
+ EXPECT_TRUE(presentationMap.end() == iterator_range.second);
+
+ iterator_range = presentationMap.findSamplesWithinPresentationRange(MediaTime(-1, 1), MediaTime(0, 1));
+ EXPECT_EQ(MediaTime(0, 1), iterator_range.first->second->presentationTime());
+ EXPECT_EQ(MediaTime(1, 1), iterator_range.second->second->presentationTime());
+
+ iterator_range = presentationMap.findSamplesWithinPresentationRange(MediaTime(10, 1), MediaTime(21, 2));
+ EXPECT_TRUE(presentationMap.end() == iterator_range.first);
+ EXPECT_TRUE(presentationMap.end() == iterator_range.second);
+
+ iterator_range = presentationMap.findSamplesWithinPresentationRange(MediaTime(20, 1), MediaTime(21, 1));
+ EXPECT_TRUE(presentationMap.end() == iterator_range.first);
+ EXPECT_TRUE(presentationMap.end() == iterator_range.second);
+}
+
+TEST_F(SampleMapTest, reverseFindSampleBeforePresentationTime)
+{
+ auto& presentationMap = map.presentationOrder();
+ EXPECT_EQ(MediaTime(0, 1), presentationMap.reverseFindSampleBeforePresentationTime(MediaTime(0, 1))->second->presentationTime());
+ EXPECT_EQ(MediaTime(9, 1), presentationMap.reverseFindSampleBeforePresentationTime(MediaTime(10, 1))->second->presentationTime());
+ EXPECT_EQ(MediaTime(19, 1), presentationMap.reverseFindSampleBeforePresentationTime(MediaTime(19, 1))->second->presentationTime());
+ EXPECT_EQ(MediaTime(19, 1), presentationMap.reverseFindSampleBeforePresentationTime(MediaTime(21, 1))->second->presentationTime());
+ EXPECT_TRUE(presentationMap.rend() == presentationMap.reverseFindSampleBeforePresentationTime(MediaTime(-1, 1)));
+}
+
+}
+
+#endif // ENABLE(MEDIA_SOURCE)
</ins></span></pre>
</div>
</div>
</body>
</html>