diff options
author | Zhijun He <zhijunhe@google.com> | 2015-05-28 12:51:52 -0700 |
---|---|---|
committer | Zhijun He <zhijunhe@google.com> | 2015-06-03 17:50:22 -0700 |
commit | b1300e39c7974937d563b3ec62f5246248a157b3 (patch) | |
tree | 57badde35684bd3320a6f9c2e3495571c230f00b /core/java/android/hardware | |
parent | fab663ebfdbb7c0c8e12e27dd82b0c9331f14184 (diff) | |
download | frameworks_base-b1300e39c7974937d563b3ec62f5246248a157b3.zip frameworks_base-b1300e39c7974937d563b3ec62f5246248a157b3.tar.gz frameworks_base-b1300e39c7974937d563b3ec62f5246248a157b3.tar.bz2 |
Camera2: add high speed video APIs
Interface only.
Bug: 21442271
Change-Id: If81caa0f2dc9f7802af564abcd9541aff3e30901
Diffstat (limited to 'core/java/android/hardware')
6 files changed, 196 insertions, 7 deletions
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java index c22ee5f..82d40d3 100644 --- a/core/java/android/hardware/camera2/CameraCaptureSession.java +++ b/core/java/android/hardware/camera2/CameraCaptureSession.java @@ -471,6 +471,17 @@ public abstract class CameraCaptureSession implements AutoCloseable { public abstract boolean isReprocessable(); /** + * Return if this capture session is constrained high speed session that is created by + * {@link CameraDevice#createConstrainedHighSpeedCaptureSession}. + * + * @return {@code true} if this session is constrained high speed capture session, + * {@code false} otherwise. + * + * @see CameraDevice#createConstrainedHighSpeedCaptureSession + */ + public abstract boolean isConstrainedHighSpeed(); + + /** * Get the input Surface associated with a reprocessable capture session. * * <p>Each reprocessable capture session has an input {@link Surface} where the reprocess diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java index d02f349..006030c 100644 --- a/core/java/android/hardware/camera2/CameraDevice.java +++ b/core/java/android/hardware/camera2/CameraDevice.java @@ -583,6 +583,147 @@ public abstract class CameraDevice implements AutoCloseable { throws CameraAccessException; /** + * <p>Create a new constrained high speed capture session.</p> + * + * <p>The application can use normal capture session (created via {@link #createCaptureSession}) + * for high speed capture if the desired high speed FPS ranges are advertised by + * {@link CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES}, in which case all API + * semantics associated with normal capture sessions applies.</p> + * + * <p>The method creates a specialized capture session that is only targeted at high speed + * video recording (>=120fps) use case if the camera device supports high speed video + * capability (i.e., {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES} contains + * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO}). + * Therefore, it has special characteristics compared with a normal capture session:</p> + * + * <ul> + * + * <li>In addition to the output target Surface requirements specified by the + * {@link #createCaptureSession} method, an active high speed capture session will support up + * to 2 output Surfaces, though the application might choose to configure just one Surface + * (e.g., preview only). All Surfaces must be either video encoder surfaces (acquired by + * {@link android.media.MediaRecorder#getSurface} or + * {@link android.media.MediaCodec#createInputSurface}) or preview surfaces (obtained from + * {@link android.view.SurfaceView}, {@link android.graphics.SurfaceTexture} via + * {@link android.view.Surface#Surface(android.graphics.SurfaceTexture)}). The Surface sizes + * must be one of the sizes reported by {@link StreamConfigurationMap#getHighSpeedVideoSizes}. + * When multiple Surfaces are configured, their size must be same.</li> + * + * <li>An active high speed capture session only accepts request lists created via + * {@link #createConstrainedHighSpeedRequestList}, and the request list can only be submitted + * to this session via {@link CameraCaptureSession#captureBurst captureBurst}, or + * {@link CameraCaptureSession#setRepeatingBurst setRepeatingBurst}.</li> + * + * <li>The FPS ranges being requested to this session must be selected from + * {@link StreamConfigurationMap#getHighSpeedVideoFpsRangesFor}. The application can still use + * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE} to control the desired FPS range. + * Switching to an FPS range that has different + * {@link android.util.Range#getUpper() maximum FPS} may trigger some camera device + * reconfigurations, which may introduce extra latency. It is recommended that the + * application avoids unnecessary maximum target FPS changes as much as possible during high + * speed streaming.</li> + * + * <li>For the request lists submitted to this session, the camera device will override the + * {@link CaptureRequest#CONTROL_MODE control mode}, auto-exposure (AE), auto-white balance + * (AWB) and auto-focus (AF) to {@link CameraMetadata#CONTROL_MODE_AUTO}, + * {@link CameraMetadata#CONTROL_AE_MODE_ON}, {@link CameraMetadata#CONTROL_AWB_MODE_AUTO} + * and {@link CameraMetadata#CONTROL_AF_MODE_CONTINUOUS_VIDEO}, respectively. All + * post-processing block mode controls will be overridden to be FAST. Therefore, no manual + * control of capture and post-processing parameters is possible. Beside these, only a subset + * of controls will work, see + * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO} for + * more details.</li> + * + * </ul> + * + * @param outputs The new set of Surfaces that should be made available as + * targets for captured high speed image data. + * @param callback The callback to notify about the status of the new capture session. + * @param handler The handler on which the callback should be invoked, or {@code null} to use + * the current thread's {@link android.os.Looper looper}. + * + * @throws IllegalArgumentException if the set of output Surfaces do not meet the requirements, + * the callback is null, or the handler is null but the current + * thread has no looper, or the camera device doesn't support + * high speed video capability. + * @throws CameraAccessException if the camera device is no longer connected or has + * encountered a fatal error + * @throws IllegalStateException if the camera device has been closed + * + * @see #createCaptureSession + * @see CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE + * @see StreamConfigurationMap#getHighSpeedVideoSizes + * @see StreamConfigurationMap#getHighSpeedVideoFpsRangesFor + * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES + * @see CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO + * @see CameraCaptureSession#captureBurst + * @see CameraCaptureSession#setRepeatingBurst + * @see #createConstrainedHighSpeedRequestList + */ + public abstract void createConstrainedHighSpeedCaptureSession(@NonNull List<Surface> outputs, + @NonNull CameraCaptureSession.StateCallback callback, + @Nullable Handler handler) + throws CameraAccessException; + + + /** + * <p>Create a unmodifiable list of requests that is suitable for constrained high speed capture + * session streaming.</p> + * + * <p>High speed video streaming creates significant performance pressue on the camera device, + * so to achieve efficient high speed streaming, the camera device may have to aggregate + * multiple frames together. This means requests must be sent in batched groups, with all + * requests sharing the same settings. This method takes the list of output target + * Surfaces (subject to the output Surface requirements specified by the contrained high speed + * session) and a {@link CaptureRequest request}, and generates a request list that has the same + * controls for each request. The input {@link CaptureRequest request} must contain the target + * output Surfaces and target high speed FPS range that is one of the + * {@link StreamConfigurationMap#getHighSpeedVideoFpsRangesFor} for the Surface size.</p> + * + * <p>If both preview and recording Surfaces are specified in the {@code request}, the + * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE target FPS range} in the input + * {@link CaptureRequest request} must be a fixed framerate FPS range, where the + * {@link android.util.Range#getLower minimal FPS} == + * {@link android.util.Range#getUpper() maximum FPS}. The created request list will contain + * a interleaved request pattern such that the preview output FPS is at least 30fps, the + * recording output FPS is {@link android.util.Range#getUpper() maximum FPS} of the requested + * FPS range. The application can submit this request list directly to an active high speed + * capture session to achieve high speed video recording. When only preview or recording + * Surface is specified, this method will return a list of request that have the same controls + * and output targets for all requests.</p> + * + * <p>Submitting a request list created by this method to a normal capture session will result + * in an {@link IllegalArgumentException} if the high speed + * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS range} is not supported by + * {@link CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES}.</p> + * + * @param request The high speed capture request that will be used to generate the high speed + * request list. + * @return A unmodifiable CaptureRequest list that is suitable for constrained high speed + * capture. + * + * @throws IllegalArgumentException if the set of output Surfaces in the request do not meet the + * high speed video capability requirements, or the camera + * device doesn't support high speed video capability, or the + * request doesn't meet the high speed video capability + * requirements, or the request doesn't contain the required + * controls for high speed capture. + * @throws CameraAccessException if the camera device is no longer connected or has + * encountered a fatal error + * @throws IllegalStateException if the camera device has been closed + * + * @see #createConstrainedHighSpeedCaptureSession + * @see CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE + * @see StreamConfigurationMap#getHighSpeedVideoSizes + * @see StreamConfigurationMap#getHighSpeedVideoFpsRangesFor + * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES + * @see CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO + */ + @NonNull + public abstract List<CaptureRequest> createConstrainedHighSpeedRequestList( + @NonNull CaptureRequest request)throws CameraAccessException; + + /** * <p>Create a {@link CaptureRequest.Builder} for new capture requests, * initialized with template for a target use case. The settings are chosen * to be the best options for the specific camera device, so it is not diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java index 7a39dd5..ab0f607 100644 --- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java @@ -721,4 +721,10 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession { } } + @Override + public boolean isConstrainedHighSpeed() { + // TODO: to be implemented + return false; + } + } diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java index e60e266..16701e5 100644 --- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java @@ -1906,4 +1906,18 @@ public class CameraDeviceImpl extends CameraDevice { private CameraCharacteristics getCharacteristics() { return mCharacteristics; } + + @Override + public void createConstrainedHighSpeedCaptureSession(List<Surface> outputs, + android.hardware.camera2.CameraCaptureSession.StateCallback callback, Handler handler) + throws CameraAccessException { + // TODO: to be implemented + throw new UnsupportedOperationException("To be implemented!!!!"); + } + + @Override + public List<CaptureRequest> createConstrainedHighSpeedRequestList(CaptureRequest request) + throws CameraAccessException { + throw new UnsupportedOperationException("To be implemented!!!!"); + } } diff --git a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableHighSpeedVideoConfiguration.java b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableHighSpeedVideoConfiguration.java index c03144b..2449abe 100644 --- a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableHighSpeedVideoConfiguration.java +++ b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableHighSpeedVideoConfiguration.java @@ -33,7 +33,7 @@ import java.nio.ByteBuffer; */ public class MarshalQueryableHighSpeedVideoConfiguration implements MarshalQueryable<HighSpeedVideoConfiguration> { - private static final int SIZE = SIZEOF_INT32 * 4; + private static final int SIZE = SIZEOF_INT32 * 5; private class MarshalerHighSpeedVideoConfiguration extends Marshaler<HighSpeedVideoConfiguration> { @@ -49,6 +49,7 @@ public class MarshalQueryableHighSpeedVideoConfiguration buffer.putInt(value.getHeight()); buffer.putInt(value.getFpsMin()); buffer.putInt(value.getFpsMax()); + buffer.putInt(value.getBatchSizeMax()); } @Override @@ -57,8 +58,9 @@ public class MarshalQueryableHighSpeedVideoConfiguration int height = buffer.getInt(); int fpsMin = buffer.getInt(); int fpsMax = buffer.getInt(); + int batchSizeMax = buffer.getInt(); - return new HighSpeedVideoConfiguration(width, height, fpsMin, fpsMax); + return new HighSpeedVideoConfiguration(width, height, fpsMin, fpsMax, batchSizeMax); } @Override diff --git a/core/java/android/hardware/camera2/params/HighSpeedVideoConfiguration.java b/core/java/android/hardware/camera2/params/HighSpeedVideoConfiguration.java index 088049f..b469126 100644 --- a/core/java/android/hardware/camera2/params/HighSpeedVideoConfiguration.java +++ b/core/java/android/hardware/camera2/params/HighSpeedVideoConfiguration.java @@ -33,6 +33,7 @@ import android.util.Size; * @hide */ public final class HighSpeedVideoConfiguration { + static final private int HIGH_SPEED_MAX_MINIMAL_FPS = 120; /** * Create a new {@link HighSpeedVideoConfiguration}. @@ -48,15 +49,18 @@ public final class HighSpeedVideoConfiguration { * @hide */ public HighSpeedVideoConfiguration( - final int width, final int height, final int fpsMin, final int fpsMax) { - if (fpsMax < 60) { - throw new IllegalArgumentException("fpsMax must be at least 60"); + final int width, final int height, final int fpsMin, final int fpsMax, + final int batchSizeMax) { + if (fpsMax < HIGH_SPEED_MAX_MINIMAL_FPS) { + throw new IllegalArgumentException("fpsMax must be at least " + + HIGH_SPEED_MAX_MINIMAL_FPS); } mFpsMax = fpsMax; mWidth = checkArgumentPositive(width, "width must be positive"); mHeight = checkArgumentPositive(height, "height must be positive"); mFpsMin = checkArgumentPositive(fpsMin, "fpsMin must be positive"); mSize = new Size(mWidth, mHeight); + mBatchSizeMax = checkArgumentPositive(batchSizeMax, "batchSizeMax must be positive"); mFpsRange = new Range<Integer>(mFpsMin, mFpsMax); } @@ -106,9 +110,18 @@ public final class HighSpeedVideoConfiguration { } /** + * Convenience method to return the max batch size of this high speed video configuration. + * + * @return the maximal batch size for this high speed video configuration + */ + public int getBatchSizeMax() { + return mBatchSizeMax; + } + + /** * Convenience method to return the FPS range of this high speed video configuration. * - * @return a Range with high bound >= 60 + * @return a Range with high bound >= {@value #HIGH_SPEED_MAX_MINIMAL_FPS} */ public Range<Integer> getFpsRange() { return mFpsRange; @@ -135,7 +148,8 @@ public final class HighSpeedVideoConfiguration { return mWidth == other.mWidth && mHeight == other.mHeight && mFpsMin == other.mFpsMin && - mFpsMax == other.mFpsMax; + mFpsMax == other.mFpsMax && + mBatchSizeMax == other.mBatchSizeMax; } return false; } @@ -152,6 +166,7 @@ public final class HighSpeedVideoConfiguration { private final int mHeight; private final int mFpsMin; private final int mFpsMax; + private final int mBatchSizeMax; private final Size mSize; private final Range<Integer> mFpsRange; } |