diff --git a/webrtc/api/androidtests/src/org/webrtc/Camera1CapturerUsingByteBufferTest.java b/webrtc/api/androidtests/src/org/webrtc/Camera1CapturerUsingByteBufferTest.java index c6d23cd26a..9fe1ba3dc8 100644 --- a/webrtc/api/androidtests/src/org/webrtc/Camera1CapturerUsingByteBufferTest.java +++ b/webrtc/api/androidtests/src/org/webrtc/Camera1CapturerUsingByteBufferTest.java @@ -22,7 +22,7 @@ public class Camera1CapturerUsingByteBufferTest extends InstrumentationTestCase static final String TAG = "Camera1CapturerUsingByteBufferTest"; private class TestObjectFactory - implements CameraVideoCapturerTestFixtures.TestObjectFactory { + extends CameraVideoCapturerTestFixtures.TestObjectFactory { @Override public CameraVideoCapturer createCapturer( String name, @@ -30,28 +30,16 @@ public class Camera1CapturerUsingByteBufferTest extends InstrumentationTestCase return new VideoCapturerAndroid(name, eventsHandler, isCapturingToTexture()); } - @Override - public String getNameOfFrontFacingDevice() { - return CameraEnumerationAndroid.getNameOfFrontFacingDevice(); - } - - @Override - public String getNameOfBackFacingDevice() { - return CameraEnumerationAndroid.getNameOfBackFacingDevice(); - } - - // Return true if the device under test have at least two cameras. - @SuppressWarnings("deprecation") - @Override - public boolean haveTwoCameras() { - return (android.hardware.Camera.getNumberOfCameras() >= 2); - } - @Override public boolean isCapturingToTexture() { return false; } + @Override + public CameraEnumerator getCameraEnumerator() { + return new Camera1Enumerator(); + } + @Override public Context getAppContext() { return getInstrumentation().getTargetContext(); @@ -60,7 +48,7 @@ public class Camera1CapturerUsingByteBufferTest extends InstrumentationTestCase @SuppressWarnings("deprecation") @Override public Object rawOpenCamera(String cameraName) { - return android.hardware.Camera.open(CameraEnumerationAndroid.getCameraIndex(cameraName)); + return android.hardware.Camera.open(Camera1Enumerator.getCameraIndex(cameraName)); } @SuppressWarnings("deprecation") diff --git a/webrtc/api/androidtests/src/org/webrtc/Camera1CapturerUsingTextureTest.java b/webrtc/api/androidtests/src/org/webrtc/Camera1CapturerUsingTextureTest.java index 27b54dbe3e..614105cd5d 100644 --- a/webrtc/api/androidtests/src/org/webrtc/Camera1CapturerUsingTextureTest.java +++ b/webrtc/api/androidtests/src/org/webrtc/Camera1CapturerUsingTextureTest.java @@ -22,34 +22,10 @@ public class Camera1CapturerUsingTextureTest extends InstrumentationTestCase { static final String TAG = "Camera1CapturerUsingTextureTest"; private class TestObjectFactory - implements CameraVideoCapturerTestFixtures.TestObjectFactory { + extends CameraVideoCapturerTestFixtures.TestObjectFactory { @Override - public CameraVideoCapturer createCapturer( - String name, - CameraVideoCapturer.CameraEventsHandler eventsHandler) { - return new VideoCapturerAndroid(name, eventsHandler, isCapturingToTexture()); - } - - @Override - public String getNameOfFrontFacingDevice() { - return CameraEnumerationAndroid.getNameOfFrontFacingDevice(); - } - - @Override - public String getNameOfBackFacingDevice() { - return CameraEnumerationAndroid.getNameOfBackFacingDevice(); - } - - // Return true if the device under test have at least two cameras. - @SuppressWarnings("deprecation") - @Override - public boolean haveTwoCameras() { - return (android.hardware.Camera.getNumberOfCameras() >= 2); - } - - @Override - public boolean isCapturingToTexture() { - return true; + public CameraEnumerator getCameraEnumerator() { + return new Camera1Enumerator(); } @Override @@ -60,7 +36,7 @@ public class Camera1CapturerUsingTextureTest extends InstrumentationTestCase { @SuppressWarnings("deprecation") @Override public Object rawOpenCamera(String cameraName) { - return android.hardware.Camera.open(CameraEnumerationAndroid.getCameraIndex(cameraName)); + return android.hardware.Camera.open(Camera1Enumerator.getCameraIndex(cameraName)); } @SuppressWarnings("deprecation") diff --git a/webrtc/api/androidtests/src/org/webrtc/CameraVideoCapturerTestFixtures.java b/webrtc/api/androidtests/src/org/webrtc/CameraVideoCapturerTestFixtures.java index 30119e5a1f..43ee88d0d4 100644 --- a/webrtc/api/androidtests/src/org/webrtc/CameraVideoCapturerTestFixtures.java +++ b/webrtc/api/androidtests/src/org/webrtc/CameraVideoCapturerTestFixtures.java @@ -240,19 +240,55 @@ class CameraVideoCapturerTestFixtures { public FakeAsyncRenderer fakeAsyncRenderer; } - public interface TestObjectFactory { - CameraVideoCapturer createCapturer( - String name, CameraVideoCapturer.CameraEventsHandler eventsHandler); - String getNameOfFrontFacingDevice(); - String getNameOfBackFacingDevice(); - boolean haveTwoCameras(); - boolean isCapturingToTexture(); - Context getAppContext(); + public abstract static class TestObjectFactory { + final CameraEnumerator cameraEnumerator; + + TestObjectFactory() { + cameraEnumerator = getCameraEnumerator(); + } + + public CameraVideoCapturer createCapturer( + String name, + CameraVideoCapturer.CameraEventsHandler eventsHandler) { + return cameraEnumerator.createCapturer(name, eventsHandler); + } + + public String getNameOfFrontFacingDevice() { + for (String deviceName : cameraEnumerator.getDeviceNames()) { + if (cameraEnumerator.isFrontFacing(deviceName)) { + return deviceName; + } + } + + return null; + } + + public String getNameOfBackFacingDevice() { + for (String deviceName : cameraEnumerator.getDeviceNames()) { + if (cameraEnumerator.isBackFacing(deviceName)) { + return deviceName; + } + } + + return null; + } + + public boolean haveTwoCameras() { + return cameraEnumerator.getDeviceNames().length >= 2; + } + + public boolean isCapturingToTexture() { + // In the future, we plan to only support capturing to texture, so default to true + return true; + } + + abstract public CameraEnumerator getCameraEnumerator(); + abstract public Context getAppContext(); // CameraVideoCapturer API is too slow for some of our tests where we need to open a competing // camera. These methods are used instead. - Object rawOpenCamera(String cameraName); - void rawCloseCamera(Object camera); + abstract public Object rawOpenCamera(String cameraName); + abstract public void rawCloseCamera(Object camera); } private PeerConnectionFactory peerConnectionFactory; diff --git a/webrtc/api/java/android/org/webrtc/Camera1Enumerator.java b/webrtc/api/java/android/org/webrtc/Camera1Enumerator.java new file mode 100644 index 0000000000..13a5237074 --- /dev/null +++ b/webrtc/api/java/android/org/webrtc/Camera1Enumerator.java @@ -0,0 +1,159 @@ +/* + * Copyright 2015 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +package org.webrtc; + +import org.webrtc.CameraEnumerationAndroid.CaptureFormat; + +import android.os.SystemClock; + +import java.util.ArrayList; +import java.util.List; + +@SuppressWarnings("deprecation") +public class Camera1Enumerator implements CameraEnumerator { + private final static String TAG = "Camera1Enumerator"; + // Each entry contains the supported formats for corresponding camera index. The formats for all + // cameras are enumerated on the first call to getSupportedFormats(), and cached for future + // reference. + private static List> cachedSupportedFormats; + + + public boolean isFrontFacing(String deviceName) { + android.hardware.Camera.CameraInfo info = getCameraInfo(getCameraIndex(deviceName)); + return info.facing == android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT; + } + + public boolean isBackFacing(String deviceName) { + android.hardware.Camera.CameraInfo info = getCameraInfo(getCameraIndex(deviceName)); + return info.facing == android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK; + } + + public CameraVideoCapturer createCapturer(String deviceName, + CameraVideoCapturer.CameraEventsHandler eventsHandler) { + return new VideoCapturerAndroid(deviceName, eventsHandler, true); + } + + private static android.hardware.Camera.CameraInfo getCameraInfo(int index) { + android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); + try { + android.hardware.Camera.getCameraInfo(index, info); + } catch (Exception e) { + Logging.e(TAG, "getCameraInfo failed on index " + index,e); + return null; + } + return info; + } + + static synchronized List getSupportedFormats(int cameraId) { + if (cachedSupportedFormats == null) { + cachedSupportedFormats = new ArrayList>(); + for (int i = 0; i < CameraEnumerationAndroid.getDeviceCount(); ++i) { + cachedSupportedFormats.add(enumerateFormats(i)); + } + } + return cachedSupportedFormats.get(cameraId); + } + + private static List enumerateFormats(int cameraId) { + Logging.d(TAG, "Get supported formats for camera index " + cameraId + "."); + final long startTimeMs = SystemClock.elapsedRealtime(); + final android.hardware.Camera.Parameters parameters; + android.hardware.Camera camera = null; + try { + Logging.d(TAG, "Opening camera with index " + cameraId); + camera = android.hardware.Camera.open(cameraId); + parameters = camera.getParameters(); + } catch (RuntimeException e) { + Logging.e(TAG, "Open camera failed on camera index " + cameraId, e); + return new ArrayList(); + } finally { + if (camera != null) { + camera.release(); + } + } + + final List formatList = new ArrayList(); + try { + int minFps = 0; + int maxFps = 0; + final List listFpsRange = parameters.getSupportedPreviewFpsRange(); + if (listFpsRange != null) { + // getSupportedPreviewFpsRange() returns a sorted list. Take the fps range + // corresponding to the highest fps. + final int[] range = listFpsRange.get(listFpsRange.size() - 1); + minFps = range[android.hardware.Camera.Parameters.PREVIEW_FPS_MIN_INDEX]; + maxFps = range[android.hardware.Camera.Parameters.PREVIEW_FPS_MAX_INDEX]; + } + for (android.hardware.Camera.Size size : parameters.getSupportedPreviewSizes()) { + formatList.add(new CaptureFormat(size.width, size.height, minFps, maxFps)); + } + } catch (Exception e) { + Logging.e(TAG, "getSupportedFormats() failed on camera index " + cameraId, e); + } + + final long endTimeMs = SystemClock.elapsedRealtime(); + Logging.d(TAG, "Get supported formats for camera index " + cameraId + " done." + + " Time spent: " + (endTimeMs - startTimeMs) + " ms."); + return formatList; + } + + // Convert from android.hardware.Camera.Size to Size. + public static List convertSizes(List cameraSizes) { + final List sizes = new ArrayList(); + for (android.hardware.Camera.Size size : cameraSizes) { + sizes.add(new Size(size.width, size.height)); + } + return sizes; + } + + // Convert from int[2] to CaptureFormat.FramerateRange. + public static List convertFramerates(List arrayRanges) { + final List ranges = new ArrayList(); + for (int[] range : arrayRanges) { + ranges.add(new CaptureFormat.FramerateRange( + range[android.hardware.Camera.Parameters.PREVIEW_FPS_MIN_INDEX], + range[android.hardware.Camera.Parameters.PREVIEW_FPS_MAX_INDEX])); + } + return ranges; + } + + // Returns device names that can be used to create a new VideoCapturerAndroid. + public String[] getDeviceNames() { + String[] names = new String[android.hardware.Camera.getNumberOfCameras()]; + for (int i = 0; i < android.hardware.Camera.getNumberOfCameras(); ++i) { + names[i] = getDeviceName(i); + } + return names; + } + + // Returns the camera index for camera with name |deviceName|, or throws IllegalArgumentException + // if no such camera can be found. + static int getCameraIndex(String deviceName) { + Logging.d(TAG, "getCameraIndex: " + deviceName); + for (int i = 0; i < android.hardware.Camera.getNumberOfCameras(); ++i) { + if (deviceName.equals(CameraEnumerationAndroid.getDeviceName(i))) { + return i; + } + } + throw new IllegalArgumentException("No such camera: " + deviceName); + } + + // Returns the name of the camera with camera index. Returns null if the + // camera can not be used. + static String getDeviceName(int index) { + android.hardware.Camera.CameraInfo info = getCameraInfo(index); + + String facing = + (info.facing == android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT) ? "front" : "back"; + return "Camera " + index + ", Facing " + facing + + ", Orientation " + info.orientation; + } +} diff --git a/webrtc/api/java/android/org/webrtc/CameraEnumerationAndroid.java b/webrtc/api/java/android/org/webrtc/CameraEnumerationAndroid.java index f3e08f6f33..b3c5062a76 100644 --- a/webrtc/api/java/android/org/webrtc/CameraEnumerationAndroid.java +++ b/webrtc/api/java/android/org/webrtc/CameraEnumerationAndroid.java @@ -114,57 +114,48 @@ public class CameraEnumerationAndroid { } } - // Returns device names that can be used to create a new VideoCapturerAndroid. + /** + * @deprecated + * Please use Camera1Enumerator.getDeviceNames() instead. + */ + @Deprecated public static String[] getDeviceNames() { - String[] names = new String[android.hardware.Camera.getNumberOfCameras()]; - for (int i = 0; i < android.hardware.Camera.getNumberOfCameras(); ++i) { - names[i] = getDeviceName(i); - } - return names; + return new Camera1Enumerator().getDeviceNames(); } - // Returns number of cameras on device. + + /** + * @deprecated + * Please use Camera1Enumerator.getDeviceNames().length instead. + */ + @Deprecated public static int getDeviceCount() { - return android.hardware.Camera.getNumberOfCameras(); + return new Camera1Enumerator().getDeviceNames().length; } - // Returns the name of the camera with camera index. Returns null if the - // camera can not be used. + /** + * @deprecated + * Please use Camera1Enumerator.getDeviceNames().get(index) instead. + */ + @Deprecated public static String getDeviceName(int index) { - android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); - try { - android.hardware.Camera.getCameraInfo(index, info); - } catch (Exception e) { - Logging.e(TAG, "getCameraInfo failed on index " + index,e); - return null; - } - - String facing = - (info.facing == android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT) ? "front" : "back"; - return "Camera " + index + ", Facing " + facing - + ", Orientation " + info.orientation; + return new Camera1Enumerator().getDeviceName(index); } - // Returns the camera index for camera with name |deviceName|, or throws IllegalArgumentException - // if no such camera can be found. - public static int getCameraIndex(String deviceName) { - Logging.d(TAG, "getCameraIndex: " + deviceName); - for (int i = 0; i < android.hardware.Camera.getNumberOfCameras(); ++i) { - if (deviceName.equals(CameraEnumerationAndroid.getDeviceName(i))) { - return i; - } - } - throw new IllegalArgumentException("No such camera: " + deviceName); - } - - // Returns the name of the front facing camera. Returns null if the - // camera can not be used or does not exist. + /** + * @deprecated + * Please use Camera1Enumerator.isFrontFacing(String deviceName) instead. + */ + @Deprecated public static String getNameOfFrontFacingDevice() { return getNameOfDevice(android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT); } - // Returns the name of the back facing camera. Returns null if the - // camera can not be used or does not exist. + /** + * @deprecated + * Please use Camera1Enumerator.isBackFacing(String deviceName) instead. + */ + @Deprecated public static String getNameOfBackFacingDevice() { return getNameOfDevice(android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK); } diff --git a/webrtc/api/java/android/org/webrtc/CameraEnumerator.java b/webrtc/api/java/android/org/webrtc/CameraEnumerator.java index 203c1954b7..752e10aed2 100644 --- a/webrtc/api/java/android/org/webrtc/CameraEnumerator.java +++ b/webrtc/api/java/android/org/webrtc/CameraEnumerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 The WebRTC project authors. All Rights Reserved. + * Copyright 2016 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source @@ -10,94 +10,11 @@ package org.webrtc; -import android.os.SystemClock; +public interface CameraEnumerator { + public String[] getDeviceNames(); + public boolean isFrontFacing(String deviceName); + public boolean isBackFacing(String deviceName); -import org.webrtc.CameraEnumerationAndroid.CaptureFormat; -import org.webrtc.Logging; - -import java.util.ArrayList; -import java.util.List; - -@SuppressWarnings("deprecation") -public class CameraEnumerator { - private final static String TAG = "CameraEnumerator"; - // Each entry contains the supported formats for corresponding camera index. The formats for all - // cameras are enumerated on the first call to getSupportedFormats(), and cached for future - // reference. - private static List> cachedSupportedFormats; - - public static synchronized List getSupportedFormats(int cameraId) { - if (cachedSupportedFormats == null) { - cachedSupportedFormats = new ArrayList>(); - for (int i = 0; i < CameraEnumerationAndroid.getDeviceCount(); ++i) { - cachedSupportedFormats.add(enumerateFormats(i)); - } - } - return cachedSupportedFormats.get(cameraId); - } - - private static List enumerateFormats(int cameraId) { - Logging.d(TAG, "Get supported formats for camera index " + cameraId + "."); - final long startTimeMs = SystemClock.elapsedRealtime(); - final android.hardware.Camera.Parameters parameters; - android.hardware.Camera camera = null; - try { - Logging.d(TAG, "Opening camera with index " + cameraId); - camera = android.hardware.Camera.open(cameraId); - parameters = camera.getParameters(); - } catch (RuntimeException e) { - Logging.e(TAG, "Open camera failed on camera index " + cameraId, e); - return new ArrayList(); - } finally { - if (camera != null) { - camera.release(); - } - } - - final List formatList = new ArrayList(); - try { - int minFps = 0; - int maxFps = 0; - final List listFpsRange = parameters.getSupportedPreviewFpsRange(); - if (listFpsRange != null) { - // getSupportedPreviewFpsRange() returns a sorted list. Take the fps range - // corresponding to the highest fps. - final int[] range = listFpsRange.get(listFpsRange.size() - 1); - minFps = range[android.hardware.Camera.Parameters.PREVIEW_FPS_MIN_INDEX]; - maxFps = range[android.hardware.Camera.Parameters.PREVIEW_FPS_MAX_INDEX]; - } - for (android.hardware.Camera.Size size : parameters.getSupportedPreviewSizes()) { - formatList.add(new CaptureFormat(size.width, size.height, minFps, maxFps)); - } - } catch (Exception e) { - Logging.e(TAG, "getSupportedFormats() failed on camera index " + cameraId, e); - } - - final long endTimeMs = SystemClock.elapsedRealtime(); - Logging.d(TAG, "Get supported formats for camera index " + cameraId + " done." - + " Time spent: " + (endTimeMs - startTimeMs) + " ms."); - return formatList; - } - - // Convert from android.hardware.Camera.Size to Size. - public static List convertSizes( - List cameraSizes) { - final List sizes = new ArrayList(); - for (android.hardware.Camera.Size size : cameraSizes) { - sizes.add(new Size(size.width, size.height)); - } - return sizes; - } - - // Convert from int[2] to CaptureFormat.FramerateRange. - public static List convertFramerates( - List arrayRanges) { - final List ranges = new ArrayList(); - for (int[] range : arrayRanges) { - ranges.add(new CaptureFormat.FramerateRange( - range[android.hardware.Camera.Parameters.PREVIEW_FPS_MIN_INDEX], - range[android.hardware.Camera.Parameters.PREVIEW_FPS_MAX_INDEX])); - } - return ranges; - } + public CameraVideoCapturer createCapturer(String deviceName, + CameraVideoCapturer.CameraEventsHandler eventsHandler); } diff --git a/webrtc/api/java/android/org/webrtc/VideoCapturerAndroid.java b/webrtc/api/java/android/org/webrtc/VideoCapturerAndroid.java index 5e9a5a6f2f..7e9d019825 100644 --- a/webrtc/api/java/android/org/webrtc/VideoCapturerAndroid.java +++ b/webrtc/api/java/android/org/webrtc/VideoCapturerAndroid.java @@ -208,7 +208,7 @@ public class VideoCapturerAndroid implements @Override public List getSupportedFormats() { - return CameraEnumerator.getSupportedFormats(getCurrentCameraId()); + return Camera1Enumerator.getSupportedFormats(getCurrentCameraId()); } // Returns true if this VideoCapturer is setup to capture video frames to a SurfaceTexture. @@ -224,7 +224,7 @@ public class VideoCapturerAndroid implements if (cameraName == null || cameraName.equals("")) { this.id = 0; } else { - this.id = CameraEnumerationAndroid.getCameraIndex(cameraName); + this.id = Camera1Enumerator.getCameraIndex(cameraName); } this.eventsHandler = eventsHandler; isCapturingToTexture = captureToTexture; @@ -391,14 +391,14 @@ public class VideoCapturerAndroid implements // Find closest supported format for |width| x |height| @ |framerate|. final android.hardware.Camera.Parameters parameters = camera.getParameters(); final List supportedFramerates = - CameraEnumerator.convertFramerates(parameters.getSupportedPreviewFpsRange()); + Camera1Enumerator.convertFramerates(parameters.getSupportedPreviewFpsRange()); Logging.d(TAG, "Available fps ranges: " + supportedFramerates); final CaptureFormat.FramerateRange fpsRange = CameraEnumerationAndroid.getClosestSupportedFramerateRange(supportedFramerates, framerate); final Size previewSize = CameraEnumerationAndroid.getClosestSupportedSize( - CameraEnumerator.convertSizes(parameters.getSupportedPreviewSizes()), width, height); + Camera1Enumerator.convertSizes(parameters.getSupportedPreviewSizes()), width, height); final CaptureFormat captureFormat = new CaptureFormat(previewSize.width, previewSize.height, fpsRange); @@ -427,7 +427,7 @@ public class VideoCapturerAndroid implements // Picture size is for taking pictures and not for preview/video, but we need to set it anyway // as a workaround for an aspect ratio problem on Nexus 7. final Size pictureSize = CameraEnumerationAndroid.getClosestSupportedSize( - CameraEnumerator.convertSizes(parameters.getSupportedPictureSizes()), width, height); + Camera1Enumerator.convertSizes(parameters.getSupportedPictureSizes()), width, height); parameters.setPictureSize(pictureSize.width, pictureSize.height); // Temporarily stop preview if it's already running. diff --git a/webrtc/api/java/jni/classreferenceholder.cc b/webrtc/api/java/jni/classreferenceholder.cc index 8ed01c51ee..3d8f304aa1 100644 --- a/webrtc/api/java/jni/classreferenceholder.cc +++ b/webrtc/api/java/jni/classreferenceholder.cc @@ -48,7 +48,7 @@ ClassReferenceHolder::ClassReferenceHolder(JNIEnv* jni) { LoadClass(jni, "java/nio/ByteBuffer"); LoadClass(jni, "java/util/ArrayList"); LoadClass(jni, "org/webrtc/AudioTrack"); - LoadClass(jni, "org/webrtc/CameraEnumerator"); + LoadClass(jni, "org/webrtc/Camera1Enumerator"); LoadClass(jni, "org/webrtc/Camera2Enumerator"); LoadClass(jni, "org/webrtc/CameraEnumerationAndroid"); LoadClass(jni, "org/webrtc/DataChannel");