Merge 24Q3 (ab/11976889) to aosp-main-future
Bug: 347831320
Merged-In: I9183c2f8b1cae60b705016804cb36780513be854
Change-Id: Ifc0af2d7b44642d06e3696a35ff7c64eb1bbc785
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/AdvancedExtenderImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/AdvancedExtenderImpl.java
index 821b11f..dc99339 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/AdvancedExtenderImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/AdvancedExtenderImpl.java
@@ -18,6 +18,7 @@
import android.annotation.SuppressLint;
import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraExtensionCharacteristics;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.util.Pair;
@@ -230,6 +231,13 @@
*
* <p>For example, an extension may limit the zoom ratio range. In this case, an OEM can return
* a new zoom ratio range for the key {@link CameraCharacteristics#CONTROL_ZOOM_RATIO_RANGE}.
+ *
+ * <p> Currently, the only synthetic keys supported for override are
+ * {@link CameraCharacteristics#REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES} and
+ * {@link CameraCharacteristics#REQUEST_AVAILABLE_COLOR_SPACE_PROFILES}. To enable them, an OEM
+ * should override the respective native keys
+ * {@link CameraCharacteristics#REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP} and
+ * {@link CameraCharacteristics#REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP}.
* @since 1.5
*/
List<Pair<CameraCharacteristics.Key, Object>> getAvailableCharacteristicsKeyValues();
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/AutoAdvancedExtenderImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/AutoAdvancedExtenderImpl.java
index 06c8c44..c818386 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/AutoAdvancedExtenderImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/AutoAdvancedExtenderImpl.java
@@ -33,6 +33,8 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -62,6 +64,39 @@
AWB_MODE_DAYLIGHT);
}
+ @Override
+ public boolean isPostviewAvailable() {
+ return true;
+ }
+
+ @Override
+ public Map<Integer, List<Size>> getSupportedPostviewResolutions(Size captureSize) {
+ Map<Integer, List<Size>> res = new HashMap<>();
+ Map<Integer, List<Size>> captureSupportedResolutions =
+ getSupportedCaptureOutputResolutions(mCameraId);
+ float targetAr = ((float) captureSize.getWidth()) / captureSize.getHeight();
+
+ List<Size> currFormatSizes = captureSupportedResolutions.get(ImageFormat.YUV_420_888);
+ if (currFormatSizes != null) {
+ List<Size> postviewSizes = new ArrayList<>();
+
+ for (Size s : currFormatSizes) {
+ if ((s.equals(captureSize)) || (s.getWidth() > captureSize.getWidth())
+ || (s.getHeight() > captureSize.getHeight())) continue;
+ float currentAr = ((float) s.getWidth()) / s.getHeight();
+ if (Math.abs(targetAr - currentAr) < 0.01) {
+ postviewSizes.add(s);
+ }
+ }
+
+ if (!postviewSizes.isEmpty()) {
+ res.put(ImageFormat.YUV_420_888, postviewSizes);
+ }
+ }
+
+ return res;
+ }
+
public class AutoAdvancedSessionProcessor extends BaseAdvancedSessionProcessor {
public AutoAdvancedSessionProcessor() {
@@ -78,6 +113,11 @@
RequestBuilder build = new RequestBuilder(mCaptureOutputConfig.getId(),
CameraDevice.TEMPLATE_STILL_CAPTURE, DEFAULT_CAPTURE_ID);
build.setParameters(CaptureRequest.CONTROL_AWB_MODE, AWB_MODE_DAYLIGHT);
+
+ if (mPostviewOutputSurfaceConfig.getSurface() != null) {
+ build.addTargetOutputConfigIds(mPostviewOutputConfig.getId());
+ }
+
applyParameters(build);
requestList.add(build.build());
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/BaseAdvancedExtenderImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/BaseAdvancedExtenderImpl.java
index b97fdbd..1b61d93 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/BaseAdvancedExtenderImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/BaseAdvancedExtenderImpl.java
@@ -23,14 +23,18 @@
import android.annotation.SuppressLint;
import android.content.Context;
+import android.graphics.ColorSpace;
import android.graphics.ImageFormat;
import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraCharacteristics.Key;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.params.ColorSpaceProfiles;
+import android.hardware.camera2.params.DynamicRangeProfiles;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.hardware.DataSpace;
import android.media.Image;
@@ -57,6 +61,7 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
@SuppressLint("UnknownNullness")
public abstract class BaseAdvancedExtenderImpl implements AdvancedExtenderImpl {
@@ -70,6 +75,12 @@
}
protected CameraCharacteristics mCameraCharacteristics;
+ protected String mCameraId;
+
+ protected static final Key REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP =
+ new Key<long[]>("android.request.availableDynamicRangeProfilesMap", long[].class);
+ protected static final Key REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP =
+ new Key<long[]>("android.request.availableColorSpaceProfilesMap", long[].class);
public BaseAdvancedExtenderImpl() {
}
@@ -82,6 +93,7 @@
public void init(String cameraId,
Map<String, CameraCharacteristics> characteristicsMap) {
mCameraCharacteristics = characteristicsMap.get(cameraId);
+ mCameraId = cameraId;
}
@Override
@@ -115,12 +127,12 @@
@Override
public Map<Integer, List<Size>> getSupportedCaptureOutputResolutions(String cameraId) {
return filterOutputResolutions(Arrays.asList(ImageFormat.JPEG, ImageFormat.YUV_420_888,
- ImageFormat.JPEG_R));
+ ImageFormat.JPEG_R, ImageFormat.YCBCR_P010));
}
@Override
public Map<Integer, List<Size>> getSupportedPostviewResolutions(Size captureSize) {
- return new HashMap<>();
+ return new HashMap<Integer, List<Size>>();
}
@Override
@@ -138,22 +150,31 @@
protected Camera2OutputConfigImpl mPreviewOutputConfig;
protected Camera2OutputConfigImpl mCaptureOutputConfig;
+ protected Camera2OutputConfigImpl mPostviewOutputConfig;
protected OutputSurfaceImpl mPreviewOutputSurfaceConfig;
protected OutputSurfaceImpl mCaptureOutputSurfaceConfig;
+ protected OutputSurfaceImpl mPostviewOutputSurfaceConfig;
protected final Object mLock = new Object();
@GuardedBy("mLock")
protected Map<CaptureRequest.Key<?>, Object> mParameters = new LinkedHashMap<>();
- protected final Object mLockCaptureSurfaceImageWriter = new Object();
- @GuardedBy("mLockCaptureSurfaceImageWriter")
+ protected final Object mLockImageWriter = new Object();
+ @GuardedBy("mLockImageWriter")
protected ImageWriter mCaptureSurfaceImageWriter;
+ @GuardedBy("mLockImageWriter")
+ protected ImageWriter mPostviewSurfaceImageWriter;
+
protected CaptureResultImageMatcher mImageCaptureCaptureResultImageMatcher =
new CaptureResultImageMatcher();
+ protected CaptureResultImageMatcher mPostviewCaptureCaptureResultImageMatcher =
+ new CaptureResultImageMatcher();
protected HashMap<Integer, Pair<ImageReferenceImpl, TotalCaptureResult>> mCaptureResults =
new HashMap<>();
+ protected HashMap<Integer, Pair<ImageReferenceImpl, TotalCaptureResult>> mPostviewResults =
+ new HashMap<>();
protected RequestProcessorImpl mRequestProcessor;
protected List<Integer> mCaptureIdList = List.of(DEFAULT_CAPTURE_ID);
@@ -177,6 +198,7 @@
mPreviewOutputSurfaceConfig = surfaceConfigs.getPreviewOutputSurface();
mCaptureOutputSurfaceConfig = surfaceConfigs.getImageCaptureOutputSurface();
+ mPostviewOutputSurfaceConfig = surfaceConfigs.getPostviewOutputSurface();
Camera2SessionConfigImplBuilder builder =
new Camera2SessionConfigImplBuilder()
@@ -190,6 +212,9 @@
Camera2OutputConfigImplBuilder.newSurfaceConfig(
mPreviewOutputSurfaceConfig.getSurface());
+ previewOutputConfigBuilder.setDynamicRangeProfile(
+ mPreviewOutputSurfaceConfig.getDynamicRangeProfile());
+
mPreviewOutputConfig = previewOutputConfigBuilder.build();
builder.addOutputConfig(mPreviewOutputConfig);
@@ -198,7 +223,7 @@
// Image Capture
if (mCaptureOutputSurfaceConfig.getSurface() != null) {
- // For this sample, JPEG_R will not be processed
+ // For this sample, JPEG_R or YCBCR_P010 will not be processed
if (isJpegR(mCaptureOutputSurfaceConfig)) {
Camera2OutputConfigImplBuilder captureOutputConfigBuilder;
@@ -210,6 +235,20 @@
builder.addOutputConfig(mCaptureOutputConfig);
mProcessCapture = false;
+ } else if (mCaptureOutputSurfaceConfig.getImageFormat() == ImageFormat.YCBCR_P010) {
+ Camera2OutputConfigImplBuilder captureOutputConfigBuilder;
+
+ captureOutputConfigBuilder =
+ Camera2OutputConfigImplBuilder.newSurfaceConfig(
+ mCaptureOutputSurfaceConfig.getSurface());
+
+ captureOutputConfigBuilder.setDynamicRangeProfile(
+ mCaptureOutputSurfaceConfig.getDynamicRangeProfile());
+
+ mCaptureOutputConfig = captureOutputConfigBuilder.build();
+
+ builder.addOutputConfig(mCaptureOutputConfig);
+ mProcessCapture = false;
} else {
Camera2OutputConfigImplBuilder captureOutputConfigBuilder;
@@ -226,6 +265,23 @@
}
}
+ // Postview
+ if (mPostviewOutputSurfaceConfig.getSurface() != null) {
+ Camera2OutputConfigImplBuilder postviewOutputConfigBuilder;
+
+ postviewOutputConfigBuilder =
+ Camera2OutputConfigImplBuilder.newImageReaderConfig(
+ mPostviewOutputSurfaceConfig.getSize(),
+ ImageFormat.YUV_420_888,
+ BASIC_CAPTURE_PROCESS_MAX_IMAGES,
+ mPostviewOutputSurfaceConfig.getUsage());
+
+ mPostviewOutputConfig = postviewOutputConfigBuilder.build();
+
+ builder.addOutputConfig(mPostviewOutputConfig);
+ }
+
+ builder.setColorSpace(surfaceConfigs.getColorSpace());
addSessionParameter(builder);
return builder.build();
@@ -255,11 +311,16 @@
@Override
public void deInitSession() {
- synchronized (mLockCaptureSurfaceImageWriter) {
+ synchronized (mLockImageWriter) {
if (mCaptureSurfaceImageWriter != null) {
mCaptureSurfaceImageWriter.close();
mCaptureSurfaceImageWriter = null;
}
+
+ if (mPostviewSurfaceImageWriter != null) {
+ mPostviewSurfaceImageWriter.close();
+ mPostviewSurfaceImageWriter = null;
+ }
}
}
@@ -373,30 +434,39 @@
mRequestProcessor = requestProcessor;
if (mCaptureOutputSurfaceConfig.getSurface() != null) {
- synchronized (mLockCaptureSurfaceImageWriter) {
- if (isJpegR(mCaptureOutputSurfaceConfig)) {
- return;
+ synchronized (mLockImageWriter) {
+ if (mProcessCapture) {
+ if (isJpeg(mCaptureOutputSurfaceConfig)) {
+ mCaptureSurfaceImageWriter = new ImageWriter
+ .Builder(mCaptureOutputSurfaceConfig.getSurface())
+ .setImageFormat(ImageFormat.JPEG)
+ .setMaxImages(MAX_NUM_IMAGES)
+ // For JPEG format, width x height should be set to (w*h) x 1
+ // since the JPEG image is returned as a 1D byte array
+ .setWidthAndHeight(
+ mCaptureOutputSurfaceConfig.getSize().getWidth()
+ * mCaptureOutputSurfaceConfig.getSize().getHeight(),
+ 1)
+ .build();
+ } else {
+ mCaptureSurfaceImageWriter = new ImageWriter
+ .Builder(mCaptureOutputSurfaceConfig.getSurface())
+ .setImageFormat(mCaptureOutputSurfaceConfig.getImageFormat())
+ .setMaxImages(MAX_NUM_IMAGES)
+ .build();
+ }
}
+ }
+ }
- if (isJpeg(mCaptureOutputSurfaceConfig)) {
- mCaptureSurfaceImageWriter = new ImageWriter
- .Builder(mCaptureOutputSurfaceConfig.getSurface())
- .setImageFormat(ImageFormat.JPEG)
- .setMaxImages(MAX_NUM_IMAGES)
- // For JPEG format, width x height should be set to (w*h) x 1
- // since the JPEG image is returned as a 1D byte array
- .setWidthAndHeight(
- mCaptureOutputSurfaceConfig.getSize().getWidth()
- * mCaptureOutputSurfaceConfig.getSize().getHeight(),
- 1)
- .build();
- } else {
- mCaptureSurfaceImageWriter = new ImageWriter
- .Builder(mCaptureOutputSurfaceConfig.getSurface())
- .setImageFormat(mCaptureOutputSurfaceConfig.getImageFormat())
- .setMaxImages(MAX_NUM_IMAGES)
- .build();
- }
+ if (mPostviewOutputSurfaceConfig != null
+ && mPostviewOutputSurfaceConfig.getSurface() != null) {
+ synchronized (mLockImageWriter) {
+ mPostviewSurfaceImageWriter = new ImageWriter
+ .Builder(mPostviewOutputSurfaceConfig.getSurface())
+ .setImageFormat(mPostviewOutputSurfaceConfig.getImageFormat())
+ .setMaxImages(MAX_NUM_IMAGES)
+ .build();
}
}
}
@@ -405,6 +475,7 @@
public void onCaptureSessionEnd() {
synchronized (this) {
mImageCaptureCaptureResultImageMatcher.clear();
+ mPostviewCaptureCaptureResultImageMatcher.clear();
}
mRequestProcessor = null;
@@ -498,6 +569,7 @@
@Override
public int startCaptureWithPostview(@NonNull CaptureCallback captureCallback) {
+ Log.d(TAG, "startCaptureWithPostview");
return startCapture(captureCallback);
}
@@ -529,6 +601,12 @@
addCaptureResultKeys(seqId, totalCaptureResult, captureCallback);
+ if (mPostviewOutputSurfaceConfig != null) {
+ mPostviewCaptureCaptureResultImageMatcher.setCameraCaptureCallback(
+ totalCaptureResult,
+ requestProcessorRequest.getCaptureStageId());
+ }
+
if (!mProcessCapture) {
captureCallback.onCaptureProcessStarted(seqId);
} else {
@@ -566,6 +644,33 @@
mRequestProcessor.submit(requestList, callback);
+ if (mPostviewOutputSurfaceConfig != null &&
+ mPostviewOutputSurfaceConfig.getSurface() != null) {
+ mRequestProcessor.setImageProcessor(mPostviewOutputConfig.getId(),
+ new ImageProcessorImpl() {
+ @Override
+ public void onNextImageAvailable(int outputStreamId,
+ long timestampNs,
+ @NonNull ImageReferenceImpl imgReferenceImpl,
+ @Nullable String physicalCameraId) {
+ mPostviewCaptureCaptureResultImageMatcher
+ .setInputImage(imgReferenceImpl);
+ }
+ });
+
+ mPostviewCaptureCaptureResultImageMatcher.setImageReferenceListener(
+ new CaptureResultImageMatcher.ImageReferenceListener() {
+ @Override
+ public void onImageReferenceIncoming(
+ @NonNull ImageReferenceImpl imageReferenceImpl,
+ @NonNull TotalCaptureResult totalCaptureResult,
+ int captureId) {
+ processImageCapture(imageReferenceImpl, totalCaptureResult,
+ captureId, true /*isPostview*/);
+ }
+ });
+ }
+
if (mCaptureOutputSurfaceConfig.getSurface() != null && mProcessCapture) {
mRequestProcessor.setImageProcessor(mCaptureOutputConfig.getId(),
new ImageProcessorImpl() {
@@ -588,7 +693,7 @@
int captureId) {
captureCallback.onCaptureProcessStarted(seqId);
processImageCapture(imageReferenceImpl, totalCaptureResult,
- captureId);
+ captureId, false /*isPostview*/);
}
});
}
@@ -597,20 +702,25 @@
}
protected void processImageCapture(@NonNull ImageReferenceImpl imageReferenceImpl,
- @NonNull TotalCaptureResult totalCaptureResult,
- int captureId) {
+ @NonNull TotalCaptureResult totalCaptureResult, int captureId,
+ boolean isPostview) {
- mCaptureResults.put(captureId, new Pair<>(imageReferenceImpl, totalCaptureResult));
+ HashMap<Integer, Pair<ImageReferenceImpl, TotalCaptureResult>> captureResults =
+ isPostview ? mPostviewResults : mCaptureResults;
+ ImageWriter imageWriter = isPostview ? mPostviewSurfaceImageWriter :
+ mCaptureSurfaceImageWriter;
- if (mCaptureResults.keySet().containsAll(mCaptureIdList)) {
+ captureResults.put(captureId, new Pair<>(imageReferenceImpl, totalCaptureResult));
+
+ if (captureResults.keySet().containsAll(mCaptureIdList)) {
List<Pair<ImageReferenceImpl, TotalCaptureResult>> imageDataPairs =
- new ArrayList<>(mCaptureResults.values());
+ new ArrayList<>(captureResults.values());
Image resultImage = null;
int captureSurfaceWriterImageFormat = ImageFormat.UNKNOWN;
- synchronized (mLockCaptureSurfaceImageWriter) {
- resultImage = mCaptureSurfaceImageWriter.dequeueInputImage();
- captureSurfaceWriterImageFormat = mCaptureSurfaceImageWriter.getFormat();
+ synchronized (mLockImageWriter) {
+ resultImage = imageWriter.dequeueInputImage();
+ captureSurfaceWriterImageFormat = imageWriter.getFormat();
}
if (captureSurfaceWriterImageFormat == ImageFormat.JPEG) {
@@ -648,11 +758,11 @@
DEFAULT_CAPTURE_ID).first.get().getTimestamp());
}
- synchronized (mLockCaptureSurfaceImageWriter) {
- mCaptureSurfaceImageWriter.queueInputImage(resultImage);
+ synchronized (mLockImageWriter) {
+ imageWriter.queueInputImage(resultImage);
}
- for (Pair<ImageReferenceImpl, TotalCaptureResult> val : mCaptureResults.values()) {
+ for (Pair<ImageReferenceImpl, TotalCaptureResult> val : captureResults.values()) {
val.first.decrement();
}
} else {
@@ -742,18 +852,62 @@
@Override
public List<Pair<CameraCharacteristics.Key, Object>> getAvailableCharacteristicsKeyValues() {
+ int[] caps = mCameraCharacteristics
+ .get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
+
+ Set<Integer> unsupportedCapabilities = new HashSet<>(Arrays.asList(
+ CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT,
+ CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_RAW,
+ CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING,
+ CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING,
+ CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO,
+ CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING,
+ CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING,
+ CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME,
+ CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA,
+ CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_SYSTEM_CAMERA,
+ CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR
+ ));
+
+ List<Integer> filtered = new ArrayList<>();
+ for (int c : caps) {
+ if (unsupportedCapabilities.contains(c)) {
+ continue;
+ }
+ filtered.add(c);
+ }
+ int[] extensionsCaps = new int[filtered.size()];
+ for (int i = 0; i < filtered.size(); i++) {
+ extensionsCaps[i] = filtered.get(i);
+ }
+
+ long[] dynamicRangeProfileArray = new long[]{
+ DynamicRangeProfiles.HLG10,
+ DynamicRangeProfiles.HLG10 | DynamicRangeProfiles.STANDARD,
+ 0L};
+ long[] colorSpacesProfileArray = new long[]{
+ ColorSpace.Named.BT2020_HLG.ordinal(),
+ ImageFormat.YCBCR_P010,
+ DynamicRangeProfiles.HLG10};
+
Range<Float> zoomRange = mCameraCharacteristics
.get(CameraCharacteristics.CONTROL_ZOOM_RATIO_RANGE);
float zoomRangeLower = Math.max(1f, zoomRange.getLower());
float zoomRangeUpper = Math.min(10f, zoomRange.getUpper());
return Arrays.asList(
+ Pair.create(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES,
+ extensionsCaps),
Pair.create(CameraCharacteristics.CONTROL_ZOOM_RATIO_RANGE,
Range.create(zoomRangeLower, zoomRangeUpper)),
Pair.create(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES,
new int[]{
CameraMetadata.CONTROL_AF_MODE_OFF,
CameraMetadata.CONTROL_AF_MODE_AUTO
- })
+ }),
+ Pair.create(REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP,
+ dynamicRangeProfileArray),
+ Pair.create(REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP,
+ colorSpacesProfileArray)
);
}
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2OutputConfigImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2OutputConfigImpl.java
index 68de01b..fe0cddf 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2OutputConfigImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2OutputConfigImpl.java
@@ -17,6 +17,7 @@
package androidx.camera.extensions.impl.advanced;
import android.annotation.SuppressLint;
+import android.hardware.camera2.params.DynamicRangeProfiles;
import java.util.List;
@@ -44,6 +45,15 @@
String getPhysicalCameraId();
/**
+ * Gets the dynamic range profile.
+ *
+ * @since 1.5
+ */
+ default long getDynamicRangeProfile() {
+ return DynamicRangeProfiles.STANDARD;
+ }
+
+ /**
* If non-null, enable surface sharing and add the surface constructed by the return
* Camera2OutputConfig.
*/
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2OutputConfigImplBuilder.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2OutputConfigImplBuilder.java
index 9ae5f83..95cd48d 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2OutputConfigImplBuilder.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2OutputConfigImplBuilder.java
@@ -17,6 +17,7 @@
package androidx.camera.extensions.impl.advanced;
import android.annotation.SuppressLint;
+import android.hardware.camera2.params.DynamicRangeProfiles;
import android.hardware.camera2.params.OutputConfiguration;
import android.util.Size;
import android.view.Surface;
@@ -35,6 +36,7 @@
private int mSurfaceGroupId = OutputConfiguration.SURFACE_GROUP_ID_NONE;
private String mPhysicalCameraId;
private List<Camera2OutputConfigImpl> mSurfaceSharingConfigs;
+ private long mDynamicRangeProfile = DynamicRangeProfiles.STANDARD;
private Camera2OutputConfigImplBuilder(OutputConfigImplImpl outputConfig) {
mOutputConfig = outputConfig;
@@ -93,6 +95,14 @@
}
/**
+ * Set dynamic range profile.
+ */
+ public Camera2OutputConfigImplBuilder setDynamicRangeProfile(long dynamicRangeProfile) {
+ mDynamicRangeProfile = dynamicRangeProfile;
+ return this;
+ }
+
+ /**
* Sets surface group id.
*/
public Camera2OutputConfigImplBuilder setSurfaceGroupId(int surfaceGroupId) {
@@ -108,6 +118,7 @@
mOutputConfig.setPhysicalCameraId(mPhysicalCameraId);
mOutputConfig.setSurfaceGroup(mSurfaceGroupId);
mOutputConfig.setSurfaceSharingConfigs(mSurfaceSharingConfigs);
+ mOutputConfig.setDynamicRangeProfile(mDynamicRangeProfile);
return mOutputConfig;
}
@@ -115,6 +126,7 @@
private int mId;
private int mSurfaceGroup;
private String mPhysicalCameraId;
+ private long mDynamicRangeProfile;
private List<Camera2OutputConfigImpl> mSurfaceSharingConfigs;
OutputConfigImplImpl() {
@@ -122,6 +134,7 @@
mSurfaceGroup = 0;
mPhysicalCameraId = null;
mSurfaceSharingConfigs = null;
+ mDynamicRangeProfile = DynamicRangeProfiles.STANDARD;
}
@Override
@@ -140,6 +153,11 @@
}
@Override
+ public long getDynamicRangeProfile() {
+ return mDynamicRangeProfile;
+ }
+
+ @Override
public List<Camera2OutputConfigImpl> getSurfaceSharingOutputConfigs() {
return mSurfaceSharingConfigs;
}
@@ -156,6 +174,10 @@
mPhysicalCameraId = physicalCameraId;
}
+ public void setDynamicRangeProfile(long dynamicRangeProfile) {
+ mDynamicRangeProfile = dynamicRangeProfile;
+ }
+
public void setSurfaceSharingConfigs(
List<Camera2OutputConfigImpl> surfaceSharingConfigs) {
mSurfaceSharingConfigs = surfaceSharingConfigs;
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImpl.java
index 6fb45bc..0b7d59b 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImpl.java
@@ -18,6 +18,7 @@
import android.annotation.SuppressLint;
import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.params.ColorSpaceProfiles;
import java.util.List;
import java.util.Map;
@@ -54,4 +55,14 @@
* will be configured to use the default regular type.
*/
int getSessionType();
+
+ /**
+ * Gets the color space.
+ *
+ * @since 1.5
+ * @return {@link android.graphics#ColorSpace.Named} set for session configuration
+ */
+ default int getColorSpace() {
+ return ColorSpaceProfiles.UNSPECIFIED;
+ }
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java
index dc1fecc..e745624 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java
@@ -20,6 +20,7 @@
import android.annotation.SuppressLint;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.params.ColorSpaceProfiles;
import android.hardware.camera2.params.SessionConfiguration;
import java.util.ArrayList;
@@ -33,6 +34,7 @@
@SuppressLint("UnknownNullness")
public class Camera2SessionConfigImplBuilder {
private int mSessionTemplateId = CameraDevice.TEMPLATE_PREVIEW;
+ private int mColorSpace = ColorSpaceProfiles.UNSPECIFIED;
private int mSessionType = SessionConfiguration.SESSION_REGULAR;
Map<CaptureRequest.Key<?>, Object> mSessionParameters = new HashMap<>();
List<Camera2OutputConfigImpl> mCamera2OutputConfigs = new ArrayList<>();
@@ -67,6 +69,21 @@
}
/**
+ * Sets the color space.
+ */
+ public Camera2SessionConfigImplBuilder setColorSpace(int colorSpace) {
+ mColorSpace = colorSpace;
+ return this;
+ }
+
+ /**
+ * Gets the color space.
+ */
+ public int getColorSpace() {
+ return mColorSpace;
+ }
+
+ /**
* Gets the session template id.
*/
public int getSessionTemplateId() {
@@ -105,12 +122,14 @@
Camera2SessionConfigImpl {
int mSessionTemplateId;
int mSessionType;
+ int mColorSpace = ColorSpaceProfiles.UNSPECIFIED;
Map<CaptureRequest.Key<?>, Object> mSessionParameters;
List<Camera2OutputConfigImpl> mCamera2OutputConfigs;
Camera2SessionConfigImplImpl(Camera2SessionConfigImplBuilder builder) {
mSessionTemplateId = builder.getSessionTemplateId();
mSessionParameters = builder.getSessionParameters();
+ mColorSpace = builder.getColorSpace();
mCamera2OutputConfigs = builder.getCamera2OutputConfigs();
mSessionType = builder.getSessionType();
}
@@ -134,6 +153,11 @@
public int getSessionType() {
return mSessionType;
}
+
+ @Override
+ public int getColorSpace() {
+ return mColorSpace;
+ }
}
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/HdrAdvancedExtenderImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/HdrAdvancedExtenderImpl.java
index 68a84b7..1a3a099 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/HdrAdvancedExtenderImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/HdrAdvancedExtenderImpl.java
@@ -247,7 +247,7 @@
Image resultImage = null;
int captureSurfaceWriterImageFormat = ImageFormat.UNKNOWN;
- synchronized (mLockCaptureSurfaceImageWriter) {
+ synchronized (mLockImageWriter) {
resultImage = mCaptureSurfaceImageWriter.dequeueInputImage();
captureSurfaceWriterImageFormat = mCaptureSurfaceImageWriter.getFormat();
}
@@ -290,7 +290,7 @@
UNDER_EXPOSED_CAPTURE_ID).first.get().getTimestamp());
}
- synchronized (mLockCaptureSurfaceImageWriter) {
+ synchronized (mLockImageWriter) {
mCaptureSurfaceImageWriter.queueInputImage(resultImage);
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/NightAdvancedExtenderImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/NightAdvancedExtenderImpl.java
index ba4ea4c..86ea363 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/NightAdvancedExtenderImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/NightAdvancedExtenderImpl.java
@@ -27,6 +27,7 @@
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.params.DynamicRangeProfiles;
import android.media.Image;
import android.media.Image.Plane;
import android.media.ImageWriter;
@@ -39,6 +40,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -70,6 +72,8 @@
public class NightAdvancedSessionProcessor extends BaseAdvancedSessionProcessor {
+ protected boolean mProcessPreview = true;
+
public NightAdvancedSessionProcessor() {
appendTag("::Night");
}
@@ -101,12 +105,23 @@
if (mPreviewOutputSurfaceConfig.getSurface() != null) {
Camera2OutputConfigImplBuilder previewOutputConfigBuilder;
- previewOutputConfigBuilder =
- Camera2OutputConfigImplBuilder.newImageReaderConfig(
- mPreviewOutputSurfaceConfig.getSize(),
- ImageFormat.YUV_420_888,
- BASIC_CAPTURE_PROCESS_MAX_IMAGES,
- mPreviewOutputSurfaceConfig.getUsage());
+ if (mPreviewOutputSurfaceConfig.getDynamicRangeProfile() ==
+ DynamicRangeProfiles.STANDARD) {
+ previewOutputConfigBuilder =
+ Camera2OutputConfigImplBuilder.newImageReaderConfig(
+ mPreviewOutputSurfaceConfig.getSize(),
+ ImageFormat.YUV_420_888,
+ BASIC_CAPTURE_PROCESS_MAX_IMAGES,
+ mPreviewOutputSurfaceConfig.getUsage());
+ } else {
+ previewOutputConfigBuilder =
+ Camera2OutputConfigImplBuilder.newSurfaceConfig(
+ mPreviewOutputSurfaceConfig.getSurface());
+ previewOutputConfigBuilder.setDynamicRangeProfile(
+ mPreviewOutputSurfaceConfig.getDynamicRangeProfile());
+
+ mProcessPreview = false;
+ }
mPreviewOutputConfig = previewOutputConfigBuilder.build();
@@ -116,7 +131,7 @@
// Image Capture
if (mCaptureOutputSurfaceConfig.getSurface() != null) {
- // For this sample, JPEG_R will not be processed
+ // For this sample, JPEG_R or YCBCR_P010 will not be processed
if (isJpegR(mCaptureOutputSurfaceConfig)) {
Camera2OutputConfigImplBuilder captureOutputConfigBuilder;
@@ -128,6 +143,20 @@
builder.addOutputConfig(mCaptureOutputConfig);
mProcessCapture = false;
+ } else if (mCaptureOutputSurfaceConfig.getImageFormat() == ImageFormat.YCBCR_P010) {
+ Camera2OutputConfigImplBuilder captureOutputConfigBuilder;
+
+ captureOutputConfigBuilder =
+ Camera2OutputConfigImplBuilder.newSurfaceConfig(
+ mCaptureOutputSurfaceConfig.getSurface());
+
+ captureOutputConfigBuilder.setDynamicRangeProfile(
+ mCaptureOutputSurfaceConfig.getDynamicRangeProfile());
+
+ mCaptureOutputConfig = captureOutputConfigBuilder.build();
+
+ builder.addOutputConfig(mCaptureOutputConfig);
+ mProcessCapture = false;
} else {
Camera2OutputConfigImplBuilder captureOutputConfigBuilder;
@@ -144,6 +173,7 @@
}
}
+ builder.setColorSpace(surfaceConfigs.getColorSpace());
addSessionParameter(builder);
return builder.build();
@@ -170,6 +200,10 @@
public void onCaptureSessionStart(@NonNull RequestProcessorImpl requestProcessor) {
super.onCaptureSessionStart(requestProcessor);
+ if (!mProcessPreview) {
+ return;
+ }
+
if (mPreviewOutputSurfaceConfig.getSurface() != null) {
synchronized (mLockPreviewSurfaceImageWriter) {
mPreviewSurfaceImageWriter = new ImageWriter
@@ -246,8 +280,10 @@
addCaptureResultKeys(seqId, totalCaptureResult, captureCallback);
- mCaptureResultImageMatcher.setCameraCaptureCallback(
- totalCaptureResult);
+ if (mProcessPreview) {
+ mCaptureResultImageMatcher.setCameraCaptureCallback(
+ totalCaptureResult);
+ }
captureCallback.onCaptureProcessStarted(seqId);
}
@@ -295,4 +331,22 @@
public SessionProcessorImpl createSessionProcessor() {
return new NightAdvancedSessionProcessor();
}
+
+ @Override
+ public List<CaptureRequest.Key> getAvailableCaptureRequestKeys() {
+ final CaptureRequest.Key [] CAPTURE_REQUEST_SET = {CaptureRequest.CONTROL_ZOOM_RATIO,
+ CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_REGIONS,
+ CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.JPEG_QUALITY,
+ CaptureRequest.JPEG_ORIENTATION};
+ return Arrays.asList(CAPTURE_REQUEST_SET);
+ }
+
+ @Override
+ public List<CaptureResult.Key> getAvailableCaptureResultKeys() {
+ final CaptureResult.Key [] CAPTURE_RESULT_SET = {CaptureResult.CONTROL_ZOOM_RATIO,
+ CaptureResult.CONTROL_AF_MODE, CaptureResult.CONTROL_AF_REGIONS,
+ CaptureResult.CONTROL_AF_TRIGGER, CaptureResult.CONTROL_AF_STATE,
+ CaptureResult.JPEG_QUALITY, CaptureResult.JPEG_ORIENTATION};
+ return Arrays.asList(CAPTURE_RESULT_SET);
+ }
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/OutputSurfaceConfigurationImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/OutputSurfaceConfigurationImpl.java
index ca3832e..8fe3514 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/OutputSurfaceConfigurationImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/OutputSurfaceConfigurationImpl.java
@@ -17,6 +17,7 @@
package androidx.camera.extensions.impl.advanced;
import android.annotation.SuppressLint;
+import android.hardware.camera2.params.ColorSpaceProfiles;
/**
* For specifying the output surface configurations for the extension.
@@ -32,4 +33,13 @@
public OutputSurfaceImpl getImageAnalysisOutputSurface();
public OutputSurfaceImpl getPostviewOutputSurface();
+
+ /*
+ * Gets the color space.
+ *
+ * @since 1.5
+ */
+ default int getColorSpace() {
+ return ColorSpaceProfiles.UNSPECIFIED;
+ }
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/OutputSurfaceImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/OutputSurfaceImpl.java
index f173c1b..33759b0 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/OutputSurfaceImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/OutputSurfaceImpl.java
@@ -17,6 +17,7 @@
package androidx.camera.extensions.impl.advanced;
import android.annotation.SuppressLint;
+import android.hardware.camera2.params.DynamicRangeProfiles;
import android.util.Size;
import android.view.Surface;
@@ -49,4 +50,13 @@
* Get the surface usage bits.
*/
long getUsage();
+
+ /**
+ * Gets the dynamic range profile.
+ *
+ * @since 1.5
+ */
+ default long getDynamicRangeProfile() {
+ return DynamicRangeProfiles.STANDARD;
+ }
}
diff --git a/camera2/extensions/eyesFreeVidSample/Android.bp b/camera2/extensions/eyesFreeVidSample/Android.bp
index 3d9567e..d555190 100644
--- a/camera2/extensions/eyesFreeVidSample/Android.bp
+++ b/camera2/extensions/eyesFreeVidSample/Android.bp
@@ -20,8 +20,19 @@
name: "EyesFreeVidService",
srcs: ["src/**/*.java"],
static_libs: [
- "androidx.annotation_annotation"
+ "androidx.annotation_annotation",
],
platform_apis: true,
- system_ext_specific: true
+ system_ext_specific: true,
+ required: ["privapp-permissions-efv.xml"],
+ privileged: true,
+ certificate: "platform",
+}
+
+prebuilt_etc {
+ name: "privapp-permissions-efv.xml",
+ system_ext_specific: true,
+ sub_dir: "permissions",
+ src: "privapp-permissions-efv.xml",
+ filename_from_src: true,
}
diff --git a/camera2/extensions/eyesFreeVidSample/AndroidManifest.xml b/camera2/extensions/eyesFreeVidSample/AndroidManifest.xml
index 1e53b09..6cf1d91 100644
--- a/camera2/extensions/eyesFreeVidSample/AndroidManifest.xml
+++ b/camera2/extensions/eyesFreeVidSample/AndroidManifest.xml
@@ -2,6 +2,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.camera.extensions.impl.service">
+ <uses-permission android:name="android.permission.SYSTEM_CAMERA" />
+ <uses-permission android:name="android.permission.CAMERA" />
+
<application
android:defaultToDeviceProtectedStorage="true"
android:forceQueryable="true"
diff --git a/camera2/extensions/eyesFreeVidSample/privapp-permissions-efv.xml b/camera2/extensions/eyesFreeVidSample/privapp-permissions-efv.xml
new file mode 100644
index 0000000..87a5bd6
--- /dev/null
+++ b/camera2/extensions/eyesFreeVidSample/privapp-permissions-efv.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2016 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
+ -->
+
+<!--
+This XML file declares which signature|privileged permissions should be granted to privileged
+applications that come with the platform
+-->
+<permissions>
+ <privapp-permissions package="android.camera.extensions.impl.service">
+ <permission name="android.permission.SYSTEM_CAMERA"/>
+ </privapp-permissions>
+</permissions>
\ No newline at end of file
diff --git a/camera2/extensions/eyesFreeVidSample/src/android/camera/extensions/impl/service/EyesFreeVidService.java b/camera2/extensions/eyesFreeVidSample/src/android/camera/extensions/impl/service/EyesFreeVidService.java
index d175c1a..496ead1 100644
--- a/camera2/extensions/eyesFreeVidSample/src/android/camera/extensions/impl/service/EyesFreeVidService.java
+++ b/camera2/extensions/eyesFreeVidSample/src/android/camera/extensions/impl/service/EyesFreeVidService.java
@@ -25,8 +25,10 @@
import java.util.Set;
import android.annotation.FlaggedApi;
+import android.graphics.ColorSpace;
import android.graphics.ImageFormat;
import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraCharacteristics.Key;
import android.hardware.camera2.CameraExtensionCharacteristics;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
@@ -38,6 +40,8 @@
import android.hardware.camera2.extension.CameraExtensionService;
import android.hardware.camera2.extension.CharacteristicsMap;
import android.hardware.camera2.extension.SessionProcessor;
+import android.hardware.camera2.params.ColorSpaceProfiles;
+import android.hardware.camera2.params.DynamicRangeProfiles;
import android.hardware.camera2.params.StreamConfiguration;
import android.hardware.camera2.params.StreamConfigurationDuration;
import android.hardware.camera2.params.StreamConfigurationMap;
@@ -50,7 +54,7 @@
import com.android.internal.camera.flags.Flags;
-@FlaggedApi(Flags.FLAG_CONCERT_MODE)
+@FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
public class EyesFreeVidService extends CameraExtensionService {
private static final String TAG = "EyesFreeVidService";
@@ -60,7 +64,12 @@
private final Set<IBinder> mAttachedClients = new HashSet<>();
CameraManager mCameraManager;
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ protected static final Key REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP =
+ new Key<long[]>("android.request.availableDynamicRangeProfilesMap", long[].class);
+ protected static final Key REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP =
+ new Key<long[]>("android.request.availableColorSpaceProfilesMap", long[].class);
+
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public boolean onRegisterClient(IBinder token) {
synchronized (mLock) {
@@ -72,7 +81,7 @@
}
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public void onUnregisterClient(IBinder token) {
synchronized (mLock) {
@@ -80,7 +89,7 @@
}
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public AdvancedExtender onInitializeAdvancedExtension(int extensionType) {
mCameraManager = getSystemService(CameraManager.class);
@@ -93,29 +102,29 @@
}
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
public static class AdvancedExtenderEyesFreeImpl extends AdvancedExtender {
private CameraCharacteristics mCameraCharacteristics;
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
public AdvancedExtenderEyesFreeImpl(@NonNull CameraManager cameraManager) {
super(cameraManager);
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public boolean isExtensionAvailable(String cameraId,
CharacteristicsMap charsMap) {
return true;
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public void initialize(String cameraId, CharacteristicsMap map) {
mCameraCharacteristics = map.get(cameraId);
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public Map<Integer, List<Size>> getSupportedPreviewOutputResolutions(
String cameraId) {
@@ -144,21 +153,21 @@
return mCameraCharacteristics;
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public Map<Integer, List<Size>> getSupportedCaptureOutputResolutions(
String cameraId) {
return filterOutputResolutions(Arrays.asList(ImageFormat.YUV_420_888,
- ImageFormat.JPEG));
+ ImageFormat.JPEG, ImageFormat.JPEG_R, ImageFormat.YCBCR_P010));
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public SessionProcessor getSessionProcessor() {
return new EyesFreeVidSessionProcessor(this);
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public List<CaptureRequest.Key> getAvailableCaptureRequestKeys(
String cameraId) {
@@ -174,7 +183,7 @@
return Arrays.asList(CAPTURE_REQUEST_SET);
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public List<CaptureResult.Key> getAvailableCaptureResultKeys(
String cameraId) {
@@ -272,6 +281,15 @@
new StreamConfigurationDuration[tmpStallDurations.size()];
filteredStallDurations = tmpStallDurations.toArray(filteredStallDurations);
+ long[] dynamicRangeProfileArray = new long[]{
+ DynamicRangeProfiles.HLG10,
+ DynamicRangeProfiles.HLG10 | DynamicRangeProfiles.STANDARD,
+ 0L};
+ long[] colorSpacesProfileArray = new long[]{
+ ColorSpace.Named.BT2020_HLG.ordinal(),
+ ImageFormat.YCBCR_P010,
+ DynamicRangeProfiles.HLG10};
+
return Arrays.asList(
Pair.create(CameraCharacteristics.SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
filteredConfigurations),
@@ -293,33 +311,37 @@
.CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION
}),
Pair.create(CameraExtensionCharacteristics.EFV_PADDING_ZOOM_FACTOR_RANGE,
- new Range<Float>(1.0f, 2.0f))
+ new Range<Float>(1.0f, 2.0f)),
+ Pair.create(REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP,
+ dynamicRangeProfileArray),
+ Pair.create(REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP,
+ colorSpacesProfileArray)
);
}
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
public static class AdvancedExtenderImpl extends AdvancedExtender {
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
public AdvancedExtenderImpl(@NonNull CameraManager cameraManager) {
super(cameraManager);
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public boolean isExtensionAvailable(String cameraId,
CharacteristicsMap charsMap) {
return false;
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public void initialize(String cameraId, CharacteristicsMap map) {
throw new RuntimeException("Extension not supported");
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public Map<Integer, List<Size>> getSupportedPreviewOutputResolutions(
String cameraId) {
@@ -334,20 +356,20 @@
throw new RuntimeException("Extension not supported");
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public Map<Integer, List<Size>> getSupportedCaptureOutputResolutions(
String cameraId) {
throw new RuntimeException("Extension not supported");
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public SessionProcessor getSessionProcessor() {
throw new RuntimeException("Extension not supported");
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public List<CaptureRequest.Key> getAvailableCaptureRequestKeys(
String cameraId) {
@@ -355,7 +377,7 @@
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public List<CaptureResult.Key> getAvailableCaptureResultKeys(
String cameraId) {
diff --git a/camera2/extensions/eyesFreeVidSample/src/android/camera/extensions/impl/service/EyesFreeVidSessionProcessor.java b/camera2/extensions/eyesFreeVidSample/src/android/camera/extensions/impl/service/EyesFreeVidSessionProcessor.java
index 92f371f..9158792 100644
--- a/camera2/extensions/eyesFreeVidSample/src/android/camera/extensions/impl/service/EyesFreeVidSessionProcessor.java
+++ b/camera2/extensions/eyesFreeVidSample/src/android/camera/extensions/impl/service/EyesFreeVidSessionProcessor.java
@@ -28,6 +28,7 @@
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.camera.extensions.impl.service.EyesFreeVidService.AdvancedExtenderEyesFreeImpl;
+import android.graphics.ImageFormat;
import android.graphics.PointF;
import android.graphics.Rect;
import android.hardware.camera2.CameraAccessException;
@@ -61,7 +62,7 @@
import java.util.concurrent.atomic.AtomicBoolean;
-@FlaggedApi(Flags.FLAG_CONCERT_MODE)
+@FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
public class EyesFreeVidSessionProcessor extends SessionProcessor {
private static final String TAG = "EyesFreeVidSessionProcessor";
@@ -93,12 +94,12 @@
protected AtomicBoolean mOnCaptureSessionEndStarted = new AtomicBoolean(false);
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
protected EyesFreeVidSessionProcessor(AdvancedExtenderEyesFreeImpl advancedExtender) {
mAdvancedExtender = advancedExtender;
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
public ExtensionConfiguration initSession(@NonNull IBinder token,
@NonNull String cameraId, @NonNull CharacteristicsMap map,
@NonNull CameraOutputSurface previewSurface,
@@ -126,9 +127,10 @@
previewSurface.getSize().getHeight(), previewSurface.getImageFormat(),
MAX_NUM_IMAGES, SurfaceUtils.getSurfaceUsage(previewSurface.getSurface()));
- List<CameraOutputSurface> previewList = new ArrayList<>(List.of(
- new CameraOutputSurface(mPreviewImageReader.getSurface(),
- previewSurface.getSize())));
+ CameraOutputSurface previewOutputSurface = new CameraOutputSurface(
+ mPreviewImageReader.getSurface(), previewSurface.getSize());
+ previewOutputSurface.setDynamicRangeProfile(previewSurface.getDynamicRangeProfile());
+ List<CameraOutputSurface> previewList = new ArrayList<>(List.of(previewOutputSurface));
ExtensionOutputConfiguration previewConfig = new ExtensionOutputConfiguration(
previewList, PREVIEW_OUTPUT_ID, null, -1);
@@ -138,10 +140,15 @@
ExtensionConfiguration res = new ExtensionConfiguration(0 /*session type*/,
CameraDevice.TEMPLATE_PREVIEW, outputs, null);
+ if (imageCaptureSurface != null
+ && imageCaptureSurface.getImageFormat() == ImageFormat.YCBCR_P010) {
+ res.setColorSpace(imageCaptureSurface.getColorSpace());
+ }
+
return res;
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public void deInitSession(@NonNull IBinder token) {
if (mPreviewImageReader != null) {
@@ -163,7 +170,7 @@
}
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public void onCaptureSessionStart(@NonNull RequestProcessor requestProcessor,
@NonNull String statsKey) {
@@ -188,7 +195,7 @@
mPreviewImageReader.setOnImageAvailableListener(new ImageListener(), mHandler);
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public void onCaptureSessionEnd() {
mOnCaptureSessionEndStarted.set(true);
@@ -200,7 +207,7 @@
mRequestProcessor = null;
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public int startRepeating(@NonNull Executor executor,
@NonNull CaptureCallback captureCallback) {
@@ -375,13 +382,13 @@
return mParametersList;
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public void stopRepeating() {
mRequestProcessor.stopRepeating();
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public int startMultiFrameCapture(@NonNull Executor executor,
@NonNull CaptureCallback captureCallback) {
@@ -446,7 +453,7 @@
return seqId;
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public int startTrigger(@NonNull CaptureRequest captureRequest,
@NonNull Executor executor, @NonNull CaptureCallback captureCallback) {
@@ -526,7 +533,7 @@
return parameters;
}
- @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+ @FlaggedApi(Flags.FLAG_CONCERT_MODE_API)
@Override
public void setParameters(@NonNull CaptureRequest captureRequest) {
synchronized (mParametersLock) {
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/AdvancedExtenderImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/AdvancedExtenderImpl.java
index abf8d45..4386b5e 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/AdvancedExtenderImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/AdvancedExtenderImpl.java
@@ -233,6 +233,13 @@
* {@link CameraCharacteristics#CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION} and
* {@link CameraCharacteristics#CONTROL_VIDEO_STABILIZATION_MODE_OFF} for the key
* {@link CameraCharacteristics#CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES}.
+ *
+ * <p> Currently, the only synthetic keys supported for override are
+ * {@link CameraCharacteristics#REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES} and
+ * {@link CameraCharacteristics#REQUEST_AVAILABLE_COLOR_SPACE_PROFILES}. To enable them, an OEM
+ * should override the respective native keys
+ * {@link CameraCharacteristics#REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP} and
+ * {@link CameraCharacteristics#REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP}.
* @since 1.5
*/
List<Pair<CameraCharacteristics.Key, Object>> getAvailableCharacteristicsKeyValues();
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2OutputConfigImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2OutputConfigImpl.java
index 68de01b..fe0cddf 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2OutputConfigImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2OutputConfigImpl.java
@@ -17,6 +17,7 @@
package androidx.camera.extensions.impl.advanced;
import android.annotation.SuppressLint;
+import android.hardware.camera2.params.DynamicRangeProfiles;
import java.util.List;
@@ -44,6 +45,15 @@
String getPhysicalCameraId();
/**
+ * Gets the dynamic range profile.
+ *
+ * @since 1.5
+ */
+ default long getDynamicRangeProfile() {
+ return DynamicRangeProfiles.STANDARD;
+ }
+
+ /**
* If non-null, enable surface sharing and add the surface constructed by the return
* Camera2OutputConfig.
*/
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2OutputConfigImplBuilder.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2OutputConfigImplBuilder.java
index 365abc3..541ade6 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2OutputConfigImplBuilder.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2OutputConfigImplBuilder.java
@@ -17,6 +17,7 @@
package androidx.camera.extensions.impl.advanced;
import android.annotation.SuppressLint;
+import android.hardware.camera2.params.DynamicRangeProfiles;
import android.hardware.camera2.params.OutputConfiguration;
import android.util.Size;
import android.view.Surface;
@@ -35,6 +36,7 @@
private int mSurfaceGroupId = OutputConfiguration.SURFACE_GROUP_ID_NONE;
private String mPhysicalCameraId;
private List<Camera2OutputConfigImpl> mSurfaceSharingConfigs;
+ private long mDynamicRangeProfile = DynamicRangeProfiles.STANDARD;
private Camera2OutputConfigImplBuilder(OutputConfigImplImpl outputConfig) {
mOutputConfig = outputConfig;
@@ -93,6 +95,14 @@
}
/**
+ * Set dynamic range profile.
+ */
+ public Camera2OutputConfigImplBuilder setDynamicRangeProfile(long dynamicRangeProfile) {
+ mDynamicRangeProfile = dynamicRangeProfile;
+ return this;
+ }
+
+ /**
* Sets surface group id.
*/
public Camera2OutputConfigImplBuilder setSurfaceGroupId(int surfaceGroupId) {
@@ -108,6 +118,7 @@
mOutputConfig.setPhysicalCameraId(mPhysicalCameraId);
mOutputConfig.setSurfaceGroup(mSurfaceGroupId);
mOutputConfig.setSurfaceSharingConfigs(mSurfaceSharingConfigs);
+ mOutputConfig.setDynamicRangeProfile(mDynamicRangeProfile);
return mOutputConfig;
}
@@ -115,6 +126,7 @@
private int mId;
private int mSurfaceGroup;
private String mPhysicalCameraId;
+ private long mDynamicRangeProfile;
private List<Camera2OutputConfigImpl> mSurfaceSharingConfigs;
OutputConfigImplImpl() {
@@ -122,6 +134,7 @@
mSurfaceGroup = 0;
mPhysicalCameraId = null;
mSurfaceSharingConfigs = null;
+ mDynamicRangeProfile = DynamicRangeProfiles.STANDARD;
}
@Override
@@ -140,6 +153,11 @@
}
@Override
+ public long getDynamicRangeProfile() {
+ return mDynamicRangeProfile;
+ }
+
+ @Override
public List<Camera2OutputConfigImpl> getSurfaceSharingOutputConfigs() {
return mSurfaceSharingConfigs;
}
@@ -156,6 +174,10 @@
mPhysicalCameraId = physicalCameraId;
}
+ public void setDynamicRangeProfile(long dynamicRangeProfile) {
+ mDynamicRangeProfile = dynamicRangeProfile;
+ }
+
public void setSurfaceSharingConfigs(
List<Camera2OutputConfigImpl> surfaceSharingConfigs) {
mSurfaceSharingConfigs = surfaceSharingConfigs;
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImpl.java
index 850f0e1..5d4444f 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImpl.java
@@ -18,6 +18,7 @@
import android.annotation.SuppressLint;
import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.params.ColorSpaceProfiles;
import java.util.List;
import java.util.Map;
@@ -55,4 +56,14 @@
* will be configured to use the default regular type.
*/
int getSessionType();
+
+ /**
+ * Gets the color space.
+ *
+ * @since 1.5
+ * @return {@link android.graphics#ColorSpace.Named} set for session configuration
+ */
+ default int getColorSpace() {
+ return ColorSpaceProfiles.UNSPECIFIED;
+ }
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java
index dc1fecc..e745624 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java
@@ -20,6 +20,7 @@
import android.annotation.SuppressLint;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.params.ColorSpaceProfiles;
import android.hardware.camera2.params.SessionConfiguration;
import java.util.ArrayList;
@@ -33,6 +34,7 @@
@SuppressLint("UnknownNullness")
public class Camera2SessionConfigImplBuilder {
private int mSessionTemplateId = CameraDevice.TEMPLATE_PREVIEW;
+ private int mColorSpace = ColorSpaceProfiles.UNSPECIFIED;
private int mSessionType = SessionConfiguration.SESSION_REGULAR;
Map<CaptureRequest.Key<?>, Object> mSessionParameters = new HashMap<>();
List<Camera2OutputConfigImpl> mCamera2OutputConfigs = new ArrayList<>();
@@ -67,6 +69,21 @@
}
/**
+ * Sets the color space.
+ */
+ public Camera2SessionConfigImplBuilder setColorSpace(int colorSpace) {
+ mColorSpace = colorSpace;
+ return this;
+ }
+
+ /**
+ * Gets the color space.
+ */
+ public int getColorSpace() {
+ return mColorSpace;
+ }
+
+ /**
* Gets the session template id.
*/
public int getSessionTemplateId() {
@@ -105,12 +122,14 @@
Camera2SessionConfigImpl {
int mSessionTemplateId;
int mSessionType;
+ int mColorSpace = ColorSpaceProfiles.UNSPECIFIED;
Map<CaptureRequest.Key<?>, Object> mSessionParameters;
List<Camera2OutputConfigImpl> mCamera2OutputConfigs;
Camera2SessionConfigImplImpl(Camera2SessionConfigImplBuilder builder) {
mSessionTemplateId = builder.getSessionTemplateId();
mSessionParameters = builder.getSessionParameters();
+ mColorSpace = builder.getColorSpace();
mCamera2OutputConfigs = builder.getCamera2OutputConfigs();
mSessionType = builder.getSessionType();
}
@@ -134,6 +153,11 @@
public int getSessionType() {
return mSessionType;
}
+
+ @Override
+ public int getColorSpace() {
+ return mColorSpace;
+ }
}
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/OutputSurfaceConfigurationImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/OutputSurfaceConfigurationImpl.java
index 723f0f4..217887b 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/OutputSurfaceConfigurationImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/OutputSurfaceConfigurationImpl.java
@@ -17,6 +17,7 @@
package androidx.camera.extensions.impl.advanced;
import android.annotation.SuppressLint;
+import android.hardware.camera2.params.ColorSpaceProfiles;
/**
* For specifying the output surface configurations for the extension.
@@ -32,4 +33,13 @@
public OutputSurfaceImpl getImageAnalysisOutputSurface();
public OutputSurfaceImpl getPostviewOutputSurface();
+
+ /*
+ * Gets the color space.
+ *
+ * @since 1.5
+ */
+ default int getColorSpace() {
+ return ColorSpaceProfiles.UNSPECIFIED;
+ }
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/OutputSurfaceImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/OutputSurfaceImpl.java
index 7bf8df2..72bc4ab 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/OutputSurfaceImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/OutputSurfaceImpl.java
@@ -17,6 +17,7 @@
package androidx.camera.extensions.impl.advanced;
import android.annotation.SuppressLint;
+import android.hardware.camera2.params.DynamicRangeProfiles;
import android.util.Size;
import android.view.Surface;
@@ -49,4 +50,13 @@
* Gets the surface usage bits.
*/
long getUsage();
+
+ /**
+ * Gets the dynamic range profile.
+ *
+ * @since 1.5
+ */
+ default long getDynamicRangeProfile() {
+ return DynamicRangeProfiles.STANDARD;
+ }
}