Index: talk/app/webrtc/androidtests/src/org/webrtc/VideoCapturerAndroidTest.java |
diff --git a/talk/app/webrtc/androidtests/src/org/webrtc/VideoCapturerAndroidTest.java b/talk/app/webrtc/androidtests/src/org/webrtc/VideoCapturerAndroidTest.java |
index 0fe827d1f9c658151dd05cb10edf0106e218700d..e0eccb1f7628d423ee1a209c19e8b626323efe00 100644 |
--- a/talk/app/webrtc/androidtests/src/org/webrtc/VideoCapturerAndroidTest.java |
+++ b/talk/app/webrtc/androidtests/src/org/webrtc/VideoCapturerAndroidTest.java |
@@ -26,148 +26,18 @@ |
*/ |
package org.webrtc; |
-import android.hardware.Camera; |
+import android.opengl.EGL14; |
import android.test.ActivityTestCase; |
-import android.test.suitebuilder.annotation.SmallTest; |
import android.test.suitebuilder.annotation.MediumTest; |
+import android.test.suitebuilder.annotation.SmallTest; |
import android.util.Size; |
import org.webrtc.CameraEnumerationAndroid.CaptureFormat; |
-import org.webrtc.VideoRenderer.I420Frame; |
- |
-import java.util.ArrayList; |
import java.util.HashSet; |
-import java.util.List; |
import java.util.Set; |
-import java.util.concurrent.CountDownLatch; |
@SuppressWarnings("deprecation") |
public class VideoCapturerAndroidTest extends ActivityTestCase { |
- static class RendererCallbacks implements VideoRenderer.Callbacks { |
- private int framesRendered = 0; |
- private Object frameLock = 0; |
- |
- @Override |
- public void renderFrame(I420Frame frame) { |
- synchronized (frameLock) { |
- ++framesRendered; |
- frameLock.notify(); |
- } |
- VideoRenderer.renderFrameDone(frame); |
- } |
- |
- public int WaitForNextFrameToRender() throws InterruptedException { |
- synchronized (frameLock) { |
- frameLock.wait(); |
- return framesRendered; |
- } |
- } |
- } |
- |
- static class FakeAsyncRenderer implements VideoRenderer.Callbacks { |
- private final List<I420Frame> pendingFrames = new ArrayList<I420Frame>(); |
- |
- @Override |
- public void renderFrame(I420Frame frame) { |
- synchronized (pendingFrames) { |
- pendingFrames.add(frame); |
- pendingFrames.notifyAll(); |
- } |
- } |
- |
- // Wait until at least one frame have been received, before returning them. |
- public List<I420Frame> waitForPendingFrames() throws InterruptedException { |
- synchronized (pendingFrames) { |
- while (pendingFrames.isEmpty()) { |
- pendingFrames.wait(); |
- } |
- return new ArrayList<I420Frame>(pendingFrames); |
- } |
- } |
- } |
- |
- static class FakeCapturerObserver implements |
- VideoCapturerAndroid.CapturerObserver { |
- private int framesCaptured = 0; |
- private int frameSize = 0; |
- private Object frameLock = 0; |
- private Object capturerStartLock = 0; |
- private boolean captureStartResult = false; |
- private List<Long> timestamps = new ArrayList<Long>(); |
- |
- @Override |
- public void OnCapturerStarted(boolean success) { |
- synchronized (capturerStartLock) { |
- captureStartResult = success; |
- capturerStartLock.notify(); |
- } |
- } |
- |
- @Override |
- public void OnFrameCaptured(byte[] frame, int length, int width, int height, |
- int rotation, long timeStamp) { |
- synchronized (frameLock) { |
- ++framesCaptured; |
- frameSize = length; |
- timestamps.add(timeStamp); |
- frameLock.notify(); |
- } |
- } |
- |
- @Override |
- public void OnOutputFormatRequest(int width, int height, int fps) {} |
- |
- public boolean WaitForCapturerToStart() throws InterruptedException { |
- synchronized (capturerStartLock) { |
- capturerStartLock.wait(); |
- return captureStartResult; |
- } |
- } |
- |
- public int WaitForNextCapturedFrame() throws InterruptedException { |
- synchronized (frameLock) { |
- frameLock.wait(); |
- return framesCaptured; |
- } |
- } |
- |
- int frameSize() { |
- synchronized (frameLock) { |
- return frameSize; |
- } |
- } |
- |
- List<Long> getCopyAndResetListOftimeStamps() { |
- synchronized (frameLock) { |
- ArrayList<Long> list = new ArrayList<Long>(timestamps); |
- timestamps.clear(); |
- return list; |
- } |
- } |
- } |
- |
- // Return true if the device under test have at least two cameras. |
- @SuppressWarnings("deprecation") |
- boolean HaveTwoCameras() { |
- return (Camera.getNumberOfCameras() >= 2); |
- } |
- |
- void startCapturerAndRender(String deviceName) throws InterruptedException { |
- PeerConnectionFactory factory = new PeerConnectionFactory(); |
- VideoCapturerAndroid capturer = |
- VideoCapturerAndroid.create(deviceName, null); |
- VideoSource source = |
- factory.createVideoSource(capturer, new MediaConstraints()); |
- VideoTrack track = factory.createVideoTrack("dummy", source); |
- RendererCallbacks callbacks = new RendererCallbacks(); |
- track.addRenderer(new VideoRenderer(callbacks)); |
- assertTrue(callbacks.WaitForNextFrameToRender() > 0); |
- track.dispose(); |
- source.dispose(); |
- factory.dispose(); |
- assertTrue(capturer.isReleased()); |
- } |
- |
@Override |
protected void setUp() { |
assertTrue(PeerConnectionFactory.initializeAndroidGlobals( |
@@ -206,15 +76,18 @@ public class VideoCapturerAndroidTest extends ActivityTestCase { |
} |
@SmallTest |
- public void testCreateAndRelease() throws Exception { |
- VideoCapturerAndroid capturer = VideoCapturerAndroid.create("", null); |
- assertNotNull(capturer); |
- capturer.dispose(); |
- assertTrue(capturer.isReleased()); |
+ public void testCreateAndRelease() { |
+ VideoCapturerAndroidTestFixtures.release(VideoCapturerAndroid.create("", null)); |
+ } |
+ |
+ @SmallTest |
+ public void testCreateAndReleaseUsingTextures() { |
+ VideoCapturerAndroidTestFixtures.release( |
+ VideoCapturerAndroid.create("", null, EGL14.EGL_NO_CONTEXT)); |
} |
@SmallTest |
- public void testCreateNonExistingCamera() throws Exception { |
+ public void testCreateNonExistingCamera() { |
VideoCapturerAndroid capturer = VideoCapturerAndroid.create( |
"non-existing camera", null); |
assertNull(capturer); |
@@ -224,195 +97,135 @@ public class VideoCapturerAndroidTest extends ActivityTestCase { |
// This test that the camera can be started and that the frames are forwarded |
// to a Java video renderer using a "default" capturer. |
// It tests both the Java and the C++ layer. |
- public void testStartVideoCapturer() throws Exception { |
- startCapturerAndRender(""); |
+ public void testStartVideoCapturer() throws InterruptedException { |
+ VideoCapturerAndroid capturer = |
+ VideoCapturerAndroid.create("", null); |
+ VideoCapturerAndroidTestFixtures.startCapturerAndRender(capturer); |
} |
+ /* TODO(perkj): Enable once VideoCapture to texture support has landed in C++. |
+ @SmallTest |
+ public void testStartVideoCapturerUsingTextures() throws InterruptedException { |
+ VideoCapturerAndroid capturer = |
+ VideoCapturerAndroid.create("", null, EGL14.EGL_NO_CONTEXT); |
+ VideoCapturerAndroidTestFixtures.startCapturerAndRender(capturer); |
+ }*/ |
+ |
@SmallTest |
// This test that the camera can be started and that the frames are forwarded |
// to a Java video renderer using the front facing video capturer. |
// It tests both the Java and the C++ layer. |
- public void testStartFrontFacingVideoCapturer() throws Exception { |
- startCapturerAndRender(CameraEnumerationAndroid.getNameOfFrontFacingDevice()); |
+ public void testStartFrontFacingVideoCapturer() throws InterruptedException { |
+ String deviceName = CameraEnumerationAndroid.getNameOfFrontFacingDevice(); |
+ VideoCapturerAndroid capturer = |
+ VideoCapturerAndroid.create(deviceName, null); |
+ VideoCapturerAndroidTestFixtures.startCapturerAndRender(capturer); |
} |
@SmallTest |
// This test that the camera can be started and that the frames are forwarded |
// to a Java video renderer using the back facing video capturer. |
// It tests both the Java and the C++ layer. |
- public void testStartBackFacingVideoCapturer() throws Exception { |
- if (!HaveTwoCameras()) { |
+ public void testStartBackFacingVideoCapturer() throws InterruptedException { |
+ if (!VideoCapturerAndroidTestFixtures.HaveTwoCameras()) { |
return; |
} |
- startCapturerAndRender(CameraEnumerationAndroid.getNameOfBackFacingDevice()); |
+ |
+ String deviceName = CameraEnumerationAndroid.getNameOfBackFacingDevice(); |
+ VideoCapturerAndroid capturer = |
+ VideoCapturerAndroid.create(deviceName, null); |
+ VideoCapturerAndroidTestFixtures.startCapturerAndRender(capturer); |
} |
@SmallTest |
// This test that the default camera can be started and that the camera can |
// later be switched to another camera. |
// It tests both the Java and the C++ layer. |
- public void testSwitchVideoCapturer() throws Exception { |
- PeerConnectionFactory factory = new PeerConnectionFactory(); |
+ public void testSwitchVideoCapturer() throws InterruptedException { |
VideoCapturerAndroid capturer = VideoCapturerAndroid.create("", null); |
- VideoSource source = |
- factory.createVideoSource(capturer, new MediaConstraints()); |
- VideoTrack track = factory.createVideoTrack("dummy", source); |
- |
- // Array with one element to avoid final problem in nested classes. |
- final boolean[] cameraSwitchSuccessful = new boolean[1]; |
- final CountDownLatch barrier = new CountDownLatch(1); |
- capturer.switchCamera(new VideoCapturerAndroid.CameraSwitchHandler() { |
- @Override |
- public void onCameraSwitchDone(boolean isFrontCamera) { |
- cameraSwitchSuccessful[0] = true; |
- barrier.countDown(); |
- } |
- @Override |
- public void onCameraSwitchError(String errorDescription) { |
- cameraSwitchSuccessful[0] = false; |
- barrier.countDown(); |
- } |
- }); |
- // Wait until the camera has been switched. |
- barrier.await(); |
- |
- // Check result. |
- if (HaveTwoCameras()) { |
- assertTrue(cameraSwitchSuccessful[0]); |
- } else { |
- assertFalse(cameraSwitchSuccessful[0]); |
- } |
- // Ensure that frames are received. |
- RendererCallbacks callbacks = new RendererCallbacks(); |
- track.addRenderer(new VideoRenderer(callbacks)); |
- assertTrue(callbacks.WaitForNextFrameToRender() > 0); |
- track.dispose(); |
- source.dispose(); |
- factory.dispose(); |
- assertTrue(capturer.isReleased()); |
+ VideoCapturerAndroidTestFixtures.switchCamera(capturer); |
} |
+ /* TODO(perkj): Enable once VideoCapture to texture support has landed in C++. |
+ @SmallTest |
+ public void testSwitchVideoCapturerUsingTextures() throws InterruptedException { |
+ VideoCapturerAndroid capturer = VideoCapturerAndroid.create("", null, EGL14.EGL_NO_CONTEXT); |
+ VideoCapturerAndroidTestFixtures.switchCamera(capturer); |
+ }*/ |
+ |
@MediumTest |
// Test what happens when attempting to call e.g. switchCamera() after camera has been stopped. |
public void testCameraCallsAfterStop() throws InterruptedException { |
final String deviceName = CameraEnumerationAndroid.getDeviceName(0); |
final VideoCapturerAndroid capturer = VideoCapturerAndroid.create(deviceName, null); |
- final List<CaptureFormat> formats = CameraEnumerationAndroid.getSupportedFormats(0); |
- final CameraEnumerationAndroid.CaptureFormat format = formats.get(0); |
- final FakeCapturerObserver observer = new FakeCapturerObserver(); |
- capturer.startCapture(format.width, format.height, format.maxFramerate, |
- getInstrumentation().getContext(), observer); |
- // Make sure camera is started and then stop it. |
- assertTrue(observer.WaitForCapturerToStart()); |
- capturer.stopCapture(); |
- for (long timeStamp : observer.getCopyAndResetListOftimeStamps()) { |
- capturer.returnBuffer(timeStamp); |
- } |
- // We can't change |capturer| at this point, but we should not crash. |
- capturer.switchCamera(null); |
- capturer.onOutputFormatRequest(640, 480, 15); |
- capturer.changeCaptureFormat(640, 480, 15); |
+ VideoCapturerAndroidTestFixtures.cameraCallsAfterStop(capturer, |
+ getInstrumentation().getContext()); |
+ } |
+ |
+ @MediumTest |
+ public void testCameraCallsAfterStopUsingTextures() throws InterruptedException { |
+ final String deviceName = CameraEnumerationAndroid.getDeviceName(0); |
+ final VideoCapturerAndroid capturer = VideoCapturerAndroid.create(deviceName, null, |
+ EGL14.EGL_NO_CONTEXT); |
- capturer.dispose(); |
- assertTrue(capturer.isReleased()); |
+ VideoCapturerAndroidTestFixtures.cameraCallsAfterStop(capturer, |
+ getInstrumentation().getContext()); |
} |
@SmallTest |
// This test that the VideoSource that the VideoCapturer is connected to can |
// be stopped and restarted. It tests both the Java and the C++ layer. |
- public void testStopRestartVideoSource() throws Exception { |
- PeerConnectionFactory factory = new PeerConnectionFactory(); |
+ public void testStopRestartVideoSource() throws InterruptedException { |
VideoCapturerAndroid capturer = VideoCapturerAndroid.create("", null); |
- VideoSource source = |
- factory.createVideoSource(capturer, new MediaConstraints()); |
- VideoTrack track = factory.createVideoTrack("dummy", source); |
- RendererCallbacks callbacks = new RendererCallbacks(); |
- track.addRenderer(new VideoRenderer(callbacks)); |
- assertTrue(callbacks.WaitForNextFrameToRender() > 0); |
- assertEquals(MediaSource.State.LIVE, source.state()); |
- |
- source.stop(); |
- assertEquals(MediaSource.State.ENDED, source.state()); |
- |
- source.restart(); |
- assertTrue(callbacks.WaitForNextFrameToRender() > 0); |
- assertEquals(MediaSource.State.LIVE, source.state()); |
- track.dispose(); |
- source.dispose(); |
- factory.dispose(); |
- assertTrue(capturer.isReleased()); |
+ VideoCapturerAndroidTestFixtures.stopRestartVideoSource(capturer); |
} |
+ /* TODO(perkj): Enable once VideoCapture to texture support has landed in C++. |
+ @SmallTest |
+ public void testStopRestartVideoSourceUsingTextures() throws InterruptedException { |
+ VideoCapturerAndroid capturer = VideoCapturerAndroid.create("", null, EGL14.EGL_NO_CONTEXT); |
+ VideoCapturerAndroidTestFixtures.stopRestartVideoSource(capturer); |
+ }*/ |
+ |
@SmallTest |
// This test that the camera can be started at different resolutions. |
// It does not test or use the C++ layer. |
- public void testStartStopWithDifferentResolutions() throws Exception { |
- FakeCapturerObserver observer = new FakeCapturerObserver(); |
- |
+ public void testStartStopWithDifferentResolutions() throws InterruptedException { |
String deviceName = CameraEnumerationAndroid.getDeviceName(0); |
- List<CaptureFormat> formats = CameraEnumerationAndroid.getSupportedFormats(0); |
VideoCapturerAndroid capturer = |
VideoCapturerAndroid.create(deviceName, null); |
+ VideoCapturerAndroidTestFixtures.startStopWithDifferentResolutions(capturer, |
+ getInstrumentation().getContext()); |
+ } |
- for(int i = 0; i < 3 ; ++i) { |
- CameraEnumerationAndroid.CaptureFormat format = formats.get(i); |
- capturer.startCapture(format.width, format.height, format.maxFramerate, |
- getInstrumentation().getContext(), observer); |
- assertTrue(observer.WaitForCapturerToStart()); |
- observer.WaitForNextCapturedFrame(); |
- // Check the frame size. |
- assertEquals(format.frameSize(), observer.frameSize()); |
- capturer.stopCapture(); |
- for (long timestamp : observer.getCopyAndResetListOftimeStamps()) { |
- capturer.returnBuffer(timestamp); |
- } |
- } |
- capturer.dispose(); |
- assertTrue(capturer.isReleased()); |
+ @SmallTest |
+ public void testStartStopWithDifferentResolutionsUsingTextures() throws InterruptedException { |
+ String deviceName = CameraEnumerationAndroid.getDeviceName(0); |
+ VideoCapturerAndroid capturer = |
+ VideoCapturerAndroid.create(deviceName, null, EGL14.EGL_NO_CONTEXT); |
+ VideoCapturerAndroidTestFixtures.startStopWithDifferentResolutions(capturer, |
+ getInstrumentation().getContext()); |
} |
@SmallTest |
// This test what happens if buffers are returned after the capturer have |
// been stopped and restarted. It does not test or use the C++ layer. |
- public void testReturnBufferLate() throws Exception { |
- FakeCapturerObserver observer = new FakeCapturerObserver(); |
- |
+ public void testReturnBufferLate() throws InterruptedException { |
String deviceName = CameraEnumerationAndroid.getDeviceName(0); |
- List<CaptureFormat> formats = CameraEnumerationAndroid.getSupportedFormats(0); |
VideoCapturerAndroid capturer = |
VideoCapturerAndroid.create(deviceName, null); |
+ VideoCapturerAndroidTestFixtures.returnBufferLate(capturer, |
+ getInstrumentation().getContext()); |
+ } |
- CameraEnumerationAndroid.CaptureFormat format = formats.get(0); |
- capturer.startCapture(format.width, format.height, format.maxFramerate, |
- getInstrumentation().getContext(), observer); |
- assertTrue(observer.WaitForCapturerToStart()); |
- |
- observer.WaitForNextCapturedFrame(); |
- capturer.stopCapture(); |
- List<Long> listOftimestamps = observer.getCopyAndResetListOftimeStamps(); |
- assertTrue(listOftimestamps.size() >= 1); |
- |
- format = formats.get(1); |
- capturer.startCapture(format.width, format.height, format.maxFramerate, |
- getInstrumentation().getContext(), observer); |
- observer.WaitForCapturerToStart(); |
- observer.WaitForNextCapturedFrame(); |
- |
- for (Long timeStamp : listOftimestamps) { |
- capturer.returnBuffer(timeStamp); |
- } |
- |
- observer.WaitForNextCapturedFrame(); |
- capturer.stopCapture(); |
- |
- listOftimestamps = observer.getCopyAndResetListOftimeStamps(); |
- assertTrue(listOftimestamps.size() >= 2); |
- for (Long timeStamp : listOftimestamps) { |
- capturer.returnBuffer(timeStamp); |
- } |
- capturer.dispose(); |
- assertTrue(capturer.isReleased()); |
+ @SmallTest |
+ public void testReturnBufferLateUsingTextures() throws InterruptedException { |
+ String deviceName = CameraEnumerationAndroid.getDeviceName(0); |
+ VideoCapturerAndroid capturer = |
+ VideoCapturerAndroid.create(deviceName, null, EGL14.EGL_NO_CONTEXT); |
+ VideoCapturerAndroidTestFixtures.returnBufferLate(capturer, |
+ getInstrumentation().getContext()); |
} |
@MediumTest |
@@ -421,38 +234,14 @@ public class VideoCapturerAndroidTest extends ActivityTestCase { |
// also test the JNI and C++ AndroidVideoCapturer parts. |
public void testReturnBufferLateEndToEnd() throws InterruptedException { |
final VideoCapturerAndroid capturer = VideoCapturerAndroid.create("", null); |
- final PeerConnectionFactory factory = new PeerConnectionFactory(); |
- final VideoSource source = factory.createVideoSource(capturer, new MediaConstraints()); |
- final VideoTrack track = factory.createVideoTrack("dummy", source); |
- final FakeAsyncRenderer renderer = new FakeAsyncRenderer(); |
- track.addRenderer(new VideoRenderer(renderer)); |
- // Wait for at least one frame that has not been returned. |
- assertFalse(renderer.waitForPendingFrames().isEmpty()); |
- |
- capturer.stopCapture(); |
- |
- // Dispose everything. |
- track.dispose(); |
- source.dispose(); |
- factory.dispose(); |
- |
- // The pending frames should keep the JNI parts and |capturer| alive. |
- assertFalse(capturer.isReleased()); |
- |
- // Return the frame(s), on a different thread out of spite. |
- final List<I420Frame> pendingFrames = renderer.waitForPendingFrames(); |
- final Thread returnThread = new Thread(new Runnable() { |
- @Override |
- public void run() { |
- for (I420Frame frame : pendingFrames) { |
- VideoRenderer.renderFrameDone(frame); |
- } |
- } |
- }); |
- returnThread.start(); |
- returnThread.join(); |
- |
- // Check that frames have successfully returned. This will cause |capturer| to be released. |
- assertTrue(capturer.isReleased()); |
+ VideoCapturerAndroidTestFixtures.returnBufferLateEndToEnd(capturer); |
} |
+ |
+ /* TODO(perkj): Enable once VideoCapture to texture support has landed in C++. |
+ @MediumTest |
+ public void testReturnBufferLateEndToEndUsingTextures() throws InterruptedException { |
+ final VideoCapturerAndroid capturer = |
+ VideoCapturerAndroid.create("", null, EGL14.EGL_NO_CONTEXT); |
+ VideoCapturerAndroidTestFixtures.returnBufferLateEndToEnd(capturer); |
+ }*/ |
} |