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 | 10 |
(...skipping 25 matching lines...) Expand all Loading... | |
36 CameraEnumerationAndroid.enumerator = enumerator; | 36 CameraEnumerationAndroid.enumerator = enumerator; |
37 } | 37 } |
38 | 38 |
39 public static synchronized List<CaptureFormat> getSupportedFormats(int cameraI d) { | 39 public static synchronized List<CaptureFormat> getSupportedFormats(int cameraI d) { |
40 final List<CaptureFormat> formats = enumerator.getSupportedFormats(cameraId) ; | 40 final List<CaptureFormat> formats = enumerator.getSupportedFormats(cameraId) ; |
41 Logging.d(TAG, "Supported formats for camera " + cameraId + ": " + formats); | 41 Logging.d(TAG, "Supported formats for camera " + cameraId + ": " + formats); |
42 return formats; | 42 return formats; |
43 } | 43 } |
44 | 44 |
45 public static class CaptureFormat { | 45 public static class CaptureFormat { |
46 // Class to represent a framerate range. The framerate varies because of lig htning conditions. | |
47 // The values are multiplied by 1000, so 1000 represents one frame per secon d. | |
48 public static class FramerateRange { | |
49 public int min; | |
50 public int max; | |
51 | |
52 public FramerateRange(int min, int max) { | |
53 this.min = min; | |
54 this.max = max; | |
55 } | |
56 | |
57 @Override | |
58 public String toString() { | |
59 return "[" + (min / 1000.0f) + ":" + (max / 1000.0f) + "]"; | |
60 } | |
61 | |
62 @Override | |
63 public boolean equals(Object other) { | |
64 if (!(other instanceof FramerateRange)) { | |
65 return false; | |
66 } | |
67 final FramerateRange otherFramerate = (FramerateRange) other; | |
68 return min == otherFramerate.min && max == otherFramerate.max; | |
69 } | |
70 | |
71 @Override | |
72 public int hashCode() { | |
73 // Use prime close to 2^16 to avoid collisions for normal values less th an 2^16. | |
74 return 1 + 65537 * min + max; | |
75 } | |
76 } | |
77 | |
46 public final int width; | 78 public final int width; |
47 public final int height; | 79 public final int height; |
48 public final int maxFramerate; | 80 public final FramerateRange framerate; |
49 public final int minFramerate; | |
50 // TODO(hbos): If VideoCapturer.startCapture is updated to support other ima ge formats then this | 81 // TODO(hbos): If VideoCapturer.startCapture is updated to support other ima ge formats then this |
51 // needs to be updated and VideoCapturer.getSupportedFormats need to return CaptureFormats of | 82 // needs to be updated and VideoCapturer.getSupportedFormats need to return CaptureFormats of |
52 // all imageFormats. | 83 // all imageFormats. |
53 public final int imageFormat = ImageFormat.NV21; | 84 public final int imageFormat = ImageFormat.NV21; |
54 | 85 |
55 public CaptureFormat(int width, int height, int minFramerate, | 86 public CaptureFormat(int width, int height, int minFramerate, int maxFramera te) { |
56 int maxFramerate) { | |
57 this.width = width; | 87 this.width = width; |
58 this.height = height; | 88 this.height = height; |
59 this.minFramerate = minFramerate; | 89 this.framerate = new FramerateRange(minFramerate, maxFramerate); |
60 this.maxFramerate = maxFramerate; | 90 } |
91 | |
92 public CaptureFormat(int width, int height, FramerateRange framerate) { | |
93 this.width = width; | |
94 this.height = height; | |
95 this.framerate = framerate; | |
61 } | 96 } |
62 | 97 |
63 // Calculates the frame size of this capture format. | 98 // Calculates the frame size of this capture format. |
64 public int frameSize() { | 99 public int frameSize() { |
65 return frameSize(width, height, imageFormat); | 100 return frameSize(width, height, imageFormat); |
66 } | 101 } |
67 | 102 |
68 // Calculates the frame size of the specified image format. Currently only | 103 // Calculates the frame size of the specified image format. Currently only |
69 // supporting ImageFormat.NV21. | 104 // supporting ImageFormat.NV21. |
70 // The size is width * height * number of bytes per pixel. | 105 // The size is width * height * number of bytes per pixel. |
71 // http://developer.android.com/reference/android/hardware/Camera.html#addCa llbackBuffer(byte[]) | 106 // http://developer.android.com/reference/android/hardware/Camera.html#addCa llbackBuffer(byte[]) |
72 public static int frameSize(int width, int height, int imageFormat) { | 107 public static int frameSize(int width, int height, int imageFormat) { |
73 if (imageFormat != ImageFormat.NV21) { | 108 if (imageFormat != ImageFormat.NV21) { |
74 throw new UnsupportedOperationException("Don't know how to calculate " | 109 throw new UnsupportedOperationException("Don't know how to calculate " |
75 + "the frame size of non-NV21 image formats."); | 110 + "the frame size of non-NV21 image formats."); |
76 } | 111 } |
77 return (width * height * ImageFormat.getBitsPerPixel(imageFormat)) / 8; | 112 return (width * height * ImageFormat.getBitsPerPixel(imageFormat)) / 8; |
78 } | 113 } |
79 | 114 |
80 @Override | 115 @Override |
81 public String toString() { | 116 public String toString() { |
82 return width + "x" + height + "@[" + minFramerate + ":" + maxFramerate + " ]"; | 117 return width + "x" + height + "@" + framerate; |
83 } | 118 } |
84 | 119 |
85 public boolean isSameFormat(final CaptureFormat that) { | 120 public boolean isSameFormat(final CaptureFormat that) { |
86 if (that == null) { | 121 if (that == null) { |
87 return false; | 122 return false; |
88 } | 123 } |
89 return width == that.width && height == that.height && maxFramerate == tha t.maxFramerate | 124 return width == that.width && height == that.height && framerate.equals(th at.framerate); |
90 && minFramerate == that.minFramerate; | |
91 } | 125 } |
92 } | 126 } |
93 | 127 |
94 // Returns device names that can be used to create a new VideoCapturerAndroid. | 128 // Returns device names that can be used to create a new VideoCapturerAndroid. |
95 public static String[] getDeviceNames() { | 129 public static String[] getDeviceNames() { |
96 String[] names = new String[android.hardware.Camera.getNumberOfCameras()]; | 130 String[] names = new String[android.hardware.Camera.getNumberOfCameras()]; |
97 for (int i = 0; i < android.hardware.Camera.getNumberOfCameras(); ++i) { | 131 for (int i = 0; i < android.hardware.Camera.getNumberOfCameras(); ++i) { |
98 names[i] = getDeviceName(i); | 132 names[i] = getDeviceName(i); |
99 } | 133 } |
100 return names; | 134 return names; |
(...skipping 26 matching lines...) Expand all Loading... | |
127 public static String getNameOfFrontFacingDevice() { | 161 public static String getNameOfFrontFacingDevice() { |
128 return getNameOfDevice(android.hardware.Camera.CameraInfo.CAMERA_FACING_FRON T); | 162 return getNameOfDevice(android.hardware.Camera.CameraInfo.CAMERA_FACING_FRON T); |
129 } | 163 } |
130 | 164 |
131 // Returns the name of the back facing camera. Returns null if the | 165 // Returns the name of the back facing camera. Returns null if the |
132 // camera can not be used or does not exist. | 166 // camera can not be used or does not exist. |
133 public static String getNameOfBackFacingDevice() { | 167 public static String getNameOfBackFacingDevice() { |
134 return getNameOfDevice(android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK ); | 168 return getNameOfDevice(android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK ); |
135 } | 169 } |
136 | 170 |
137 // Helper class for finding the closest supported format for the two functions below. | 171 // Helper class for finding the closest supported format for the two functions below. It creates a |
172 // comparator based on the difference to some requested parameters, where the element with the | |
173 // minimum difference is the element that is closest to the requested paramete rs. | |
138 private static abstract class ClosestComparator<T> implements Comparator<T> { | 174 private static abstract class ClosestComparator<T> implements Comparator<T> { |
139 // Difference between supported and requested parameter. | 175 // Difference between supported and requested parameter. |
140 abstract int diff(T supportedParameter); | 176 abstract int diff(T supportedParameter); |
141 | 177 |
142 @Override | 178 @Override |
143 public int compare(T t1, T t2) { | 179 public int compare(T t1, T t2) { |
144 return diff(t1) - diff(t2); | 180 return diff(t1) - diff(t2); |
145 } | 181 } |
146 } | 182 } |
147 | 183 |
148 public static int[] getFramerateRange(android.hardware.Camera.Parameters param eters, | 184 public static CaptureFormat.FramerateRange getClosestSupportedFramerateRange( |
sakal
2016/05/26 12:36:51
I would move this to the FramerateRange class.
magjed_webrtc
2016/05/26 13:13:31
I prefer to keep CaptureFormat.FramerateRange as a
| |
149 final int framerate) { | 185 List<CaptureFormat.FramerateRange> supportedFramerates, final int requeste dFps) { |
150 List<int[]> listFpsRange = parameters.getSupportedPreviewFpsRange(); | 186 return Collections.min(supportedFramerates, |
151 if (listFpsRange.isEmpty()) { | 187 new ClosestComparator<CaptureFormat.FramerateRange>() { |
152 Logging.w(TAG, "No supported preview fps range"); | 188 @Override |
153 return new int[]{0, 0}; | 189 int diff(CaptureFormat.FramerateRange range) { |
154 } | |
155 return Collections.min(listFpsRange, | |
156 new ClosestComparator<int[]>() { | |
157 @Override int diff(int[] range) { | |
158 final int maxFpsWeight = 10; | 190 final int maxFpsWeight = 10; |
sakal
2016/05/26 12:36:51
As a constant, I feel this should be a static fina
magjed_webrtc
2016/05/26 13:13:31
Done.
| |
159 return range[android.hardware.Camera.Parameters.PREVIEW_FPS_MIN_INDE X] | 191 return range.min + maxFpsWeight * abs(requestedFps * 1000 - range.ma x); |
160 + maxFpsWeight * abs(framerate | |
161 - range[android.hardware.Camera.Parameters.PREVIEW_FPS_MAX_I NDEX]); | |
162 } | 192 } |
163 }); | 193 }); |
164 } | 194 } |
165 | 195 |
166 public static android.hardware.Camera.Size getClosestSupportedSize( | 196 public static android.hardware.Camera.Size getClosestSupportedSize( |
167 List<android.hardware.Camera.Size> supportedSizes, final int requestedWidt h, | 197 List<android.hardware.Camera.Size> supportedSizes, final int requestedWidt h, |
168 final int requestedHeight) { | 198 final int requestedHeight) { |
169 return Collections.min(supportedSizes, | 199 return Collections.min(supportedSizes, |
170 new ClosestComparator<android.hardware.Camera.Size>() { | 200 new ClosestComparator<android.hardware.Camera.Size>() { |
171 @Override int diff(android.hardware.Camera.Size size) { | 201 @Override int diff(android.hardware.Camera.Size size) { |
(...skipping 10 matching lines...) Expand all Loading... | |
182 if (info.facing == facing) { | 212 if (info.facing == facing) { |
183 return getDeviceName(i); | 213 return getDeviceName(i); |
184 } | 214 } |
185 } catch (Exception e) { | 215 } catch (Exception e) { |
186 Logging.e(TAG, "getCameraInfo() failed on index " + i, e); | 216 Logging.e(TAG, "getCameraInfo() failed on index " + i, e); |
187 } | 217 } |
188 } | 218 } |
189 return null; | 219 return null; |
190 } | 220 } |
191 } | 221 } |
OLD | NEW |