Merge "Camera2: add high speed video APIs" into mnc-dev
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -721,4 +721,10 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConstrainedHighSpeed() {
|
||||
// TODO: to be implemented
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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!!!!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user