summaryrefslogtreecommitdiffstats
path: root/core/java/android/hardware
diff options
context:
space:
mode:
authorEino-Ville Talvala <etalvala@google.com>2015-01-23 00:05:25 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-01-23 00:05:26 +0000
commit7fde5e5ba3d306bc694e2b97edf5892755fcb6d0 (patch)
tree1207aaa3a80c61b86aa3dced091141f899e890f1 /core/java/android/hardware
parentdbabf37fd3a6b70be5cf9639f11656e12601154d (diff)
parentfa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186 (diff)
downloadframeworks_base-7fde5e5ba3d306bc694e2b97edf5892755fcb6d0.zip
frameworks_base-7fde5e5ba3d306bc694e2b97edf5892755fcb6d0.tar.gz
frameworks_base-7fde5e5ba3d306bc694e2b97edf5892755fcb6d0.tar.bz2
Merge "Camera2: StreamConfigurationMap#isOutputSupportedFor(Surface)" into lmp-mr1-dev
Diffstat (limited to 'core/java/android/hardware')
-rw-r--r--core/java/android/hardware/camera2/CameraDevice.java28
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java34
-rw-r--r--core/java/android/hardware/camera2/params/StreamConfigurationMap.java52
3 files changed, 86 insertions, 28 deletions
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 9e90d01..482b1f0 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -147,20 +147,20 @@ public abstract class CameraDevice implements AutoCloseable {
* <ul>
*
* <li>For drawing to a {@link android.view.SurfaceView SurfaceView}: Once the SurfaceView's
- * Surface is {@link android.view.SurfaceHolder.Callback#surfaceCreated created}, set the
- * size of the Surface with {@link android.view.SurfaceHolder#setFixedSize} to be one of the
- * sizes returned by
- * {@link StreamConfigurationMap#getOutputSizes(Class) getOutputSizes(SurfaceHolder.class)}
- * and then obtain the Surface by calling {@link android.view.SurfaceHolder#getSurface}.</li>
- *
- * <li>For accessing through an OpenGL texture via a
- * {@link android.graphics.SurfaceTexture SurfaceTexture}: Set the size of
- * the SurfaceTexture with
- * {@link android.graphics.SurfaceTexture#setDefaultBufferSize} to be one
- * of the sizes returned by
+ * Surface is {@link android.view.SurfaceHolder.Callback#surfaceCreated created}, set the size
+ * of the Surface with {@link android.view.SurfaceHolder#setFixedSize} to be one of the sizes
+ * returned by {@link StreamConfigurationMap#getOutputSizes(Class)
+ * getOutputSizes(SurfaceHolder.class)} and then obtain the Surface by calling {@link
+ * android.view.SurfaceHolder#getSurface}. If the size is not set by the application, it will
+ * be rounded to the nearest supported size less than 1080p, by the camera device.</li>
+ *
+ * <li>For accessing through an OpenGL texture via a {@link android.graphics.SurfaceTexture
+ * SurfaceTexture}: Set the size of the SurfaceTexture with {@link
+ * android.graphics.SurfaceTexture#setDefaultBufferSize} to be one of the sizes returned by
* {@link StreamConfigurationMap#getOutputSizes(Class) getOutputSizes(SurfaceTexture.class)}
- * before creating a Surface from the SurfaceTexture with
- * {@link Surface#Surface}.</li>
+ * before creating a Surface from the SurfaceTexture with {@link Surface#Surface}. If the size
+ * is not set by the application, it will be set to be the smallest supported size less than
+ * 1080p, by the camera device.</li>
*
* <li>For recording with {@link android.media.MediaCodec}: Call
* {@link android.media.MediaCodec#createInputSurface} after configuring
@@ -189,6 +189,8 @@ public abstract class CameraDevice implements AutoCloseable {
* corresponding supported sizes by passing the chosen output format into
* {@link StreamConfigurationMap#getOutputSizes(int)}. Then obtain a
* {@link android.view.Surface} from it with {@link android.media.ImageReader#getSurface()}.
+ * If the ImageReader size is not set to a supported size, it will be rounded to a supported
+ * size less than 1080p by the camera device.
* </li>
*
* </ul>
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
index 3043d13..367a078 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
@@ -85,7 +85,7 @@ public class LegacyCameraDevice implements AutoCloseable {
private static final int GRALLOC_USAGE_HW_COMPOSER = 0x00000800;
private static final int GRALLOC_USAGE_HW_VIDEO_ENCODER = 0x00010000;
- private static final int MAX_DIMEN_FOR_ROUNDING = 1080; // maximum allowed width for rounding
+ public static final int MAX_DIMEN_FOR_ROUNDING = 1080; // maximum allowed width for rounding
private CaptureResultExtras getExtrasFromRequest(RequestHolder holder) {
if (holder == null) {
@@ -299,15 +299,8 @@ public class LegacyCameraDevice implements AutoCloseable {
try {
Size s = getSurfaceSize(output);
int surfaceType = detectSurfaceType(output);
- int usageFlags = detectSurfaceUsageFlags(output);
- // Keep up to date with allowed consumer types in
- // frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
- int disallowedFlags = GRALLOC_USAGE_HW_VIDEO_ENCODER | GRALLOC_USAGE_RENDERSCRIPT;
- int allowedFlags = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_OFTEN |
- GRALLOC_USAGE_HW_COMPOSER;
- boolean flexibleConsumer = ((usageFlags & disallowedFlags) == 0 &&
- (usageFlags & allowedFlags) != 0);
+ boolean flexibleConsumer = isFlexibleConsumer(output);
Size[] sizes = streamConfigurations.getOutputSizes(surfaceType);
if (sizes == null) {
@@ -531,7 +524,7 @@ public class LegacyCameraDevice implements AutoCloseable {
* @throws NullPointerException if the {@code surface} was {@code null}
* @throws IllegalStateException if the {@code surface} was invalid
*/
- static Size getSurfaceSize(Surface surface) throws BufferQueueAbandonedException {
+ public static Size getSurfaceSize(Surface surface) throws BufferQueueAbandonedException {
checkNotNull(surface);
int[] dimens = new int[2];
@@ -540,12 +533,31 @@ public class LegacyCameraDevice implements AutoCloseable {
return new Size(dimens[0], dimens[1]);
}
+ public static boolean isFlexibleConsumer(Surface output) {
+ int usageFlags = detectSurfaceUsageFlags(output);
+
+ // Keep up to date with allowed consumer types in
+ // frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+ int disallowedFlags = GRALLOC_USAGE_HW_VIDEO_ENCODER | GRALLOC_USAGE_RENDERSCRIPT;
+ int allowedFlags = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_OFTEN |
+ GRALLOC_USAGE_HW_COMPOSER;
+ boolean flexibleConsumer = ((usageFlags & disallowedFlags) == 0 &&
+ (usageFlags & allowedFlags) != 0);
+ return flexibleConsumer;
+ }
+
+ /**
+ * Query the surface for its currently configured usage flags
+ */
static int detectSurfaceUsageFlags(Surface surface) {
checkNotNull(surface);
return nativeDetectSurfaceUsageFlags(surface);
}
- static int detectSurfaceType(Surface surface) throws BufferQueueAbandonedException {
+ /**
+ * Query the surface for its currently configured format
+ */
+ public static int detectSurfaceType(Surface surface) throws BufferQueueAbandonedException {
checkNotNull(surface);
return LegacyExceptionUtils.throwOnError(nativeDetectSurfaceType(surface));
}
diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
index 5d226e3..479c842 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -22,6 +22,9 @@ import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.utils.HashCodeHelpers;
+import android.hardware.camera2.legacy.LegacyCameraDevice;
+import android.hardware.camera2.legacy.LegacyMetadataMapper;
+import android.hardware.camera2.legacy.LegacyExceptionUtils.BufferQueueAbandonedException;
import android.view.Surface;
import android.util.Log;
import android.util.Range;
@@ -292,13 +295,21 @@ public final class StreamConfigurationMap {
* </li>
* </ul>
*
- * This is not an exhaustive list; see the particular class's documentation for further
+ * <p>Surfaces from flexible sources will return true even if the exact size of the Surface does
+ * not match a camera-supported size, as long as the format (or class) is supported and the
+ * camera device supports a size that is equal to or less than 1080p in that format. If such as
+ * Surface is used to create a capture session, it will have its size rounded to the nearest
+ * supported size, below or equal to 1080p. Flexible sources include SurfaceView, SurfaceTexture,
+ * and ImageReader.</p>
+ *
+ * <p>This is not an exhaustive list; see the particular class's documentation for further
* possible reasons of incompatibility.</p>
*
* @param surface a non-{@code null} {@link Surface} object reference
* @return {@code true} if this is supported, {@code false} otherwise
*
* @throws NullPointerException if {@code surface} was {@code null}
+ * @throws IllegalArgumentException if the Surface endpoint is no longer valid
*
* @see CameraDevice#createCaptureSession
* @see #isOutputSupportedFor(Class)
@@ -306,9 +317,37 @@ public final class StreamConfigurationMap {
public boolean isOutputSupportedFor(Surface surface) {
checkNotNull(surface, "surface must not be null");
- throw new UnsupportedOperationException("Not implemented yet");
+ Size surfaceSize;
+ int surfaceFormat = -1;
+ try {
+ surfaceSize = LegacyCameraDevice.getSurfaceSize(surface);
+ surfaceFormat = LegacyCameraDevice.detectSurfaceType(surface);
+ } catch(BufferQueueAbandonedException e) {
+ throw new IllegalArgumentException("Abandoned surface", e);
+ }
+
+ // See if consumer is flexible.
+ boolean isFlexible = LegacyCameraDevice.isFlexibleConsumer(surface);
- // TODO: JNI function that checks the Surface's IGraphicBufferProducer state
+ // Override RGB formats to IMPLEMENTATION_DEFINED, b/9487482
+ if ((surfaceFormat >= LegacyMetadataMapper.HAL_PIXEL_FORMAT_RGBA_8888 &&
+ surfaceFormat <= LegacyMetadataMapper.HAL_PIXEL_FORMAT_BGRA_8888)) {
+ surfaceFormat = LegacyMetadataMapper.HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
+ }
+
+ for (StreamConfiguration config : mConfigurations) {
+ if (config.getFormat() == surfaceFormat && config.isOutput()) {
+ // Mathing format, either need exact size match, or a flexible consumer
+ // and a size no bigger than MAX_DIMEN_FOR_ROUNDING
+ if (config.getSize().equals(surfaceSize)) {
+ return true;
+ } else if (isFlexible &&
+ (config.getSize().getWidth() <= LegacyCameraDevice.MAX_DIMEN_FOR_ROUNDING)) {
+ return true;
+ }
+ }
+ }
+ return false;
}
/**
@@ -1027,7 +1066,8 @@ public final class StreamConfigurationMap {
int i = 0;
for (int format : getFormatsMap(output).keySet()) {
- if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+ if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
+ format != HAL_PIXEL_FORMAT_RAW_OPAQUE) {
formats[i++] = format;
}
}
@@ -1089,6 +1129,10 @@ public final class StreamConfigurationMap {
if (formatsMap.containsKey(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)) {
size -= 1;
}
+ if (formatsMap.containsKey(HAL_PIXEL_FORMAT_RAW_OPAQUE)) {
+ size -= 1;
+ }
+
return size;
}