Title: [206129] trunk/LayoutTests/imported/w3c
Revision
206129
Author
jer.no...@apple.com
Date
2016-09-19 16:30:53 -0700 (Mon, 19 Sep 2016)

Log Message

Unreviewed gardening; update LayoutTests/media-source to the most recent version (5a011ca).

* resources/TestRepositories:
* web-platform-tests/media-source/OWNERS:
* web-platform-tests/media-source/interfaces.html:
* web-platform-tests/media-source/manifest.txt:
* web-platform-tests/media-source/mediasource-appendbuffer-quota-exceeded.html:
* web-platform-tests/media-source/mediasource-attach-stops-delaying-load-event.html: Added.
* web-platform-tests/media-source/mediasource-avtracks.html:
* web-platform-tests/media-source/mediasource-detach.html:
* web-platform-tests/media-source/mediasource-duration-expected.txt:
* web-platform-tests/media-source/mediasource-duration.html:
* web-platform-tests/media-source/mediasource-endofstream.html:
* web-platform-tests/media-source/mediasource-errors.html:
* web-platform-tests/media-source/mediasource-getvideoplaybackquality-expected.txt:
* web-platform-tests/media-source/mediasource-getvideoplaybackquality.html:
* web-platform-tests/media-source/mediasource-is-type-supported.html:
* web-platform-tests/media-source/mediasource-liveseekable.html:
* web-platform-tests/media-source/mediasource-remove-expected.txt:
* web-platform-tests/media-source/mediasource-remove.html:
* web-platform-tests/media-source/mediasource-removesourcebuffer.html:
* web-platform-tests/media-source/mediasource-seekable.html:
* web-platform-tests/media-source/mediasource-sourcebuffer-mode-timestamps.html: Added.
* web-platform-tests/media-source/mediasource-sourcebuffer-mode.html:
* web-platform-tests/media-source/mediasource-sourcebuffer-trackdefaults.html:
* web-platform-tests/media-source/mediasource-timestamp-offset.html:
* web-platform-tests/media-source/mediasource-trackdefault.html:
* web-platform-tests/media-source/mediasource-trackdefaultlist.html:
* web-platform-tests/media-source/mediasource-util.js:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2016-09-19 23:30:53 UTC (rev 206129)
@@ -1,3 +1,35 @@
+2016-09-19  Jer Noble  <jer.no...@apple.com>
+
+        Unreviewed gardening; update LayoutTests/media-source to the most recent version (5a011ca).
+
+        * resources/TestRepositories:
+        * web-platform-tests/media-source/OWNERS:
+        * web-platform-tests/media-source/interfaces.html:
+        * web-platform-tests/media-source/manifest.txt:
+        * web-platform-tests/media-source/mediasource-appendbuffer-quota-exceeded.html:
+        * web-platform-tests/media-source/mediasource-attach-stops-delaying-load-event.html: Added.
+        * web-platform-tests/media-source/mediasource-avtracks.html:
+        * web-platform-tests/media-source/mediasource-detach.html:
+        * web-platform-tests/media-source/mediasource-duration-expected.txt:
+        * web-platform-tests/media-source/mediasource-duration.html:
+        * web-platform-tests/media-source/mediasource-endofstream.html:
+        * web-platform-tests/media-source/mediasource-errors.html:
+        * web-platform-tests/media-source/mediasource-getvideoplaybackquality-expected.txt:
+        * web-platform-tests/media-source/mediasource-getvideoplaybackquality.html:
+        * web-platform-tests/media-source/mediasource-is-type-supported.html:
+        * web-platform-tests/media-source/mediasource-liveseekable.html:
+        * web-platform-tests/media-source/mediasource-remove-expected.txt:
+        * web-platform-tests/media-source/mediasource-remove.html:
+        * web-platform-tests/media-source/mediasource-removesourcebuffer.html:
+        * web-platform-tests/media-source/mediasource-seekable.html:
+        * web-platform-tests/media-source/mediasource-sourcebuffer-mode-timestamps.html: Added.
+        * web-platform-tests/media-source/mediasource-sourcebuffer-mode.html:
+        * web-platform-tests/media-source/mediasource-sourcebuffer-trackdefaults.html:
+        * web-platform-tests/media-source/mediasource-timestamp-offset.html:
+        * web-platform-tests/media-source/mediasource-trackdefault.html:
+        * web-platform-tests/media-source/mediasource-trackdefaultlist.html:
+        * web-platform-tests/media-source/mediasource-util.js:
+
 2016-09-19  Chris Dumez  <cdu...@apple.com>
 
         Update XHTMLParser to recognize "-//W3C//DTD MathML 2.0//EN" public identifier

Modified: trunk/LayoutTests/imported/w3c/resources/TestRepositories (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/resources/TestRepositories	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/resources/TestRepositories	2016-09-19 23:30:53 UTC (rev 206129)
@@ -15,7 +15,7 @@
     {
         "name": "web-platform-tests",
         "url": "https://github.com/w3c/web-platform-tests.git", 
-        "revision": "6d9c836",
+        "revision": "5a011ca",
         "paths_to_skip": [
             "conformance-checkers",
             "docs",

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/OWNERS (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/OWNERS	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/OWNERS	2016-09-19 23:30:53 UTC (rev 206129)
@@ -1,5 +1,3 @@
-@bit
-@acolwell
 @shishimaru
 @sideshowbarker
 @wolenetz

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/interfaces.html (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/interfaces.html	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/interfaces.html	2016-09-19 23:30:53 UTC (rev 206129)
@@ -26,93 +26,63 @@
 <script type=text/plain>
 [Constructor]
 interface MediaSource : EventTarget {
-    readonly    attribute SourceBufferList    sourceBuffers;
-    readonly    attribute SourceBufferList    activeSourceBuffers;
-    readonly    attribute ReadyState          readyState;
-                attribute unrestricted double duration;
-                attribute EventHandler        onsourceopen;
-                attribute EventHandler        onsourceended;
-                attribute EventHandler        onsourceclose;
-    SourceBuffer   addSourceBuffer (DOMString type);
-    void           removeSourceBuffer (SourceBuffer sourceBuffer);
-    void           endOfStream (optional EndOfStreamError error);
-    void           setLiveSeekableRange (double start, double end);
-    void           clearLiveSeekableRange ();
-    static boolean isTypeSupported (DOMString type);
+    readonly attribute SourceBufferList    sourceBuffers;
+    readonly attribute SourceBufferList    activeSourceBuffers;
+    readonly attribute ReadyState          readyState;
+             attribute unrestricted double duration;
+             attribute EventHandler        onsourceopen;
+             attribute EventHandler        onsourceended;
+             attribute EventHandler        onsourceclose;
+    SourceBuffer addSourceBuffer(DOMString type);
+    void         removeSourceBuffer(SourceBuffer sourceBuffer);
+    void         endOfStream(optional EndOfStreamError error);
+    void         setLiveSeekableRange(double start, double end);
+    void         clearLiveSeekableRange();
+    static boolean isTypeSupported(DOMString type);
 };
 
 interface SourceBuffer : EventTarget {
-                attribute AppendMode          mode;
-    readonly    attribute boolean             updating;
-    readonly    attribute TimeRanges          buffered;
-                attribute double              timestampOffset;
-    readonly    attribute AudioTrackList      audioTracks;
-    readonly    attribute VideoTrackList      videoTracks;
-    readonly    attribute TextTrackList       textTracks;
-                attribute double              appendWindowStart;
-                attribute unrestricted double appendWindowEnd;
-                attribute EventHandler        onupdatestart;
-                attribute EventHandler        onupdate;
-                attribute EventHandler        onupdateend;
-                attribute EventHandler        onerror;
-                attribute EventHandler        onabort;
-    void appendBuffer (ArrayBuffer data);
-    void appendBuffer (ArrayBufferView data);
-    void appendStream (ReadableStream stream, [EnforceRange] optional unsigned long long maxSize);
-    void abort ();
-    void remove (double start, unrestricted double end);
-                    attribute TrackDefaultList    trackDefaults;
+             attribute AppendMode          mode;
+    readonly attribute boolean             updating;
+    readonly attribute TimeRanges          buffered;
+             attribute double              timestampOffset;
+    readonly attribute AudioTrackList      audioTracks;
+    readonly attribute VideoTrackList      videoTracks;
+    readonly attribute TextTrackList       textTracks;
+             attribute double              appendWindowStart;
+             attribute unrestricted double appendWindowEnd;
+             attribute EventHandler        onupdatestart;
+             attribute EventHandler        onupdate;
+             attribute EventHandler        onupdateend;
+             attribute EventHandler        onerror;
+             attribute EventHandler        onabort;
+    void appendBuffer(BufferSource data);
+    void abort();
+    void remove(double start, unrestricted double end);
 };
 
 interface SourceBufferList : EventTarget {
-    readonly    attribute unsigned long length;
-                attribute EventHandler  onaddsourcebuffer;
-                attribute EventHandler  onremovesourcebuffer;
+    readonly attribute unsigned long length;
+             attribute EventHandler  onaddsourcebuffer;
+             attribute EventHandler  onremovesourcebuffer;
     getter SourceBuffer (unsigned long index);
 };
 
-interface VideoPlaybackQuality {
-    readonly    attribute DOMHighResTimeStamp creationTime;
-    readonly    attribute unsigned long       totalVideoFrames;
-    readonly    attribute unsigned long       droppedVideoFrames;
-    readonly    attribute unsigned long       corruptedVideoFrames;
-    readonly    attribute double              totalFrameDelay;
-};
-
-[ Constructor (TrackDefaultType type, DOMString language, DOMString label, sequence<DOMString> kinds, optional DOMString byteStreamTrackID = "")]
-interface TrackDefault {
-    readonly    attribute TrackDefaultType    type;
-    readonly    attribute DOMString           byteStreamTrackID;
-    readonly    attribute DOMString           language;
-    readonly    attribute DOMString           label;
-    sequence<DOMString> getKinds ();
-};
-
-[ Constructor (optional sequence<TrackDefault> trackDefaults = [])]
-interface TrackDefaultList {
-    readonly    attribute unsigned long length;
-    getter TrackDefault (unsigned long index);
-};
-
 [Exposed=Window,DedicatedWorker,SharedWorker]
 partial interface URL {
-    static DOMString createObjectURL (MediaSource mediaSource);
+    static DOMString createObjectURL(MediaSource mediaSource);
 };
 
-partial interface HTMLVideoElement {
-    VideoPlaybackQuality getVideoPlaybackQuality ();
-};
-
 partial interface AudioTrack {
-    readonly    attribute SourceBuffer? sourceBuffer;
+    readonly attribute SourceBuffer? sourceBuffer;
 };
 
 partial interface VideoTrack {
-    readonly    attribute SourceBuffer? sourceBuffer;
+    readonly attribute SourceBuffer? sourceBuffer;
 };
 
 partial interface TextTrack {
-    readonly    attribute SourceBuffer? sourceBuffer;
+    readonly attribute SourceBuffer? sourceBuffer;
 };
 
 enum EndOfStreamError {
@@ -130,15 +100,10 @@
     "open",
     "ended"
 };
-
-enum TrackDefaultType {
-    "audio",
-    "video",
-    "text"
-};
 </script>
 <script>
 "use strict";
+setup({ explicit_done: true });
 var mediaSource;
 var sourceBuffer;
 var video = document.createElement("video");
@@ -154,11 +119,10 @@
   idlArray.add_objects({
     MediaSource: ['mediaSource'],
     SourceBuffer: ['sourceBuffer'],
-    SourceBufferList: ['mediaSource.sourceBuffers'],
-    VideoPlaybackQuality: ['video.getVideoPlaybackQuality()'],
-    TrackDefaultList: ['sourceBuffer.trackDefaults']
+    SourceBufferList: ['mediaSource.sourceBuffers']
   });
   idlArray.test();
+  done();
 }
 mediaSource = new MediaSource();
 video.src = ""

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/manifest.txt (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/manifest.txt	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/manifest.txt	2016-09-19 23:30:53 UTC (rev 206129)
@@ -1,6 +1,12 @@
+interfaces.html
+mediasource-activesourcebuffers.html
 mediasource-addsourcebuffer.html
+mediasource-addsourcebuffer-mode.html
 mediasource-append-buffer.html
+mediasource-appendbuffer-quota-exceeded.html
 mediasource-appendwindow.html
+mediasource-attach-stops-delaying-load-event.html
+mediasource-avtracks.html
 mediasource-buffered.html
 mediasource-closed.html
 mediasource-config-change-mp4-a-bitrate.html
@@ -17,10 +23,12 @@
 mediasource-config-change-webm-v-bitrate.html
 mediasource-config-change-webm-v-framerate.html
 mediasource-config-change-webm-v-framesize.html
+mediasource-detach.html
 mediasource-duration-boundaryconditions.html
 mediasource-duration.html
+mediasource-endofstream.html
 mediasource-endofstream-invaliderror.html
-mediasource-getvideoplaybackquality.html
+mediasource-errors.html
 mediasource-is-type-supported.html
 mediasource-liveseekable.html
 mediasource-multiple-attach.html
@@ -30,9 +38,18 @@
 mediasource-redundant-seek.html
 mediasource-remove.html
 mediasource-removesourcebuffer.html
+mediasource-seekable.html
 mediasource-seek-beyond-duration.html
 mediasource-seek-during-pending-seek.html
 mediasource-sequencemode-append-buffer.html
 mediasource-sourcebufferlist.html
 mediasource-sourcebuffer-mode.html
+mediasource-sourcebuffer-mode-timestamps.html
 mediasource-timestamp-offset.html
+SourceBuffer-abort.html
+SourceBuffer-abort-readyState.html
+SourceBuffer-abort-removed.html
+SourceBuffer-abort-updating.html
+URL-createObjectURL.html
+URL-createObjectURL-null.html
+URL-createObjectURL-revoke.html

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-appendbuffer-quota-exceeded.html (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-appendbuffer-quota-exceeded.html	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-appendbuffer-quota-exceeded.html	2016-09-19 23:30:53 UTC (rev 206129)
@@ -1,10 +1,14 @@
 <!DOCTYPE html>
-<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<!--  Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
 <meta charset="utf-8">
+<meta name="timeout" content="long">
 <script src=""
 <script src=""
 <script src=""
 <script>
+    var subType = MediaSourceUtil.getSubType(MediaSourceUtil.AUDIO_ONLY_TYPE);
+    var manifestFilenameAudio = subType + "/test-a-128k-44100Hz-1ch-manifest.json";
+
     // Fill up a given SourceBuffer by appending data repeatedly via doAppendDataFunc until
     // an exception is thrown. The thrown exception is passed to onCaughtExceptionCallback.
     function fillUpSourceBuffer(test, sourceBuffer, doAppendDataFunc, onCaughtExceptionCallback) {
@@ -19,16 +23,21 @@
         test.waitForExpectedEvents(function() { fillUpSourceBuffer(test, sourceBuffer, doAppendDataFunc, onCaughtExceptionCallback); });
     }
 
-    mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+    mediasource_test(function(test, mediaElement, mediaSource)
     {
-        sourceBuffer.mode = 'sequence';
-        fillUpSourceBuffer(test, sourceBuffer,
-            function () { // doAppendDataFunc
-                sourceBuffer.appendBuffer(mediaData);
-            },
-            function (ex) { // onCaughtExceptionCallback
-                assert_equals(ex.name, 'QuotaExceededError');
-                test.done();
-            });
+        mediaElement.addEventListener("error", test.unreached_func("Unexpected event 'error'"));
+        MediaSourceUtil.fetchManifestAndData(test, manifestFilenameAudio, function(typeAudio, dataAudio)
+        {
+            var sourceBuffer = mediaSource.addSourceBuffer(typeAudio);
+            sourceBuffer.mode = 'sequence';
+            fillUpSourceBuffer(test, sourceBuffer,
+                function () { // doAppendDataFunc
+                    sourceBuffer.appendBuffer(dataAudio);
+                },
+                function (ex) { // onCaughtExceptionCallback
+                    assert_equals(ex.name, 'QuotaExceededError');
+                    test.done();
+                });
+        });
     }, 'Appending data repeatedly should fill up the buffer and throw a QuotaExceededError when buffer is full.');
 </script>

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-attach-stops-delaying-load-event.html (0 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-attach-stops-delaying-load-event.html	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-attach-stops-delaying-load-event.html	2016-09-19 23:30:53 UTC (rev 206129)
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<!--  Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
+<title>Tests that MediaSource attachment stops delaying the load event.</title>
+<link rel="author" title="Matthew Wolenetz" href=""
+<script src=""
+<script src=""
+<script>
+async_test(function(test)
+{
+    var receivedLoadEvent = false;
+    var receivedSourceOpenEvent = false;
+
+    window.addEventListener("load", test.step_func(function() {
+        assert_false(receivedLoadEvent, "window should not receive multiple load events");
+        receivedLoadEvent = true;
+        assert_equals(document.readyState, "complete", "document should be complete");
+        if (receivedLoadEvent && receivedSourceOpenEvent) {
+            test.done();
+        }
+    }));
+
+    assert_equals(document.readyState, "loading", "document should not be complete yet");
+    var video = document.createElement("video");
+    var mediaSource = new MediaSource();
+
+    // |video| should stop delaying the load event long and complete the MediaSource attachment
+    // before either a "progress", "stalled" or "suspend" event are enqueued.
+    video.addEventListener("suspend", test.unreached_func("unexpected 'suspend' event"));
+    video.addEventListener("stalled", test.unreached_func("unexpected 'stalled' event"));
+    video.addEventListener("progress", test.unreached_func("unexpected 'progress' event"));
+
+    // No error is expected.
+    video.addEventListener("error", test.unreached_func("unexpected 'error' event"));
+
+    mediaSource.addEventListener("sourceopen", test.step_func(function() {
+        assert_false(receivedSourceOpenEvent, "only one sourceopen event should occur in this test");
+        receivedSourceOpenEvent = true;
+        assert_equals(video.networkState, video.NETWORK_LOADING);
+        assert_equals(video.readyState, video.HAVE_NOTHING);
+        if (receivedLoadEvent && receivedSourceOpenEvent) {
+            test.done();
+        }
+    }));
+
+    var mediaSourceURL = URL.createObjectURL(mediaSource);
+    video.src = ""
+    test.add_cleanup(function() { URL.revokeObjectURL(mediaSourceURL); });
+}, "MediaSource attachment should immediately stop delaying the load event");
+</script>

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-avtracks.html (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-avtracks.html	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-avtracks.html	2016-09-19 23:30:53 UTC (rev 206129)
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<!--  Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
 <meta charset="utf-8">
 <script src=""
 <script src=""

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-detach.html (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-detach.html	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-detach.html	2016-09-19 23:30:53 UTC (rev 206129)
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<!--  Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
 <meta charset="utf-8">
 <script src=""
 <script src=""

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-duration-expected.txt (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-duration-expected.txt	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-duration-expected.txt	2016-09-19 23:30:53 UTC (rev 206129)
@@ -4,4 +4,8 @@
 PASS Test endOfStream completes previous seek to truncated duration 
 PASS Test setting same duration multiple times does not fire duplicate durationchange 
 PASS Test setting the duration to less than the highest starting presentation timestamp will throw 
+PASS Truncating the duration throws an InvalidStateError exception when new duration is less than the highest buffered range start time of one of the track buffers 
+PASS Truncating the duration throws an InvalidStateError exception when new duration is less than a buffered coded frame presentation time 
+PASS Increasing the duration does not trigger any SourceBuffer update 
+PASS Increasing the duration during media playback does not trigger any SourceBuffer update 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-duration.html (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-duration.html	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-duration.html	2016-09-19 23:30:53 UTC (rev 206129)
@@ -10,6 +10,11 @@
     <body>
         <div id="log"></div>
         <script>
+
+          var subType = MediaSourceUtil.getSubType(MediaSourceUtil.AUDIO_ONLY_TYPE);
+          var manifestFilenameAudio = subType + "/test-a-128k-44100Hz-1ch-manifest.json";
+          var manifestFilenameVideo = subType + "/test-v-128k-320x240-30fps-10kfr-manifest.json";
+
           function mediasource_truncated_duration_seek_test(testFunction, description, options)
           {
               return mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
@@ -53,15 +58,31 @@
 
                   test.waitForExpectedEvents(function()
                   {
-                      // remove will not remove partial frames. The truncated duration is as such the highest end time.
-                      truncatedDuration = sourceBuffer.buffered.end(sourceBuffer.buffered.length-1);
                       assert_greater_than_equal(mediaElement.currentTime, seekTo, 'Playback time has reached seekTo');
-                      test.expectEvent(mediaElement, 'seeking', 'Seeking to truncated duration');
-
                       assert_false(sourceBuffer.updating, 'sourceBuffer.updating');
 
+                      // Remove will not remove partial frames, so the resulting duration is the highest end time
+                      // of the track buffer ranges, and is greater than or equal to the highest coded frame
+                      // presentation time across all track buffer ranges. We first obtain the intersected track buffer
+                      // ranges end time and set the duration to that value.
+                      truncatedDuration = sourceBuffer.buffered.end(sourceBuffer.buffered.length-1);
+                      assert_less_than(truncatedDuration, seekTo,
+                                       'remove has removed the current playback position from at least one track buffer');
+
                       mediaSource.duration = truncatedDuration;
+                      test.expectEvent(mediaElement, 'seeking', 'Seeking to truncated duration');
 
+                      // The actual duration may be slightly higher than truncatedDuration because the
+                      // duration is adjusted upwards if necessary to be the highest end time across all track buffer
+                      // ranges. Allow that increase here.
+                      assert_less_than_equal(truncatedDuration, mediaSource.duration,
+                                              'Duration should not be less than what was set');
+                      // Here, we assume no test media coded frame duration is longer than 100ms.
+                      assert_less_than(mediaSource.duration - truncatedDuration, 0.1);
+
+                      // Update our truncatedDuration to be the actual new duration.
+                      truncatedDuration = mediaSource.duration;
+
                       assert_true(mediaElement.seeking, 'Seeking after setting truncatedDuration');
                   });
 
@@ -253,6 +274,110 @@
               });
           }, 'Test setting the duration to less than the highest starting presentation timestamp will throw');
 
+          mediasource_test(function(test, mediaElement, mediaSource)
+          {
+              mediaElement.addEventListener("error", test.unreached_func("Unexpected event 'error'"));
+              MediaSourceUtil.fetchManifestAndData(test, manifestFilenameAudio, function(typeAudio, dataAudio)
+              {
+                  MediaSourceUtil.fetchManifestAndData(test, manifestFilenameVideo, function(typeVideo, dataVideo)
+                  {
+                      var sourceBufferAudio = mediaSource.addSourceBuffer(typeAudio);
+                      var sourceBufferVideo = mediaSource.addSourceBuffer(typeVideo);
+                      var newDuration = 1.2;
+
+                      sourceBufferAudio.appendWindowEnd = 2.0;
+                      sourceBufferAudio.appendWindowStart = newDuration / 2.0;
+                      sourceBufferAudio.appendBuffer(dataAudio);
+
+                      sourceBufferVideo.appendWindowEnd = 2.0;
+                      sourceBufferVideo.appendWindowStart = newDuration * 1.3;
+                      sourceBufferVideo.appendBuffer(dataVideo);
+
+                      test.expectEvent(sourceBufferAudio, "updateend");
+                      test.expectEvent(sourceBufferVideo, "updateend");
+                      test.waitForExpectedEvents(function()
+                      {
+                          assert_equals(sourceBufferAudio.buffered.length, 1);
+                          assert_equals(sourceBufferVideo.buffered.length, 1);
+                          assert_less_than(sourceBufferAudio.buffered.start(0), newDuration);
+                          assert_greater_than(sourceBufferVideo.buffered.start(0), newDuration);
+                          assert_throws("InvalidStateError", function () { mediaSource.duration = newDuration; });
+                          test.done();
+                      });
+                  });
+              });
+          }, "Truncating the duration throws an InvalidStateError exception when new duration is less than the highest buffered range start time of one of the track buffers");
+
+          mediasource_test(function(test, mediaElement, mediaSource)
+          {
+              mediaElement.addEventListener("error", test.unreached_func("Unexpected event 'error'"));
+              MediaSourceUtil.fetchManifestAndData(test, manifestFilenameAudio, function(typeAudio, dataAudio)
+              {
+                  MediaSourceUtil.fetchManifestAndData(test, manifestFilenameVideo, function(typeVideo, dataVideo)
+                  {
+                      var sourceBufferAudio = mediaSource.addSourceBuffer(typeAudio);
+                      var sourceBufferVideo = mediaSource.addSourceBuffer(typeVideo);
+
+                      // Buffer audio [0.8,1.8)
+                      sourceBufferAudio.timestampOffset = 0.8;
+                      sourceBufferAudio.appendWindowEnd = 1.8;
+                      sourceBufferAudio.appendBuffer(dataAudio);
+
+                      // Buffer video [1.5,3)
+                      sourceBufferVideo.timestampOffset = 1.5;
+                      sourceBufferVideo.appendWindowEnd = 3;
+                      sourceBufferVideo.appendBuffer(dataVideo);
+
+                      test.expectEvent(sourceBufferAudio, "updateend");
+                      test.expectEvent(sourceBufferVideo, "updateend");
+                      test.waitForExpectedEvents(function()
+                      {
+                          var newDuration = 2.0;
+
+                          // Verify the test setup
+                          assert_equals(sourceBufferAudio.buffered.length, 1);
+                          assert_equals(sourceBufferVideo.buffered.length, 1);
+                          assert_greater_than(sourceBufferAudio.buffered.end(0), 1.5);
+                          assert_less_than(sourceBufferAudio.buffered.end(0), newDuration);
+                          assert_less_than(sourceBufferVideo.buffered.start(0), newDuration);
+                          assert_greater_than(sourceBufferVideo.buffered.end(0), newDuration + 0.5);
+
+                          // Verify the expected error
+                          // We assume relocated test video has at least one coded
+                          // frame presentation interval which fits in [>2.0,>2.5)
+                          assert_throws("InvalidStateError", function () { mediaSource.duration = newDuration; });
+                          test.done();
+                      });
+                  });
+              });
+          }, "Truncating the duration throws an InvalidStateError exception when new duration is less than a buffered coded frame presentation time");
+
+          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+          {
+              assert_less_than(segmentInfo.duration, 60, 'Sufficient test media duration');
+              sourceBuffer.appendBuffer(mediaData);
+              test.expectEvent(sourceBuffer, 'updateend', 'Media data appended to the SourceBuffer');
+              test.waitForExpectedEvents(function()
+              {
+                  mediaSource.duration = 60;
+                  assert_false(sourceBuffer.updating, 'No SourceBuffer update when duration is increased');
+                  test.done();
+              });
+          }, 'Increasing the duration does not trigger any SourceBuffer update');
+
+          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+          {
+              assert_greater_than(segmentInfo.duration, 2, 'Sufficient test media duration');
+              mediaElement.play();
+              sourceBuffer.appendBuffer(mediaData);
+              test.expectEvent(sourceBuffer, 'updateend', 'Media data appended to the SourceBuffer');
+              test.waitForExpectedEvents(function()
+              {
+                  mediaSource.duration = 60;
+                  assert_false(sourceBuffer.updating, 'No SourceBuffer update when duration is increased');
+                  test.done();
+              });
+          }, 'Increasing the duration during media playback does not trigger any SourceBuffer update');
         </script>
     </body>
 </html>

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-endofstream.html (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-endofstream.html	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-endofstream.html	2016-09-19 23:30:53 UTC (rev 206129)
@@ -23,37 +23,23 @@
             mediaSource.endOfStream();
             test.expectEvent(mediaElement, 'canplaythrough',
               'Media element may render the media content until the end');
-            test.waitForExpectedEvents(function()
-            {
-                assert_equals(mediaElement.readyState, HTMLMediaElement.HAVE_ENOUGH_DATA,
-                  'Media element has enough data to render the content');
-                test.done();
-            });
         });
-    }, 'MediaSource.endOfStream(): media element notified that it now has all of the media data');
 
-    mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
-    {
-        sourceBuffer.appendBuffer(mediaData);
-        test.expectEvent(sourceBuffer, 'updateend',
-          'Media buffer appended to SourceBuffer');
         test.waitForExpectedEvents(function()
         {
-            assert_equals(sourceBuffer.buffered.length, 1,
-              'Media data properly buffered');
-            var highestEndTime = sourceBuffer.buffered.end(0);
-
-            mediaSource.endOfStream();
-
-            assert_equals(sourceBuffer.buffered.end(0), highestEndTime,
-              'Ending the stream does not affect buffered data');
+            assert_equals(mediaElement.readyState, HTMLMediaElement.HAVE_ENOUGH_DATA,
+              'Media element has enough data to render the content');
             test.done();
         });
-    }, 'MediaSource.endOfStream(): buffered data not modified when endOfStream is called');
+    }, 'MediaSource.endOfStream(): media element notified that it now has all of the media data');
 
+    function threeDecimalPlaces(number)
+    {
+        return Number(number.toFixed(3));
+    }
+
     mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
     {
-        assert_less_than(segmentInfo.duration, 60, 'Sufficient test media duration');
         sourceBuffer.appendBuffer(mediaData);
         test.expectEvent(sourceBuffer, 'updateend',
           'Media buffer appended to SourceBuffer');
@@ -61,13 +47,30 @@
         {
             assert_equals(sourceBuffer.buffered.length, 1,
               'Media data properly buffered');
+            var highestEndTime = sourceBuffer.buffered.end(0);
 
-            mediaSource.duration = 60;
+            // Note that segmentInfo.duration is expected to also be the
+            // highest track buffer range end time. Therefore, endOfStream() should
+            // not change duration with this media.
+            assert_equals(threeDecimalPlaces(segmentInfo.duration), threeDecimalPlaces(mediaSource.duration));
+            assert_less_than_equal(highestEndTime, mediaSource.duration,
+                'Media duration may be slightly longer than intersected track buffered ranges');
+
+            // Set the duration even higher, then confirm that endOfStream() drops it back to be
+            // the highest track buffer range end time.
+            mediaSource.duration += 10;
             mediaSource.endOfStream();
 
-            assert_equals(mediaSource.duration, sourceBuffer.buffered.end(0),
-              'Duration set to the higest end time');
+            assert_equals(sourceBuffer.buffered.length, 1,
+              'Media data properly buffered after endOfStream');
+
+            assert_equals(threeDecimalPlaces(segmentInfo.duration), threeDecimalPlaces(mediaSource.duration));
+            assert_less_than_equal(highestEndTime, mediaSource.duration,
+                'Media duration may be slightly longer than intersected track buffered ranges');
+            assert_equals(sourceBuffer.buffered.end(0), mediaSource.duration,
+                'After endOfStream(), highest buffered range end time must be the highest track buffer range end time');
+
             test.done();
         });
-    }, 'MediaSource.endOfStream(): duration set to the highest end time reported by the buffered attribute');
-</script>
\ No newline at end of file
+    }, 'MediaSource.endOfStream(): duration and buffered range end time before and after endOfStream');
+</script>

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-errors.html (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-errors.html	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-errors.html	2016-09-19 23:30:53 UTC (rev 206129)
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<!--  Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
 <meta charset="utf-8">
 <script src=""
 <script src=""

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-getvideoplaybackquality-expected.txt (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-getvideoplaybackquality-expected.txt	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-getvideoplaybackquality-expected.txt	2016-09-19 23:30:53 UTC (rev 206129)
@@ -1,3 +1,4 @@
 
 PASS Test HTMLVideoElement.getVideoPlaybackQuality() with MediaSource API 
+PASS Test the totalFrameDelay attribute of HTMLVideoElement.getVideoPlaybackQuality() with MediaSource API 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-getvideoplaybackquality.html (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-getvideoplaybackquality.html	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-getvideoplaybackquality.html	2016-09-19 23:30:53 UTC (rev 206129)
@@ -18,18 +18,33 @@
               {
                   var videoElement = e.target;
                   var newQuality = videoElement.getVideoPlaybackQuality();
+                  var now = window.performance.now();
 
-                  assert_not_equals(previousQuality, newQuality, "Verify new object");
-                  assert_greater_than(newQuality.creationTime, previousQuality.creationTime, "creationTime");
+                  assert_not_equals(previousQuality, newQuality,
+                    "New quality object is different from the previous one");
+                  assert_greater_than(newQuality.creationTime, previousQuality.creationTime,
+                    "creationTime increases monotonically");
+                  assert_approx_equals(newQuality.creationTime, now, 100,
+                    "creationTime roughly equals current time");
 
                   assert_greater_than_equal(newQuality.totalVideoFrames, 0, "totalVideoFrames >= 0");
-                  assert_greater_than_equal(newQuality.totalVideoFrames, previousQuality.totalVideoFrames, "totalVideoFrames");
+                  assert_greater_than_equal(newQuality.totalVideoFrames, previousQuality.totalVideoFrames,
+                    "totalVideoFrames increases monotonically");
+                  assert_less_than(newQuality.totalVideoFrames, 300,
+                    "totalVideoFrames should remain low as duration is less than 10s and framerate less than 30fps");
 
                   assert_greater_than_equal(newQuality.droppedVideoFrames, 0, "droppedVideoFrames >= 0");
-                  assert_greater_than_equal(newQuality.droppedVideoFrames, previousQuality.droppedVideoFrames, "droppedVideoFrames");
+                  assert_greater_than_equal(newQuality.droppedVideoFrames, previousQuality.droppedVideoFrames,
+                    "droppedVideoFrames increases monotonically");
+                  assert_less_than_equal(newQuality.droppedVideoFrames, newQuality.totalVideoFrames,
+                    "droppedVideoFrames is only a portion of totalVideoFrames");
 
                   assert_greater_than_equal(newQuality.corruptedVideoFrames, 0, "corruptedVideoFrames >= 0");
-                  assert_greater_than_equal(newQuality.corruptedVideoFrames, previousQuality.corruptedVideoFrames, "corruptedVideoFrames");
+                  assert_greater_than_equal(newQuality.corruptedVideoFrames, previousQuality.corruptedVideoFrames,
+                    "corruptedVideoFrames increases monotonically");
+                  assert_less_than_equal(newQuality.corruptedVideoFrames, newQuality.totalVideoFrames,
+                    "corruptedVideoFrames is only a portion of totalVideoFrames");
+
                   previousQuality = newQuality;
                   timeUpdateCount++;
               }));
@@ -36,36 +51,57 @@
 
               mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
 
-              test.expectEvent(sourceBuffer, 'updatestart', 'sourceBuffer');
-              test.expectEvent(sourceBuffer, 'update', 'sourceBuffer');
+              sourceBuffer.appendBuffer(mediaData);
               test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer');
-              sourceBuffer.appendBuffer(mediaData);
 
               test.waitForExpectedEvents(function()
               {
                   assert_false(sourceBuffer.updating, "updating");
-
-                  sourceBuffer.remove(1, Infinity);
-
-                  assert_true(sourceBuffer.updating, "updating");
-                  test.expectEvent(sourceBuffer, 'updatestart', 'sourceBuffer');
-                  test.expectEvent(sourceBuffer, 'update', 'sourceBuffer');
-                  test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer');
+                  mediaSource.endOfStream();
+                  assert_less_than(mediaSource.duration, 10, "duration");
+                  mediaElement.play();
+                  test.expectEvent(mediaElement, 'ended', 'mediaElement');
               });
 
               test.waitForExpectedEvents(function()
               {
-                  assert_false(sourceBuffer.updating, "updating");
-                  assert_greater_than(mediaSource.duration, 1, "duration");
+                  assert_greater_than(timeUpdateCount, 2, "timeUpdateCount");
+                  test.done();
+              });
+          }, "Test HTMLVideoElement.getVideoPlaybackQuality() with MediaSource API");
 
-                  mediaSource.duration = 1;
 
-                  test.expectEvent(mediaElement, "durationchange");
-              });
+          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+          {
+              var previousQuality = mediaElement.getVideoPlaybackQuality();
+              var timeUpdateCount = 0;
+              var startTime = 0;
+              mediaElement.addEventListener("timeupdate", test.step_func(function (e)
+              {
+                  var videoElement = e.target;
+                  var newQuality = videoElement.getVideoPlaybackQuality();
+                  var now = window.performance.now();
 
+                  assert_greater_than_equal(newQuality.totalFrameDelay, 0, "totalFrameDelay >= 0");
+                  assert_greater_than_equal(newQuality.totalFrameDelay, previousQuality.totalFrameDelay,
+                    "totalFrameDelay increases monotonically");
+                  assert_less_than(newQuality.totalFrameDelay, (now - startTime) / 1000,
+                    "totalFrameDelay does not exceed the time elapsed since playback started");
+
+                  previousQuality = newQuality;
+                  timeUpdateCount++;
+              }));
+
+              mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
+
+              sourceBuffer.appendBuffer(mediaData);
+              test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer');
               test.waitForExpectedEvents(function()
               {
+                  assert_false(sourceBuffer.updating, "updating");
                   mediaSource.endOfStream();
+                  assert_less_than(mediaSource.duration, 10, "duration");
+                  startTime = window.performance.now();
                   mediaElement.play();
                   test.expectEvent(mediaElement, 'ended', 'mediaElement');
               });
@@ -75,7 +111,7 @@
                   assert_greater_than(timeUpdateCount, 2, "timeUpdateCount");
                   test.done();
               });
-          }, "Test HTMLVideoElement.getVideoPlaybackQuality() with MediaSource API");
+          }, "Test the totalFrameDelay attribute of HTMLVideoElement.getVideoPlaybackQuality() with MediaSource API");
         </script>
     </body>
 </html>

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-is-type-supported.html (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-is-type-supported.html	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-is-type-supported.html	2016-09-19 23:30:53 UTC (rev 206129)
@@ -5,6 +5,7 @@
         <title>MediaSource.isTypeSupported() test cases.</title>
         <script src=""
         <script src=""
+        <script src=""
     </head>
     <body>
         <div id="log"></div>
@@ -36,6 +37,12 @@
           ], false, 'Test invalid MIME format');
 
           test_type_support([
+              'xxx',
+              'text/html',
+              'image/jpeg'
+          ], false, 'Test invalid MSE MIME media type');
+
+          test_type_support([
               'audio/webm;codecs="vp8"',
               'audio/mp4;codecs="avc1.4d001e"',
           ], false, 'Test invalid mismatch between major type and codec ID');
@@ -46,7 +53,6 @@
               'video/mp4;codecs="vp8"',
               'video/webm;codecs="mp4a.40.2"',
               'video/mp4;codecs="vorbis"',
-              'video/webm;codecs="mp4a.40.2"',
           ], false, 'Test invalid mismatch between minor type and codec ID');
 
           test_type_support([

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-liveseekable.html (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-liveseekable.html	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-liveseekable.html	2016-09-19 23:30:53 UTC (rev 206129)
@@ -1,118 +1,137 @@
 <!DOCTYPE html>
-<html>
-    <head>
-        <title>Checks setting/clearing the live seekable range and HTMLMediaElement.seekable</title>
-        <script src=""
-        <script src=""
-        <script src=""
-    </head>
-    <body>
-        <div id="log"></div>
-        <script>
-          test(function(test)
-          {
-              var mediaSource = new MediaSource();
-              assert_equals(mediaSource.readyState, "closed", "media source is closed.");
-              assert_throws("InvalidStateError", function() { mediaSource.setLiveSeekableRange(0, 1); });
-          }, "setLiveSeekableRange throws an InvalidStateError exception if the readyState attribute is not 'open'");
+<!--  Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
+<meta charset="utf-8">
+<title>Checks setting/clearing the live seekable range and HTMLMediaElement.seekable</title>
+<script src=""
+<script src=""
+<script src=""
+<script>
+test(function(test)
+{
+    var mediaSource = new MediaSource();
+    assert_equals(mediaSource.readyState, "closed", "media source is closed.");
+    assert_throws("InvalidStateError", function() { mediaSource.setLiveSeekableRange(0, 1); });
+}, "setLiveSeekableRange throws an InvalidStateError exception if the readyState attribute is not 'open'");
 
 
-          test(function(test)
-          {
-              var mediaSource = new MediaSource();
-              assert_equals(mediaSource.readyState, "closed", "media source is closed.");
-              assert_throws("InvalidStateError", function() { mediaSource.clearLiveSeekableRange(); });
-          }, "clearLiveSeekableRange throws an InvalidStateError exception if the readyState attribute is not 'open'");
+test(function(test)
+{
+    var mediaSource = new MediaSource();
+    assert_equals(mediaSource.readyState, "closed", "media source is closed.");
+    assert_throws("InvalidStateError", function() { mediaSource.clearLiveSeekableRange(); });
+}, "clearLiveSeekableRange throws an InvalidStateError exception if the readyState attribute is not 'open'");
 
 
-          mediasource_test(function(test, mediaElement, mediaSource)
-          {
-              mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
-              assert_throws(new TypeError(), function() { mediaSource.setLiveSeekableRange(-1, 1); });
-              test.done();
-          }, "setLiveSeekableRange throws a TypeError if start is negative");
+mediasource_test(function(test, mediaElement, mediaSource)
+{
+    mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
+    var mimetype = MediaSourceUtil.AUDIO_VIDEO_TYPE;
+    var sourceBuffer = mediaSource.addSourceBuffer(mimetype);
+    sourceBuffer.appendBuffer(new Uint8Array(0));
+    assert_true(sourceBuffer.updating, "Updating set when a buffer is appended.");
+    mediaSource.setLiveSeekableRange(0, 1);
+    test.done();
+}, "setLiveSeekableRange does not restrict to not currently updating");
 
 
-          mediasource_test(function(test, mediaElement, mediaSource)
-          {
-              mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
-              assert_throws(new TypeError(), function() { mediaSource.setLiveSeekableRange(2, 1); });
-              test.done();
-          }, "setLiveSeekableRange throws a TypeError if start is greater than end");
+mediasource_test(function(test, mediaElement, mediaSource)
+{
+    mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
+    var mimetype = MediaSourceUtil.AUDIO_VIDEO_TYPE;
+    var sourceBuffer = mediaSource.addSourceBuffer(mimetype);
+    sourceBuffer.appendBuffer(new Uint8Array(0));
+    assert_true(sourceBuffer.updating, "Updating set when a buffer is appended.");
+    mediaSource.clearLiveSeekableRange();
+    test.done();
+}, "clearLiveSeekableRange does not restrict to not currently updating");
 
 
-          mediasource_test(function(test, mediaElement, mediaSource)
-          {
-              mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
-              mediaSource.setLiveSeekableRange(0, 1);
-              test.done();
-          }, "setLiveSeekableRange returns with no error when conditions are correct");
+mediasource_test(function(test, mediaElement, mediaSource)
+{
+    mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
+    assert_throws(new TypeError(), function() { mediaSource.setLiveSeekableRange(-1, 1); });
+    test.done();
+}, "setLiveSeekableRange throws a TypeError if start is negative");
 
 
-          mediasource_test(function(test, mediaElement, mediaSource)
-          {
-              mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
-              mediaSource.clearLiveSeekableRange();
-              test.done();
-          }, "clearLiveSeekableRange returns with no error when conditions are correct");
+mediasource_test(function(test, mediaElement, mediaSource)
+{
+    mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
+    assert_throws(new TypeError(), function() { mediaSource.setLiveSeekableRange(2, 1); });
+    test.done();
+}, "setLiveSeekableRange throws a TypeError if start is greater than end");
 
 
-          mediasource_test(function(test, mediaElement, mediaSource)
-          {
-              mediaSource.duration = +Infinity;
-              mediaSource.setLiveSeekableRange(1, 2);
-              assert_equals(mediaElement.seekable.length, 1,
-                'The seekable attribute contains a single range.');
-              assertSeekableEquals(mediaElement, '{ [1.000, 2.000) }',
-                'The seekable attribute returns the correct range.');
+mediasource_test(function(test, mediaElement, mediaSource)
+{
+    mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
+    mediaSource.setLiveSeekableRange(0, 1);
+    test.done();
+}, "setLiveSeekableRange returns with no error when conditions are correct");
 
-              mediaSource.clearLiveSeekableRange();
-              assertSeekableEquals(mediaElement, '{ }',
-                'The seekable attribute now returns an empty range.');
-              test.done();
-          }, "HTMLMediaElement.seekable returns the live seekable range or an empty range if that range was cleared when nothing is buffered");
 
+mediasource_test(function(test, mediaElement, mediaSource)
+{
+    mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
+    mediaSource.clearLiveSeekableRange();
+    test.done();
+}, "clearLiveSeekableRange returns with no error when conditions are correct");
 
-          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
-          {
-              var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
-              test.expectEvent(sourceBuffer, 'updateend', 'Init segment appended to SourceBuffer.');
-              sourceBuffer.appendBuffer(initSegment);
-              test.waitForExpectedEvents(function()
-              {
-                  mediaSource.duration = +Infinity;
-                  mediaSource.setLiveSeekableRange(40, 42);
 
-                  // Append a segment that starts after 1s to ensure seekable
-                  // won't use 0 as starting point.
-                  var midSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.media[5]);
-                  test.expectEvent(sourceBuffer, 'updateend');
-                  sourceBuffer.appendBuffer(midSegment);
-                  test.waitForExpectedEvents(function()
-                  {
-                      assert_equals(mediaElement.seekable.length, 1,
-                        'The seekable attribute contains a single range.');
-                      assert_equals(mediaElement.buffered.length, 1,
-                        'The buffered attribute contains a single range.');
-                      assert_not_equals(mediaElement.seekable.start(0), 0,
-                        'The range starts after 0.');
-                      assert_equals(mediaElement.seekable.start(0), mediaElement.buffered.start(0),
-                        'The start time is the start time of the buffered range.');
-                      assert_equals(mediaElement.seekable.end(0), 42,
-                        'The end time is the end time of the seekable range.');
+mediasource_test(function(test, mediaElement, mediaSource)
+{
+    mediaSource.duration = +Infinity;
+    mediaSource.setLiveSeekableRange(1, 2);
+    assert_equals(mediaElement.seekable.length, 1,
+      'The seekable attribute contains a single range.');
+    assertSeekableEquals(mediaElement, '{ [1.000, 2.000) }',
+      'The seekable attribute returns the correct range.');
 
-                      mediaSource.clearLiveSeekableRange();
-                      assert_equals(mediaElement.seekable.length, 1,
-                        'The seekable attribute contains a single range.');
-                      assert_equals(mediaElement.seekable.start(0), 0,
-                        'The start time is now 0.');
-                      assert_equals(mediaElement.seekable.end(0), mediaElement.buffered.end(0),
-                        'The end time is now the end time of the buffered range.');
+    mediaSource.clearLiveSeekableRange();
+    assertSeekableEquals(mediaElement, '{ }',
+      'The seekable attribute now returns an empty range.');
+    test.done();
+}, "HTMLMediaElement.seekable returns the live seekable range or an empty range if that range was cleared when nothing is buffered");
 
-                      test.done();
-                  });
-              });
-          }, 'HTMLMediaElement.seekable returns the union of the buffered range and the live seekable range, when set');
-        </script>
-    </body>
-</html>
+
+mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+{
+    var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
+    test.expectEvent(sourceBuffer, 'updateend', 'Init segment appended to SourceBuffer.');
+    sourceBuffer.appendBuffer(initSegment);
+    test.waitForExpectedEvents(function()
+    {
+        mediaSource.duration = +Infinity;
+        mediaSource.setLiveSeekableRange(40, 42);
+
+        // Append a segment that starts after 1s to ensure seekable
+        // won't use 0 as starting point.
+        var midSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.media[5]);
+        test.expectEvent(sourceBuffer, 'updateend');
+        sourceBuffer.appendBuffer(midSegment);
+        test.waitForExpectedEvents(function()
+        {
+            assert_equals(mediaElement.seekable.length, 1,
+              'The seekable attribute contains a single range.');
+            assert_equals(mediaElement.buffered.length, 1,
+              'The buffered attribute contains a single range.');
+            assert_not_equals(mediaElement.seekable.start(0), 0,
+              'The range starts after 0.');
+            assert_equals(mediaElement.seekable.start(0), mediaElement.buffered.start(0),
+              'The start time is the start time of the buffered range.');
+            assert_equals(mediaElement.seekable.end(0), 42,
+              'The end time is the end time of the seekable range.');
+
+            mediaSource.clearLiveSeekableRange();
+            assert_equals(mediaElement.seekable.length, 1,
+              'The seekable attribute contains a single range.');
+            assert_equals(mediaElement.seekable.start(0), 0,
+              'The start time is now 0.');
+            assert_equals(mediaElement.seekable.end(0), mediaElement.buffered.end(0),
+              'The end time is now the end time of the buffered range.');
+
+            test.done();
+        });
+    });
+}, 'HTMLMediaElement.seekable returns the union of the buffered range and the live seekable range, when set');
+</script>

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-remove-expected.txt (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-remove-expected.txt	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-remove-expected.txt	2016-09-19 23:30:53 UTC (rev 206129)
@@ -6,6 +6,7 @@
 PASS Test remove with a NEGATIVE_INFINITY end. 
 PASS Test remove with a NaN end. 
 PASS Test remove after SourceBuffer removed from mediaSource. 
+PASS Test remove with a NaN duration. 
 PASS Test remove while update pending. 
 PASS Test aborting a remove operation. 
 PASS Test remove with a start at the duration. 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-remove.html (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-remove.html	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-remove.html	2016-09-19 23:30:53 UTC (rev 206129)
@@ -2,6 +2,7 @@
 <!--  Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
 <html>
     <head>
+        <meta  charset="utf-8">
         <title>SourceBuffer.remove() test cases.</title>
         <script src=""
         <script src=""
@@ -14,6 +15,8 @@
           {
               var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
 
+              mediaSource.duration = 10;
+
               assert_throws(new TypeError(), function()
               {
                   sourceBuffer.remove(-1, 2);
@@ -26,6 +29,8 @@
           {
               var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
 
+              mediaSource.duration = 10;
+
               [ undefined, NaN, Infinity, -Infinity ].forEach(function(item)
               {
                   assert_throws(new TypeError(), function()
@@ -69,6 +74,8 @@
           {
               var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
 
+              mediaSource.duration = 10;
+
               assert_throws(new TypeError(), function()
               {
                   sourceBuffer.remove(0, Number.NEGATIVE_INFINITY);
@@ -81,6 +88,8 @@
           {
               var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
 
+              mediaSource.duration = 10;
+
               assert_throws(new TypeError(), function()
               {
                   sourceBuffer.remove(0, Number.NaN);
@@ -105,7 +114,21 @@
               test.done();
           }, "Test remove after SourceBuffer removed from mediaSource.");
 
+          mediasource_test(function(test, mediaElement, mediaSource)
+          {
+              var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
 
+              assert_false(sourceBuffer.updating, "updating is false");
+              assert_equals(mediaSource.duration, NaN, "duration isn't set");
+
+              assert_throws(new TypeError(), function()
+              {
+                  sourceBuffer.remove(0, 0);
+              }, "remove");
+
+              test.done();
+          }, "Test remove with a NaN duration.");
+
           mediasource_test(function(test, mediaElement, mediaSource)
           {
               var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
@@ -201,6 +224,7 @@
                   test.expectEvent(sourceBuffer, "updatestart");
                   test.expectEvent(sourceBuffer, "update");
                   test.expectEvent(sourceBuffer, "updateend");
+                  test.expectEvent(mediaSource, "sourceopen");
                   sourceBuffer.remove(1, 2);
 
                   assert_true(sourceBuffer.updating, "updating");

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-removesourcebuffer.html (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-removesourcebuffer.html	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-removesourcebuffer.html	2016-09-19 23:30:53 UTC (rev 206129)
@@ -42,11 +42,46 @@
 
               assert_throws("NotFoundError",
                   function() { mediaSource.removeSourceBuffer(sourceBuffer); },
-                  "removeSourceBuffer() threw an exception when a SourceBuffer that was already removed.");
+                  "removeSourceBuffer() threw an exception for a SourceBuffer that was already removed.");
 
               test.done();
           }, "Test calling removeSourceBuffer() twice with the same object.");
 
+          mediasource_test(function(test, mediaElement1, mediaSource1)
+          {
+              var sourceBuffer1 = mediaSource1.addSourceBuffer(MediaSourceUtil.AUDIO_ONLY_TYPE);
+              assert_class_string(sourceBuffer1, "SourceBuffer", "New SourceBuffer returned");
+
+              var mediaElement2 = document.createElement("video");
+              document.body.appendChild(mediaElement2);
+              test.add_cleanup(function() { document.body.removeChild(mediaElement2); });
+
+              var mediaSource2 = new MediaSource();
+              var mediaSource2URL = URL.createObjectURL(mediaSource2);
+              mediaElement2.src = ""
+              test.expectEvent(mediaSource2, "sourceopen", "Second MediaSource opened");
+              test.waitForExpectedEvents(function()
+              {
+                  URL.revokeObjectURL(mediaSource2URL);
+
+                  var sourceBuffer2 = mediaSource2.addSourceBuffer(MediaSourceUtil.VIDEO_ONLY_TYPE);
+                  assert_class_string(sourceBuffer2, "SourceBuffer", "Second new SourceBuffer returned");
+                  assert_not_equals(mediaSource1, mediaSource2, "MediaSources are different instances");
+                  assert_not_equals(sourceBuffer1, sourceBuffer2, "SourceBuffers are different instances");
+                  assert_equals(mediaSource1.sourceBuffers[0], sourceBuffer1);
+                  assert_equals(mediaSource2.sourceBuffers[0], sourceBuffer2);
+                  assert_throws("NotFoundError",
+                      function() { mediaSource1.removeSourceBuffer(sourceBuffer2); },
+                      "MediaSource1.removeSourceBuffer() threw an exception for SourceBuffer2");
+                  assert_throws("NotFoundError",
+                      function() { mediaSource2.removeSourceBuffer(sourceBuffer1); },
+                      "MediaSource2.removeSourceBuffer() threw an exception for SourceBuffer1");
+                  mediaSource1.removeSourceBuffer(sourceBuffer1);
+                  mediaSource2.removeSourceBuffer(sourceBuffer2);
+                  test.done();
+              });
+          }, "Test calling removeSourceBuffer() for a sourceBuffer belonging to a different mediaSource instance.");
+
           mediasource_test(function(test, mediaElement, mediaSource)
           {
               var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-seekable.html (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-seekable.html	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-seekable.html	2016-09-19 23:30:53 UTC (rev 206129)
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<!--  Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
 <meta charset="utf-8">
 <script src=""
 <script src=""

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-sourcebuffer-mode-timestamps.html (0 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-sourcebuffer-mode-timestamps.html	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-sourcebuffer-mode-timestamps.html	2016-09-19 23:30:53 UTC (rev 206129)
@@ -0,0 +1,52 @@
+<!doctype html>
+<html>
+<head>
+  <meta charset='utf-8'>
+  <title>SourceBuffer#mode with generate timestamps flag true</title>
+  <script src=""
+  <script src=""
+</head>
+<body>
+<div id="log"></div>
+
+<script>
+var mimes = ['audio/aac', 'audio/mpeg'];
+
+//check the browser supports the MIME used in this test
+function isTypeSupported(mime) {
+    if(!MediaSource.isTypeSupported(mime)) {
+        this.step(function() {
+            assert_unreached("Browser doesn't support the MIME used in this test: " + mime);
+        });
+        this.done();
+        return false;
+    }
+    return true;
+}
+function mediaTest(mime) {
+    async_test(function(t) {
+        if(!isTypeSupported.bind(t)(mime)) {
+            return;
+        }
+        var mediaSource = new MediaSource();
+        mediaSource.addEventListener('sourceopen', t.step_func_done(function(e) {
+            var sourceBuffer = mediaSource.addSourceBuffer(mime);
+            assert_equals(sourceBuffer.updating, false, "SourceBuffer.updating is false");
+            assert_throws({name: 'TypeError'},
+                          function() {
+                              sourceBuffer.mode = "segments";
+                          },
+                          'SourceBuffer#mode with generate timestamps flag true');
+        }), false);
+        var video = document.createElement('video');
+        video.src = ""
+    }, mime + ' : ' +
+       'If generate timestamps flag equals true and new mode equals "segments", ' +
+       'then throw a TypeError exception and abort these steps.');
+}
+mimes.forEach(function(mime) {
+    mediaTest(mime);
+});
+</script>
+</body>
+</html>

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-sourcebuffer-mode.html (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-sourcebuffer-mode.html	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-sourcebuffer-mode.html	2016-09-19 23:30:53 UTC (rev 206129)
@@ -2,6 +2,7 @@
 <!--  Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
 <html>
     <head>
+        <meta charset="utf-8">
         <title>SourceBuffer.mode test cases.</title>
         <script src=""
         <script src=""

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-sourcebuffer-trackdefaults.html (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-sourcebuffer-trackdefaults.html	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-sourcebuffer-trackdefaults.html	2016-09-19 23:30:53 UTC (rev 206129)
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<!--  Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
 <meta charset="utf-8">
 <script src=""
 <script src=""

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-timestamp-offset.html (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-timestamp-offset.html	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-timestamp-offset.html	2016-09-19 23:30:53 UTC (rev 206129)
@@ -17,6 +17,9 @@
                   var segmentInfo = MediaSourceUtil.SEGMENT_INFO;
                   var sourceBuffer = mediaSource.addSourceBuffer(segmentInfo.type);
 
+                  assert_equals(sourceBuffer.timestampOffset, 0,
+                      "Initial timestampOffset of a SourceBuffer is 0");
+
                   if (expected == "TypeError")  {
                       assert_throws({name: "TypeError"},
                           function() { sourceBuffer.timestampOffset = value; },

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-trackdefault.html (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-trackdefault.html	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-trackdefault.html	2016-09-19 23:30:53 UTC (rev 206129)
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<!--  Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
 <meta charset="utf-8">
 <script src=""
 <script src=""

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-trackdefaultlist.html (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-trackdefaultlist.html	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-trackdefaultlist.html	2016-09-19 23:30:53 UTC (rev 206129)
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
+<!--  Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
 <meta charset="utf-8">
 <script src=""
 <script src=""

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-util.js (206128 => 206129)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-util.js	2016-09-19 23:27:26 UTC (rev 206128)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-util.js	2016-09-19 23:30:53 UTC (rev 206129)
@@ -303,7 +303,7 @@
 
         var i = startingIndex;
         var _onAppendDone_ = function() {
-            if (eventFired)
+            if (eventFired || (i >= (segmentInfo.media.length - 1)))
                 return;
 
             i++;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to