Refactored SourceBuffer.append() & added SourceBuffer.remove().
authorAaron Colwell <acolwell@google.com>
Thu, 18 Oct 2012 09:09:08 -0700
changeset 38 4d013fe2dbec
parent 37 6d127e69c9f8
child 39 e029f71aafca
Refactored SourceBuffer.append() & added SourceBuffer.remove().

Misc:
- Explicitly state that all trun boxes must start with a random access point in section 8.2.2.
- Changed sentences that started with "queue a task" to "Queue a task".
- Split SourceBuffer.append() algorithm into sub-algorithms to make it easier to address other open issues:
* Added "Segment Parser Loop" algorithm to clarify how appended bytes are collected and processed.
* Added "Initialization Segment Received" algorithm to hold all initialization segment processing.
* Added "Coded Frame Processing" algorithm to hold timestampOffset adjustments & readyState transitions.

https://www.w3.org/Bugs/Public/show_bug.cgi?id=18709
- Added SourceBuffer.remove().
media-source/media-source.html
media-source/media-source.xml
media-source/spec-html.xsl
--- a/media-source/media-source.html	Tue Oct 09 10:29:57 2012 -0700
+++ b/media-source/media-source.html	Thu Oct 18 09:09:08 2012 -0700
@@ -42,7 +42,7 @@
     <div class="head">
       <p><a href="http://www.w3.org/"><img src="http://www.w3.org/Icons/w3c_home" alt="W3C" width="72" height="48"></a></p>
       <h1>Media Source Extensions</h1>
-      <h2>W3C Editor's Draft 8 October 2012</h2>
+      <h2>W3C Editor's Draft 18 October 2012</h2>
       <dl>
 	<dt>Latest published version:</dt>
 	<dd>Not yet published</dd>
@@ -137,7 +137,14 @@
 	  <li><a href="#mediasource-algorithms">3.3. Algorithms</a></li>
 	</ul>
       </li>
-      <li><a href="#sourcebuffer">4. SourceBuffer Object</a></li>
+      <li>
+<a href="#sourcebuffer">4. SourceBuffer Object</a>
+        <ul>
+	  <li><a href="#sourcebuffer-methods">4.1. Methods and Attributes</a></li>
+	  <li><a href="#sourcebuffer-algorithms">4.2. Algorithms</a></li>
+	</ul>
+      </li>
+
       <li>
 <a href="#sourcebufferlist">5. SourceBufferList Object</a>
 	<ul>
@@ -233,6 +240,9 @@
    <h4 id="track-description">1.2.10. Track Description</h4>
    <p>A byte stream format specific structure that provides the <a href="#track-id">Track ID</a>, codec configuration, and other metadata for a single track. Each track description inside a single <a href="#init-segment">initialization segment</a> must have a unique <a href="#track-id">Track ID</a>.</p>
 
+   <h4 id="coded-frame">1.2.11. Coded Frame</h4>
+   <p>A unit of compressed media data that has a presentation timestamp and  decode timestamp. The presentation timestamp indicates when the frame should be rendered. The decode timestamp indicates when the frame needs to be decoded. If frames can be decoded out of order, then the decode timestamp must be present in the bytestream. If frames cannot be decoded out of order and a decode timestamp is not present in the bytestream, then the decode timestamp is equal to the presentation timestamp.</p>
+
 
     <h2 id="source-buffer-model">2. Source Buffer Model</h2>
     <p>The subsections below outline the buffering model for this proposal. It describes how to add and remove <a href="#source-buffer">source buffers</a> from the presentation and describes the various rules and behaviors associated with appending data to an individual <a href="#source-buffer">source buffer</a>. At the highest level, the web application simply creates <a href="#source-buffer">source buffers</a> and appends a sequence of <a href="#init-segment">initialization segments</a> and <a href="#media-segment">media segments</a> to update the buffer's state. The media element pulls media data out of the <a href="#source-buffer">source buffers</a>, plays it, and fires events just like it would if a normal URL was passed to the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#attr-media-src">src</a></code> attribute. The web application is expected to monitor media element events to determine when it needs to append more <a href="#media-segment">media segments</a>.</p>
@@ -424,7 +434,7 @@
       <li>If the <code><a href="#dom-readystate">readyState</a></code> attribute is not in the <code><a href="#dom-%22open%22">"open"</a></code> state then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
       <li>Change the <code><a href="#dom-readystate">readyState</a></code> attribute value to <code><a href="#dom-%22ended%22">"ended"</a></code>.</li>
       <li>
-<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
+<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">Queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
    <code><a href="#dom-evt-sourceended">sourceended</a></code> at the <code><a href="#dom-mediasource">MediaSource</a></code>.</li>
       <dl class="switch">
           <dt>If <var title="true">error</var> is not set, null, or an empty string</dt>
@@ -513,7 +523,7 @@
           <ol>
             <li>Set the <code><a href="#dom-readystate">readyState</a></code> attribute to <code><a href="#dom-%22open%22">"open"</a></code>.</li>
             <li>
-<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
+<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">Queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
    <code><a href="#dom-evt-sourceopen">sourceopen</a></code> at the <code><a href="#dom-mediasource">MediaSource</a></code>.</li>
             <li>Allow the <a href="http://dev.w3.org/html5/spec/media-elements.html#concept-media-load-resource">resource fetch algorithm</a> to progress based on data passed in via <code><a href="#dom-append">append()</a></code>.</li>
           </ol>
@@ -529,14 +539,14 @@
       <li>Set the <code><a href="#dom-duration">duration</a></code> attribute to NaN.</li>
       <li>Remove all the <code><a href="#dom-sourcebuffer">SourceBuffer</a></code> objects from <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code>.</li>
       <li>
-<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
+<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">Queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
    <code><a href="#dom-evt-removesourcebuffer">removesourcebuffer</a></code> at <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code>.</li>
       <li>Remove all the <code><a href="#dom-sourcebuffer">SourceBuffer</a></code> objects from <code><a href="#dom-sourcebuffers">sourceBuffers</a></code>.</li>
       <li>
-<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
+<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">Queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
    <code><a href="#dom-evt-removesourcebuffer">removesourcebuffer</a></code> at <code><a href="#dom-sourcebuffers">sourceBuffers</a></code>.</li>
       <li>
-<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
+<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">Queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
    <code><a href="#dom-evt-sourceclose">sourceclose</a></code> at the <code><a href="#dom-mediasource">MediaSource</a></code>.</li>
     </ol>
 
@@ -583,7 +593,7 @@
 	<ol>
 	  <li>Set the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute to <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_enough_data">HAVE_ENOUGH_DATA</a></code>.</li>
 	  <li>
-<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
+<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">Queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
    <code><a href="http://dev.w3.org/html5/spec/media-elements.html#event-media-canplaythrough">canplaythrough</a></code> at the media element.</li>
 	  <li>Playback may resume at this point if it was previously suspended by a transition to <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_current_data">HAVE_CURRENT_DATA</a></code>.</li>
 	  <li>Abort these steps.</li>
@@ -621,7 +631,7 @@
   	  <ol>
 	    <li>Remove the <code><a href="#dom-sourcebuffer">SourceBuffer</a></code> from <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code>.</li>
 	    <li>
-<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
+<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">Queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
    <code><a href="#dom-evt-removesourcebuffer">removesourcebuffer</a></code> at <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code>
 </li>
 	  </ol>
@@ -630,7 +640,7 @@
 	  <ol>
 	    <li>Add the <code><a href="#dom-sourcebuffer">SourceBuffer</a></code> to <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code>.</li>
 	    <li>
-<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
+<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">Queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
    <code><a href="#dom-evt-addsourcebuffer">addsourcebuffer</a></code> at <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code>
 </li>
 	  </ol>
@@ -643,7 +653,7 @@
 	  <li>Remove the <code><a href="#dom-sourcebuffer">SourceBuffer</a></code> associated with the audio track from <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code>
 </li>
 	  <li>
-<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
+<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">Queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
    <code><a href="#dom-evt-removesourcebuffer">removesourcebuffer</a></code> at <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code>
 </li>
 	</ol>
@@ -655,7 +665,7 @@
 	  <li>Add the <code><a href="#dom-sourcebuffer">SourceBuffer</a></code> associated with the audio track to <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code>
 </li>
 	  <li>
-<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
+<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">Queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
    <code><a href="#dom-evt-addsourcebuffer">addsourcebuffer</a></code> at <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code>
 </li>
 	</ol>
@@ -666,7 +676,7 @@
 	  <li>Remove the <code><a href="#dom-sourcebuffer">SourceBuffer</a></code> associated with the text track from <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code>
 </li>
 	  <li>
-<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
+<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">Queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
    <code><a href="#dom-evt-removesourcebuffer">removesourcebuffer</a></code> at <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code>
 </li>
 	</ol>
@@ -678,7 +688,7 @@
 	  <li>Add the <code><a href="#dom-sourcebuffer">SourceBuffer</a></code> associated with the text track to <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code>
 </li>
 	  <li>
-<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
+<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">Queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
    <code><a href="#dom-evt-addsourcebuffer">addsourcebuffer</a></code> at <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code>
 </li>
 	</ol>
@@ -697,7 +707,7 @@
     </ol>
 
    <h2 id="sourcebuffer">4. SourceBuffer Object</h2>
-    <pre class="idl">
+   <pre class="idl">
 interface <dfn id="dom-sourcebuffer">SourceBuffer</dfn> : EventTarget {
   // Returns the time ranges buffered.
   readonly attribute TimeRanges <a href="#dom-buffered">buffered</a>;
@@ -710,168 +720,259 @@
 
   // Abort the current segment append sequence.
   void <a href="#dom-abort">abort</a>();
+
+  // Remove media for a specific time range.
+  void <a href="#dom-remove">remove</a>(double start, double end);
 };
-    </pre>
+   </pre>
+   <h3 id="sourcebuffer-methods">4.1. Methods and Attributes</h3>
+
+   <p>The <dfn id="sourcebuffer-parent-media-source">parent media source</dfn> of a <code><a href="#dom-sourcebuffer">SourceBuffer</a></code> object is the <code><a href="#dom-mediasource">MediaSource</a></code> object that created it.</p>
+
    <p>The <dfn id="dom-buffered"><code>buffered</code></dfn> attribute indicates what <code><a href="http://dev.w3.org/html5/spec/media-elements.html#timeranges">TimeRanges</a></code> are buffered in the <code><a href="#dom-sourcebuffer">SourceBuffer</a></code>. When the attribute is read the following steps must occur:</p>
    <ol>
-     <li>If this object has been removed from the <code><a href="#dom-sourcebuffers">sourceBuffers</a></code> attribute of the <code><a href="#dom-mediasource">MediaSource</a></code> object that created it then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
+     <li>If this object has been removed from the <code><a href="#dom-sourcebuffers">sourceBuffers</a></code> attribute of the <a href="#sourcebuffer-parent-media-source">parent media source</a> then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
      <li>Return a new static <a href="http://dev.w3.org/html5/spec/media-elements.html#normalized-timeranges-object">normalized TimeRanges object</a> for the <a href="#media-segment">media segments</a> buffered.</li>
    </ol>
 
    <p>The <dfn id="dom-timestampoffset"><code>timestampOffset</code></dfn> attribute controls the offset applied to timestamps inside subsequent <a href="#media-segment">media segments</a> that are appended to this <code><a href="#dom-sourcebuffer">SourceBuffer</a></code>. The <code><a href="#dom-timestampoffset">timestampOffset</a></code> is initially set to 0 which indicates that no offset is being applied. On getting, the initial value or the last value that was successfully set is returned. On setting, run following steps:</p>
    <ol>
-     <li>If this object has been removed from the <code><a href="#dom-sourcebuffers">sourceBuffers</a></code> attribute of the <code><a href="#dom-mediasource">MediaSource</a></code> object that created it, then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
-     <li>If the <code><a href="#dom-readystate">readyState</a></code> attribute of the <code><a href="#dom-mediasource">MediaSource</a></code> object that created this object is not in the <code><a href="#dom-%22open%22">"open"</a></code> state, then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
+     <li>If this object has been removed from the <code><a href="#dom-sourcebuffers">sourceBuffers</a></code> attribute of the <a href="#sourcebuffer-parent-media-source">parent media source</a>, then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
+     <li>If the <code><a href="#dom-readystate">readyState</a></code> attribute of the <a href="#sourcebuffer-parent-media-source">parent media source</a> is not in the <code><a href="#dom-%22open%22">"open"</a></code> state, then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
      <li>If this object is waiting for the end of a <a href="#media-segment">media segment</a> to be appended, then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> and abort these steps.</li>
      <li>Update the attribute to the new value.</li>
    </ol>
 
-    <p>The <dfn id="dom-append"><code>append(data)</code></dfn> method must run the following steps:</p>
+   <p>The <dfn id="dom-append"><code>append(data)</code></dfn> method must run the following steps:</p>
+   <ol>
+     <li>If <var title="true">data</var> is null then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_access_err">INVALID_ACCESS_ERR</a></code> exception and abort these steps.</li>
+     <li>If this object has been removed from the <code><a href="#dom-sourcebuffers">sourceBuffers</a></code> attribute of the <a href="#sourcebuffer-parent-media-source">parent media source</a> then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
+     <li>If the <code><a href="#dom-readystate">readyState</a></code> attribute of the <a href="#sourcebuffer-parent-media-source">parent media source</a> is in the <code><a href="#dom-closed">"closed"</a></code> state then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
+     <li>
+       <p>If the <code><a href="#dom-readystate">readyState</a></code> attribute of the <a href="#sourcebuffer-parent-media-source">parent media source</a> is in the <code><a href="#dom-%22ended%22">"ended"</a></code> state then run the following steps:</p>
+       <ol>
+	 <li>Set the <code><a href="#dom-readystate">readyState</a></code> attribute of the <a href="#sourcebuffer-parent-media-source">parent media source</a> to <code><a href="#dom-%22open%22">"open"</a></code>
+</li>
+	 <li>
+<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">Queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
+   <code><a href="#dom-evt-sourceopen">sourceopen</a></code> at the <a href="#sourcebuffer-parent-media-source">parent media source</a> .</li>
+       </ol>
+     </li>
+     <li>If <var title="true">data</var>.byteLength is 0 abort these steps.</li>
+     <li>Add <var title="true">data</var> to the end of the <a href="#sourcebuffer-input-buffer">input buffer</a>
+</li>
+     <li>Run the <a href="#sourcebuffer-segment-parser-loop">segment parser loop</a>.</li>
+   </ol>
+
+    <p>The <dfn id="dom-abort"><code>abort()</code></dfn> method must run the following steps:</p>
     <ol>
-      <li>Let <var title="true">media source</var> be the <code><a href="#dom-mediasource">MediaSource</a></code> object that created this object.</li>
-      <li>If <var title="true">data</var> is null then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_access_err">INVALID_ACCESS_ERR</a></code> exception and abort these steps.</li>
-      <li>If this object has been removed from the <code><a href="#dom-sourcebuffers">sourceBuffers</a></code> attribute of <var title="true">media source</var> then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
-      <li>If the <code><a href="#dom-readystate">readyState</a></code> attribute of <var title="true">media source</var> is in the <code><a href="#dom-closed">"closed"</a></code> state then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
-      <li>If the <code><a href="#dom-readystate">readyState</a></code> attribute of <var title="true">media source</var> is in the <code><a href="#dom-%22ended%22">"ended"</a></code> state then run the following steps:
-      <ol>
-	<li>Set the <code><a href="#dom-readystate">readyState</a></code> attribute of <var title="true">media source</var> to <code><a href="#dom-%22open%22">"open"</a></code>
+      <li>If this object has been removed from the <code><a href="#dom-sourcebuffers">sourceBuffers</a></code> attribute of the <a href="#sourcebuffer-parent-media-source">parent media source</a> then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
+      <li>If the <code><a href="#dom-readystate">readyState</a></code> attribute of the <a href="#sourcebuffer-parent-media-source">parent media source</a> is not in the <code><a href="#dom-%22open%22">"open"</a></code> state then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
+      <li>The media element aborts parsing the current segment.</li>
+      <li>If the <a href="#sourcebuffer-append-state">append state</a> equals <a href="#sourcebuffer-parsing-media-segment">PARSING_MEDIA_SEGMENT</a> and the <a href="#sourcebuffer-input-buffer">input buffer</a> contains some complete <a href="#coded-frame">coded frames</a>, then run the <a href="#sourcebuffer-coded-frame-processing">coded frame processing algorithm</a> as if the media segment only contained these frames.</li>
+      <li>Remove all bytes from the <a href="#sourcebuffer-input-buffer">input buffer</a>.</li>
+      <li>Set <a href="#sourcebuffer-append-state">append state</a> to <a href="#sourcebuffer-waiting-for-segment">WAITING_FOR_SEGMENT</a>.</li>
+    </ol>
+
+    <p>The <dfn id="dom-remove"><code>remove(start, end)</code></dfn> method must run the following steps:</p>
+    <ol>
+      <li>If <var title="true">start</var> is negative or greater than <code><a href="#dom-duration">duration</a></code>, then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_access_err">INVALID_ACCESS_ERR</a></code> exception and abort these steps.</li>
+      <li>If <var title="true">end</var> is less than or equal to <var title="true">start</var>, then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_access_err">INVALID_ACCESS_ERR</a></code> exception and abort these steps.</li>
+      <li>If this object has been removed from the <code><a href="#dom-sourcebuffers">sourceBuffers</a></code> attribute of the <a href="#sourcebuffer-parent-media-source">parent media source</a> then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
+      <li>If the <code><a href="#dom-readystate">readyState</a></code> attribute of the <a href="#sourcebuffer-parent-media-source">parent media source</a> is not in the <code><a href="#dom-%22open%22">"open"</a></code> state then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
+      <li>
+<p>For each track in this source buffer, run the following steps:</p>
+        <ol>
+	  <li>
+	    <p>Let <var title="true">next random access point timestamp</var> be the timestamp of the next <a href="#random-access-point">random access point</a>, for this track, that is greater than or equal to <var title="true">end</var>.</p>
+	    <p class="note">Note: <var title="true">next random access point timestamp</var> can be different across tracks because the dependencies between <a href="#coded-frame">coded frames</a> within a track are usually different than the dependencies in another track.</p>
 </li>
-	<li>
-<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
-   <code><a href="#dom-evt-sourceopen">sourceopen</a></code> at <var title="true">media source</var> .</li>
-      </ol>
+	  <li>Remove all media data, for this track, that contain starting timestamps greater than or equal to <var title="true">start</var> and less than the <var title="true">next random access point timestamp</var>.</li>
+	</ol>
       </li>
-      <li>If <var title="true">data</var>.byteLength is 0 abort these steps.</li>
-      <li>If <var title="true">data</var> contains anything that violates the <a href="#byte-stream-formats">byte stream format specifications</a>, then call <code><a href="#dom-endofstream">endOfStream("decode")</a></code>, and abort these steps.</li>
-      <li>Add <var title="true">data</var> to the source buffer:
-	<dl class="switch">
-	  <dt>If <var title="true">data</var> is part of a <a href="#media-segment">media segment</a> and <code><a href="#dom-timestampoffset">timestampOffset</a></code> is not 0:</dt>
-	  <dd>
-	    <ol>
-	      <li>Find all timestamps inside <var title="true">data</var> and add <code><a href="#dom-timestampoffset">timestampOffset</a></code> to them.</li>
-	      <li>If any of the modified timestamps are earlier than the <a href="#presentation-start-time">presentation start time</a>, then call <code><a href="#dom-endofstream">endOfStream("decode")</a></code>, and abort these steps.</li>
-	      <li>Copy the contents of <var title="true">data</var>, with the modified timestamps, into the source buffer.</li>
-	    </ol>
-	  </dd>
-	  <dt>Otherwise</dt>
-	  <dd>Copy the contents of <var title="true">data</var> into the source buffer.</dd>
-	</dl>
+      
+    </ol>
+
+    <h3 id="sourcebuffer-algorithms">4.2. Algorithms</h3>
+
+    <h4 id="sourcebuffer-segment-parser-loop">4.2.1 Segment Parser Loop</h4>
+    <p>All SourceBuffer objects have an internal <dfn id="sourcebuffer-append-state">append state</dfn> variable that keeps track of the high-level segment parsing state. It is initially set to <a href="#sourcebuffer-waiting-for-segment">WAITING_FOR_SEGMENT</a> and can transition to the following states as data is appended.</p>
+    <table>
+      <thead>
+	<tr>
+          <th>Append state name</th>
+          <th>Description</th>
+        </tr>
+      </thead>
+      <tbody>
+        <tr>
+          <td><dfn id="sourcebuffer-waiting-for-segment">WAITING_FOR_SEGMENT</dfn></td>
+          <td>Waiting for the start of an <a href="#init-segment">initialization segment</a> or <a href="#media-segment">media segment</a> to be appended.</td>
+        </tr>
+        <tr>
+          <td><dfn id="sourcebuffer-parsing-init-segment">PARSING_INIT_SEGMENT</dfn></td>
+          <td>Currently parsing an <a href="#init-segment">initialization segment</a>.</td>
+        </tr>
+	<tr>
+	  <td><dfn id="sourcebuffer-parsing-media-segment">PARSING_MEDIA_SEGMENT</dfn></td>
+          <td>Currently parsing a <a href="#media-segment">media segment</a>.</td>
+        </tr>
+      </tbody>
+    </table>
+    
+    <p>The <dfn id="sourcebuffer-input-buffer">input buffer</dfn> is a byte buffer that is used to hold unparsed bytes across <code><a href="#dom-append">append()</a></code> calls. The buffer is empty when the SourceBuffer object is created.</p>
+
+    <p>While the <a href="#sourcebuffer-input-buffer">input buffer</a> is not empty, run the following steps in a loop:</p>
+    <ol>
+      <li>If the <a href="#sourcebuffer-input-buffer">input buffer</a> starts with bytes that violate the <a href="#byte-stream-formats">byte stream format specifications</a>, then call <code><a href="#dom-endofstream">endOfStream("decode")</a></code>, and abort this algorithm.</li>
+      <li>Remove any bytes that the <a href="#byte-stream-formats">byte stream format specifications</a> say should be ignored from the start of the <a href="#sourcebuffer-input-buffer">input buffer</a>.</li>
+      <li>
+	<p>If the <a href="#sourcebuffer-append-state">append state</a> equals <a href="#sourcebuffer-waiting-for-segment">WAITING_FOR_SEGMENT</a>, then run the following steps:</p>
+	<ol>
+	  <li>If the beginning of the <a href="#sourcebuffer-input-buffer">input buffer</a> indicates the start of an <a href="#init-segment">initialization segment</a>, set the <a href="#sourcebuffer-append-state">append state</a> to <a href="#sourcebuffer-parsing-init-segment">PARSING_INIT_SEGMENT</a>.</li>
+	  <li>If the beginning of the <a href="#sourcebuffer-input-buffer">input buffer</a> indicates the start of an <a href="#media-segment">media segment</a>, set <a href="#sourcebuffer-append-state">append state</a> to <a href="#sourcebuffer-parsing-media-segment">PARSING_MEDIA_SEGMENT</a>.</li>
+	  <li>Return  to the top of the loop.</li>
+	</ol>
       </li>
-      <li>Handle end of segment cases:</li>
+      <li>
+	<p>If the <a href="#sourcebuffer-append-state">append state</a> equals <a href="#sourcebuffer-parsing-init-segment">PARSING_INIT_SEGMENT</a>, then run the following steps:</p>
+	<ol>
+	  <li>If the <a href="#sourcebuffer-input-buffer">input buffer</a> does not contain a complete <a href="#init-segment">initialization segment</a> yet, then exit the loop.</li>
+	  <li>Run the <a href="#sourcebuffer-init-segment-received">initialization segment received algorithm</a>.</li>
+	  <li>Remove the <a href="#init-segment">initialization segment</a> bytes from the beginning of the <a href="#sourcebuffer-input-buffer">input buffer</a>.</li>
+	  <li>Set <a href="#sourcebuffer-append-state">append state</a> to <a href="#sourcebuffer-waiting-for-segment">WAITING_FOR_SEGMENT</a>.</li>
+	  <li>Return  to the top of the loop.</li>
+	</ol>
+      </li>
+      <li>
+	<p>If the <a href="#sourcebuffer-append-state">append state</a> equals <a href="#sourcebuffer-parsing-media-segment">PARSING_MEDIA_SEGMENT</a>, then run the following steps:</p>
+	<ol>
+	  <li>
+	    <p>If the <a href="#sourcebuffer-input-buffer">input buffer</a> does not contain a complete <a href="#media-segment">media segment</a> header yet, then exit the loop.</p>
+	    <p class="note">Note: Implementations may choose to implement this state as an incremental parser so that it is not necessary to have the entire media segment before running the <a href="#sourcebuffer-coded-frame-processing">coded frame processing algorithm</a>.</p>
+	  </li>
+	  <li>Run the <a href="#sourcebuffer-coded-frame-processing">coded frame processing algorithm</a>.</li>
+	  <li>Remove the <a href="#media-segment">media segment</a> bytes from the beginning of the <a href="#sourcebuffer-input-buffer">input buffer</a>.</li>
+	  <li>
+	    <p>Set <a href="#sourcebuffer-append-state">append state</a> to <a href="#sourcebuffer-waiting-for-segment">WAITING_FOR_SEGMENT</a>.</p>
+	    <p class="note">Note: Incremental parsers should only do this transition after the entire media segment has been received.</p>
+	  </li>
+	  <li>Return  to the top of the loop.</li>
+	</ol>
+      </li>
+    </ol>
+
+    <h4 id="sourcebuffer-init-segment-received">4.2.2 Initialization Segment Received</h4>
+    <p>The following steps are run when the <a href="#sourcebuffer-segment-parser-loop">segment parser loop</a> successfully parses a complete <a href="#init-segment">initialization segment</a>:</p>
+    <ol>
+      <li>Update the <code><a href="#dom-duration">duration</a></code> attribute if it currently equals NaN:</li>
       <dl class="switch">
-	<dt>If <var title="true">data</var> completes the first <a href="#init-segment">initialization segment</a> appended to the <a href="#source-buffer">source buffer</a> run the following steps:</dt>
+	<dt>If the initialization segment contains a duration:</dt>
+	<dd>Run the <a href="#duration-change-algorithm">duration change algorithm</a> with <var title="true">new duration</var> set to the duration in the initialization segment.</dd>
+	<dt>Otherwise:</dt>
+	<dd>Run the <a href="#duration-change-algorithm">duration change algorithm</a> with <var title="true">new duration</var> set to positive Infinity.</dd>
+      </dl>
+      <li>Handle state transitions:</li>
+      <dl class="switch">
+	<dt>If the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute is <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_nothing">HAVE_NOTHING</a></code>:</dt>
 	<dd>
 	  <ol>
-	    <li>Update <code><a href="#dom-duration">duration</a></code> attribute if it currently equals NaN:</li>
-	    <dl class="switch">
-	      <dt>If the initialization segment contains a duration:</dt>
-	      <dd>Run the <a href="#duration-change-algorithm">duration change algorithm</a> with <var title="true">new duration</var> set to the duration in the initialization segment.</dd>
-	      <dt>Otherwise:</dt>
-	      <dd>Run the <a href="#duration-change-algorithm">duration change algorithm</a> with <var title="true">new duration</var> set to positive Infinity.</dd>
-	    </dl>
-	    <li>Handle state transitions:</li>
-	    <dl class="switch">
-	      <dt>If the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute is <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_nothing">HAVE_NOTHING</a></code>:</dt>
-	      <dd>
-	       <ol>
-		 <li>Set the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute to <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_metadata">HAVE_METADATA</a></code>.</li>
-		 <li>
-<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
+	    <li>Set the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute to <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_metadata">HAVE_METADATA</a></code>.</li>
+	    <li>
+<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">Queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
     <code><a href="http://dev.w3.org/html5/spec/media-elements.html#event-media-loadedmetadata">loadedmetadata</a></code> at the media element.</li>
-	       </ol>
-	      </dd>
-	      <dt>If the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute is greater than <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_current_data">HAVE_CURRENT_DATA</a></code> and the <a href="#init-segment">initialization segment</a> contains the first video or first audio track in the presentation:</dt>
-	      <dd>
-		Set the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute to <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_metadata">HAVE_METADATA</a></code>.
-	      </dd>
-	      <dt>Otherwise:</dt>
-	      <dd>Continue</dd>
-	    </dl>
-	    <li>Update <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-audiotracks">audioTracks</a></code>
-</li>
-	    <dl class="switch">
-	      <dt>If <a href="#init-segment">initialization segment</a> contains the first audio track:</dt>
-	      <dd>
-		<ol>
-		  <li>Add an <code><a href="http://dev.w3.org/html5/spec/media-elements.html#audiotrack">AudioTrack</a></code> and mark it as enabled.</li>
-		  <li>Add this <code><a href="#dom-sourcebuffer">SourceBuffer</a></code> to <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code>.</li>
-		</ol>
-	      </dd>
-	      <dt>If <a href="#init-segment">initialization segment</a> contains audio tracks beyond those already in the presentation:</dt>
-	      <dd>Add a disabled <code><a href="http://dev.w3.org/html5/spec/media-elements.html#audiotrack">AudioTrack</a></code> for each audio track in the <a href="#init-segment">initialization segment</a>.</dd>
-	    </dl>
-	    <li>Update <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-videotracks">videoTracks</a></code>:</li>
-	    <dl class="switch">
-	      <dt>If <a href="#init-segment">initialization segment</a> contains the first video track:</dt>
-	      <dd>
-		<ol>
-		  <li>Add a <code><a href="http://dev.w3.org/html5/spec/media-elements.html#videotrack">VideoTrack</a></code> and mark it as selected.</li>
-		  <li>Add this <code><a href="#dom-sourcebuffer">SourceBuffer</a></code> to <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code>.</li>
-		</ol>
-	      </dd>
-	      <dt>If <a href="#init-segment">initialization segment</a> contains the video tracks beyond those already in the presentation:</dt>
-	      <dd>Add a disabled <code><a href="http://dev.w3.org/html5/spec/media-elements.html#videotrack">VideoTrack</a></code> for each video track in the <a href="#init-segment">initialization segment</a>.</dd>
-	    </dl>
-	    <li>Update <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-texttracks">textTracks</a></code>
-</li>
-	    <dl class="switch">
-	      <dd>
-		<ol>
-		  <li>Add a <code><a href="http://dev.w3.org/html5/spec/media-elements.html#texttrack">TextTrack</a></code> for each text track in the <a href="#init-segment">initialization segment</a>.</li>
-		  <li>If the text track <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-texttrack-mode">mode</a></code> is <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-texttrack-showing">"showing"</a></code> or <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-texttrack-hidden">"hidden"</a></code> then add this <code><a href="#dom-sourcebuffer">SourceBuffer</a></code> to <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code>.</li>
-		</ol>
-	      </dd>
-	    </dl>
 	  </ol>
 	</dd>
-	<dt>If the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute is <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_metadata">HAVE_METADATA</a></code> and <var title="true">data</var> causes all objects in <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code> to have media data for the current playback position.</dt>
+	<dt>If the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute is greater than <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_current_data">HAVE_CURRENT_DATA</a></code> and the <a href="#init-segment">initialization segment</a> contains the first video or first audio track in the presentation:</dt>
 	<dd>
+	  Set the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute to <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_metadata">HAVE_METADATA</a></code>.
+	</dd>
+	<dt>Otherwise:</dt>
+	<dd>Continue</dd>
+      </dl>
+      <li>Update <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-audiotracks">audioTracks</a></code>
+</li>
+      <dl class="switch">
+	<dt>If <a href="#init-segment">initialization segment</a> contains the first audio track:</dt>
+	<dd>
+	  <ol>
+	    <li>Add an <code><a href="http://dev.w3.org/html5/spec/media-elements.html#audiotrack">AudioTrack</a></code> and mark it as enabled.</li>
+	    <li>Add this <code><a href="#dom-sourcebuffer">SourceBuffer</a></code> to <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code>.</li>
+	  </ol>
+	</dd>
+	<dt>If <a href="#init-segment">initialization segment</a> contains audio tracks beyond those already in the presentation:</dt>
+	<dd>Add a disabled <code><a href="http://dev.w3.org/html5/spec/media-elements.html#audiotrack">AudioTrack</a></code> for each audio track in the <a href="#init-segment">initialization segment</a>.</dd>
+      </dl>
+      <li>Update <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-videotracks">videoTracks</a></code>:</li>
+      <dl class="switch">
+	<dt>If <a href="#init-segment">initialization segment</a> contains the first video track:</dt>
+	<dd>
+	  <ol>
+	    <li>Add a <code><a href="http://dev.w3.org/html5/spec/media-elements.html#videotrack">VideoTrack</a></code> and mark it as selected.</li>
+	    <li>Add this <code><a href="#dom-sourcebuffer">SourceBuffer</a></code> to <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code>.</li>
+	  </ol>
+	</dd>
+	<dt>If <a href="#init-segment">initialization segment</a> contains the video tracks beyond those already in the presentation:</dt>
+	<dd>Add a disabled <code><a href="http://dev.w3.org/html5/spec/media-elements.html#videotrack">VideoTrack</a></code> for each video track in the <a href="#init-segment">initialization segment</a>.</dd>
+      </dl>
+      <li>Update <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-texttracks">textTracks</a></code>
+</li>
+      <dl class="switch">
+	<dd>
+	  <ol>
+	    <li>Add a <code><a href="http://dev.w3.org/html5/spec/media-elements.html#texttrack">TextTrack</a></code> for each text track in the <a href="#init-segment">initialization segment</a>.</li>
+	    <li>If the text track <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-texttrack-mode">mode</a></code> is <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-texttrack-showing">"showing"</a></code> or <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-texttrack-hidden">"hidden"</a></code> then add this <code><a href="#dom-sourcebuffer">SourceBuffer</a></code> to <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code>.</li>
+	  </ol>
+	</dd>
+      </dl>
+    </ol>
+
+    <h4 id="sourcebuffer-coded-frame-processing">4.2.3 Coded Frame Processing</h4>
+    <p>When a complete <a href="#coded-frame">coded frame</a> has been parsed by the <a href="#sourcebuffer-segment-parser-loop">segment parser loop</a> then the following steps are run:</p>
+    <ol>
+      <li>
+	<p>For each <a href="#coded-frame">coded frame</a> in the <a href="#media-segment">media segment</a> run the following steps:</p>
+	<ol>
+	  <li>Let <var title="true">presentation timestamp</var> be a double precision floating point representation of the coded frame's presentation timestamp.</li>
+	  <li>Let <var title="true">decode timestamp</var> be a double precision floating point representation of the coded frame's decode timestamp.</li>
+	  <li>
+	    <p>If <code><a href="#dom-timestampoffset">timestampOffset</a></code> is not 0, then run the following steps:</p>
+	    <ol>
+	      <li>Add <code><a href="#dom-timestampoffset">timestampOffset</a></code> to the <var title="true">presentation timestamp</var>.</li>
+	      <li>Add <code><a href="#dom-timestampoffset">timestampOffset</a></code> to the <var title="true">decode timestamp</var>.</li>
+	      <li>If the <var title="true">presentation timestamp</var> or <var title="true">decode timestamp</var> is less than the <a href="#presentation-start-time">presentation start time</a>, then call <code><a href="#dom-endofstream">endOfStream("decode")</a></code>, and abort these steps.</li>
+	    </ol>
+	  </li>
+	  <li>Add the <a href="#coded-frame">coded frame</a> with the <var title="true">presentation timestamp</var> and <var title="true">decode timestamp</var>, to the source buffer.</li>
+	</ol>
+      </li>
+      <li>
+<p>If the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute is <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_metadata">HAVE_METADATA</a></code> and the new <a href="#coded-frame">coded frames</a> cause all objects in <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code> to have media data for the current playback position, then run the following steps:</p>
 	  <ol>
 	    <li>Set the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute to <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_current_data">HAVE_CURRENT_DATA</a></code>.</li>
 	    <li>If this is the first transition to <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_current_data">HAVE_CURRENT_DATA</a></code>, then <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
    <code><a href="http://dev.w3.org/html5/spec/media-elements.html#event-media-loadeddata">loadeddata</a></code> at the media element.</li>
 	  </ol>
-	</dd>
-	<dt>If the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute is <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_current_data">HAVE_CURRENT_DATA</a></code> and <var title="true">data</var> causes all objects in <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code> to have media data beyond the current playback position.</dt>
-	<dd>
-	  <ol>
-	    <li>Set the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute to <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_future_data">HAVE_FUTURE_DATA</a></code>.</li>
-	    <li>
-<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
+      </li>
+      <li>
+	<p>If the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute is <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_current_data">HAVE_CURRENT_DATA</a></code> and the new <a href="#coded-frame">coded frames</a> cause all objects in <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code> to have media data beyond the current playback position, then run the following steps:</p>
+	<ol>
+	  <li>Set the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute to <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_future_data">HAVE_FUTURE_DATA</a></code>.</li>
+	  <li>
+<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">Queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
    <code><a href="http://dev.w3.org/html5/spec/media-elements.html#event-media-canplay">canplay</a></code> at the media element.</li>
-	  </ol>
-	</dd>
-	<dt>If the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute is <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_future_data">HAVE_FUTURE_DATA</a></code> and <var title="true">data</var> causes all objects in <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code> to have enough data to start playback.</dt>
-	<dd>
-	  <ol>
-	    <li>Set the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute to <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_enough_data">HAVE_ENOUGH_DATA</a></code>.</li>
-	    <li>
-<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
+	</ol>
+      </li>
+      <li>
+	<p>If the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute is <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_future_data">HAVE_FUTURE_DATA</a></code> and the new <a href="#coded-frame">coded frames</a> cause all objects in <code><a href="#dom-activesourcebuffers">activeSourceBuffers</a></code> to have enough data to start playback, then run the following steps:</p>
+	<ol>
+	  <li>Set the <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute to <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-have_enough_data">HAVE_ENOUGH_DATA</a></code>.</li>
+	  <li>
+<a href="http://dev.w3.org/html5/spec/textFieldSelection.html#queue-a-task">Queue a task</a> to <a href="http://dev.w3.org/html5/spec/textFieldSelection.html#fire-a-simple-event">fire a simple event</a> named
    <code><a href="http://dev.w3.org/html5/spec/media-elements.html#event-media-canplaythrough">canplaythrough</a></code> at the media element.</li>
-	  </ol>
-	</dd>
-	<dt>If the <a href="#media-segment">media segment</a> contains data beyond the current <code><a href="#dom-duration">duration</a></code>
-</dt>
-	<dd>Run the <a href="#duration-change-algorithm">duration change algorithm</a> with <var title="true">new duration</var> set to the maximum of the current duration and the highest end timestamp reported by <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-buffered">HTMLMediaElement.buffered</a></code>.</dd>
-      </dl>
-    </ol>
-
-    <p>The <dfn id="dom-abort"><code>abort()</code></dfn> method must run the following steps:</p>
-    <ol>
-      <li>If this object has been removed from the <code><a href="#dom-sourcebuffers">sourceBuffers</a></code> attribute of the <code><a href="#dom-mediasource">MediaSource</a></code> object that created it then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
-      <li>If the <code><a href="#dom-readystate">readyState</a></code> attribute of the <code><a href="#dom-mediasource">MediaSource</a></code> object that created this object is not in the <code><a href="#dom-%22open%22">"open"</a></code> state then throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
-      <li>The media element aborts parsing the current segment.</li>
-      <dl class="switch">
-	<dt>If waiting for the start of a new segment</dt>
-	<dd>Continue</dd>
-	<dt>If the current segment is an <a href="#init-segment">initialization segment</a>
-</dt>
-	<dd>Flush any data associated with this partial segment.</dd>
-	<dt>If the current segment is a <a href="#media-segment">media segment</a>
-</dt>
-	<dd>The media element may keep any media data it finds valuable in the partial segment. For example if the abort happens in the middle of a 10 second <a href="#media-segment">media segment</a>, the media element may choose to keep the 5 seconds of media data it has already parsed in the source buffer. <code><a href="#dom-buffered">buffered</a></code> will reflect what data, if any, was kept.</dd>
-      </dl>
-      <li>The media element resets the segment parser so that it can accept a new <a href="#init-segment">initialization segment</a> or <a href="#media-segment">media segment</a>.</li>
+	</ol>
+      </li>
+      <li>If the <a href="#media-segment">media segment</a> contains data beyond the current <code><a href="#dom-duration">duration</a></code>, then run the <a href="#duration-change-algorithm">duration change algorithm</a> with <var title="true">new duration</var> set to the maximum of the current duration and the highest end timestamp reported by <code><a href="http://dev.w3.org/html5/spec/media-elements.html#dom-media-buffered">HTMLMediaElement.buffered</a></code>.</li>
     </ol>
 
     <h2 id="sourcebufferlist">5. SourceBufferList Object</h2>
@@ -1034,7 +1135,8 @@
 	<li>External data references must not be used.</li>
 	<li>If the Movie Fragment contains multiple tracks, the duration by which each track extends should be as close to equal as practical.</li>
 	<li>Each Track Fragment Box must contain a Track Fragment Decode Time Box (<strong>tfdt</strong>)</li>
-	<li>The Media Data Boxes must contain all the samples referenced by the Track Run Boxes (<strong>trun</strong>) of the Movie Fragment Box.</li>
+	<li>The first sample in each Track Fragment Run Box (<strong>trun</strong>) must indicate that the sample is a <a href="#random-access-point">random access point</a>.</li>
+	<li>The Media Data Boxes must contain all the samples referenced by the Track Fragment Run Boxes (<strong>trun</strong>) of the Movie Fragment Box.</li>
       </ol>
 
       <h4 id="iso-random-access-points">8.2.3. Random Access Points</h4>
@@ -1132,7 +1234,11 @@
       </thead>
       <tbody>
 	<tr>
-	  <td>8 October 2012</td>
+	  <td>18 October 2012</td>
+          <td>Refactored SourceBuffer.append() &amp; added SourceBuffer.remove().</td>
+        </tr>
+	<tr>
+	  <td><a href="http://dvcs.w3.org/hg/html-media/rev/6d127e69c9f8">8 October 2012</a></td>
           <td>
 	    <ul>
 	      <li>Defined what HTMLMediaElement.seekable and HTMLMediaElement.buffered should return.</li>
--- a/media-source/media-source.xml	Tue Oct 09 10:29:57 2012 -0700
+++ b/media-source/media-source.xml	Thu Oct 18 09:09:08 2012 -0700
@@ -41,7 +41,7 @@
     <div class="head">
       <p><a href="http://www.w3.org/"><img src="http://www.w3.org/Icons/w3c_home" alt="W3C" width="72" height="48" /></a></p>
       <h1>Media Source Extensions</h1>
-      <h2>W3C Editor's Draft 8 October 2012</h2>
+      <h2>W3C Editor's Draft 18 October 2012</h2>
       <dl>
 	<dt>Latest published version:</dt>
 	<dd>Not yet published</dd>
@@ -133,7 +133,13 @@
 	  <li><a href="#mediasource-algorithms">3.3. Algorithms</a></li>
 	</ul>
       </li>
-      <li><a href="#sourcebuffer">4. SourceBuffer Object</a></li>
+      <li><a href="#sourcebuffer">4. SourceBuffer Object</a>
+        <ul>
+	  <li><a href="#sourcebuffer-methods">4.1. Methods and Attributes</a></li>
+	  <li><a href="#sourcebuffer-algorithms">4.2. Algorithms</a></li>
+	</ul>
+      </li>
+
       <li><a href="#sourcebufferlist">5. SourceBufferList Object</a>
 	<ul>
 	  <li><a href="#sourcebufferlist-methods">5.1. Methods and Attributes</a></li>
@@ -227,6 +233,9 @@
    <h4 id="track-description">1.2.10. Track Description</h4>
    <p>A byte stream format specific structure that provides the <track-id/>, codec configuration, and other metadata for a single track. Each track description inside a single <init-segment/> must have a unique <track-id/>.</p>
 
+   <h4 id="coded-frame">1.2.11. Coded Frame</h4>
+   <p>A unit of compressed media data that has a presentation timestamp and  decode timestamp. The presentation timestamp indicates when the frame should be rendered. The decode timestamp indicates when the frame needs to be decoded. If frames can be decoded out of order, then the decode timestamp must be present in the bytestream. If frames cannot be decoded out of order and a decode timestamp is not present in the bytestream, then the decode timestamp is equal to the presentation timestamp.</p>
+
 
     <h2 id="source-buffer-model">2. Source Buffer Model</h2>
     <p>The subsections below outline the buffering model for this proposal. It describes how to add and remove <source-buffers/> from the presentation and describes the various rules and behaviors associated with appending data to an individual <source-buffer/>. At the highest level, the web application simply creates <source-buffers/> and appends a sequence of <init-segments/> and <media-segments/> to update the buffer's state. The media element pulls media data out of the <source-buffers/>, plays it, and fires events just like it would if a normal URL was passed to the <media-src/> attribute. The web application is expected to monitor media element events to determine when it needs to append more <media-segments/>.</p>
@@ -410,7 +419,7 @@
     <ol>
       <li>If the <readyState/> attribute is not in the <open/> state then throw an <invalid-state-err/> exception and abort these steps.</li>
       <li>Change the <readyState/> attribute value to <ended/>.</li>
-      <li><queue-a-task-to-fire-an-event-named/> <sourceended/> at the <MediaSource/>.</li>
+      <li><Queue-a-task-to-fire-an-event-named/> <sourceended/> at the <MediaSource/>.</li>
       <dl class="switch">
           <dt>If <var title="true">error</var> is not set, null, or an empty string</dt>
           <dd>
@@ -486,7 +495,7 @@
         <dd>
           <ol>
             <li>Set the <readyState/> attribute to <open/>.</li>
-            <li><queue-a-task-to-fire-an-event-named/> <sourceopen/> at the <MediaSource/>.</li>
+            <li><Queue-a-task-to-fire-an-event-named/> <sourceopen/> at the <MediaSource/>.</li>
             <li>Allow the <resource-fetch-algorithm/> to progress based on data passed in via <append/>.</li>
           </ol>
         </dd>
@@ -499,10 +508,10 @@
       <li>Set the <readyState/> attribute to <closed/>.</li>
       <li>Set the <duration/> attribute to NaN.</li>
       <li>Remove all the <SourceBuffer/> objects from <activeSourceBuffers/>.</li>
-      <li><queue-a-task-to-fire-an-event-named/> <removesourcebuffer/> at <activeSourceBuffers/>.</li>
+      <li><Queue-a-task-to-fire-an-event-named/> <removesourcebuffer/> at <activeSourceBuffers/>.</li>
       <li>Remove all the <SourceBuffer/> objects from <sourceBuffers/>.</li>
-      <li><queue-a-task-to-fire-an-event-named/> <removesourcebuffer/> at <sourceBuffers/>.</li>
-      <li><queue-a-task-to-fire-an-event-named/> <sourceclose/> at the <MediaSource/>.</li>
+      <li><Queue-a-task-to-fire-an-event-named/> <removesourcebuffer/> at <sourceBuffers/>.</li>
+      <li><Queue-a-task-to-fire-an-event-named/> <sourceclose/> at the <MediaSource/>.</li>
     </ol>
 
     <h4 id="mediasource-seeking">3.3.3 Seeking</h4>
@@ -541,7 +550,7 @@
       <dd>
 	<ol>
 	  <li>Set the <ready-state/> attribute to <have-enough-data/>.</li>
-	  <li><queue-a-task-to-fire-an-event-named/> <canplaythrough/> at the media element.</li>
+	  <li><Queue-a-task-to-fire-an-event-named/> <canplaythrough/> at the media element.</li>
 	  <li>Playback may resume at this point if it was previously suspended by a transition to <have-current-data/>.</li>
 	  <li>Abort these steps.</li>
 	</ol>
@@ -575,13 +584,13 @@
 	  <li>If the <SourceBuffer/> associated with the previously selected video track is not associated with any other enabled tracks, run the following steps:
   	  <ol>
 	    <li>Remove the <SourceBuffer/> from <activeSourceBuffers/>.</li>
-	    <li><queue-a-task-to-fire-an-event-named/> <removesourcebuffer/> at <activeSourceBuffers/></li>
+	    <li><Queue-a-task-to-fire-an-event-named/> <removesourcebuffer/> at <activeSourceBuffers/></li>
 	  </ol>
 	  </li>
 	  <li>If the <SourceBuffer/> associated with the newly selected video track is not already in <activeSourceBuffers/>, run the following steps:
 	  <ol>
 	    <li>Add the <SourceBuffer/> to <activeSourceBuffers/>.</li>
-	    <li><queue-a-task-to-fire-an-event-named/> <addsourcebuffer/> at <activeSourceBuffers/></li>
+	    <li><Queue-a-task-to-fire-an-event-named/> <addsourcebuffer/> at <activeSourceBuffers/></li>
 	  </ol>
 	  </li>
 	</ol>
@@ -590,28 +599,28 @@
       <dd>
 	<ol>
 	  <li>Remove the <SourceBuffer/> associated with the audio track from <activeSourceBuffers/></li>
-	  <li><queue-a-task-to-fire-an-event-named/> <removesourcebuffer/> at <activeSourceBuffers/></li>
+	  <li><Queue-a-task-to-fire-an-event-named/> <removesourcebuffer/> at <activeSourceBuffers/></li>
 	</ol>
       </dd>
       <dt>If an audio track becomes enabled and the <SourceBuffer/> associated with this track is not already in <activeSourceBuffers/></dt>
       <dd>
 	<ol>
 	  <li>Add the <SourceBuffer/> associated with the audio track to <activeSourceBuffers/></li>
-	  <li><queue-a-task-to-fire-an-event-named/> <addsourcebuffer/> at <activeSourceBuffers/></li>
+	  <li><Queue-a-task-to-fire-an-event-named/> <addsourcebuffer/> at <activeSourceBuffers/></li>
 	</ol>
       </dd>
       <dt>If a text track <videoref name="dom-texttrack-mode">mode</videoref> becomes <videoref name="dom-texttrack-disabled">&quot;disabled&quot;</videoref> and the <SourceBuffer/> associated with this track is not associated with any other enabled or selected track</dt>
       <dd>
 	<ol>
 	  <li>Remove the <SourceBuffer/> associated with the text track from <activeSourceBuffers/></li>
-	  <li><queue-a-task-to-fire-an-event-named/> <removesourcebuffer/> at <activeSourceBuffers/></li>
+	  <li><Queue-a-task-to-fire-an-event-named/> <removesourcebuffer/> at <activeSourceBuffers/></li>
 	</ol>
       </dd>
       <dt>If a text track <videoref name="dom-texttrack-mode">mode</videoref> becomes <videoref name="dom-texttrack-showing">&quot;showing&quot;</videoref> or <videoref name="dom-texttrack-hidden">&quot;hidden&quot;</videoref> and the <SourceBuffer/> associated with this track is not already in <activeSourceBuffers/></dt>
       <dd>
 	<ol>
 	  <li>Add the <SourceBuffer/> associated with the text track to <activeSourceBuffers/></li>
-	  <li><queue-a-task-to-fire-an-event-named/> <addsourcebuffer/> at <activeSourceBuffers/></li>
+	  <li><Queue-a-task-to-fire-an-event-named/> <addsourcebuffer/> at <activeSourceBuffers/></li>
 	</ol>
       </dd>
     </dl>
@@ -628,7 +637,7 @@
     </ol>
 
    <h2 id="sourcebuffer">4. SourceBuffer Object</h2>
-    <pre class="idl">
+   <pre class="idl">
 interface <dfn id="dom-sourcebuffer">SourceBuffer</dfn> : EventTarget {
   // Returns the time ranges buffered.
   readonly attribute TimeRanges <precoderef>buffered</precoderef>;
@@ -641,153 +650,243 @@
 
   // Abort the current segment append sequence.
   void <premethodref>abort</premethodref>();
+
+  // Remove media for a specific time range.
+  void <premethodref>remove</premethodref>(double start, double end);
 };
-    </pre>
+   </pre>
+   <h3 id="sourcebuffer-methods">4.1. Methods and Attributes</h3>
+
+   <p>The <dfn id="sourcebuffer-parent-media-source">parent media source</dfn> of a <SourceBuffer/> object is the <MediaSource/> object that created it.</p>
+
    <p>The <codedfn>buffered</codedfn> attribute indicates what <timeranges/> are buffered in the <SourceBuffer/>. When the attribute is read the following steps must occur:</p>
    <ol>
-     <li>If this object has been removed from the <sourceBuffers/> attribute of the <MediaSource/> object that created it then throw an <invalid-state-err/> exception and abort these steps.</li>
+     <li>If this object has been removed from the <sourceBuffers/> attribute of the <parent-media-source/> then throw an <invalid-state-err/> exception and abort these steps.</li>
      <li>Return a new static <normalized-timeranges-object/> for the <media-segments/> buffered.</li>
    </ol>
 
    <p>The <codedfn>timestampOffset</codedfn> attribute controls the offset applied to timestamps inside subsequent <media-segments/> that are appended to this <SourceBuffer/>. The <timestampOffset/> is initially set to 0 which indicates that no offset is being applied. On getting, the initial value or the last value that was successfully set is returned. On setting, run following steps:</p>
    <ol>
-     <li>If this object has been removed from the <sourceBuffers/> attribute of the <MediaSource/> object that created it, then throw an <invalid-state-err/> exception and abort these steps.</li>
-     <li>If the <readyState/> attribute of the <MediaSource/> object that created this object is not in the <open/> state, then throw an <invalid-state-err/> exception and abort these steps.</li>
+     <li>If this object has been removed from the <sourceBuffers/> attribute of the <parent-media-source/>, then throw an <invalid-state-err/> exception and abort these steps.</li>
+     <li>If the <readyState/> attribute of the <parent-media-source/> is not in the <open/> state, then throw an <invalid-state-err/> exception and abort these steps.</li>
      <li>If this object is waiting for the end of a <media-segment/> to be appended, then throw an <invalid-state-err/> and abort these steps.</li>
      <li>Update the attribute to the new value.</li>
    </ol>
 
-    <p>The <methoddfn name="append">append(<var title="true">data</var>)</methoddfn> method must run the following steps:</p>
+   <p>The <methoddfn name="append">append(<var title="true">data</var>)</methoddfn> method must run the following steps:</p>
+   <ol>
+     <li>If <var title="true">data</var> is null then throw an <invalid-access-err/> exception and abort these steps.</li>
+     <li>If this object has been removed from the <sourceBuffers/> attribute of the <parent-media-source/> then throw an <invalid-state-err/> exception and abort these steps.</li>
+     <li>If the <readyState/> attribute of the <parent-media-source/> is in the <closed/> state then throw an <invalid-state-err/> exception and abort these steps.</li>
+     <li>
+       <p>If the <readyState/> attribute of the <parent-media-source/> is in the <ended/> state then run the following steps:</p>
+       <ol>
+	 <li>Set the <readyState/> attribute of the <parent-media-source/> to <open/></li>
+	 <li><Queue-a-task-to-fire-an-event-named/> <sourceopen/> at the <parent-media-source/> .</li>
+       </ol>
+     </li>
+     <li>If <var title="true">data</var>.byteLength is 0 abort these steps.</li>
+     <li>Add <var title="true">data</var> to the end of the <input-buffer/></li>
+     <li>Run the <segment-parser-loop/>.</li>
+   </ol>
+
+    <p>The <methoddfn name="abort">abort()</methoddfn> method must run the following steps:</p>
     <ol>
-      <li>Let <var title="true">media source</var> be the <MediaSource/> object that created this object.</li>
-      <li>If <var title="true">data</var> is null then throw an <invalid-access-err/> exception and abort these steps.</li>
-      <li>If this object has been removed from the <sourceBuffers/> attribute of <var title="true">media source</var> then throw an <invalid-state-err/> exception and abort these steps.</li>
-      <li>If the <readyState/> attribute of <var title="true">media source</var> is in the <closed/> state then throw an <invalid-state-err/> exception and abort these steps.</li>
-      <li>If the <readyState/> attribute of <var title="true">media source</var> is in the <ended/> state then run the following steps:
-      <ol>
-	<li>Set the <readyState/> attribute of <var title="true">media source</var> to <open/></li>
-	<li><queue-a-task-to-fire-an-event-named/> <sourceopen/> at <var title="true">media source</var> .</li>
-      </ol>
+      <li>If this object has been removed from the <sourceBuffers/> attribute of the <parent-media-source/> then throw an <invalid-state-err/> exception and abort these steps.</li>
+      <li>If the <readyState/> attribute of the <parent-media-source/> is not in the <open/> state then throw an <invalid-state-err/> exception and abort these steps.</li>
+      <li>The media element aborts parsing the current segment.</li>
+      <li>If the <append-state/> equals <parsing-media-segment/> and the <input-buffer/> contains some complete <coded-frames/>, then run the <coded-frame-processing-algorithm/> as if the media segment only contained these frames.</li>
+      <li>Remove all bytes from the <input-buffer/>.</li>
+      <li>Set <append-state/> to <waiting-for-segment/>.</li>
+    </ol>
+
+    <p>The <methoddfn name="remove">remove(<var title="true">start</var>, <var title="true">end</var>)</methoddfn> method must run the following steps:</p>
+    <ol>
+      <li>If <var title="true">start</var> is negative or greater than <duration/>, then throw an <invalid-access-err/> exception and abort these steps.</li>
+      <li>If <var title="true">end</var> is less than or equal to <var title="true">start</var>, then throw an <invalid-access-err/> exception and abort these steps.</li>
+      <li>If this object has been removed from the <sourceBuffers/> attribute of the <parent-media-source/> then throw an <invalid-state-err/> exception and abort these steps.</li>
+      <li>If the <readyState/> attribute of the <parent-media-source/> is not in the <open/> state then throw an <invalid-state-err/> exception and abort these steps.</li>
+      <li><p>For each track in this source buffer, run the following steps:</p>
+        <ol>
+	  <li>
+	    <p>Let <var title="true">next random access point timestamp</var> be the timestamp of the next <random-access-point/>, for this track, that is greater than or equal to <var title="true">end</var>.</p>
+	    <p class="note">Note: <var title="true">next random access point timestamp</var> can be different across tracks because the dependencies between <coded-frames/> within a track are usually different than the dependencies in another track.</p></li>
+	  <li>Remove all media data, for this track, that contain starting timestamps greater than or equal to <var title="true">start</var> and less than the <var title="true">next random access point timestamp</var>.</li>
+	</ol>
       </li>
-      <li>If <var title="true">data</var>.byteLength is 0 abort these steps.</li>
-      <li>If <var title="true">data</var> contains anything that violates the <a href="#byte-stream-formats">byte stream format specifications</a>, then call <eos-decode/>, and abort these steps.</li>
-      <li>Add <var title="true">data</var> to the source buffer:
-	<dl class="switch">
-	  <dt>If <var title="true">data</var> is part of a <media-segment/> and <timestampOffset/> is not 0:</dt>
-	  <dd>
-	    <ol>
-	      <li>Find all timestamps inside <var title="true">data</var> and add <timestampOffset/> to them.</li>
-	      <li>If any of the modified timestamps are earlier than the <presentation-start-time/>, then call <eos-decode/>, and abort these steps.</li>
-	      <li>Copy the contents of <var title="true">data</var>, with the modified timestamps, into the source buffer.</li>
-	    </ol>
-	  </dd>
-	  <dt>Otherwise</dt>
-	  <dd>Copy the contents of <var title="true">data</var> into the source buffer.</dd>
-	</dl>
+      
+    </ol>
+
+    <h3 id="sourcebuffer-algorithms">4.2. Algorithms</h3>
+
+    <h4 id="sourcebuffer-segment-parser-loop">4.2.1 Segment Parser Loop</h4>
+    <p>All SourceBuffer objects have an internal <dfn id="sourcebuffer-append-state">append state</dfn> variable that keeps track of the high-level segment parsing state. It is initially set to <waiting-for-segment/> and can transition to the following states as data is appended.</p>
+    <table>
+      <thead>
+	<tr>
+          <th>Append state name</th>
+          <th>Description</th>
+        </tr>
+      </thead>
+      <tbody>
+        <tr>
+          <td><dfn id="sourcebuffer-waiting-for-segment">WAITING_FOR_SEGMENT</dfn></td>
+          <td>Waiting for the start of an <init-segment/> or <media-segment/> to be appended.</td>
+        </tr>
+        <tr>
+          <td><dfn id="sourcebuffer-parsing-init-segment">PARSING_INIT_SEGMENT</dfn></td>
+          <td>Currently parsing an <init-segment/>.</td>
+        </tr>
+	<tr>
+	  <td><dfn id="sourcebuffer-parsing-media-segment">PARSING_MEDIA_SEGMENT</dfn></td>
+          <td>Currently parsing a <media-segment/>.</td>
+        </tr>
+      </tbody>
+    </table>
+    
+    <p>The <dfn id="sourcebuffer-input-buffer">input buffer</dfn> is a byte buffer that is used to hold unparsed bytes across <append/> calls. The buffer is empty when the SourceBuffer object is created.</p>
+
+    <p>While the <input-buffer/> is not empty, run the following steps in a loop:</p>
+    <ol>
+      <li>If the <input-buffer/> starts with bytes that violate the <byte-stream-format-specs/>, then call <eos-decode/>, and abort this algorithm.</li>
+      <li>Remove any bytes that the <byte-stream-format-specs/> say should be ignored from the start of the <input-buffer/>.</li>
+      <li>
+	<p>If the <append-state/> equals <waiting-for-segment/>, then run the following steps:</p>
+	<ol>
+	  <li>If the beginning of the <input-buffer/> indicates the start of an <init-segment/>, set the <append-state/> to <parsing-init-segment/>.</li>
+	  <li>If the beginning of the <input-buffer/> indicates the start of an <media-segment/>, set <append-state/> to <parsing-media-segment/>.</li>
+	  <li>Return  to the top of the loop.</li>
+	</ol>
       </li>
-      <li>Handle end of segment cases:</li>
+      <li>
+	<p>If the <append-state/> equals <parsing-init-segment/>, then run the following steps:</p>
+	<ol>
+	  <li>If the <input-buffer/> does not contain a complete <init-segment/> yet, then exit the loop.</li>
+	  <li>Run the <init-segment-received-algorithm/>.</li>
+	  <li>Remove the <init-segment/> bytes from the beginning of the <input-buffer/>.</li>
+	  <li>Set <append-state/> to <waiting-for-segment/>.</li>
+	  <li>Return  to the top of the loop.</li>
+	</ol>
+      </li>
+      <li>
+	<p>If the <append-state/> equals <parsing-media-segment/>, then run the following steps:</p>
+	<ol>
+	  <li>
+	    <p>If the <input-buffer/> does not contain a complete <media-segment/> header yet, then exit the loop.</p>
+	    <p class="note">Note: Implementations may choose to implement this state as an incremental parser so that it is not necessary to have the entire media segment before running the <coded-frame-processing-algorithm/>.</p>
+	  </li>
+	  <li>Run the <coded-frame-processing-algorithm/>.</li>
+	  <li>Remove the <media-segment/> bytes from the beginning of the <input-buffer/>.</li>
+	  <li>
+	    <p>Set <append-state/> to <waiting-for-segment/>.</p>
+	    <p class="note">Note: Incremental parsers should only do this transition after the entire media segment has been received.</p>
+	  </li>
+	  <li>Return  to the top of the loop.</li>
+	</ol>
+      </li>
+    </ol>
+
+    <h4 id="sourcebuffer-init-segment-received">4.2.2 Initialization Segment Received</h4>
+    <p>The following steps are run when the <segment-parser-loop/> successfully parses a complete <init-segment/>:</p>
+    <ol>
+      <li>Update the <duration/> attribute if it currently equals NaN:</li>
       <dl class="switch">
-	<dt>If <var title="true">data</var> completes the first <init-segment/> appended to the <source-buffer/> run the following steps:</dt>
+	<dt>If the initialization segment contains a duration:</dt>
+	<dd>Run the <duration-change-algorithm/> with <new-duration/> set to the duration in the initialization segment.</dd>
+	<dt>Otherwise:</dt>
+	<dd>Run the <duration-change-algorithm/> with <new-duration/> set to positive Infinity.</dd>
+      </dl>
+      <li>Handle state transitions:</li>
+      <dl class="switch">
+	<dt>If the <ready-state/> attribute is <have-nothing/>:</dt>
 	<dd>
 	  <ol>
-	    <li>Update <duration/> attribute if it currently equals NaN:</li>
-	    <dl class="switch">
-	      <dt>If the initialization segment contains a duration:</dt>
-	      <dd>Run the <duration-change-algorithm/> with <new-duration/> set to the duration in the initialization segment.</dd>
-	      <dt>Otherwise:</dt>
-	      <dd>Run the <duration-change-algorithm/> with <new-duration/> set to positive Infinity.</dd>
-	    </dl>
-	    <li>Handle state transitions:</li>
-	    <dl class="switch">
-	      <dt>If the <ready-state/> attribute is <have-nothing/>:</dt>
-	      <dd>
-	       <ol>
-		 <li>Set the <ready-state/> attribute to <have-metadata/>.</li>
-		 <li><queue-a-task-to-fire-an-event-named/>  <loadedmetadata/> at the media element.</li>
-	       </ol>
-	      </dd>
-	      <dt>If the <ready-state/> attribute is greater than <have-current-data/> and the <init-segment/> contains the first video or first audio track in the presentation:</dt>
-	      <dd>
-		Set the <ready-state/> attribute to <have-metadata/>.
-	      </dd>
-	      <dt>Otherwise:</dt>
-	      <dd>Continue</dd>
-	    </dl>
-	    <li>Update <audiotracks/></li>
-	    <dl class="switch">
-	      <dt>If <init-segment/> contains the first audio track:</dt>
-	      <dd>
-		<ol>
-		  <li>Add an <audio-track/> and mark it as enabled.</li>
-		  <li>Add this <SourceBuffer/> to <activeSourceBuffers/>.</li>
-		</ol>
-	      </dd>
-	      <dt>If <init-segment/> contains audio tracks beyond those already in the presentation:</dt>
-	      <dd>Add a disabled <audio-track/> for each audio track in the <init-segment/>.</dd>
-	    </dl>
-	    <li>Update <videotracks/>:</li>
-	    <dl class="switch">
-	      <dt>If <init-segment/> contains the first video track:</dt>
-	      <dd>
-		<ol>
-		  <li>Add a <video-track/> and mark it as selected.</li>
-		  <li>Add this <SourceBuffer/> to <activeSourceBuffers/>.</li>
-		</ol>
-	      </dd>
-	      <dt>If <init-segment/> contains the video tracks beyond those already in the presentation:</dt>
-	      <dd>Add a disabled <video-track/> for each video track in the <init-segment/>.</dd>
-	    </dl>
-	    <li>Update <texttracks/></li>
-	    <dl class="switch">
-	      <dd>
-		<ol>
-		  <li>Add a <text-track/> for each text track in the <init-segment/>.</li>
-		  <li>If the text track <videoref name="dom-texttrack-mode">mode</videoref> is <videoref name="dom-texttrack-showing">&quot;showing&quot;</videoref> or <videoref name="dom-texttrack-hidden">&quot;hidden&quot;</videoref> then add this <SourceBuffer/> to <activeSourceBuffers/>.</li>
-		</ol>
-	      </dd>
-	    </dl>
+	    <li>Set the <ready-state/> attribute to <have-metadata/>.</li>
+	    <li><Queue-a-task-to-fire-an-event-named/>  <loadedmetadata/> at the media element.</li>
 	  </ol>
 	</dd>
-	<dt>If the <ready-state/> attribute is <have-metadata/> and <var title="true">data</var> causes all objects in <activeSourceBuffers/> to have media data for the current playback position.</dt>
+	<dt>If the <ready-state/> attribute is greater than <have-current-data/> and the <init-segment/> contains the first video or first audio track in the presentation:</dt>
 	<dd>
+	  Set the <ready-state/> attribute to <have-metadata/>.
+	</dd>
+	<dt>Otherwise:</dt>
+	<dd>Continue</dd>
+      </dl>
+      <li>Update <audiotracks/></li>
+      <dl class="switch">
+	<dt>If <init-segment/> contains the first audio track:</dt>
+	<dd>
+	  <ol>
+	    <li>Add an <audio-track/> and mark it as enabled.</li>
+	    <li>Add this <SourceBuffer/> to <activeSourceBuffers/>.</li>
+	  </ol>
+	</dd>
+	<dt>If <init-segment/> contains audio tracks beyond those already in the presentation:</dt>
+	<dd>Add a disabled <audio-track/> for each audio track in the <init-segment/>.</dd>
+      </dl>
+      <li>Update <videotracks/>:</li>
+      <dl class="switch">
+	<dt>If <init-segment/> contains the first video track:</dt>
+	<dd>
+	  <ol>
+	    <li>Add a <video-track/> and mark it as selected.</li>
+	    <li>Add this <SourceBuffer/> to <activeSourceBuffers/>.</li>
+	  </ol>
+	</dd>
+	<dt>If <init-segment/> contains the video tracks beyond those already in the presentation:</dt>
+	<dd>Add a disabled <video-track/> for each video track in the <init-segment/>.</dd>
+      </dl>
+      <li>Update <texttracks/></li>
+      <dl class="switch">
+	<dd>
+	  <ol>
+	    <li>Add a <text-track/> for each text track in the <init-segment/>.</li>
+	    <li>If the text track <videoref name="dom-texttrack-mode">mode</videoref> is <videoref name="dom-texttrack-showing">&quot;showing&quot;</videoref> or <videoref name="dom-texttrack-hidden">&quot;hidden&quot;</videoref> then add this <SourceBuffer/> to <activeSourceBuffers/>.</li>
+	  </ol>
+	</dd>
+      </dl>
+    </ol>
+
+    <h4 id="sourcebuffer-coded-frame-processing">4.2.3 Coded Frame Processing</h4>
+    <p>When a complete <coded-frame/> has been parsed by the <segment-parser-loop/> then the following steps are run:</p>
+    <ol>
+      <li>
+	<p>For each <coded-frame/> in the <media-segment/> run the following steps:</p>
+	<ol>
+	  <li>Let <var title="true">presentation timestamp</var> be a double precision floating point representation of the coded frame's presentation timestamp.</li>
+	  <li>Let <var title="true">decode timestamp</var> be a double precision floating point representation of the coded frame's decode timestamp.</li>
+	  <li>
+	    <p>If <timestampOffset/> is not 0, then run the following steps:</p>
+	    <ol>
+	      <li>Add <timestampOffset/> to the <var title="true">presentation timestamp</var>.</li>
+	      <li>Add <timestampOffset/> to the <var title="true">decode timestamp</var>.</li>
+	      <li>If the <var title="true">presentation timestamp</var> or <var title="true">decode timestamp</var> is less than the <presentation-start-time/>, then call <eos-decode/>, and abort these steps.</li>
+	    </ol>
+	  </li>
+	  <li>Add the <coded-frame/> with the <var title="true">presentation timestamp</var> and <var title="true">decode timestamp</var>, to the source buffer.</li>
+	</ol>
+      </li>
+      <li><p>If the <ready-state/> attribute is <have-metadata/> and the new <coded-frames/> cause all objects in <activeSourceBuffers/> to have media data for the current playback position, then run the following steps:</p>
 	  <ol>
 	    <li>Set the <ready-state/> attribute to <have-current-data/>.</li>
 	    <li>If this is the first transition to <have-current-data/>, then <queue-a-task-to-fire-an-event-named/> <loadeddata/> at the media element.</li>
 	  </ol>
-	</dd>
-	<dt>If the <ready-state/> attribute is <have-current-data/> and <var title="true">data</var> causes all objects in <activeSourceBuffers/> to have media data beyond the current playback position.</dt>
-	<dd>
-	  <ol>
-	    <li>Set the <ready-state/> attribute to <have-future-data/>.</li>
-	    <li><queue-a-task-to-fire-an-event-named/> <canplay/> at the media element.</li>
-	  </ol>
-	</dd>
-	<dt>If the <ready-state/> attribute is <have-future-data/> and <var title="true">data</var> causes all objects in <activeSourceBuffers/> to have enough data to start playback.</dt>
-	<dd>
-	  <ol>
-	    <li>Set the <ready-state/> attribute to <have-enough-data/>.</li>
-	    <li><queue-a-task-to-fire-an-event-named/> <canplaythrough/> at the media element.</li>
-	  </ol>
-	</dd>
-	<dt>If the <media-segment/> contains data beyond the current <duration/></dt>
-	<dd>Run the <duration-change-algorithm/> with <new-duration/> set to the maximum of the current duration and the highest end timestamp reported by <videoref name="dom-media-buffered">HTMLMediaElement.buffered</videoref>.</dd>
-      </dl>
-    </ol>
-
-    <p>The <methoddfn name="abort">abort()</methoddfn> method must run the following steps:</p>
-    <ol>
-      <li>If this object has been removed from the <sourceBuffers/> attribute of the <MediaSource/> object that created it then throw an <invalid-state-err/> exception and abort these steps.</li>
-      <li>If the <readyState/> attribute of the <MediaSource/> object that created this object is not in the <open/> state then throw an <invalid-state-err/> exception and abort these steps.</li>
-      <li>The media element aborts parsing the current segment.</li>
-      <dl class="switch">
-	<dt>If waiting for the start of a new segment</dt>
-	<dd>Continue</dd>
-	<dt>If the current segment is an <init-segment/></dt>
-	<dd>Flush any data associated with this partial segment.</dd>
-	<dt>If the current segment is a <media-segment/></dt>
-	<dd>The media element may keep any media data it finds valuable in the partial segment. For example if the abort happens in the middle of a 10 second <media-segment/>, the media element may choose to keep the 5 seconds of media data it has already parsed in the source buffer. <buffered/> will reflect what data, if any, was kept.</dd>
-      </dl>
-      <li>The media element resets the segment parser so that it can accept a new <init-segment/> or <media-segment/>.</li>
+      </li>
+      <li>
+	<p>If the <ready-state/> attribute is <have-current-data/> and the new <coded-frames/> cause all objects in <activeSourceBuffers/> to have media data beyond the current playback position, then run the following steps:</p>
+	<ol>
+	  <li>Set the <ready-state/> attribute to <have-future-data/>.</li>
+	  <li><Queue-a-task-to-fire-an-event-named/> <canplay/> at the media element.</li>
+	</ol>
+      </li>
+      <li>
+	<p>If the <ready-state/> attribute is <have-future-data/> and the new <coded-frames/> cause all objects in <activeSourceBuffers/> to have enough data to start playback, then run the following steps:</p>
+	<ol>
+	  <li>Set the <ready-state/> attribute to <have-enough-data/>.</li>
+	  <li><Queue-a-task-to-fire-an-event-named/> <canplaythrough/> at the media element.</li>
+	</ol>
+      </li>
+      <li>If the <media-segment/> contains data beyond the current <duration/>, then run the <duration-change-algorithm/> with <new-duration/> set to the maximum of the current duration and the highest end timestamp reported by <videoref name="dom-media-buffered">HTMLMediaElement.buffered</videoref>.</li>
     </ol>
 
     <h2 id="sourcebufferlist">5. SourceBufferList Object</h2>
@@ -947,7 +1046,8 @@
 	<li>External data references must not be used.</li>
 	<li>If the Movie Fragment contains multiple tracks, the duration by which each track extends should be as close to equal as practical.</li>
 	<li>Each Track Fragment Box must contain a Track Fragment Decode Time Box (<iso-box>tfdt</iso-box>)</li>
-	<li>The Media Data Boxes must contain all the samples referenced by the Track Run Boxes (<iso-box>trun</iso-box>) of the Movie Fragment Box.</li>
+	<li>The first sample in each Track Fragment Run Box (<iso-box>trun</iso-box>) must indicate that the sample is a <random-access-point/>.</li>
+	<li>The Media Data Boxes must contain all the samples referenced by the Track Fragment Run Boxes (<iso-box>trun</iso-box>) of the Movie Fragment Box.</li>
       </ol>
 
       <h4 id="iso-random-access-points">8.2.3. Random Access Points</h4>
@@ -1045,7 +1145,11 @@
       </thead>
       <tbody>
 	<tr>
-	  <td>8 October 2012</td>
+	  <td>18 October 2012</td>
+          <td>Refactored SourceBuffer.append() &amp; added SourceBuffer.remove().</td>
+        </tr>
+	<tr>
+	  <td><a href="http://dvcs.w3.org/hg/html-media/rev/6d127e69c9f8">8 October 2012</a></td>
           <td>
 	    <ul>
 	      <li>Defined what HTMLMediaElement.seekable and HTMLMediaElement.buffered should return.</li>
--- a/media-source/spec-html.xsl	Tue Oct 09 10:29:57 2012 -0700
+++ b/media-source/spec-html.xsl	Thu Oct 18 09:09:08 2012 -0700
@@ -53,10 +53,19 @@
     <a href="#track-id">Track IDs</a>
   </xsl:template>
  
- <xsl:template match="//track-description">
+  <xsl:template match="//track-description">
     <a href="#track-id">track description</a>
   </xsl:template>
 
+  <xsl:template match="//coded-frame">
+    <a href="#coded-frame">coded frame</a>
+  </xsl:template>
+
+  <xsl:template match="//coded-frames">
+    <a href="#coded-frame">coded frames</a>
+  </xsl:template>
+
+
   <!-- MediaSource tags -->
   <xsl:template match="//sourceBuffers">
     <xsl:call-template name="coderef_helper">
@@ -164,6 +173,46 @@
   </xsl:template>
 
   <!-- SourceBuffer tags -->
+  <xsl:template match="//parent-media-source">
+    <a href="#sourcebuffer-parent-media-source">parent media source</a>
+  </xsl:template>
+
+  <xsl:template match="//segment-parser-loop">
+    <a href="#sourcebuffer-segment-parser-loop">segment parser loop</a>
+  </xsl:template>
+
+  <xsl:template match="//append-state">
+    <a href="#sourcebuffer-append-state">append state</a>
+  </xsl:template>
+
+  <xsl:template match="//waiting-for-segment">
+    <a href="#sourcebuffer-waiting-for-segment">WAITING_FOR_SEGMENT</a>
+  </xsl:template>
+
+  <xsl:template match="//parsing-init-segment">
+    <a href="#sourcebuffer-parsing-init-segment">PARSING_INIT_SEGMENT</a>
+  </xsl:template>
+
+  <xsl:template match="//parsing-media-segment">
+    <a href="#sourcebuffer-parsing-media-segment">PARSING_MEDIA_SEGMENT</a>
+  </xsl:template>
+
+  <xsl:template match="//byte-stream-format-specs">
+    <a href="#byte-stream-formats">byte stream format specifications</a>
+  </xsl:template>
+
+  <xsl:template match="//init-segment-received-algorithm">
+    <a href="#sourcebuffer-init-segment-received">initialization segment received algorithm</a>
+  </xsl:template>
+
+  <xsl:template match="//coded-frame-processing-algorithm">
+    <a href="#sourcebuffer-coded-frame-processing">coded frame processing algorithm</a>
+  </xsl:template>
+
+  <xsl:template match="//input-buffer">
+    <a href="#sourcebuffer-input-buffer">input buffer</a>
+  </xsl:template>
+
   <xsl:template match="//append">
     <xsl:call-template name="coderef_helper">
       <xsl:with-param name="fragment">append</xsl:with-param>
@@ -698,6 +747,16 @@
     </xsl:call-template> named
   </xsl:template>
 
+  <xsl:template match="//Queue-a-task-to-fire-an-event-named">
+    <xsl:call-template name="webappapis_helper">
+      <xsl:with-param name="fragment">queue-a-task</xsl:with-param>
+      <xsl:with-param name="link_text">Queue a task</xsl:with-param>
+    </xsl:call-template> to <xsl:call-template name="webappapis_helper">
+      <xsl:with-param name="fragment">fire-a-simple-event</xsl:with-param>
+      <xsl:with-param name="link_text">fire a simple event</xsl:with-param>
+    </xsl:call-template> named
+  </xsl:template>
+
   <xsl:template match="//provide-a-stable-state">
     <xsl:call-template name="webappapis_helper">
       <xsl:with-param name="fragment">provide-a-stable-state</xsl:with-param>