OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 | 5 |
6 // The file runs a series of Media Source Entensions (MSE) operations on a | 6 // The file runs a series of Media Source Entensions (MSE) operations on a |
7 // video tag. The test takes several URL parameters described in | 7 // video tag. The test takes several URL parameters described in |
8 //loadTestParams() function. | 8 //loadTestParams() function. |
9 | 9 |
10 (function() { | 10 (function() { |
(...skipping 17 matching lines...) Expand all Loading... |
28 | 28 |
29 return params; | 29 return params; |
30 } | 30 } |
31 | 31 |
32 var testParams; | 32 var testParams; |
33 function loadTestParams() { | 33 function loadTestParams() { |
34 var queryParameters = parseQueryParameters(); | 34 var queryParameters = parseQueryParameters(); |
35 testParams = {}; | 35 testParams = {}; |
36 testParams.testType = queryParameters["testType"] || "AV"; | 36 testParams.testType = queryParameters["testType"] || "AV"; |
37 testParams.useAppendStream = (queryParameters["useAppendStream"] == "true"); | 37 testParams.useAppendStream = (queryParameters["useAppendStream"] == "true"); |
38 testParams.doNotWaitForBodyOnLoad = (queryParameters["doNotWaitForBodyOnLoad
"] == "true"); | 38 testParams.doNotWaitForBodyOnLoad = |
| 39 (queryParameters["doNotWaitForBodyOnLoad"] == "true"); |
39 testParams.startOffset = 0; | 40 testParams.startOffset = 0; |
40 testParams.appendSize = parseInt(queryParameters["appendSize"] || "65536"); | 41 testParams.appendSize = parseInt(queryParameters["appendSize"] || "65536"); |
41 testParams.graphDuration = parseInt(queryParameters["graphDuration"] || "100
0"); | 42 testParams.graphDuration = |
| 43 parseInt(queryParameters["graphDuration"] || "1000"); |
42 } | 44 } |
43 | 45 |
44 function plotTimestamps(timestamps, graphDuration, element) { | 46 function plotTimestamps(timestamps, graphDuration, element) { |
| 47 if (!timestamps) |
| 48 return; |
45 var c = document.getElementById('c'); | 49 var c = document.getElementById('c'); |
46 var ctx = c.getContext('2d'); | 50 var ctx = c.getContext('2d'); |
47 | 51 |
48 var bars = [ | 52 var bars = [ |
49 { label: 'Page Load Total', | 53 { label: 'Page Load Total', |
50 start: pageStartTime, | 54 start: pageStartTime, |
51 end: pageEndTime, | 55 end: pageEndTime, |
52 color: '#404040' }, | 56 color: '#404040' }, |
53 { label: 'body.onload Delay', | 57 { label: 'body.onload Delay', |
54 start: pageStartTime, | 58 start: pageStartTime, |
(...skipping 18 matching lines...) Expand all Loading... |
73 color: '#0088FF' }); | 77 color: '#0088FF' }); |
74 bars.push({ label: 'Append', | 78 bars.push({ label: 'Append', |
75 start: appender.appendStartTime, | 79 start: appender.appendStartTime, |
76 end: appender.appendEndTime, | 80 end: appender.appendEndTime, |
77 color: '#00FFFF' }); | 81 color: '#00FFFF' }); |
78 if (appender.appendEndTime > maxAppendEndTime) { | 82 if (appender.appendEndTime > maxAppendEndTime) { |
79 maxAppendEndTime = appender.appendEndTime; | 83 maxAppendEndTime = appender.appendEndTime; |
80 } | 84 } |
81 } | 85 } |
82 | 86 |
83 bars.push({label: 'Post Append Delay', start: maxAppendEndTime, end: timesta
mps.testEndTime, color: '#B0B0B0' }); | 87 bars.push({ |
| 88 label: 'Post Append Delay', |
| 89 start: maxAppendEndTime, |
| 90 end: timestamps.testEndTime, |
| 91 color: '#B0B0B0' }); |
84 | 92 |
85 var minTimestamp = Number.MAX_VALUE; | 93 var minTimestamp = Number.MAX_VALUE; |
86 for (var i = 0; i < bars.length; ++i) { | 94 for (var i = 0; i < bars.length; ++i) { |
87 minTimestamp = Math.min(minTimestamp, bars[i].start); | 95 minTimestamp = Math.min(minTimestamp, bars[i].start); |
88 } | 96 } |
89 | 97 |
90 var graphWidth = c.width - 100; | 98 var graphWidth = c.width - 100; |
91 function convertTimestampToX(t) { | 99 function convertTimestampToX(t) { |
92 return graphWidth * (t - minTimestamp) / graphDuration; | 100 return graphWidth * (t - minTimestamp) / graphDuration; |
93 } | 101 } |
(...skipping 19 matching lines...) Expand all Loading... |
113 function displayResults(stats) { | 121 function displayResults(stats) { |
114 var statsDiv = document.getElementById('stats'); | 122 var statsDiv = document.getElementById('stats'); |
115 | 123 |
116 if (!stats) { | 124 if (!stats) { |
117 statsDiv.innerHTML = "Test failed"; | 125 statsDiv.innerHTML = "Test failed"; |
118 return; | 126 return; |
119 } | 127 } |
120 | 128 |
121 var statsMarkup = "Test passed<br><table>"; | 129 var statsMarkup = "Test passed<br><table>"; |
122 for (var i in stats) { | 130 for (var i in stats) { |
123 statsMarkup += "<tr><td style=\"text-align:right\">" + i + ":</td><td>" +
stats[i].toFixed(3) + " ms</td>"; | 131 statsMarkup += "<tr><td style=\"text-align:right\">" + i + ":</td><td>" + |
| 132 stats[i].toFixed(3) + " ms</td>"; |
124 } | 133 } |
125 statsMarkup += "</table>"; | 134 statsMarkup += "</table>"; |
126 statsDiv.innerHTML = statsMarkup; | 135 statsDiv.innerHTML = statsMarkup; |
127 } | 136 } |
128 | 137 |
129 function reportTelemetryMediaMetrics(stats, element) { | 138 function reportTelemetryMediaMetrics(stats, element) { |
130 var metrics = {}; | 139 var metrics = {}; |
131 for (var i = 0; i < stats.length; ++i) { | 140 for (var i = 0; i < stats.length; ++i) { |
132 var bar = stats[i]; | 141 var bar = stats[i]; |
133 var label = bar.label.toLowerCase().replace(/\s+|\./g, '_'); | 142 var label = bar.label.toLowerCase().replace(/\s+|\./g, '_'); |
(...skipping 15 matching lines...) Expand all Loading... |
149 | 158 |
150 function updateControls(testParams) { | 159 function updateControls(testParams) { |
151 var testTypeElement = document.getElementById("testType"); | 160 var testTypeElement = document.getElementById("testType"); |
152 for (var i in testTypeElement.options) { | 161 for (var i in testTypeElement.options) { |
153 var option = testTypeElement.options[i]; | 162 var option = testTypeElement.options[i]; |
154 if (option.value == testParams.testType) { | 163 if (option.value == testParams.testType) { |
155 testTypeElement.selectedIndex = option.index; | 164 testTypeElement.selectedIndex = option.index; |
156 } | 165 } |
157 } | 166 } |
158 | 167 |
159 document.getElementById("useAppendStream").checked = testParams.useAppendStr
eam; | 168 document.getElementById("useAppendStream").checked = |
160 document.getElementById("doNotWaitForBodyOnLoad").checked = testParams.doNot
WaitForBodyOnLoad; | 169 testParams.useAppendStream; |
| 170 document.getElementById("doNotWaitForBodyOnLoad").checked = |
| 171 testParams.doNotWaitForBodyOnLoad; |
161 document.getElementById("appendSize").value = testParams.appendSize; | 172 document.getElementById("appendSize").value = testParams.appendSize; |
162 document.getElementById("graphDuration").value = testParams.graphDuration; | 173 document.getElementById("graphDuration").value = testParams.graphDuration; |
163 } | 174 } |
164 | 175 |
165 function BufferAppender(mimetype, url, id, startOffset, appendSize) { | 176 function BufferAppender(mimetype, url, id, startOffset, appendSize) { |
166 this.mimetype = mimetype; | 177 this.mimetype = mimetype; |
167 this.url = url; | 178 this.url = url; |
168 this.id = id; | 179 this.id = id; |
169 this.startOffset = startOffset; | 180 this.startOffset = startOffset; |
170 this.appendSize = appendSize; | 181 this.appendSize = appendSize; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 | 259 |
249 StreamAppender.prototype.start = function() { | 260 StreamAppender.prototype.start = function() { |
250 this.xhr.addEventListener('readystatechange', | 261 this.xhr.addEventListener('readystatechange', |
251 this.attemptAppend.bind(this)); | 262 this.attemptAppend.bind(this)); |
252 this.xhr.addEventListener('loadend', this.onLoadEnd.bind(this)); | 263 this.xhr.addEventListener('loadend', this.onLoadEnd.bind(this)); |
253 this.xhr.open('GET', this.url); | 264 this.xhr.open('GET', this.url); |
254 this.xhr.setRequestHeader('Range', 'bytes=' + this.startOffset + '-' + | 265 this.xhr.setRequestHeader('Range', 'bytes=' + this.startOffset + '-' + |
255 (this.startOffset + this.appendSize - 1)); | 266 (this.startOffset + this.appendSize - 1)); |
256 this.xhr.responseType = 'stream'; | 267 this.xhr.responseType = 'stream'; |
257 if (this.xhr.responseType != 'stream') { | 268 if (this.xhr.responseType != 'stream') { |
258 throw "XHR does not support 'stream' responses."; | 269 EndTest("XHR does not support 'stream' responses."); |
259 } | 270 } |
260 this.xhr.send(); | 271 this.xhr.send(); |
261 | 272 |
262 this.xhrStartTime = getPerfTimestamp(); | 273 this.xhrStartTime = getPerfTimestamp(); |
263 }; | 274 }; |
264 | 275 |
265 StreamAppender.prototype.onLoadEnd = function() { | 276 StreamAppender.prototype.onLoadEnd = function() { |
266 this.xhrEndTime = getPerfTimestamp(); | 277 this.xhrEndTime = getPerfTimestamp(); |
267 this.attemptAppend(); | 278 this.attemptAppend(); |
268 }; | 279 }; |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 doneCallback(stats, timestamps); | 425 doneCallback(stats, timestamps); |
415 }; | 426 }; |
416 | 427 |
417 mediaElement.addEventListener('timeupdate', checkForCurrentTimeChange); | 428 mediaElement.addEventListener('timeupdate', checkForCurrentTimeChange); |
418 | 429 |
419 listener = setInterval(checkForCurrentTimeChange, 15); | 430 listener = setInterval(checkForCurrentTimeChange, 15); |
420 timeout = setTimeout(function() { | 431 timeout = setTimeout(function() { |
421 if (testDone) | 432 if (testDone) |
422 return; | 433 return; |
423 | 434 |
424 console.log('Test timed out.'); | |
425 testDone = true; | 435 testDone = true; |
426 window.clearInterval(listener); | 436 window.clearInterval(listener); |
427 | 437 |
428 mediaElement.pause(); | 438 mediaElement.pause(); |
429 doneCallback(null); | 439 doneCallback(null); |
| 440 EndTest("Test timed out."); |
430 }, 10000); | 441 }, 10000); |
431 | 442 |
432 mediaSourceOpenStartTime = getPerfTimestamp(); | 443 mediaSourceOpenStartTime = getPerfTimestamp(); |
433 mediaElement.src = URL.createObjectURL(mediaSource); | 444 mediaElement.src = URL.createObjectURL(mediaSource); |
434 }; | 445 }; |
435 | 446 |
436 function onBodyLoad() { | 447 function onBodyLoad() { |
437 bodyLoadTime = getPerfTimestamp(); | 448 bodyLoadTime = getPerfTimestamp(); |
438 | 449 |
439 if (!testParams.doNotWaitForBodyOnLoad) { | 450 if (!testParams.doNotWaitForBodyOnLoad) { |
440 startTest(); | 451 startTest(); |
441 } | 452 } |
442 } | 453 } |
443 | 454 |
444 function startTest() { | 455 function startTest() { |
445 updateControls(testParams); | 456 updateControls(testParams); |
446 | 457 |
447 var appenders = []; | 458 var appenders = []; |
448 | 459 |
449 if (useAppendStream && !window.MediaSource) | 460 if (testParams.useAppendStream && !window.MediaSource) |
450 throw "Can't use appendStream() because the unprefixed MediaSource object
is not present."; | 461 EndTest("Can't use appendStream() because the unprefixed MediaSource " + |
| 462 "object is not present."); |
451 | 463 |
452 var Appender = testParams.useAppendStream ? StreamAppender : BufferAppender; | 464 var Appender = testParams.useAppendStream ? StreamAppender : BufferAppender; |
453 | 465 |
454 if (testParams.testType.indexOf("A") != -1) { | 466 if (testParams.testType.indexOf("A") != -1) { |
455 appenders.push(new Appender("audio/mp4; codecs=\"mp4a.40.2\"", "audio.mp4"
, "a", testParams.startOffset, testParams.appendSize)); | 467 appenders.push( |
| 468 new Appender("audio/mp4; codecs=\"mp4a.40.2\"", |
| 469 "audio.mp4", |
| 470 "a", |
| 471 testParams.startOffset, |
| 472 testParams.appendSize)); |
456 } | 473 } |
457 | 474 |
458 if (testParams.testType.indexOf("V") != -1) { | 475 if (testParams.testType.indexOf("V") != -1) { |
459 appenders.push(new Appender("video/mp4; codecs=\"avc1.640028\"", "video.mp
4", "v", testParams.startOffset, testParams.appendSize)); | 476 appenders.push( |
| 477 new Appender("video/mp4; codecs=\"avc1.640028\"", |
| 478 "video.mp4", |
| 479 "v", |
| 480 testParams.startOffset, |
| 481 testParams.appendSize)); |
460 } | 482 } |
461 | 483 |
462 var video = document.getElementById('v'); | 484 var video = document.getElementById("v"); |
| 485 video.addEventListener("error", function(e) { |
| 486 console.log("video error!"); |
| 487 EndTest("Video error: " + video.error); |
| 488 }); |
| 489 |
463 video.id = getTestID(); | 490 video.id = getTestID(); |
464 runAppendTest(video, appenders, function(stats, timestamps) { | 491 runAppendTest(video, appenders, function(stats, timestamps) { |
465 displayResults(stats); | 492 displayResults(stats); |
466 plotTimestamps(timestamps, testParams.graphDuration, video); | 493 plotTimestamps(timestamps, testParams.graphDuration, video); |
467 window.__testDone = true; | 494 EndTest("Call back call done."); |
468 }); | 495 }); |
469 } | 496 } |
470 | 497 |
| 498 function EndTest(msg) { |
| 499 console.log("Ending test: " + msg); |
| 500 window.__testDone = true; |
| 501 } |
| 502 |
471 function getTestID() { | 503 function getTestID() { |
472 console.log("setting test ID") | |
473 console.log(testParams.doNotWaitForBodyOnLoad) | |
474 var id = testParams.testType; | 504 var id = testParams.testType; |
475 if (testParams.useAppendStream) | 505 if (testParams.useAppendStream) |
476 id += "_stream" | 506 id += "_stream" |
477 else | 507 else |
478 id += "_buffer" | 508 id += "_buffer" |
479 if (testParams.doNotWaitForBodyOnLoad) | 509 if (testParams.doNotWaitForBodyOnLoad) |
480 id += "_pre_load" | 510 id += "_pre_load" |
481 else | 511 else |
482 id += "_post_load" | 512 id += "_post_load" |
483 return id; | 513 return id; |
484 } | 514 } |
485 | 515 |
486 function setupTest() { | 516 function setupTest() { |
487 loadTestParams(); | 517 loadTestParams(); |
488 document.body.onload = onBodyLoad; | 518 document.body.onload = onBodyLoad; |
489 | 519 |
490 if (testParams.doNotWaitForBodyOnLoad) { | 520 if (testParams.doNotWaitForBodyOnLoad) { |
491 startTest(); | 521 startTest(); |
492 } | 522 } |
493 } | 523 } |
494 | 524 |
495 window["setupTest"] = setupTest; | 525 window["setupTest"] = setupTest; |
496 window.__testDone = false; | 526 window.__testDone = false; |
497 window.__testMetrics = null; | 527 window.__testMetrics = {}; |
498 })(); | 528 })(); |
OLD | NEW |