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

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: Addressed review comments on content_browsertest 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 = '';
15
16 // This function is called when all expected events have occurred.
17 gAllEventsOccured = function() {
18 document.title = 'OK';
19 }
25 20
26 // Test that we can setup call with an audio and video track. 21 // Test that we can setup call with an audio and video track.
27 function call(constraints) { 22 function call(constraints) {
28 createConnections(null); 23 createConnections(null);
29 navigator.webkitGetUserMedia(constraints, 24 navigator.webkitGetUserMedia(constraints,
30 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError); 25 addStreamToBothConnectionsAndNegotiate, printGetUserMediaError);
31 waitForVideo('remote-view-1'); 26 waitForVideo('remote-view-1');
32 waitForVideo('remote-view-2'); 27 waitForVideo('remote-view-2');
33 } 28 }
34 29
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 if (gSentTones == tones) { 97 if (gSentTones == tones) {
103 clearInterval(waitDtmf); 98 clearInterval(waitDtmf);
104 eventOccured(); 99 eventOccured();
105 } 100 }
106 }, 100); 101 }, 100);
107 } 102 }
108 103
109 // Do the DTMF test after we have received video. 104 // Do the DTMF test after we have received video.
110 detectVideoIn('remote-view-2', onCallEstablished); 105 detectVideoIn('remote-view-2', onCallEstablished);
111 } 106 }
107
108 // Test call with a new Video MediaStream that has been created based on a
109 // stream generated by getUserMedia.
110 function callWithNewVideoMediaStream() {
111 createConnections(null);
112 navigator.webkitGetUserMedia({audio:true, video:true},
113 createNewVideoStreamAndAddToBothConnections, printGetUserMediaError);
114 waitForVideo('remote-view-1');
115 waitForVideo('remote-view-2');
116 }
112 117
113 // This function is used for setting up a test that: 118 // This function is used for setting up a test that:
114 // 1. Creates a data channel on |gFirstConnection| and sends data to 119 // 1. Creates a data channel on |gFirstConnection| and sends data to
115 // |gSecondConnection|. 120 // |gSecondConnection|.
116 // 2. When data is received on |gSecondConnection| a message 121 // 2. When data is received on |gSecondConnection| a message
117 // is sent to |gFirstConnection|. 122 // is sent to |gFirstConnection|.
118 // 3. When data is received on |gFirstConnection|, the data 123 // 3. When data is received on |gFirstConnection|, the data
119 // channel is closed. The test passes when the state transition completes. 124 // channel is closed. The test passes when the state transition completes.
120 function setupDataChannel() { 125 function setupDataChannel() {
121 var sendDataString = "send some text on a data channel." 126 var sendDataString = "send some text on a data channel."
(...skipping 26 matching lines...) Expand all
148 gSecondConnection.ondatachannel = function (event) { 153 gSecondConnection.ondatachannel = function (event) {
149 var secondDataChannel = event.channel; 154 var secondDataChannel = event.channel;
150 155
151 // When |secondDataChannel| receive a message, send a message back. 156 // When |secondDataChannel| receive a message, send a message back.
152 secondDataChannel.onmessage = function(event) { 157 secondDataChannel.onmessage = function(event) {
153 expectEquals(event.data, sendDataString); 158 expectEquals(event.data, sendDataString);
154 expectEquals('open', secondDataChannel.readyState); 159 expectEquals('open', secondDataChannel.readyState);
155 secondDataChannel.send(sendDataString); 160 secondDataChannel.send(sendDataString);
156 } 161 }
157 } 162 }
158 } 163 }
159 164
160 function onToneChange(tone) { 165 function onToneChange(tone) {
161 gSentTones += tone.tone; 166 gSentTones += tone.tone;
162 document.title = gSentTones; 167 document.title = gSentTones;
163 } 168 }
164 169
165 function createConnections(constraints) { 170 function createConnections(constraints) {
166 gFirstConnection = new webkitRTCPeerConnection(null, constraints); 171 gFirstConnection = new webkitRTCPeerConnection(null, constraints);
167 gFirstConnection.onicecandidate = onIceCandidateToFirst; 172 gFirstConnection.onicecandidate = onIceCandidateToFirst;
168 gFirstConnection.onaddstream = function(event) { 173 gFirstConnection.onaddstream = function(event) {
(...skipping 27 matching lines...) Expand all
196 gSecondConnection.addStream(localStream); 201 gSecondConnection.addStream(localStream);
197 negotiate(); 202 negotiate();
198 } 203 }
199 204
200 // Called if getUserMedia succeeds when we want to send from one connection. 205 // Called if getUserMedia succeeds when we want to send from one connection.
201 function addStreamToTheFirstConnectionAndNegotiate(localStream) { 206 function addStreamToTheFirstConnectionAndNegotiate(localStream) {
202 displayAndRemember(localStream); 207 displayAndRemember(localStream);
203 gFirstConnection.addStream(localStream); 208 gFirstConnection.addStream(localStream);
204 negotiate(); 209 negotiate();
205 } 210 }
211
212 // Called if getUserMedia succeeds when we want to send a modified
213 // MediaStream. A new MediaStream is created and the video track from
214 // |localStream| is added.
phoglund_chromium 2013/04/11 11:16:48 Also removes the audio track.
215 function createNewVideoStreamAndAddToBothConnections(localStream) {
216 var new_stream = new webkitMediaStream(localStream.getAudioTracks());
217 new_stream.addTrack(localStream.getVideoTracks()[0]);
218 new_stream.removeTrack(new_stream.getAudioTracks()[0]);
219 addStreamToBothConnectionsAndNegotiate(new_stream);
220 }
206 221
207 function negotiate() { 222 function negotiate() {
208 gFirstConnection.createOffer(onOfferCreated); 223 gFirstConnection.createOffer(onOfferCreated);
209 } 224 }
210 225
211 function onOfferCreated(offer) { 226 function onOfferCreated(offer) {
212 gFirstConnection.setLocalDescription(offer); 227 gFirstConnection.setLocalDescription(offer);
213 expectEquals('have-local-offer', gFirstConnection.signalingState); 228 expectEquals('have-local-offer', gFirstConnection.signalingState);
214 receiveOffer(offer.sdp); 229 receiveOffer(offer.sdp);
215 } 230 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 function onRemoteStream(e, target) { 283 function onRemoteStream(e, target) {
269 if (gTestWithoutMsidAndBundle && e.stream.label != "default") { 284 if (gTestWithoutMsidAndBundle && e.stream.label != "default") {
270 document.title = 'a default remote stream was expected but instead ' + 285 document.title = 'a default remote stream was expected but instead ' +
271 e.stream.label + ' was received.'; 286 e.stream.label + ' was received.';
272 return; 287 return;
273 } 288 }
274 var remoteStreamUrl = webkitURL.createObjectURL(e.stream); 289 var remoteStreamUrl = webkitURL.createObjectURL(e.stream);
275 var remoteVideo = $(target); 290 var remoteVideo = $(target);
276 remoteVideo.src = remoteStreamUrl; 291 remoteVideo.src = remoteStreamUrl;
277 } 292 }
278 293
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> 294 </script>
339 </head> 295 </head>
340 <body> 296 <body>
341 <table border="0"> 297 <table border="0">
342 <tr> 298 <tr>
343 <td>Local Preview</td> 299 <td>Local Preview</td>
344 <td>Remote Stream for Connection 1</td> 300 <td>Remote Stream for Connection 1</td>
345 <td>Remote Stream for Connection 2</td> 301 <td>Remote Stream for Connection 2</td>
346 </tr> 302 </tr>
347 <tr> 303 <tr>
348 <td><video width="320" height="240" id="local-view" 304 <td><video width="320" height="240" id="local-view"
349 autoplay="autoplay"></video></td> 305 autoplay="autoplay"></video></td>
350 <td><video width="320" height="240" id="remote-view-1" 306 <td><video width="320" height="240" id="remote-view-1"
351 autoplay="autoplay"></video></td> 307 autoplay="autoplay"></video></td>
352 <td><video width="320" height="240" id="remote-view-2" 308 <td><video width="320" height="240" id="remote-view-2"
353 autoplay="autoplay"></video></td> 309 autoplay="autoplay"></video></td>
354 <!-- Canvases are named after their corresponding video elements. --> 310 <!-- Canvases are named after their corresponding video elements. -->
355 <td><canvas width="320" height="240" id="remote-view-1-canvas" 311 <td><canvas width="320" height="240" id="remote-view-1-canvas"
356 style="display:none"></canvas></td> 312 style="display:none"></canvas></td>
357 <td><canvas width="320" height="240" id="remote-view-2-canvas"> 313 <td><canvas width="320" height="240" id="remote-view-2-canvas">
358 style="display:none"></canvas></td> 314 style="display:none"></canvas></td>
359 </tr> 315 </tr>
360 </table> 316 </table>
361 </body> 317 </body>
362 </html> 318 </html>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698