Add the initial version of ResolutionSelector and Builder class
- Add ResolutionSelector class
- Add Builder and functions to the ResolutionSelector class
- Add setResolutionSelector function to the use cases' builder classes
Bug: 227546858
Test: ./gradlew bOS
Change-Id: Ia1e318d0e6f4a06bb54f42604dcd24725b4578d2
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysis.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysis.java
index 9cd621b..0732044 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysis.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysis.java
@@ -23,6 +23,7 @@
import static androidx.camera.core.impl.ImageAnalysisConfig.OPTION_OUTPUT_IMAGE_FORMAT;
import static androidx.camera.core.impl.ImageAnalysisConfig.OPTION_OUTPUT_IMAGE_ROTATION_ENABLED;
import static androidx.camera.core.impl.ImageOutputConfig.OPTION_MAX_RESOLUTION;
+import static androidx.camera.core.impl.ImageOutputConfig.OPTION_RESOLUTION_SELECTOR;
import static androidx.camera.core.impl.ImageOutputConfig.OPTION_SUPPORTED_RESOLUTIONS;
import static androidx.camera.core.impl.ImageOutputConfig.OPTION_TARGET_ASPECT_RATIO;
import static androidx.camera.core.impl.ImageOutputConfig.OPTION_TARGET_RESOLUTION;
@@ -1317,6 +1318,55 @@
return this;
}
+ /**
+ * Sets the resolution selector to select the preferred supported resolution.
+ *
+ * <p>CameraX will select a supported resolution for the {@link ImageAnalysis} according to
+ * the target resolution, aspect ratio, max resolution or high resolution enabled
+ * settings of the resolution selector. When using the <code>camera-camera2</code> CameraX
+ * implementation, which resolution will be finally selected will depend on the camera
+ * device's hardware level and the bound use cases combination. The device hardware level
+ * information can be retrieved by
+ * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
+ * from the interop class
+ * {@link androidx.camera.camera2.interop.Camera2CameraInfo#getCameraCharacteristic(CameraCharacteristics.Key)}.
+ *
+ * <p>A <code>LIMITED-level</code> above device can support a <code>RECORD</code> size
+ * resolution for {@link ImageAnalysis} when it is bound together with {@link Preview}
+ * and {@link ImageCapture}. The trade-off is the selected resolution for the
+ * {@link ImageCapture} will also be restricted by the <code>RECORD</code> size. To
+ * successfully select a <code>RECORD</code> size resolution for {@link ImageAnalysis}, a
+ * <code>RECORD</code> size target resolution should be set on both {@link ImageCapture}
+ * and {@link ImageAnalysis}. This indicates that the application clearly understand the
+ * trade-off and prefer the {@link ImageAnalysis} to have a larger resolution rather than
+ * the {@link ImageCapture} to have a <code>MAXIMUM</code> size resolution. For the
+ * definitions of <code>RECORD</code>, <code>MAXIMUM</code> sizes and more details see the
+ * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraDevice#regular-capture">Regular capture</a>
+ * section in {@link android.hardware.camera2.CameraDevice}'s. The <code>RECORD</code>
+ * size refers to the camera device's maximum supported recording resolution, as
+ * determined by {@link CamcorderProfile}. The <code>MAXIMUM</code> size refers to the
+ * camera device's maximum output resolution for that format or target from
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes}.
+ *
+ * <p>If no resolution selector is set, resolution of 640x480 will be selected to use in
+ * priority.
+ *
+ * <p>The existing {@link #setTargetResolution(Size)} and
+ * {@link #setTargetAspectRatio(int)} APIs are deprecated and are not compatible with
+ * {@link ResolutionSelector}. Calling any of these APIs together with
+ * {@link ResolutionSelector} will throw an {@link IllegalArgumentException} while
+ * {@link #build()} is called to create the {@link ImageAnalysis} instance.
+ *
+ * @hide
+ **/
+ @RestrictTo(Scope.LIBRARY_GROUP)
+ @Override
+ @NonNull
+ public Builder setResolutionSelector(@NonNull ResolutionSelector resolutionSelector) {
+ getMutableConfig().insertOption(OPTION_RESOLUTION_SELECTOR, resolutionSelector);
+ return this;
+ }
+
// Implementations of ThreadConfig.Builder default methods
/**
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
index a689360..c6d64d7 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
@@ -41,6 +41,7 @@
import static androidx.camera.core.impl.ImageCaptureConfig.OPTION_USE_CASE_EVENT_CALLBACK;
import static androidx.camera.core.impl.ImageCaptureConfig.OPTION_USE_SOFTWARE_JPEG_ENCODER;
import static androidx.camera.core.impl.ImageInputConfig.OPTION_INPUT_FORMAT;
+import static androidx.camera.core.impl.ImageOutputConfig.OPTION_RESOLUTION_SELECTOR;
import static androidx.camera.core.impl.UseCaseConfig.OPTION_CAMERA_SELECTOR;
import static androidx.camera.core.impl.UseCaseConfig.OPTION_ZSL_DISABLED;
import static androidx.camera.core.impl.utils.Threads.checkMainThread;
@@ -3142,6 +3143,37 @@
return this;
}
+ /**
+ * Sets the resolution selector to select the preferred supported resolution.
+ *
+ * <p>CameraX will select a supported resolution for the {@link ImageCapture} according to
+ * the target resolution, aspect ratio, max resolution or high resolution enabled
+ * settings of the resolution selector.
+ *
+ * <p>If no resolution selector is set, the largest available resolution will be selected
+ * to use. Usually, users will intend to get the largest still image that the camera
+ * device can support. Unlike {@link Builder#setTargetResolution(Size)},
+ * {@link #setCropAspectRatio(Rational)} won't be automatically called to set the
+ * corresponding value and crop the output image when a target resolution is set. Use
+ * {@link ViewPort} instead if the output images need to be cropped in a specific
+ * aspect ratio.
+ *
+ * <p>The existing {@link #setTargetResolution(Size)} and
+ * {@link #setTargetAspectRatio(int)} APIs are deprecated and are not compatible with
+ * {@link ResolutionSelector}. Calling any of these APIs together with
+ * {@link ResolutionSelector} will throw an {@link IllegalArgumentException} while
+ * {@link #build()} is called to create the {@link ImageCapture} instance.
+ *
+ * @hide
+ **/
+ @RestrictTo(Scope.LIBRARY_GROUP)
+ @Override
+ @NonNull
+ public Builder setResolutionSelector(@NonNull ResolutionSelector resolutionSelector) {
+ getMutableConfig().insertOption(OPTION_RESOLUTION_SELECTOR, resolutionSelector);
+ return this;
+ }
+
/** @hide */
@NonNull
@RestrictTo(Scope.LIBRARY_GROUP)
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/Preview.java b/camera/camera-core/src/main/java/androidx/camera/core/Preview.java
index 7b7a0a2..e38dded 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/Preview.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/Preview.java
@@ -19,6 +19,7 @@
import static androidx.camera.core.SurfaceOutput.GlTransformOptions.APPLY_CROP_ROTATE_AND_MIRRORING;
import static androidx.camera.core.impl.ImageInputConfig.OPTION_INPUT_FORMAT;
import static androidx.camera.core.impl.ImageOutputConfig.OPTION_APP_TARGET_ROTATION;
+import static androidx.camera.core.impl.ImageOutputConfig.OPTION_RESOLUTION_SELECTOR;
import static androidx.camera.core.impl.PreviewConfig.IMAGE_INFO_PROCESSOR;
import static androidx.camera.core.impl.PreviewConfig.OPTION_BACKGROUND_EXECUTOR;
import static androidx.camera.core.impl.PreviewConfig.OPTION_CAPTURE_CONFIG_UNPACKER;
@@ -1075,6 +1076,41 @@
return this;
}
+ /**
+ * Sets the resolution selector to select the preferred supported resolution.
+ *
+ * <p>CameraX will select a supported resolution for the {@link Preview} according to
+ * the target resolution, aspect ratio, max resolution or high resolution enabled
+ * settings of the resolution selector.
+ *
+ * <p>The selected resolution will be limited by the <code>PREVIEW</code> size which is
+ * defined as the best size match to the device's screen resolution, or to 1080p
+ * (1920x1080), whichever is smaller. See the
+ * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraDevice#regular-capture">Regular capture</a>
+ * section in {@link android.hardware.camera2.CameraDevice}'. If the
+ * {@link ResolutionSelector} contains the max resolution setting larger than the
+ * <code>PREVIEW</code> size, a size larger than the device's screen resolution or 1080p
+ * can be selected to use for {@link Preview}.
+ *
+ * <p>Note that due to compatibility reasons, CameraX may select a resolution that is
+ * larger than the default screen resolution on certain devices.
+ *
+ * <p>The existing {@link #setTargetResolution(Size)} and
+ * {@link #setTargetAspectRatio(int)} APIs are deprecated and are not compatible with
+ * {@link ResolutionSelector}. Calling any of these APIs together with
+ * {@link ResolutionSelector} will throw an {@link IllegalArgumentException} while
+ * {@link #build()} is called to create the {@link Preview} instance.
+ *
+ * @hide
+ **/
+ @RestrictTo(Scope.LIBRARY_GROUP)
+ @Override
+ @NonNull
+ public Builder setResolutionSelector(@NonNull ResolutionSelector resolutionSelector) {
+ getMutableConfig().insertOption(OPTION_RESOLUTION_SELECTOR, resolutionSelector);
+ return this;
+ }
+
// Implementations of ThreadConfig.Builder default methods
/**
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ResolutionSelector.java b/camera/camera-core/src/main/java/androidx/camera/core/ResolutionSelector.java
new file mode 100644
index 0000000..3667b24
--- /dev/null
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ResolutionSelector.java
@@ -0,0 +1,358 @@
+/*
+ * Copyright 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 androidx.camera.core;
+
+import android.util.Size;
+import android.view.Surface;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
+
+/**
+ * A set of requirements and priorities used to select a resolution for the use case.
+ *
+ * <p>The resolution size or the aspect ratio parameters being set in this
+ * {@link ResolutionSelector} is used to find the surface size in the camera sensor's natural
+ * orientation (landscape) from the supported resolution list. In camera2 implementation, this
+ * supported resolution list can be retrieved from
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes(int)}. The
+ * {@link android.hardware.camera2.params.StreamConfigurationMap} can be retrieved from interop
+ * class
+ * {@link androidx.camera.camera2.interop.Camera2CameraInfo#getCameraCharacteristic(CameraCharacteristics.Key)}.
+ *
+ * <p>When the target aspect ratio is set, the resolutions of the specified aspect ratio will be
+ * selected in priority. If no resolution matches the aspect ratio, the resolution of the aspect
+ * ratio which is closest to the specified target aspect ratio will be selected in priority.
+ *
+ * <p>When the target resolution is set, the target resolution attempts to establish a minimum
+ * bound for the image resolution. If no resolution exists that is equal to or larger than the
+ * target resolution, the nearest available resolution smaller than the target resolution will be
+ * chosen. Resolutions with the same aspect ratio of the provided size will be considered in
+ * higher priority before resolutions of different aspect ratios.
+ *
+ * <p>When the max resolution is set, the resolutions that either width or height exceed the
+ * specified max resolution will be filtered out to be prevented from selecting.
+ *
+ * <p>When the high resolution support is enabled, the resolutions retrieved from
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getHighResolutionOutputSizes(int)}
+ * can be selected. This is typically used to take high resolution still images. Please note that
+ * enabling high resolutions might cause the entire capture session to not meet the 20 fps frame
+ * rate.
+ *
+ * <p>According to the camera device's hardware level and the bound use cases combination,
+ * CameraX will select the best resolution for the use case by the all conditions. Applications
+ * can know which resolution is finally selected to use by the use case's
+ * <code>getResolutionInfo()</code> function. For more details see the guaranteed supported
+ * configurations tables in {@link android.hardware.camera2.CameraDevice}'s
+ * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraDevice#regular-capture">Regular capture</a> section.
+ *
+ * <p>This {@link ResolutionSelector} determines the size of the {@link Surface} to get the camera
+ * output for the use case. However, the actual output that the user sees will be adjusted by the
+ * camera sensor orientation and the display orientation so that the user gets the upright image
+ * properly. For example, when setting the target resolution size to <code>(1920, 1080)</code> in
+ * a camera sensor that has sensor rotation 90 degrees and the device is in natural portrait
+ * orientation ({@link Surface#ROTATION_0}), the output images will be transformed properly to be
+ * displayed correctly in preview which has the aspect ratio of 9:16.
+ *
+ * <p>The existing setTargetResolution and setTargetAspectRatio APIs in
+ * Preview/ImageCapture/ImageAnalysis's Builder are deprecated and are not compatible with
+ * {@link ResolutionSelector}. Calling any of these APIs together with {@link ResolutionSelector}
+ * will throw an {@link IllegalArgumentException}.
+ *
+ * @hide
+ */
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public final class ResolutionSelector {
+
+ private static final int ASPECT_RATIO_UNKNOWN = -1;
+ private final int mTargetAspectRatio;
+ @Nullable
+ private final Size mTargetResolution;
+ @Nullable
+ private final Size mMaxResolution;
+ private final boolean mIsHighResolutionEnabled;
+
+ ResolutionSelector(int targetAspectRatio, @Nullable Size targetResolution,
+ @Nullable Size maxResolution, boolean isHighResolutionEnabled) {
+ mTargetAspectRatio = targetAspectRatio;
+ mTargetResolution = targetResolution;
+ mMaxResolution = maxResolution;
+ mIsHighResolutionEnabled = isHighResolutionEnabled;
+ }
+
+ /**
+ * Returns whether a target aspect ratio is set in the {@link ResolutionSelector}.
+ *
+ * @hide
+ */
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+ public boolean hasTargetAspectRatio() {
+ return mTargetAspectRatio != ASPECT_RATIO_UNKNOWN;
+ }
+
+ /**
+ * Retrieves the target aspect ratio setting in the {@link ResolutionSelector}.
+ *
+ * @throws IllegalArgumentException when no target aspect ratio is set.
+ * @hide
+ */
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+ @AspectRatio.Ratio
+ public int getTargetAspectRatio() {
+ if (mTargetAspectRatio == ASPECT_RATIO_UNKNOWN) {
+ throw new IllegalArgumentException("No target aspect ratio is set!!");
+ }
+
+ return mTargetAspectRatio;
+ }
+
+ /**
+ * Retrieves the target resolution setting in the {@link ResolutionSelector}.
+ *
+ * @hide
+ */
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+ @Nullable
+ public Size getTargetResolution() {
+ return mTargetResolution;
+ }
+
+ /**
+ * Returns the max resolution setting in the {@link ResolutionSelector}.
+ *
+ * @hide
+ */
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+ @Nullable
+ public Size getMaxResolution() {
+ return mMaxResolution;
+ }
+
+ /**
+ * Returns whether high resolutions are allowed to be selected.
+ *
+ * @hide
+ */
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+ public boolean isHighResolutionEnabled() {
+ return mIsHighResolutionEnabled;
+ }
+
+ /**
+ * Builder for a {@link ResolutionSelector}.
+ */
+ public static final class Builder {
+ private int mTargetAspectRatio = ASPECT_RATIO_UNKNOWN;
+ @Nullable
+ private Size mTargetResolution = null;
+ @Nullable
+ private Size mMaxResolution = null;
+ private boolean mIsHighResolutionEnabled = false;
+
+ /**
+ * Creates a new {@link Builder} object.
+ */
+ public Builder() {
+ }
+
+ private Builder(@NonNull ResolutionSelector selector) {
+ if (selector.hasTargetAspectRatio()) {
+ mTargetAspectRatio = selector.getTargetAspectRatio();
+ }
+ mTargetResolution = selector.getTargetResolution();
+ mMaxResolution = selector.getMaxResolution();
+ mIsHighResolutionEnabled = selector.isHighResolutionEnabled();
+ }
+
+ /**
+ * Generates a {@link Builder} from another {@link ResolutionSelector} object.
+ *
+ * @param selector An existing {@link ResolutionSelector}.
+ * @return The new {@link Builder}.
+ */
+ @NonNull
+ public static Builder fromSelector(@NonNull ResolutionSelector selector) {
+ return new Builder(selector);
+ }
+
+ /**
+ * Sets the target aspect ratio that the output images are expected to have.
+ *
+ * <p>The input aspect ratio parameter being set in this {@link ResolutionSelector} is
+ * used to find the surface size in the camera sensor's natural orientation (landscape)
+ * from the supported resolution list.
+ *
+ * <p>It is not allowed to set both target aspect ratio and target resolution on the same
+ * use case. Attempting so will throw an IllegalArgumentException when calling the
+ * {@link #build()} function.
+ *
+ * <p>About the usage example, if the device has a <code>16:9</code> display and wants to
+ * capture images matching the display aspect ratio, a {@link ResolutionSelector} created
+ * with {@link AspectRatio.Ratio#RATIO_16_9} target aspect ratio setting can be used. If
+ * no target aspect ratio and resolution is set for the use case,
+ * {@link AspectRatio.Ratio#RATIO_4_3} target aspect ratio is set by default. Usually,
+ * the camera sensor is in size of <code>4:3</code> aspect ratio and output images of
+ * <code>4:3</code> aspect ratio will have the full FOV of the camera device.
+ *
+ * <p>The target aspect ratio is used as a hint when determining the resulting output aspect
+ * ratio which may differ from the request, possibly due to device constraints. Application
+ * code should check the resulting output's resolution and the resulting aspect ratio may
+ * not be exactly as requested.
+ *
+ * @param targetAspectRatio A {@link AspectRatio} representing the ratio of the target's
+ * width and height.
+ */
+ @NonNull
+ public Builder setTargetAspectRatio(@AspectRatio.Ratio int targetAspectRatio) {
+ mTargetAspectRatio = targetAspectRatio;
+ return this;
+ }
+
+ /**
+ * Sets the target resolution that the output images are expected to have.
+ *
+ * <p>The input resolution parameter being set in this {@link ResolutionSelector} is used
+ * to find the surface size in the camera sensor's natural orientation (landscape) from
+ * the supported resolution list.
+ *
+ * <p>It is not allowed to set both target resolution and target aspect ratio on the same
+ * use case. Attempting so will throw an IllegalArgumentException when calling the
+ * {@link #build()} function.
+ *
+ * <p>About the usage example, if applications have a 1080p (1920x1080) display but only
+ * need a <code>640x480</code> preview for some specific performance or design concern, a
+ * {@link ResolutionSelector} created with <code>640x480</code> target resolution setting
+ * can be used. If no target resolution and aspect ratio is set, each type of use case
+ * has its own default value. {@link ImageCapture} will try to capture the largest image
+ * as it can. {@link ImageAnalysis} will capture <code>640x480</code> size of images for
+ * analyzing by default. {@link Preview} will select a resolution under the device's
+ * screen resolution or 1080p (1920x1080), whichever is smaller.
+ *
+ * <p>The target resolution attempts to establish a minimum bound for the image
+ * resolution. The actual image resolution will be the closest available resolution in
+ * size that is not smaller than the target resolution, as determined by the Camera
+ * implementation. However, if no resolution exists that is equal to or larger than the
+ * target resolution, the nearest available resolution smaller than the target resolution
+ * will be chosen. Resolutions with the same aspect ratio of the provided {@link Size}
+ * will be considered in higher priority before resolutions of different aspect ratios.
+ *
+ * @param targetResolution The target resolution to choose from supported output sizes list.
+ */
+ @NonNull
+ public Builder setTargetResolution(@NonNull Size targetResolution) {
+ mTargetResolution = targetResolution;
+ return this;
+ }
+
+ /**
+ * Sets the max resolution condition for the use case.
+ *
+ * <p>The max resolution prevents the use case to select the sizes which either width or
+ * height exceeds the specified resolution.
+ *
+ * <p>The resolution should be expressed in the camera sensor's natural orientation
+ * (landscape).
+ *
+ * <p>About the usage example, if applications want to select a resolution smaller than a
+ * specific resolution to have better performance, a {@link ResolutionSelector} which
+ * sets this specific resolution as the max resolution can be used. Or, if applications
+ * want to select a larger resolution for a {@link Preview} which has the default max
+ * resolution setting of the small one of device's screen size and 1080p (1920x1080), a
+ * {@link ResolutionSelector} created with max resolution setting can also be used.
+ *
+ * <p>When using the <code>camera-camera2</code> CameraX implementation, which resolution
+ * will be finally selected will depend on the camera device's hardware level and the
+ * bound use cases combination. The device hardware level information can be retrieved by
+ * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
+ * from the interop class
+ * {@link androidx.camera.camera2.interop.Camera2CameraInfo#getCameraCharacteristic(CameraCharacteristics.Key)}.
+ * For more details see the
+ * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraDevice#regular-capture">Regular capture</a>
+ * section in {@link android.hardware.camera2.CameraDevice}.
+ *
+ * @param resolution The max resolution limitation to choose from supported output sizes
+ * list.
+ * @return The current {@link Builder}.
+ */
+ @NonNull
+ public Builder setMaxResolution(@NonNull Size resolution) {
+ mMaxResolution = resolution;
+ return this;
+ }
+
+ /**
+ * Sets whether high resolutions are allowed to be selected for the use cases.
+ *
+ * <p> Calling this function will allow the use case to select the high resolution output
+ * sizes if it is supported for the camera device.
+ *
+ * <p>When using the <code>camera-camera2</code> CameraX implementation, the supported
+ * high resolutions are retrieved from
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getHighResolutionOutputSizes(int)}.
+ * Be noticed that the high resolution sizes might cause the entire capture session to
+ * not meet the 20 fps frame rate. Even if only an ImageCapture use case selects a high
+ * resolution, it might still impact the FPS of the Preview, ImageAnalysis or
+ * VideoCapture use cases which are bound together. This function only takes effect on
+ * devices with
+ * {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE}
+ * capability. For devices without
+ * {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE}
+ * capability, all resolutions can be retrieved from
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes(int)}, but
+ * it is not guaranteed to meet >= 20 fps for any resolution in the list.
+ *
+ * <p>Which resolution will be finally selected will depend on the camera device's
+ * hardware level and the bound use cases combination. The device hardware level
+ * information can be retrieved by
+ * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
+ * from the interop class
+ * {@link androidx.camera.camera2.interop.Camera2CameraInfo#getCameraCharacteristic(CameraCharacteristics.Key)}.
+ * For more details see the
+ * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraDevice#regular-capture">Regular capture</a>
+ * section in {@link android.hardware.camera2.CameraDevice}.
+ *
+ * @param enabled True to allow to select high resolution for the use case.
+ * @return The current {@link Builder}.
+ */
+ @NonNull
+ public Builder setHighResolutionEnabled(boolean enabled) {
+ mIsHighResolutionEnabled = enabled;
+ return this;
+ }
+
+ /**
+ * Builds the {@link ResolutionSelector}.
+ *
+ * @return the {@link ResolutionSelector} built with the specified resolution settings.
+ * @throws IllegalArgumentException when both target aspect and resolution are set at the
+ * same time.
+ */
+ @NonNull
+ public ResolutionSelector build() {
+ if (mTargetAspectRatio != ASPECT_RATIO_UNKNOWN && mTargetResolution != null) {
+ throw new IllegalArgumentException("Cannot use both setTargetResolution and "
+ + "setTargetAspectRatio at the same time.");
+ }
+
+ return new ResolutionSelector(mTargetAspectRatio, mTargetResolution, mMaxResolution,
+ mIsHighResolutionEnabled);
+ }
+ }
+}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/VideoCapture.java b/camera/camera-core/src/main/java/androidx/camera/core/VideoCapture.java
index 6e77562..dcd6bfb 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/VideoCapture.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/VideoCapture.java
@@ -18,6 +18,7 @@
import static androidx.camera.core.impl.ImageOutputConfig.OPTION_DEFAULT_RESOLUTION;
import static androidx.camera.core.impl.ImageOutputConfig.OPTION_MAX_RESOLUTION;
+import static androidx.camera.core.impl.ImageOutputConfig.OPTION_RESOLUTION_SELECTOR;
import static androidx.camera.core.impl.ImageOutputConfig.OPTION_SUPPORTED_RESOLUTIONS;
import static androidx.camera.core.impl.ImageOutputConfig.OPTION_TARGET_ASPECT_RATIO;
import static androidx.camera.core.impl.ImageOutputConfig.OPTION_TARGET_RESOLUTION;
@@ -1753,6 +1754,15 @@
return this;
}
+ /** @hide */
+ @RestrictTo(Scope.LIBRARY_GROUP)
+ @Override
+ @NonNull
+ public Builder setResolutionSelector(@NonNull ResolutionSelector resolutionSelector) {
+ getMutableConfig().insertOption(OPTION_RESOLUTION_SELECTOR, resolutionSelector);
+ return this;
+ }
+
// Implementations of ThreadConfig.Builder default methods
/**
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/ImageOutputConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/ImageOutputConfig.java
index 334bc6c..ce28e63 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/ImageOutputConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/ImageOutputConfig.java
@@ -26,6 +26,7 @@
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.camera.core.AspectRatio;
+import androidx.camera.core.ResolutionSelector;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -88,6 +89,12 @@
Option<List<Pair<Integer, Size[]>>> OPTION_SUPPORTED_RESOLUTIONS =
Option.create("camerax.core.imageOutput.supportedResolutions", List.class);
+ /**
+ * Option: camerax.core.imageOutput.resolutionSelector
+ */
+ Option<ResolutionSelector> OPTION_RESOLUTION_SELECTOR =
+ Option.create("camerax.core.imageOutput.resolutionSelector", ResolutionSelector.class);
+
// *********************************************************************************************
/**
@@ -243,6 +250,29 @@
}
/**
+ * Retrieves the resolution selector can be used by the target from this configuration.
+ *
+ * @param valueIfMissing The value to return if this configuration option has not been set.
+ * @return The stored value or <code>valueIfMissing</code> if the value does not exist in this
+ * configuration.
+ */
+ @Nullable
+ default ResolutionSelector getResolutionSelector(@Nullable ResolutionSelector valueIfMissing) {
+ return retrieveOption(OPTION_RESOLUTION_SELECTOR, valueIfMissing);
+ }
+
+ /**
+ * Retrieves the resolution selector can be used by the target from this configuration.
+ *
+ * @return The stored value, if it exists in this configuration.
+ * @throws IllegalArgumentException if the option does not exist in this configuration.
+ */
+ @NonNull
+ default ResolutionSelector getResolutionSelector() {
+ return retrieveOption(OPTION_RESOLUTION_SELECTOR);
+ }
+
+ /**
* Retrieves the supported resolutions can be used by the target from this configuration.
*
* <p>Pair list is composed with {@link ImageFormat} and {@link Size} array. The returned
@@ -336,6 +366,15 @@
*/
@NonNull
B setSupportedResolutions(@NonNull List<Pair<Integer, Size[]>> resolutionsList);
+
+ /**
+ * Sets the resolution selector can be used by target from this configuration.
+ *
+ * @param resolutionSelector The resolution selector to select a preferred resolution.
+ * @return The current Builder.
+ */
+ @NonNull
+ B setResolutionSelector(@NonNull ResolutionSelector resolutionSelector);
}
/**
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeUseCaseConfig.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeUseCaseConfig.java
index 71bc549..9f4fb98 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeUseCaseConfig.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeUseCaseConfig.java
@@ -22,6 +22,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.camera.core.CameraSelector;
+import androidx.camera.core.ResolutionSelector;
import androidx.camera.core.UseCase;
import androidx.camera.core.impl.CaptureConfig;
import androidx.camera.core.impl.Config;
@@ -223,6 +224,13 @@
return this;
}
+ @NonNull
+ @Override
+ public Builder setResolutionSelector(@NonNull ResolutionSelector resolutionSelector) {
+ getMutableConfig().insertOption(OPTION_RESOLUTION_SELECTOR, resolutionSelector);
+ return this;
+ }
+
/**
* Sets specific image format to the fake use case.
*/
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/VideoCapture.java b/camera/camera-video/src/main/java/androidx/camera/video/VideoCapture.java
index 8c33f0a..dbed878 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/VideoCapture.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/VideoCapture.java
@@ -20,6 +20,7 @@
import static androidx.camera.core.SurfaceOutput.GlTransformOptions.APPLY_CROP_ROTATE_AND_MIRRORING;
import static androidx.camera.core.impl.ImageOutputConfig.OPTION_DEFAULT_RESOLUTION;
import static androidx.camera.core.impl.ImageOutputConfig.OPTION_MAX_RESOLUTION;
+import static androidx.camera.core.impl.ImageOutputConfig.OPTION_RESOLUTION_SELECTOR;
import static androidx.camera.core.impl.ImageOutputConfig.OPTION_SUPPORTED_RESOLUTIONS;
import static androidx.camera.core.impl.ImageOutputConfig.OPTION_TARGET_ASPECT_RATIO;
import static androidx.camera.core.impl.ImageOutputConfig.OPTION_TARGET_ROTATION;
@@ -66,6 +67,7 @@
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.Logger;
+import androidx.camera.core.ResolutionSelector;
import androidx.camera.core.SurfaceRequest;
import androidx.camera.core.UseCase;
import androidx.camera.core.ViewPort;
@@ -1410,6 +1412,15 @@
return this;
}
+ /** @hide */
+ @RestrictTo(Scope.LIBRARY_GROUP)
+ @Override
+ @NonNull
+ public Builder<T> setResolutionSelector(@NonNull ResolutionSelector resolutionSelector) {
+ getMutableConfig().insertOption(OPTION_RESOLUTION_SELECTOR, resolutionSelector);
+ return this;
+ }
+
// Implementations of ThreadConfig.Builder default methods
/**