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

Unified Diff: webrtc/api/java/android/org/webrtc/Camera2Enumerator.java

Issue 2078473002: Android: Camera2 implementation and tests for it. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@enumerator_change
Patch Set: Make stopCapture non-blocking. Created 4 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: webrtc/api/java/android/org/webrtc/Camera2Enumerator.java
diff --git a/webrtc/api/java/android/org/webrtc/Camera2Enumerator.java b/webrtc/api/java/android/org/webrtc/Camera2Enumerator.java
index 8c342c5c25b51716dd6f1149945330bb22535d9e..fe2b259d2c727af68bef49a2648562796a4b787b 100644
--- a/webrtc/api/java/android/org/webrtc/Camera2Enumerator.java
+++ b/webrtc/api/java/android/org/webrtc/Camera2Enumerator.java
@@ -10,20 +10,20 @@
package org.webrtc;
+import org.webrtc.CameraEnumerationAndroid.CaptureFormat;
+
import android.annotation.TargetApi;
import android.content.Context;
-
import android.graphics.ImageFormat;
+import android.graphics.SurfaceTexture;
+import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.os.Build;
import android.os.SystemClock;
import android.util.Range;
-import android.util.Size;
-
-import org.webrtc.CameraEnumerationAndroid.CaptureFormat;
-import org.webrtc.Logging;
import java.util.ArrayList;
import java.util.HashMap;
@@ -31,7 +31,7 @@ import java.util.List;
import java.util.Map;
@TargetApi(21)
-public class Camera2Enumerator {
+public class Camera2Enumerator implements CameraEnumerator {
private final static String TAG = "Camera2Enumerator";
private final static double NANO_SECONDS_PER_SECOND = 1.0e9;
@@ -40,21 +40,104 @@ public class Camera2Enumerator {
private static final Map<String, List<CaptureFormat>> cachedSupportedFormats =
new HashMap<String, List<CaptureFormat>>();
+ final Context context;
+ final CameraManager cameraManager;
+
+ public Camera2Enumerator(Context context) {
+ this.context = context;
+ this.cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
+ }
+
+ @Override
+ public String[] getDeviceNames() {
+ try {
+ return cameraManager.getCameraIdList();
+ } catch (CameraAccessException e) {
+ Logging.e(TAG, "Camera access exception: " + e);
+ return new String[] {};
+ }
+ }
+
+ @Override
+ public boolean isFrontFacing(String deviceName) {
+ CameraCharacteristics characteristics
+ = getCameraCharacteristics(deviceName);
+
+ return characteristics != null
+ && characteristics.get(CameraCharacteristics.LENS_FACING)
+ == CameraMetadata.LENS_FACING_FRONT;
+ }
+
+ @Override
+ public boolean isBackFacing(String deviceName) {
+ CameraCharacteristics characteristics
+ = getCameraCharacteristics(deviceName);
+
+ return characteristics != null
+ && characteristics.get(CameraCharacteristics.LENS_FACING)
+ == CameraMetadata.LENS_FACING_BACK;
+ }
+
+ @Override
+ public CameraVideoCapturer createCapturer(String deviceName,
+ CameraVideoCapturer.CameraEventsHandler eventsHandler) {
+ return new Camera2Capturer(context, deviceName, eventsHandler);
+ }
+
+ private CameraCharacteristics getCameraCharacteristics(String deviceName) {
+ try {
+ return cameraManager.getCameraCharacteristics(deviceName);
+ } catch (CameraAccessException e) {
+ Logging.e(TAG, "Camera access exception: " + e);
+ return null;
+ }
+ }
+
public static boolean isSupported() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
}
- public static List<CaptureFormat> getSupportedFormats(Context context, String cameraId) {
+ static List<CaptureFormat.FramerateRange> getSupportedFramerateRanges(
+ CameraCharacteristics cameraCharacteristics) {
+ final Range<Integer>[] fpsRanges =
+ cameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
+
+ if (fpsRanges == null) {
+ return new ArrayList<CaptureFormat.FramerateRange>();
+ }
+
+ int maxFps = 0;
+ for (Range<Integer> fpsRange : fpsRanges) {
+ maxFps = Math.max(maxFps, fpsRange.getUpper());
+ }
+ int unitFactor = maxFps < 1000 ? 1000 : 1;
+ return convertFramerates(fpsRanges, unitFactor);
+ }
+
+ static List<Size> getSupportedSizes(
+ CameraCharacteristics cameraCharacteristics) {
+ final StreamConfigurationMap streamMap =
+ cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+ final android.util.Size[] sizes = streamMap.getOutputSizes(SurfaceTexture.class);
+ if (sizes == null) {
+ Logging.e(TAG, "No supported camera output sizes.");
+ return new ArrayList<Size>();
+ }
+ return convertSizes(sizes);
+ }
+
+ static List<CaptureFormat> getSupportedFormats(Context context, String cameraId) {
return getSupportedFormats(
(CameraManager) context.getSystemService(Context.CAMERA_SERVICE), cameraId);
}
- public static List<CaptureFormat> getSupportedFormats(
+ static List<CaptureFormat> getSupportedFormats(
CameraManager cameraManager, String cameraId) {
synchronized (cachedSupportedFormats) {
if (cachedSupportedFormats.containsKey(cameraId)) {
return cachedSupportedFormats.get(cameraId);
}
+
Logging.d(TAG, "Get supported formats for camera index " + cameraId + ".");
final long startTimeMs = SystemClock.elapsedRealtime();
@@ -66,35 +149,34 @@ public class Camera2Enumerator {
return new ArrayList<CaptureFormat>();
}
- // Calculate default max fps from auto-exposure ranges in case getOutputMinFrameDuration() is
- // not supported.
- final Range<Integer>[] fpsRanges =
- cameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
- int defaultMaxFps = 0;
- for (Range<Integer> fpsRange : fpsRanges) {
- defaultMaxFps = Math.max(defaultMaxFps, fpsRange.getUpper());
- }
-
final StreamConfigurationMap streamMap =
cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
- final Size[] sizes = streamMap.getOutputSizes(ImageFormat.YUV_420_888);
- if (sizes == null) {
- throw new RuntimeException("ImageFormat.YUV_420_888 not supported.");
+
+ List<CaptureFormat.FramerateRange> framerateRanges = getSupportedFramerateRanges(
+ cameraCharacteristics);
+ List<Size> sizes = getSupportedSizes(cameraCharacteristics);
+
+ int defaultMaxFps = 0;
+ for (CaptureFormat.FramerateRange framerateRange : framerateRanges) {
+ defaultMaxFps = Math.max(defaultMaxFps, framerateRange.max);
}
final List<CaptureFormat> formatList = new ArrayList<CaptureFormat>();
for (Size size : sizes) {
long minFrameDurationNs = 0;
try {
- minFrameDurationNs = streamMap.getOutputMinFrameDuration(ImageFormat.YUV_420_888, size);
+ minFrameDurationNs = streamMap.getOutputMinFrameDuration(SurfaceTexture.class,
+ new android.util.Size(size.width, size.height));
} catch (Exception e) {
// getOutputMinFrameDuration() is not supported on all devices. Ignore silently.
}
final int maxFps = (minFrameDurationNs == 0)
- ? defaultMaxFps
- : (int) Math.round(NANO_SECONDS_PER_SECOND / minFrameDurationNs);
- formatList.add(new CaptureFormat(size.getWidth(), size.getHeight(), 0, maxFps * 1000));
+ ? defaultMaxFps
+ : (int) Math.round(NANO_SECONDS_PER_SECOND / minFrameDurationNs) * 1000;
+ formatList.add(new CaptureFormat(size.width, size.height, 0, maxFps));
+ Logging.d(TAG, "Format: " + size.width + "x" + size.height + "@" + maxFps);
}
+
cachedSupportedFormats.put(cameraId, formatList);
final long endTimeMs = SystemClock.elapsedRealtime();
Logging.d(TAG, "Get supported formats for camera index " + cameraId + " done."
@@ -102,4 +184,25 @@ public class Camera2Enumerator {
return formatList;
}
}
+
+ // Convert from android.util.Size to Size.
+ private static List<Size> convertSizes(android.util.Size[] cameraSizes) {
+ final List<Size> sizes = new ArrayList<Size>();
+ for (android.util.Size size : cameraSizes) {
+ sizes.add(new Size(size.getWidth(), size.getHeight()));
+ }
+ return sizes;
+ }
+
+ // Convert from android.util.Range<Integer> to CaptureFormat.FramerateRange.
+ private static List<CaptureFormat.FramerateRange> convertFramerates(
+ Range<Integer>[] arrayRanges, int unitFactor) {
+ final List<CaptureFormat.FramerateRange> ranges = new ArrayList<CaptureFormat.FramerateRange>();
+ for (Range<Integer> range : arrayRanges) {
+ ranges.add(new CaptureFormat.FramerateRange(
+ range.getLower() * unitFactor,
+ range.getUpper() * unitFactor));
+ }
+ return ranges;
+ }
}

Powered by Google App Engine
This is Rietveld 408576698