| 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 |