Bug 21112 - Add appendWindowStart & appendWindowEnd attributes.
Bug 19676 - Clarify overlapped frame definitions and splice logic.
Bug 21172 - Added coded frame removal and eviction algorithms.
--- a/media-source/media-source-respec.html Mon Mar 04 09:42:34 2013 -0800
+++ b/media-source/media-source-respec.html Tue Mar 12 11:43:03 2013 -0700
@@ -153,9 +153,16 @@
<dt id="append-sequence">Append Sequence</dt>
<dd>A series of <a def-id="appendBuffer"></a> or <a def-id="appendStream"></a> calls on a <a>SourceBuffer</a> without any intervening <a def-id="abort"></a> calls. The
- <a def-id="media-segments"></a> in an append sequence must be adjacent and monotonically increasing in time without any gaps. An
- <a def-id="abort"></a> call starts a new append sequence which allows <a def-id="media-segments"></a> to be appended in non-monotonically
- increasing order.</dd>
+ <a def-id="media-segments"></a> in an append sequence must be adjacent and monotonically increasing in time without any gaps. An
+ <a def-id="abort"></a> call starts a new append sequence which allows <a def-id="media-segments"></a> to be appended in non-monotonically
+ increasing order.
+ </dd>
+
+ <dt id="append-window">Append Window</dt>
+ <dd>A presentation timestamp range used to filter out <a def-id="coded-frames"></a> while appending. The append window represents a single
+ continuous time range with a single start time and end time. Coded frames with presentation timestamps within this range are allowed to be appended
+ to the <a>SourceBuffer</a> while coded frames outside this range are filtered out. The append window start and end times are controlled by
+ the <a def-id="appendWindowStart"></a> and <a def-id="appendWindowEnd"></a> attributes respectively.</dd>
</dl>
</section>
</section>
@@ -683,6 +690,36 @@
The list of <a def-id="text-track"></a> objects created by this object.
</dd>
+ <dt>attribute double appendWindowStart</dt>
+ <dd>
+ <p>The presentation timestamp for the start of the <a def-id="append-window"></a>. This attribute is initially set to 0.</p>
+ <p>On getting, Return the initial value or the last value that was successfully set.</p>
+ <p>On setting, run the following steps:</p>
+ <ol>
+ <li>If this object has been removed from the <a def-id="sourceBuffers"></a> attribute of the <a def-id="parent-media-source"></a>, then throw an
+ <a def-id="invalid-state-err"></a> exception and abort these steps.</li>
+ <li>If the <a def-id="updating"></a> attribute equals true, then throw an <a def-id="invalid-state-err"></a> exception and abort these steps.</li>
+ <li>If the new value is less than 0 or greater than or equal to <a def-id="appendWindowEnd"></a> then throw an <a def-id="invalid-access-err"></a> exception
+ and abort these steps.</li>
+ <li>Update the attribute to the new value.</li>
+ </ol>
+ </dd>
+
+ <dt>attribute double appendWindowEnd</dt>
+ <dd>
+ <p>The presentation timestamp for the end of the <a def-id="append-window"></a>. This attribute is initially set to positive Infinity.</p>
+ <p>On getting, Return the initial value or the last value that was successfully set.</p>
+ <p>On setting, run the following steps:</p>
+ <ol>
+ <li>If this object has been removed from the <a def-id="sourceBuffers"></a> attribute of the <a def-id="parent-media-source"></a>, then throw an
+ <a def-id="invalid-state-err"></a> exception and abort these steps.</li>
+ <li>If the <a def-id="updating"></a> attribute equals true, then throw an <a def-id="invalid-state-err"></a> exception and abort these steps.</li>
+ <li>If the new value is less than or equal to <a def-id="appendWindowStart"></a> then throw an <a def-id="invalid-access-err"></a> exception and abort these
+ steps.</li>
+ <li>Update the attribute to the new value.</li>
+ </ol>
+ </dd>
+
<dt>void appendBuffer(ArrayBuffer data)</dt>
<dd>
<p>Appends the segment data in an ArrayBuffer to the source buffer.</p>
@@ -706,9 +743,11 @@
<a def-id="Queue-a-task-to-fire-an-event-named"></a> <a def-id="sourceopen"></a> at the <a def-id="parent-media-source"></a> .</li>
</ol>
</li>
+ <li>Run the <a def-id="coded-frame-eviction-algorithm"></a>.</li>
<li>
<p>If the <a def-id="buffer-full-flag"></a> equals true, then throw a <a def-id="quota-exceeded-err"></a> exception and abort these step.</p>
- <p class="note">The web application must use <a def-id="remove"></a> to free up space in the <a>SourceBuffer</a>.</p>
+ <p class="note">This is the signal that the implementation was unable to evict enough data to accomodate the append or the append is too big. The web
+ application must use <a def-id="remove"></a> to explicitly free up space and/or reduce the size of the append.</p>
</li>
<li>Add <var>data</var> to the end of the <a def-id="input-buffer"></a>.</li>
<li>Set the <a def-id="updating"></a> attribute to true.</li>
@@ -739,9 +778,11 @@
<li><a def-id="Queue-a-task-to-fire-an-event-named"></a> <a def-id="sourceopen"></a> at the <a def-id="parent-media-source"></a> .</li>
</ol>
</li>
+ <li>Run the <a def-id="coded-frame-eviction-algorithm"></a>.</li>
<li>
<p>If the <a def-id="buffer-full-flag"></a> equals true, then throw a <a def-id="quota-exceeded-err"></a> exception and abort these step.</p>
- <p class="note">The web application must use <a def-id="remove"></a> to free up space in the <a>SourceBuffer</a>.</p>
+ <p class="note">This is the signal that the implementation was unable to evict enough data to accomodate the append or the append is too big. The web
+ application must use <a def-id="remove"></a> to explicitly free up space and/or reduce the size of the append.</p>
</li>
<li>Set the <a def-id="updating"></a> attribute to true.</li>
<li><a def-id="Queue-a-task-to-fire-an-event-named"></a> <a def-id="updatestart"></a> at this <a>SourceBuffer</a> object.</li>
@@ -782,6 +823,8 @@
<dd>Update the <a def-id="abort-mode"></a> to equal <var>mode</var>.</dd>
</dl>
</li>
+ <li>Set <a def-id="appendWindowStart"></a> to 0.</li>
+ <li>Set <a def-id="appendWindowEnd"></a> to positive Infinity.</li>
<li>Run the <a def-id="reset-parser-state-algorithm"></a>.</li>
</ol>
</dd>
@@ -799,23 +842,7 @@
<li>Set the <a def-id="updating"></a> attribute to true.</li>
<li><a def-id="Queue-a-task-to-fire-an-event-named"></a> <a def-id="updatestart"></a> at this <a>SourceBuffer</a> object.</li>
<li>Return control to the caller and run the rest of the steps asynchronously.</li>
- <li>
- <p>For each <a def-id="track-buffer"></a> in this source buffer, run the following steps:</p>
- <ol>
- <li>Let <var>remove end timestamp</var> be the current value of <a def-id="duration"></a></li>
- <li>
- <p>If this <a def-id="track-buffer"></a> has a <a def-id="random-access-point"></a> timestamp that is greater than or equal to <var>end</var>, then update <var>remove end timestamp</var> to that timestamp.</p>
- <p class="note">Random access point timestamps can be different across tracks because the dependencies between <a def-id="coded-frames"></a> within a track are usually different than the dependencies in another track.</p>
- </li>
- <li>Remove all media data, from this <a def-id="track-buffer"></a>, that contain starting timestamps greater than or equal to <var>start</var> and less than the <var>remove end timestamp</var>.</li>
- <li>
- <p>If this object is in <a def-id="activeSourceBuffers"></a>, the <a def-id="current-playback-position"></a> is greater than or equal to <var>start</var> and less than the <var>remove end timestamp</var>, and <a def-id="ready-state"></a> is greater than <a def-id="have-metadata"></a>, then set the <a def-id="ready-state"></a> attribute to <a def-id="have-metadata"></a> and stall playback.</p>
- <p class="note">This transition occurs because media data for the current position has been removed. Playback cannot progress until media for the <a def-id="current-playback-position"></a> is appended or the <a href="#active-source-buffer-changes">selected/enabled tracks change</a>.</p>
- </li>
- </ol>
- </li>
- <li>If <a def-id="buffer-full-flag"></a> equals true and this object is ready to accept more bytes, then set
- the <a def-id="buffer-full-flag"></a> to false.</li>
+ <li>Run the <a def-id="coded-frame-removal-algorithm"></a> with <var>start</var> and <var>end</var> as the start and end of the removal range.</li>
<li>Set the <a def-id="updating"></a> attribute to false.</li>
<li><a def-id="Queue-a-task-to-fire-an-event-named"></a> <a def-id="update"></a> at this <a>SourceBuffer</a> object.</li>
<li><a def-id="Queue-a-task-to-fire-an-event-named"></a> <a def-id="updateend"></a> at this <a>SourceBuffer</a> object.</li>
@@ -1020,10 +1047,6 @@
<li>If <var>maxSize</var> is set, then let <var>bytesLeft</var> equal <var>maxSize</var>.</li>
<li><i>Loop Top: </i>If <var>maxSize</var> is set and <var>bytesLeft</var> equals 0, then jump to the <i>loop done</i> step below.</li>
<li>If <var>stream</var> has been closed, then jump to the <i>loop done</i> step below.</li>
- <li>
- <p>If the <a def-id="buffer-full-flag"></a> equals true, then run the <a def-id="append-error-algorithm"></a> and abort this algorithm.</p>
- <p class="note">The web application must use <a def-id="remove"></a> to free up space in the <a>SourceBuffer</a>.</p>
- </li>
<li>Read data from <var>stream</var> into <var>data</var>:
<dl class="switch">
<dt>If <var>maxSize</var> is set:</dt>
@@ -1037,6 +1060,11 @@
</dl>
</li>
<li>If an error occured while reading from <var>stream</var>, then run the <a def-id="append-error-algorithm"></a> and abort this algorithm.</li>
+ <li>Run the <a def-id="coded-frame-eviction-algorithm"></a>.</li>
+ <li>
+ <p>If the <a def-id="buffer-full-flag"></a> equals true, then run the <a def-id="append-error-algorithm"></a> and abort this algorithm.</p>
+ <p class="note">The web application must use <a def-id="remove"></a> to free up space in the <a>SourceBuffer</a>.</p>
+ </li>
<li>Add <var>data</var> to the end of the <a def-id="input-buffer"></a>.</li>
<li>Run the <a def-id="segment-parser-loop"></a> algorithm.</li>
<li>Jump to the <i>loop top</i> step above.</li>
@@ -1229,8 +1257,17 @@
<p class="note">These checks trigger an error when the application attempts out-of-order appends without an intervening
<a def-id="abort"></a>.</p>
</li>
-
<li>Let <var>frame end timestamp</var> equal the sum of <var>presentation timestamp</var> and <var>frame duration</var>.</li>
+ <li>If <var>presentation timestamp</var> is less than <a def-id="appendWindowStart"></a>, then set the <a def-id="need-RAP-flag"></a> to true, drop the
+ coded frame, and jump to the top of the loop to start processing the next coded frame.
+ <p class="note">Some implementations may choose to collect some of these coded frames that are outside the <a def-id="append-window"></a> and use them
+ to generate a splice at the first coded frame that has a presentation timestamp greater than or equal to <a def-id="appendWindowStart"></a> even if
+ that frame is not a <a def-id="random-access-point"></a>. Supporting this requires multiple decoders or faster than real-time decoding so for now
+ this behavior will not be a normative requirement.
+ </p>
+ </li>
+ <li>If <var>frame end timestamp</var> is greater than <a def-id="appendWindowEnd"></a>, then set the <a def-id="need-RAP-flag"></a> to true, drop the
+ coded frame, and jump to the top of the loop to start processing the next coded frame.
<li>If the <a def-id="need-RAP-flag"></a> on <var>track buffer</var> equals true, then run the following steps:
<ol>
<li>If the coded frame is not a <a def-id="random-access-point"></a>, then drop the coded frame and jump to the top of the loop to start
@@ -1239,15 +1276,19 @@
</ol>
</li>
<li>Let <var>spliced frame</var> be an unset variable for holding audio splice information</li>
- <li>If <a def-id="last-decode-timestamp"></a> for <var>track buffer</var> is unset and <var>presentation timestamp</var> lies within a
- <a def-id="coded-frame"></a> already stored in <var>track buffer</var>, then run the following steps:
+ <li>If <a def-id="last-decode-timestamp"></a> for <var>track buffer</var> is unset and there is a <a def-id="coded-frame"></a> in
+ <var>track buffer</var> with a presentation timestamp less than or equal to <var>presentation timestamp</var> and
+ <var>presentation timestamp</var> is less than this coded frame's presentation timestamp plus its frame duration, then run the
+ following steps:
<ol>
- <li>Let <var>overlapped frame</var> be the <a def-id="coded-frame"></a> in <var>track buffer</var> that contains <var>presentation timestamp</var>.</li>
+ <li>Let <var>overlapped frame</var> be the <a def-id="coded-frame"></a> in <var>track buffer</var> that matches the condition above.</li>
<li>If <var>track buffer</var> contains audio <a def-id="coded-frames"></a>, then run the <a def-id="audio-splice-frame-algorithm"></a> and if a splice
frame is returned, assign it to <var>spliced frame</var>.</li>
- <li>If <var>track buffer</var> contains video <a def-id="coded-frames"></a> and <var>presentation timestamp</var> is less than 1 microsecond
- beyond the presentation timestamp of <var>overlapped frame</var>, then remove <var>overlapped frame</var> and any
- <a def-id="coded-frames"></a> that depend on it from <var>track buffer</var>.
+ <li>Let <var>overlapped frame presentation timestamp</var> equal the presentation timestamp of <var>overlapped frame</var>.</li>
+ <li>Let <var>remove window timestamp</var> equal <var>overlapped frame presentation timestamp</var> plus 1 microsecond.</li>
+ <li>If <var>track buffer</var> contains video <a def-id="coded-frames"></a> and the <var>presentation timestamp</var> is greater than or equal to
+ the <var>overlapped frame presentation timestamp</var> and the <var>presentation timestamp</var> is less than the <var>remove window timestamp</var>,
+ then remove <var>overlapped frame</var> and any <a def-id="coded-frames"></a> that depend on it from <var>track buffer</var>.
<p class="note">
This is to compensate for minor errors in frame timestamp computations that can appear when converting back and forth between double precision
floating point numbers and rationals. This tolerance allows a frame to replace an existing one as long as it is within 1 microsecond of the existing
@@ -1318,6 +1359,54 @@
</ol>
</section>
+ <section id="sourcebuffer-coded-frame-removal">
+ <h4>Coded Frame Removal Algorithm</h4>
+ <p>Follow these steps when <a def-id="coded-frames"></a> for a specific time range need to be removed from the SourceBuffer:</p>
+ <ol>
+ <li>Let <var>start</var> be the starting presentation timestamp for the removal range.</li>
+ <li>Let <var>end</var> be the end presentation timestamp for the removal range. </li>
+ <li><p>For each <a def-id="track-buffer"></a> in this source buffer, run the following steps:</p>
+ <ol>
+ <li>Let <var>remove end timestamp</var> be the current value of <a def-id="duration"></a></li>
+ <li>
+ <p>If this <a def-id="track-buffer"></a> has a <a def-id="random-access-point"></a> timestamp that is greater than or equal to
+ <var>end</var>, then update <var>remove end timestamp</var> to that random access point timestamp.</p>
+ <p class="note">Random access point timestamps can be different across tracks because the dependencies between <a def-id="coded-frames"></a> within a
+ track are usually different than the dependencies in another track.</p>
+ </li>
+ <li>Remove all media data, from this <a def-id="track-buffer"></a>, that contain starting timestamps greater than or equal to
+ <var>start</var> and less than the <var>remove end timestamp</var>.</li>
+ <li>
+ <p>If this object is in <a def-id="activeSourceBuffers"></a>, the <a def-id="current-playback-position"></a> is greater than or equal to
+ <var>start</var> and less than the <var>remove end timestamp</var>, and <a def-id="ready-state"></a> is greater than
+ <a def-id="have-metadata"></a>, then set the <a def-id="ready-state"></a> attribute to <a def-id="have-metadata"></a> and stall playback.</p>
+ <p class="note">This transition occurs because media data for the current position has been removed. Playback cannot progress until media for the
+ <a def-id="current-playback-position"></a> is appended or the <a href="#active-source-buffer-changes">selected/enabled tracks change</a>.</p>
+ </li>
+ </ol>
+ </li>
+ <li>If <a def-id="buffer-full-flag"></a> equals true and this object is ready to accept more bytes, then set
+ the <a def-id="buffer-full-flag"></a> to false.</li>
+ </ol>
+ </section>
+
+ <section id="sourcebuffer-coded-frame-eviction">
+ <h4>Coded Frame Eviction Algorithm</h4>
+ <p>This algorithm is run to free up space in this source buffer when new data is appended.</p>
+ <ol>
+ <li>Let <var>new data</var> equal the data that is about to be appended to this SourceBuffer.</li>
+ <li>If the <a def-id="buffer-full-flag"></a> equals false, then abort these steps.</li>
+ <li>Let <var>removal ranges</var> equal a list of presentation time ranges that can be evicted from the presentation to make room for the
+ <var>new data</var>.
+ <p class="note">Implementations may use different methods for selecting <var>removal ranges</var> so web applications must not depend on a
+ specific behavior. The web application can use the <a def-id="buffered"></a> attribute to observe whether portions of the buffered data have been evicted.
+ </p>
+ </li>
+ <li>For each range in <var>removal ranges</var>, run the <a def-id="coded-frame-removal-algorithm"></a> with <var>start</var> and <var>end</var> equal to
+ the removal range start and end timestamp respectively.</li>
+ </ol>
+ </section>
+
<section id="sourcebuffer-audio-splice-frame-algorithm">
<h4>Audio Splice Frame Algorithm</h4>
<p>Follow these steps when the <a def-id="coded-frame-processing-algorithm"></a> needs to generate a splice frame for two overlapping audio
@@ -1328,9 +1417,12 @@
<li>Let <var>presentation timestamp</var> be the presentation timestamp for <var>new coded frame</var></li>
<li>Let <var>decode timestamp</var> be the decode timestamp for <var>new coded frame</var>.</li>
<li>Let <var>frame duration</var> be the duration of <var>new coded frame</var>.</li>
- <li>Let <var>overlapped frame</var> be the <a def-id="coded-frame"></a> in <var>track buffer</var> that overlaps with <var>new coded frame</var>
- (ie. it contains <var>presentation timestamp).</li>
- <li>Round & update <var>presentation timestamp</var> and <var>decode timestamp</var> to the nearest audio sample timestamp based on sample rate of the audio in <var>overlapped frame</var>.
+ <li>Let <var>overlapped frame</var> be the <a def-id="coded-frame"></a> in <var>track buffer</var> with a presentation timestamp less than or equal to
+ <var>presentation timestamp</var> and <var>presentation timestamp</var> is less than this coded frame's presentation timestamp plus its frame duration.
+ </li>
+ <li>Update <var>presentation timestamp</var> and <var>decode timestamp</var> to the nearest audio sample timestamp based on sample rate of the
+ audio in <var>overlapped frame</var>. If a timestamp is equidistant from both audio sample timestamps, then use the higher timestamp. (eg.
+ floor(x * sample_rate + 0.5) / sample_rate).
<div class="note">
<p>For example, given the following values:</p>
<ul>
@@ -1339,7 +1431,7 @@
<li><var>presentation timestamp</var> equals 10.01255</li>
<li><var>decode timestamp</var> equals 10.01255</li>
</ul>
- <p><var>presentation timestamp</var> and <var>decode timestamp</var> are rounded & updated to 10.0125 since 10.01255 is closer to
+ <p><var>presentation timestamp</var> and <var>decode timestamp</var> are updated to 10.0125 since 10.01255 is closer to
10 + 100/8000 (10.0125) than 10 + 101/8000 (10.012625)</p>
</div>
</li>
@@ -1968,7 +2060,17 @@
</thead>
<tbody>
<tr>
- <td>05 March 2013</td>
+ <td>12 March 2013</td>
+ <td>
+ <ul>
+ <li>Bug 21112 - Add appendWindowStart & appendWindowEnd attributes.</li>
+ <li>Bug 19676 - Clarify overlapped frame definitions and splice logic.</li>
+ <li>Bug 21172 - Added coded frame removal and eviction algorithms.</li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="https://dvcs.w3.org/hg/html-media/raw-file/dcd406812201/media-source/media-source.html">05 March 2013</a></td>
<td>
<ul>
<li>Bug 21170 - Remove 'stream aborted' step from stream append loop algorithm.</li>
--- a/media-source/media-source.html Mon Mar 04 09:42:34 2013 -0800
+++ b/media-source/media-source.html Tue Mar 12 11:43:03 2013 -0700
@@ -397,7 +397,7 @@
</p>
<h1 class="title" id="title">Media Source Extensions</h1>
- <h2 id="w3c-editor-s-draft-05-march-2013"><abbr title="World Wide Web Consortium">W3C</abbr> Editor's Draft 05 March 2013</h2>
+ <h2 id="w3c-editor-s-draft-12-march-2013"><abbr title="World Wide Web Consortium">W3C</abbr> Editor's Draft 12 March 2013</h2>
<dl>
<dt>This version:</dt>
@@ -507,7 +507,7 @@
-</section><section id="toc"><h2 class="introductory">Table of Contents</h2><ul class="toc"><li class="tocline"><a href="#introduction" class="tocxref"><span class="secno">1. </span>Introduction</a><ul class="toc"><li class="tocline"><a href="#goals" class="tocxref"><span class="secno">1.1 </span>Goals</a></li><li class="tocline"><a href="#definitions" class="tocxref"><span class="secno">1.2 </span>Definitions</a></li></ul></li><li class="tocline"><a href="#mediasource" class="tocxref"><span class="secno">2. </span>MediaSource Object</a><ul class="toc"><li class="tocline"><a href="#attributes" class="tocxref"><span class="secno">2.1 </span>Attributes</a></li><li class="tocline"><a href="#methods" class="tocxref"><span class="secno">2.2 </span>Methods</a></li><li class="tocline"><a href="#mediasource-events" class="tocxref"><span class="secno">2.3 </span>Event Summary</a></li><li class="tocline"><a href="#mediasource-algorithms" class="tocxref"><span class="secno">2.4 </span>Algorithms</a><ul class="toc"><li class="tocline"><a href="#mediasource-attach" class="tocxref"><span class="secno">2.4.1 </span>Attaching to a media element</a></li><li class="tocline"><a href="#mediasource-detach" class="tocxref"><span class="secno">2.4.2 </span>Detaching from a media element</a></li><li class="tocline"><a href="#mediasource-seeking" class="tocxref"><span class="secno">2.4.3 </span>Seeking</a></li><li class="tocline"><a href="#buffer-monitoring" class="tocxref"><span class="secno">2.4.4 </span>SourceBuffer Monitoring</a></li><li class="tocline"><a href="#active-source-buffer-changes" class="tocxref"><span class="secno">2.4.5 </span>Changes to selected/enabled track state</a></li><li class="tocline"><a href="#duration-change-algorithm" class="tocxref"><span class="secno">2.4.6 </span>Duration change</a></li></ul></li></ul></li><li class="tocline"><a href="#sourcebuffer" class="tocxref"><span class="secno">3. </span>SourceBuffer Object</a><ul class="toc"><li class="tocline"><a href="#attributes-1" class="tocxref"><span class="secno">3.1 </span>Attributes</a></li><li class="tocline"><a href="#methods-1" class="tocxref"><span class="secno">3.2 </span>Methods</a></li><li class="tocline"><a href="#track-buffers" class="tocxref"><span class="secno">3.3 </span>Track Buffers</a></li><li class="tocline"><a href="#sourcebuffer-events" class="tocxref"><span class="secno">3.4 </span>Event Summary</a></li><li class="tocline"><a href="#sourcebuffer-algorithms" class="tocxref"><span class="secno">3.5 </span>Algorithms</a><ul class="toc"><li class="tocline"><a href="#sourcebuffer-segment-parser-loop" class="tocxref"><span class="secno">3.5.1 </span>Segment Parser Loop</a></li><li class="tocline"><a href="#sourcebuffer-reset-parser-state" class="tocxref"><span class="secno">3.5.2 </span>Reset Parser State</a></li><li class="tocline"><a href="#sourcebuffer-append-error" class="tocxref"><span class="secno">3.5.3 </span>Append Error</a></li><li class="tocline"><a href="#sourcebuffer-stream-append-loop" class="tocxref"><span class="secno">3.5.4 </span>Stream Append Loop</a></li><li class="tocline"><a href="#sourcebuffer-init-segment-received" class="tocxref"><span class="secno">3.5.5 </span>Initialization Segment Received</a></li><li class="tocline"><a href="#sourcebuffer-coded-frame-processing" class="tocxref"><span class="secno">3.5.6 </span>Coded Frame Processing</a></li><li class="tocline"><a href="#sourcebuffer-audio-splice-frame-algorithm" class="tocxref"><span class="secno">3.5.7 </span>Audio Splice Frame Algorithm</a></li><li class="tocline"><a href="#sourcebuffer-audio-splice-rendering-algorithm" class="tocxref"><span class="secno">3.5.8 </span>Audio Splice Rendering Algorithm</a></li></ul></li></ul></li><li class="tocline"><a href="#sourcebufferlist" class="tocxref"><span class="secno">4. </span>SourceBufferList Object</a><ul class="toc"><li class="tocline"><a href="#attributes-2" class="tocxref"><span class="secno">4.1 </span>Attributes</a></li><li class="tocline"><a href="#methods-2" class="tocxref"><span class="secno">4.2 </span>Methods</a></li><li class="tocline"><a href="#sourcebufferlist-events" class="tocxref"><span class="secno">4.3 </span>Event Summary</a></li></ul></li><li class="tocline"><a href="#url" class="tocxref"><span class="secno">5. </span>URL Object</a><ul class="toc"><li class="tocline"><a href="#methods-3" class="tocxref"><span class="secno">5.1 </span>Methods</a></li></ul></li><li class="tocline"><a href="#htmlmediaelement-attributes" class="tocxref"><span class="secno">6. </span>HTMLMediaElement attributes</a></li><li class="tocline"><a href="#audio-track-extensions" class="tocxref"><span class="secno">7. </span>AudioTrack Extensions</a><ul class="toc"><li class="tocline"><a href="#attributes-3" class="tocxref"><span class="secno">7.1 </span>Attributes</a></li></ul></li><li class="tocline"><a href="#video-track-extensions" class="tocxref"><span class="secno">8. </span>VideoTrack Extensions</a><ul class="toc"><li class="tocline"><a href="#attributes-4" class="tocxref"><span class="secno">8.1 </span>Attributes</a></li></ul></li><li class="tocline"><a href="#text-track-extensions" class="tocxref"><span class="secno">9. </span>TextTrack Extensions</a><ul class="toc"><li class="tocline"><a href="#attributes-5" class="tocxref"><span class="secno">9.1 </span>Attributes</a></li></ul></li><li class="tocline"><a href="#byte-stream-formats" class="tocxref"><span class="secno">10. </span>Byte Stream Formats</a><ul class="toc"><li class="tocline"><a href="#webm" class="tocxref"><span class="secno">10.1 </span>WebM Byte Streams</a><ul class="toc"><li class="tocline"><a href="#webm-init-segments" class="tocxref"><span class="secno">10.1.1 </span>Initialization Segments</a></li><li class="tocline"><a href="#webm-media-segments" class="tocxref"><span class="secno">10.1.2 </span>Media Segments</a></li><li class="tocline"><a href="#webm-random-access-points" class="tocxref"><span class="secno">10.1.3 </span>Random Access Points</a></li></ul></li><li class="tocline"><a href="#iso" class="tocxref"><span class="secno">10.2 </span>ISO Base Media File Format Byte Streams</a><ul class="toc"><li class="tocline"><a href="#iso-init-segments" class="tocxref"><span class="secno">10.2.1 </span>Initialization Segments</a></li><li class="tocline"><a href="#iso-media-segments" class="tocxref"><span class="secno">10.2.2 </span>Media Segments</a></li><li class="tocline"><a href="#iso-random-access-points" class="tocxref"><span class="secno">10.2.3 </span>Random Access Points</a></li></ul></li><li class="tocline"><a href="#mpeg2ts" class="tocxref"><span class="secno">10.3 </span>MPEG-2 Transport Stream Byte Streams</a><ul class="toc"><li class="tocline"><a href="#mpeg2ts-general" class="tocxref"><span class="secno">10.3.1 </span>General</a></li><li class="tocline"><a href="#mpeg2ts-init-segments" class="tocxref"><span class="secno">10.3.2 </span>Initialization Segments</a></li><li class="tocline"><a href="#mpeg2ts-media-segments" class="tocxref"><span class="secno">10.3.3 </span>Media Segments</a></li><li class="tocline"><a href="#mpeg2ts-random-access-points" class="tocxref"><span class="secno">10.3.4 </span>Random Access Points</a></li><li class="tocline"><a href="#mpeg2ts-discontinuities" class="tocxref"><span class="secno">10.3.5 </span>Timestamp Rollover & Discontinuities</a></li></ul></li></ul></li><li class="tocline"><a href="#examples" class="tocxref"><span class="secno">11. </span>Examples</a></li><li class="tocline"><a href="#revision-history" class="tocxref"><span class="secno">12. </span>Revision History</a></li><li class="tocline"><a href="#references" class="tocxref"><span class="secno">A. </span>References</a><ul class="toc"><li class="tocline"><a href="#informative-references" class="tocxref"><span class="secno">A.1 </span>Informative references</a></li></ul></li></ul></section>
+</section><section id="toc"><h2 class="introductory">Table of Contents</h2><ul class="toc"><li class="tocline"><a href="#introduction" class="tocxref"><span class="secno">1. </span>Introduction</a><ul class="toc"><li class="tocline"><a href="#goals" class="tocxref"><span class="secno">1.1 </span>Goals</a></li><li class="tocline"><a href="#definitions" class="tocxref"><span class="secno">1.2 </span>Definitions</a></li></ul></li><li class="tocline"><a href="#mediasource" class="tocxref"><span class="secno">2. </span>MediaSource Object</a><ul class="toc"><li class="tocline"><a href="#attributes" class="tocxref"><span class="secno">2.1 </span>Attributes</a></li><li class="tocline"><a href="#methods" class="tocxref"><span class="secno">2.2 </span>Methods</a></li><li class="tocline"><a href="#mediasource-events" class="tocxref"><span class="secno">2.3 </span>Event Summary</a></li><li class="tocline"><a href="#mediasource-algorithms" class="tocxref"><span class="secno">2.4 </span>Algorithms</a><ul class="toc"><li class="tocline"><a href="#mediasource-attach" class="tocxref"><span class="secno">2.4.1 </span>Attaching to a media element</a></li><li class="tocline"><a href="#mediasource-detach" class="tocxref"><span class="secno">2.4.2 </span>Detaching from a media element</a></li><li class="tocline"><a href="#mediasource-seeking" class="tocxref"><span class="secno">2.4.3 </span>Seeking</a></li><li class="tocline"><a href="#buffer-monitoring" class="tocxref"><span class="secno">2.4.4 </span>SourceBuffer Monitoring</a></li><li class="tocline"><a href="#active-source-buffer-changes" class="tocxref"><span class="secno">2.4.5 </span>Changes to selected/enabled track state</a></li><li class="tocline"><a href="#duration-change-algorithm" class="tocxref"><span class="secno">2.4.6 </span>Duration change</a></li></ul></li></ul></li><li class="tocline"><a href="#sourcebuffer" class="tocxref"><span class="secno">3. </span>SourceBuffer Object</a><ul class="toc"><li class="tocline"><a href="#attributes-1" class="tocxref"><span class="secno">3.1 </span>Attributes</a></li><li class="tocline"><a href="#methods-1" class="tocxref"><span class="secno">3.2 </span>Methods</a></li><li class="tocline"><a href="#track-buffers" class="tocxref"><span class="secno">3.3 </span>Track Buffers</a></li><li class="tocline"><a href="#sourcebuffer-events" class="tocxref"><span class="secno">3.4 </span>Event Summary</a></li><li class="tocline"><a href="#sourcebuffer-algorithms" class="tocxref"><span class="secno">3.5 </span>Algorithms</a><ul class="toc"><li class="tocline"><a href="#sourcebuffer-segment-parser-loop" class="tocxref"><span class="secno">3.5.1 </span>Segment Parser Loop</a></li><li class="tocline"><a href="#sourcebuffer-reset-parser-state" class="tocxref"><span class="secno">3.5.2 </span>Reset Parser State</a></li><li class="tocline"><a href="#sourcebuffer-append-error" class="tocxref"><span class="secno">3.5.3 </span>Append Error</a></li><li class="tocline"><a href="#sourcebuffer-stream-append-loop" class="tocxref"><span class="secno">3.5.4 </span>Stream Append Loop</a></li><li class="tocline"><a href="#sourcebuffer-init-segment-received" class="tocxref"><span class="secno">3.5.5 </span>Initialization Segment Received</a></li><li class="tocline"><a href="#sourcebuffer-coded-frame-processing" class="tocxref"><span class="secno">3.5.6 </span>Coded Frame Processing</a></li><li class="tocline"><a href="#sourcebuffer-coded-frame-removal" class="tocxref"><span class="secno">3.5.7 </span>Coded Frame Removal Algorithm</a></li><li class="tocline"><a href="#sourcebuffer-coded-frame-eviction" class="tocxref"><span class="secno">3.5.8 </span>Coded Frame Eviction Algorithm</a></li><li class="tocline"><a href="#sourcebuffer-audio-splice-frame-algorithm" class="tocxref"><span class="secno">3.5.9 </span>Audio Splice Frame Algorithm</a></li><li class="tocline"><a href="#sourcebuffer-audio-splice-rendering-algorithm" class="tocxref"><span class="secno">3.5.10 </span>Audio Splice Rendering Algorithm</a></li></ul></li></ul></li><li class="tocline"><a href="#sourcebufferlist" class="tocxref"><span class="secno">4. </span>SourceBufferList Object</a><ul class="toc"><li class="tocline"><a href="#attributes-2" class="tocxref"><span class="secno">4.1 </span>Attributes</a></li><li class="tocline"><a href="#methods-2" class="tocxref"><span class="secno">4.2 </span>Methods</a></li><li class="tocline"><a href="#sourcebufferlist-events" class="tocxref"><span class="secno">4.3 </span>Event Summary</a></li></ul></li><li class="tocline"><a href="#url" class="tocxref"><span class="secno">5. </span>URL Object</a><ul class="toc"><li class="tocline"><a href="#methods-3" class="tocxref"><span class="secno">5.1 </span>Methods</a></li></ul></li><li class="tocline"><a href="#htmlmediaelement-attributes" class="tocxref"><span class="secno">6. </span>HTMLMediaElement attributes</a></li><li class="tocline"><a href="#audio-track-extensions" class="tocxref"><span class="secno">7. </span>AudioTrack Extensions</a><ul class="toc"><li class="tocline"><a href="#attributes-3" class="tocxref"><span class="secno">7.1 </span>Attributes</a></li></ul></li><li class="tocline"><a href="#video-track-extensions" class="tocxref"><span class="secno">8. </span>VideoTrack Extensions</a><ul class="toc"><li class="tocline"><a href="#attributes-4" class="tocxref"><span class="secno">8.1 </span>Attributes</a></li></ul></li><li class="tocline"><a href="#text-track-extensions" class="tocxref"><span class="secno">9. </span>TextTrack Extensions</a><ul class="toc"><li class="tocline"><a href="#attributes-5" class="tocxref"><span class="secno">9.1 </span>Attributes</a></li></ul></li><li class="tocline"><a href="#byte-stream-formats" class="tocxref"><span class="secno">10. </span>Byte Stream Formats</a><ul class="toc"><li class="tocline"><a href="#webm" class="tocxref"><span class="secno">10.1 </span>WebM Byte Streams</a><ul class="toc"><li class="tocline"><a href="#webm-init-segments" class="tocxref"><span class="secno">10.1.1 </span>Initialization Segments</a></li><li class="tocline"><a href="#webm-media-segments" class="tocxref"><span class="secno">10.1.2 </span>Media Segments</a></li><li class="tocline"><a href="#webm-random-access-points" class="tocxref"><span class="secno">10.1.3 </span>Random Access Points</a></li></ul></li><li class="tocline"><a href="#iso" class="tocxref"><span class="secno">10.2 </span>ISO Base Media File Format Byte Streams</a><ul class="toc"><li class="tocline"><a href="#iso-init-segments" class="tocxref"><span class="secno">10.2.1 </span>Initialization Segments</a></li><li class="tocline"><a href="#iso-media-segments" class="tocxref"><span class="secno">10.2.2 </span>Media Segments</a></li><li class="tocline"><a href="#iso-random-access-points" class="tocxref"><span class="secno">10.2.3 </span>Random Access Points</a></li></ul></li><li class="tocline"><a href="#mpeg2ts" class="tocxref"><span class="secno">10.3 </span>MPEG-2 Transport Stream Byte Streams</a><ul class="toc"><li class="tocline"><a href="#mpeg2ts-general" class="tocxref"><span class="secno">10.3.1 </span>General</a></li><li class="tocline"><a href="#mpeg2ts-init-segments" class="tocxref"><span class="secno">10.3.2 </span>Initialization Segments</a></li><li class="tocline"><a href="#mpeg2ts-media-segments" class="tocxref"><span class="secno">10.3.3 </span>Media Segments</a></li><li class="tocline"><a href="#mpeg2ts-random-access-points" class="tocxref"><span class="secno">10.3.4 </span>Random Access Points</a></li><li class="tocline"><a href="#mpeg2ts-discontinuities" class="tocxref"><span class="secno">10.3.5 </span>Timestamp Rollover & Discontinuities</a></li></ul></li></ul></li><li class="tocline"><a href="#examples" class="tocxref"><span class="secno">11. </span>Examples</a></li><li class="tocline"><a href="#revision-history" class="tocxref"><span class="secno">12. </span>Revision History</a></li><li class="tocline"><a href="#references" class="tocxref"><span class="secno">A. </span>References</a><ul class="toc"><li class="tocline"><a href="#informative-references" class="tocxref"><span class="secno">A.1 </span>Informative references</a></li></ul></li></ul></section>
<section id="introduction">
@@ -573,9 +573,16 @@
<dt id="append-sequence">Append Sequence</dt>
<dd>A series of <code><a href="#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data">appendBuffer()</a></code> or <code><a href="#widl-SourceBuffer-appendStream-void-Stream-stream-unsigned-long-long-maxSize">appendStream()</a></code> calls on a <a href="#idl-def-SourceBuffer" class="idlType"><code>SourceBuffer</code></a> without any intervening <code><a href="#widl-SourceBuffer-abort-void-AbortMode-mode">abort()</a></code> calls. The
- <a href="#media-segment">media segments</a> in an append sequence must be adjacent and monotonically increasing in time without any gaps. An
- <code><a href="#widl-SourceBuffer-abort-void-AbortMode-mode">abort()</a></code> call starts a new append sequence which allows <a href="#media-segment">media segments</a> to be appended in non-monotonically
- increasing order.</dd>
+ <a href="#media-segment">media segments</a> in an append sequence must be adjacent and monotonically increasing in time without any gaps. An
+ <code><a href="#widl-SourceBuffer-abort-void-AbortMode-mode">abort()</a></code> call starts a new append sequence which allows <a href="#media-segment">media segments</a> to be appended in non-monotonically
+ increasing order.
+ </dd>
+
+ <dt id="append-window">Append Window</dt>
+ <dd>A presentation timestamp range used to filter out <a href="#coded-frame">coded frames</a> while appending. The append window represents a single
+ continuous time range with a single start time and end time. Coded frames with presentation timestamps within this range are allowed to be appended
+ to the <a href="#idl-def-SourceBuffer" class="idlType"><code>SourceBuffer</code></a> while coded frames outside this range are filtered out. The append window start and end times are controlled by
+ the <code><a href="#widl-SourceBuffer-appendWindowStart">appendWindowStart</a></code> and <code><a href="#widl-SourceBuffer-appendWindowEnd">appendWindowEnd</a></code> attributes respectively.</dd>
</dl>
</section>
</section>
@@ -1037,12 +1044,38 @@
<span class="idlAttribute"> readonly attribute <span class="idlAttrType"><a>AudioTrackList</a></span> <span class="idlAttrName"><a href="#widl-SourceBuffer-audioTracks">audioTracks</a></span>;</span>
<span class="idlAttribute"> readonly attribute <span class="idlAttrType"><a>VideoTrackList</a></span> <span class="idlAttrName"><a href="#widl-SourceBuffer-videoTracks">videoTracks</a></span>;</span>
<span class="idlAttribute"> readonly attribute <span class="idlAttrType"><a>TextTrackList</a></span> <span class="idlAttrName"><a href="#widl-SourceBuffer-textTracks">textTracks</a></span>;</span>
+<span class="idlAttribute"> attribute <span class="idlAttrType"><a>double</a></span> <span class="idlAttrName"><a href="#widl-SourceBuffer-appendWindowStart">appendWindowStart</a></span>;</span>
+<span class="idlAttribute"> attribute <span class="idlAttrType"><a>double</a></span> <span class="idlAttrName"><a href="#widl-SourceBuffer-appendWindowEnd">appendWindowEnd</a></span>;</span>
<span class="idlMethod"> <span class="idlMethType"><a>void</a></span> <span class="idlMethName"><a href="#widl-SourceBuffer-appendBuffer-void-ArrayBuffer-data">appendBuffer</a></span> (<span class="idlParam"><span class="idlParamType"><a>ArrayBuffer</a></span> <span class="idlParamName">data</span></span>);</span>
<span class="idlMethod"> <span class="idlMethType"><a>void</a></span> <span class="idlMethName"><a href="#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data">appendBuffer</a></span> (<span class="idlParam"><span class="idlParamType"><a>ArrayBufferView</a></span> <span class="idlParamName">data</span></span>);</span>
<span class="idlMethod"> <span class="idlMethType"><a>void</a></span> <span class="idlMethName"><a href="#widl-SourceBuffer-appendStream-void-Stream-stream-unsigned-long-long-maxSize">appendStream</a></span> (<span class="idlParam"><span class="idlParamType"><a>Stream</a></span> <span class="idlParamName">stream</span></span>, <span class="idlParam">optional <span class="idlParamType"><a>unsigned long long</a></span> <span class="idlParamName">maxSize</span></span>);</span>
<span class="idlMethod"> <span class="idlMethType"><a>void</a></span> <span class="idlMethName"><a href="#widl-SourceBuffer-abort-void-AbortMode-mode">abort</a></span> (<span class="idlParam">optional <span class="idlParamType"><a href="#idl-def-AbortMode" class="idlType"><code>AbortMode</code></a></span> <span class="idlParamName">mode</span></span>);</span>
<span class="idlMethod"> <span class="idlMethType"><a>void</a></span> <span class="idlMethName"><a href="#widl-SourceBuffer-remove-void-double-start-double-end">remove</a></span> (<span class="idlParam"><span class="idlParamType"><a>double</a></span> <span class="idlParamName">start</span></span>, <span class="idlParam"><span class="idlParamType"><a>double</a></span> <span class="idlParamName">end</span></span>);</span>
-};</span></pre><section id="attributes-1"><h3><span class="secno">3.1 </span>Attributes</h3><dl class="attributes"><dt id="widl-SourceBuffer-audioTracks"><code>audioTracks</code> of type <span class="idlAttrType"><a>AudioTrackList</a></span>, readonly</dt><dd>
+};</span></pre><section id="attributes-1"><h3><span class="secno">3.1 </span>Attributes</h3><dl class="attributes"><dt id="widl-SourceBuffer-appendWindowEnd"><code>appendWindowEnd</code> of type <span class="idlAttrType"><a>double</a></span></dt><dd>
+ <p>The presentation timestamp for the end of the <a href="#append-window">append window</a>. This attribute is initially set to positive Infinity.</p>
+ <p>On getting, Return the initial value or the last value that was successfully set.</p>
+ <p>On setting, run the following steps:</p>
+ <ol>
+ <li>If this object has been removed from the <code><a href="#widl-MediaSource-sourceBuffers">sourceBuffers</a></code> attribute of the <a href="#parent-media-source">parent media source</a>, then throw an
+ <code><a href="http://dom.spec.whatwg.org/#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
+ <li>If the <code><a href="#widl-SourceBuffer-updating">updating</a></code> attribute equals true, then throw an <code><a href="http://dom.spec.whatwg.org/#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
+ <li>If the new value is less than or equal to <code><a href="#widl-SourceBuffer-appendWindowStart">appendWindowStart</a></code> then throw an <code><a href="http://dom.spec.whatwg.org/#dom-domexception-invalid_access_err">INVALID_ACCESS_ERR</a></code> exception and abort these
+ steps.</li>
+ <li>Update the attribute to the new value.</li>
+ </ol>
+ </dd><dt id="widl-SourceBuffer-appendWindowStart"><code>appendWindowStart</code> of type <span class="idlAttrType"><a>double</a></span></dt><dd>
+ <p>The presentation timestamp for the start of the <a href="#append-window">append window</a>. This attribute is initially set to 0.</p>
+ <p>On getting, Return the initial value or the last value that was successfully set.</p>
+ <p>On setting, run the following steps:</p>
+ <ol>
+ <li>If this object has been removed from the <code><a href="#widl-MediaSource-sourceBuffers">sourceBuffers</a></code> attribute of the <a href="#parent-media-source">parent media source</a>, then throw an
+ <code><a href="http://dom.spec.whatwg.org/#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
+ <li>If the <code><a href="#widl-SourceBuffer-updating">updating</a></code> attribute equals true, then throw an <code><a href="http://dom.spec.whatwg.org/#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code> exception and abort these steps.</li>
+ <li>If the new value is less than 0 or greater than or equal to <code><a href="#widl-SourceBuffer-appendWindowEnd">appendWindowEnd</a></code> then throw an <code><a href="http://dom.spec.whatwg.org/#dom-domexception-invalid_access_err">INVALID_ACCESS_ERR</a></code> exception
+ and abort these steps.</li>
+ <li>Update the attribute to the new value.</li>
+ </ol>
+ </dd><dt id="widl-SourceBuffer-audioTracks"><code>audioTracks</code> of type <span class="idlAttrType"><a>AudioTrackList</a></span>, readonly</dt><dd>
The list of <code><a href="http://www.w3.org/TR/html5/embedded-content-0.html#audiotrack">AudioTrack</a></code> objects created by this object.
</dd><dt id="widl-SourceBuffer-buffered"><code>buffered</code> of type <span class="idlAttrType"><a>TimeRanges</a></span>, readonly</dt><dd>
<p>Indicates what <code><a href="http://www.w3.org/TR/html5/embedded-content-0.html#timeranges">TimeRanges</a></code> are buffered in the <a href="#idl-def-SourceBuffer" class="idlType"><code>SourceBuffer</code></a>.</p>
@@ -1108,6 +1141,8 @@
<dd>Update the <var><a href="#sourcebuffer-abort-mode">abort mode</a></var> to equal <var>mode</var>.</dd>
</dl>
</li>
+ <li>Set <code><a href="#widl-SourceBuffer-appendWindowStart">appendWindowStart</a></code> to 0.</li>
+ <li>Set <code><a href="#widl-SourceBuffer-appendWindowEnd">appendWindowEnd</a></code> to positive Infinity.</li>
<li>Run the <a href="#sourcebuffer-reset-parser-state">reset parser state algorithm</a>.</li>
</ol></dd><dt id="widl-SourceBuffer-appendBuffer-void-ArrayBuffer-data"><code>appendBuffer</code></dt><dd>
<p>Appends the segment data in an ArrayBuffer to the source buffer.</p>
@@ -1129,9 +1164,11 @@
<a href="http://www.w3.org/TR/html5/webappapis.html#queue-a-task">Queue a task</a> to <a href="http://www.w3.org/TR/html5/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-evt-sourceopen">sourceopen</a></code> at the <a href="#parent-media-source">parent media source</a> .</li>
</ol>
</li>
+ <li>Run the <a href="#sourcebuffer-coded-frame-eviction">coded frame eviction algorithm</a>.</li>
<li>
<p>If the <var><a href="#sourcebuffer-buffer-full-flag">buffer full flag</a></var> equals true, then throw a <code><a href="http://dom.spec.whatwg.org/#dom-domexception-quota_exceeded_err">QUOTA_EXCEEDED_ERR</a></code> exception and abort these step.</p>
- <div class="note"><div class="note-title"><span>Note</span></div><p class="">The web application must use <code><a href="#widl-SourceBuffer-remove-void-double-start-double-end">remove()</a></code> to free up space in the <a href="#idl-def-SourceBuffer" class="idlType"><code>SourceBuffer</code></a>.</p></div>
+ <div class="note"><div class="note-title"><span>Note</span></div><p class="">This is the signal that the implementation was unable to evict enough data to accomodate the append or the append is too big. The web
+ application must use <code><a href="#widl-SourceBuffer-remove-void-double-start-double-end">remove()</a></code> to explicitly free up space and/or reduce the size of the append.</p></div>
</li>
<li>Add <var>data</var> to the end of the <var><a href="#sourcebuffer-input-buffer">input buffer</a></var>.</li>
<li>Set the <code><a href="#widl-SourceBuffer-updating">updating</a></code> attribute to true.</li>
@@ -1159,9 +1196,11 @@
<li><a href="http://www.w3.org/TR/html5/webappapis.html#queue-a-task">Queue a task</a> to <a href="http://www.w3.org/TR/html5/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-evt-sourceopen">sourceopen</a></code> at the <a href="#parent-media-source">parent media source</a> .</li>
</ol>
</li>
+ <li>Run the <a href="#sourcebuffer-coded-frame-eviction">coded frame eviction algorithm</a>.</li>
<li>
<p>If the <var><a href="#sourcebuffer-buffer-full-flag">buffer full flag</a></var> equals true, then throw a <code><a href="http://dom.spec.whatwg.org/#dom-domexception-quota_exceeded_err">QUOTA_EXCEEDED_ERR</a></code> exception and abort these step.</p>
- <div class="note"><div class="note-title"><span>Note</span></div><p class="">The web application must use <code><a href="#widl-SourceBuffer-remove-void-double-start-double-end">remove()</a></code> to free up space in the <a href="#idl-def-SourceBuffer" class="idlType"><code>SourceBuffer</code></a>.</p></div>
+ <div class="note"><div class="note-title"><span>Note</span></div><p class="">This is the signal that the implementation was unable to evict enough data to accomodate the append or the append is too big. The web
+ application must use <code><a href="#widl-SourceBuffer-remove-void-double-start-double-end">remove()</a></code> to explicitly free up space and/or reduce the size of the append.</p></div>
</li>
<li>Set the <code><a href="#widl-SourceBuffer-updating">updating</a></code> attribute to true.</li>
<li><a href="http://www.w3.org/TR/html5/webappapis.html#queue-a-task">Queue a task</a> to <a href="http://www.w3.org/TR/html5/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-evt-updatestart">updatestart</a></code> at this <a href="#idl-def-SourceBuffer" class="idlType"><code>SourceBuffer</code></a> object.</li>
@@ -1180,23 +1219,7 @@
<li>Set the <code><a href="#widl-SourceBuffer-updating">updating</a></code> attribute to true.</li>
<li><a href="http://www.w3.org/TR/html5/webappapis.html#queue-a-task">Queue a task</a> to <a href="http://www.w3.org/TR/html5/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-evt-updatestart">updatestart</a></code> at this <a href="#idl-def-SourceBuffer" class="idlType"><code>SourceBuffer</code></a> object.</li>
<li>Return control to the caller and run the rest of the steps asynchronously.</li>
- <li>
- <p>For each <a href="#track-buffer">track buffer</a> in this source buffer, run the following steps:</p>
- <ol>
- <li>Let <var>remove end timestamp</var> be the current value of <code><a href="#widl-MediaSource-duration">duration</a></code></li>
- <li>
- <p>If this <a href="#track-buffer">track buffer</a> has a <a href="#random-access-point">random access point</a> timestamp that is greater than or equal to <var>end</var>, then update <var>remove end timestamp</var> to that timestamp.</p>
- <div class="note"><div class="note-title"><span>Note</span></div><p class="">Random access point timestamps 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></div>
- </li>
- <li>Remove all media data, from this <a href="#track-buffer">track buffer</a>, that contain starting timestamps greater than or equal to <var>start</var> and less than the <var>remove end timestamp</var>.</li>
- <li>
- <p>If this object is in <code><a href="#widl-MediaSource-activeSourceBuffers">activeSourceBuffers</a></code>, the <a href="http://www.w3.org/TR/html5/embedded-content-0.html#current-playback-position">current playback position</a> is greater than or equal to <var>start</var> and less than the <var>remove end timestamp</var>, and <code><a href="http://www.w3.org/TR/html5/embedded-content-0.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> is greater than <code><a href="http://www.w3.org/TR/html5/embedded-content-0.html#dom-media-have_metadata">HAVE_METADATA</a></code>, then set the <code><a href="http://www.w3.org/TR/html5/embedded-content-0.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute to <code><a href="http://www.w3.org/TR/html5/embedded-content-0.html#dom-media-have_metadata">HAVE_METADATA</a></code> and stall playback.</p>
- <div class="note"><div class="note-title"><span>Note</span></div><p class="">This transition occurs because media data for the current position has been removed. Playback cannot progress until media for the <a href="http://www.w3.org/TR/html5/embedded-content-0.html#current-playback-position">current playback position</a> is appended or the <a href="#active-source-buffer-changes">selected/enabled tracks change</a>.</p></div>
- </li>
- </ol>
- </li>
- <li>If <var><a href="#sourcebuffer-buffer-full-flag">buffer full flag</a></var> equals true and this object is ready to accept more bytes, then set
- the <var><a href="#sourcebuffer-buffer-full-flag">buffer full flag</a></var> to false.</li>
+ <li>Run the <a href="#sourcebuffer-coded-frame-removal">coded frame removal algorithm</a> with <var>start</var> and <var>end</var> as the start and end of the removal range.</li>
<li>Set the <code><a href="#widl-SourceBuffer-updating">updating</a></code> attribute to false.</li>
<li><a href="http://www.w3.org/TR/html5/webappapis.html#queue-a-task">Queue a task</a> to <a href="http://www.w3.org/TR/html5/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-evt-update">update</a></code> at this <a href="#idl-def-SourceBuffer" class="idlType"><code>SourceBuffer</code></a> object.</li>
<li><a href="http://www.w3.org/TR/html5/webappapis.html#queue-a-task">Queue a task</a> to <a href="http://www.w3.org/TR/html5/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-evt-updateend">updateend</a></code> at this <a href="#idl-def-SourceBuffer" class="idlType"><code>SourceBuffer</code></a> object.</li>
@@ -1398,10 +1421,6 @@
<li>If <var>maxSize</var> is set, then let <var>bytesLeft</var> equal <var>maxSize</var>.</li>
<li><i>Loop Top: </i>If <var>maxSize</var> is set and <var>bytesLeft</var> equals 0, then jump to the <i>loop done</i> step below.</li>
<li>If <var>stream</var> has been closed, then jump to the <i>loop done</i> step below.</li>
- <li>
- <p>If the <var><a href="#sourcebuffer-buffer-full-flag">buffer full flag</a></var> equals true, then run the <a href="#sourcebuffer-append-error">append error algorithm</a> and abort this algorithm.</p>
- <div class="note"><div class="note-title"><span>Note</span></div><p class="">The web application must use <code><a href="#widl-SourceBuffer-remove-void-double-start-double-end">remove()</a></code> to free up space in the <a href="#idl-def-SourceBuffer" class="idlType"><code>SourceBuffer</code></a>.</p></div>
- </li>
<li>Read data from <var>stream</var> into <var>data</var>:
<dl class="switch">
<dt>If <var>maxSize</var> is set:</dt>
@@ -1415,6 +1434,11 @@
</dl>
</li>
<li>If an error occured while reading from <var>stream</var>, then run the <a href="#sourcebuffer-append-error">append error algorithm</a> and abort this algorithm.</li>
+ <li>Run the <a href="#sourcebuffer-coded-frame-eviction">coded frame eviction algorithm</a>.</li>
+ <li>
+ <p>If the <var><a href="#sourcebuffer-buffer-full-flag">buffer full flag</a></var> equals true, then run the <a href="#sourcebuffer-append-error">append error algorithm</a> and abort this algorithm.</p>
+ <div class="note"><div class="note-title"><span>Note</span></div><p class="">The web application must use <code><a href="#widl-SourceBuffer-remove-void-double-start-double-end">remove()</a></code> to free up space in the <a href="#idl-def-SourceBuffer" class="idlType"><code>SourceBuffer</code></a>.</p></div>
+ </li>
<li>Add <var>data</var> to the end of the <var><a href="#sourcebuffer-input-buffer">input buffer</a></var>.</li>
<li>Run the <a href="#sourcebuffer-segment-parser-loop">segment parser loop</a> algorithm.</li>
<li>Jump to the <i>loop top</i> step above.</li>
@@ -1607,9 +1631,18 @@
<div class="note"><div class="note-title"><span>Note</span></div><p class="">These checks trigger an error when the application attempts out-of-order appends without an intervening
<code><a href="#widl-SourceBuffer-abort-void-AbortMode-mode">abort()</a></code>.</p></div>
</li>
-
<li>Let <var>frame end timestamp</var> equal the sum of <var>presentation timestamp</var> and <var>frame duration</var>.</li>
- <li>If the <var><a href="#need-RAP-flag">need random access point flag</a></var> on <var>track buffer</var> equals true, then run the following steps:
+ <li>If <var>presentation timestamp</var> is less than <code><a href="#widl-SourceBuffer-appendWindowStart">appendWindowStart</a></code>, then set the <var><a href="#need-RAP-flag">need random access point flag</a></var> to true, drop the
+ coded frame, and jump to the top of the loop to start processing the next coded frame.
+ <div class="note"><div class="note-title"><span>Note</span></div><p class="">Some implementations may choose to collect some of these coded frames that are outside the <a href="#append-window">append window</a> and use them
+ to generate a splice at the first coded frame that has a presentation timestamp greater than or equal to <code><a href="#widl-SourceBuffer-appendWindowStart">appendWindowStart</a></code> even if
+ that frame is not a <a href="#random-access-point">random access point</a>. Supporting this requires multiple decoders or faster than real-time decoding so for now
+ this behavior will not be a normative requirement.
+ </p></div>
+ </li>
+ <li>If <var>frame end timestamp</var> is greater than <code><a href="#widl-SourceBuffer-appendWindowEnd">appendWindowEnd</a></code>, then set the <var><a href="#need-RAP-flag">need random access point flag</a></var> to true, drop the
+ coded frame, and jump to the top of the loop to start processing the next coded frame.
+ </li><li>If the <var><a href="#need-RAP-flag">need random access point flag</a></var> on <var>track buffer</var> equals true, then run the following steps:
<ol>
<li>If the coded frame is not a <a href="#random-access-point">random access point</a>, then drop the coded frame and jump to the top of the loop to start
processing the next coded frame.</li>
@@ -1617,15 +1650,19 @@
</ol>
</li>
<li>Let <var>spliced frame</var> be an unset variable for holding audio splice information</li>
- <li>If <var><a href="#last-decode-timestamp">last decode timestamp</a></var> for <var>track buffer</var> is unset and <var>presentation timestamp</var> lies within a
- <a href="#coded-frame">coded frame</a> already stored in <var>track buffer</var>, then run the following steps:
+ <li>If <var><a href="#last-decode-timestamp">last decode timestamp</a></var> for <var>track buffer</var> is unset and there is a <a href="#coded-frame">coded frame</a> in
+ <var>track buffer</var> with a presentation timestamp less than or equal to <var>presentation timestamp</var> and
+ <var>presentation timestamp</var> is less than this coded frame's presentation timestamp plus its frame duration, then run the
+ following steps:
<ol>
- <li>Let <var>overlapped frame</var> be the <a href="#coded-frame">coded frame</a> in <var>track buffer</var> that contains <var>presentation timestamp</var>.</li>
+ <li>Let <var>overlapped frame</var> be the <a href="#coded-frame">coded frame</a> in <var>track buffer</var> that matches the condition above.</li>
<li>If <var>track buffer</var> contains audio <a href="#coded-frame">coded frames</a>, then run the <a href="#sourcebuffer-audio-splice-frame-algorithm">audio splice frame algorithm</a> and if a splice
frame is returned, assign it to <var>spliced frame</var>.</li>
- <li>If <var>track buffer</var> contains video <a href="#coded-frame">coded frames</a> and <var>presentation timestamp</var> is less than 1 microsecond
- beyond the presentation timestamp of <var>overlapped frame</var>, then remove <var>overlapped frame</var> and any
- <a href="#coded-frame">coded frames</a> that depend on it from <var>track buffer</var>.
+ <li>Let <var>overlapped frame presentation timestamp</var> equal the presentation timestamp of <var>overlapped frame</var>.</li>
+ <li>Let <var>remove window timestamp</var> equal <var>overlapped frame presentation timestamp</var> plus 1 microsecond.</li>
+ <li>If <var>track buffer</var> contains video <a href="#coded-frame">coded frames</a> and the <var>presentation timestamp</var> is greater than or equal to
+ the <var>overlapped frame presentation timestamp</var> and the <var>presentation timestamp</var> is less than the <var>remove window timestamp</var>,
+ then remove <var>overlapped frame</var> and any <a href="#coded-frame">coded frames</a> that depend on it from <var>track buffer</var>.
<div class="note"><div class="note-title"><span>Note</span></div><p class="">
This is to compensate for minor errors in frame timestamp computations that can appear when converting back and forth between double precision
floating point numbers and rationals. This tolerance allows a frame to replace an existing one as long as it is within 1 microsecond of the existing
@@ -1696,8 +1733,56 @@
</ol>
</section>
+ <section id="sourcebuffer-coded-frame-removal">
+ <h4><span class="secno">3.5.7 </span>Coded Frame Removal Algorithm</h4>
+ <p>Follow these steps when <a href="#coded-frame">coded frames</a> for a specific time range need to be removed from the SourceBuffer:</p>
+ <ol>
+ <li>Let <var>start</var> be the starting presentation timestamp for the removal range.</li>
+ <li>Let <var>end</var> be the end presentation timestamp for the removal range. </li>
+ <li><p>For each <a href="#track-buffer">track buffer</a> in this source buffer, run the following steps:</p>
+ <ol>
+ <li>Let <var>remove end timestamp</var> be the current value of <code><a href="#widl-MediaSource-duration">duration</a></code></li>
+ <li>
+ <p>If this <a href="#track-buffer">track buffer</a> has a <a href="#random-access-point">random access point</a> timestamp that is greater than or equal to
+ <var>end</var>, then update <var>remove end timestamp</var> to that random access point timestamp.</p>
+ <div class="note"><div class="note-title"><span>Note</span></div><p class="">Random access point timestamps 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></div>
+ </li>
+ <li>Remove all media data, from this <a href="#track-buffer">track buffer</a>, that contain starting timestamps greater than or equal to
+ <var>start</var> and less than the <var>remove end timestamp</var>.</li>
+ <li>
+ <p>If this object is in <code><a href="#widl-MediaSource-activeSourceBuffers">activeSourceBuffers</a></code>, the <a href="http://www.w3.org/TR/html5/embedded-content-0.html#current-playback-position">current playback position</a> is greater than or equal to
+ <var>start</var> and less than the <var>remove end timestamp</var>, and <code><a href="http://www.w3.org/TR/html5/embedded-content-0.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> is greater than
+ <code><a href="http://www.w3.org/TR/html5/embedded-content-0.html#dom-media-have_metadata">HAVE_METADATA</a></code>, then set the <code><a href="http://www.w3.org/TR/html5/embedded-content-0.html#dom-media-readystate">HTMLMediaElement.readyState</a></code> attribute to <code><a href="http://www.w3.org/TR/html5/embedded-content-0.html#dom-media-have_metadata">HAVE_METADATA</a></code> and stall playback.</p>
+ <div class="note"><div class="note-title"><span>Note</span></div><p class="">This transition occurs because media data for the current position has been removed. Playback cannot progress until media for the
+ <a href="http://www.w3.org/TR/html5/embedded-content-0.html#current-playback-position">current playback position</a> is appended or the <a href="#active-source-buffer-changes">selected/enabled tracks change</a>.</p></div>
+ </li>
+ </ol>
+ </li>
+ <li>If <var><a href="#sourcebuffer-buffer-full-flag">buffer full flag</a></var> equals true and this object is ready to accept more bytes, then set
+ the <var><a href="#sourcebuffer-buffer-full-flag">buffer full flag</a></var> to false.</li>
+ </ol>
+ </section>
+
+ <section id="sourcebuffer-coded-frame-eviction">
+ <h4><span class="secno">3.5.8 </span>Coded Frame Eviction Algorithm</h4>
+ <p>This algorithm is run to free up space in this source buffer when new data is appended.</p>
+ <ol>
+ <li>Let <var>new data</var> equal the data that is about to be appended to this SourceBuffer.</li>
+ <li>If the <var><a href="#sourcebuffer-buffer-full-flag">buffer full flag</a></var> equals false, then abort these steps.</li>
+ <li>Let <var>removal ranges</var> equal a list of presentation time ranges that can be evicted from the presentation to make room for the
+ <var>new data</var>.
+ <div class="note"><div class="note-title"><span>Note</span></div><p class="">Implementations may use different methods for selecting <var>removal ranges</var> so web applications must not depend on a
+ specific behavior. The web application can use the <code><a href="#widl-SourceBuffer-buffered">buffered</a></code> attribute to observe whether portions of the buffered data have been evicted.
+ </p></div>
+ </li>
+ <li>For each range in <var>removal ranges</var>, run the <a href="#sourcebuffer-coded-frame-removal">coded frame removal algorithm</a> with <var>start</var> and <var>end</var> equal to
+ the removal range start and end timestamp respectively.</li>
+ </ol>
+ </section>
+
<section id="sourcebuffer-audio-splice-frame-algorithm">
- <h4><span class="secno">3.5.7 </span>Audio Splice Frame Algorithm</h4>
+ <h4><span class="secno">3.5.9 </span>Audio Splice Frame Algorithm</h4>
<p>Follow these steps when the <a href="#sourcebuffer-coded-frame-processing">coded frame processing algorithm</a> needs to generate a splice frame for two overlapping audio
<a href="#coded-frame">coded frames</a>:</p>
<ol>
@@ -1706,9 +1791,12 @@
<li>Let <var>presentation timestamp</var> be the presentation timestamp for <var>new coded frame</var></li>
<li>Let <var>decode timestamp</var> be the decode timestamp for <var>new coded frame</var>.</li>
<li>Let <var>frame duration</var> be the duration of <var>new coded frame</var>.</li>
- <li>Let <var>overlapped frame</var> be the <a href="#coded-frame">coded frame</a> in <var>track buffer</var> that overlaps with <var>new coded frame</var>
- (ie. it contains <var>presentation timestamp).</var></li>
- <li>Round & update <var>presentation timestamp</var> and <var>decode timestamp</var> to the nearest audio sample timestamp based on sample rate of the audio in <var>overlapped frame</var>.
+ <li>Let <var>overlapped frame</var> be the <a href="#coded-frame">coded frame</a> in <var>track buffer</var> with a presentation timestamp less than or equal to
+ <var>presentation timestamp</var> and <var>presentation timestamp</var> is less than this coded frame's presentation timestamp plus its frame duration.
+ </li>
+ <li>Update <var>presentation timestamp</var> and <var>decode timestamp</var> to the nearest audio sample timestamp based on sample rate of the
+ audio in <var>overlapped frame</var>. If a timestamp is equidistant from both audio sample timestamps, then use the higher timestamp. (eg.
+ floor(x * sample_rate + 0.5) / sample_rate).
<div class="note"><div class="note-title"><span>Note</span></div><div class="">
<p>For example, given the following values:</p>
<ul>
@@ -1717,7 +1805,7 @@
<li><var>presentation timestamp</var> equals 10.01255</li>
<li><var>decode timestamp</var> equals 10.01255</li>
</ul>
- <p><var>presentation timestamp</var> and <var>decode timestamp</var> are rounded & updated to 10.0125 since 10.01255 is closer to
+ <p><var>presentation timestamp</var> and <var>decode timestamp</var> are updated to 10.0125 since 10.01255 is closer to
10 + 100/8000 (10.0125) than 10 + 101/8000 (10.012625)</p>
</div></div>
</li>
@@ -1757,7 +1845,7 @@
</ol>
</section>
<section id="sourcebuffer-audio-splice-rendering-algorithm">
- <h4><span class="secno">3.5.8 </span>Audio Splice Rendering Algorithm</h4>
+ <h4><span class="secno">3.5.10 </span>Audio Splice Rendering Algorithm</h4>
<p>The following steps are run when a spliced frame, generated by the <a href="#sourcebuffer-audio-splice-frame-algorithm">audio splice frame algorithm</a>, needs to be rendered by the
media element:</p>
<ol>
@@ -2326,7 +2414,17 @@
</thead>
<tbody>
<tr>
- <td>05 March 2013</td>
+ <td>12 March 2013</td>
+ <td>
+ <ul>
+ <li>Bug 21112 - Add appendWindowStart & appendWindowEnd attributes.</li>
+ <li>Bug 19676 - Clarify overlapped frame definitions and splice logic.</li>
+ <li>Bug 21172 - Added coded frame removal and eviction algorithms.</li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="https://dvcs.w3.org/hg/html-media/raw-file/dcd406812201/media-source/media-source.html">05 March 2013</a></td>
<td>
<ul>
<li>Bug 21170 - Remove 'stream aborted' step from stream append loop algorithm.</li>
--- a/media-source/media-source.js Mon Mar 04 09:42:34 2013 -0800
+++ b/media-source/media-source.js Tue Mar 12 11:43:03 2013 -0700
@@ -86,6 +86,8 @@
'sourcebuffer-textTracks': { func: idlref_helper, fragment: 'widl-SourceBuffer-textTracks', link_text: 'textTracks', },
'buffered': { func: idlref_helper, fragment: 'widl-SourceBuffer-buffered', link_text: 'buffered', },
'timestampOffset': { func: idlref_helper, fragment: 'widl-SourceBuffer-timestampOffset', link_text: 'timestampOffset', },
+ 'appendWindowStart': { func: idlref_helper, fragment: 'widl-SourceBuffer-appendWindowStart', link_text: 'appendWindowStart', },
+ 'appendWindowEnd': { func: idlref_helper, fragment: 'widl-SourceBuffer-appendWindowEnd', link_text: 'appendWindowEnd', },
'length': { func: idlref_helper, fragment: 'widl-SourceBufferList-length', link_text: 'length', },
'createObjectURL': { func: idlref_helper, fragment: 'widl-URL-createObjectURL-DOMString-MediaSource-mediaSource', link_text: 'createObjectURL()', },
'open': { func: idlref_helper, fragment: 'idl-def-ReadyState', link_text: '"open"', },
@@ -120,6 +122,7 @@
'coded-frames': { func: term_helper, fragment: 'coded-frame', link_text: 'coded frames', },
'parent-media-source': { func: term_helper, fragment: 'parent-media-source', link_text: 'parent media source', },
'append-sequence': { func: term_helper, fragment: 'append-sequence', link_text: 'append sequence', },
+ 'append-window': { func: term_helper, fragment: 'append-window', link_text: 'append window', },
'enough-data': { func: term_helper, fragment: 'enough-data', link_text: 'enough data to ensure uninterrupted playback', },
'duration-change-algorithm': { func: link_helper, fragment: '#duration-change-algorithm', link_text: 'duration change algorithm', },
@@ -134,6 +137,8 @@
'stream-append-loop': { func: link_helper, fragment: '#sourcebuffer-stream-append-loop', link_text: 'stream append loop', },
'init-segment-received-algorithm': { func: link_helper, fragment: '#sourcebuffer-init-segment-received', link_text: 'initialization segment received algorithm', },
'coded-frame-processing-algorithm': { func: link_helper, fragment: '#sourcebuffer-coded-frame-processing', link_text: 'coded frame processing algorithm', },
+ 'coded-frame-removal-algorithm': { func: link_helper, fragment: '#sourcebuffer-coded-frame-removal', link_text: 'coded frame removal algorithm', },
+ 'coded-frame-eviction-algorithm': { func: link_helper, fragment: '#sourcebuffer-coded-frame-eviction', link_text: 'coded frame eviction algorithm', },
'audio-splice-frame-algorithm': { func: link_helper, fragment: '#sourcebuffer-audio-splice-frame-algorithm', link_text: 'audio splice frame algorithm', },
'audio-splice-rendering-algorithm': { func: link_helper, fragment: '#sourcebuffer-audio-splice-rendering-algorithm', link_text: 'audio splice rendering algorithm', },
'input-buffer': { func: var_helper, fragment: '#sourcebuffer-input-buffer', link_text: 'input buffer', },