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

Side by Side 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: Longer delimeter. 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 unified diff | Download patch
OLDNEW
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 10
11 package org.webrtc; 11 package org.webrtc;
12 12
13 import android.annotation.TargetApi; 13 import android.annotation.TargetApi;
14 import android.content.Context; 14 import android.content.Context;
15 15
16 import android.graphics.ImageFormat; 16 import android.graphics.ImageFormat;
17 import android.graphics.SurfaceTexture;
18 import android.hardware.camera2.CameraAccessException;
17 import android.hardware.camera2.CameraCharacteristics; 19 import android.hardware.camera2.CameraCharacteristics;
18 import android.hardware.camera2.CameraManager; 20 import android.hardware.camera2.CameraManager;
21 import android.hardware.camera2.CameraMetadata;
19 import android.hardware.camera2.params.StreamConfigurationMap; 22 import android.hardware.camera2.params.StreamConfigurationMap;
20 import android.os.Build; 23 import android.os.Build;
21 import android.os.SystemClock; 24 import android.os.SystemClock;
22 import android.util.Range; 25 import android.util.Range;
23 import android.util.Size;
24 26
25 import org.webrtc.CameraEnumerationAndroid.CaptureFormat; 27 import org.webrtc.CameraEnumerationAndroid.CaptureFormat;
26 import org.webrtc.Logging; 28 import org.webrtc.Logging;
27 29
28 import java.util.ArrayList; 30 import java.util.ArrayList;
29 import java.util.HashMap; 31 import java.util.HashMap;
30 import java.util.List; 32 import java.util.List;
31 import java.util.Map; 33 import java.util.Map;
32 34
33 @TargetApi(21) 35 @TargetApi(21)
34 public class Camera2Enumerator { 36 public class Camera2Enumerator implements CameraEnumerator {
35 private final static String TAG = "Camera2Enumerator"; 37 private final static String TAG = "Camera2Enumerator";
36 private final static double NANO_SECONDS_PER_SECOND = 1.0e9; 38 private final static double NANO_SECONDS_PER_SECOND = 1.0e9;
37 39
38 // Each entry contains the supported formats for a given camera index. The for mats are enumerated 40 // Each entry contains the supported formats for a given camera index. The for mats are enumerated
39 // lazily in getSupportedFormats(), and cached for future reference. 41 // lazily in getSupportedFormats(), and cached for future reference.
40 private static final Map<String, List<CaptureFormat>> cachedSupportedFormats = 42 private static final Map<String, List<CaptureFormat>> cachedSupportedFormats =
41 new HashMap<String, List<CaptureFormat>>(); 43 new HashMap<String, List<CaptureFormat>>();
42 44
45 final Context context;
46 final CameraManager cameraManager;
47
48 public Camera2Enumerator(Context context) {
49 this.context = context;
50 this.cameraManager = (CameraManager) context.getSystemService(Context.CAMERA _SERVICE);
51 }
52
53 public String[] getDeviceNames() {
54 try {
55 return cameraManager.getCameraIdList();
56 } catch (CameraAccessException e) {
57 Logging.e(TAG, "Camera access exception: " + e);
58 return new String[] {};
59 }
60 }
61
62 public boolean isFrontFacing(String deviceName) {
63 CameraCharacteristics characteristics
64 = getCameraCharacteristics(deviceName);
65
66 return characteristics != null
67 && characteristics.get(CameraCharacteristics.LENS_FACING)
68 == CameraMetadata.LENS_FACING_FRONT;
69 }
70
71 public boolean isBackFacing(String deviceName) {
72 CameraCharacteristics characteristics
73 = getCameraCharacteristics(deviceName);
74
75 return characteristics != null
76 && characteristics.get(CameraCharacteristics.LENS_FACING)
77 == CameraMetadata.LENS_FACING_BACK;
78 }
79
80 public CameraVideoCapturer createCapturer(String deviceName,
81 CameraVideoCapturer.CameraEventsHandler eventsHandler) {
82 return new Camera2Capturer(context, deviceName, eventsHandler);
83 }
84
85 private CameraCharacteristics getCameraCharacteristics(String deviceName) {
86 try {
87 return cameraManager.getCameraCharacteristics(deviceName);
88 } catch (CameraAccessException e) {
89 Logging.e(TAG, "Camera access exception: " + e);
90 return null;
91 }
92 }
93
43 public static boolean isSupported() { 94 public static boolean isSupported() {
44 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; 95 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
45 } 96 }
46 97
47 public static List<CaptureFormat> getSupportedFormats(Context context, String cameraId) { 98 static List<CaptureFormat.FramerateRange> getSupportedFramerateRanges(
99 CameraCharacteristics cameraCharacteristics) {
100 final Range<Integer>[] fpsRanges =
101 cameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TAR GET_FPS_RANGES);
102
103 if (fpsRanges == null) {
104 return new ArrayList<CaptureFormat.FramerateRange>();
105 }
106
107 int maxFps = 0;
108 for (Range<Integer> fpsRange : fpsRanges) {
109 maxFps = Math.max(maxFps, fpsRange.getUpper());
110 }
111 int unitFactor = maxFps < 1000 ? 1000 : 1;
112 return convertFramerates(fpsRanges, unitFactor);
113 }
114
115 static List<Size> getSupportedSizes(
116 CameraCharacteristics cameraCharacteristics) {
117 final StreamConfigurationMap streamMap =
118 cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGUR ATION_MAP);
119 final android.util.Size[] sizes = streamMap.getOutputSizes(SurfaceTexture.cl ass);
120 if (sizes == null) {
121 Logging.e(TAG, "No supported camera output sizes.");
122 return new ArrayList<Size>();
123 }
124 return convertSizes(sizes);
125 }
126
127 static List<CaptureFormat> getSupportedFormats(Context context, String cameraI d) {
48 return getSupportedFormats( 128 return getSupportedFormats(
49 (CameraManager) context.getSystemService(Context.CAMERA_SERVICE), camera Id); 129 (CameraManager) context.getSystemService(Context.CAMERA_SERVICE), camera Id);
50 } 130 }
51 131
52 public static List<CaptureFormat> getSupportedFormats( 132 static List<CaptureFormat> getSupportedFormats(
53 CameraManager cameraManager, String cameraId) { 133 CameraManager cameraManager, String cameraId) {
54 synchronized (cachedSupportedFormats) { 134 synchronized (cachedSupportedFormats) {
55 if (cachedSupportedFormats.containsKey(cameraId)) { 135 if (cachedSupportedFormats.containsKey(cameraId)) {
56 return cachedSupportedFormats.get(cameraId); 136 return cachedSupportedFormats.get(cameraId);
57 } 137 }
138
58 Logging.d(TAG, "Get supported formats for camera index " + cameraId + ".") ; 139 Logging.d(TAG, "Get supported formats for camera index " + cameraId + ".") ;
59 final long startTimeMs = SystemClock.elapsedRealtime(); 140 final long startTimeMs = SystemClock.elapsedRealtime();
60 141
61 final CameraCharacteristics cameraCharacteristics; 142 final CameraCharacteristics cameraCharacteristics;
62 try { 143 try {
63 cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId) ; 144 cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId) ;
64 } catch (Exception ex) { 145 } catch (Exception ex) {
65 Logging.e(TAG, "getCameraCharacteristics(): " + ex); 146 Logging.e(TAG, "getCameraCharacteristics(): " + ex);
66 return new ArrayList<CaptureFormat>(); 147 return new ArrayList<CaptureFormat>();
67 } 148 }
68 149
69 // Calculate default max fps from auto-exposure ranges in case getOutputMi nFrameDuration() is
70 // not supported.
71 final Range<Integer>[] fpsRanges =
72 cameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_T ARGET_FPS_RANGES);
73 int defaultMaxFps = 0;
74 for (Range<Integer> fpsRange : fpsRanges) {
75 defaultMaxFps = Math.max(defaultMaxFps, fpsRange.getUpper());
76 }
77
78 final StreamConfigurationMap streamMap = 150 final StreamConfigurationMap streamMap =
79 cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGUR ATION_MAP); 151 cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGUR ATION_MAP);
80 final Size[] sizes = streamMap.getOutputSizes(ImageFormat.YUV_420_888); 152
81 if (sizes == null) { 153 List<CaptureFormat.FramerateRange> framerateRanges = getSupportedFramerate Ranges(
82 throw new RuntimeException("ImageFormat.YUV_420_888 not supported."); 154 cameraCharacteristics);
155 List<Size> sizes = getSupportedSizes(cameraCharacteristics);
156
157 int defaultMaxFps = 0;
158 for (CaptureFormat.FramerateRange framerateRange : framerateRanges) {
159 defaultMaxFps = Math.max(defaultMaxFps, framerateRange.max);
160 }
161 if (defaultMaxFps < 1000) {
magjed_webrtc 2016/06/27 10:33:24 This check should not be needed for CaptureFormat.
sakal 2016/06/27 12:08:28 You're right.
162 defaultMaxFps *= 1000;
83 } 163 }
84 164
85 final List<CaptureFormat> formatList = new ArrayList<CaptureFormat>(); 165 final List<CaptureFormat> formatList = new ArrayList<CaptureFormat>();
86 for (Size size : sizes) { 166 for (Size size : sizes) {
87 long minFrameDurationNs = 0; 167 long minFrameDurationNs = 0;
88 try { 168 try {
89 minFrameDurationNs = streamMap.getOutputMinFrameDuration(ImageFormat.Y UV_420_888, size); 169 minFrameDurationNs = streamMap.getOutputMinFrameDuration(SurfaceTextur e.class,
170 new android.util.Size(size.width, size.height));
90 } catch (Exception e) { 171 } catch (Exception e) {
91 // getOutputMinFrameDuration() is not supported on all devices. Ignore silently. 172 // getOutputMinFrameDuration() is not supported on all devices. Ignore silently.
92 } 173 }
93 final int maxFps = (minFrameDurationNs == 0) 174 final int maxFps = (minFrameDurationNs == 0)
94 ? defaultMaxFps 175 ? defaultMaxFps
95 : (int) Math.round(NANO_SECONDS_PER_SECOND / minF rameDurationNs); 176 : (int) Math.round(NANO_SECONDS_PER_SECOND / minFrameDurationNs) * 1 000;
96 formatList.add(new CaptureFormat(size.getWidth(), size.getHeight(), 0, m axFps * 1000)); 177 formatList.add(new CaptureFormat(size.width, size.height, 0, maxFps));
178 Logging.d(TAG, "Format: " + size.width + "x" + size.height + "@" + maxFp s);
97 } 179 }
180
98 cachedSupportedFormats.put(cameraId, formatList); 181 cachedSupportedFormats.put(cameraId, formatList);
99 final long endTimeMs = SystemClock.elapsedRealtime(); 182 final long endTimeMs = SystemClock.elapsedRealtime();
100 Logging.d(TAG, "Get supported formats for camera index " + cameraId + " do ne." 183 Logging.d(TAG, "Get supported formats for camera index " + cameraId + " do ne."
101 + " Time spent: " + (endTimeMs - startTimeMs) + " ms."); 184 + " Time spent: " + (endTimeMs - startTimeMs) + " ms.");
102 return formatList; 185 return formatList;
103 } 186 }
104 } 187 }
188
189 // Convert from android.util.Size to Size.
190 public static List<Size> convertSizes(android.util.Size[] cameraSizes) {
magjed_webrtc 2016/06/27 10:33:24 Can this be a private method instead?
sakal 2016/06/27 12:08:28 I changed this. I reduced visibility in Camera1Enu
191 final List<Size> sizes = new ArrayList<Size>();
192 for (android.util.Size size : cameraSizes) {
193 sizes.add(new Size(size.getWidth(), size.getHeight()));
194 }
195 return sizes;
196 }
197
198 // Convert from android.util.Range<Integer> to CaptureFormat.FramerateRange.
199 public static List<CaptureFormat.FramerateRange> convertFramerates(
magjed_webrtc 2016/06/27 10:33:24 ditto, private?
200 Range<Integer>[] arrayRanges, int unitFactor) {
201 final List<CaptureFormat.FramerateRange> ranges = new ArrayList<CaptureForma t.FramerateRange>();
202 for (Range<Integer> range : arrayRanges) {
203 ranges.add(new CaptureFormat.FramerateRange(
204 range.getLower() * unitFactor,
205 range.getUpper() * unitFactor));
206 }
207 return ranges;
208 }
105 } 209 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698