Loading core/java/android/hardware/camera2/CameraDevice.java +15 −13 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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> Loading core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java +23 −11 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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) { Loading Loading @@ -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]; Loading @@ -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)); } Loading core/java/android/hardware/camera2/params/StreamConfigurationMap.java +48 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) Loading @@ -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; } /** Loading Loading @@ -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; } } Loading Loading @@ -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; } Loading Loading
core/java/android/hardware/camera2/CameraDevice.java +15 −13 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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> Loading
core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java +23 −11 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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) { Loading Loading @@ -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]; Loading @@ -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)); } Loading
core/java/android/hardware/camera2/params/StreamConfigurationMap.java +48 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) Loading @@ -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; } /** Loading Loading @@ -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; } } Loading Loading @@ -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; } Loading