Add some performance tests for various aspects of media loading and playback.
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 28 Nov 2016 17:22:30 +0000 (17:22 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 28 Nov 2016 17:22:30 +0000 (17:22 +0000)
https://bugs.webkit.org/show_bug.cgi?id=164977

Reviewed by Darin Adler.

PerformanceTests:

Add new tests for a few aspects of media playback; namely: how quickly  media elements fire
the "canplaythrough" event when all data is immediately available, how quickly HLS playback
switches resolutions, and at what playback rate MSE-backed video can play without dropping
frames. Skip these tests by default, as they're not runnable on all ports, and they require
a webserver (run-webkit-httpd) to complete on macOS.

* Media/HLSCanPlayThrough.html: Added.
* Media/HLSGearChange.html: Added.
* Media/MSECanPlayThrough.html: Added.
* Media/MSEPlaybackRate.html: Added.
* Media/StandardCanPlayThrough.html: Added.
* Media/hls/1080p/iframe_index.m3u8: Added.
* Media/hls/1080p/prog_index.m3u8: Added.
* Media/hls/1080p/test.ts: Added.
* Media/hls/480p/iframe_index.m3u8: Added.
* Media/hls/480p/prog_index.m3u8: Added.
* Media/hls/480p/test.ts: Added.
* Media/hls/720p/iframe_index.m3u8: Added.
* Media/hls/720p/prog_index.m3u8: Added.
* Media/hls/720p/test.ts: Added.
* Media/hls/720p/test.ts.back: Added.
* Media/hls/index.m3u8: Added.
* Media/media-source-loader.js: Added.
(MediaSourceLoader):
(MediaSourceLoader.prototype.loadManifest):
(MediaSourceLoader.prototype.loadManifestSucceeded):
(MediaSourceLoader.prototype.loadManifestFailed):
(MediaSourceLoader.prototype.loadMediaData):
(MediaSourceLoader.prototype.loadMediaDataSucceeded):
(MediaSourceLoader.prototype.loadMediaDataFailed):
(MediaSourceLoader.prototype.get type):
(MediaSourceLoader.prototype.get duration):
(MediaSourceLoader.prototype.get initSegment):
(MediaSourceLoader.prototype.get mediaSegmentsLength):
(MediaSourceLoader.prototype.mediaSegments):
(MediaSourceLoader.prototype.get everyMediaSegment):
* Media/test-fragmented-video.json: Added.
* Media/test-fragmented-video.mp4: Added.
* Media/test.mp4: Added.
* Skipped:

Tools:

Allow callers to pass in extra alias/directory pairs to run-webkit-httpd.

* Scripts/run-webkit-httpd:
(parse_args):
(main):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@208999 268f45cc-cd09-0410-ab3c-d52691b4dbfc

38 files changed:
PerformanceTests/ChangeLog
PerformanceTests/Media/HLSCanPlayThrough.html [new file with mode: 0644]
PerformanceTests/Media/HLSGearChange.html [new file with mode: 0644]
PerformanceTests/Media/MSECanPlayThrough.html [new file with mode: 0644]
PerformanceTests/Media/MSEPlaybackRate.html [new file with mode: 0644]
PerformanceTests/Media/StandardCanPlayThrough.html [new file with mode: 0644]
PerformanceTests/Media/hls/1080p/iframe_index.m3u8 [new file with mode: 0644]
PerformanceTests/Media/hls/1080p/prog_index.m3u8 [new file with mode: 0644]
PerformanceTests/Media/hls/1080p/test.ts [new file with mode: 0644]
PerformanceTests/Media/hls/1080p/test1.ts [new symlink]
PerformanceTests/Media/hls/1080p/test2.ts [new symlink]
PerformanceTests/Media/hls/1080p/test3.ts [new symlink]
PerformanceTests/Media/hls/1080p/test4.ts [new symlink]
PerformanceTests/Media/hls/1080p/test5.ts [new symlink]
PerformanceTests/Media/hls/480p/iframe_index.m3u8 [new file with mode: 0644]
PerformanceTests/Media/hls/480p/prog_index.m3u8 [new file with mode: 0644]
PerformanceTests/Media/hls/480p/test.ts [new file with mode: 0644]
PerformanceTests/Media/hls/480p/test1.ts [new symlink]
PerformanceTests/Media/hls/480p/test2.ts [new symlink]
PerformanceTests/Media/hls/480p/test3.ts [new symlink]
PerformanceTests/Media/hls/480p/test4.ts [new symlink]
PerformanceTests/Media/hls/480p/test5.ts [new symlink]
PerformanceTests/Media/hls/720p/iframe_index.m3u8 [new file with mode: 0644]
PerformanceTests/Media/hls/720p/prog_index.m3u8 [new file with mode: 0644]
PerformanceTests/Media/hls/720p/test.ts [new file with mode: 0644]
PerformanceTests/Media/hls/720p/test1.ts [new symlink]
PerformanceTests/Media/hls/720p/test2.ts [new symlink]
PerformanceTests/Media/hls/720p/test3.ts [new symlink]
PerformanceTests/Media/hls/720p/test4.ts [new symlink]
PerformanceTests/Media/hls/720p/test5.ts [new symlink]
PerformanceTests/Media/hls/index.m3u8 [new file with mode: 0644]
PerformanceTests/Media/media-source-loader.js [new file with mode: 0644]
PerformanceTests/Media/test-fragmented-video.json [new file with mode: 0644]
PerformanceTests/Media/test-fragmented-video.mp4 [new file with mode: 0644]
PerformanceTests/Media/test.mp4 [new file with mode: 0644]
PerformanceTests/Skipped
Tools/ChangeLog
Tools/Scripts/run-webkit-httpd

index 8ee3482..98484fc 100644 (file)
@@ -1,3 +1,51 @@
+2016-11-18  Jer Noble  <jer.noble@apple.com>
+
+        Add some performance tests for various aspects of media loading and playback.
+        https://bugs.webkit.org/show_bug.cgi?id=164977
+
+        Reviewed by Darin Adler.
+
+        Add new tests for a few aspects of media playback; namely: how quickly  media elements fire
+        the "canplaythrough" event when all data is immediately available, how quickly HLS playback
+        switches resolutions, and at what playback rate MSE-backed video can play without dropping
+        frames. Skip these tests by default, as they're not runnable on all ports, and they require
+        a webserver (run-webkit-httpd) to complete on macOS.
+
+        * Media/HLSCanPlayThrough.html: Added.
+        * Media/HLSGearChange.html: Added.
+        * Media/MSECanPlayThrough.html: Added.
+        * Media/MSEPlaybackRate.html: Added.
+        * Media/StandardCanPlayThrough.html: Added.
+        * Media/hls/1080p/iframe_index.m3u8: Added.
+        * Media/hls/1080p/prog_index.m3u8: Added.
+        * Media/hls/1080p/test.ts: Added.
+        * Media/hls/480p/iframe_index.m3u8: Added.
+        * Media/hls/480p/prog_index.m3u8: Added.
+        * Media/hls/480p/test.ts: Added.
+        * Media/hls/720p/iframe_index.m3u8: Added.
+        * Media/hls/720p/prog_index.m3u8: Added.
+        * Media/hls/720p/test.ts: Added.
+        * Media/hls/720p/test.ts.back: Added.
+        * Media/hls/index.m3u8: Added.
+        * Media/media-source-loader.js: Added.
+        (MediaSourceLoader):
+        (MediaSourceLoader.prototype.loadManifest):
+        (MediaSourceLoader.prototype.loadManifestSucceeded):
+        (MediaSourceLoader.prototype.loadManifestFailed):
+        (MediaSourceLoader.prototype.loadMediaData):
+        (MediaSourceLoader.prototype.loadMediaDataSucceeded):
+        (MediaSourceLoader.prototype.loadMediaDataFailed):
+        (MediaSourceLoader.prototype.get type):
+        (MediaSourceLoader.prototype.get duration):
+        (MediaSourceLoader.prototype.get initSegment):
+        (MediaSourceLoader.prototype.get mediaSegmentsLength):
+        (MediaSourceLoader.prototype.mediaSegments):
+        (MediaSourceLoader.prototype.get everyMediaSegment):
+        * Media/test-fragmented-video.json: Added.
+        * Media/test-fragmented-video.mp4: Added.
+        * Media/test.mp4: Added.
+        * Skipped:
+
 2016-11-18  Filip Pizlo  <fpizlo@apple.com>
 
         Concurrent GC should be able to run splay in debug mode and earley/raytrace in release mode with no perf regression
diff --git a/PerformanceTests/Media/HLSCanPlayThrough.html b/PerformanceTests/Media/HLSCanPlayThrough.html
new file mode 100644 (file)
index 0000000..6230356
--- /dev/null
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script>
+var video;
+var url;
+
+window.addEventListener('load', () => {
+    PerfTestRunner.prepareToMeasureValuesAsync({
+        unit: 'ms',
+        done: function () {
+            if (video) {
+                video.src = null;
+                video.load();
+            }
+        }
+    });
+
+    runTest();
+});
+
+function runTest() {   
+    video =  document.createElement('video');
+
+    var startTime = PerfTestRunner.now();
+    video.src = 'hls/720p/prog_index.m3u8';
+    video.addEventListener('canplaythrough', () => {
+        if (!PerfTestRunner.measureValueAsync(PerfTestRunner.now() - startTime))
+            return;
+
+        PerfTestRunner.gc();
+        setTimeout(runTest, 0);
+    });
+}
+
+</script>
+</head>
+<body>
+    <button onclick="pauseAll()">pause</button><button onclick="playAll()">play</button><br>
+</body>
+</html>
\ No newline at end of file
diff --git a/PerformanceTests/Media/HLSGearChange.html b/PerformanceTests/Media/HLSGearChange.html
new file mode 100644 (file)
index 0000000..d084066
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script>
+var video;
+var url;
+
+window.addEventListener('load', () => {
+    PerfTestRunner.prepareToMeasureValuesAsync({
+        unit: 'ms',
+        done: function () {
+            if (video) {
+                video.src = null;
+                video.load();
+            }
+        }
+    });
+
+    runTest();
+});
+
+function runTest() {   
+    video =  document.createElement('video');
+    document.body.appendChild(video);
+
+    video.src = 'hls/index.m3u8';
+    video.addEventListener('canplaythrough', () => {
+        video.play();
+        var startTime = PerfTestRunner.now();
+
+        video.addEventListener('resize', () => {
+            if (!PerfTestRunner.measureValueAsync(PerfTestRunner.now() - startTime))
+                return;
+
+            document.body.removeChild(video);
+            PerfTestRunner.gc();
+            setTimeout(runTest, 0);
+        })
+    });
+}
+
+</script>
+</head>
+<body>
+    <button onclick="pauseAll()">pause</button><button onclick="playAll()">play</button><br>
+</body>
+</html>
\ No newline at end of file
diff --git a/PerformanceTests/Media/MSECanPlayThrough.html b/PerformanceTests/Media/MSECanPlayThrough.html
new file mode 100644 (file)
index 0000000..10c69da
--- /dev/null
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="media-source-loader.js"></script>
+<script src="../resources/runner.js"></script>
+<script>
+var loader;
+var video;
+
+window.addEventListener('load', () => {
+    PerfTestRunner.prepareToMeasureValuesAsync({
+        unit: 'ms',
+        done: function () {
+            if (video) {
+                video.src = null;
+                video.load();
+            }
+        }
+    });
+
+    loader = new MediaSourceLoader('test-fragmented-video.json');
+    loader.loadMediaData().then(runTest);
+});
+
+function runTest() {   
+    video =  document.createElement('video');
+
+    var startTime = PerfTestRunner.now();
+    var loadPromise = loadMediaDataIntoVideo(video);
+    video.addEventListener('canplaythrough', () => {
+        if (!PerfTestRunner.measureValueAsync(PerfTestRunner.now() - startTime))
+            return;
+
+        loadPromise.then(() => {
+            PerfTestRunner.gc();
+            setTimeout(runTest, 0);
+        });
+    });
+}
+
+function loadMediaDataIntoVideo(video, segmentCount) {
+    return new Promise((resolve, reject) => {
+        var source = new MediaSource();
+        source.addEventListener('sourceopen', (e) => {
+            var source = e.target;
+            var currentMediaSegment = 0;
+            var sourceBuffer = source.addSourceBuffer(loader.type);
+            sourceBuffer.appendBuffer(loader.initSegment);
+
+            var appendedMediaSegment = false;
+            sourceBuffer.addEventListener('update', () => {
+
+                if (appendedMediaSegment) {
+                    if (source.readyState !== 'ended') {
+                        source.endOfStream();
+                        resolve();
+                    }
+                    return;
+                }
+
+                sourceBuffer.appendBuffer(loader.everyMediaSegment);
+                appendedMediaSegment = true;
+            });
+            sourceBuffer.addEventListener('error', error => {
+                reject();
+            });
+        });
+        video.src = URL.createObjectURL(source);
+    });
+}
+</script>
+</head>
+<body>
+</body>
+</html>
\ No newline at end of file
diff --git a/PerformanceTests/Media/MSEPlaybackRate.html b/PerformanceTests/Media/MSEPlaybackRate.html
new file mode 100644 (file)
index 0000000..dba4949
--- /dev/null
@@ -0,0 +1,192 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="media-source-loader.js"></script>
+<script src="../resources/runner.js"></script>
+<script>
+var loader;
+
+window.addEventListener('load', () => {
+    loader = new MediaSourceLoader('test-fragmented-video.json');
+    loader.loadMediaData().then(runTest);
+});
+
+function *range(start, end) {
+    while (start < end)
+        yield(start++);
+}
+
+function addVideos(count, autoplay) {
+    return new Promise((resolve, reject) => {
+        var promises = [];
+        var videos = [];
+        for (var i of range(0, count)) {
+            var video = document.createElement('video');
+            video.controls = false;
+            video.loop = true;
+            video.muted = true;
+            document.body.appendChild(video);
+            promises.push(loadMediaDataIntoVideo(video));
+            videos.push(video);
+        }
+        document.getElementById('video-count').innerText = videoCount();
+        Promise.all(promises).then(() => {
+            resolve(videos);
+        });
+    });
+}
+
+function removeVideos(count) {
+    while (count > 0) {
+        --count;
+        var video = document.querySelector('video:last-child');
+        video.src = '';
+        video.load();
+        document.body.removeChild(video);
+    }
+    document.getElementById('video-count').innerText = videoCount();
+}
+
+function loadMediaDataIntoVideo(video) {
+    return new Promise((resolve, reject) => {
+        var source = new MediaSource();
+        source.addEventListener('sourceopen', (e) => {
+            var source = e.target;
+            var currentMediaSegment = 0;
+            var sourceBuffer = source.addSourceBuffer(loader.type);
+            var mediaSegments = loader.mediaSegments();
+            sourceBuffer.appendBuffer(loader.initSegment);
+            sourceBuffer.addEventListener('update', () => {
+                if (source.readyState === 'closed') {
+                    resolve(video);
+                    return;
+                }
+                var nextSegment = mediaSegments.next();
+                if (nextSegment.done) {
+                    if (source.readyState !== 'ended') {
+                        source.endOfStream();
+                        resolve(video);
+                    }
+                    return;
+                }
+
+                sourceBuffer.appendBuffer(nextSegment.value);
+            });
+            sourceBuffer.addEventListener('error', (e) => {
+                reject();
+            });
+        });
+        video.src = URL.createObjectURL(source);
+    });
+}
+
+function videoCount() {
+    return document.querySelectorAll('video').length;
+}
+
+function totalDroppedFrames() {
+    var total = 0;
+    for (var video of document.querySelectorAll('video')) {
+        if (typeof(video.getVideoPlaybackQuality) !== 'undefined')
+            total += video.getVideoPlaybackQuality().droppedVideoFrames;
+        else if (typeof(video.webkitDroppedFrameCount) !== 'undefined')
+            total += video.webkitDroppedFrameCount;
+    }
+    return total;
+}
+
+function pauseAll() {
+    for (var video of document.querySelectorAll('video'))
+        video.pause();
+}
+
+function playVideos(videos) {
+    return new Promise((resolve, reject) => {
+        var promises = [];
+        for (var video of videos)
+            promises.push(video.play());
+        Promise.all(promises).then(() => { resolve(videos); });
+    });
+}
+    
+function playAll() {
+    playVideos(document.querySelectorAll('video'));
+}
+
+function runTest() {
+    addVideos(initialVideoCount).then(playVideos);
+    trySeekingFaster(1.6);
+}
+
+function finishTest() {
+    pauseAll();
+}
+
+var initialVideoCount = 10;
+var droppedFrameLimit = 1;
+var initialPlaybackRate = 1;
+
+function trySeekingFaster(value) {
+    initialPlaybackRate += value;
+    document.getElementById('video-speed').innerText = initialPlaybackRate;
+    for (var video of document.querySelectorAll('video'))
+        video.playbackRate = initialPlaybackRate;
+
+
+    setTimeout(() => {
+        var initialDroppedFrames = totalDroppedFrames();
+
+        setTimeout(() => {
+            var endingDroppedFrames = totalDroppedFrames();
+            document.getElementById('dropped-frame').innerText = endingDroppedFrames - initialDroppedFrames;
+
+            if (endingDroppedFrames - initialDroppedFrames <= droppedFrameLimit) {
+                if (value <= 0.05) {
+                    finishTest();
+                    return;
+                }
+
+                trySeekingFaster(value);
+            }
+            else
+                trySeekingSlower(value/2);
+        }, 1000);
+    }, 1000);
+}
+
+function trySeekingSlower(value) {
+    initialPlaybackRate -= value;
+    document.getElementById('video-speed').innerText = initialPlaybackRate;
+    for (var video of document.querySelectorAll('video'))
+        video.playbackRate = initialPlaybackRate;
+
+    setTimeout(() => {
+        var initialDroppedFrames = totalDroppedFrames();
+        setTimeout(() => {
+            var endingDroppedFrames = totalDroppedFrames();
+            document.getElementById('dropped-frame').innerText = endingDroppedFrames - initialDroppedFrames;
+
+            if (endingDroppedFrames - initialDroppedFrames <= droppedFrameLimit) {
+                if (value <= 0.05) {
+                    finishTest();
+                    return;
+                }
+
+                trySeekingFaster(value/2);
+            } else
+                trySeekingSlower(value);
+        }, 2000);
+    }, 2000);
+}
+
+</script>
+</head>
+<body>
+    <div>
+        Video Count: <span id="video-count">0</span> Speed: <span id="video-speed">0</span> Dropped Frame Delta: <span id="dropped-frame">0</span>
+    </div>
+    <div>
+        <button onclick="addVideos(1).then(playVideos)">add video</button><button onclick="removeVideos(1)">remove video</button><button onclick="pauseAll()">pause</button><button onclick="playAll()">play</button><br>
+    </div>
+</body>
+</html>
\ No newline at end of file
diff --git a/PerformanceTests/Media/StandardCanPlayThrough.html b/PerformanceTests/Media/StandardCanPlayThrough.html
new file mode 100644 (file)
index 0000000..14618f5
--- /dev/null
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script>
+var video;
+var url;
+
+window.addEventListener('load', () => {
+    PerfTestRunner.prepareToMeasureValuesAsync({
+        unit: 'ms',
+        done: function () {
+            if (video) {
+                video.src = null;
+                video.load();
+            }
+        }
+    });
+
+    loadMediaData('test.mp4').then((blob) => {
+        url = URL.createObjectURL(blob);
+        runTest();
+    });
+});
+
+function loadMediaData(url) {
+    return new Promise((resolve, reject) => {
+        var request = new XMLHttpRequest();
+        request.open('GET', url, true);
+        request.responseType = 'blob';
+        request.addEventListener('load', (event) => {
+            resolve(event.target.response);
+        });
+        request.addEventListener('error', (event) => {
+            reject(event.error);
+        });
+        request.send();
+    })
+}
+
+function runTest() {   
+    video =  document.createElement('video');
+
+    var startTime = PerfTestRunner.now();
+    video.src = url;
+    video.addEventListener('canplaythrough', () => {
+        if (!PerfTestRunner.measureValueAsync(PerfTestRunner.now() - startTime))
+            return;
+
+        PerfTestRunner.gc();
+        setTimeout(runTest, 0);
+    });
+}
+
+</script>
+</head>
+<body>
+    <button onclick="pauseAll()">pause</button><button onclick="playAll()">play</button><br>
+</body>
+</html>
\ No newline at end of file
diff --git a/PerformanceTests/Media/hls/1080p/iframe_index.m3u8 b/PerformanceTests/Media/hls/1080p/iframe_index.m3u8
new file mode 100644 (file)
index 0000000..9f19313
--- /dev/null
@@ -0,0 +1,271 @@
+#EXTM3U
+#EXT-X-TARGETDURATION:10
+#EXT-X-VERSION:4
+#EXT-X-MEDIA-SEQUENCE:0
+#EXT-X-PLAYLIST-TYPE:VOD
+#EXT-X-I-FRAMES-ONLY
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:30268@376
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:19928@97760
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20492@194392
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20868@277676
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:33276@373368
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:21056@483160
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20304@565692
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:19740@663076
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:47564@746548
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:19552@855776
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20492@952408
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20868@1035880
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:33464@1131384
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:21056@1241552
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20304@1324272
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:19740@1421092
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:47752@1504376
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:19740@1613980
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20492@1710424
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20680@1794084
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:33464@1889776
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:21056@1999944
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20680@2082852
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20116@2180236
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:47564@2263896
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:19740@2373124
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20492@2469756
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20868@2553792
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:33464@2649484
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:21056@2759652
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20492@2842748
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20116@2939756
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:47752@3023416
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:19928@3132832
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20304@3229840
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20868@3313500
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:33652@3409192
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20680@3519736
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20304@3602080
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:19740@3699088
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:47564@3782372
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:19740@3891600
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20492@3988420
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20868@4072268
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:33464@4168148
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:21056@4278316
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20492@4361224
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:19740@4458984
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:30268@376
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:19928@97760
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20492@194392
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20868@277676
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:33276@373368
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:21056@483160
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20304@565692
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:19740@663076
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:30268@376
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:19928@97760
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20492@194392
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20868@277676
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:33276@373368
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:21056@483160
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20304@565692
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:19740@663076
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:30268@376
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:19928@97760
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20492@194392
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20868@277676
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:33276@373368
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:21056@483160
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20304@565692
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:19740@663076
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:30268@376
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:19928@97760
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20492@194392
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20868@277676
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:33276@373368
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:21056@483160
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20304@565692
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:19740@663076
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:30268@376
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:19928@97760
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20492@194392
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20868@277676
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:33276@373368
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:21056@483160
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:20304@565692
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:19740@663076
+test.ts
+#EXT-X-ENDLIST
diff --git a/PerformanceTests/Media/hls/1080p/prog_index.m3u8 b/PerformanceTests/Media/hls/1080p/prog_index.m3u8
new file mode 100644 (file)
index 0000000..6a08553
--- /dev/null
@@ -0,0 +1,19 @@
+#EXTM3U
+#EXT-X-TARGETDURATION:10
+#EXT-X-VERSION:4
+#EXT-X-MEDIA-SEQUENCE:0
+#EXT-X-PLAYLIST-TYPE:VOD
+#EXT-X-INDEPENDENT-SEGMENTS
+#EXTINF:10.00000,      
+test.ts
+#EXTINF:10.00000,      
+test1.ts
+#EXTINF:10.00000,      
+test2.ts
+#EXTINF:10.00000,      
+test3.ts
+#EXTINF:10.00000,      
+test4.ts
+#EXTINF:10.00000,      
+test5.ts
+#EXT-X-ENDLIST
diff --git a/PerformanceTests/Media/hls/1080p/test.ts b/PerformanceTests/Media/hls/1080p/test.ts
new file mode 100644 (file)
index 0000000..d86e099
Binary files /dev/null and b/PerformanceTests/Media/hls/1080p/test.ts differ
diff --git a/PerformanceTests/Media/hls/1080p/test1.ts b/PerformanceTests/Media/hls/1080p/test1.ts
new file mode 120000 (symlink)
index 0000000..0c2fc0c
--- /dev/null
@@ -0,0 +1 @@
+test.ts
\ No newline at end of file
diff --git a/PerformanceTests/Media/hls/1080p/test2.ts b/PerformanceTests/Media/hls/1080p/test2.ts
new file mode 120000 (symlink)
index 0000000..0c2fc0c
--- /dev/null
@@ -0,0 +1 @@
+test.ts
\ No newline at end of file
diff --git a/PerformanceTests/Media/hls/1080p/test3.ts b/PerformanceTests/Media/hls/1080p/test3.ts
new file mode 120000 (symlink)
index 0000000..0c2fc0c
--- /dev/null
@@ -0,0 +1 @@
+test.ts
\ No newline at end of file
diff --git a/PerformanceTests/Media/hls/1080p/test4.ts b/PerformanceTests/Media/hls/1080p/test4.ts
new file mode 120000 (symlink)
index 0000000..0c2fc0c
--- /dev/null
@@ -0,0 +1 @@
+test.ts
\ No newline at end of file
diff --git a/PerformanceTests/Media/hls/1080p/test5.ts b/PerformanceTests/Media/hls/1080p/test5.ts
new file mode 120000 (symlink)
index 0000000..0c2fc0c
--- /dev/null
@@ -0,0 +1 @@
+test.ts
\ No newline at end of file
diff --git a/PerformanceTests/Media/hls/480p/iframe_index.m3u8 b/PerformanceTests/Media/hls/480p/iframe_index.m3u8
new file mode 100644 (file)
index 0000000..0de38bd
--- /dev/null
@@ -0,0 +1,151 @@
+#EXTM3U
+#EXT-X-TARGETDURATION:10
+#EXT-X-VERSION:4
+#EXT-X-MEDIA-SEQUENCE:0
+#EXT-X-PLAYLIST-TYPE:VOD
+#EXT-X-I-FRAMES-ONLY
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:22560@376
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:17672@79148
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:18048@154348
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:18424@225976
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:28388@299484
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:18612@385212
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:17860@454960
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:17484@532416
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:22560@376
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:17672@79148
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:18048@154348
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:18424@225976
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:28388@299484
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:18612@385212
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:17860@454960
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:17484@532416
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:22560@376
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:17672@79148
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:18048@154348
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:18424@225976
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:28388@299484
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:18612@385212
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:17860@454960
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:17484@532416
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:22560@376
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:17672@79148
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:18048@154348
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:18424@225976
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:28388@299484
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:18612@385212
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:17860@454960
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:17484@532416
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:22560@376
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:17672@79148
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:18048@154348
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:18424@225976
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:28388@299484
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:18612@385212
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:17860@454960
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:17484@532416
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:22560@376
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:17672@79148
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:18048@154348
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:18424@225976
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:28388@299484
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:18612@385212
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:17860@454960
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:17484@532416
+test.ts
+#EXT-X-ENDLIST
diff --git a/PerformanceTests/Media/hls/480p/prog_index.m3u8 b/PerformanceTests/Media/hls/480p/prog_index.m3u8
new file mode 100644 (file)
index 0000000..6a08553
--- /dev/null
@@ -0,0 +1,19 @@
+#EXTM3U
+#EXT-X-TARGETDURATION:10
+#EXT-X-VERSION:4
+#EXT-X-MEDIA-SEQUENCE:0
+#EXT-X-PLAYLIST-TYPE:VOD
+#EXT-X-INDEPENDENT-SEGMENTS
+#EXTINF:10.00000,      
+test.ts
+#EXTINF:10.00000,      
+test1.ts
+#EXTINF:10.00000,      
+test2.ts
+#EXTINF:10.00000,      
+test3.ts
+#EXTINF:10.00000,      
+test4.ts
+#EXTINF:10.00000,      
+test5.ts
+#EXT-X-ENDLIST
diff --git a/PerformanceTests/Media/hls/480p/test.ts b/PerformanceTests/Media/hls/480p/test.ts
new file mode 100644 (file)
index 0000000..cb92b4f
Binary files /dev/null and b/PerformanceTests/Media/hls/480p/test.ts differ
diff --git a/PerformanceTests/Media/hls/480p/test1.ts b/PerformanceTests/Media/hls/480p/test1.ts
new file mode 120000 (symlink)
index 0000000..0c2fc0c
--- /dev/null
@@ -0,0 +1 @@
+test.ts
\ No newline at end of file
diff --git a/PerformanceTests/Media/hls/480p/test2.ts b/PerformanceTests/Media/hls/480p/test2.ts
new file mode 120000 (symlink)
index 0000000..0c2fc0c
--- /dev/null
@@ -0,0 +1 @@
+test.ts
\ No newline at end of file
diff --git a/PerformanceTests/Media/hls/480p/test3.ts b/PerformanceTests/Media/hls/480p/test3.ts
new file mode 120000 (symlink)
index 0000000..0c2fc0c
--- /dev/null
@@ -0,0 +1 @@
+test.ts
\ No newline at end of file
diff --git a/PerformanceTests/Media/hls/480p/test4.ts b/PerformanceTests/Media/hls/480p/test4.ts
new file mode 120000 (symlink)
index 0000000..0c2fc0c
--- /dev/null
@@ -0,0 +1 @@
+test.ts
\ No newline at end of file
diff --git a/PerformanceTests/Media/hls/480p/test5.ts b/PerformanceTests/Media/hls/480p/test5.ts
new file mode 120000 (symlink)
index 0000000..0c2fc0c
--- /dev/null
@@ -0,0 +1 @@
+test.ts
\ No newline at end of file
diff --git a/PerformanceTests/Media/hls/720p/iframe_index.m3u8 b/PerformanceTests/Media/hls/720p/iframe_index.m3u8
new file mode 100644 (file)
index 0000000..866d7ca
--- /dev/null
@@ -0,0 +1,151 @@
+#EXTM3U
+#EXT-X-TARGETDURATION:10
+#EXT-X-VERSION:4
+#EXT-X-MEDIA-SEQUENCE:0
+#EXT-X-PLAYLIST-TYPE:VOD
+#EXT-X-I-FRAMES-ONLY
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:39292@376
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:30268@135924
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:31020@266208
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:31960@385024
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:47564@513428
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:32148@659880
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:31020@777004
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:30080@908040
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:39292@376
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:30268@135924
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:31020@266208
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:31960@385024
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:47564@513428
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:32148@659880
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:31020@777004
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:30080@908040
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:39292@376
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:30268@135924
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:31020@266208
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:31960@385024
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:47564@513428
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:32148@659880
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:31020@777004
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:30080@908040
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:39292@376
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:30268@135924
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:31020@266208
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:31960@385024
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:47564@513428
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:32148@659880
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:31020@777004
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:30080@908040
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:39292@376
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:30268@135924
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:31020@266208
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:31960@385024
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:47564@513428
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:32148@659880
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:31020@777004
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:30080@908040
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:39292@376
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:30268@135924
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:31020@266208
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:31960@385024
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:47564@513428
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:32148@659880
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:31020@777004
+test.ts
+#EXTINF:1.25000,       
+#EXT-X-BYTERANGE:30080@908040
+test.ts
+#EXT-X-ENDLIST
diff --git a/PerformanceTests/Media/hls/720p/prog_index.m3u8 b/PerformanceTests/Media/hls/720p/prog_index.m3u8
new file mode 100644 (file)
index 0000000..6a08553
--- /dev/null
@@ -0,0 +1,19 @@
+#EXTM3U
+#EXT-X-TARGETDURATION:10
+#EXT-X-VERSION:4
+#EXT-X-MEDIA-SEQUENCE:0
+#EXT-X-PLAYLIST-TYPE:VOD
+#EXT-X-INDEPENDENT-SEGMENTS
+#EXTINF:10.00000,      
+test.ts
+#EXTINF:10.00000,      
+test1.ts
+#EXTINF:10.00000,      
+test2.ts
+#EXTINF:10.00000,      
+test3.ts
+#EXTINF:10.00000,      
+test4.ts
+#EXTINF:10.00000,      
+test5.ts
+#EXT-X-ENDLIST
diff --git a/PerformanceTests/Media/hls/720p/test.ts b/PerformanceTests/Media/hls/720p/test.ts
new file mode 100644 (file)
index 0000000..ebe6c06
Binary files /dev/null and b/PerformanceTests/Media/hls/720p/test.ts differ
diff --git a/PerformanceTests/Media/hls/720p/test1.ts b/PerformanceTests/Media/hls/720p/test1.ts
new file mode 120000 (symlink)
index 0000000..0c2fc0c
--- /dev/null
@@ -0,0 +1 @@
+test.ts
\ No newline at end of file
diff --git a/PerformanceTests/Media/hls/720p/test2.ts b/PerformanceTests/Media/hls/720p/test2.ts
new file mode 120000 (symlink)
index 0000000..0c2fc0c
--- /dev/null
@@ -0,0 +1 @@
+test.ts
\ No newline at end of file
diff --git a/PerformanceTests/Media/hls/720p/test3.ts b/PerformanceTests/Media/hls/720p/test3.ts
new file mode 120000 (symlink)
index 0000000..0c2fc0c
--- /dev/null
@@ -0,0 +1 @@
+test.ts
\ No newline at end of file
diff --git a/PerformanceTests/Media/hls/720p/test4.ts b/PerformanceTests/Media/hls/720p/test4.ts
new file mode 120000 (symlink)
index 0000000..0c2fc0c
--- /dev/null
@@ -0,0 +1 @@
+test.ts
\ No newline at end of file
diff --git a/PerformanceTests/Media/hls/720p/test5.ts b/PerformanceTests/Media/hls/720p/test5.ts
new file mode 120000 (symlink)
index 0000000..0c2fc0c
--- /dev/null
@@ -0,0 +1 @@
+test.ts
\ No newline at end of file
diff --git a/PerformanceTests/Media/hls/index.m3u8 b/PerformanceTests/Media/hls/index.m3u8
new file mode 100644 (file)
index 0000000..2a0eb57
--- /dev/null
@@ -0,0 +1,10 @@
+#EXTM3U
+#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=489279,BANDWIDTH=491959,CODECS="avc1.4d401e",RESOLUTION=640x480,FRAME-RATE=24.000,CLOSED-CAPTIONS=NONE
+480p/prog_index.m3u8
+#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=135436,BANDWIDTH=215373,CODECS="avc1.4d401e",RESOLUTION=640x480,URI="480p/iframe_index.m3u8"
+#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=755703,BANDWIDTH=838932,CODECS="avc1.64001f",RESOLUTION=1280x720,FRAME-RATE=24.000,CLOSED-CAPTIONS=NONE
+720p/prog_index.m3u8
+#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=213333,BANDWIDTH=404276,CODECS="avc1.64001f",RESOLUTION=1280x720,URI="720p/iframe_index.m3u8"
+#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=562481,BANDWIDTH=610474,CODECS="avc1.4d4028",RESOLUTION=1920x1080,FRAME-RATE=24.000,CLOSED-CAPTIONS=NONE
+1080p/prog_index.m3u8
+#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=150400,BANDWIDTH=306816,CODECS="avc1.4d4028",RESOLUTION=1920x1080,URI="1080p/iframe_index.m3u8"
diff --git a/PerformanceTests/Media/media-source-loader.js b/PerformanceTests/Media/media-source-loader.js
new file mode 100644 (file)
index 0000000..8af4015
--- /dev/null
@@ -0,0 +1,124 @@
+class MediaSourceLoader {
+    constructor(url)
+    {
+        this._url = url;
+        this.onload = null;
+        this.onerror = null;
+    }
+
+    loadManifest()
+    {
+        return new Promise((resolve, reject) => {
+            if (this._manifest) {
+                resolve();
+                return;
+            }
+
+            var request = new XMLHttpRequest();
+            request.open('GET', this._url, true);
+            request.responseType = 'json';
+            request.onload = (event) => {
+                this.loadManifestSucceeded(event);
+                resolve();
+            }
+            request.onerror = (event) => {
+                this.loadManifestFailed(event);
+                reject(event);
+            }
+            request.send();
+        })
+    }
+
+    loadManifestSucceeded(event)
+    {
+        this._manifest = event.target.response;
+
+        if (!this._manifest || !this._manifest.url) {
+            if (this.onerror)
+                this.onerror();
+            return;
+        }
+    }
+
+    loadManifestFailed()
+    {
+        if (this.onerror)
+            this.onerror();
+    }
+
+    loadMediaData()
+    {
+        return new Promise((resolve, reject) => {
+            this.loadManifest().then(() => {
+                var request = new XMLHttpRequest();
+                request.open('GET', this._manifest.url, true);
+                request.responseType = 'arraybuffer';
+                request.onload = (event) => {
+                    this.loadMediaDataSucceeded(event);
+                    resolve();
+                }
+                request.onerror = (event) => {
+                    this.loadMediaDataFailed(event);
+                    reject(event);
+                }
+                request.send();
+            });
+        });
+    }
+
+    loadMediaDataSucceeded(event)
+    {
+        this._mediaData = event.target.response;
+
+        if (this.onload)
+            this.onload();
+    }
+
+    loadMediaDataFailed()
+    {
+        if (this.onerror)
+            this.onerror();
+    }
+
+    get type()
+    {
+        return this._manifest ? this._manifest.type : "";
+    }
+
+    get duration()
+    {
+        return this._manifest ? this._manifest.duration : 0
+    }
+
+    get initSegment()
+    {
+        if (!this._manifest || !this._manifest.init || !this._mediaData)
+            return null;
+        var init = this._manifest.init;
+        return this._mediaData.slice(init.offset, init.offset + init.size);
+    }
+
+    get mediaSegmentsLength()
+    {
+        if (!this._manifest || !this._manifest.media)
+            return 0;
+        return this._manifest.media.length;   
+    }
+
+    *mediaSegments()
+    {
+        if (!this._manifest || !this._manifest.media || !this._mediaData)
+            return;
+
+        for (var media of this._manifest.media)
+            yield this._mediaData.slice(media.offset, media.offset + media.size);
+    }
+
+    get everyMediaSegment()
+    {
+        if (!this._manifest || !this._manifest.media || !this._mediaData)
+            return null;
+
+        return this._mediaData.slice(this._manifest.media[0].offset);
+    }
+};
\ No newline at end of file
diff --git a/PerformanceTests/Media/test-fragmented-video.json b/PerformanceTests/Media/test-fragmented-video.json
new file mode 100644 (file)
index 0000000..6c898c9
--- /dev/null
@@ -0,0 +1,70 @@
+{
+    "url": "test-fragmented-video.mp4",
+    "type": "video/mp4; codecs=\"avc1.42c00d\"",
+    "init": {
+        "offset": 0,
+        "size": 692
+    },
+    "media": [
+        {
+            "offset": 692,
+            "size": 39865,
+            "timestamp": 0,
+            "duration": 1
+        },
+        {
+            "offset": 40557,
+            "size": 39333,
+            "timestamp": 1,
+            "duration": 1
+        },
+        {
+            "offset": 79890,
+            "size": 42651,
+            "timestamp": 2,
+            "duration": 1
+        },
+        {
+            "offset": 122541,
+            "size": 39979,
+            "timestamp": 3,
+            "duration": 1
+        },
+        {
+            "offset": 162520,
+            "size": 42743,
+            "timestamp": 4,
+            "duration": 1
+        },
+        {
+            "offset": 205263,
+            "size": 39869,
+            "timestamp": 5,
+            "duration": 1
+        },
+        {
+            "offset": 245132,
+            "size": 42718,
+            "timestamp": 6,
+            "duration": 1
+        },
+        {
+            "offset": 287850,
+            "size": 40327,
+            "timestamp": 7,
+            "duration": 1
+        },
+        {
+            "offset": 328177,
+            "size": 42830,
+            "timestamp": 8,
+            "duration": 1
+        },
+        {
+            "offset": 371007,
+            "size": 39738,
+            "timestamp": 9,
+            "duration": 1
+        }
+    ]
+}
\ No newline at end of file
diff --git a/PerformanceTests/Media/test-fragmented-video.mp4 b/PerformanceTests/Media/test-fragmented-video.mp4
new file mode 100644 (file)
index 0000000..c8b5e24
Binary files /dev/null and b/PerformanceTests/Media/test-fragmented-video.mp4 differ
diff --git a/PerformanceTests/Media/test.mp4 b/PerformanceTests/Media/test.mp4
new file mode 100644 (file)
index 0000000..8cbcdcc
Binary files /dev/null and b/PerformanceTests/Media/test.mp4 differ
index bbfcc3a..0ee503e 100644 (file)
@@ -104,3 +104,6 @@ Animation/css-accelerated-animation.html
 Animation/raf-animation.html
 Animation/svg-animation.html
 
+# Media tests take too long to run; require MSE, HLS which are not supported on all ports;
+# and require a webserver (run-webkit-httpd) which is not part of normal performance testing.
+Media/
index f7f6171..11b40bb 100644 (file)
@@ -1,3 +1,16 @@
+2016-11-18  Jer Noble  <jer.noble@apple.com>
+
+        Add some performance tests for various aspects of media loading and playback.
+        https://bugs.webkit.org/show_bug.cgi?id=164977
+
+        Reviewed by Darin Adler.
+
+        Allow callers to pass in extra alias/directory pairs to run-webkit-httpd.
+
+        * Scripts/run-webkit-httpd:
+        (parse_args):
+        (main):
+
 2016-11-27  Simon Fraser  <simon.fraser@apple.com>
 
         Another fix for CMake.
index f688ca6..42aec6f 100755 (executable)
@@ -44,6 +44,7 @@ def parse_args(args):
     parser.add_option("-p", "--port", help="Bind to port NNNN", action="store", type="int", dest="http_port")
     parser.add_option("--no-httpd", help="Do not start httpd server", action="store_false", default=True, dest="httpd_server")
     parser.add_option("--no-wpt", help="Do not start web-platform-tests server", action="store_false", default=True, dest="web_platform_test_server")
+    parser.add_option("-D", "--additional-dir", help="Additional directory and alias", action="append", default=[], type="string", nargs=2, dest="additional_dirs")
     return parser.parse_args(args)
 
 def main(argv, stdout, stderr):
@@ -73,7 +74,8 @@ def main(argv, stdout, stderr):
         else:
             print "Starting httpd on <http://127.0.0.1:%s>" % http_port
 
-        port.start_http_server()
+        additionalDirs = {additional_dir[0]: additional_dir[1] for additional_dir in options.additional_dirs}
+        port.start_http_server(additionalDirs)
         port.start_websocket_server()
 
     try: