Merge "Camera2: StreamConfigurationMap#isOutputSupportedFor(Surface)" into lmp-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
7fde5e5ba3
@@ -147,20 +147,20 @@ public abstract class CameraDevice implements AutoCloseable {
|
|||||||
* <ul>
|
* <ul>
|
||||||
*
|
*
|
||||||
* <li>For drawing to a {@link android.view.SurfaceView SurfaceView}: Once the SurfaceView's
|
* <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
|
* Surface is {@link android.view.SurfaceHolder.Callback#surfaceCreated created}, set the size
|
||||||
* size of the Surface with {@link android.view.SurfaceHolder#setFixedSize} to be one of the
|
* of the Surface with {@link android.view.SurfaceHolder#setFixedSize} to be one of the sizes
|
||||||
* sizes returned by
|
* returned by {@link StreamConfigurationMap#getOutputSizes(Class)
|
||||||
* {@link StreamConfigurationMap#getOutputSizes(Class) getOutputSizes(SurfaceHolder.class)}
|
* getOutputSizes(SurfaceHolder.class)} and then obtain the Surface by calling {@link
|
||||||
* and then obtain the Surface by calling {@link android.view.SurfaceHolder#getSurface}.</li>
|
* 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
|
* <li>For accessing through an OpenGL texture via a {@link android.graphics.SurfaceTexture
|
||||||
* {@link android.graphics.SurfaceTexture SurfaceTexture}: Set the size of
|
* SurfaceTexture}: Set the size of the SurfaceTexture with {@link
|
||||||
* the SurfaceTexture with
|
* android.graphics.SurfaceTexture#setDefaultBufferSize} to be one of the sizes returned by
|
||||||
* {@link android.graphics.SurfaceTexture#setDefaultBufferSize} to be one
|
|
||||||
* of the sizes returned by
|
|
||||||
* {@link StreamConfigurationMap#getOutputSizes(Class) getOutputSizes(SurfaceTexture.class)}
|
* {@link StreamConfigurationMap#getOutputSizes(Class) getOutputSizes(SurfaceTexture.class)}
|
||||||
* before creating a Surface from the SurfaceTexture with
|
* before creating a Surface from the SurfaceTexture with {@link Surface#Surface}. If the size
|
||||||
* {@link Surface#Surface}.</li>
|
* 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
|
* <li>For recording with {@link android.media.MediaCodec}: Call
|
||||||
* {@link android.media.MediaCodec#createInputSurface} after configuring
|
* {@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
|
* corresponding supported sizes by passing the chosen output format into
|
||||||
* {@link StreamConfigurationMap#getOutputSizes(int)}. Then obtain a
|
* {@link StreamConfigurationMap#getOutputSizes(int)}. Then obtain a
|
||||||
* {@link android.view.Surface} from it with {@link android.media.ImageReader#getSurface()}.
|
* {@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>
|
* </li>
|
||||||
*
|
*
|
||||||
* </ul>
|
* </ul>
|
||||||
|
|||||||
@@ -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_COMPOSER = 0x00000800;
|
||||||
private static final int GRALLOC_USAGE_HW_VIDEO_ENCODER = 0x00010000;
|
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) {
|
private CaptureResultExtras getExtrasFromRequest(RequestHolder holder) {
|
||||||
if (holder == null) {
|
if (holder == null) {
|
||||||
@@ -299,15 +299,8 @@ public class LegacyCameraDevice implements AutoCloseable {
|
|||||||
try {
|
try {
|
||||||
Size s = getSurfaceSize(output);
|
Size s = getSurfaceSize(output);
|
||||||
int surfaceType = detectSurfaceType(output);
|
int surfaceType = detectSurfaceType(output);
|
||||||
int usageFlags = detectSurfaceUsageFlags(output);
|
|
||||||
|
|
||||||
// Keep up to date with allowed consumer types in
|
boolean flexibleConsumer = isFlexibleConsumer(output);
|
||||||
// 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);
|
|
||||||
|
|
||||||
Size[] sizes = streamConfigurations.getOutputSizes(surfaceType);
|
Size[] sizes = streamConfigurations.getOutputSizes(surfaceType);
|
||||||
if (sizes == null) {
|
if (sizes == null) {
|
||||||
@@ -531,7 +524,7 @@ public class LegacyCameraDevice implements AutoCloseable {
|
|||||||
* @throws NullPointerException if the {@code surface} was {@code null}
|
* @throws NullPointerException if the {@code surface} was {@code null}
|
||||||
* @throws IllegalStateException if the {@code surface} was invalid
|
* @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);
|
checkNotNull(surface);
|
||||||
|
|
||||||
int[] dimens = new int[2];
|
int[] dimens = new int[2];
|
||||||
@@ -540,12 +533,31 @@ public class LegacyCameraDevice implements AutoCloseable {
|
|||||||
return new Size(dimens[0], dimens[1]);
|
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) {
|
static int detectSurfaceUsageFlags(Surface surface) {
|
||||||
checkNotNull(surface);
|
checkNotNull(surface);
|
||||||
return nativeDetectSurfaceUsageFlags(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);
|
checkNotNull(surface);
|
||||||
return LegacyExceptionUtils.throwOnError(nativeDetectSurfaceType(surface));
|
return LegacyExceptionUtils.throwOnError(nativeDetectSurfaceType(surface));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ import android.hardware.camera2.CameraCharacteristics;
|
|||||||
import android.hardware.camera2.CameraDevice;
|
import android.hardware.camera2.CameraDevice;
|
||||||
import android.hardware.camera2.CaptureRequest;
|
import android.hardware.camera2.CaptureRequest;
|
||||||
import android.hardware.camera2.utils.HashCodeHelpers;
|
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.view.Surface;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Range;
|
import android.util.Range;
|
||||||
@@ -292,13 +295,21 @@ public final class StreamConfigurationMap {
|
|||||||
* </li>
|
* </li>
|
||||||
* </ul>
|
* </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>
|
* possible reasons of incompatibility.</p>
|
||||||
*
|
*
|
||||||
* @param surface a non-{@code null} {@link Surface} object reference
|
* @param surface a non-{@code null} {@link Surface} object reference
|
||||||
* @return {@code true} if this is supported, {@code false} otherwise
|
* @return {@code true} if this is supported, {@code false} otherwise
|
||||||
*
|
*
|
||||||
* @throws NullPointerException if {@code surface} was {@code null}
|
* @throws NullPointerException if {@code surface} was {@code null}
|
||||||
|
* @throws IllegalArgumentException if the Surface endpoint is no longer valid
|
||||||
*
|
*
|
||||||
* @see CameraDevice#createCaptureSession
|
* @see CameraDevice#createCaptureSession
|
||||||
* @see #isOutputSupportedFor(Class)
|
* @see #isOutputSupportedFor(Class)
|
||||||
@@ -306,9 +317,37 @@ public final class StreamConfigurationMap {
|
|||||||
public boolean isOutputSupportedFor(Surface surface) {
|
public boolean isOutputSupportedFor(Surface surface) {
|
||||||
checkNotNull(surface, "surface must not be null");
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: JNI function that checks the Surface's IGraphicBufferProducer state
|
// See if consumer is flexible.
|
||||||
|
boolean isFlexible = LegacyCameraDevice.isFlexibleConsumer(surface);
|
||||||
|
|
||||||
|
// 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;
|
int i = 0;
|
||||||
|
|
||||||
for (int format : getFormatsMap(output).keySet()) {
|
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;
|
formats[i++] = format;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1089,6 +1129,10 @@ public final class StreamConfigurationMap {
|
|||||||
if (formatsMap.containsKey(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)) {
|
if (formatsMap.containsKey(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)) {
|
||||||
size -= 1;
|
size -= 1;
|
||||||
}
|
}
|
||||||
|
if (formatsMap.containsKey(HAL_PIXEL_FORMAT_RAW_OPAQUE)) {
|
||||||
|
size -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user