<!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>[286485] 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/286485">286485</a></dd>
<dt>Author</dt> <dd>aboya@igalia.com</dd>
<dt>Date</dt> <dd>2021-12-03 00:25:14 -0800 (Fri, 03 Dec 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>[MSE] Fix erase range to prevent accidental deletion in files with changing durations
https://bugs.webkit.org/show_bug.cgi?id=233528

Reviewed by Xabier Rodriguez-Calvar.

Source/WebCore:

In didReceiveSample(), eraseBeginTime was being set to
highestPresentationTimestamp minus a tolerance. The tolerance is not
needed since highestPresentationTimestamp is loaded from exact frame
timestamps, and can cause accidental frame erasure in situations where
there are frames with frames smaller than the tolerance, which is the
case for certain MP4 files.

Test: media/media-source/media-source-append-tiny-durations.html

* platform/graphics/SourceBufferPrivate.cpp:
(WebCore::SourceBufferPrivate::didReceiveSample):

LayoutTests:

* media/media-source/media-source-append-tiny-durations-expected.txt: Added.
* media/media-source/media-source-append-tiny-durations.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="#trunkSourceWebCoreplatformgraphicsSourceBufferPrivatecpp">trunk/Source/WebCore/platform/graphics/SourceBufferPrivate.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsmediamediasourcemediasourceappendtinydurationsexpectedtxt">trunk/LayoutTests/media/media-source/media-source-append-tiny-durations-expected.txt</a></li>
<li><a href="#trunkLayoutTestsmediamediasourcemediasourceappendtinydurationshtml">trunk/LayoutTests/media/media-source/media-source-append-tiny-durations.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (286484 => 286485)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2021-12-03 08:06:10 UTC (rev 286484)
+++ trunk/LayoutTests/ChangeLog 2021-12-03 08:25:14 UTC (rev 286485)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2021-12-03  Alicia Boya García  <aboya@igalia.com>
+
+        [MSE] Fix erase range to prevent accidental deletion in files with changing durations
+        https://bugs.webkit.org/show_bug.cgi?id=233528
+
+        Reviewed by Xabier Rodriguez-Calvar.
+
+        * media/media-source/media-source-append-tiny-durations-expected.txt: Added.
+        * media/media-source/media-source-append-tiny-durations.html: Added.
+
</ins><span class="cx"> 2021-12-02  Chris Dumez  <cdumez@apple.com>
</span><span class="cx"> 
</span><span class="cx">         html/semantics/forms/constraints/form-validation-validity-valid.html WPT test is failing
</span></span></pre></div>
<a id="trunkLayoutTestsmediamediasourcemediasourceappendtinydurationsexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/media/media-source/media-source-append-tiny-durations-expected.txt (0 => 286485)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/media-source/media-source-append-tiny-durations-expected.txt                             (rev 0)
+++ trunk/LayoutTests/media/media-source/media-source-append-tiny-durations-expected.txt        2021-12-03 08:25:14 UTC (rev 286485)
</span><span class="lines">@@ -0,0 +1,27 @@
</span><ins>+This tests that an append of non-overlapping samples of varying durations, some of them under a millisecond, don't trigger accidental erasure.
+This is done in some MP4 files, where decode durations are manipulated to code media containing B-frames while maintaining a start PTS = 0.
+
+RUN(video.src = URL.createObjectURL(source))
+EVENT(sourceopen)
+RUN(sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock"))
+RUN(sourceBuffer.appendBuffer(initSegment))
+EVENT(updateend)
+RUN(sourceBuffer.appendBuffer(makeSamples(1)))
+EVENT(updateend)
+EXPECTED (bufferedSamples.length == '5') OK
+{PTS({0/10000 = 0.000000}), DTS({0/10000 = 0.000000}), duration({1/10000 = 0.000100}), flags(1), generation(1)}
+{PTS({2000/10000 = 0.200000}), DTS({1/10000 = 0.000100}), duration({999/10000 = 0.099900}), flags(0), generation(1)}
+{PTS({1000/10000 = 0.100000}), DTS({1000/10000 = 0.100000}), duration({1/10000 = 0.000100}), flags(0), generation(1)}
+{PTS({4000/10000 = 0.400000}), DTS({1001/10000 = 0.100100}), duration({999/10000 = 0.099900}), flags(0), generation(1)}
+{PTS({3000/10000 = 0.300000}), DTS({2000/10000 = 0.200000}), duration({1000/10000 = 0.100000}), flags(0), generation(1)}
+Testing the behavior is consistent when re-appending.
+RUN(sourceBuffer.appendBuffer(makeSamples(2)))
+EVENT(updateend)
+EXPECTED (bufferedSamples.length == '5') OK
+{PTS({0/10000 = 0.000000}), DTS({0/10000 = 0.000000}), duration({1/10000 = 0.000100}), flags(1), generation(2)}
+{PTS({2000/10000 = 0.200000}), DTS({1/10000 = 0.000100}), duration({999/10000 = 0.099900}), flags(0), generation(2)}
+{PTS({1000/10000 = 0.100000}), DTS({1000/10000 = 0.100000}), duration({1/10000 = 0.000100}), flags(0), generation(2)}
+{PTS({4000/10000 = 0.400000}), DTS({1001/10000 = 0.100100}), duration({999/10000 = 0.099900}), flags(0), generation(2)}
+{PTS({3000/10000 = 0.300000}), DTS({2000/10000 = 0.200000}), duration({1000/10000 = 0.100000}), flags(0), generation(2)}
+END OF TEST
+
</ins></span></pre></div>
<a id="trunkLayoutTestsmediamediasourcemediasourceappendtinydurationshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/media/media-source/media-source-append-tiny-durations.html (0 => 286485)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/media-source/media-source-append-tiny-durations.html                             (rev 0)
+++ trunk/LayoutTests/media/media-source/media-source-append-tiny-durations.html        2021-12-03 08:25:14 UTC (rev 286485)
</span><span class="lines">@@ -0,0 +1,63 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+    <title>media-source-append-tiny-durations</title>
+    <script src="mock-media-source.js"></script>
+    <script src="../video-test.js"></script>
+    <script>
+    var source;
+    var sourceBuffer;
+    var initSegment;
+
+    if (window.internals)
+        internals.initializeMockMediaSource();
+
+    function makeSamples(generation) {
+        return concatenateSamples([
+            //           pts,  dts, dur,  scale
+            makeASample(   0,    0,    1, 10000, 1, SAMPLE_FLAG.SYNC, generation),
+            makeASample(2000,    1,  999, 10000, 1, SAMPLE_FLAG.NONE, generation),
+            makeASample(1000, 1000,    1, 10000, 1, SAMPLE_FLAG.NONE, generation),
+            makeASample(4000, 1001,  999, 10000, 1, SAMPLE_FLAG.NONE, generation),
+            makeASample(3000, 2000, 1000, 10000, 1, SAMPLE_FLAG.NONE, generation),
+        ]);
+    }
+
+    window.addEventListener('load', async event => {
+
+        findMediaElement();
+
+        source = new MediaSource();
+        run('video.src = URL.createObjectURL(source)');
+        await waitFor(source, 'sourceopen');
+
+        run('sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock")');
+        initSegment = makeAInit(4, [makeATrack(1, 'mock', TRACK_KIND.VIDEO)]);
+        run('sourceBuffer.appendBuffer(initSegment)');
+
+        await waitFor(sourceBuffer, 'updateend');
+
+        run('sourceBuffer.appendBuffer(makeSamples(1))');
+        await waitFor(sourceBuffer, 'updateend');
+        bufferedSamples = await internals.bufferedSamplesForTrackId(sourceBuffer, 1);
+        testExpected("bufferedSamples.length", 5);
+        bufferedSamples.forEach(consoleWrite);
+
+        consoleWrite("Testing the behavior is consistent when re-appending.")
+        run('sourceBuffer.appendBuffer(makeSamples(2))');
+        await waitFor(sourceBuffer, 'updateend');
+        bufferedSamples = await internals.bufferedSamplesForTrackId(sourceBuffer, 1);
+        testExpected("bufferedSamples.length", 5);
+        bufferedSamples.forEach(consoleWrite);
+
+        endTest();
+
+    }, {once: true});
+    </script>
+</head>
+<body>
+    <div>This tests that an append of non-overlapping samples of varying durations, some of them under a millisecond, don't trigger accidental erasure.
+    <br>This is done in some MP4 files, where decode durations are manipulated to code media containing B-frames while maintaining a start PTS = 0.</div>
+    <video></video>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (286484 => 286485)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2021-12-03 08:06:10 UTC (rev 286484)
+++ trunk/Source/WebCore/ChangeLog      2021-12-03 08:25:14 UTC (rev 286485)
</span><span class="lines">@@ -1,3 +1,22 @@
</span><ins>+2021-12-03  Alicia Boya García  <aboya@igalia.com>
+
+        [MSE] Fix erase range to prevent accidental deletion in files with changing durations
+        https://bugs.webkit.org/show_bug.cgi?id=233528
+
+        Reviewed by Xabier Rodriguez-Calvar.
+
+        In didReceiveSample(), eraseBeginTime was being set to
+        highestPresentationTimestamp minus a tolerance. The tolerance is not
+        needed since highestPresentationTimestamp is loaded from exact frame
+        timestamps, and can cause accidental frame erasure in situations where
+        there are frames with frames smaller than the tolerance, which is the
+        case for certain MP4 files.
+
+        Test: media/media-source/media-source-append-tiny-durations.html
+
+        * platform/graphics/SourceBufferPrivate.cpp:
+        (WebCore::SourceBufferPrivate::didReceiveSample):
+
</ins><span class="cx"> 2021-12-03  Kimmo Kinnunen  <kkinnunen@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Network process does not seem to initialize logging
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsSourceBufferPrivatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/SourceBufferPrivate.cpp (286484 => 286485)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/SourceBufferPrivate.cpp   2021-12-03 08:06:10 UTC (rev 286484)
+++ trunk/Source/WebCore/platform/graphics/SourceBufferPrivate.cpp      2021-12-03 08:25:14 UTC (rev 286485)
</span><span class="lines">@@ -1169,7 +1169,7 @@
</span><span class="cx">                     break;
</span><span class="cx"> 
</span><span class="cx">                 MediaTime highestBufferedTime = trackBuffer.buffered.maximumBufferedTime();
</span><del>-                MediaTime eraseBeginTime = trackBuffer.highestPresentationTimestamp - contiguousFrameTolerance;
</del><ins>+                MediaTime eraseBeginTime = trackBuffer.highestPresentationTimestamp;
</ins><span class="cx">                 MediaTime eraseEndTime = frameEndTimestamp - contiguousFrameTolerance;
</span><span class="cx"> 
</span><span class="cx">                 PresentationOrderSampleMap::iterator_range range;
</span></span></pre>
</div>
</div>

</body>
</html>