Merge "Camera2: add high speed video APIs" into mnc-dev

This commit is contained in:
Zhijun He
2015-06-04 01:58:30 +00:00
committed by Android (Google) Code Review
9 changed files with 216 additions and 17 deletions

View File

@@ -13192,6 +13192,7 @@ package android.hardware.camera2 {
method public abstract void close();
method public abstract android.hardware.camera2.CameraDevice getDevice();
method public abstract android.view.Surface getInputSurface();
method public abstract boolean isConstrainedHighSpeed();
method public abstract boolean isReprocessable();
method public abstract void prepare(android.view.Surface) throws android.hardware.camera2.CameraAccessException;
method public abstract int setRepeatingBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
@@ -13312,6 +13313,8 @@ package android.hardware.camera2 {
method public abstract void close();
method public abstract android.hardware.camera2.CaptureRequest.Builder createCaptureRequest(int) throws android.hardware.camera2.CameraAccessException;
method public abstract void createCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract void createConstrainedHighSpeedCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract java.util.List<android.hardware.camera2.CaptureRequest> createConstrainedHighSpeedRequestList(android.hardware.camera2.CaptureRequest) throws android.hardware.camera2.CameraAccessException;
method public abstract android.hardware.camera2.CaptureRequest.Builder createReprocessCaptureRequest(android.hardware.camera2.TotalCaptureResult) throws android.hardware.camera2.CameraAccessException;
method public abstract void createReprocessableCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract java.lang.String getId();

View File

@@ -13510,6 +13510,7 @@ package android.hardware.camera2 {
method public abstract void close();
method public abstract android.hardware.camera2.CameraDevice getDevice();
method public abstract android.view.Surface getInputSurface();
method public abstract boolean isConstrainedHighSpeed();
method public abstract boolean isReprocessable();
method public abstract void prepare(android.view.Surface) throws android.hardware.camera2.CameraAccessException;
method public abstract int setRepeatingBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
@@ -13630,6 +13631,8 @@ package android.hardware.camera2 {
method public abstract void close();
method public abstract android.hardware.camera2.CaptureRequest.Builder createCaptureRequest(int) throws android.hardware.camera2.CameraAccessException;
method public abstract void createCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract void createConstrainedHighSpeedCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract java.util.List<android.hardware.camera2.CaptureRequest> createConstrainedHighSpeedRequestList(android.hardware.camera2.CaptureRequest) throws android.hardware.camera2.CameraAccessException;
method public abstract android.hardware.camera2.CaptureRequest.Builder createReprocessCaptureRequest(android.hardware.camera2.TotalCaptureResult) throws android.hardware.camera2.CameraAccessException;
method public abstract void createReprocessableCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract java.lang.String getId();

View File

@@ -470,6 +470,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.
*

View File

@@ -582,6 +582,147 @@ public abstract class CameraDevice implements AutoCloseable {
@Nullable Handler handler)
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

View File

@@ -721,4 +721,10 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
}
}
@Override
public boolean isConstrainedHighSpeed() {
// TODO: to be implemented
return false;
}
}

View File

@@ -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!!!!");
}
}

View File

@@ -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

View File

@@ -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);
}
@@ -105,10 +109,19 @@ public final class HighSpeedVideoConfiguration {
return mSize;
}
/**
* 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;
}

View File

@@ -731,27 +731,31 @@ public class CameraMetadataTest extends junit.framework.TestCase {
@SmallTest
public void testReadWriteHighSpeedVideoConfiguration() {
// int32 x 4 x 1
// int32 x 5 x 1
checkKeyMarshal("android.control.availableHighSpeedVideoConfigurations",
new HighSpeedVideoConfiguration(
/*width*/1000, /*height*/255, /*fpsMin*/30, /*fpsMax*/200),
/*width*/1000, /*height*/255, /*fpsMin*/30, /*fpsMax*/200,
/*batchSizeMax*/8),
/* width, height, fpsMin, fpsMax */
toByteArray(1000, 255, 30, 200));
toByteArray(1000, 255, 30, 200, 8));
// int32 x 4 x 3
// int32 x 5 x 3
checkKeyMarshal("android.control.availableHighSpeedVideoConfigurations",
new HighSpeedVideoConfiguration[] {
new HighSpeedVideoConfiguration(
/*width*/1280, /*height*/720, /*fpsMin*/60, /*fpsMax*/120),
/*width*/1280, /*height*/720, /*fpsMin*/60, /*fpsMax*/120,
/*batchSizeMax*/8),
new HighSpeedVideoConfiguration(
/*width*/123, /*height*/456, /*fpsMin*/1, /*fpsMax*/200),
/*width*/123, /*height*/456, /*fpsMin*/1, /*fpsMax*/200,
/*batchSizeMax*/4),
new HighSpeedVideoConfiguration(
/*width*/4096, /*height*/2592, /*fpsMin*/30, /*fpsMax*/60)
/*width*/4096, /*height*/2592, /*fpsMin*/30, /*fpsMax*/60,
/*batchSizeMax*/2)
},
toByteArray(
1280, 720, 60, 120,
123, 456, 1, 200,
4096, 2592, 30, 60
1280, 720, 60, 120, 8,
123, 456, 1, 200, 4,
4096, 2592, 30, 60, 2
));
}