<!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>[171316] trunk</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/171316">171316</a></dd>
<dt>Author</dt> <dd>jer.noble@apple.com</dd>
<dt>Date</dt> <dd>2014-07-21 13:47:03 -0700 (Mon, 21 Jul 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>[MSE] YouTube video decode error when variant-switching
https://bugs.webkit.org/show_bug.cgi?id=135128

Reviewed by Brent Fulgham.

Source/WebCore:
Test: media/media-source/media-source-overlapping-decodetime.html

When variant-switching, the situation can arise where an existing sample with a presentation
timestamp of N and a decode timestamp of M, and a new sample with a presentation timestamp &gt; N
and the same decode timestamp of M, will keep the new sample from being added to the SampleMap.
This can result in a decode error when samples depending on that new, missing sample are enqueued.

The MSE spec is silent on the issue of overlapping decode timestamps. However, it guarantees that
presentation timestamps are non-overlapping. So instead of using just the decode timestamp as a key
for storing the samples in decode order, use both the decode timestamp and the presentation timestamp.
That ensures that samples with different presentation times but equal decode times are both inserted
into the decode queue, and in the correct order.

* Modules/mediasource/SampleMap.cpp:
(WebCore::SampleIsRandomAccess::operator()): Update the parameter type to match the new KeyType.
(WebCore::SampleMap::addSample): Pass both decodeTime and presentationTime as the key to decodeOrder.
(WebCore::SampleMap::removeSample): Ditto.
(WebCore::DecodeOrderSampleMap::findSampleWithDecodeKey): Renamed from findSampleWithDecodeTime.
(WebCore::DecodeOrderSampleMap::reverseFindSampleWithDecodeKey): renamed from reverseFindSampleWithDecodeTime.
(WebCore::DecodeOrderSampleMap::findSyncSamplePriorToPresentationTime): Use renamed version of above.
(WebCore::DecodeOrderSampleMap::findSyncSampleAfterPresentationTime): Ditto.
(WebCore::DecodeOrderSampleMap::findDependentSamples): Ditto.
(WebCore::DecodeOrderSampleMap::findSampleWithDecodeTime): Deleted.
(WebCore::DecodeOrderSampleMap::reverseFindSampleWithDecodeTime): Deleted.
* Modules/mediasource/SampleMap.h:
* Modules/mediasource/SourceBuffer.cpp:
(WebCore::SourceBuffer::removeCodedFrames): Ditto.
(WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample): Ditto.
(WebCore::SourceBuffer::reenqueueMediaForTime): Ditto.

LayoutTests:
* media/media-source/media-source-overlapping-decodetime-expected.txt: Added.
* media/media-source/media-source-overlapping-decodetime.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesmediasourceSampleMapcpp">trunk/Source/WebCore/Modules/mediasource/SampleMap.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediasourceSampleMaph">trunk/Source/WebCore/Modules/mediasource/SampleMap.h</a></li>
<li><a href="#trunkSourceWebCoreModulesmediasourceSourceBuffercpp">trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsmediamediasourcemediasourceoverlappingdecodetimeexpectedtxt">trunk/LayoutTests/media/media-source/media-source-overlapping-decodetime-expected.txt</a></li>
<li><a href="#trunkLayoutTestsmediamediasourcemediasourceoverlappingdecodetimehtml">trunk/LayoutTests/media/media-source/media-source-overlapping-decodetime.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (171315 => 171316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-07-21 19:26:15 UTC (rev 171315)
+++ trunk/LayoutTests/ChangeLog        2014-07-21 20:47:03 UTC (rev 171316)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2014-07-21  Jer Noble  &lt;jer.noble@apple.com&gt;
+
+        [MSE] YouTube video decode error when variant-switching
+        https://bugs.webkit.org/show_bug.cgi?id=135128
+
+        Reviewed by Brent Fulgham.
+
+        * media/media-source/media-source-overlapping-decodetime-expected.txt: Added.
+        * media/media-source/media-source-overlapping-decodetime.html: Added.
+
</ins><span class="cx"> 2014-07-21  Alexey Proskuryakov  &lt;ap@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         fast/canvas/canvas-putImageData-zero-alpha.html is flaky
</span></span></pre></div>
<a id="trunkLayoutTestsmediamediasourcemediasourceoverlappingdecodetimeexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/media/media-source/media-source-overlapping-decodetime-expected.txt (0 => 171316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/media-source/media-source-overlapping-decodetime-expected.txt                                (rev 0)
+++ trunk/LayoutTests/media/media-source/media-source-overlapping-decodetime-expected.txt        2014-07-21 20:47:03 UTC (rev 171316)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+
+RUN(video.src = URL.createObjectURL(source))
+EVENT(sourceopen)
+RUN(sourceBuffer = source.addSourceBuffer(&quot;video/mock; codecs=mock&quot;))
+RUN(sourceBuffer.appendBuffer(initSegment))
+EVENT(updateend)
+RUN(sourceBuffer.appendBuffer(samples))
+EVENT(updateend)
+RUN(sourceBuffer.appendBuffer(samples))
+EVENT(updateend)
+EXPECTED (bufferedSamples.length == '7') OK
+{PTS({0/1000, 0.000000}), DTS({0/1000, 0.000000}), duration({1000/1000, 1.000000}), flags(1), generation(0)}
+{PTS({1000/1000, 1.000000}), DTS({1000/1000, 1.000000}), duration({1000/1000, 1.000000}), flags(0), generation(0)}
+{PTS({2000/1000, 2.000000}), DTS({2000/1000, 2.000000}), duration({1000/1000, 1.000000}), flags(0), generation(0)}
+{PTS({3000/1000, 3.000000}), DTS({3000/1000, 3.000000}), duration({1000/1000, 1.000000}), flags(1), generation(0)}
+{PTS({4000/1000, 4.000000}), DTS({3000/1000, 3.000000}), duration({1000/1000, 1.000000}), flags(1), generation(1)}
+{PTS({5000/1000, 5.000000}), DTS({4000/1000, 4.000000}), duration({1000/1000, 1.000000}), flags(0), generation(1)}
+{PTS({6000/1000, 6.000000}), DTS({5000/1000, 5.000000}), duration({1000/1000, 1.000000}), flags(0), generation(1)}
+END OF TEST
+
</ins></span></pre></div>
<a id="trunkLayoutTestsmediamediasourcemediasourceoverlappingdecodetimehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/media/media-source/media-source-overlapping-decodetime.html (0 => 171316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/media-source/media-source-overlapping-decodetime.html                                (rev 0)
+++ trunk/LayoutTests/media/media-source/media-source-overlapping-decodetime.html        2014-07-21 20:47:03 UTC (rev 171316)
</span><span class="lines">@@ -0,0 +1,71 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+    &lt;title&gt;mock-media-source&lt;/title&gt;
+    &lt;script src=&quot;mock-media-source.js&quot;&gt;&lt;/script&gt;
+    &lt;script src=&quot;../video-test.js&quot;&gt;&lt;/script&gt;
+    &lt;script&gt;
+    var source;
+    var sourceBuffer;
+    var initSegment;
+    var samples;
+    var bufferedSamples;
+
+    if (window.internals)
+        internals.initializeMockMediaSource();
+
+    function runTest()
+    {
+        findMediaElement();
+
+        source = new MediaSource();
+        waitForEventOn(source, 'sourceopen', sourceOpen);
+        run('video.src = URL.createObjectURL(source)');
+    }
+
+    function sourceOpen()
+    {
+        run('sourceBuffer = source.addSourceBuffer(&quot;video/mock; codecs=mock&quot;)');
+        waitForEventOn(sourceBuffer, 'updateend', loadOrderedSamples, false, true);
+        initSegment = makeAInit(8, [makeATrack(1, 'mock', TRACK_KIND.VIDEO)]);
+        run('sourceBuffer.appendBuffer(initSegment)');
+    }
+
+    function loadOrderedSamples()
+    {
+       samples = concatenateSamples([
+            makeASample(0, 0, 1, 1, SAMPLE_FLAG.SYNC, 0),
+            makeASample(1, 1, 1, 1, SAMPLE_FLAG.NONE, 0),
+            makeASample(2, 2, 1, 1, SAMPLE_FLAG.NONE, 0),
+            makeASample(3, 3, 1, 1, SAMPLE_FLAG.SYNC, 0),
+            makeASample(4, 4, 1, 1, SAMPLE_FLAG.NONE, 0),
+            makeASample(5, 5, 1, 1, SAMPLE_FLAG.NONE, 0),
+        ]);
+        waitForEventOn(sourceBuffer, 'updateend', loadMoreOrderedSamples, false, true);
+        run('sourceBuffer.appendBuffer(samples)');
+    }
+
+    function loadMoreOrderedSamples()
+    {
+        samples = concatenateSamples([
+            makeASample(4, 3, 1, 1, SAMPLE_FLAG.SYNC, 1),
+            makeASample(5, 4, 1, 1, SAMPLE_FLAG.NONE, 1),
+            makeASample(6, 5, 1, 1, SAMPLE_FLAG.NONE, 1),
+        ]);
+        waitForEventOn(sourceBuffer, 'updateend', samplesAdded, false, true);
+        run('sourceBuffer.appendBuffer(samples)');
+    }
+
+     function samplesAdded()
+    {
+        bufferedSamples = internals.bufferedSamplesForTrackID(sourceBuffer, 1);
+        testExpected(&quot;bufferedSamples.length&quot;, 7);
+        bufferedSamples.forEach(consoleWrite);
+
+        endTest();
+    }
+    &lt;/script&gt;
+&lt;/head&gt;
+&lt;body onload=&quot;runTest()&quot;&gt;
+    &lt;video&gt;&lt;/video&gt;
+&lt;/body&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (171315 => 171316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-07-21 19:26:15 UTC (rev 171315)
+++ trunk/Source/WebCore/ChangeLog        2014-07-21 20:47:03 UTC (rev 171316)
</span><span class="lines">@@ -1,3 +1,40 @@
</span><ins>+2014-07-21  Jer Noble  &lt;jer.noble@apple.com&gt;
+
+        [MSE] YouTube video decode error when variant-switching
+        https://bugs.webkit.org/show_bug.cgi?id=135128
+
+        Reviewed by Brent Fulgham.
+
+        Test: media/media-source/media-source-overlapping-decodetime.html
+
+        When variant-switching, the situation can arise where an existing sample with a presentation
+        timestamp of N and a decode timestamp of M, and a new sample with a presentation timestamp &gt; N
+        and the same decode timestamp of M, will keep the new sample from being added to the SampleMap.
+        This can result in a decode error when samples depending on that new, missing sample are enqueued.
+
+        The MSE spec is silent on the issue of overlapping decode timestamps. However, it guarantees that
+        presentation timestamps are non-overlapping. So instead of using just the decode timestamp as a key
+        for storing the samples in decode order, use both the decode timestamp and the presentation timestamp.
+        That ensures that samples with different presentation times but equal decode times are both inserted
+        into the decode queue, and in the correct order.
+
+        * Modules/mediasource/SampleMap.cpp:
+        (WebCore::SampleIsRandomAccess::operator()): Update the parameter type to match the new KeyType.
+        (WebCore::SampleMap::addSample): Pass both decodeTime and presentationTime as the key to decodeOrder.
+        (WebCore::SampleMap::removeSample): Ditto.
+        (WebCore::DecodeOrderSampleMap::findSampleWithDecodeKey): Renamed from findSampleWithDecodeTime.
+        (WebCore::DecodeOrderSampleMap::reverseFindSampleWithDecodeKey): renamed from reverseFindSampleWithDecodeTime.
+        (WebCore::DecodeOrderSampleMap::findSyncSamplePriorToPresentationTime): Use renamed version of above.
+        (WebCore::DecodeOrderSampleMap::findSyncSampleAfterPresentationTime): Ditto.
+        (WebCore::DecodeOrderSampleMap::findDependentSamples): Ditto.
+        (WebCore::DecodeOrderSampleMap::findSampleWithDecodeTime): Deleted.
+        (WebCore::DecodeOrderSampleMap::reverseFindSampleWithDecodeTime): Deleted.
+        * Modules/mediasource/SampleMap.h:
+        * Modules/mediasource/SourceBuffer.cpp:
+        (WebCore::SourceBuffer::removeCodedFrames): Ditto.
+        (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample): Ditto.
+        (WebCore::SourceBuffer::reenqueueMediaForTime): Ditto.
+
</ins><span class="cx"> 2014-07-21  Andy Estes  &lt;aestes@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS] Handle QuickLook ResourceLoaders in the web process
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasourceSampleMapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediasource/SampleMap.cpp (171315 => 171316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediasource/SampleMap.cpp        2014-07-21 19:26:15 UTC (rev 171315)
+++ trunk/Source/WebCore/Modules/mediasource/SampleMap.cpp        2014-07-21 20:47:03 UTC (rev 171316)
</span><span class="lines">@@ -66,7 +66,7 @@
</span><span class="cx"> 
</span><span class="cx"> class SampleIsRandomAccess {
</span><span class="cx"> public:
</span><del>-    bool operator()(std::pair&lt;MediaTime, RefPtr&lt;MediaSample&gt;&gt; value)
</del><ins>+    bool operator()(DecodeOrderSampleMap::MapType::value_type&amp; value)
</ins><span class="cx">     {
</span><span class="cx">         return value.second-&gt;flags() == MediaSample::IsSync;
</span><span class="cx">     }
</span><span class="lines">@@ -112,9 +112,12 @@
</span><span class="cx"> {
</span><span class="cx">     RefPtr&lt;MediaSample&gt; sample = prpSample;
</span><span class="cx">     ASSERT(sample);
</span><ins>+
</ins><span class="cx">     presentationOrder().m_samples.insert(PresentationOrderSampleMap::MapType::value_type(sample-&gt;presentationTime(), sample));
</span><del>-    decodeOrder().m_samples.insert(DecodeOrderSampleMap::MapType::value_type(sample-&gt;decodeTime(), sample));
</del><span class="cx"> 
</span><ins>+    auto decodeKey = DecodeOrderSampleMap::KeyType(sample-&gt;decodeTime(), sample-&gt;presentationTime());
+    decodeOrder().m_samples.insert(DecodeOrderSampleMap::MapType::value_type(decodeKey, sample));
+
</ins><span class="cx">     m_totalSize += sample-&gt;sizeInBytes();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -122,8 +125,10 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(sample);
</span><span class="cx">     presentationOrder().m_samples.erase(sample-&gt;presentationTime());
</span><del>-    decodeOrder().m_samples.erase(sample-&gt;decodeTime());
</del><span class="cx"> 
</span><ins>+    auto decodeKey = DecodeOrderSampleMap::KeyType(sample-&gt;decodeTime(), sample-&gt;presentationTime());
+    decodeOrder().m_samples.erase(decodeKey);
+
</ins><span class="cx">     m_totalSize -= sample-&gt;sizeInBytes();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -148,9 +153,9 @@
</span><span class="cx">     return m_samples.lower_bound(time);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-DecodeOrderSampleMap::iterator DecodeOrderSampleMap::findSampleWithDecodeTime(const MediaTime&amp; time)
</del><ins>+DecodeOrderSampleMap::iterator DecodeOrderSampleMap::findSampleWithDecodeKey(const KeyType&amp; key)
</ins><span class="cx"> {
</span><del>-    return m_samples.find(time);
</del><ins>+    return m_samples.find(key);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> PresentationOrderSampleMap::reverse_iterator PresentationOrderSampleMap::reverseFindSampleContainingPresentationTime(const MediaTime&amp; time)
</span><span class="lines">@@ -166,9 +171,9 @@
</span><span class="cx">     return std::lower_bound(rbegin(), rend(), time, SampleIsGreaterThanMediaTimeComparator&lt;MapType&gt;());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-DecodeOrderSampleMap::reverse_iterator DecodeOrderSampleMap::reverseFindSampleWithDecodeTime(const MediaTime&amp; time)
</del><ins>+DecodeOrderSampleMap::reverse_iterator DecodeOrderSampleMap::reverseFindSampleWithDecodeKey(const KeyType&amp; key)
</ins><span class="cx"> {
</span><del>-    DecodeOrderSampleMap::iterator found = findSampleWithDecodeTime(time);
</del><ins>+    DecodeOrderSampleMap::iterator found = findSampleWithDecodeKey(key);
</ins><span class="cx">     if (found == end())
</span><span class="cx">         return rend();
</span><span class="cx">     return --reverse_iterator(found);
</span><span class="lines">@@ -180,7 +185,8 @@
</span><span class="cx">     if (reverseCurrentSamplePTS == m_presentationOrder.rend())
</span><span class="cx">         return rend();
</span><span class="cx"> 
</span><del>-    reverse_iterator reverseCurrentSampleDTS = reverseFindSampleWithDecodeTime(reverseCurrentSamplePTS-&gt;second-&gt;decodeTime());
</del><ins>+    const RefPtr&lt;MediaSample&gt;&amp; sample = reverseCurrentSamplePTS-&gt;second;
+    reverse_iterator reverseCurrentSampleDTS = reverseFindSampleWithDecodeKey(KeyType(sample-&gt;decodeTime(), sample-&gt;presentationTime()));
</ins><span class="cx"> 
</span><span class="cx">     reverse_iterator foundSample = findSyncSamplePriorToDecodeIterator(reverseCurrentSampleDTS);
</span><span class="cx">     if (foundSample == rend())
</span><span class="lines">@@ -201,7 +207,8 @@
</span><span class="cx">     if (currentSamplePTS == m_presentationOrder.end())
</span><span class="cx">         return end();
</span><span class="cx"> 
</span><del>-    iterator currentSampleDTS = findSampleWithDecodeTime(currentSamplePTS-&gt;second-&gt;decodeTime());
</del><ins>+    const RefPtr&lt;MediaSample&gt;&amp; sample = currentSamplePTS-&gt;second;
+    iterator currentSampleDTS = findSampleWithDecodeKey(KeyType(sample-&gt;decodeTime(), sample-&gt;presentationTime()));
</ins><span class="cx">     
</span><span class="cx">     MediaTime upperBound = time + threshold;
</span><span class="cx">     iterator foundSample = std::find_if(currentSampleDTS, end(), SampleIsRandomAccess());
</span><span class="lines">@@ -234,7 +241,7 @@
</span><span class="cx"> DecodeOrderSampleMap::reverse_iterator_range DecodeOrderSampleMap::findDependentSamples(MediaSample* sample)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(sample);
</span><del>-    reverse_iterator currentDecodeIter = reverseFindSampleWithDecodeTime(sample-&gt;decodeTime());
</del><ins>+    reverse_iterator currentDecodeIter = reverseFindSampleWithDecodeKey(KeyType(sample-&gt;decodeTime(), sample-&gt;presentationTime()));
</ins><span class="cx">     reverse_iterator nextSyncSample = findSyncSamplePriorToDecodeIterator(currentDecodeIter);
</span><span class="cx">     return reverse_iterator_range(currentDecodeIter, nextSyncSample);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasourceSampleMaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediasource/SampleMap.h (171315 => 171316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediasource/SampleMap.h        2014-07-21 19:26:15 UTC (rev 171315)
+++ trunk/Source/WebCore/Modules/mediasource/SampleMap.h        2014-07-21 20:47:03 UTC (rev 171316)
</span><span class="lines">@@ -65,7 +65,8 @@
</span><span class="cx"> class DecodeOrderSampleMap {
</span><span class="cx">     friend class SampleMap;
</span><span class="cx"> public:
</span><del>-    typedef std::map&lt;MediaTime, RefPtr&lt;MediaSample&gt;&gt; MapType;
</del><ins>+    typedef std::pair&lt;MediaTime, MediaTime&gt; KeyType;
+    typedef std::map&lt;KeyType, RefPtr&lt;MediaSample&gt;&gt; MapType;
</ins><span class="cx">     typedef MapType::iterator iterator;
</span><span class="cx">     typedef MapType::reverse_iterator reverse_iterator;
</span><span class="cx">     typedef std::pair&lt;reverse_iterator, reverse_iterator&gt; reverse_iterator_range;
</span><span class="lines">@@ -75,8 +76,8 @@
</span><span class="cx">     reverse_iterator rbegin() { return m_samples.rbegin(); }
</span><span class="cx">     reverse_iterator rend() { return m_samples.rend(); }
</span><span class="cx"> 
</span><del>-    iterator findSampleWithDecodeTime(const MediaTime&amp;);
-    reverse_iterator reverseFindSampleWithDecodeTime(const MediaTime&amp;);
</del><ins>+    iterator findSampleWithDecodeKey(const KeyType&amp;);
+    reverse_iterator reverseFindSampleWithDecodeKey(const KeyType&amp;);
</ins><span class="cx">     reverse_iterator findSyncSamplePriorToPresentationTime(const MediaTime&amp;, const MediaTime&amp; threshold = MediaTime::positiveInfiniteTime());
</span><span class="cx">     reverse_iterator findSyncSamplePriorToDecodeIterator(reverse_iterator);
</span><span class="cx">     iterator findSyncSampleAfterPresentationTime(const MediaTime&amp;, const MediaTime&amp; threshold = MediaTime::positiveInfiniteTime());
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasourceSourceBuffercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp (171315 => 171316)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp        2014-07-21 19:26:15 UTC (rev 171315)
+++ trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp        2014-07-21 20:47:03 UTC (rev 171316)
</span><span class="lines">@@ -562,7 +562,8 @@
</span><span class="cx">         // and the next sync sample frame are removed. But we must start from the first sample in decode order, not
</span><span class="cx">         // presentation order.
</span><span class="cx">         PresentationOrderSampleMap::iterator minDecodeTimeIter = std::min_element(removePresentationStart, removePresentationEnd, decodeTimeComparator);
</span><del>-        DecodeOrderSampleMap::iterator removeDecodeStart = trackBuffer.samples.decodeOrder().findSampleWithDecodeTime(minDecodeTimeIter-&gt;second-&gt;decodeTime());
</del><ins>+        DecodeOrderSampleMap::KeyType decodeKey(minDecodeTimeIter-&gt;second-&gt;decodeTime(), minDecodeTimeIter-&gt;second-&gt;presentationTime());
+        DecodeOrderSampleMap::iterator removeDecodeStart = trackBuffer.samples.decodeOrder().findSampleWithDecodeKey(decodeKey);
</ins><span class="cx"> 
</span><span class="cx">         DecodeOrderSampleMap::MapType erasedSamples(removeDecodeStart, removeDecodeEnd);
</span><span class="cx"> 
</span><span class="lines">@@ -1157,8 +1158,8 @@
</span><span class="cx"> 
</span><span class="cx">             // Otherwise: Remove all coded frames between the coded frames removed in the previous step
</span><span class="cx">             // and the next random access point after those removed frames.
</span><del>-            auto firstDecodeIter = trackBuffer.samples.decodeOrder().findSampleWithDecodeTime(erasedSamples.decodeOrder().begin()-&gt;first);
-            auto lastDecodeIter = trackBuffer.samples.decodeOrder().findSampleWithDecodeTime(erasedSamples.decodeOrder().rbegin()-&gt;first);
</del><ins>+            auto firstDecodeIter = trackBuffer.samples.decodeOrder().findSampleWithDecodeKey(erasedSamples.decodeOrder().begin()-&gt;first);
+            auto lastDecodeIter = trackBuffer.samples.decodeOrder().findSampleWithDecodeKey(erasedSamples.decodeOrder().rbegin()-&gt;first);
</ins><span class="cx">             auto nextSyncIter = trackBuffer.samples.decodeOrder().findSyncSampleAfterDecodeIterator(lastDecodeIter);
</span><span class="cx">             dependentSamples.insert(firstDecodeIter, nextSyncIter);
</span><span class="cx"> 
</span><span class="lines">@@ -1186,8 +1187,10 @@
</span><span class="cx">         // Otherwise:
</span><span class="cx">         // Add the coded frame with the presentation timestamp, decode timestamp, and frame duration to the track buffer.
</span><span class="cx">         trackBuffer.samples.addSample(sample);
</span><del>-        trackBuffer.decodeQueue.insert(DecodeOrderSampleMap::MapType::value_type(decodeTimestamp, sample));
</del><span class="cx"> 
</span><ins>+        DecodeOrderSampleMap::KeyType decodeKey(decodeTimestamp, presentationTimestamp);
+        trackBuffer.decodeQueue.insert(DecodeOrderSampleMap::MapType::value_type(decodeKey, sample));
+
</ins><span class="cx">         // 1.18 Set last decode timestamp for track buffer to decode timestamp.
</span><span class="cx">         trackBuffer.lastDecodeTimestamp = decodeTimestamp;
</span><span class="cx"> 
</span><span class="lines">@@ -1380,8 +1383,8 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Seach backward for the previous sync sample.
</span><del>-    MediaTime currentSampleDecodeTime = currentSamplePTSIterator-&gt;second-&gt;decodeTime();
-    auto currentSampleDTSIterator = trackBuffer.samples.decodeOrder().findSampleWithDecodeTime(currentSampleDecodeTime);
</del><ins>+    DecodeOrderSampleMap::KeyType decodeKey(currentSamplePTSIterator-&gt;second-&gt;decodeTime(), currentSamplePTSIterator-&gt;second-&gt;presentationTime());
+    auto currentSampleDTSIterator = trackBuffer.samples.decodeOrder().findSampleWithDecodeKey(decodeKey);
</ins><span class="cx">     ASSERT(currentSampleDTSIterator != trackBuffer.samples.decodeOrder().end());
</span><span class="cx"> 
</span><span class="cx">     auto reverseCurrentSampleIter = --DecodeOrderSampleMap::reverse_iterator(currentSampleDTSIterator);
</span></span></pre>
</div>
</div>

</body>
</html>