1 /* 2 * Copyright 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.camera.core.impl; 18 19 import android.hardware.camera2.CameraMetadata; 20 import android.util.Range; 21 import android.util.Size; 22 23 import androidx.camera.core.DynamicRange; 24 import androidx.camera.core.ViewPort; 25 import androidx.camera.core.streamsharing.StreamSharing; 26 27 import com.google.auto.value.AutoValue; 28 29 import org.jspecify.annotations.NonNull; 30 import org.jspecify.annotations.Nullable; 31 32 /** 33 * A stream specification defining how a camera frame stream should be configured. 34 * 35 * <p>The values communicated by this class specify what the camera is expecting to produce as a 36 * frame stream, and can be useful for configuring the frame consumer. 37 */ 38 @AutoValue 39 public abstract class StreamSpec { 40 41 /** A frame rate range with no specified upper or lower bound. */ 42 public static final Range<Integer> FRAME_RATE_RANGE_UNSPECIFIED = new Range<>(0, 0); 43 44 /** 45 * Returns the resolution for the stream associated with this stream specification. 46 * @return the resolution for the stream. 47 */ getResolution()48 public abstract @NonNull Size getResolution(); 49 50 /** 51 * Returns the original resolution configured by the camera. This value is useful for 52 * debugging and analysis, as it represents the initial resolution intended for the stream, 53 * even if the stream is later modified. 54 * 55 * <p>This value typically matches the resolution returned by {@link #getResolution()}, 56 * but may differ if the stream is modified (e.g., cropped, scaled, or rotated) 57 * after being configured by the camera. For example, {@link StreamSharing} first determines 58 * which child use case's requested resolution to be its configured resolution and then 59 * request a larger resolution from the camera. The camera stream is further modified (e.g., 60 * cropped, scaled, or rotated) to fit the configured resolution and other requirements such 61 * as {@link ViewPort} and rotation. The final resolution after these 62 * modifications would be reflected by {@link #getResolution()}, while this method returns the 63 * original configured resolution. 64 * 65 * @return The originally configured camera resolution. 66 */ getOriginalConfiguredResolution()67 public abstract @NonNull Size getOriginalConfiguredResolution(); 68 69 /** 70 * Returns the {@link DynamicRange} for the stream associated with this stream specification. 71 * @return the dynamic range for the stream. 72 */ getDynamicRange()73 public abstract @NonNull DynamicRange getDynamicRange(); 74 75 /** Returns the session type associated with this stream. */ getSessionType()76 public abstract int getSessionType(); 77 78 /** 79 * Returns the expected frame rate range for the stream associated with this stream 80 * specification. 81 * @return the expected frame rate range for the stream. 82 */ getExpectedFrameRateRange()83 public abstract @NonNull Range<Integer> getExpectedFrameRateRange(); 84 85 /** 86 * Returns the implementation options associated with this stream 87 * specification. 88 * @return the implementation options for the stream. 89 */ getImplementationOptions()90 public abstract @Nullable Config getImplementationOptions(); 91 92 /** 93 * Returns the flag if zero-shutter lag needs to be disabled by user case combinations. 94 */ getZslDisabled()95 public abstract boolean getZslDisabled(); 96 97 /** Returns a build for a stream configuration that takes a required resolution. */ builder(@onNull Size resolution)98 public static @NonNull Builder builder(@NonNull Size resolution) { 99 return new AutoValue_StreamSpec.Builder() 100 .setResolution(resolution) 101 .setOriginalConfiguredResolution(resolution) 102 .setSessionType(SessionConfig.DEFAULT_SESSION_TYPE) 103 .setExpectedFrameRateRange(FRAME_RATE_RANGE_UNSPECIFIED) 104 .setDynamicRange(DynamicRange.SDR) 105 .setZslDisabled(false); 106 } 107 108 /** Returns a builder pre-populated with the current specification. */ toBuilder()109 public abstract @NonNull Builder toBuilder(); 110 111 /** A builder for a stream specification */ 112 @AutoValue.Builder 113 public abstract static class Builder { 114 // Restrict construction to same package Builder()115 Builder() { 116 } 117 118 /** Sets the resolution, overriding the existing resolution set in this builder. */ setResolution(@onNull Size resolution)119 public abstract @NonNull Builder setResolution(@NonNull Size resolution); 120 121 /** 122 * Sets the original resolution configured by the camera. This value is useful for 123 * debugging and analysis, as it represents the initial resolution intended by the stream 124 * consumer, even if the stream is later modified. 125 * 126 * <p>This value typically matches the resolution set by {@link #setResolution(Size)}, 127 * but may differ if the stream is modified (e.g., cropped, scaled, or rotated) 128 * after being configured by the camera. For example, {@link StreamSharing} first 129 * determines which child use case's requested resolution to be its configured resolution 130 * and then request a larger resolution from the camera. The camera stream is further 131 * modified (e.g., cropped, scaled, or rotated) to fit the configured resolution and other 132 * requirements such as {@link ViewPort} and rotation. The final resolution after these 133 * modifications is set by {@link #setResolution(Size)}, while this method retains the 134 * original configured resolution. 135 * 136 * <p>If not set, this value will default to the resolution set in this builder. 137 */ setOriginalConfiguredResolution(@onNull Size resolution)138 public abstract @NonNull Builder setOriginalConfiguredResolution(@NonNull Size resolution); 139 140 /** 141 * Sets the session type. 142 * 143 * <p>If not set, the default session type is {@link SessionConfig#DEFAULT_SESSION_TYPE}. 144 */ setSessionType(int sessionType)145 public abstract @NonNull Builder setSessionType(int sessionType); 146 /** 147 * Sets the dynamic range. 148 * 149 * <p>If not set, the default dynamic range is {@link DynamicRange#SDR}. 150 */ setDynamicRange(@onNull DynamicRange dynamicRange)151 public abstract @NonNull Builder setDynamicRange(@NonNull DynamicRange dynamicRange); 152 153 /** 154 * Sets the expected frame rate range. 155 * 156 * <p>If not set, the default expected frame rate range is 157 * {@link #FRAME_RATE_RANGE_UNSPECIFIED}. 158 */ setExpectedFrameRateRange(@onNull Range<Integer> range)159 public abstract @NonNull Builder setExpectedFrameRateRange(@NonNull Range<Integer> range); 160 161 /** 162 * Sets the implementation options. 163 * 164 * <p>If not set, the default expected frame rate range is 165 * {@link CameraMetadata#SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT}. 166 */ setImplementationOptions(@onNull Config config)167 public abstract @NonNull Builder setImplementationOptions(@NonNull Config config); 168 169 /** 170 * Sets the flag if zero-shutter lag needs to be disabled by user case combinations. 171 */ setZslDisabled(boolean disabled)172 public abstract @NonNull Builder setZslDisabled(boolean disabled); 173 174 /** Builds the stream specification */ build()175 public abstract @NonNull StreamSpec build(); 176 } 177 178 } 179