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