OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2015 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 package org.webrtc; | 10 package org.webrtc; |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 } | 184 } |
185 } | 185 } |
186 } | 186 } |
187 | 187 |
188 static class CameraEvents implements | 188 static class CameraEvents implements |
189 CameraVideoCapturer.CameraEventsHandler { | 189 CameraVideoCapturer.CameraEventsHandler { |
190 public boolean onCameraOpeningCalled; | 190 public boolean onCameraOpeningCalled; |
191 public boolean onFirstFrameAvailableCalled; | 191 public boolean onFirstFrameAvailableCalled; |
192 public final Object onCameraFreezedLock = new Object(); | 192 public final Object onCameraFreezedLock = new Object(); |
193 private String onCameraFreezedDescription; | 193 private String onCameraFreezedDescription; |
| 194 public final Object cameraClosedLock = new Object(); |
| 195 private boolean cameraClosed = true; |
194 | 196 |
195 @Override | 197 @Override |
196 public void onCameraError(String errorDescription) { | 198 public void onCameraError(String errorDescription) { |
| 199 Logging.w(TAG, "Camera error: " + errorDescription); |
| 200 cameraClosed = true; |
197 } | 201 } |
198 | 202 |
199 @Override | 203 @Override |
200 public void onCameraFreezed(String errorDescription) { | 204 public void onCameraFreezed(String errorDescription) { |
201 synchronized (onCameraFreezedLock) { | 205 synchronized (onCameraFreezedLock) { |
202 onCameraFreezedDescription = errorDescription; | 206 onCameraFreezedDescription = errorDescription; |
203 onCameraFreezedLock.notifyAll(); | 207 onCameraFreezedLock.notifyAll(); |
204 } | 208 } |
205 } | 209 } |
206 | 210 |
207 @Override | 211 @Override |
208 public void onCameraOpening(int cameraId) { | 212 public void onCameraOpening(int cameraId) { |
209 onCameraOpeningCalled = true; | 213 onCameraOpeningCalled = true; |
| 214 synchronized (cameraClosedLock) { |
| 215 cameraClosed = false; |
| 216 } |
210 } | 217 } |
211 | 218 |
212 @Override | 219 @Override |
213 public void onFirstFrameAvailable() { | 220 public void onFirstFrameAvailable() { |
214 onFirstFrameAvailableCalled = true; | 221 onFirstFrameAvailableCalled = true; |
215 } | 222 } |
216 | 223 |
217 @Override | 224 @Override |
218 public void onCameraClosed() { } | 225 public void onCameraClosed() { |
| 226 synchronized (cameraClosedLock) { |
| 227 cameraClosed = true; |
| 228 cameraClosedLock.notifyAll(); |
| 229 } |
| 230 } |
219 | 231 |
220 public String waitForCameraFreezed() throws InterruptedException { | 232 public String waitForCameraFreezed() throws InterruptedException { |
221 Logging.d(TAG, "Waiting for the camera to freeze"); | 233 Logging.d(TAG, "Waiting for the camera to freeze"); |
222 synchronized (onCameraFreezedLock) { | 234 synchronized (onCameraFreezedLock) { |
223 onCameraFreezedLock.wait(); | 235 onCameraFreezedLock.wait(); |
224 return onCameraFreezedDescription; | 236 return onCameraFreezedDescription; |
225 } | 237 } |
226 } | 238 } |
| 239 |
| 240 public void waitForCameraClosed() throws InterruptedException { |
| 241 synchronized (cameraClosedLock) { |
| 242 while (!cameraClosed) { |
| 243 Logging.d(TAG, "Waiting for the camera to close."); |
| 244 cameraClosedLock.wait(); |
| 245 } |
| 246 } |
| 247 } |
227 } | 248 } |
228 | 249 |
229 /** | 250 /** |
230 * Class to collect all classes related to single capturer instance. | 251 * Class to collect all classes related to single capturer instance. |
231 */ | 252 */ |
232 static private class CapturerInstance { | 253 static private class CapturerInstance { |
233 public CameraVideoCapturer capturer; | 254 public CameraVideoCapturer capturer; |
234 public CameraEvents cameraEvents; | 255 public CameraEvents cameraEvents; |
235 public SurfaceTextureHelper surfaceTextureHelper; | 256 public SurfaceTextureHelper surfaceTextureHelper; |
236 public FakeCapturerObserver observer; | 257 public FakeCapturerObserver observer; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 instance.observer = new FakeCapturerObserver(); | 346 instance.observer = new FakeCapturerObserver(); |
326 if (initialize) { | 347 if (initialize) { |
327 instance.capturer.initialize( | 348 instance.capturer.initialize( |
328 instance.surfaceTextureHelper, testObjectFactory.getAppContext(), inst
ance.observer); | 349 instance.surfaceTextureHelper, testObjectFactory.getAppContext(), inst
ance.observer); |
329 } | 350 } |
330 instance.supportedFormats = instance.capturer.getSupportedFormats(); | 351 instance.supportedFormats = instance.capturer.getSupportedFormats(); |
331 return instance; | 352 return instance; |
332 } | 353 } |
333 | 354 |
334 private CapturerInstance createCapturer(boolean initialize) { | 355 private CapturerInstance createCapturer(boolean initialize) { |
335 return createCapturer("", initialize); | 356 String name = testObjectFactory.cameraEnumerator.getDeviceNames()[0]; |
| 357 return createCapturer(name, initialize); |
336 } | 358 } |
337 | 359 |
338 private void startCapture(CapturerInstance instance) { | 360 private void startCapture(CapturerInstance instance) { |
339 startCapture(instance, 0); | 361 startCapture(instance, 0); |
340 } | 362 } |
341 | 363 |
342 private void startCapture(CapturerInstance instance, int formatIndex) { | 364 private void startCapture(CapturerInstance instance, int formatIndex) { |
343 final CameraEnumerationAndroid.CaptureFormat format = | 365 final CameraEnumerationAndroid.CaptureFormat format = |
344 instance.supportedFormats.get(formatIndex); | 366 instance.supportedFormats.get(formatIndex); |
345 | 367 |
346 instance.capturer.startCapture(format.width, format.height, format.framerate
.max); | 368 instance.capturer.startCapture(format.width, format.height, format.framerate
.max); |
347 instance.format = format; | 369 instance.format = format; |
348 } | 370 } |
349 | 371 |
350 private void disposeCapturer(CapturerInstance instance) { | 372 private void disposeCapturer(CapturerInstance instance) throws InterruptedExce
ption { |
351 try { | 373 instance.capturer.stopCapture(); |
352 instance.capturer.stopCapture(); | 374 instance.cameraEvents.waitForCameraClosed(); |
353 } catch (InterruptedException e) { | |
354 // TODO(sakal): Remove this once stopCapture no longer throws InterruptedE
xception | |
355 } | |
356 instance.capturer.dispose(); | 375 instance.capturer.dispose(); |
357 instance.surfaceTextureHelper.returnTextureFrame(); | 376 instance.surfaceTextureHelper.returnTextureFrame(); |
358 instance.surfaceTextureHelper.dispose(); | 377 instance.surfaceTextureHelper.dispose(); |
359 } | 378 } |
360 | 379 |
361 private VideoTrackWithRenderer createVideoTrackWithRenderer(CameraVideoCapture
r capturer, | 380 private VideoTrackWithRenderer createVideoTrackWithRenderer(CameraVideoCapture
r capturer, |
362 VideoRenderer.Callbacks rendererCallbacks) { | 381 VideoRenderer.Callbacks rendererCallbacks) { |
363 VideoTrackWithRenderer videoTrackWithRenderer = new VideoTrackWithRenderer()
; | 382 VideoTrackWithRenderer videoTrackWithRenderer = new VideoTrackWithRenderer()
; |
364 videoTrackWithRenderer.source = peerConnectionFactory.createVideoSource(capt
urer); | 383 videoTrackWithRenderer.source = peerConnectionFactory.createVideoSource(capt
urer); |
365 capturer.startCapture(DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FPS); | 384 capturer.startCapture(DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FPS); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 | 428 |
410 final CapturerInstance capturerInstance = createCapturer(name, false /* init
ialize */); | 429 final CapturerInstance capturerInstance = createCapturer(name, false /* init
ialize */); |
411 final VideoTrackWithRenderer videoTrackWithRenderer = | 430 final VideoTrackWithRenderer videoTrackWithRenderer = |
412 createVideoTrackWithRenderer(capturerInstance.capturer); | 431 createVideoTrackWithRenderer(capturerInstance.capturer); |
413 assertTrue(videoTrackWithRenderer.rendererCallbacks.waitForNextFrameToRender
() > 0); | 432 assertTrue(videoTrackWithRenderer.rendererCallbacks.waitForNextFrameToRender
() > 0); |
414 disposeCapturer(capturerInstance); | 433 disposeCapturer(capturerInstance); |
415 disposeVideoTrackWithRenderer(videoTrackWithRenderer); | 434 disposeVideoTrackWithRenderer(videoTrackWithRenderer); |
416 } | 435 } |
417 | 436 |
418 // Test methods | 437 // Test methods |
419 public void createCapturerAndDispose() { | 438 public void createCapturerAndDispose() throws InterruptedException { |
420 disposeCapturer(createCapturer(true /* initialize */)); | 439 disposeCapturer(createCapturer(true /* initialize */)); |
421 } | 440 } |
422 | 441 |
423 public void createNonExistingCamera() { | 442 public void createNonExistingCamera() throws InterruptedException { |
424 try { | 443 try { |
425 disposeCapturer(createCapturer("non-existing camera", false /* initialize
*/)); | 444 disposeCapturer(createCapturer("non-existing camera", false /* initialize
*/)); |
426 } catch (IllegalArgumentException e) { | 445 } catch (IllegalArgumentException e) { |
427 return; | 446 return; |
428 } | 447 } |
429 | 448 |
430 fail("Expected illegal argument exception when creating non-existing camera.
"); | 449 fail("Expected illegal argument exception when creating non-existing camera.
"); |
431 } | 450 } |
432 | 451 |
433 public void createCapturerAndRender() throws InterruptedException { | 452 public void createCapturerAndRender() throws InterruptedException { |
434 createCapturerAndRender(""); | 453 String name = testObjectFactory.cameraEnumerator.getDeviceNames()[0]; |
| 454 createCapturerAndRender(name); |
435 } | 455 } |
436 | 456 |
437 public void createFrontFacingCapturerAndRender() throws InterruptedException { | 457 public void createFrontFacingCapturerAndRender() throws InterruptedException { |
438 createCapturerAndRender(testObjectFactory.getNameOfFrontFacingDevice()); | 458 createCapturerAndRender(testObjectFactory.getNameOfFrontFacingDevice()); |
439 } | 459 } |
440 | 460 |
441 public void createBackFacingCapturerAndRender() throws InterruptedException { | 461 public void createBackFacingCapturerAndRender() throws InterruptedException { |
442 createCapturerAndRender(testObjectFactory.getNameOfBackFacingDevice()); | 462 createCapturerAndRender(testObjectFactory.getNameOfBackFacingDevice()); |
443 } | 463 } |
444 | 464 |
445 public void switchCamera() throws InterruptedException { | 465 public void switchCamera() throws InterruptedException { |
446 if (!testObjectFactory.haveTwoCameras()) { | 466 if (!testObjectFactory.haveTwoCameras()) { |
447 Logging.w(TAG, | 467 Logging.w(TAG, |
448 "Skipping test switch video capturer because the device doesn't have t
wo cameras."); | 468 "Skipping test switch video capturer because the device doesn't have t
wo cameras."); |
449 return; | 469 return; |
450 } | 470 } |
451 | 471 |
452 final CapturerInstance capturerInstance = createCapturer(false /* initialize
*/); | 472 final CapturerInstance capturerInstance = createCapturer(false /* initialize
*/); |
453 final VideoTrackWithRenderer videoTrackWithRenderer = | 473 final VideoTrackWithRenderer videoTrackWithRenderer = |
454 createVideoTrackWithRenderer(capturerInstance.capturer); | 474 createVideoTrackWithRenderer(capturerInstance.capturer); |
| 475 // Wait for the camera to start so we can switch it |
| 476 assertTrue(videoTrackWithRenderer.rendererCallbacks.waitForNextFrameToRender
() > 0); |
455 | 477 |
456 // Array with one element to avoid final problem in nested classes. | 478 // Array with one element to avoid final problem in nested classes. |
457 final boolean[] cameraSwitchSuccessful = new boolean[1]; | 479 final boolean[] cameraSwitchSuccessful = new boolean[1]; |
458 final CountDownLatch barrier = new CountDownLatch(1); | 480 final CountDownLatch barrier = new CountDownLatch(1); |
459 capturerInstance.capturer.switchCamera(new CameraVideoCapturer.CameraSwitchH
andler() { | 481 capturerInstance.capturer.switchCamera(new CameraVideoCapturer.CameraSwitchH
andler() { |
460 @Override | 482 @Override |
461 public void onCameraSwitchDone(boolean isFrontCamera) { | 483 public void onCameraSwitchDone(boolean isFrontCamera) { |
462 cameraSwitchSuccessful[0] = true; | 484 cameraSwitchSuccessful[0] = true; |
463 barrier.countDown(); | 485 barrier.countDown(); |
464 } | 486 } |
(...skipping 13 matching lines...) Expand all Loading... |
478 disposeCapturer(capturerInstance); | 500 disposeCapturer(capturerInstance); |
479 disposeVideoTrackWithRenderer(videoTrackWithRenderer); | 501 disposeVideoTrackWithRenderer(videoTrackWithRenderer); |
480 } | 502 } |
481 | 503 |
482 public void cameraEventsInvoked() throws InterruptedException { | 504 public void cameraEventsInvoked() throws InterruptedException { |
483 final CapturerInstance capturerInstance = createCapturer(true /* initialize
*/); | 505 final CapturerInstance capturerInstance = createCapturer(true /* initialize
*/); |
484 startCapture(capturerInstance); | 506 startCapture(capturerInstance); |
485 // Make sure camera is started and first frame is received and then stop it. | 507 // Make sure camera is started and first frame is received and then stop it. |
486 assertTrue(capturerInstance.observer.waitForCapturerToStart()); | 508 assertTrue(capturerInstance.observer.waitForCapturerToStart()); |
487 capturerInstance.observer.waitForNextCapturedFrame(); | 509 capturerInstance.observer.waitForNextCapturedFrame(); |
488 capturerInstance.capturer.stopCapture(); | |
489 disposeCapturer(capturerInstance); | 510 disposeCapturer(capturerInstance); |
490 | 511 |
491 assertTrue(capturerInstance.cameraEvents.onCameraOpeningCalled); | 512 assertTrue(capturerInstance.cameraEvents.onCameraOpeningCalled); |
492 assertTrue(capturerInstance.cameraEvents.onFirstFrameAvailableCalled); | 513 assertTrue(capturerInstance.cameraEvents.onFirstFrameAvailableCalled); |
493 } | 514 } |
494 | 515 |
495 public void cameraCallsAfterStop() throws InterruptedException { | 516 public void cameraCallsAfterStop() throws InterruptedException { |
496 final CapturerInstance capturerInstance = createCapturer(true /* initialize
*/); | 517 final CapturerInstance capturerInstance = createCapturer(true /* initialize
*/); |
497 startCapture(capturerInstance); | 518 startCapture(capturerInstance); |
498 // Make sure camera is started and then stop it. | 519 // Make sure camera is started and then stop it. |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 // At this point camera is not actually opened. | 684 // At this point camera is not actually opened. |
664 final CapturerInstance capturerInstance = createCapturer(cameraName, true /*
initialize */); | 685 final CapturerInstance capturerInstance = createCapturer(cameraName, true /*
initialize */); |
665 | 686 |
666 final Object competingCamera = testObjectFactory.rawOpenCamera(cameraName); | 687 final Object competingCamera = testObjectFactory.rawOpenCamera(cameraName); |
667 | 688 |
668 startCapture(capturerInstance); | 689 startCapture(capturerInstance); |
669 | 690 |
670 if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.LOLLIP
OP_MR1) { | 691 if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.LOLLIP
OP_MR1) { |
671 // The first opened camera client will be evicted. | 692 // The first opened camera client will be evicted. |
672 assertTrue(capturerInstance.observer.waitForCapturerToStart()); | 693 assertTrue(capturerInstance.observer.waitForCapturerToStart()); |
673 capturerInstance.capturer.stopCapture(); | |
674 } else { | 694 } else { |
675 assertFalse(capturerInstance.observer.waitForCapturerToStart()); | 695 assertFalse(capturerInstance.observer.waitForCapturerToStart()); |
676 } | 696 } |
677 | 697 |
678 testObjectFactory.rawCloseCamera(competingCamera); | 698 testObjectFactory.rawCloseCamera(competingCamera); |
679 disposeCapturer(capturerInstance); | 699 disposeCapturer(capturerInstance); |
680 } | 700 } |
681 | 701 |
682 public void startWhileCameraIsAlreadyOpenAndCloseCamera() throws InterruptedEx
ception { | 702 public void startWhileCameraIsAlreadyOpenAndCloseCamera() throws InterruptedEx
ception { |
683 final String cameraName = testObjectFactory.getNameOfBackFacingDevice(); | 703 final String cameraName = testObjectFactory.getNameOfBackFacingDevice(); |
684 // At this point camera is not actually opened. | 704 // At this point camera is not actually opened. |
685 final CapturerInstance capturerInstance = createCapturer(cameraName, false /
* initialize */); | 705 final CapturerInstance capturerInstance = createCapturer(cameraName, false /
* initialize */); |
686 | 706 |
687 Logging.d(TAG, "startWhileCameraIsAlreadyOpenAndCloseCamera: Opening competi
ng camera."); | 707 Logging.d(TAG, "startWhileCameraIsAlreadyOpenAndCloseCamera: Opening competi
ng camera."); |
688 final Object competingCamera = testObjectFactory.rawOpenCamera(cameraName); | 708 final Object competingCamera = testObjectFactory.rawOpenCamera(cameraName); |
689 | 709 |
690 Logging.d(TAG, "startWhileCameraIsAlreadyOpenAndCloseCamera: Opening camera.
"); | 710 Logging.d(TAG, "startWhileCameraIsAlreadyOpenAndCloseCamera: Opening camera.
"); |
691 final VideoTrackWithRenderer videoTrackWithRenderer = | 711 final VideoTrackWithRenderer videoTrackWithRenderer = |
692 createVideoTrackWithRenderer(capturerInstance.capturer); | 712 createVideoTrackWithRenderer(capturerInstance.capturer); |
693 waitUntilIdle(capturerInstance); | 713 waitUntilIdle(capturerInstance); |
694 | 714 |
695 Logging.d(TAG, "startWhileCameraIsAlreadyOpenAndCloseCamera: Closing competi
ng camera."); | 715 Logging.d(TAG, "startWhileCameraIsAlreadyOpenAndCloseCamera: Closing competi
ng camera."); |
696 testObjectFactory.rawCloseCamera(competingCamera); | 716 testObjectFactory.rawCloseCamera(competingCamera); |
697 | 717 |
698 // Make sure camera is started and first frame is received and then stop it. | 718 // Make sure camera is started and first frame is received and then stop it. |
699 Logging.d(TAG, "startWhileCameraIsAlreadyOpenAndCloseCamera: Waiting for cap
ture to start."); | 719 Logging.d(TAG, "startWhileCameraIsAlreadyOpenAndCloseCamera: Waiting for cap
ture to start."); |
700 videoTrackWithRenderer.rendererCallbacks.waitForNextFrameToRender(); | 720 videoTrackWithRenderer.rendererCallbacks.waitForNextFrameToRender(); |
701 Logging.d(TAG, "startWhileCameraIsAlreadyOpenAndCloseCamera: Stopping captur
e."); | 721 Logging.d(TAG, "startWhileCameraIsAlreadyOpenAndCloseCamera: Stopping captur
e."); |
702 capturerInstance.capturer.stopCapture(); | |
703 disposeCapturer(capturerInstance); | 722 disposeCapturer(capturerInstance); |
704 } | 723 } |
705 | 724 |
706 public void startWhileCameraIsAlreadyOpenAndStop() throws InterruptedException
{ | 725 public void startWhileCameraIsAlreadyOpenAndStop() throws InterruptedException
{ |
707 final String cameraName = testObjectFactory.getNameOfBackFacingDevice(); | 726 final String cameraName = testObjectFactory.getNameOfBackFacingDevice(); |
708 // At this point camera is not actually opened. | 727 // At this point camera is not actually opened. |
709 final CapturerInstance capturerInstance = createCapturer(cameraName, true /*
initialize */); | 728 final CapturerInstance capturerInstance = createCapturer(cameraName, true /*
initialize */); |
710 | 729 |
711 final Object competingCamera = testObjectFactory.rawOpenCamera(cameraName); | 730 final Object competingCamera = testObjectFactory.rawOpenCamera(cameraName); |
712 | 731 |
713 startCapture(capturerInstance); | 732 startCapture(capturerInstance); |
714 | |
715 capturerInstance.capturer.stopCapture(); | |
716 disposeCapturer(capturerInstance); | 733 disposeCapturer(capturerInstance); |
717 | 734 |
718 testObjectFactory.rawCloseCamera(competingCamera); | 735 testObjectFactory.rawCloseCamera(competingCamera); |
719 } | 736 } |
720 } | 737 } |
OLD | NEW |