<!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  &lt;matthew_hanson@apple.com&gt;
+
+        Merge r211746. rdar://problem/30107622
+
+    2017-02-06  Jer Noble  &lt;jer.noble@apple.com&gt;
+
+            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  &lt;beidson@apple.com&gt;
</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>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;media-source-loader.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../resources/runner.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+var loader;
+var video;
+var longMediaSegment;
+
+function concatArrayBuffers() {
+    var byteLength = 0;
+    Array.prototype.forEach.call(arguments, arrayBuffer =&gt; {
+        if (!arrayBuffer.byteLength)
+            throw &quot;Not an ArrayBuffer!&quot;;
+        byteLength += arrayBuffer.byteLength;
+    });
+
+
+    var view = new Uint8Array(byteLength);
+    var offset = 0;
+    Array.prototype.forEach.call(arguments, arrayBuffer =&gt; {
+        view.set(new Uint8Array(arrayBuffer), offset);
+        offset += arrayBuffer.byteLength;
+    });
+    return view.buffer;
+}
+
+function concatMediaData() {
+    return new Promise((resolve, reject) =&gt; {
+        var segments = new Array(100);
+        segments.fill(loader.everyMediaSegment);
+        longMediaSegment = concatArrayBuffers.apply(this, segments);
+        resolve(longMediaSegment);
+    });
+}
+
+window.addEventListener('load', () =&gt; {
+    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 =&gt; {
+        var removeNext30Seconds = () =&gt; {
+            var start = sourceBuffer.buffered.start(0);
+            sourceBuffer.remove(start, start + 30)
+        }
+        sourceBuffer.onupdate = () =&gt; {
+            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 =&gt; {
+        startTime = PerfTestRunner.now();
+        return remove30SecondsAtATimeTillEmpty(sourceBuffer);
+    }).then(() =&gt; {
+        if (PerfTestRunner.measureValueAsync(PerfTestRunner.now() - startTime))
+            setTimeout(runTest, 0);
+    });
+}
+
+function loadMediaDataIntoVideo(video, segmentCount) {
+    return new Promise((resolve, reject) =&gt; {
+        var source = new MediaSource();
+        source.onsourceopen = () =&gt; {
+            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 = () =&gt; {
+
+                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 =&gt; {
+                reject(error);
+            };
+        };
+        video.src = URL.createObjectURL(source);
+    });
+}
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</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) =&gt; { 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 &quot;../../../../Internal/Configurations/HaveInternalSDK.xcconfig&quot;
+
+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: &lt;http://webkit.org/b/107093&gt; 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 &quot;Base.xcconfig&quot;
+
+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 = &quot;&lt;group&gt;&quot;; };
+                CD836D001E43BDB4009F8091 /* DebugRelease.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DebugRelease.xcconfig; sourceTree = &quot;&lt;group&gt;&quot;; };
+                CDB099DD1E4308470039E198 /* MediaTime */ = {isa = PBXFileReference; explicitFileType = &quot;compiled.mach-o.executable&quot;; 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 = &quot;&lt;group&gt;&quot;; };
+                CDB099E81E4308700039E198 /* libWTF.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libWTF.a; path = ../../WebKit.git/OpenSource/WebKitBuild/Debug/libWTF.a; sourceTree = &quot;&lt;group&gt;&quot;; };
+                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 = &quot;compiled.mach-o.dylib&quot;; 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 = &quot;&lt;group&gt;&quot;;
+                };
+                CDB099D41E4308470039E198 = {
+                        isa = PBXGroup;
+                        children = (
+                                CDB099E01E4308470039E198 /* main.cpp */,
+                                CD836CFD1E43BDB4009F8091 /* Configurations */,
+                                CDB099DE1E4308470039E198 /* Products */,
+                                CDB099E71E43086F0039E198 /* Frameworks */,
+                        );
+                        sourceTree = &quot;&lt;group&gt;&quot;;
+                };
+                CDB099DE1E4308470039E198 /* Products */ = {
+                        isa = PBXGroup;
+                        children = (
+                                CDB099DD1E4308470039E198 /* MediaTime */,
+                        );
+                        name = Products;
+                        sourceTree = &quot;&lt;group&gt;&quot;;
+                };
+                CDB099E71E43086F0039E198 /* Frameworks */ = {
+                        isa = PBXGroup;
+                        children = (
+                                CDB099EE1E430B550039E198 /* libicucore.dylib */,
+                                CDB099EC1E430B440039E198 /* Foundation.framework */,
+                                CDB099EA1E430B250039E198 /* CoreFoundation.framework */,
+                                CDB099E81E4308700039E198 /* libWTF.a */,
+                        );
+                        name = Frameworks;
+                        sourceTree = &quot;&lt;group&gt;&quot;;
+                };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+                CDB099DC1E4308470039E198 /* MediaTime */ = {
+                        isa = PBXNativeTarget;
+                        buildConfigurationList = CDB099E41E4308470039E198 /* Build configuration list for PBXNativeTarget &quot;MediaTime&quot; */;
+                        buildPhases = (
+                                CDB099D91E4308470039E198 /* Sources */,
+                                CDB099DA1E4308470039E198 /* Frameworks */,
+                                CDB099DB1E4308470039E198 /* CopyFiles */,
+                        );
+                        buildRules = (
+                        );
+                        dependencies = (
+                        );
+                        name = MediaTime;
+                        productName = MediaTimeTestcase;
+                        productReference = CDB099DD1E4308470039E198 /* MediaTime */;
+                        productType = &quot;com.apple.product-type.tool&quot;;
+                };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+                CDB099D51E4308470039E198 /* Project object */ = {
+                        isa = PBXProject;
+                        attributes = {
+                                LastUpgradeCheck = 0830;
+                                ORGANIZATIONNAME = &quot;Jeremy Noble&quot;;
+                                TargetAttributes = {
+                                        CDB099DC1E4308470039E198 = {
+                                                CreatedOnToolsVersion = 8.3;
+                                                DevelopmentTeam = G5UYP5CS7K;
+                                                ProvisioningStyle = Automatic;
+                                        };
+                                };
+                        };
+                        buildConfigurationList = CDB099D81E4308470039E198 /* Build configuration list for PBXProject &quot;MediaTime&quot; */;
+                        compatibilityVersion = &quot;Xcode 3.2&quot;;
+                        developmentRegion = English;
+                        hasScannedForEncodings = 0;
+                        knownRegions = (
+                                en,
+                        );
+                        mainGroup = CDB099D41E4308470039E198;
+                        productRefGroup = CDB099DE1E4308470039E198 /* Products */;
+                        projectDirPath = &quot;&quot;;
+                        projectRoot = &quot;&quot;;
+                        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 = &quot;c++0x&quot;;
+                                CLANG_CXX_LIBRARY = &quot;libc++&quot;;
+                                DEBUG_INFORMATION_FORMAT = dwarf;
+                                ENABLE_TESTABILITY = YES;
+                                GCC_DYNAMIC_NO_PIC = NO;
+                                GCC_NO_COMMON_BLOCKS = YES;
+                                GCC_OPTIMIZATION_LEVEL = 0;
+                                GCC_PREPROCESSOR_DEFINITIONS = (
+                                        &quot;DEBUG=1&quot;,
+                                        &quot;$(inherited)&quot;,
+                                );
+                                ONLY_ACTIVE_ARCH = YES;
+                        };
+                        name = Debug;
+                };
+                CDB099E31E4308470039E198 /* Release */ = {
+                        isa = XCBuildConfiguration;
+                        baseConfigurationReference = CD836D001E43BDB4009F8091 /* DebugRelease.xcconfig */;
+                        buildSettings = {
+                                ALWAYS_SEARCH_USER_PATHS = YES;
+                                CLANG_CXX_LANGUAGE_STANDARD = &quot;c++0x&quot;;
+                                CLANG_CXX_LIBRARY = &quot;libc++&quot;;
+                                DEBUG_INFORMATION_FORMAT = &quot;dwarf-with-dsym&quot;;
+                                GCC_NO_COMMON_BLOCKS = YES;
+                        };
+                        name = Release;
+                };
+                CDB099E51E4308470039E198 /* Debug */ = {
+                        isa = XCBuildConfiguration;
+                        buildSettings = {
+                                CLANG_CXX_LANGUAGE_STANDARD = &quot;c++14&quot;;
+                                DEVELOPMENT_TEAM = G5UYP5CS7K;
+                                PRODUCT_NAME = &quot;$(TARGET_NAME)&quot;;
+                        };
+                        name = Debug;
+                };
+                CDB099E61E4308470039E198 /* Release */ = {
+                        isa = XCBuildConfiguration;
+                        buildSettings = {
+                                CLANG_CXX_LANGUAGE_STANDARD = &quot;c++14&quot;;
+                                DEVELOPMENT_TEAM = G5UYP5CS7K;
+                                PRODUCT_NAME = &quot;$(TARGET_NAME)&quot;;
+                        };
+                        name = Release;
+                };
+                CDB099F01E4394540039E198 /* Control */ = {
+                        isa = XCBuildConfiguration;
+                        buildSettings = {
+                                ALWAYS_SEARCH_USER_PATHS = YES;
+                                CLANG_CXX_LANGUAGE_STANDARD = &quot;c++0x&quot;;
+                                CLANG_CXX_LIBRARY = &quot;libc++&quot;;
+                                DEBUG_INFORMATION_FORMAT = &quot;dwarf-with-dsym&quot;;
+                                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 = &quot;c++14&quot;;
+                                DEVELOPMENT_TEAM = G5UYP5CS7K;
+                                PRODUCT_NAME = &quot;$(TARGET_NAME)&quot;;
+                        };
+                        name = Control;
+                };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+                CDB099D81E4308470039E198 /* Build configuration list for PBXProject &quot;MediaTime&quot; */ = {
+                        isa = XCConfigurationList;
+                        buildConfigurations = (
+                                CDB099E21E4308470039E198 /* Debug */,
+                                CDB099E31E4308470039E198 /* Release */,
+                                CDB099F01E4394540039E198 /* Control */,
+                        );
+                        defaultConfigurationIsVisible = 0;
+                        defaultConfigurationName = Release;
+                };
+                CDB099E41E4308470039E198 /* Build configuration list for PBXNativeTarget &quot;MediaTime&quot; */ = {
+                        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 &lt;chrono&gt;
+#include &lt;random&gt;
+#include &lt;set&gt;
+#include &lt;wtf/MediaTime.h&gt;
+
+using namespace std;
+using namespace std::chrono;
+
+static const size_t setSize = 100000;
+
+void performTest(const char* name, function&lt;void()&gt; test)
+{
+    vector&lt;double&gt; runtimes(21);
+    for (auto&amp; runtime : runtimes) {
+        auto start = steady_clock::now();
+        test();
+        runtime = duration_cast&lt;milliseconds&gt;(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(&quot;RESULT %s: Time= %g ms&quot;, name, sum);
+    printf(&quot;median= %g ms, stdev= %g ms, min= %g ms, max = %g ms&quot;, median, stdev, min, max);
+}
+
+void test(int32_t count, function&lt;MediaTime(int32_t)&gt; generator)
+{
+    set&lt;MediaTime&gt; times;
+
+    for (int32_t i = 0; i &lt; count; ++i)
+        times.insert(generator(i));
+
+    for (int32_t i = 0; i &lt; count; ++i)
+        times.upper_bound(generator(i));
+}
+
+int main(int argc, const char * argv[])
+{
+    performTest(&quot;Equal TimeScales&quot;, [] { test(setSize, [] (int32_t i) { return MediaTime(i, 1); }); });
+    performTest(&quot;Equal TimeValues&quot;, [] { test(setSize, [] (int32_t i) { return MediaTime(1, i + 1); }); });
+    performTest(&quot;Disparate TimeValues &amp; TimeScales&quot;, [] { test(setSize, [] (int32_t i) { return MediaTime(i, i + 1); }); });
+    performTest(&quot;Non-uniform&quot;, [] {
+        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  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r211746. rdar://problem/30107622
+
+    2017-02-06  Jer Noble  &lt;jer.noble@apple.com&gt;
+
+            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&lt;): Deleted.
+            (WTF::MediaTime::operator&gt;): Deleted.
+            (WTF::MediaTime::operator!=): Deleted.
+            (WTF::MediaTime::operator==): Deleted.
+            (WTF::MediaTime::operator&gt;=): Deleted.
+            (WTF::MediaTime::operator&lt;=): Deleted.
+            * wtf/MediaTime.h:
+
+2017-02-09  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
+
</ins><span class="cx">         Merge r211622. rdar://problem/30116072
</span><span class="cx"> 
</span><span class="cx">     2017-02-02  Andreas Kling  &lt;akling@apple.com&gt;
</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 &quot;MediaTime.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &lt;algorithm&gt;
</span><ins>+#include &lt;cstdlib&gt;
</ins><span class="cx"> #include &lt;wtf/CheckedArithmetic.h&gt;
</span><span class="cx"> #include &lt;wtf/MathExtras.h&gt;
</span><span class="cx"> #include &lt;wtf/PrintStream.h&gt;
</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 &amp;result)
</del><ins>+static uint32_t leastCommonMultiple(uint32_t a, uint32_t b, uint32_t &amp;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 &lt; val) - (val &lt; 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 &gt; 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-&gt;m_timeScale, rhs.m_timeScale, commonTimeScale) || commonTimeScale &gt; 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&lt;(const MediaTime&amp; rhs) const
-{
-    return compare(rhs) == LessThan;
-}
-
-bool MediaTime::operator&gt;(const MediaTime&amp; rhs) const
-{
-    return compare(rhs) == GreaterThan;
-}
-
-bool MediaTime::operator!=(const MediaTime&amp; rhs) const
-{
-    return compare(rhs) != EqualTo;
-}
-
-bool MediaTime::operator==(const MediaTime&amp; rhs) const
-{
-    return compare(rhs) == EqualTo;
-}
-
-bool MediaTime::operator&gt;=(const MediaTime&amp; rhs) const
-{
-    return compare(rhs) &gt;= EqualTo;
-}
-
-bool MediaTime::operator&lt;=(const MediaTime&amp; rhs) const
-{
-    return compare(rhs) &lt;= 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 &amp;&amp; !m_timeValue)
+        || (m_timeFlags == (Valid | DoubleValue) &amp;&amp; !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 &amp;&amp; !m_timeValue)
+        &amp;&amp; !(m_timeFlags == (Valid | DoubleValue) &amp;&amp; !m_timeValueAsDouble);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> MediaTime::ComparisonFlags MediaTime::compare(const MediaTime&amp; rhs) const
</span><span class="cx"> {
</span><del>-    if ((isPositiveInfinite() &amp;&amp; rhs.isPositiveInfinite())
-        || (isNegativeInfinite() &amp;&amp; rhs.isNegativeInfinite())
-        || (isInvalid() &amp;&amp; rhs.isInvalid())
-        || (isIndefinite() &amp;&amp; rhs.isIndefinite()))
</del><ins>+    auto andFlags = m_timeFlags &amp; rhs.m_timeFlags;
+    if (andFlags &amp; (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 &amp; Valid))
+        return EqualTo;
</ins><span class="cx"> 
</span><del>-    if (rhs.isInvalid())
-        return LessThan;
</del><ins>+    if (!(andFlags &amp; Valid))
+        return isInvalid() ? GreaterThan : LessThan;
</ins><span class="cx"> 
</span><del>-    if (rhs.isNegativeInfinite() || isPositiveInfinite())
-        return GreaterThan;
</del><ins>+    if (orFlags &amp; NegativeInfinite)
+        return isNegativeInfinite() ? LessThan : GreaterThan;
</ins><span class="cx"> 
</span><del>-    if (rhs.isPositiveInfinite() || isNegativeInfinite())
-        return LessThan;
</del><ins>+    if (orFlags &amp; PositiveInfinite)
+        return isPositiveInfinite() ? GreaterThan : LessThan;
</ins><span class="cx"> 
</span><del>-    if (isIndefinite())
-        return GreaterThan;
</del><ins>+    if (orFlags &amp; Indefinite)
+        return isIndefinite() ? GreaterThan : LessThan;
</ins><span class="cx"> 
</span><del>-    if (rhs.isIndefinite())
-        return LessThan;
-
-    if (hasDoubleValue() &amp;&amp; rhs.hasDoubleValue()) {
</del><ins>+    if (andFlags &amp; 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 &lt; rhs.m_timeValueAsDouble ? LessThan : GreaterThan;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (hasDoubleValue() || rhs.hasDoubleValue()) {
</del><ins>+    if (orFlags &amp; DoubleValue) {
</ins><span class="cx">         double a = toDouble();
</span><span class="cx">         double b = rhs.toDouble();
</span><span class="cx">         if (a &gt; 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 &lt; 0) != (rhs.m_timeValue &lt; 0))
+        return m_timeValue &lt; 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 &amp;&amp; !rhs.m_timeValue)
+        return EqualTo;
+
+    if (m_timeScale == rhs.m_timeScale) {
+        if (m_timeValue == rhs.m_timeValue)
+            return EqualTo;
+        return m_timeValue &lt; rhs.m_timeValue ? LessThan : GreaterThan;
+    }
+
+    if (m_timeValue == rhs.m_timeValue)
+        return m_timeScale &lt; rhs.m_timeScale ? GreaterThan : LessThan;
+
+    if (m_timeValue &lt; rhs.m_timeValue &amp;&amp; m_timeScale &gt; rhs.m_timeScale)
+        return LessThan;
+
+    if (m_timeValue &gt; rhs.m_timeValue &amp;&amp; m_timeScale &lt; rhs.m_timeScale)
+        return GreaterThan;
+
+    int64_t lhsFactor;
+    int64_t rhsFactor;
+    if (safeMultiply(m_timeValue, static_cast&lt;int64_t&gt;(rhs.m_timeScale), lhsFactor)
+        &amp;&amp; safeMultiply(rhs.m_timeValue, static_cast&lt;int64_t&gt;(m_timeScale), rhsFactor)) {
+        if (lhsFactor == rhsFactor)
+            return EqualTo;
+        return lhsFactor &lt; 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 &gt; rhsWhole)
</span><span class="cx">         return GreaterThan;
</span><span class="cx">     if (lhsWhole &lt; 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&lt;int64_t&gt;(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&amp; 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&amp; rhs) const;
</span><span class="cx">     MediaTime operator-() const;
</span><span class="cx">     MediaTime operator*(int32_t) const;
</span><del>-    bool operator&lt;(const MediaTime&amp; rhs) const;
-    bool operator&gt;(const MediaTime&amp; rhs) const;
-    bool operator!=(const MediaTime&amp; rhs) const;
-    bool operator==(const MediaTime&amp; rhs) const;
-    bool operator&gt;=(const MediaTime&amp; rhs) const;
-    bool operator&lt;=(const MediaTime&amp; rhs) const;
</del><ins>+    bool operator&lt;(const MediaTime&amp; rhs) const { return compare(rhs) == LessThan; }
+    bool operator&gt;(const MediaTime&amp; rhs) const { return compare(rhs) == GreaterThan; }
+    bool operator!=(const MediaTime&amp; rhs) const { return compare(rhs) != EqualTo; }
+    bool operator==(const MediaTime&amp; rhs) const { return compare(rhs) == EqualTo; }
+    bool operator&gt;=(const MediaTime&amp; rhs) const { return compare(rhs) &gt;= EqualTo; }
+    bool operator&lt;=(const MediaTime&amp; rhs) const { return compare(rhs) &lt;= 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&amp; indefiniteTime();
</span><span class="cx"> 
</span><span class="cx">     const int64_t&amp; timeValue() const { return m_timeValue; }
</span><del>-    const int32_t&amp; timeScale() const { return m_timeScale; }
</del><ins>+    const uint32_t&amp; timeScale() const { return m_timeScale; }
</ins><span class="cx"> 
</span><span class="cx">     void dump(PrintStream&amp; 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&amp; 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&amp; 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  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r211746. rdar://problem/30107622
+
+    2017-02-06  Jer Noble  &lt;jer.noble@apple.com&gt;
+
+            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  &lt;matthew_hanson@apple.com&gt;
+
</ins><span class="cx">         Merge r211730. rdar://problem/30251840
</span><span class="cx"> 
</span><span class="cx">     2017-02-06  Antti Koivisto  &lt;antti@apple.com&gt;
</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&amp; time)
</span><span class="cx"> {
</span><del>-    auto range = std::equal_range(begin(), end(), time, SampleIsLessThanMediaTimeComparator&lt;MapType&gt;());
-    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&amp; sample = *iter-&gt;second;
+    if (sample.presentationTime() + sample.duration() &gt; time)
+        return iter;
+    return end();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-PresentationOrderSampleMap::iterator PresentationOrderSampleMap::findSampleOnOrAfterPresentationTime(const MediaTime&amp; time)
</del><ins>+PresentationOrderSampleMap::iterator PresentationOrderSampleMap::findSampleStartingOnOrAfterPresentationTime(const MediaTime&amp; 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&amp; time)
</span><span class="cx"> {
</span><del>-    return std::lower_bound(rbegin(), rend(), time, SampleIsGreaterThanMediaTimeComparator&lt;MapType&gt;());
</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&amp; key)
</span><span class="lines">@@ -203,7 +226,7 @@
</span><span class="cx"> 
</span><span class="cx"> DecodeOrderSampleMap::iterator DecodeOrderSampleMap::findSyncSampleAfterPresentationTime(const MediaTime&amp; time, const MediaTime&amp; 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&amp; beginTime, const MediaTime&amp; endTime)
</span><span class="cx"> {
</span><del>-    std::pair&lt;MediaTime, MediaTime&gt; 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&amp; beginTime, const MediaTime&amp; endTime)
</span><span class="cx"> {
</span><del>-    std::pair&lt;MediaTime, MediaTime&gt; 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&amp; beginTime, const MediaTime&amp; 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&lt;iterator, iterator&gt; 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&amp;);
-    iterator findSampleContainingPresentationTime(const MediaTime&amp;);
-    iterator findSampleOnOrAfterPresentationTime(const MediaTime&amp;);
-    reverse_iterator reverseFindSampleContainingPresentationTime(const MediaTime&amp;);
-    reverse_iterator reverseFindSampleBeforePresentationTime(const MediaTime&amp;);
-    iterator_range findSamplesBetweenPresentationTimes(const MediaTime&amp;, const MediaTime&amp;);
-    iterator_range findSamplesWithinPresentationRange(const MediaTime&amp;, const MediaTime&amp;);
-    iterator_range findSamplesWithinPresentationRangeFromEnd(const MediaTime&amp;, const MediaTime&amp;);
</del><ins>+    WEBCORE_EXPORT iterator findSampleWithPresentationTime(const MediaTime&amp;);
+    WEBCORE_EXPORT iterator findSampleContainingPresentationTime(const MediaTime&amp;);
+    WEBCORE_EXPORT iterator findSampleStartingOnOrAfterPresentationTime(const MediaTime&amp;);
+    WEBCORE_EXPORT reverse_iterator reverseFindSampleContainingPresentationTime(const MediaTime&amp;);
+    WEBCORE_EXPORT reverse_iterator reverseFindSampleBeforePresentationTime(const MediaTime&amp;);
+    WEBCORE_EXPORT iterator_range findSamplesBetweenPresentationTimes(const MediaTime&amp;, const MediaTime&amp;);
+    WEBCORE_EXPORT iterator_range findSamplesWithinPresentationRange(const MediaTime&amp;, const MediaTime&amp;);
+    WEBCORE_EXPORT iterator_range findSamplesWithinPresentationRangeFromEnd(const MediaTime&amp;, const MediaTime&amp;);
</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&lt;reverse_iterator, reverse_iterator&gt; 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&amp;);
-    reverse_iterator reverseFindSampleWithDecodeKey(const KeyType&amp;);
-    reverse_iterator findSyncSamplePriorToPresentationTime(const MediaTime&amp;, const MediaTime&amp; threshold = MediaTime::positiveInfiniteTime());
-    reverse_iterator findSyncSamplePriorToDecodeIterator(reverse_iterator);
-    iterator findSyncSampleAfterPresentationTime(const MediaTime&amp;, const MediaTime&amp; threshold = MediaTime::positiveInfiniteTime());
-    iterator findSyncSampleAfterDecodeIterator(iterator);
-    reverse_iterator_range findDependentSamples(MediaSample*);
</del><ins>+    WEBCORE_EXPORT iterator findSampleWithDecodeKey(const KeyType&amp;);
+    WEBCORE_EXPORT reverse_iterator reverseFindSampleWithDecodeKey(const KeyType&amp;);
+    WEBCORE_EXPORT reverse_iterator findSyncSamplePriorToPresentationTime(const MediaTime&amp;, const MediaTime&amp; threshold = MediaTime::positiveInfiniteTime());
+    WEBCORE_EXPORT reverse_iterator findSyncSamplePriorToDecodeIterator(reverse_iterator);
+    WEBCORE_EXPORT iterator findSyncSampleAfterPresentationTime(const MediaTime&amp;, const MediaTime&amp; 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&amp;);
-    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&amp;);
+    WEBCORE_EXPORT void removeSample(MediaSample*);
+    WEBCORE_EXPORT size_t sizeInBytes() const { return m_totalSize; }
</ins><span class="cx"> 
</span><span class="cx">     template&lt;typename I&gt;
</span><span class="cx">     void addRange(I begin, I end);
</span><span class="cx"> 
</span><del>-    DecodeOrderSampleMap&amp; decodeOrder() { return m_decodeOrder; }
-    const DecodeOrderSampleMap&amp; decodeOrder() const { return m_decodeOrder; }
-    PresentationOrderSampleMap&amp; presentationOrder() { return m_decodeOrder.m_presentationOrder; }
-    const PresentationOrderSampleMap&amp; presentationOrder() const { return m_decodeOrder.m_presentationOrder; }
</del><ins>+    WEBCORE_EXPORT DecodeOrderSampleMap&amp; decodeOrder() { return m_decodeOrder; }
+    WEBCORE_EXPORT const DecodeOrderSampleMap&amp; decodeOrder() const { return m_decodeOrder; }
+    WEBCORE_EXPORT PresentationOrderSampleMap&amp; presentationOrder() { return m_decodeOrder.m_presentationOrder; }
+    WEBCORE_EXPORT const PresentationOrderSampleMap&amp; 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-&gt;second-&gt;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-&gt;first - time) &gt; 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  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r211746. rdar://problem/30107622
+
+    2017-02-06  Jer Noble  &lt;jer.noble@apple.com&gt;
+
+            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&lt;&lt;):
+            (TestWebKitAPI::TestSample::create):
+            (TestWebKitAPI::TestSample::TestSample):
+            (TestWebKitAPI::TEST_F):
+
+2017-02-09  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
+
</ins><span class="cx">         Merge r211663. rdar://problem/30343810
</span><span class="cx"> 
</span><span class="cx">     2017-02-03  Jeremy Jones  &lt;jeremyj@apple.com&gt;
</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 = &quot;video-with-audio.mp4&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CDC8E48B1BC5C96200594FEC /* video-without-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = &quot;video-without-audio.html&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CDC8E48C1BC5C96200594FEC /* video-without-audio.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = &quot;video-without-audio.mp4&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                CDCFA7A91E45122F00C2433D /* SampleMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SampleMap.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 CDE195B21CFE0ADE0053D256 /* FullscreenTopContentInset.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = FullscreenTopContentInset.html; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CDE195B31CFE0ADE0053D256 /* FullscreenTopContentInset.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FullscreenTopContentInset.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CE14F1A2181873B0001C2705 /* WillPerformClientRedirectToURLCrash.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = WillPerformClientRedirectToURLCrash.html; sourceTree = &quot;&lt;group&gt;&quot;; };
</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&lt;int64_t&gt;::max(), 2) + MediaTime(numeric_limits&lt;int64_t&gt;::max(), 2)).timeScale(), 1);
-    EXPECT_EQ((MediaTime(numeric_limits&lt;int64_t&gt;::min(), 2) - MediaTime(numeric_limits&lt;int64_t&gt;::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&lt;int64_t&gt;::max(), 2) + MediaTime(numeric_limits&lt;int64_t&gt;::max(), 2)).timeScale(), 1U);
+    EXPECT_EQ((MediaTime(numeric_limits&lt;int64_t&gt;::min(), 2) - MediaTime(numeric_limits&lt;int64_t&gt;::max(), 2)).timeScale(), 1U);
</ins><span class="cx">     EXPECT_EQ(MediaTime(numeric_limits&lt;int64_t&gt;::max(), 1) + MediaTime(numeric_limits&lt;int64_t&gt;::max(), 1), MediaTime::positiveInfiniteTime());
</span><span class="cx">     EXPECT_EQ(MediaTime(numeric_limits&lt;int64_t&gt;::min(), 1) + MediaTime(numeric_limits&lt;int64_t&gt;::min(), 1), MediaTime::negativeInfiniteTime());
</span><span class="cx">     EXPECT_EQ(MediaTime(numeric_limits&lt;int64_t&gt;::min(), 1) - MediaTime(numeric_limits&lt;int64_t&gt;::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 &quot;config.h&quot;
+
+#if ENABLE(MEDIA_SOURCE)
+
+#include &quot;Test.h&quot;
+#include &lt;WebCore/MediaSample.h&gt;
+#include &lt;WebCore/SampleMap.h&gt;
+
+namespace WTF {
+inline std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const MediaTime&amp; time)
+{
+    if (time.hasDoubleValue())
+        os &lt;&lt; &quot;{ &quot; &lt;&lt; time.toDouble() &lt;&lt; &quot; }&quot;;
+    else
+        os &lt;&lt; &quot;{ &quot; &lt;&lt; time.timeValue() &lt;&lt; &quot; / &quot; &lt;&lt; time.timeScale() &lt;&lt; &quot;, &quot; &lt;&lt; time.toDouble() &lt;&lt; &quot; }&quot;;
+    return os;
+}
+}
+
+using namespace WebCore;
+
+namespace TestWebKitAPI {
+
+class TestSample : public MediaSample {
+public:
+    static Ref&lt;TestSample&gt; create(const MediaTime&amp; presentationTime, const MediaTime&amp; decodeTime, const MediaTime&amp; 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&amp; trackID) final { m_trackID = trackID; }
+    size_t sizeInBytes() const final { return m_sizeInBytes; }
+    FloatSize presentationSize() const final { return m_presentationSize; }
+    void offsetTimestampsBy(const MediaTime&amp; offset) final { m_presentationTime += offset; m_decodeTime += offset; }
+    void setTimestamps(const MediaTime&amp; presentationTime, const MediaTime&amp; decodeTime) final {
+        m_presentationTime = presentationTime;
+        m_decodeTime = decodeTime;
+    };
+    bool isDivisable() const final { return false; }
+    std::pair&lt;RefPtr&lt;MediaSample&gt;, RefPtr&lt;MediaSample&gt;&gt; divide(const MediaTime&amp; presentationTime) final { return { }; }
+    Ref&lt;MediaSample&gt; createNonDisplayingCopy() const final {
+        return create(m_presentationTime, m_decodeTime, m_duration, static_cast&lt;SampleFlags&gt;(m_flags | IsNonDisplaying));
+    }
+    SampleFlags flags() const final { return m_flags; }
+    PlatformSample platformSample() final { return { PlatformSample::None, {nullptr}}; }
+    void dump(PrintStream&amp;) const final { }
+
+private:
+    TestSample(const MediaTime&amp; presentationTime, const MediaTime&amp; decodeTime, const MediaTime&amp; 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) -&gt; 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&amp; presentationMap = map.presentationOrder();
+    EXPECT_EQ(MediaTime(0, 1), presentationMap.findSampleWithPresentationTime(MediaTime(0, 1))-&gt;second-&gt;presentationTime());
+    EXPECT_EQ(MediaTime(19, 1), presentationMap.findSampleWithPresentationTime(MediaTime(19, 1))-&gt;second-&gt;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&amp; presentationMap = map.presentationOrder();
+    EXPECT_EQ(MediaTime(0, 1), presentationMap.findSampleContainingPresentationTime(MediaTime(0, 1))-&gt;second-&gt;presentationTime());
+    EXPECT_EQ(MediaTime(19, 1), presentationMap.findSampleContainingPresentationTime(MediaTime(19, 1))-&gt;second-&gt;presentationTime());
+    EXPECT_EQ(MediaTime(0, 1), presentationMap.findSampleContainingPresentationTime(MediaTime(1, 2))-&gt;second-&gt;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&amp; presentationMap = map.presentationOrder();
+    EXPECT_EQ(MediaTime(0, 1), presentationMap.findSampleStartingOnOrAfterPresentationTime(MediaTime(0, 1))-&gt;second-&gt;presentationTime());
+    EXPECT_EQ(MediaTime(19, 1), presentationMap.findSampleStartingOnOrAfterPresentationTime(MediaTime(19, 1))-&gt;second-&gt;presentationTime());
+    EXPECT_EQ(MediaTime(1, 1), presentationMap.findSampleStartingOnOrAfterPresentationTime(MediaTime(1, 2))-&gt;second-&gt;presentationTime());
+    EXPECT_EQ(MediaTime(0, 1), presentationMap.findSampleStartingOnOrAfterPresentationTime(MediaTime(-1, 1))-&gt;second-&gt;presentationTime());
+    EXPECT_EQ(MediaTime(11, 1), presentationMap.findSampleStartingOnOrAfterPresentationTime(MediaTime(10, 1))-&gt;second-&gt;presentationTime());
+    EXPECT_TRUE(presentationMap.end() == presentationMap.findSampleContainingPresentationTime(MediaTime(20, 1)));
+}
+
+TEST_F(SampleMapTest, findSamplesBetweenPresentationTimes)
+{
+    auto&amp; presentationMap = map.presentationOrder();
+    auto iterator_range = presentationMap.findSamplesBetweenPresentationTimes(MediaTime(0, 1), MediaTime(1, 1));
+    EXPECT_EQ(MediaTime(0, 1), iterator_range.first-&gt;second-&gt;presentationTime());
+    EXPECT_EQ(MediaTime(1, 1), iterator_range.second-&gt;second-&gt;presentationTime());
+
+    iterator_range = presentationMap.findSamplesBetweenPresentationTimes(MediaTime(1, 2), MediaTime(3, 2));
+    EXPECT_EQ(MediaTime(1, 1), iterator_range.first-&gt;second-&gt;presentationTime());
+    EXPECT_EQ(MediaTime(2, 1), iterator_range.second-&gt;second-&gt;presentationTime());
+
+    iterator_range = presentationMap.findSamplesBetweenPresentationTimes(MediaTime(9, 1), MediaTime(21, 1));
+    EXPECT_EQ(MediaTime(9, 1), iterator_range.first-&gt;second-&gt;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&amp; presentationMap = map.presentationOrder();
+    auto iterator_range = presentationMap.findSamplesWithinPresentationRange(MediaTime(0, 1), MediaTime(1, 1));
+    EXPECT_EQ(MediaTime(1, 1), iterator_range.first-&gt;second-&gt;presentationTime());
+    EXPECT_EQ(MediaTime(2, 1), iterator_range.second-&gt;second-&gt;presentationTime());
+
+    iterator_range = presentationMap.findSamplesWithinPresentationRange(MediaTime(1, 2), MediaTime(3, 2));
+    EXPECT_EQ(MediaTime(1, 1), iterator_range.first-&gt;second-&gt;presentationTime());
+    EXPECT_EQ(MediaTime(2, 1), iterator_range.second-&gt;second-&gt;presentationTime());
+
+    iterator_range = presentationMap.findSamplesWithinPresentationRange(MediaTime(9, 1), MediaTime(21, 1));
+    EXPECT_EQ(MediaTime(11, 1), iterator_range.first-&gt;second-&gt;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-&gt;second-&gt;presentationTime());
+    EXPECT_EQ(MediaTime(1, 1), iterator_range.second-&gt;second-&gt;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&amp; presentationMap = map.presentationOrder();
+    EXPECT_EQ(MediaTime(0, 1), presentationMap.reverseFindSampleBeforePresentationTime(MediaTime(0, 1))-&gt;second-&gt;presentationTime());
+    EXPECT_EQ(MediaTime(9, 1), presentationMap.reverseFindSampleBeforePresentationTime(MediaTime(10, 1))-&gt;second-&gt;presentationTime());
+    EXPECT_EQ(MediaTime(19, 1), presentationMap.reverseFindSampleBeforePresentationTime(MediaTime(19, 1))-&gt;second-&gt;presentationTime());
+    EXPECT_EQ(MediaTime(19, 1), presentationMap.reverseFindSampleBeforePresentationTime(MediaTime(21, 1))-&gt;second-&gt;presentationTime());
+    EXPECT_TRUE(presentationMap.rend() == presentationMap.reverseFindSampleBeforePresentationTime(MediaTime(-1, 1)));
+}
+
+}
+
+#endif // ENABLE(MEDIA_SOURCE)
</ins></span></pre>
</div>
</div>

</body>
</html>