Android: Add Size class.

The Camera1 and Camera2 API use different size types. Camera1 uses
android.hardware.Camera.Size while Camera2 uses android.util.Size.
android.util.Size is only available from Lollipop forward so this CL
adds a similar Size class in CaptureFormat.

The purpose of this CL is to have a common size type that can be reused
from both Camera1 and Camera2 helper functions such as
CameraEnumerationAndroid.getClosestSupportedSize().

BUG=webrtc:5519

Review-Url: https://codereview.webrtc.org/2066773002
Cr-Commit-Position: refs/heads/master@{#13181}
This commit is contained in:
sakal
2016-06-17 01:02:04 -07:00
committed by Commit bot
parent 50c4821110
commit e6c9e88c18
4 changed files with 83 additions and 27 deletions

View File

@ -12,8 +12,6 @@ package org.webrtc;
import static java.lang.Math.abs;
import org.webrtc.Logging;
import android.graphics.ImageFormat;
import java.util.Collections;
@ -60,6 +58,7 @@ public class CameraEnumerationAndroid {
public final int width;
public final int height;
public final FramerateRange framerate;
// TODO(hbos): If VideoCapturer.startCapture is updated to support other image formats then this
// needs to be updated and VideoCapturer.getSupportedFormats need to return CaptureFormats of
// all imageFormats.
@ -99,11 +98,19 @@ public class CameraEnumerationAndroid {
return width + "x" + height + "@" + framerate;
}
public boolean isSameFormat(final CaptureFormat that) {
if (that == null) {
@Override
public boolean equals(Object other) {
if (!(other instanceof CaptureFormat)) {
return false;
}
return width == that.width && height == that.height && framerate.equals(that.framerate);
final CaptureFormat otherFormat = (CaptureFormat) other;
return width == otherFormat.width && height == otherFormat.height
&& framerate.equals(otherFormat.framerate);
}
@Override
public int hashCode() {
return 1 + (width * 65497 + height) * 251 + framerate.hashCode();
}
}
@ -210,12 +217,13 @@ public class CameraEnumerationAndroid {
});
}
public static android.hardware.Camera.Size getClosestSupportedSize(
List<android.hardware.Camera.Size> supportedSizes, final int requestedWidth,
public static Size getClosestSupportedSize(
List<Size> supportedSizes, final int requestedWidth,
final int requestedHeight) {
return Collections.min(supportedSizes,
new ClosestComparator<android.hardware.Camera.Size>() {
@Override int diff(android.hardware.Camera.Size size) {
new ClosestComparator<Size>() {
@Override
int diff(Size size) {
return abs(requestedWidth - size.width) + abs(requestedHeight - size.height);
}
});

View File

@ -79,6 +79,16 @@ public class CameraEnumerator {
return formatList;
}
// Convert from android.hardware.Camera.Size to Size.
public static List<Size> convertSizes(
List<android.hardware.Camera.Size> cameraSizes) {
final List<Size> sizes = new ArrayList<Size>();
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<CaptureFormat.FramerateRange> convertFramerates(
List<int[]> arrayRanges) {

View File

@ -394,23 +394,17 @@ public class VideoCapturerAndroid implements
CameraEnumerator.convertFramerates(parameters.getSupportedPreviewFpsRange());
Logging.d(TAG, "Available fps ranges: " + supportedFramerates);
final CaptureFormat.FramerateRange bestFpsRange;
if (supportedFramerates.isEmpty()) {
Logging.w(TAG, "No supported preview fps range");
bestFpsRange = new CaptureFormat.FramerateRange(0, 0);
} else {
bestFpsRange = CameraEnumerationAndroid.getClosestSupportedFramerateRange(
supportedFramerates, framerate);
}
final CaptureFormat.FramerateRange fpsRange =
CameraEnumerationAndroid.getClosestSupportedFramerateRange(supportedFramerates, framerate);
final android.hardware.Camera.Size previewSize =
CameraEnumerationAndroid.getClosestSupportedSize(
parameters.getSupportedPreviewSizes(), width, height);
final CaptureFormat captureFormat = new CaptureFormat(
previewSize.width, previewSize.height, bestFpsRange);
final Size previewSize = CameraEnumerationAndroid.getClosestSupportedSize(
CameraEnumerator.convertSizes(parameters.getSupportedPreviewSizes()), width, height);
final CaptureFormat captureFormat =
new CaptureFormat(previewSize.width, previewSize.height, fpsRange);
// Check if we are already using this capture format, then we don't need to do anything.
if (captureFormat.isSameFormat(this.captureFormat)) {
if (captureFormat.equals(this.captureFormat)) {
return;
}
@ -425,16 +419,15 @@ public class VideoCapturerAndroid implements
if (captureFormat.framerate.max > 0) {
parameters.setPreviewFpsRange(captureFormat.framerate.min, captureFormat.framerate.max);
}
parameters.setPreviewSize(captureFormat.width, captureFormat.height);
parameters.setPreviewSize(previewSize.width, previewSize.height);
if (!isCapturingToTexture) {
parameters.setPreviewFormat(captureFormat.imageFormat);
}
// 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 android.hardware.Camera.Size pictureSize =
CameraEnumerationAndroid.getClosestSupportedSize(
parameters.getSupportedPictureSizes(), width, height);
final Size pictureSize = CameraEnumerationAndroid.getClosestSupportedSize(
CameraEnumerator.convertSizes(parameters.getSupportedPictureSizes()), width, height);
parameters.setPictureSize(pictureSize.width, pictureSize.height);
// Temporarily stop preview if it's already running.