Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(119)

Side by Side Diff: content/test/data/media/peerconnection-call.html

Issue 13496009: Hookup the MediaStream glue for Adding and Removing tracks to an existing MediaStream. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add workaround when there are no microphones on bots. Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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>
OLDNEW
« no previous file with comments | « content/test/data/media/getusermedia_and_stop.html ('k') | content/test/data/media/webrtc_test_utilities.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698