Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / test / data / webrtc / video_extraction.js
blobbf01dc46581407bfe85d8fba467287ec03642296
1 /**
2 * Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
7 /**
8 * The ID of the video tag from which frames are captured.
9 * @private
11 var gVideoId = 'remote-view';
13 /**
14 * Counts the number of frames that have been captured. Used in timeout
15 * adjustments.
16 * @private
18 var gFrameCounter = 0;
20 /**
21 * The gStartOfTime when the capturing begins. Used for timeout adjustments.
22 * @private
24 var gStartOfTime = 0;
26 /**
27 * The duration of the all frame capture in milliseconds.
28 * @private
30 var gCaptureDuration = 0;
32 /**
33 * The time interval at which the video is sampled.
34 * @private
36 var gFrameCaptureInterval = 0;
38 /**
39 * The global array of frames. Frames are pushed, i.e. this should be treated as
40 * a queue and we should read from the start.
41 * @private
43 var gFrames = new Array();
45 /**
46 * The WebSocket connection to the PyWebSocket server.
47 * @private
49 var gWebSocket = null;
51 /**
52 * A flag to show whether the WebSocket is open;
53 * @private
55 var gWebSocketOpened = false;
57 /**
58 * We need to skip the first two frames due to timing issues. This flags helps
59 * us determine weather or not to skip them.
60 * @private
62 var gFrameIntervalAdjustment = false;
64 /**
65 * We need this global variable to synchronize with the test how long to run the
66 * call between the two peers.
68 var dDoneFrameCapturing = false;
70 /**
71 * Upon load of the window opens the WebSocket to the PyWebSocket server. The
72 * server should already be up and running.
74 window.onload = function() {
75 tryOpeningWebSocket();
78 /**
79 * Starts the frame capturing.
81 * @param {Number} The width of the video/canvas area to be captured.
82 * @param {Number} The height of the video area to be captured.
83 * @param {Number} The height of the canvas where we put the video frames.
84 * @param {Number} The frame rate at which we would like to capture frames.
85 * @param {Number} The duration of the frame capture in seconds.
87 function startFrameCapture(width, height, canvas_height, frame_rate, duration){
88 gFrameCaptureInterval = 1000/frame_rate;
89 gCaptureDuration = 1000 * duration;
91 console.log('Received width is: ' + width + ', received height is: ' + height
92 + ', capture interval is: ' + gFrameCaptureInterval +
93 ', duration is: ' + gCaptureDuration);
94 gStartOfTime = new Date().getTime();
95 setTimeout(function() { shoot(width, height, canvas_height); },
96 gFrameCaptureInterval);
99 /**
100 * Captures an image frame from the provided video element.
102 * @param {Video} video HTML5 video element from where the image frame will
103 * be captured.
104 * @param {Number} The width of the video/canvas area to be captured.
105 * @param {Number} The height of the video/canvas area to be captured.
107 * @return {Canvas}
109 function capture(video, width, height) {
110 var canvas = document.getElementById('remote-canvas');
111 var ctx = canvas.getContext('2d');
112 ctx.drawImage(video, 0, 0, width, height);
113 return canvas;
117 * The function which is called at the end of every gFrameCaptureInterval. Gets
118 * the current frame from the video and extracts the data from it. Then it saves
119 * it in the frames array and adjusts the capture interval (timers in JavaScript
120 * aren't precise).
122 * @param {Number} The width of the video/canvas area to be captured.
123 * @param {Number} The height of the video area to be captured.
124 * @param {Number} The height of the canvas where we put the video frames.
126 function shoot(width, height, canvas_height){
127 // The first two captured frames have big difference between the ideal time
128 // interval between two frames and the real one. As a consequence this affects
129 // enormously the interval adjustment for subsequent frames. That's why we
130 // have to reset the time after the first two frames and get rid of these two
131 // frames.
132 if (gFrameCounter == 1 && !gFrameIntervalAdjustment) {
133 gStartOfTime = new Date().getTime();
134 gFrameCounter = 0;
135 gFrameIntervalAdjustment = true;
136 gFrames.pop();
137 gFrames.pop();
139 var video = document.getElementById(gVideoId);
140 var canvas = capture(video, width, height);
142 // Extract the data from the canvas.
143 var ctx = canvas.getContext('2d');
144 var img;
145 if (height == canvas_height) {
146 // We capture the whole video frame.
147 img = ctx.getImageData(0, 0, width, height);
148 } else {
149 // We capture only the barcode (canvas_height is the height of the barcode).
150 img = ctx.getImageData(0, 0, width, canvas_height);
152 gFrames.push(img.data.buffer);
153 gFrameCounter++;
155 // Adjust the timer.
156 var current_time = new Date().getTime();
157 var ideal_time = gFrameCounter*gFrameCaptureInterval;
158 var real_time_elapsed = current_time - gStartOfTime;
159 var diff = real_time_elapsed - ideal_time;
161 if (real_time_elapsed < gCaptureDuration) {
162 // If duration isn't over shoot again
163 setTimeout(function() { shoot(width, height, canvas_height); },
164 gFrameCaptureInterval - diff);
165 } else { // Else reset gFrameCounter and send the frames
166 dDoneFrameCapturing = true;
167 gFrameCounter = 0;
168 clearPage_();
169 prepareProgressBar_();
170 sendFrames();
175 * Queries if we're done with the frame capturing yet.
177 function doneFrameCapturing() {
178 if (dDoneFrameCapturing) {
179 returnToTest('done-capturing');
180 } else {
181 returnToTest('still-capturing');
186 * Send the frames to the remote PyWebSocket server. Use setTimeout to regularly
187 * try to send the frames.
189 function sendFrames() {
190 if (!gWebSocketOpened) {
191 console.log('WebSocket connection is not yet open');
192 setTimeout(function() { sendFrames(); }, 100);
195 progressBar = document.getElementById('progress-bar');
196 if (gFrames.length > 0) {
197 var frame = gFrames.shift();
198 gWebSocket.send(frame);
199 gFrameCounter++;
200 setTimeout(function() { sendFrames(); }, 100);
202 var totalNumFrames = gFrameCounter + gFrames.length;
203 progressBar.innerHTML =
204 'Writing captured frames to disk: ' +
205 '(' + gFrameCounter + '/' + totalNumFrames + ')';
206 } else {
207 progressBar.innerHTML = 'Finished sending frames.'
208 console.log('Finished sending frames.');
213 * Function checking whether there are more frames to send to the pywebsocket
214 * server.
216 function haveMoreFramesToSend() {
217 if (gFrames.length == 0) {
218 returnToTest('no-more-frames');
219 } else {
220 returnToTest('still-have-frames');
225 * Continuously tries to open a WebSocket to the pywebsocket server.
227 function tryOpeningWebSocket() {
228 if (!gWebSocketOpened) {
229 console.log('Once again trying to open web socket');
230 openWebSocket();
231 setTimeout(function() { tryOpeningWebSocket(); }, 1000);
236 * Open the WebSocket connection and register some events.
238 function openWebSocket() {
239 if (!gWebSocketOpened) {
240 gWebSocket = new WebSocket('ws://localhost:12221/webrtc_write');
243 gWebSocket.onopen = function () {
244 console.log('Opened WebSocket connection');
245 gWebSocketOpened = true;
248 gWebSocket.onerror = function (error) {
249 console.log('WebSocket Error ' + error);
252 gWebSocket.onmessage = function (e) {
253 console.log('Server says: ' + e.data);
258 * @private
260 function clearPage_() {
261 document.body.innerHTML = '';
265 * @private
267 function prepareProgressBar_() {
268 document.body.innerHTML =
269 '<html><body>' +
270 '<p id="progress-bar" style="position: absolute; top: 50%; left: 40%;">' +
271 'Preparing to send frames.</p>' +
272 '</body></html>';