Merge "Create API for reporting color space support to Camera2 framework consumers."

This commit is contained in:
Austin Borger
2022-10-24 17:25:12 +00:00
committed by Android (Google) Code Review
10 changed files with 534 additions and 6 deletions

View File

@@ -17630,6 +17630,7 @@ package android.hardware.camera2 {
field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES;
field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REPROCESS_MAX_CAPTURE_STALL;
field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> REQUEST_AVAILABLE_CAPABILITIES;
field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.hardware.camera2.params.ColorSpaceProfiles> REQUEST_AVAILABLE_COLOR_SPACE_PROFILES;
field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.hardware.camera2.params.DynamicRangeProfiles> REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES;
field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_MAX_NUM_INPUT_STREAMS;
field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_MAX_NUM_OUTPUT_PROC;
@@ -17993,6 +17994,7 @@ package android.hardware.camera2 {
field public static final int NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG = 4; // 0x4
field public static final int REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE = 0; // 0x0
field public static final int REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE = 6; // 0x6
field public static final int REQUEST_AVAILABLE_CAPABILITIES_COLOR_SPACE_PROFILES = 20; // 0x14
field public static final int REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO = 9; // 0x9
field public static final int REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT = 8; // 0x8
field public static final int REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT = 18; // 0x12
@@ -18344,6 +18346,15 @@ package android.hardware.camera2.params {
method @NonNull public android.util.Range<java.lang.Float> getZoomRatioRange();
}
public final class ColorSpaceProfiles {
ctor public ColorSpaceProfiles(@NonNull long[]);
method @NonNull public java.util.Set<android.graphics.ColorSpace.Named> getSupportedColorSpaces(int);
method @NonNull public java.util.Set<android.graphics.ColorSpace.Named> getSupportedColorSpacesForDynamicRange(int, long);
method @NonNull public java.util.Set<java.lang.Long> getSupportedDynamicRangeProfiles(@NonNull android.graphics.ColorSpace.Named, int);
method @NonNull public java.util.Set<java.lang.Integer> getSupportedImageFormatsForColorSpace(@NonNull android.graphics.ColorSpace.Named);
field public static final int UNSPECIFIED = -1; // 0xffffffff
}
public final class ColorSpaceTransform {
ctor public ColorSpaceTransform(android.util.Rational[]);
ctor public ColorSpaceTransform(int[]);
@@ -18575,13 +18586,16 @@ package android.hardware.camera2.params {
public final class SessionConfiguration implements android.os.Parcelable {
ctor public SessionConfiguration(int, @NonNull java.util.List<android.hardware.camera2.params.OutputConfiguration>, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.CameraCaptureSession.StateCallback);
method public void clearColorSpace();
method public int describeContents();
method @Nullable public android.graphics.ColorSpace getColorSpace();
method public java.util.concurrent.Executor getExecutor();
method public android.hardware.camera2.params.InputConfiguration getInputConfiguration();
method public java.util.List<android.hardware.camera2.params.OutputConfiguration> getOutputConfigurations();
method public android.hardware.camera2.CaptureRequest getSessionParameters();
method public int getSessionType();
method public android.hardware.camera2.CameraCaptureSession.StateCallback getStateCallback();
method public void setColorSpace(@NonNull android.graphics.ColorSpace.Named);
method public void setInputConfiguration(@NonNull android.hardware.camera2.params.InputConfiguration);
method public void setSessionParameters(android.hardware.camera2.CaptureRequest);
method public void writeToParcel(android.os.Parcel, int);

View File

@@ -1170,6 +1170,20 @@ package android.hardware.camera2 {
}
package android.hardware.camera2.params {
public final class ColorSpaceProfiles {
method @NonNull public java.util.Map<android.graphics.ColorSpace.Named,java.util.Map<java.lang.Integer,java.util.Set<java.lang.Long>>> getProfileMap();
}
public final class OutputConfiguration implements android.os.Parcelable {
method public void clearColorSpace();
method @Nullable public android.graphics.ColorSpace getColorSpace();
method public void setColorSpace(@NonNull android.graphics.ColorSpace.Named);
}
}
package android.hardware.devicestate {
public final class DeviceStateManager {

View File

@@ -16,6 +16,7 @@
package android.hardware;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.params.ColorSpaceProfiles;
import android.hardware.camera2.params.DynamicRangeProfiles;
import android.os.Parcel;
import android.os.Parcelable;
@@ -50,6 +51,7 @@ public class CameraStreamStats implements Parcelable {
private long[] mHistogramCounts;
private long mDynamicRangeProfile;
private long mStreamUseCase;
private int mColorSpace;
private static final String TAG = "CameraStreamStats";
@@ -68,12 +70,13 @@ public class CameraStreamStats implements Parcelable {
mHistogramType = HISTOGRAM_TYPE_UNKNOWN;
mDynamicRangeProfile = DynamicRangeProfiles.STANDARD;
mStreamUseCase = CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
mColorSpace = ColorSpaceProfiles.UNSPECIFIED;
}
public CameraStreamStats(int width, int height, int format, float maxPreviewFps,
int dataSpace, long usage, long requestCount, long errorCount,
int startLatencyMs, int maxHalBuffers, int maxAppBuffers, long dynamicRangeProfile,
long streamUseCase) {
long streamUseCase, int colorSpace) {
mWidth = width;
mHeight = height;
mFormat = format;
@@ -88,6 +91,7 @@ public class CameraStreamStats implements Parcelable {
mHistogramType = HISTOGRAM_TYPE_UNKNOWN;
mDynamicRangeProfile = dynamicRangeProfile;
mStreamUseCase = streamUseCase;
mColorSpace = colorSpace;
}
public static final @android.annotation.NonNull Parcelable.Creator<CameraStreamStats> CREATOR =
@@ -136,6 +140,7 @@ public class CameraStreamStats implements Parcelable {
dest.writeLongArray(mHistogramCounts);
dest.writeLong(mDynamicRangeProfile);
dest.writeLong(mStreamUseCase);
dest.writeInt(mColorSpace);
}
public void readFromParcel(Parcel in) {
@@ -155,6 +160,7 @@ public class CameraStreamStats implements Parcelable {
mHistogramCounts = in.createLongArray();
mDynamicRangeProfile = in.readLong();
mStreamUseCase = in.readLong();
mColorSpace = in.readInt();
}
public int getWidth() {
@@ -217,6 +223,10 @@ public class CameraStreamStats implements Parcelable {
return mDynamicRangeProfile;
}
public int getColorSpace() {
return mColorSpace;
}
public long getStreamUseCase() {
return mStreamUseCase;
}

View File

@@ -2224,6 +2224,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING REMOSAIC_REPROCESSING}</li>
* <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT DYNAMIC_RANGE_TEN_BIT}</li>
* <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE STREAM_USE_CASE}</li>
* <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_COLOR_SPACE_PROFILES COLOR_SPACE_PROFILES}</li>
* </ul>
*
* <p>This key is available on all devices.</p>
@@ -2249,6 +2250,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* @see #REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING
* @see #REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT
* @see #REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE
* @see #REQUEST_AVAILABLE_CAPABILITIES_COLOR_SPACE_PROFILES
*/
@PublicKey
@NonNull
@@ -2472,6 +2474,82 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
public static final Key<Long> REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE =
new Key<Long>("android.request.recommendedTenBitDynamicRangeProfile", long.class);
/**
* <p>An interface for querying the color space profiles supported by a camera device.</p>
* <p>A color space profile is a combination of a color space, an image format, and a dynamic
* range profile. Camera clients can retrieve the list of supported color spaces by calling
* {@link android.hardware.camera2.params.ColorSpaceProfiles#getSupportedColorSpaces } or
* {@link android.hardware.camera2.params.ColorSpaceProfiles#getSupportedColorSpacesForDynamicRange }.
* If a camera does not support the
* {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT }
* capability, the dynamic range profile will always be
* {@link android.hardware.camera2.params.DynamicRangeProfiles#STANDARD }. Color space
* capabilities are queried in combination with an {@link android.graphics.ImageFormat }.
* If a camera client wants to know the general color space capabilities of a camera device
* regardless of image format, it can specify {@link android.graphics.ImageFormat#UNKNOWN }.
* The color space for a session can be configured by setting the SessionConfiguration
* color space via {@link android.hardware.camera2.params.SessionConfiguration#setColorSpace }.</p>
* <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
*/
@PublicKey
@NonNull
@SyntheticKey
public static final Key<android.hardware.camera2.params.ColorSpaceProfiles> REQUEST_AVAILABLE_COLOR_SPACE_PROFILES =
new Key<android.hardware.camera2.params.ColorSpaceProfiles>("android.request.availableColorSpaceProfiles", android.hardware.camera2.params.ColorSpaceProfiles.class);
/**
* <p>A list of all possible color space profiles supported by a camera device.</p>
* <p>A color space profile is a combination of a color space, an image format, and a dynamic range
* profile. If a camera does not support the
* {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT }
* capability, the dynamic range profile will always be
* {@link android.hardware.camera2.params.DynamicRangeProfiles#STANDARD }. Camera clients can
* use {@link android.hardware.camera2.params.SessionConfiguration#setColorSpace } to select
* a color space.</p>
* <p><b>Possible values:</b></p>
* <ul>
* <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED UNSPECIFIED}</li>
* <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_SRGB SRGB}</li>
* <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_LINEAR_SRGB LINEAR_SRGB}</li>
* <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_EXTENDED_SRGB EXTENDED_SRGB}</li>
* <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_LINEAR_EXTENDED_SRGB LINEAR_EXTENDED_SRGB}</li>
* <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_BT709 BT709}</li>
* <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_BT2020 BT2020}</li>
* <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_DCI_P3 DCI_P3}</li>
* <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_DISPLAY_P3 DISPLAY_P3}</li>
* <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_NTSC_1953 NTSC_1953}</li>
* <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_SMPTE_C SMPTE_C}</li>
* <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_ADOBE_RGB ADOBE_RGB}</li>
* <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_PRO_PHOTO_RGB PRO_PHOTO_RGB}</li>
* <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_ACES ACES}</li>
* <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_ACESCG ACESCG}</li>
* <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_CIE_XYZ CIE_XYZ}</li>
* <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_CIE_LAB CIE_LAB}</li>
* </ul>
*
* <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
* @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED
* @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_SRGB
* @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_LINEAR_SRGB
* @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_EXTENDED_SRGB
* @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_LINEAR_EXTENDED_SRGB
* @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_BT709
* @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_BT2020
* @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_DCI_P3
* @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_DISPLAY_P3
* @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_NTSC_1953
* @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_SMPTE_C
* @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_ADOBE_RGB
* @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_PRO_PHOTO_RGB
* @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_ACES
* @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_ACESCG
* @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_CIE_XYZ
* @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_CIE_LAB
* @hide
*/
public static final Key<long[]> REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP =
new Key<long[]>("android.request.availableColorSpaceProfilesMap", long[].class);
/**
* <p>The list of image formats that are supported by this
* camera device for output streams.</p>

View File

@@ -1257,6 +1257,24 @@ public abstract class CameraMetadata<TKey> {
*/
public static final int REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE = 19;
/**
* <p>The device supports querying the possible combinations of color spaces, image
* formats, and dynamic range profiles supported by the camera and requesting a
* particular color space for a session via
* {@link android.hardware.camera2.params.SessionConfiguration#setColorSpace }.</p>
* <p>Cameras that enable this capability may or may not also implement dynamic range
* profiles. If they don't,
* {@link android.hardware.camera2.params.ColorSpaceProfiles#getSupportedDynamicRangeProfiles }
* will return only
* {@link android.hardware.camera2.params.DynamicRangeProfiles#STANDARD } and
* {@link android.hardware.camera2.params.ColorSpaceProfiles#getSupportedColorSpacesForDynamicRange }
* will assume support of the
* {@link android.hardware.camera2.params.DynamicRangeProfiles#STANDARD }
* profile in all combinations of color spaces and image formats.</p>
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
public static final int REQUEST_AVAILABLE_CAPABILITIES_COLOR_SPACE_PROFILES = 20;
//
// Enumeration values for CameraCharacteristics#REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP
//
@@ -1366,6 +1384,18 @@ public abstract class CameraMetadata<TKey> {
*/
public static final int REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX = 0x1000;
//
// Enumeration values for CameraCharacteristics#REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP
//
/**
* <p>Default value, when not explicitly specified. The Camera device will choose the color
* space to employ.</p>
* @see CameraCharacteristics#REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP
* @hide
*/
public static final int REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED = -1;
//
// Enumeration values for CameraCharacteristics#SCALER_CROPPING_TYPE
//

View File

@@ -50,6 +50,7 @@ import android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfiguration
import android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfigurationDuration;
import android.hardware.camera2.marshal.impl.MarshalQueryableString;
import android.hardware.camera2.params.Capability;
import android.hardware.camera2.params.ColorSpaceProfiles;
import android.hardware.camera2.params.DeviceStateSensorOrientationMap;
import android.hardware.camera2.params.DynamicRangeProfiles;
import android.hardware.camera2.params.Face;
@@ -812,6 +813,15 @@ public class CameraMetadataNative implements Parcelable {
return (T) metadata.getDynamicRangeProfiles();
}
});
sGetCommandMap.put(
CameraCharacteristics.REQUEST_AVAILABLE_COLOR_SPACE_PROFILES.getNativeKey(),
new GetCommand() {
@Override
@SuppressWarnings("unchecked")
public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {
return (T) metadata.getColorSpaceProfiles();
}
});
sGetCommandMap.put(
CaptureResult.STATISTICS_OIS_SAMPLES.getNativeKey(),
new GetCommand() {
@@ -1068,6 +1078,17 @@ public class CameraMetadataNative implements Parcelable {
return new DynamicRangeProfiles(profileArray);
}
private ColorSpaceProfiles getColorSpaceProfiles() {
long[] profileArray = getBase(
CameraCharacteristics.REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP);
if (profileArray == null) {
return null;
}
return new ColorSpaceProfiles(profileArray);
}
private Location getGpsLocation() {
String processingMethod = get(CaptureResult.JPEG_GPS_PROCESSING_METHOD);
double[] coords = get(CaptureResult.JPEG_GPS_COORDINATES);

View File

@@ -0,0 +1,257 @@
/*
* Copyright (C) 2022 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.NonNull;
import android.annotation.TestApi;
import android.graphics.ColorSpace;
import android.graphics.ImageFormat;
import android.hardware.camera2.CameraMetadata;
import android.util.ArrayMap;
import android.util.ArraySet;
import java.util.Map;
import java.util.Set;
/**
* Immutable class with information about supported color space profiles.
*
* <p>An instance of this class can be queried by retrieving the value of
* {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_COLOR_SPACE_PROFILES}.
* </p>
*
* <p>All camera devices supporting the
* {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_COLOR_SPACE_PROFILES}
* capability must advertise the supported color space profiles in
* {@link #getSupportedColorSpaces}</p>
*
* @see SessionConfiguration#setColorSpace
*/
public final class ColorSpaceProfiles {
/*
* @hide
*/
public static final int UNSPECIFIED =
CameraMetadata.REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED;
private final Map<ColorSpace.Named, Map<Integer, Set<Long>>> mProfileMap = new ArrayMap<>();
/**
* Create a new immutable ColorSpaceProfiles instance.
*
* <p>This constructor takes over the array; do not write to the array afterwards.</p>
*
* <p>Do note that the constructor is available for testing purposes only!
* Camera clients must always retrieve the value of
* {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_COLOR_SPACE_PROFILES}.
* for a given camera id in order to retrieve the device capabilities.</p>
*
* @param elements
* An array of elements describing the map. It contains three elements per entry which
* describe the supported color space profile value in the first element, a compatible
* image format in the second, and in the third element a bitmap of compatible dynamic
* range profiles (see {@link DynamicRangeProfiles#STANDARD} and others for the
* individual bitmap components).
*
* @throws IllegalArgumentException
* if the {@code elements} array length is invalid, not divisible by 3 or contains
* invalid element values
* @throws NullPointerException
* if {@code elements} is {@code null}
*
*/
public ColorSpaceProfiles(@NonNull final long[] elements) {
if ((elements.length % 3) != 0) {
throw new IllegalArgumentException("Color space profile map length "
+ elements.length + " is not divisible by 3!");
}
for (int i = 0; i < elements.length; i += 3) {
int colorSpace = (int) elements[i];
checkProfileValue(colorSpace);
ColorSpace.Named namedColorSpace = ColorSpace.Named.values()[colorSpace];
int imageFormat = (int) elements[i + 1];
long dynamicRangeProfileBitmap = elements[i + 2];
if (!mProfileMap.containsKey(namedColorSpace)) {
ArrayMap<Integer, Set<Long>> imageFormatMap = new ArrayMap<>();
mProfileMap.put(namedColorSpace, imageFormatMap);
}
if (!mProfileMap.get(namedColorSpace).containsKey(imageFormat)) {
ArraySet<Long> dynamicRangeProfiles = new ArraySet<>();
mProfileMap.get(namedColorSpace).put(imageFormat, dynamicRangeProfiles);
}
if (dynamicRangeProfileBitmap != 0) {
for (long dynamicRangeProfile = DynamicRangeProfiles.STANDARD;
dynamicRangeProfile < DynamicRangeProfiles.PUBLIC_MAX;
dynamicRangeProfile <<= 1) {
if ((dynamicRangeProfileBitmap & dynamicRangeProfile) != 0) {
mProfileMap.get(namedColorSpace).get(imageFormat).add(dynamicRangeProfile);
}
}
}
}
}
/**
* @hide
*/
public static void checkProfileValue(int colorSpace) {
boolean found = false;
for (ColorSpace.Named value : ColorSpace.Named.values()) {
if (colorSpace == value.ordinal()) {
found = true;
break;
}
}
if (!found) {
throw new IllegalArgumentException("Unknown ColorSpace " + colorSpace);
}
}
/**
* @hide
*/
@TestApi
public @NonNull Map<ColorSpace.Named, Map<Integer, Set<Long>>> getProfileMap() {
return mProfileMap;
}
/**
* Return a list of color spaces that are compatible with an ImageFormat. If ImageFormat.UNKNOWN
* is provided, this function will return a set of all unique color spaces supported by the
* device, regardless of image format.
*
* Color spaces which are compatible with ImageFormat.PRIVATE are able to be used with
* SurfaceView, SurfaceTexture, MediaCodec and MediaRecorder.
*
* @return set of color spaces
* @see SessionConfiguration#setColorSpace
* @see ColorSpace.Named
*/
public @NonNull Set<ColorSpace.Named> getSupportedColorSpaces(
@ImageFormat.Format int imageFormat) {
ArraySet<ColorSpace.Named> supportedColorSpaceProfiles = new ArraySet<>();
for (ColorSpace.Named colorSpace : mProfileMap.keySet()) {
if (imageFormat == ImageFormat.UNKNOWN) {
supportedColorSpaceProfiles.add(colorSpace);
} else {
Map<Integer, Set<Long>> imageFormatMap = mProfileMap.get(colorSpace);
if (imageFormatMap.containsKey(imageFormat)) {
supportedColorSpaceProfiles.add(colorSpace);
}
}
}
return supportedColorSpaceProfiles;
}
/**
* Return a list of image formats that are compatible with a color space.
*
* Color spaces which are compatible with ImageFormat.PRIVATE are able to be used with
* SurfaceView, SurfaceTexture, MediaCodec and MediaRecorder.
*
* @return set of image formats
* @see SessionConfiguration#setColorSpace
* @see ColorSpace.Named
*/
public @NonNull Set<Integer> getSupportedImageFormatsForColorSpace(
@NonNull ColorSpace.Named colorSpace) {
Map<Integer, Set<Long>> imageFormatMap = mProfileMap.get(colorSpace);
if (imageFormatMap == null) {
return new ArraySet<Integer>();
}
return imageFormatMap.keySet();
}
/**
* Return a list of dynamic range profiles that are compatible with a color space and
* ImageFormat. If ImageFormat.UNKNOWN is provided, this function will return a set of
* all unique dynamic range profiles supported by the device given a color space,
* regardless of image format.
*
* @return set of dynamic range profiles.
* @see OutputConfiguration#setDynamicRangeProfile
* @see SessionConfiguration#setColorSpace
* @see ColorSpace.Named
* @see DynamicRangeProfiles.Profile
*/
public @NonNull Set<Long> getSupportedDynamicRangeProfiles(@NonNull ColorSpace.Named colorSpace,
@ImageFormat.Format int imageFormat) {
Map<Integer, Set<Long>> imageFormatMap = mProfileMap.get(colorSpace);
if (imageFormatMap == null) {
return new ArraySet<Long>();
}
Set<Long> dynamicRangeProfiles = null;
if (imageFormat == ImageFormat.UNKNOWN) {
dynamicRangeProfiles = new ArraySet<>();
for (int supportedImageFormat : imageFormatMap.keySet()) {
Set<Long> supportedDynamicRangeProfiles = imageFormatMap.get(
supportedImageFormat);
for (Long supportedDynamicRangeProfile : supportedDynamicRangeProfiles) {
dynamicRangeProfiles.add(supportedDynamicRangeProfile);
}
}
} else {
dynamicRangeProfiles = imageFormatMap.get(imageFormat);
if (dynamicRangeProfiles == null) {
return new ArraySet<>();
}
}
return dynamicRangeProfiles;
}
/**
* Return a list of color spaces that are compatible with an ImageFormat and a dynamic range
* profile. If ImageFormat.UNKNOWN is provided, this function will return a set of all unique
* color spaces compatible with the given dynamic range profile, regardless of image format.
*
* @return set of color spaces
* @see SessionConfiguration#setColorSpace
* @see OutputConfiguration#setDynamicRangeProfile
* @see ColorSpace.Named
* @see DynamicRangeProfiles.Profile
*/
public @NonNull Set<ColorSpace.Named> getSupportedColorSpacesForDynamicRange(
@ImageFormat.Format int imageFormat,
@DynamicRangeProfiles.Profile long dynamicRangeProfile) {
ArraySet<ColorSpace.Named> supportedColorSpaceProfiles = new ArraySet<>();
for (ColorSpace.Named colorSpace : mProfileMap.keySet()) {
Map<Integer, Set<Long>> imageFormatMap = mProfileMap.get(colorSpace);
if (imageFormat == ImageFormat.UNKNOWN) {
for (int supportedImageFormat : imageFormatMap.keySet()) {
Set<Long> dynamicRangeProfiles = imageFormatMap.get(supportedImageFormat);
if (dynamicRangeProfiles.contains(dynamicRangeProfile)) {
supportedColorSpaceProfiles.add(colorSpace);
}
}
} else if (imageFormatMap.containsKey(imageFormat)) {
Set<Long> dynamicRangeProfiles = imageFormatMap.get(imageFormat);
if (dynamicRangeProfiles.contains(dynamicRangeProfile)) {
supportedColorSpaceProfiles.add(colorSpace);
}
}
}
return supportedColorSpaceProfiles;
}
}

View File

@@ -22,7 +22,10 @@ import static com.android.internal.util.Preconditions.*;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.graphics.ColorSpace;
import android.graphics.ImageFormat;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
@@ -30,7 +33,6 @@ import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.MultiResolutionImageReader;
import android.hardware.camera2.params.DynamicRangeProfiles;
import android.hardware.camera2.params.DynamicRangeProfiles.Profile;
import android.hardware.camera2.params.MultiResolutionStreamInfo;
import android.hardware.camera2.utils.HashCodeHelpers;
import android.hardware.camera2.utils.SurfaceUtils;
@@ -454,7 +456,7 @@ public final class OutputConfiguration implements Parcelable {
* {@link android.media.MediaCodec} etc.)
* or {@link ImageFormat#YCBCR_P010}.</p>
*/
public void setDynamicRangeProfile(@Profile long profile) {
public void setDynamicRangeProfile(@DynamicRangeProfiles.Profile long profile) {
mDynamicRangeProfile = profile;
}
@@ -463,10 +465,53 @@ public final class OutputConfiguration implements Parcelable {
*
* @return the currently set dynamic range profile
*/
public @Profile long getDynamicRangeProfile() {
public @DynamicRangeProfiles.Profile long getDynamicRangeProfile() {
return mDynamicRangeProfile;
}
/**
* Set a specific device-supported color space.
*
* <p>Clients can choose from any profile advertised as supported in
* {@link CameraCharacteristics#REQUEST_AVAILABLE_COLOR_SPACE_PROFILES}
* queried using {@link ColorSpaceProfiles#getSupportedColorSpaces}.
* When set, the colorSpace will override the default color spaces of the output targets,
* or the color space implied by the dataSpace passed into an {@link ImageReader}'s
* constructor.</p>
*
* @hide
*/
@TestApi
public void setColorSpace(@NonNull ColorSpace.Named colorSpace) {
mColorSpace = colorSpace.ordinal();
}
/**
* Clear the color space, such that the default color space will be used.
*
* @hide
*/
@TestApi
public void clearColorSpace() {
mColorSpace = ColorSpaceProfiles.UNSPECIFIED;
}
/**
* Return the current color space.
*
* @return the currently set color space
* @hide
*/
@TestApi
@SuppressLint("MethodNameUnits")
public @Nullable ColorSpace getColorSpace() {
if (mColorSpace != ColorSpaceProfiles.UNSPECIFIED) {
return ColorSpace.get(ColorSpace.Named.values()[mColorSpace]);
} else {
return null;
}
}
/**
* Create a new {@link OutputConfiguration} instance.
*
@@ -530,6 +575,7 @@ public final class OutputConfiguration implements Parcelable {
mIsMultiResolution = false;
mSensorPixelModesUsed = new ArrayList<Integer>();
mDynamicRangeProfile = DynamicRangeProfiles.STANDARD;
mColorSpace = ColorSpaceProfiles.UNSPECIFIED;
mStreamUseCase = CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
mTimestampBase = TIMESTAMP_BASE_DEFAULT;
mMirrorMode = MIRROR_MODE_AUTO;
@@ -631,6 +677,7 @@ public final class OutputConfiguration implements Parcelable {
mIsMultiResolution = false;
mSensorPixelModesUsed = new ArrayList<Integer>();
mDynamicRangeProfile = DynamicRangeProfiles.STANDARD;
mColorSpace = ColorSpaceProfiles.UNSPECIFIED;
mStreamUseCase = CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
}
@@ -1079,6 +1126,7 @@ public final class OutputConfiguration implements Parcelable {
this.mIsMultiResolution = other.mIsMultiResolution;
this.mSensorPixelModesUsed = other.mSensorPixelModesUsed;
this.mDynamicRangeProfile = other.mDynamicRangeProfile;
this.mColorSpace = other.mColorSpace;
this.mStreamUseCase = other.mStreamUseCase;
this.mTimestampBase = other.mTimestampBase;
this.mMirrorMode = other.mMirrorMode;
@@ -1105,6 +1153,7 @@ public final class OutputConfiguration implements Parcelable {
checkArgumentInRange(rotation, ROTATION_0, ROTATION_270, "Rotation constant");
long dynamicRangeProfile = source.readLong();
DynamicRangeProfiles.checkProfileValue(dynamicRangeProfile);
int colorSpace = source.readInt();
int timestampBase = source.readInt();
int mirrorMode = source.readInt();
@@ -1132,6 +1181,7 @@ public final class OutputConfiguration implements Parcelable {
mIsMultiResolution = isMultiResolutionOutput;
mSensorPixelModesUsed = convertIntArrayToIntegerList(sensorPixelModesUsed);
mDynamicRangeProfile = dynamicRangeProfile;
mColorSpace = colorSpace;
mStreamUseCase = streamUseCase;
mTimestampBase = timestampBase;
mMirrorMode = mirrorMode;
@@ -1251,6 +1301,7 @@ public final class OutputConfiguration implements Parcelable {
// writeList doesn't seem to work well with Integer list.
dest.writeIntArray(convertIntegerToIntList(mSensorPixelModesUsed));
dest.writeLong(mDynamicRangeProfile);
dest.writeInt(mColorSpace);
dest.writeLong(mStreamUseCase);
dest.writeInt(mTimestampBase);
dest.writeInt(mMirrorMode);
@@ -1305,6 +1356,9 @@ public final class OutputConfiguration implements Parcelable {
if (mDynamicRangeProfile != other.mDynamicRangeProfile) {
return false;
}
if (mColorSpace != other.mColorSpace) {
return false;
}
return true;
}
@@ -1325,7 +1379,8 @@ public final class OutputConfiguration implements Parcelable {
mSurfaceGroupId, mSurfaceType, mIsShared ? 1 : 0,
mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode(),
mIsMultiResolution ? 1 : 0, mSensorPixelModesUsed.hashCode(),
mDynamicRangeProfile, mStreamUseCase, mTimestampBase, mMirrorMode);
mDynamicRangeProfile, mColorSpace, mStreamUseCase,
mTimestampBase, mMirrorMode);
}
return HashCodeHelpers.hashCode(
@@ -1334,7 +1389,7 @@ public final class OutputConfiguration implements Parcelable {
mConfiguredDataspace, mSurfaceGroupId, mIsShared ? 1 : 0,
mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode(),
mIsMultiResolution ? 1 : 0, mSensorPixelModesUsed.hashCode(),
mDynamicRangeProfile, mStreamUseCase, mTimestampBase,
mDynamicRangeProfile, mColorSpace, mStreamUseCase, mTimestampBase,
mMirrorMode);
}
@@ -1369,6 +1424,8 @@ public final class OutputConfiguration implements Parcelable {
private ArrayList<Integer> mSensorPixelModesUsed;
// Dynamic range profile
private long mDynamicRangeProfile;
// Color space
private int mColorSpace;
// Stream use case
private long mStreamUseCase;
// Timestamp base

View File

@@ -23,6 +23,8 @@ import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.graphics.ColorSpace;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
@@ -30,6 +32,7 @@ import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.InputConfiguration;
import android.hardware.camera2.params.OutputConfiguration;
import android.hardware.camera2.utils.HashCodeHelpers;
import android.media.ImageReader;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
@@ -94,6 +97,7 @@ public final class SessionConfiguration implements Parcelable {
private Executor mExecutor = null;
private InputConfiguration mInputConfig = null;
private CaptureRequest mSessionParameters = null;
private int mColorSpace;
/**
* Create a new {@link SessionConfiguration}.
@@ -314,4 +318,45 @@ public final class SessionConfiguration implements Parcelable {
public CaptureRequest getSessionParameters() {
return mSessionParameters;
}
/**
* Set a specific device-supported color space.
*
* <p>Clients can choose from any profile advertised as supported in
* {@link CameraCharacteristics#REQUEST_AVAILABLE_COLOR_SPACE_PROFILES}
* queried using {@link ColorSpaceProfiles#getSupportedColorSpaces}.
* When set, the colorSpace will override the default color spaces of the output targets,
* or the color space implied by the dataSpace passed into an {@link ImageReader}'s
* constructor.</p>
*/
public void setColorSpace(@NonNull ColorSpace.Named colorSpace) {
mColorSpace = colorSpace.ordinal();
for (OutputConfiguration outputConfiguration : mOutputConfigurations) {
outputConfiguration.setColorSpace(colorSpace);
}
}
/**
* Clear the color space, such that the default color space will be used.
*/
public void clearColorSpace() {
mColorSpace = ColorSpaceProfiles.UNSPECIFIED;
for (OutputConfiguration outputConfiguration : mOutputConfigurations) {
outputConfiguration.clearColorSpace();
}
}
/**
* Return the current color space.
*
* @return the currently set color space
*/
@SuppressLint("MethodNameUnits")
public @Nullable ColorSpace getColorSpace() {
if (mColorSpace != ColorSpaceProfiles.UNSPECIFIED) {
return ColorSpace.get(ColorSpace.Named.values()[mColorSpace]);
} else {
return null;
}
}
}

View File

@@ -67,4 +67,6 @@ message CameraStreamProto {
optional int64 dynamic_range_profile = 14;
// The stream use case
optional int64 stream_use_case = 15;
// The color space of the stream
optional int32 color_space = 16;
}