| Index: chrome/test/data/extensions/api_test/cast_streaming/end_to_end_sender.js
|
| diff --git a/chrome/test/data/extensions/api_test/cast_streaming/end_to_end_sender.js b/chrome/test/data/extensions/api_test/cast_streaming/end_to_end_sender.js
|
| index f67b3ea91ee8562f392b26ed2aaed4b052d2cba6..d25b5f840c6b2f6269ef1ab288623cf7882bab48 100644
|
| --- a/chrome/test/data/extensions/api_test/cast_streaming/end_to_end_sender.js
|
| +++ b/chrome/test/data/extensions/api_test/cast_streaming/end_to_end_sender.js
|
| @@ -4,9 +4,9 @@
|
|
|
| // This code uses the tab capture and Cast streaming APIs to capture the content
|
| // and send it to a Cast receiver end-point controlled by
|
| -// CastStreamingApiTestcode. It generates audio/video test patterns that rotate
|
| -// cyclicly, and these test patterns are checked for by an in-process Cast
|
| -// receiver to confirm the correct end-to-end functionality of the Cast
|
| +// CastStreamingApiTest code. It generates audio/video test patterns that
|
| +// rotate cyclicly, and these test patterns are checked for by an in-process
|
| +// Cast receiver to confirm the correct end-to-end functionality of the Cast
|
| // streaming API.
|
| //
|
| // Once everything is set up and fully operational, chrome.test.succeed() is
|
| @@ -20,60 +20,82 @@ var freqs = [ 200, 500, 1800 ];
|
| var curTestIdx = 0;
|
|
|
| function updateTestPattern() {
|
| - if (document.body && document.body.style) // Check that page is loaded.
|
| - document.body.style.backgroundColor = "rgb(" + colors[curTestIdx] + ")";
|
| -
|
| - // Important: Blink the testing message so that the capture pipeline will
|
| - // observe drawing updates and continue to produce video frames.
|
| - var message = document.getElementById("message");
|
| - if (message && !message.blinkInterval) {
|
| - message.innerHTML = "Testing...";
|
| - message.blinkInterval = setInterval(
|
| - function toggleVisibility() {
|
| - message.style.visibility =
|
| - message.style.visibility == "hidden" ? "visible" : "hidden";
|
| - },
|
| - 125);
|
| + if (!this.canvas) {
|
| + this.canvas = document.createElement("canvas");
|
| + this.canvas.width = 320;
|
| + this.canvas.height = 200;
|
| + this.canvas.style.position = "absolute";
|
| + this.canvas.style.top = "0px";
|
| + this.canvas.style.left = "0px";
|
| + this.canvas.style.width = "100%";
|
| + this.canvas.style.height = "100%";
|
| + document.body.appendChild(this.canvas);
|
| }
|
| + var context = this.canvas.getContext("2d");
|
| + // Fill with solid color.
|
| + context.fillStyle = "rgb(" + colors[curTestIdx] + ")";
|
| + context.fillRect(0, 0, this.canvas.width, this.canvas.height);
|
| + // Draw the circle that moves around the page.
|
| + context.fillStyle = "rgb(" + colors[(curTestIdx + 1) % colors.length] + ")";
|
| + context.beginPath();
|
| + if (!this.frameNumber) {
|
| + this.frameNumber = 1;
|
| + } else {
|
| + ++this.frameNumber;
|
| + }
|
| + var i = this.frameNumber % 200;
|
| + var t = (this.frameNumber + 3000) * (0.01 + i / 8000.0);
|
| + var x = (Math.sin(t) * 0.45 + 0.5) * this.canvas.width;
|
| + var y = (Math.cos(t * 0.9) * 0.45 + 0.5) * this.canvas.height;
|
| + context.arc(x, y, 16, 0, 2 * Math.PI, false);
|
| + context.closePath();
|
| + context.fill();
|
|
|
| if (!this.audioContext) {
|
| this.audioContext = new AudioContext();
|
| this.gainNode = this.audioContext.createGain();
|
| this.gainNode.gain.value = 0.5;
|
| this.gainNode.connect(this.audioContext.destination);
|
| - } else {
|
| - this.oscillator.stop();
|
| - this.oscillator.disconnect();
|
| }
|
| - // Note: We recreate the oscillator each time because this switches the audio
|
| - // frequency immediately. Re-using the same oscillator tends to take several
|
| - // hundred milliseconds to ramp-up/down the frequency.
|
| - this.oscillator = audioContext.createOscillator();
|
| - this.oscillator.type = OscillatorNode.SINE;
|
| - this.oscillator.frequency.value = freqs[curTestIdx];
|
| - this.oscillator.connect(this.gainNode);
|
| - this.oscillator.start();
|
| + if (!this.oscillator ||
|
| + this.oscillator.frequency.value != freqs[curTestIdx]) {
|
| + // Note: We recreate the oscillator each time because this switches the
|
| + // audio frequency immediately. Re-using the same oscillator tends to take
|
| + // several hundred milliseconds to ramp-up/down the frequency.
|
| + if (this.oscillator) {
|
| + this.oscillator.stop();
|
| + this.oscillator.disconnect();
|
| + }
|
| + this.oscillator = this.audioContext.createOscillator();
|
| + this.oscillator.type = OscillatorNode.SINE;
|
| + this.oscillator.frequency.value = freqs[curTestIdx];
|
| + this.oscillator.connect(this.gainNode);
|
| + this.oscillator.start();
|
| + }
|
| }
|
|
|
| -// Calls updateTestPattern(), then waits and calls itself again to advance to
|
| -// the next one.
|
| -function runTestPatternLoop() {
|
| +// Called to render each frame of video, and also to update the main fill color
|
| +// and audio frequency.
|
| +function renderTestPatternLoop() {
|
| + requestAnimationFrame(renderTestPatternLoop);
|
| updateTestPattern();
|
| - if (!this.curAdvanceWaitTimeMillis) {
|
| - this.curAdvanceWaitTimeMillis = 750;
|
| +
|
| + if (!this.stepTimeMillis) {
|
| + this.stepTimeMillis = 100;
|
| + }
|
| + var now = new Date().getTime();
|
| + if (!this.nextSteppingAt) {
|
| + this.nextSteppingAt = now + this.stepTimeMillis;
|
| + } else if (now >= this.nextSteppingAt) {
|
| + ++curTestIdx;
|
| + if (curTestIdx >= colors.length) { // Completed a cycle.
|
| + curTestIdx = 0;
|
| + // Increase the wait time between switching test patterns for overloaded
|
| + // bots that aren't capturing all the frames of video.
|
| + this.stepTimeMillis *= 1.25;
|
| + }
|
| + this.nextSteppingAt = now + this.stepTimeMillis;
|
| }
|
| - setTimeout(
|
| - function advanceTestPattern() {
|
| - ++curTestIdx;
|
| - if (curTestIdx >= colors.length) { // Completed a cycle.
|
| - curTestIdx = 0;
|
| - // Increase the wait time between switching test patterns for
|
| - // overloaded bots that aren't capturing all the frames of video.
|
| - this.curAdvanceWaitTimeMillis *= 1.25;
|
| - }
|
| - runTestPatternLoop();
|
| - },
|
| - this.curAdvanceWaitTimeMillis);
|
| }
|
|
|
| chrome.test.runTests([
|
| @@ -81,23 +103,29 @@ chrome.test.runTests([
|
| // The receive port changes between browser_test invocations, and is passed
|
| // as an query parameter in the URL.
|
| var recvPort;
|
| + var aesKey;
|
| + var aesIvMask;
|
| try {
|
| - recvPort = parseInt(window.location.search.substring("?port=".length));
|
| + recvPort = parseInt(window.location.search.match(/(\?|&)port=(\d+)/)[2]);
|
| chrome.test.assertTrue(recvPort > 0);
|
| + aesKey = window.location.search.match(/(\?|&)aesKey=(\w+)/)[2];
|
| + chrome.test.assertTrue(aesKey.length > 0);
|
| + aesIvMask = window.location.search.match(/(\?|&)aesIvMask=(\w+)/)[2];
|
| + chrome.test.assertTrue(aesIvMask.length > 0);
|
| } catch (err) {
|
| - chrome.test.fail("Error parsing ?port=### -- " + err.message);
|
| + chrome.test.fail("Error parsing query params -- " + err.message);
|
| return;
|
| }
|
|
|
| // Set to true if you want to confirm the sender color/tone changes are
|
| // working, without starting tab capture and Cast sending.
|
| if (false) {
|
| - setTimeout(runTestPatternLoop, 0);
|
| + renderTestPatternLoop();
|
| return;
|
| }
|
|
|
| - var width = 400;
|
| - var height = 400;
|
| + var width = 320;
|
| + var height = 200;
|
| var frameRate = 15;
|
|
|
| chrome.tabCapture.capture(
|
| @@ -122,21 +150,18 @@ chrome.test.runTests([
|
| chrome.cast.streaming.udpTransport.setDestination(
|
| udpId, { address: "127.0.0.1", port: recvPort } );
|
| var rtpStream = chrome.cast.streaming.rtpStream;
|
| - rtpStream.start(audioId,
|
| - rtpStream.getSupportedParams(audioId)[0]);
|
| + var audioParams = rtpStream.getSupportedParams(audioId)[0];
|
| + audioParams.payload.aesKey = aesKey;
|
| + audioParams.payload.aesIvMask = aesIvMask;
|
| + rtpStream.start(audioId, audioParams);
|
| var videoParams = rtpStream.getSupportedParams(videoId)[0];
|
| videoParams.payload.width = width;
|
| videoParams.payload.height = height;
|
| - videoParams.payload.clockRate = frameRate;
|
| + videoParams.payload.maxFrameRate = frameRate;
|
| + videoParams.payload.aesKey = aesKey;
|
| + videoParams.payload.aesIvMask = aesIvMask;
|
| rtpStream.start(videoId, videoParams);
|
| - setTimeout(runTestPatternLoop, 0);
|
| - if (window.innerWidth > 2 * width ||
|
| - window.innerHeight > 2 & height) {
|
| - console.warn("***TIMEOUT HAZARD*** Tab size is " +
|
| - window.innerWidth + "x" + window.innerHeight +
|
| - ", which is much larger than the expected " +
|
| - width + "x" + height);
|
| - }
|
| + renderTestPatternLoop();
|
| chrome.test.succeed();
|
| });
|
| });
|
|
|