528 lines
21 KiB
Java
528 lines
21 KiB
Java
/*
|
|
* Copyright (C) 2018 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package android.hardware.camera2.params;
|
|
|
|
import android.annotation.IntDef;
|
|
import android.annotation.IntRange;
|
|
import android.annotation.NonNull;
|
|
import android.annotation.Nullable;
|
|
import android.graphics.ImageFormat;
|
|
import android.graphics.ImageFormat.Format;
|
|
import android.graphics.PixelFormat;
|
|
import android.hardware.camera2.CameraCharacteristics;
|
|
import android.hardware.camera2.CameraDevice;
|
|
import android.hardware.camera2.CameraMetadata;
|
|
import android.hardware.camera2.CaptureRequest;
|
|
import android.util.ArraySet;
|
|
import android.util.Range;
|
|
import android.util.Size;
|
|
import android.view.Surface;
|
|
|
|
import java.lang.annotation.Retention;
|
|
import java.lang.annotation.RetentionPolicy;
|
|
|
|
import java.util.Arrays;
|
|
import java.util.Collections;
|
|
import java.util.Set;
|
|
|
|
/**
|
|
* Immutable class to store the recommended stream configurations to set up
|
|
* {@link android.view.Surface Surfaces} for creating a
|
|
* {@link android.hardware.camera2.CameraCaptureSession capture session} with
|
|
* {@link android.hardware.camera2.CameraDevice#createCaptureSession(SessionConfiguration)}.
|
|
*
|
|
* <p>The recommended list does not replace or deprecate the exhaustive complete list found in
|
|
* {@link StreamConfigurationMap}. It is a suggestion about available power and performance
|
|
* efficient stream configurations for a specific use case. Per definition it is only a subset
|
|
* of {@link StreamConfigurationMap} and can be considered by developers for optimization
|
|
* purposes.</p>
|
|
*
|
|
* <p>This also duplicates the minimum frame durations and stall durations from the
|
|
* {@link StreamConfigurationMap} for each format/size combination that can be used to calculate
|
|
* effective frame rate when submitting multiple captures.
|
|
* </p>
|
|
*
|
|
* <p>An instance of this object is available by invoking
|
|
* {@link CameraCharacteristics#getRecommendedStreamConfigurationMap} and passing a respective
|
|
* usecase id. For more information about supported use case constants see
|
|
* {@link #USECASE_PREVIEW}.</p>
|
|
*
|
|
* <pre><code>{@code
|
|
* CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
|
|
* RecommendedStreamConfigurationMap configs = characteristics.getRecommendedStreamConfigurationMap(
|
|
* RecommendedStreamConfigurationMap.USECASE_PREVIEW);
|
|
* }</code></pre>
|
|
*
|
|
* @see CameraCharacteristics#getRecommendedStreamConfigurationMap
|
|
* @see CameraDevice#createCaptureSession(SessionConfiguration)
|
|
*/
|
|
public final class RecommendedStreamConfigurationMap {
|
|
|
|
private static final String TAG = "RecommendedStreamConfigurationMap";
|
|
private int mUsecase;
|
|
private boolean mSupportsPrivate;
|
|
private StreamConfigurationMap mRecommendedMap;
|
|
|
|
/** @hide */
|
|
public static final int MAX_USECASE_COUNT = 32;
|
|
|
|
/**
|
|
* The recommended stream configuration map for use case preview must contain a subset of
|
|
* efficient, non-stalling configurations that must include both
|
|
* {@link android.graphics.ImageFormat#PRIVATE} and
|
|
* {@link android.graphics.ImageFormat#YUV_420_888} output formats. Even if available for the
|
|
* camera device, high speed or input configurations will be absent.
|
|
*/
|
|
public static final int USECASE_PREVIEW = 0x0;
|
|
|
|
/**
|
|
* The recommended stream configuration map for recording must contain a subset of efficient
|
|
* video configurations that include {@link android.graphics.ImageFormat#PRIVATE}
|
|
* output format for at least all supported {@link android.media.CamcorderProfile profiles}.
|
|
* High speed configurations if supported will be available as well. Even if available for the
|
|
* camera device, input configurations will be absent.
|
|
*/
|
|
public static final int USECASE_RECORD = 0x1;
|
|
|
|
/**
|
|
* The recommended stream configuration map for use case video snapshot must only contain a
|
|
* subset of efficient liveshot configurations that include
|
|
* {@link android.graphics.ImageFormat#JPEG} output format. The sizes will match at least
|
|
* the maximum resolution of usecase record and will not cause any preview glitches. Even
|
|
* if available for the camera device, high speed or input configurations will be absent.
|
|
*/
|
|
public static final int USECASE_VIDEO_SNAPSHOT = 0x2;
|
|
|
|
/**
|
|
* The recommended stream configuration map for use case snapshot must contain a subset of
|
|
* efficient still capture configurations that must include
|
|
* {@link android.graphics.ImageFormat#JPEG} output format and at least one configuration with
|
|
* size approximately equal to the sensor pixel array size
|
|
* {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE}.
|
|
* Even if available for the camera device, high speed or input configurations will be absent.
|
|
*/
|
|
public static final int USECASE_SNAPSHOT = 0x3;
|
|
|
|
/**
|
|
* In case the device supports
|
|
* {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING} and/or
|
|
* {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING},
|
|
* the recommended stream configuration map for use case ZSL must contain a subset of efficient
|
|
* configurations that include the suggested input and output format mappings. Even if
|
|
* available for the camera device, high speed configurations will be absent.
|
|
*/
|
|
public static final int USECASE_ZSL = 0x4;
|
|
|
|
/**
|
|
* In case the device supports
|
|
* {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_RAW}, the
|
|
* recommended stream configuration map for use case RAW must contain a subset of efficient
|
|
* configurations that include the {@link android.graphics.ImageFormat#RAW_SENSOR} and other
|
|
* RAW output formats. Even if available for the camera device, high speed and input
|
|
* configurations will be absent.
|
|
*/
|
|
public static final int USECASE_RAW = 0x5;
|
|
|
|
/**
|
|
* The recommended stream configuration map for use case low latency snapshot must contain
|
|
* subset of configurations with end-to-end latency that does not exceed 200 ms. under standard
|
|
* operating conditions (reasonable light levels, not loaded system). The expected output format
|
|
* will be primarily {@link android.graphics.ImageFormat#JPEG} however other image formats can
|
|
* be present as well. Even if available for the camera device, high speed and input
|
|
* configurations will be absent. This suggested configuration map may be absent on some devices
|
|
* that can not support any low latency requests.
|
|
*/
|
|
public static final int USECASE_LOW_LATENCY_SNAPSHOT = 0x6;
|
|
|
|
/**
|
|
* If supported, the recommended 10-bit output stream configurations must include
|
|
* a subset of the advertised {@link android.graphics.ImageFormat#YCBCR_P010} and
|
|
* {@link android.graphics.ImageFormat#PRIVATE} outputs that are optimized for power
|
|
* and performance when registered along with a supported 10-bit dynamic range profile.
|
|
* {@see android.hardware.camera2.params.OutputConfiguration#setDynamicRangeProfile} for
|
|
* details.
|
|
*/
|
|
public static final int USECASE_10BIT_OUTPUT = 0x8;
|
|
|
|
/**
|
|
* Device specific use cases.
|
|
* @hide
|
|
*/
|
|
public static final int USECASE_VENDOR_START = 0x18;
|
|
|
|
/** @hide */
|
|
@Retention(RetentionPolicy.SOURCE)
|
|
@IntDef(prefix = {"USECASE_"}, value =
|
|
{USECASE_PREVIEW,
|
|
USECASE_RECORD,
|
|
USECASE_VIDEO_SNAPSHOT,
|
|
USECASE_SNAPSHOT,
|
|
USECASE_ZSL,
|
|
USECASE_RAW,
|
|
USECASE_LOW_LATENCY_SNAPSHOT,
|
|
USECASE_10BIT_OUTPUT})
|
|
public @interface RecommendedUsecase {};
|
|
|
|
/**
|
|
* Create a new {@link RecommendedStreamConfigurationMap}.
|
|
*
|
|
* @param recommendedMap stream configuration map that contains for the specific use case
|
|
* @param usecase Recommended use case
|
|
* @param supportsPrivate Flag indicating private format support.
|
|
*
|
|
* @hide
|
|
*/
|
|
public RecommendedStreamConfigurationMap(StreamConfigurationMap recommendedMap, int usecase,
|
|
boolean supportsPrivate) {
|
|
mRecommendedMap = recommendedMap;
|
|
mUsecase = usecase;
|
|
mSupportsPrivate = supportsPrivate;
|
|
}
|
|
|
|
/**
|
|
* Get the use case value for the recommended stream configurations.
|
|
*
|
|
* @return Use case id.
|
|
*/
|
|
public @RecommendedUsecase int getRecommendedUseCase() {
|
|
return mUsecase;
|
|
}
|
|
|
|
private Set<Integer> getUnmodifiableIntegerSet(int[] intArray) {
|
|
if ((intArray != null) && (intArray.length > 0)) {
|
|
ArraySet<Integer> integerSet = new ArraySet<Integer>();
|
|
integerSet.ensureCapacity(intArray.length);
|
|
for (int intEntry : intArray) {
|
|
integerSet.add(intEntry);
|
|
}
|
|
|
|
return Collections.unmodifiableSet(integerSet);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Get the image {@code format} output formats in this stream configuration.
|
|
*
|
|
* <p>
|
|
* For more information refer to {@link StreamConfigurationMap#getOutputFormats}.
|
|
* </p>
|
|
*
|
|
* @return a non-modifiable set of Integer formats
|
|
*/
|
|
public @NonNull Set<Integer> getOutputFormats() {
|
|
return getUnmodifiableIntegerSet(mRecommendedMap.getOutputFormats());
|
|
}
|
|
|
|
/**
|
|
* Get the image {@code format} output formats for a reprocessing input format.
|
|
*
|
|
* <p>
|
|
* For more information refer to {@link StreamConfigurationMap#getValidOutputFormatsForInput}.
|
|
* </p>
|
|
*
|
|
* @return a non-modifiable set of Integer formats
|
|
*/
|
|
public @Nullable Set<Integer> getValidOutputFormatsForInput(@Format int inputFormat) {
|
|
return getUnmodifiableIntegerSet(mRecommendedMap.getValidOutputFormatsForInput(
|
|
inputFormat));
|
|
}
|
|
|
|
/**
|
|
* Get the image {@code format} input formats in this stream configuration.
|
|
*
|
|
* <p>All image formats returned by this function will be defined in either {@link ImageFormat}
|
|
* or in {@link PixelFormat} (and there is no possibility of collision).</p>
|
|
*
|
|
* @return a non-modifiable set of Integer formats
|
|
*/
|
|
public @Nullable Set<Integer> getInputFormats() {
|
|
return getUnmodifiableIntegerSet(mRecommendedMap.getInputFormats());
|
|
}
|
|
|
|
private Set<Size> getUnmodifiableSizeSet(Size[] sizeArray) {
|
|
if ((sizeArray != null) && (sizeArray.length > 0)) {
|
|
ArraySet<Size> sizeSet = new ArraySet<Size>();
|
|
sizeSet.addAll(Arrays.asList(sizeArray));
|
|
return Collections.unmodifiableSet(sizeSet);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Get the supported input sizes for this input format.
|
|
*
|
|
* <p>The format must have come from {@link #getInputFormats}; otherwise
|
|
* {@code null} is returned.</p>
|
|
*
|
|
* @param format a format from {@link #getInputFormats}
|
|
* @return a non-modifiable set of sizes, or {@code null} if the format was not available.
|
|
*/
|
|
public @Nullable Set<Size> getInputSizes(@Format int format) {
|
|
return getUnmodifiableSizeSet(mRecommendedMap.getInputSizes(format));
|
|
}
|
|
|
|
/**
|
|
* Determine whether or not output surfaces with a particular user-defined format can be passed
|
|
* {@link CameraDevice#createCaptureSession(SessionConfiguration) createCaptureSession}.
|
|
*
|
|
* <p>
|
|
* For further information refer to {@link StreamConfigurationMap#isOutputSupportedFor}.
|
|
* </p>
|
|
*
|
|
*
|
|
* @param format an image format from either {@link ImageFormat} or {@link PixelFormat}
|
|
* @return
|
|
* {@code true} if using a {@code surface} with this {@code format} will be
|
|
* supported with {@link CameraDevice#createCaptureSession(SessionConfiguration)}
|
|
*
|
|
* @throws IllegalArgumentException
|
|
* if the image format was not a defined named constant
|
|
* from either {@link ImageFormat} or {@link PixelFormat}
|
|
*/
|
|
public boolean isOutputSupportedFor(@Format int format) {
|
|
return mRecommendedMap.isOutputSupportedFor(format);
|
|
}
|
|
|
|
/**
|
|
* Get a list of sizes compatible with the requested image {@code format}.
|
|
*
|
|
* <p>
|
|
* For more information refer to {@link StreamConfigurationMap#getOutputSizes}.
|
|
* </p>
|
|
*
|
|
*
|
|
* @param format an image format from {@link ImageFormat} or {@link PixelFormat}
|
|
* @return a non-modifiable set of supported sizes,
|
|
* or {@code null} if the {@code format} is not a supported output
|
|
*/
|
|
public @Nullable Set<Size> getOutputSizes(@Format int format) {
|
|
return getUnmodifiableSizeSet(mRecommendedMap.getOutputSizes(format));
|
|
}
|
|
|
|
/**
|
|
* Get a list of supported high speed video recording sizes.
|
|
* <p>
|
|
* For more information refer to {@link StreamConfigurationMap#getHighSpeedVideoSizes}.
|
|
* </p>
|
|
*
|
|
* @return a non-modifiable set of supported high speed video recording sizes
|
|
*/
|
|
public @Nullable Set<Size> getHighSpeedVideoSizes() {
|
|
return getUnmodifiableSizeSet(mRecommendedMap.getHighSpeedVideoSizes());
|
|
}
|
|
|
|
private Set<Range<Integer>> getUnmodifiableRangeSet(Range<Integer>[] rangeArray) {
|
|
if ((rangeArray != null) && (rangeArray.length > 0)) {
|
|
ArraySet<Range<Integer>> rangeSet = new ArraySet<Range<Integer>>();
|
|
rangeSet.addAll(Arrays.asList(rangeArray));
|
|
return Collections.unmodifiableSet(rangeSet);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Get the frame per second ranges (fpsMin, fpsMax) for input high speed video size.
|
|
*
|
|
* <p>
|
|
* For further information refer to
|
|
* {@link StreamConfigurationMap#getHighSpeedVideoFpsRangesFor}.
|
|
* </p>
|
|
* @param size one of the sizes returned by {@link #getHighSpeedVideoSizes()}
|
|
* @return a non-modifiable set of supported high speed video recording FPS ranges The upper
|
|
* bound of returned ranges is guaranteed to be greater than or equal to 120.
|
|
* @throws IllegalArgumentException if input size does not exist in the return value of
|
|
* getHighSpeedVideoSizes
|
|
*/
|
|
public @Nullable Set<Range<Integer>> getHighSpeedVideoFpsRangesFor(@NonNull Size size) {
|
|
return getUnmodifiableRangeSet(mRecommendedMap.getHighSpeedVideoFpsRangesFor(size));
|
|
}
|
|
|
|
/**
|
|
* Get a list of supported high speed video recording FPS ranges.
|
|
* <p>
|
|
* For further information refer to {@link StreamConfigurationMap#getHighSpeedVideoFpsRanges}.
|
|
* </p>
|
|
* @return a non-modifiable set of supported high speed video recording FPS ranges The upper
|
|
* bound of returned ranges is guaranteed to be larger or equal to 120.
|
|
*/
|
|
public @Nullable Set<Range<Integer>> getHighSpeedVideoFpsRanges() {
|
|
return getUnmodifiableRangeSet(mRecommendedMap.getHighSpeedVideoFpsRanges());
|
|
}
|
|
|
|
/**
|
|
* Get the supported video sizes for an input high speed FPS range.
|
|
*
|
|
* <p>
|
|
* For further information refer to {@link StreamConfigurationMap#getHighSpeedVideoSizesFor}.
|
|
* </p>
|
|
*
|
|
* @param fpsRange one of the FPS ranges returned by {@link #getHighSpeedVideoFpsRanges()}
|
|
* @return A non-modifiable set of video sizes to create high speed capture sessions for high
|
|
* speed streaming use cases.
|
|
*
|
|
* @throws IllegalArgumentException if input FPS range does not exist in the return value of
|
|
* getHighSpeedVideoFpsRanges
|
|
*/
|
|
public @Nullable Set<Size> getHighSpeedVideoSizesFor(@NonNull Range<Integer> fpsRange) {
|
|
return getUnmodifiableSizeSet(mRecommendedMap.getHighSpeedVideoSizesFor(fpsRange));
|
|
}
|
|
|
|
/**
|
|
* Get a list of supported high resolution sizes, which cannot operate at full BURST_CAPTURE
|
|
* rate.
|
|
*
|
|
* <p>
|
|
* For further information refer to {@link StreamConfigurationMap#getHighResolutionOutputSizes}.
|
|
* </p>
|
|
*
|
|
* @return a non-modifiable set of supported slower high-resolution sizes, or {@code null} if
|
|
* the BURST_CAPTURE capability is not supported
|
|
*/
|
|
public @Nullable Set<Size> getHighResolutionOutputSizes(@Format int format) {
|
|
return getUnmodifiableSizeSet(mRecommendedMap.getHighResolutionOutputSizes(format));
|
|
}
|
|
|
|
/**
|
|
* Get the minimum
|
|
* {@link android.hardware.camera2.CaptureRequest#SENSOR_FRAME_DURATION frame duration}
|
|
* for the format/size combination (in nanoseconds).
|
|
*
|
|
* <p>
|
|
* For further information refer to {@link StreamConfigurationMap#getOutputMinFrameDuration}.
|
|
* </p>
|
|
*
|
|
* @param format an image format from {@link ImageFormat} or {@link PixelFormat}
|
|
* @param size an output-compatible size
|
|
* @return a minimum frame duration {@code >} 0 in nanoseconds, or
|
|
* 0 if the minimum frame duration is not available.
|
|
*
|
|
* @throws IllegalArgumentException if {@code format} or {@code size} was not supported
|
|
*/
|
|
public @IntRange(from = 0) long getOutputMinFrameDuration(@Format int format,
|
|
@NonNull Size size) {
|
|
return mRecommendedMap.getOutputMinFrameDuration(format, size);
|
|
}
|
|
|
|
/**
|
|
* Get the stall duration for the format/size combination (in nanoseconds).
|
|
*
|
|
* <p>
|
|
* For further information refer to {@link StreamConfigurationMap#getOutputStallDuration}.
|
|
* </p>
|
|
*
|
|
* @param format an image format from {@link ImageFormat} or {@link PixelFormat}
|
|
* @param size an output-compatible size
|
|
* @return a stall duration {@code >=} 0 in nanoseconds
|
|
*
|
|
* @throws IllegalArgumentException if {@code format} or {@code size} was not supported
|
|
*/
|
|
public @IntRange(from = 0) long getOutputStallDuration(@Format int format, @NonNull Size size) {
|
|
return mRecommendedMap.getOutputStallDuration(format, size);
|
|
}
|
|
|
|
/**
|
|
* Get a list of sizes compatible with {@code klass} to use as an output.
|
|
*
|
|
* <p>For further information refer to {@link StreamConfigurationMap#getOutputSizes(Class)}.
|
|
* </p>
|
|
*
|
|
* @param klass
|
|
* a {@link Class} object reference
|
|
* @return
|
|
* a non-modifiable set of supported sizes for {@link ImageFormat#PRIVATE} format,
|
|
* or {@code null} if the {@code klass} is not a supported output.
|
|
*/
|
|
public @Nullable <T> Set<Size> getOutputSizes(@NonNull Class<T> klass) {
|
|
if (mSupportsPrivate) {
|
|
return getUnmodifiableSizeSet(mRecommendedMap.getOutputSizes(klass));
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Get the minimum {@link CaptureRequest#SENSOR_FRAME_DURATION frame duration}
|
|
* for the class/size combination (in nanoseconds).
|
|
*
|
|
* <p>For more information refer to
|
|
* {@link StreamConfigurationMap#getOutputMinFrameDuration(Class, Size)}.</p>
|
|
*
|
|
* @param klass
|
|
* a class which has a non-empty array returned by {@link #getOutputSizes(Class)}
|
|
* @param size an output-compatible size
|
|
* @return a minimum frame duration {@code >} 0 in nanoseconds, or
|
|
* 0 if the minimum frame duration is not available.
|
|
*
|
|
* @throws IllegalArgumentException if {@code klass} or {@code size} was not supported
|
|
*/
|
|
public @IntRange(from = 0) <T> long getOutputMinFrameDuration(@NonNull final Class<T> klass,
|
|
@NonNull final Size size) {
|
|
if (mSupportsPrivate) {
|
|
return mRecommendedMap.getOutputMinFrameDuration(klass, size);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Get the stall duration for the class/size combination (in nanoseconds).
|
|
*
|
|
* <p>For more information refer to
|
|
* {@link StreamConfigurationMap#getOutputStallDuration(Class, Size)}.
|
|
*
|
|
* @param klass
|
|
* a class which has a non-empty array returned by {@link #getOutputSizes(Class)}.
|
|
* @param size an output-compatible size
|
|
* @return a minimum frame duration {@code >} 0 in nanoseconds, or 0 if the stall duration is
|
|
* not available.
|
|
*
|
|
* @throws IllegalArgumentException if {@code klass} or {@code size} was not supported
|
|
*/
|
|
public @IntRange(from = 0) <T> long getOutputStallDuration(@NonNull final Class<T> klass,
|
|
@NonNull final Size size) {
|
|
if (mSupportsPrivate) {
|
|
return mRecommendedMap.getOutputStallDuration(klass, size);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Determine whether or not the {@code surface} in its current
|
|
* state is suitable to be included in a {@link
|
|
* CameraDevice#createCaptureSession(SessionConfiguration) capture
|
|
* session} as an output.
|
|
*
|
|
* <p>For more information refer to {@link StreamConfigurationMap#isOutputSupportedFor}.
|
|
* </p>
|
|
*
|
|
* @param surface a {@link Surface} object reference
|
|
* @return {@code true} if this is supported, {@code false} otherwise
|
|
*
|
|
* @throws IllegalArgumentException if the Surface endpoint is no longer valid
|
|
*
|
|
*/
|
|
public boolean isOutputSupportedFor(@NonNull Surface surface) {
|
|
return mRecommendedMap.isOutputSupportedFor(surface);
|
|
}
|
|
|
|
}
|