OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 24 matching lines...) Expand all Loading... |
35 import org.webrtc.Camera1Enumerator; | 35 import org.webrtc.Camera1Enumerator; |
36 import org.webrtc.Camera2Enumerator; | 36 import org.webrtc.Camera2Enumerator; |
37 import org.webrtc.CameraEnumerator; | 37 import org.webrtc.CameraEnumerator; |
38 import org.webrtc.IceCandidate; | 38 import org.webrtc.IceCandidate; |
39 import org.webrtc.MediaCodecVideoEncoder; | 39 import org.webrtc.MediaCodecVideoEncoder; |
40 import org.webrtc.PeerConnection; | 40 import org.webrtc.PeerConnection; |
41 import org.webrtc.PeerConnectionFactory; | 41 import org.webrtc.PeerConnectionFactory; |
42 import org.webrtc.SessionDescription; | 42 import org.webrtc.SessionDescription; |
43 import org.webrtc.StatsReport; | 43 import org.webrtc.StatsReport; |
44 import org.webrtc.VideoCapturer; | 44 import org.webrtc.VideoCapturer; |
| 45 import org.webrtc.VideoFrame; |
45 import org.webrtc.VideoRenderer; | 46 import org.webrtc.VideoRenderer; |
| 47 import org.webrtc.VideoSink; |
46 | 48 |
47 @RunWith(BaseJUnit4ClassRunner.class) | 49 @RunWith(BaseJUnit4ClassRunner.class) |
48 public class PeerConnectionClientTest implements PeerConnectionEvents { | 50 public class PeerConnectionClientTest implements PeerConnectionEvents { |
49 private static final String TAG = "RTCClientTest"; | 51 private static final String TAG = "RTCClientTest"; |
50 private static final int ICE_CONNECTION_WAIT_TIMEOUT = 10000; | 52 private static final int ICE_CONNECTION_WAIT_TIMEOUT = 10000; |
51 private static final int WAIT_TIMEOUT = 7000; | 53 private static final int WAIT_TIMEOUT = 7000; |
52 private static final int CAMERA_SWITCH_ATTEMPTS = 3; | 54 private static final int CAMERA_SWITCH_ATTEMPTS = 3; |
53 private static final int VIDEO_RESTART_ATTEMPTS = 3; | 55 private static final int VIDEO_RESTART_ATTEMPTS = 3; |
54 private static final int CAPTURE_FORMAT_CHANGE_ATTEMPTS = 3; | 56 private static final int CAPTURE_FORMAT_CHANGE_ATTEMPTS = 3; |
55 private static final int VIDEO_RESTART_TIMEOUT = 500; | 57 private static final int VIDEO_RESTART_TIMEOUT = 500; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 } | 121 } |
120 | 122 |
121 // This method shouldn't hold any locks or touch member variables since it | 123 // This method shouldn't hold any locks or touch member variables since it |
122 // blocks. | 124 // blocks. |
123 public boolean waitForFramesRendered(int timeoutMs) throws InterruptedExcept
ion { | 125 public boolean waitForFramesRendered(int timeoutMs) throws InterruptedExcept
ion { |
124 doneRendering.await(timeoutMs, TimeUnit.MILLISECONDS); | 126 doneRendering.await(timeoutMs, TimeUnit.MILLISECONDS); |
125 return (doneRendering.getCount() <= 0); | 127 return (doneRendering.getCount() <= 0); |
126 } | 128 } |
127 } | 129 } |
128 | 130 |
| 131 // Mock VideoSink implementation. |
| 132 private static class MockSink implements VideoSink { |
| 133 // These are protected by 'this' since we gets called from worker threads. |
| 134 private String rendererName; |
| 135 private boolean renderFrameCalled = false; |
| 136 |
| 137 // Thread-safe in itself. |
| 138 private CountDownLatch doneRendering; |
| 139 |
| 140 public MockSink(int expectedFrames, String rendererName) { |
| 141 this.rendererName = rendererName; |
| 142 reset(expectedFrames); |
| 143 } |
| 144 |
| 145 // Resets render to wait for new amount of video frames. |
| 146 public synchronized void reset(int expectedFrames) { |
| 147 renderFrameCalled = false; |
| 148 doneRendering = new CountDownLatch(expectedFrames); |
| 149 } |
| 150 |
| 151 @Override |
| 152 public synchronized void onFrame(VideoFrame frame) { |
| 153 if (!renderFrameCalled) { |
| 154 if (rendererName != null) { |
| 155 Log.d(TAG, |
| 156 rendererName + " render frame: " + frame.getRotatedWidth() + " x " |
| 157 + frame.getRotatedHeight()); |
| 158 } else { |
| 159 Log.d(TAG, "Render frame: " + frame.getRotatedWidth() + " x " + frame.
getRotatedHeight()); |
| 160 } |
| 161 } |
| 162 renderFrameCalled = true; |
| 163 doneRendering.countDown(); |
| 164 } |
| 165 |
| 166 // This method shouldn't hold any locks or touch member variables since it |
| 167 // blocks. |
| 168 public boolean waitForFramesRendered(int timeoutMs) throws InterruptedExcept
ion { |
| 169 doneRendering.await(timeoutMs, TimeUnit.MILLISECONDS); |
| 170 return (doneRendering.getCount() <= 0); |
| 171 } |
| 172 } |
| 173 |
129 // Peer connection events implementation. | 174 // Peer connection events implementation. |
130 @Override | 175 @Override |
131 public void onLocalDescription(SessionDescription sdp) { | 176 public void onLocalDescription(SessionDescription sdp) { |
132 Log.d(TAG, "LocalSDP type: " + sdp.type); | 177 Log.d(TAG, "LocalSDP type: " + sdp.type); |
133 synchronized (localSdpEvent) { | 178 synchronized (localSdpEvent) { |
134 localSdp = sdp; | 179 localSdp = sdp; |
135 localSdpEvent.notifyAll(); | 180 localSdpEvent.notifyAll(); |
136 } | 181 } |
137 } | 182 } |
138 | 183 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 | 274 |
230 private boolean waitForPeerConnectionClosed(int timeoutMs) throws InterruptedE
xception { | 275 private boolean waitForPeerConnectionClosed(int timeoutMs) throws InterruptedE
xception { |
231 synchronized (closeEvent) { | 276 synchronized (closeEvent) { |
232 if (!isClosed) { | 277 if (!isClosed) { |
233 closeEvent.wait(timeoutMs); | 278 closeEvent.wait(timeoutMs); |
234 } | 279 } |
235 return isClosed; | 280 return isClosed; |
236 } | 281 } |
237 } | 282 } |
238 | 283 |
239 PeerConnectionClient createPeerConnectionClient(MockRenderer localRenderer, | 284 PeerConnectionClient createPeerConnectionClient(MockSink localRenderer, |
240 MockRenderer remoteRenderer, PeerConnectionParameters peerConnectionParame
ters, | 285 MockRenderer remoteRenderer, PeerConnectionParameters peerConnectionParame
ters, |
241 VideoCapturer videoCapturer) { | 286 VideoCapturer videoCapturer) { |
242 List<PeerConnection.IceServer> iceServers = new LinkedList<PeerConnection.Ic
eServer>(); | 287 List<PeerConnection.IceServer> iceServers = new LinkedList<PeerConnection.Ic
eServer>(); |
243 SignalingParameters signalingParameters = | 288 SignalingParameters signalingParameters = |
244 new SignalingParameters(iceServers, true, // iceServers, initiator. | 289 new SignalingParameters(iceServers, true, // iceServers, initiator. |
245 null, null, null, // clientId, wssUrl, wssPostUrl. | 290 null, null, null, // clientId, wssUrl, wssPostUrl. |
246 null, null); // offerSdp, iceCandidates. | 291 null, null); // offerSdp, iceCandidates. |
247 | 292 |
248 PeerConnectionClient client = new PeerConnectionClient(); | 293 PeerConnectionClient client = new PeerConnectionClient(); |
249 PeerConnectionFactory.Options options = new PeerConnectionFactory.Options(); | 294 PeerConnectionFactory.Options options = new PeerConnectionFactory.Options(); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 | 371 |
327 @After | 372 @After |
328 public void tearDown() { | 373 public void tearDown() { |
329 signalingExecutor.shutdown(); | 374 signalingExecutor.shutdown(); |
330 } | 375 } |
331 | 376 |
332 @Test | 377 @Test |
333 @SmallTest | 378 @SmallTest |
334 public void testSetLocalOfferMakesVideoFlowLocally() throws InterruptedExcepti
on { | 379 public void testSetLocalOfferMakesVideoFlowLocally() throws InterruptedExcepti
on { |
335 Log.d(TAG, "testSetLocalOfferMakesVideoFlowLocally"); | 380 Log.d(TAG, "testSetLocalOfferMakesVideoFlowLocally"); |
336 MockRenderer localRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, LOCAL_R
ENDERER_NAME); | 381 MockSink localRenderer = new MockSink(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_
NAME); |
337 pcClient = createPeerConnectionClient(localRenderer, new MockRenderer(0, nul
l), | 382 pcClient = createPeerConnectionClient(localRenderer, new MockRenderer(0, nul
l), |
338 createParametersForVideoCall(VIDEO_CODEC_VP8), | 383 createParametersForVideoCall(VIDEO_CODEC_VP8), |
339 createCameraCapturer(false /* captureToTexture */)); | 384 createCameraCapturer(false /* captureToTexture */)); |
340 | 385 |
341 // Wait for local SDP and ice candidates set events. | 386 // Wait for local SDP and ice candidates set events. |
342 assertTrue("Local SDP was not set.", waitForLocalSDP(WAIT_TIMEOUT)); | 387 assertTrue("Local SDP was not set.", waitForLocalSDP(WAIT_TIMEOUT)); |
343 assertTrue("ICE candidates were not generated.", waitForIceCandidates(WAIT_T
IMEOUT)); | 388 assertTrue("ICE candidates were not generated.", waitForIceCandidates(WAIT_T
IMEOUT)); |
344 | 389 |
345 // Check that local video frames were rendered. | 390 // Check that local video frames were rendered. |
346 assertTrue( | 391 assertTrue( |
347 "Local video frames were not rendered.", localRenderer.waitForFramesRend
ered(WAIT_TIMEOUT)); | 392 "Local video frames were not rendered.", localRenderer.waitForFramesRend
ered(WAIT_TIMEOUT)); |
348 | 393 |
349 pcClient.close(); | 394 pcClient.close(); |
350 assertTrue( | 395 assertTrue( |
351 "PeerConnection close event was not received.", waitForPeerConnectionClo
sed(WAIT_TIMEOUT)); | 396 "PeerConnection close event was not received.", waitForPeerConnectionClo
sed(WAIT_TIMEOUT)); |
352 Log.d(TAG, "testSetLocalOfferMakesVideoFlowLocally Done."); | 397 Log.d(TAG, "testSetLocalOfferMakesVideoFlowLocally Done."); |
353 } | 398 } |
354 | 399 |
355 private void doLoopbackTest(PeerConnectionParameters parameters, VideoCapturer
videoCapturer, | 400 private void doLoopbackTest(PeerConnectionParameters parameters, VideoCapturer
videoCapturer, |
356 boolean decodeToTexture) throws InterruptedException { | 401 boolean decodeToTexture) throws InterruptedException { |
357 loopback = true; | 402 loopback = true; |
358 MockRenderer localRenderer = null; | 403 MockSink localRenderer = null; |
359 MockRenderer remoteRenderer = null; | 404 MockRenderer remoteRenderer = null; |
360 if (parameters.videoCallEnabled) { | 405 if (parameters.videoCallEnabled) { |
361 Log.d(TAG, "testLoopback for video " + parameters.videoCodec); | 406 Log.d(TAG, "testLoopback for video " + parameters.videoCodec); |
362 localRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_NAM
E); | 407 localRenderer = new MockSink(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_NAME); |
363 remoteRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, REMOTE_RENDERER_N
AME); | 408 remoteRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, REMOTE_RENDERER_N
AME); |
364 } else { | 409 } else { |
365 Log.d(TAG, "testLoopback for audio."); | 410 Log.d(TAG, "testLoopback for audio."); |
366 } | 411 } |
367 pcClient = createPeerConnectionClient(localRenderer, remoteRenderer, paramet
ers, videoCapturer); | 412 pcClient = createPeerConnectionClient(localRenderer, remoteRenderer, paramet
ers, videoCapturer); |
368 | 413 |
369 // Wait for local SDP, rename it to answer and set as remote SDP. | 414 // Wait for local SDP, rename it to answer and set as remote SDP. |
370 assertTrue("Local SDP was not set.", waitForLocalSDP(WAIT_TIMEOUT)); | 415 assertTrue("Local SDP was not set.", waitForLocalSDP(WAIT_TIMEOUT)); |
371 SessionDescription remoteSdp = new SessionDescription( | 416 SessionDescription remoteSdp = new SessionDescription( |
372 SessionDescription.Type.fromCanonicalForm("answer"), localSdp.descriptio
n); | 417 SessionDescription.Type.fromCanonicalForm("answer"), localSdp.descriptio
n); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 } | 532 } |
488 | 533 |
489 // Checks if default front camera can be switched to back camera and then | 534 // Checks if default front camera can be switched to back camera and then |
490 // again to front camera. | 535 // again to front camera. |
491 @Test | 536 @Test |
492 @SmallTest | 537 @SmallTest |
493 public void testCameraSwitch() throws InterruptedException { | 538 public void testCameraSwitch() throws InterruptedException { |
494 Log.d(TAG, "testCameraSwitch"); | 539 Log.d(TAG, "testCameraSwitch"); |
495 loopback = true; | 540 loopback = true; |
496 | 541 |
497 MockRenderer localRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, LOCAL_R
ENDERER_NAME); | 542 MockSink localRenderer = new MockSink(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_
NAME); |
498 MockRenderer remoteRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, REMOTE
_RENDERER_NAME); | 543 MockRenderer remoteRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, REMOTE
_RENDERER_NAME); |
499 | 544 |
500 pcClient = createPeerConnectionClient(localRenderer, remoteRenderer, | 545 pcClient = createPeerConnectionClient(localRenderer, remoteRenderer, |
501 createParametersForVideoCall(VIDEO_CODEC_VP8), | 546 createParametersForVideoCall(VIDEO_CODEC_VP8), |
502 createCameraCapturer(false /* captureToTexture */)); | 547 createCameraCapturer(false /* captureToTexture */)); |
503 | 548 |
504 // Wait for local SDP, rename it to answer and set as remote SDP. | 549 // Wait for local SDP, rename it to answer and set as remote SDP. |
505 assertTrue("Local SDP was not set.", waitForLocalSDP(WAIT_TIMEOUT)); | 550 assertTrue("Local SDP was not set.", waitForLocalSDP(WAIT_TIMEOUT)); |
506 SessionDescription remoteSdp = new SessionDescription( | 551 SessionDescription remoteSdp = new SessionDescription( |
507 SessionDescription.Type.fromCanonicalForm("answer"), localSdp.descriptio
n); | 552 SessionDescription.Type.fromCanonicalForm("answer"), localSdp.descriptio
n); |
(...skipping 27 matching lines...) Expand all Loading... |
535 } | 580 } |
536 | 581 |
537 // Checks if video source can be restarted - simulate app goes to | 582 // Checks if video source can be restarted - simulate app goes to |
538 // background and back to foreground. | 583 // background and back to foreground. |
539 @Test | 584 @Test |
540 @SmallTest | 585 @SmallTest |
541 public void testVideoSourceRestart() throws InterruptedException { | 586 public void testVideoSourceRestart() throws InterruptedException { |
542 Log.d(TAG, "testVideoSourceRestart"); | 587 Log.d(TAG, "testVideoSourceRestart"); |
543 loopback = true; | 588 loopback = true; |
544 | 589 |
545 MockRenderer localRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, LOCAL_R
ENDERER_NAME); | 590 MockSink localRenderer = new MockSink(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_
NAME); |
546 MockRenderer remoteRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, REMOTE
_RENDERER_NAME); | 591 MockRenderer remoteRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, REMOTE
_RENDERER_NAME); |
547 | 592 |
548 pcClient = createPeerConnectionClient(localRenderer, remoteRenderer, | 593 pcClient = createPeerConnectionClient(localRenderer, remoteRenderer, |
549 createParametersForVideoCall(VIDEO_CODEC_VP8), | 594 createParametersForVideoCall(VIDEO_CODEC_VP8), |
550 createCameraCapturer(false /* captureToTexture */)); | 595 createCameraCapturer(false /* captureToTexture */)); |
551 | 596 |
552 // Wait for local SDP, rename it to answer and set as remote SDP. | 597 // Wait for local SDP, rename it to answer and set as remote SDP. |
553 assertTrue("Local SDP was not set.", waitForLocalSDP(WAIT_TIMEOUT)); | 598 assertTrue("Local SDP was not set.", waitForLocalSDP(WAIT_TIMEOUT)); |
554 SessionDescription remoteSdp = new SessionDescription( | 599 SessionDescription remoteSdp = new SessionDescription( |
555 SessionDescription.Type.fromCanonicalForm("answer"), localSdp.descriptio
n); | 600 SessionDescription.Type.fromCanonicalForm("answer"), localSdp.descriptio
n); |
(...skipping 28 matching lines...) Expand all Loading... |
584 Log.d(TAG, "testVideoSourceRestart done."); | 629 Log.d(TAG, "testVideoSourceRestart done."); |
585 } | 630 } |
586 | 631 |
587 // Checks if capture format can be changed on fly and decoder can be reset pro
perly. | 632 // Checks if capture format can be changed on fly and decoder can be reset pro
perly. |
588 @Test | 633 @Test |
589 @SmallTest | 634 @SmallTest |
590 public void testCaptureFormatChange() throws InterruptedException { | 635 public void testCaptureFormatChange() throws InterruptedException { |
591 Log.d(TAG, "testCaptureFormatChange"); | 636 Log.d(TAG, "testCaptureFormatChange"); |
592 loopback = true; | 637 loopback = true; |
593 | 638 |
594 MockRenderer localRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, LOCAL_R
ENDERER_NAME); | 639 MockSink localRenderer = new MockSink(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_
NAME); |
595 MockRenderer remoteRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, REMOTE
_RENDERER_NAME); | 640 MockRenderer remoteRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, REMOTE
_RENDERER_NAME); |
596 | 641 |
597 pcClient = createPeerConnectionClient(localRenderer, remoteRenderer, | 642 pcClient = createPeerConnectionClient(localRenderer, remoteRenderer, |
598 createParametersForVideoCall(VIDEO_CODEC_VP8), | 643 createParametersForVideoCall(VIDEO_CODEC_VP8), |
599 createCameraCapturer(false /* captureToTexture */)); | 644 createCameraCapturer(false /* captureToTexture */)); |
600 | 645 |
601 // Wait for local SDP, rename it to answer and set as remote SDP. | 646 // Wait for local SDP, rename it to answer and set as remote SDP. |
602 assertTrue("Local SDP was not set.", waitForLocalSDP(WAIT_TIMEOUT)); | 647 assertTrue("Local SDP was not set.", waitForLocalSDP(WAIT_TIMEOUT)); |
603 SessionDescription remoteSdp = new SessionDescription( | 648 SessionDescription remoteSdp = new SessionDescription( |
604 SessionDescription.Type.fromCanonicalForm("answer"), localSdp.descriptio
n); | 649 SessionDescription.Type.fromCanonicalForm("answer"), localSdp.descriptio
n); |
(...skipping 24 matching lines...) Expand all Loading... |
629 localRenderer.waitForFramesRendered(WAIT_TIMEOUT)); | 674 localRenderer.waitForFramesRendered(WAIT_TIMEOUT)); |
630 assertTrue("Remote video frames were not rendered after capture format cha
nge.", | 675 assertTrue("Remote video frames were not rendered after capture format cha
nge.", |
631 remoteRenderer.waitForFramesRendered(WAIT_TIMEOUT)); | 676 remoteRenderer.waitForFramesRendered(WAIT_TIMEOUT)); |
632 } | 677 } |
633 | 678 |
634 pcClient.close(); | 679 pcClient.close(); |
635 assertTrue(waitForPeerConnectionClosed(WAIT_TIMEOUT)); | 680 assertTrue(waitForPeerConnectionClosed(WAIT_TIMEOUT)); |
636 Log.d(TAG, "testCaptureFormatChange done."); | 681 Log.d(TAG, "testCaptureFormatChange done."); |
637 } | 682 } |
638 } | 683 } |
OLD | NEW |