Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / test / data / webrtc / video_extraction.js
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  */
6
7 /**
8  * The ID of the video tag from which frames are captured.
9  * @private
10  */
11 var gVideoId = 'remote-view';
12
13 /**
14  * Counts the number of frames that have been captured. Used in timeout
15  * adjustments.
16  * @private
17  */
18 var gFrameCounter = 0;
19
20 /**
21  * The gStartOfTime when the capturing begins. Used for timeout adjustments.
22  * @private
23  */
24 var gStartOfTime = 0;
25
26 /**
27  * The duration of the all frame capture in milliseconds.
28  * @private
29  */
30 var gCaptureDuration = 0;
31
32 /**
33  * The time interval at which the video is sampled.
34  * @private
35  */
36 var gFrameCaptureInterval = 0;
37
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
42  */
43 var gFrames = new Array();
44
45 /**
46  * The WebSocket connection to the PyWebSocket server.
47  * @private
48  */
49 var gWebSocket = null;
50
51 /**
52  * A flag to show whether the WebSocket is open;
53  * @private
54  */
55 var gWebSocketOpened = false;
56
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
61  */
62 var gFrameIntervalAdjustment = false;
63
64 /**
65  * We need this global variable to synchronize with the test how long to run the
66  * call between the two peers.
67  */
68 var dDoneFrameCapturing = false;
69
70 /**
71  * Upon load of the window opens the WebSocket to the PyWebSocket server. The
72  * server should already be up and running.
73  */
74 window.onload = function() {
75   tryOpeningWebSocket();
76 }
77
78 /**
79  * Starts the frame capturing.
80  *
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.
86  */
87 function startFrameCapture(width, height, canvas_height, frame_rate, duration){
88   gFrameCaptureInterval = 1000/frame_rate;
89   gCaptureDuration = 1000 * duration;
90
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);
97 }
98
99 /**
100  * Captures an image frame from the provided video element.
101  *
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.
106  *
107  * @return {Canvas}
108  */
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;
114 }
115
116 /**
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).
121  *
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.
125  */
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();
138   }
139   var video  = document.getElementById(gVideoId);
140   var canvas = capture(video, width, height);
141
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);
151   }
152   gFrames.push(img.data.buffer);
153   gFrameCounter++;
154
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;
160
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();
171   }
172 }
173
174 /**
175  * Queries if we're done with the frame capturing yet.
176  */
177 function doneFrameCapturing() {
178   if (dDoneFrameCapturing) {
179     returnToTest('done-capturing');
180   } else {
181     returnToTest('still-capturing');
182   }
183 }
184
185 /**
186  * Send the frames to the remote PyWebSocket server. Use setTimeout to regularly
187  * try to send the frames.
188  */
189 function sendFrames() {
190   if (!gWebSocketOpened) {
191     console.log('WebSocket connection is not yet open');
192     setTimeout(function() { sendFrames(); }, 100);
193     return;
194   }
195
196   progressBar = document.getElementById('progress-bar');
197   if (gFrames.length > 0) {
198     var frame = gFrames.shift();
199     gWebSocket.send(frame);
200     gFrameCounter++;
201     setTimeout(function() { sendFrames(); }, 100);
202
203     var totalNumFrames = gFrameCounter + gFrames.length;
204     progressBar.innerHTML =
205         'Writing captured frames to disk: ' +
206         '(' + gFrameCounter + '/' + totalNumFrames + ')';
207   } else {
208     progressBar.innerHTML = 'Finished sending frames.'
209     console.log('Finished sending frames.');
210   }
211 }
212
213 /**
214  * Function checking whether there are more frames to send to the pywebsocket
215  * server.
216  */
217 function haveMoreFramesToSend() {
218   if (gFrames.length == 0) {
219     returnToTest('no-more-frames');
220   } else {
221     returnToTest('still-have-frames');
222   }
223 }
224
225 /**
226  * Continuously tries to open a WebSocket to the pywebsocket server.
227  */
228 function tryOpeningWebSocket() {
229   if (!gWebSocketOpened) {
230     console.log('Once again trying to open web socket');
231     openWebSocket();
232     setTimeout(function() { tryOpeningWebSocket(); }, 1000);
233   }
234 }
235
236 /**
237  * Open the WebSocket connection and register some events.
238  */
239 function openWebSocket() {
240   if (!gWebSocketOpened) {
241     gWebSocket = new WebSocket('ws://localhost:12221/webrtc_write');
242   }
243
244   gWebSocket.onopen = function () {
245     console.log('Opened WebSocket connection');
246     gWebSocketOpened = true;
247   };
248
249   gWebSocket.onerror = function (error) {
250     console.log('WebSocket Error ' + error);
251   };
252
253   gWebSocket.onmessage = function (e) {
254     console.log('Server says: ' + e.data);
255   };
256 }
257
258 /**
259  * @private
260  */
261 function clearPage_() {
262   document.body.innerHTML = '';
263 }
264
265 /**
266  * @private
267  */
268 function prepareProgressBar_() {
269   document.body.innerHTML =
270     '<html><body>' +
271     '<p id="progress-bar" style="position: absolute; top: 50%; left: 40%;">' +
272     'Preparing to send frames.</p>' +
273     '</body></html>';
274 }