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