diff options
author | Eino-Ville Talvala <etalvala@google.com> | 2015-01-23 00:05:25 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-01-23 00:05:26 +0000 |
commit | 7fde5e5ba3d306bc694e2b97edf5892755fcb6d0 (patch) | |
tree | 1207aaa3a80c61b86aa3dced091141f899e890f1 /core/java/android/hardware | |
parent | dbabf37fd3a6b70be5cf9639f11656e12601154d (diff) | |
parent | fa0b9a00b48394bd9b7e5d54b2b4a5a33d7bd186 (diff) | |
download | frameworks_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')
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; } |