OLD | NEW |
1 <html> | 1 <html> |
2 <head> | 2 <head> |
| 3 <script type="text/javascript" src="webrtc_test_utilities.js"></script> |
3 <script type="text/javascript"> | 4 <script type="text/javascript"> |
4 $ = function(id) { | 5 $ = function(id) { |
5 return document.getElementById(id); | 6 return document.getElementById(id); |
6 }; | 7 }; |
7 | 8 |
8 // These must match with how the video and canvas tags are declared in html. | |
9 const VIDEO_TAG_WIDTH = 320; | |
10 const VIDEO_TAG_HEIGHT = 240; | |
11 | |
12 var gFirstConnection = null; | 9 var gFirstConnection = null; |
13 var gSecondConnection = null; | 10 var gSecondConnection = null; |
14 var gTestWithoutMsidAndBundle = false; | 11 var gTestWithoutMsidAndBundle = false; |
15 | 12 |
16 // Number of test events to occur before the test pass. When the test pass, | |
17 // the document title change to OK. | |
18 var gNumberOfExpectedEvents = 0; | |
19 | |
20 // Number of events that currently have occured. | |
21 var gNumberOfEvents = 0; | |
22 | |
23 var gLocalStream = null; | 13 var gLocalStream = null; |
24 var gSentTones = ''; | 14 var gSentTones = ''; |
25 | 15 |
| 16 setAllEventsOccuredHandler(function() { |
| 17 document.title = 'OK'; |
| 18 }); |
| 19 |
26 // Test that we can setup call with an audio and video track. | 20 // Test that we can setup call with an audio and video track. |
27 function call(constraints) { | 21 function call(constraints) { |
28 createConnections(null); | 22 createConnections(null); |
29 navigator.webkitGetUserMedia(constraints, | 23 navigator.webkitGetUserMedia(constraints, |
30 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); | 24 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); |
31 waitForVideo('remote-view-1'); | 25 waitForVideo('remote-view-1'); |
32 waitForVideo('remote-view-2'); | 26 waitForVideo('remote-view-2'); |
33 } | 27 } |
34 | 28 |
35 // First calls without streams on any connections, and then adds a stream | 29 // First calls without streams on any connections, and then adds a stream |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 if (gSentTones == tones) { | 96 if (gSentTones == tones) { |
103 clearInterval(waitDtmf); | 97 clearInterval(waitDtmf); |
104 eventOccured(); | 98 eventOccured(); |
105 } | 99 } |
106 }, 100); | 100 }, 100); |
107 } | 101 } |
108 | 102 |
109 // Do the DTMF test after we have received video. | 103 // Do the DTMF test after we have received video. |
110 detectVideoIn('remote-view-2', onCallEstablished); | 104 detectVideoIn('remote-view-2', onCallEstablished); |
111 } | 105 } |
| 106 |
| 107 // Test call with a new Video MediaStream that has been created based on a |
| 108 // stream generated by getUserMedia. |
| 109 function callWithNewVideoMediaStream() { |
| 110 createConnections(null); |
| 111 navigator.webkitGetUserMedia({audio:true, video:true}, |
| 112 createNewVideoStreamAndAddToBothConnections, printGetUserMediaError); |
| 113 waitForVideo('remote-view-1'); |
| 114 waitForVideo('remote-view-2'); |
| 115 } |
112 | 116 |
113 // This function is used for setting up a test that: | 117 // This function is used for setting up a test that: |
114 // 1. Creates a data channel on |gFirstConnection| and sends data to | 118 // 1. Creates a data channel on |gFirstConnection| and sends data to |
115 // |gSecondConnection|. | 119 // |gSecondConnection|. |
116 // 2. When data is received on |gSecondConnection| a message | 120 // 2. When data is received on |gSecondConnection| a message |
117 // is sent to |gFirstConnection|. | 121 // is sent to |gFirstConnection|. |
118 // 3. When data is received on |gFirstConnection|, the data | 122 // 3. When data is received on |gFirstConnection|, the data |
119 // channel is closed. The test passes when the state transition completes. | 123 // channel is closed. The test passes when the state transition completes. |
120 function setupDataChannel() { | 124 function setupDataChannel() { |
121 var sendDataString = "send some text on a data channel." | 125 var sendDataString = "send some text on a data channel." |
(...skipping 26 matching lines...) Expand all Loading... |
148 gSecondConnection.ondatachannel = function (event) { | 152 gSecondConnection.ondatachannel = function (event) { |
149 var secondDataChannel = event.channel; | 153 var secondDataChannel = event.channel; |
150 | 154 |
151 // When |secondDataChannel| receive a message, send a message back. | 155 // When |secondDataChannel| receive a message, send a message back. |
152 secondDataChannel.onmessage = function(event) { | 156 secondDataChannel.onmessage = function(event) { |
153 expectEquals(event.data, sendDataString); | 157 expectEquals(event.data, sendDataString); |
154 expectEquals('open', secondDataChannel.readyState); | 158 expectEquals('open', secondDataChannel.readyState); |
155 secondDataChannel.send(sendDataString); | 159 secondDataChannel.send(sendDataString); |
156 } | 160 } |
157 } | 161 } |
158 } | 162 } |
159 | 163 |
160 function onToneChange(tone) { | 164 function onToneChange(tone) { |
161 gSentTones += tone.tone; | 165 gSentTones += tone.tone; |
162 document.title = gSentTones; | 166 document.title = gSentTones; |
163 } | 167 } |
164 | 168 |
165 function createConnections(constraints) { | 169 function createConnections(constraints) { |
166 gFirstConnection = new webkitRTCPeerConnection(null, constraints); | 170 gFirstConnection = new webkitRTCPeerConnection(null, constraints); |
167 gFirstConnection.onicecandidate = onIceCandidateToFirst; | 171 gFirstConnection.onicecandidate = onIceCandidateToFirst; |
168 gFirstConnection.onaddstream = function(event) { | 172 gFirstConnection.onaddstream = function(event) { |
(...skipping 27 matching lines...) Expand all Loading... |
196 gSecondConnection.addStream(localStream); | 200 gSecondConnection.addStream(localStream); |
197 negotiate(); | 201 negotiate(); |
198 } | 202 } |
199 | 203 |
200 // Called if getUserMedia succeeds when we want to send from one connection. | 204 // Called if getUserMedia succeeds when we want to send from one connection. |
201 function addStreamToTheFirstConnectionAndNegotiate(localStream) { | 205 function addStreamToTheFirstConnectionAndNegotiate(localStream) { |
202 displayAndRemember(localStream); | 206 displayAndRemember(localStream); |
203 gFirstConnection.addStream(localStream); | 207 gFirstConnection.addStream(localStream); |
204 negotiate(); | 208 negotiate(); |
205 } | 209 } |
| 210 |
| 211 // Called if getUserMedia succeeds when we want to send a modified |
| 212 // MediaStream. A new MediaStream is created and the video track from |
| 213 // |localStream| is added. |
| 214 function createNewVideoStreamAndAddToBothConnections(localStream) { |
| 215 var new_stream = new webkitMediaStream(); |
| 216 new_stream.addTrack(localStream.getVideoTracks()[0]); |
| 217 addStreamToBothConnectionsAndNegotiate(new_stream); |
| 218 } |
206 | 219 |
207 function negotiate() { | 220 function negotiate() { |
208 gFirstConnection.createOffer(onOfferCreated); | 221 gFirstConnection.createOffer(onOfferCreated); |
209 } | 222 } |
210 | 223 |
211 function onOfferCreated(offer) { | 224 function onOfferCreated(offer) { |
212 gFirstConnection.setLocalDescription(offer); | 225 gFirstConnection.setLocalDescription(offer); |
213 expectEquals('have-local-offer', gFirstConnection.signalingState); | 226 expectEquals('have-local-offer', gFirstConnection.signalingState); |
214 receiveOffer(offer.sdp); | 227 receiveOffer(offer.sdp); |
215 } | 228 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 function onRemoteStream(e, target) { | 281 function onRemoteStream(e, target) { |
269 if (gTestWithoutMsidAndBundle && e.stream.label != "default") { | 282 if (gTestWithoutMsidAndBundle && e.stream.label != "default") { |
270 document.title = 'a default remote stream was expected but instead ' + | 283 document.title = 'a default remote stream was expected but instead ' + |
271 e.stream.label + ' was received.'; | 284 e.stream.label + ' was received.'; |
272 return; | 285 return; |
273 } | 286 } |
274 var remoteStreamUrl = webkitURL.createObjectURL(e.stream); | 287 var remoteStreamUrl = webkitURL.createObjectURL(e.stream); |
275 var remoteVideo = $(target); | 288 var remoteVideo = $(target); |
276 remoteVideo.src = remoteStreamUrl; | 289 remoteVideo.src = remoteStreamUrl; |
277 } | 290 } |
278 | 291 |
279 // TODO(phoglund): perhaps use the video detector in chrome/test/data/webrtc/? | |
280 function detectVideoIn(videoElementName, callback) { | |
281 var width = VIDEO_TAG_WIDTH; | |
282 var height = VIDEO_TAG_HEIGHT; | |
283 var videoElement = $(videoElementName); | |
284 var canvas = $(videoElementName + '-canvas'); | |
285 var waitVideo = setInterval(function() { | |
286 var context = canvas.getContext('2d'); | |
287 context.drawImage(videoElement, 0, 0, width, height); | |
288 var pixels = context.getImageData(0, 0, width, height).data; | |
289 | |
290 if (isVideoPlaying(pixels, width, height)) { | |
291 clearInterval(waitVideo); | |
292 callback(); | |
293 } | |
294 }, 100); | |
295 } | |
296 | |
297 function waitForVideo(videoElement) { | |
298 document.title = 'Waiting for video...'; | |
299 addExpectedEvent(); | |
300 detectVideoIn(videoElement, function () { eventOccured(); }); | |
301 } | |
302 | |
303 // This very basic video verification algorithm will be satisfied if any | |
304 // pixels are nonzero in a small sample area in the middle. It relies on the | |
305 // assumption that a video element with null source just presents zeroes. | |
306 function isVideoPlaying(pixels, width, height) { | |
307 // Sample somewhere near the middle of the image. | |
308 var middle = width * height / 2; | |
309 for (var i = 0; i < 20; i++) { | |
310 if (pixels[middle + i] > 0) { | |
311 return true; | |
312 } | |
313 } | |
314 return false; | |
315 } | |
316 | |
317 | |
318 // This function matches |left| and |right| and throws an exception if the | |
319 // values don't match. | |
320 function expectEquals(left, right) { | |
321 if (left != right) { | |
322 var s = "expectEquals failed left: " + left + " right: " + right; | |
323 document.title = s; | |
324 throw s; | |
325 } | |
326 } | |
327 | |
328 function addExpectedEvent() { | |
329 ++gNumberOfExpectedEvents; | |
330 } | |
331 | |
332 function eventOccured() { | |
333 ++gNumberOfEvents; | |
334 if (gNumberOfEvents == gNumberOfExpectedEvents) { | |
335 document.title = 'OK'; | |
336 } | |
337 } | |
338 </script> | 292 </script> |
339 </head> | 293 </head> |
340 <body> | 294 <body> |
341 <table border="0"> | 295 <table border="0"> |
342 <tr> | 296 <tr> |
343 <td>Local Preview</td> | 297 <td>Local Preview</td> |
344 <td>Remote Stream for Connection 1</td> | 298 <td>Remote Stream for Connection 1</td> |
345 <td>Remote Stream for Connection 2</td> | 299 <td>Remote Stream for Connection 2</td> |
346 </tr> | 300 </tr> |
347 <tr> | 301 <tr> |
348 <td><video width="320" height="240" id="local-view" | 302 <td><video width="320" height="240" id="local-view" |
349 autoplay="autoplay"></video></td> | 303 autoplay="autoplay"></video></td> |
350 <td><video width="320" height="240" id="remote-view-1" | 304 <td><video width="320" height="240" id="remote-view-1" |
351 autoplay="autoplay"></video></td> | 305 autoplay="autoplay"></video></td> |
352 <td><video width="320" height="240" id="remote-view-2" | 306 <td><video width="320" height="240" id="remote-view-2" |
353 autoplay="autoplay"></video></td> | 307 autoplay="autoplay"></video></td> |
354 <!-- Canvases are named after their corresponding video elements. --> | 308 <!-- Canvases are named after their corresponding video elements. --> |
355 <td><canvas width="320" height="240" id="remote-view-1-canvas" | 309 <td><canvas width="320" height="240" id="remote-view-1-canvas" |
356 style="display:none"></canvas></td> | 310 style="display:none"></canvas></td> |
357 <td><canvas width="320" height="240" id="remote-view-2-canvas"> | 311 <td><canvas width="320" height="240" id="remote-view-2-canvas"> |
358 style="display:none"></canvas></td> | 312 style="display:none"></canvas></td> |
359 </tr> | 313 </tr> |
360 </table> | 314 </table> |
361 </body> | 315 </body> |
362 </html> | 316 </html> |
OLD | NEW |