<!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>[179725] 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/179725">179725</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2015-02-05 16:57:41 -0800 (Thu, 05 Feb 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>[MSE] Implement Append Error algorithm.
https://bugs.webkit.org/show_bug.cgi?id=139439

Patch by Bartlomiej Gajda &lt;b.gajda@samsung.com&gt; on 2015-02-05
Reviewed by Jer Noble.

If Source Buffer has not received first init segment, then it shall call endOfStream after receiving
Media Segment, as per Media Source spec. (from 17 July 2014) in paragraph 3.5.1 point 6.1.
Source/WebCore:

Based this change on Editor's Draft 12 December 2014, as it clarifies order of events.

Test: media/media-source/media-source-append-media-segment-without-init.html

* Modules/mediasource/MediaSource.cpp:
(WebCore::MediaSource::streamEndedWithError):
* Modules/mediasource/MediaSource.h:
* Modules/mediasource/SourceBuffer.cpp:
(WebCore::SourceBuffer::sourceBufferPrivateAppendComplete):
(WebCore::SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment):
(WebCore::SourceBuffer::validateInitializationSegment):
(WebCore::SourceBuffer::appendError):
* Modules/mediasource/SourceBuffer.h:

LayoutTests:

Added test which after creating SourceBuffer sends media sample, without any init segments.

* media/media-source/media-source-append-media-segment-without-init-expected.txt: Added.
* media/media-source/media-source-append-media-segment-without-init.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="#trunkSourceWebCoreModulesmediasourceSourceBuffercpp">trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediasourceSourceBufferh">trunk/Source/WebCore/Modules/mediasource/SourceBuffer.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsmediamediasourcemediasourceappendmediasegmentwithoutinitexpectedtxt">trunk/LayoutTests/media/media-source/media-source-append-media-segment-without-init-expected.txt</a></li>
<li><a href="#trunkLayoutTestsmediamediasourcemediasourceappendmediasegmentwithoutinithtml">trunk/LayoutTests/media/media-source/media-source-append-media-segment-without-init.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (179724 => 179725)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-02-06 00:53:37 UTC (rev 179724)
+++ trunk/LayoutTests/ChangeLog        2015-02-06 00:57:41 UTC (rev 179725)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2015-02-05  Bartlomiej Gajda  &lt;b.gajda@samsung.com&gt;
+
+        [MSE] Implement Append Error algorithm.
+        https://bugs.webkit.org/show_bug.cgi?id=139439
+
+        Reviewed by Jer Noble.
+
+        If Source Buffer has not received first init segment, then it shall call endOfStream after receiving
+        Media Segment, as per Media Source spec. (from 17 July 2014) in paragraph 3.5.1 point 6.1.
+        Added test which after creating SourceBuffer sends media sample, without any init segments.
+
+        * media/media-source/media-source-append-media-segment-without-init-expected.txt: Added.
+        * media/media-source/media-source-append-media-segment-without-init.html: Added.
+
</ins><span class="cx"> 2015-02-05  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Mac] Unreviewed gardening.
</span></span></pre></div>
<a id="trunkLayoutTestsmediamediasourcemediasourceappendmediasegmentwithoutinitexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/media/media-source/media-source-append-media-segment-without-init-expected.txt (0 => 179725)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/media-source/media-source-append-media-segment-without-init-expected.txt                                (rev 0)
+++ trunk/LayoutTests/media/media-source/media-source-append-media-segment-without-init-expected.txt        2015-02-06 00:57:41 UTC (rev 179725)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+
+RUN(video.src = URL.createObjectURL(source))
+EVENT(sourceopen)
+RUN(sourceBuffer = source.addSourceBuffer(&quot;video/mock; codecs=mock&quot;))
+RUN(sourceBuffer.appendBuffer(samples))
+EVENT(error)
+END OF TEST
+
</ins></span></pre></div>
<a id="trunkLayoutTestsmediamediasourcemediasourceappendmediasegmentwithoutinithtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/media/media-source/media-source-append-media-segment-without-init.html (0 => 179725)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/media-source/media-source-append-media-segment-without-init.html                                (rev 0)
+++ trunk/LayoutTests/media/media-source/media-source-append-media-segment-without-init.html        2015-02-06 00:57:41 UTC (rev 179725)
</span><span class="lines">@@ -0,0 +1,48 @@
</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 wasError = false;
+
+    if (window.internals)
+        internals.initializeMockMediaSource();
+
+    function runTest() {
+        findMediaElement();
+
+        source = new MediaSource();
+        waitForEventOn(source, 'sourceopen', sourceOpen, false, true);
+        run('video.src = URL.createObjectURL(source)');
+    }
+
+    function sourceOpen() {
+        run('sourceBuffer = source.addSourceBuffer(&quot;video/mock; codecs=mock&quot;)');
+
+        // Note: In normal usage we should send this line, but this checks what happens if we don't.
+        // initSegment = makeAInit(0, [makeATrack(1, 'mock', TRACK_KIND.VIDEO)]);
+
+        samples = concatenateSamples([
+            makeASample(0, 0, 1, 1, SAMPLE_FLAG.SYNC),
+            makeASample(1, 1, 1, 1, SAMPLE_FLAG.NONE),
+        ]);
+
+        // Note: if code correctly handles sample without init, it will go through Segment Parser Loop
+        // if not, we will receive update event as part of Coded Frame Processing
+        waitForEventOn(sourceBuffer, 'error', null, true, true);
+        failTestIn(2000);
+
+        run('sourceBuffer.appendBuffer(samples)');
+    }
+
+    &lt;/script&gt;
+&lt;/head&gt;
+&lt;body onload=&quot;runTest()&quot;&gt;
+    &lt;video&gt;&lt;/video&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (179724 => 179725)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-02-06 00:53:37 UTC (rev 179724)
+++ trunk/Source/WebCore/ChangeLog        2015-02-06 00:57:41 UTC (rev 179725)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2015-02-05  Bartlomiej Gajda  &lt;b.gajda@samsung.com&gt;
+
+        [MSE] Implement Append Error algorithm.
+        https://bugs.webkit.org/show_bug.cgi?id=139439
+
+        Reviewed by Jer Noble.
+
+        If Source Buffer has not received first init segment, then it shall call endOfStream after receiving
+        Media Segment, as per Media Source spec. (from 17 July 2014) in paragraph 3.5.1 point 6.1.
+
+        Based this change on Editor's Draft 12 December 2014, as it clarifies order of events.
+
+        Test: media/media-source/media-source-append-media-segment-without-init.html
+
+        * Modules/mediasource/MediaSource.cpp:
+        (WebCore::MediaSource::streamEndedWithError):
+        * Modules/mediasource/MediaSource.h:
+        * Modules/mediasource/SourceBuffer.cpp:
+        (WebCore::SourceBuffer::sourceBufferPrivateAppendComplete):
+        (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment):
+        (WebCore::SourceBuffer::validateInitializationSegment):
+        (WebCore::SourceBuffer::appendError):
+        * Modules/mediasource/SourceBuffer.h:
+
</ins><span class="cx"> 2015-02-05  Maciej Stachowiak  &lt;mjs@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Crash due to failing to dirty a removed text node's line box
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasourceSourceBuffercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp (179724 => 179725)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp        2015-02-06 00:53:37 UTC (rev 179724)
+++ trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp        2015-02-06 00:57:41 UTC (rev 179725)
</span><span class="lines">@@ -616,10 +616,10 @@
</span><span class="cx">     // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#sourcebuffer-buffer-append
</span><span class="cx"> 
</span><span class="cx">     // 2. If the input buffer contains bytes that violate the SourceBuffer byte stream format specification,
</span><del>-    // then run the end of stream algorithm with the error parameter set to &quot;decode&quot; and abort this algorithm.
</del><ins>+    // then run the append error algorithm with the decode error parameter set to true and abort this algorithm.
</ins><span class="cx">     if (result == ParsingFailed) {
</span><span class="cx">         LOG(MediaSource, &quot;SourceBuffer::sourceBufferPrivateAppendComplete(%p) - result = ParsingFailed&quot;, this);
</span><del>-        m_source-&gt;streamEndedWithError(decodeError(), IgnorableExceptionCode());
</del><ins>+        appendError(true);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -997,8 +997,9 @@
</span><span class="cx"> 
</span><span class="cx">     LOG(MediaSource, &quot;SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment(%p)&quot;, this);
</span><span class="cx"> 
</span><del>-    // 3.5.7 Initialization Segment Received
-    // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#sourcebuffer-init-segment-received
</del><ins>+    // 3.5.8 Initialization Segment Received (ctd)
+    // https://rawgit.com/w3c/media-source/c3ad59c7a370d04430969ba73d18dc9bcde57a33/index.html#sourcebuffer-init-segment-received [Editor's Draft 09 January 2015]
+
</ins><span class="cx">     // 1. Update the duration attribute if it currently equals NaN:
</span><span class="cx">     if (m_source-&gt;duration().isInvalid()) {
</span><span class="cx">         // ↳ If the initialization segment contains a duration:
</span><span class="lines">@@ -1009,16 +1010,18 @@
</span><span class="cx">         m_source-&gt;setDurationInternal(newDuration);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // 2. If the initialization segment has no audio, video, or text tracks, then run the end of stream
-    // algorithm with the error parameter set to &quot;decode&quot; and abort these steps.
</del><ins>+    // 2. If the initialization segment has no audio, video, or text tracks, then run the append error algorithm
+    // with the decode error parameter set to true and abort these steps.
</ins><span class="cx">     if (!segment.audioTracks.size() &amp;&amp; !segment.videoTracks.size() &amp;&amp; !segment.textTracks.size())
</span><del>-        m_source-&gt;streamEndedWithError(decodeError(), IgnorableExceptionCode());
</del><ins>+        appendError(true);
</ins><span class="cx"> 
</span><del>-
</del><span class="cx">     // 3. If the first initialization segment flag is true, then run the following steps:
</span><span class="cx">     if (m_receivedFirstInitializationSegment) {
</span><ins>+
+        // 3.1. Verify the following properties. If any of the checks fail then run the append error algorithm
+        // with the decode error parameter set to true and abort these steps.
</ins><span class="cx">         if (!validateInitializationSegment(segment)) {
</span><del>-            m_source-&gt;streamEndedWithError(decodeError(), IgnorableExceptionCode());
</del><ins>+            appendError(true);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         // 3.2 Add the appropriate track descriptions from this initialization segment to each of the track buffers.
</span><span class="lines">@@ -1058,6 +1061,7 @@
</span><span class="cx">             downcast&lt;InbandTextTrack&gt;(*textTrack).setPrivate(textTrackInfo.track);
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        // 3.3 Set the need random access point flag on all track buffers to true.
</ins><span class="cx">         for (auto&amp; trackBuffer : m_trackBufferMap.values())
</span><span class="cx">             trackBuffer.needRandomAccessFlag = true;
</span><span class="cx">     }
</span><span class="lines">@@ -1068,13 +1072,14 @@
</span><span class="cx">     // 5. If the first initialization segment flag is false, then run the following steps:
</span><span class="cx">     if (!m_receivedFirstInitializationSegment) {
</span><span class="cx">         // 5.1 If the initialization segment contains tracks with codecs the user agent does not support,
</span><del>-        // then run the end of stream algorithm with the error parameter set to &quot;decode&quot; and abort these steps.
</del><ins>+        // then run the append error algorithm with the decode error parameter set to true and abort these steps.
</ins><span class="cx">         // NOTE: This check is the responsibility of the SourceBufferPrivate.
</span><span class="cx"> 
</span><span class="cx">         // 5.2 For each audio track in the initialization segment, run following steps:
</span><span class="cx">         for (auto&amp; audioTrackInfo : segment.audioTracks) {
</span><span class="cx">             AudioTrackPrivate* audioTrackPrivate = audioTrackInfo.track.get();
</span><span class="cx"> 
</span><ins>+            // FIXME: Implement steps 5.2.1-5.2.8.1 as per Editor's Draft 09 January 2015, and reorder this
</ins><span class="cx">             // 5.2.1 Let new audio track be a new AudioTrack object.
</span><span class="cx">             // 5.2.2 Generate a unique ID and assign it to the id property on new video track.
</span><span class="cx">             RefPtr&lt;AudioTrack&gt; newAudioTrack = AudioTrack::create(this, audioTrackPrivate);
</span><span class="lines">@@ -1115,6 +1120,7 @@
</span><span class="cx">         for (auto&amp; videoTrackInfo : segment.videoTracks) {
</span><span class="cx">             VideoTrackPrivate* videoTrackPrivate = videoTrackInfo.track.get();
</span><span class="cx"> 
</span><ins>+            // FIXME: Implement steps 5.3.1-5.3.8.1 as per Editor's Draft 09 January 2015, and reorder this
</ins><span class="cx">             // 5.3.1 Let new video track be a new VideoTrack object.
</span><span class="cx">             // 5.3.2 Generate a unique ID and assign it to the id property on new video track.
</span><span class="cx">             RefPtr&lt;VideoTrack&gt; newVideoTrack = VideoTrack::create(this, videoTrackPrivate);
</span><span class="lines">@@ -1155,6 +1161,7 @@
</span><span class="cx">         for (auto&amp; textTrackInfo : segment.textTracks) {
</span><span class="cx">             InbandTextTrackPrivate* textTrackPrivate = textTrackInfo.track.get();
</span><span class="cx"> 
</span><ins>+            // FIXME: Implement steps 5.4.1-5.4.8.1 as per Editor's Draft 09 January 2015, and reorder this
</ins><span class="cx">             // 5.4.1 Let new text track be a new TextTrack object with its properties populated with the
</span><span class="cx">             // appropriate information from the initialization segment.
</span><span class="cx">             RefPtr&lt;InbandTextTrack&gt; newTextTrack = InbandTextTrack::create(scriptExecutionContext(), this, textTrackPrivate);
</span><span class="lines">@@ -1189,6 +1196,7 @@
</span><span class="cx">         // 5.5 If active track flag equals true, then run the following steps:
</span><span class="cx">         if (activeTrackFlag) {
</span><span class="cx">             // 5.5.1 Add this SourceBuffer to activeSourceBuffers.
</span><ins>+            // 5.5.2 Queue a task to fire a simple event named addsourcebuffer at activeSourceBuffers
</ins><span class="cx">             setActive(true);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -1218,11 +1226,11 @@
</span><span class="cx"> 
</span><span class="cx"> bool SourceBuffer::validateInitializationSegment(const InitializationSegment&amp; segment)
</span><span class="cx"> {
</span><del>-    // 3.5.7 Initialization Segment Received (ctd)
-    // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#sourcebuffer-init-segment-received
</del><ins>+    // FIXME: ordering of all 3.5.X (X&gt;=7) functions needs to be updated to post-[24 July 2014 Editor's Draft] version
+    // 3.5.8 Initialization Segment Received (ctd)
+    // https://rawgit.com/w3c/media-source/c3ad59c7a370d04430969ba73d18dc9bcde57a33/index.html#sourcebuffer-init-segment-received [Editor's Draft 09 January 2015]
</ins><span class="cx"> 
</span><del>-    // 3.1. Verify the following properties. If any of the checks fail then run the end of stream
-    // algorithm with the error parameter set to &quot;decode&quot; and abort these steps.
</del><ins>+    // Note: those are checks from step 3.1
</ins><span class="cx">     //   * The number of audio, video, and text tracks match what was in the first initialization segment.
</span><span class="cx">     if (segment.audioTracks.size() != audioTracks()-&gt;length()
</span><span class="cx">         || segment.videoTracks.size() != videoTracks()-&gt;length()
</span><span class="lines">@@ -1289,11 +1297,45 @@
</span><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+void SourceBuffer::appendError(bool decodeErrorParam)
+{
+    // 3.5.3 Append Error Algorithm
+    // https://rawgit.com/w3c/media-source/c3ad59c7a370d04430969ba73d18dc9bcde57a33/index.html#sourcebuffer-append-error [Editor's Draft 09 January 2015]
+
+    ASSERT(m_updating);
+    // 1. Run the reset parser state algorithm.
+    resetParserState();
+
+    // 2. Set the updating attribute to false.
+    m_updating = false;
+
+    // 3. Queue a task to fire a simple event named error at this SourceBuffer object.
+    scheduleEvent(eventNames().errorEvent);
+
+    // 4. Queue a task to fire a simple event named updateend at this SourceBuffer object.
+    scheduleEvent(eventNames().updateendEvent);
+
+    // 5. If decode error is true, then run the end of stream algorithm with the error parameter set to &quot;decode&quot;.
+    if (decodeErrorParam)
+        m_source-&gt;streamEndedWithError(decodeError(), IgnorableExceptionCode());
+}
+
</ins><span class="cx"> void SourceBuffer::sourceBufferPrivateDidReceiveSample(SourceBufferPrivate*, PassRefPtr&lt;MediaSample&gt; prpSample)
</span><span class="cx"> {
</span><span class="cx">     if (isRemoved())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    // 3.5.1 Segment Parser Loop
+    // 6.1 If the first initialization segment received flag is false, then run the append error algorithm
+    //     with the decode error parameter set to true and abort this algorithm.
+    // Note: current design makes SourceBuffer somehow ignorant of append state - it's more a thing
+    //  of SourceBufferPrivate. That's why this check can't really be done in appendInternal.
+    //  unless we force some kind of design with state machine switching.
+    if (!m_receivedFirstInitializationSegment) {
+        appendError(true);
+        return;
+    }
+
</ins><span class="cx">     RefPtr&lt;MediaSample&gt; sample = prpSample;
</span><span class="cx"> 
</span><span class="cx">     // 3.5.8 Coded Frame Processing
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasourceSourceBufferh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediasource/SourceBuffer.h (179724 => 179725)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediasource/SourceBuffer.h        2015-02-06 00:53:37 UTC (rev 179724)
+++ trunk/Source/WebCore/Modules/mediasource/SourceBuffer.h        2015-02-06 00:57:41 UTC (rev 179725)
</span><span class="lines">@@ -92,6 +92,7 @@
</span><span class="cx">     void remove(double start, double end, ExceptionCode&amp;);
</span><span class="cx">     void remove(const MediaTime&amp;, const MediaTime&amp;, ExceptionCode&amp;);
</span><span class="cx"> 
</span><ins>+    void appendError(bool);
</ins><span class="cx">     void abortIfUpdating();
</span><span class="cx">     void removedFromMediaSource();
</span><span class="cx">     void seekToTime(const MediaTime&amp;);
</span></span></pre>
</div>
</div>

</body>
</html>