• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 
18 package android.hardware.camera2.params;
19 
20 import static com.android.internal.util.Preconditions.*;
21 
22 import android.annotation.CallbackExecutor;
23 import android.annotation.IntDef;
24 import android.annotation.NonNull;
25 import android.annotation.Nullable;
26 import android.hardware.camera2.CameraCaptureSession;
27 import android.hardware.camera2.CameraCharacteristics;
28 import android.hardware.camera2.CameraDevice;
29 import android.hardware.camera2.CaptureRequest;
30 import android.hardware.camera2.params.InputConfiguration;
31 import android.hardware.camera2.params.OutputConfiguration;
32 import android.hardware.camera2.utils.HashCodeHelpers;
33 import android.os.Parcel;
34 import android.os.Parcelable;
35 import android.util.Log;
36 
37 import java.lang.annotation.Retention;
38 import java.lang.annotation.RetentionPolicy;
39 import java.util.ArrayList;
40 import java.util.Collections;
41 import java.util.List;
42 import java.util.concurrent.Executor;
43 
44 /**
45  * A helper class that aggregates all supported arguments for capture session initialization.
46  */
47 public final class SessionConfiguration implements Parcelable {
48     private static final String TAG = "SessionConfiguration";
49 
50     /**
51      * A regular session type containing instances of {@link OutputConfiguration} running
52      * at regular non high speed FPS ranges and optionally {@link InputConfiguration} for
53      * reprocessable sessions.
54      *
55      * @see CameraDevice#createCaptureSession
56      * @see CameraDevice#createReprocessableCaptureSession
57      */
58     public static final int SESSION_REGULAR = CameraDevice.SESSION_OPERATION_MODE_NORMAL;
59 
60     /**
61      * A high speed session type that can only contain instances of {@link OutputConfiguration}.
62      * The outputs can run using high speed FPS ranges. Calls to {@link #setInputConfiguration}
63      * are not supported.
64      * <p>
65      * When using this type, the CameraCaptureSession returned by
66      * {@link android.hardware.camera2.CameraCaptureSession.StateCallback} can be cast to a
67      * {@link android.hardware.camera2.CameraConstrainedHighSpeedCaptureSession} to access the extra
68      * methods for constrained high speed recording.
69      * </p>
70      *
71      * @see CameraDevice#createConstrainedHighSpeedCaptureSession
72      */
73     public static final int SESSION_HIGH_SPEED =
74         CameraDevice.SESSION_OPERATION_MODE_CONSTRAINED_HIGH_SPEED;
75 
76     /**
77      * First vendor-specific session mode
78      * @hide
79      */
80     public static final int SESSION_VENDOR_START =
81         CameraDevice.SESSION_OPERATION_MODE_VENDOR_START;
82 
83      /** @hide */
84     @Retention(RetentionPolicy.SOURCE)
85     @IntDef(prefix = {"SESSION_"}, value =
86             {SESSION_REGULAR,
87              SESSION_HIGH_SPEED })
88     public @interface SessionMode {};
89 
90     // Camera capture session related parameters.
91     private List<OutputConfiguration> mOutputConfigurations;
92     private CameraCaptureSession.StateCallback mStateCallback;
93     private int mSessionType;
94     private Executor mExecutor = null;
95     private InputConfiguration mInputConfig = null;
96     private CaptureRequest mSessionParameters = null;
97 
98     /**
99      * Create a new {@link SessionConfiguration}.
100      *
101      * @param sessionType The session type.
102      * @param outputs A list of output configurations for the capture session.
103      * @param executor The executor which should be used to invoke the callback. In general it is
104      *                 recommended that camera operations are not done on the main (UI) thread.
105      * @param cb A state callback interface implementation.
106      *
107      * @see #SESSION_REGULAR
108      * @see #SESSION_HIGH_SPEED
109      * @see CameraDevice#createCaptureSession(List, CameraCaptureSession.StateCallback, Handler)
110      * @see CameraDevice#createCaptureSessionByOutputConfigurations
111      * @see CameraDevice#createReprocessableCaptureSession
112      * @see CameraDevice#createConstrainedHighSpeedCaptureSession
113      */
SessionConfiguration(@essionMode int sessionType, @NonNull List<OutputConfiguration> outputs, @NonNull @CallbackExecutor Executor executor, @NonNull CameraCaptureSession.StateCallback cb)114     public SessionConfiguration(@SessionMode int sessionType,
115             @NonNull List<OutputConfiguration> outputs,
116             @NonNull @CallbackExecutor Executor executor,
117             @NonNull CameraCaptureSession.StateCallback cb) {
118         mSessionType = sessionType;
119         mOutputConfigurations = Collections.unmodifiableList(new ArrayList<>(outputs));
120         mStateCallback = cb;
121         mExecutor = executor;
122     }
123 
124     /**
125      * Create a SessionConfiguration from Parcel.
126      * No support for parcelable 'mStateCallback', 'mExecutor' and 'mSessionParameters' yet.
127      */
SessionConfiguration(@onNull Parcel source)128     private SessionConfiguration(@NonNull Parcel source) {
129         int sessionType = source.readInt();
130         int inputWidth = source.readInt();
131         int inputHeight = source.readInt();
132         int inputFormat = source.readInt();
133         boolean isInputMultiResolution = source.readBoolean();
134         ArrayList<OutputConfiguration> outConfigs = new ArrayList<OutputConfiguration>();
135         source.readTypedList(outConfigs, OutputConfiguration.CREATOR);
136 
137         if ((inputWidth > 0) && (inputHeight > 0) && (inputFormat != -1)) {
138             mInputConfig = new InputConfiguration(inputWidth, inputHeight,
139                     inputFormat, isInputMultiResolution);
140         }
141         mSessionType = sessionType;
142         mOutputConfigurations = outConfigs;
143     }
144 
145     public static final @android.annotation.NonNull Parcelable.Creator<SessionConfiguration> CREATOR =
146             new Parcelable.Creator<SessionConfiguration> () {
147         @Override
148         public SessionConfiguration createFromParcel(Parcel source) {
149             return new SessionConfiguration(source);
150         }
151 
152         @Override
153         public SessionConfiguration[] newArray(int size) {
154             return new SessionConfiguration[size];
155         }
156     };
157 
158     @Override
writeToParcel(Parcel dest, int flags)159     public void writeToParcel(Parcel dest, int flags) {
160         if (dest == null) {
161             throw new IllegalArgumentException("dest must not be null");
162         }
163         dest.writeInt(mSessionType);
164         if (mInputConfig != null) {
165             dest.writeInt(mInputConfig.getWidth());
166             dest.writeInt(mInputConfig.getHeight());
167             dest.writeInt(mInputConfig.getFormat());
168             dest.writeBoolean(mInputConfig.isMultiResolution());
169         } else {
170             dest.writeInt(/*inputWidth*/ 0);
171             dest.writeInt(/*inputHeight*/ 0);
172             dest.writeInt(/*inputFormat*/ -1);
173             dest.writeBoolean(/*isMultiResolution*/ false);
174         }
175         dest.writeTypedList(mOutputConfigurations);
176     }
177 
178     @Override
describeContents()179     public int describeContents() {
180         return 0;
181     }
182 
183     /**
184      * Check if this {@link SessionConfiguration} is equal to another {@link SessionConfiguration}.
185      *
186      * <p>Two output session configurations are only equal if and only if the underlying input
187      * configuration, output configurations, and session type are equal. </p>
188      *
189      * @return {@code true} if the objects were equal, {@code false} otherwise
190      */
191     @Override
equals(@ullable Object obj)192     public boolean equals(@Nullable Object obj) {
193         if (obj == null) {
194             return false;
195         } else if (this == obj) {
196             return true;
197         } else if (obj instanceof SessionConfiguration) {
198             final SessionConfiguration other = (SessionConfiguration) obj;
199             if (mInputConfig != other.mInputConfig || mSessionType != other.mSessionType ||
200                     mOutputConfigurations.size() != other.mOutputConfigurations.size()) {
201                 return false;
202             }
203 
204             for (int i = 0;  i < mOutputConfigurations.size(); i++) {
205                 if (!mOutputConfigurations.get(i).equals(other.mOutputConfigurations.get(i)))
206                     return false;
207             }
208 
209             return true;
210         }
211 
212         return false;
213     }
214 
215     /**
216      * {@inheritDoc}
217      */
218     @Override
hashCode()219     public int hashCode() {
220         return HashCodeHelpers.hashCode(mOutputConfigurations.hashCode(), mInputConfig.hashCode(),
221                 mSessionType);
222     }
223 
224     /**
225      * Retrieve the type of the capture session.
226      *
227      * @return The capture session type.
228      */
getSessionType()229     public @SessionMode int getSessionType() {
230         return mSessionType;
231     }
232 
233     /**
234      * Retrieve the {@link OutputConfiguration} list for the capture session.
235      *
236      * @return A list of output configurations for the capture session.
237      */
getOutputConfigurations()238     public List<OutputConfiguration> getOutputConfigurations() {
239         return mOutputConfigurations;
240     }
241 
242     /**
243      * Retrieve the {@link CameraCaptureSession.StateCallback} for the capture session.
244      *
245      * @return A state callback interface implementation.
246      */
getStateCallback()247     public CameraCaptureSession.StateCallback getStateCallback() {
248         return mStateCallback;
249     }
250 
251     /**
252      * Retrieve the {@link java.util.concurrent.Executor} for the capture session.
253      *
254      * @return The Executor on which the callback will be invoked.
255      */
getExecutor()256     public Executor getExecutor() {
257         return mExecutor;
258     }
259 
260     /**
261      * Sets the {@link InputConfiguration} for a reprocessable session. Input configuration are not
262      * supported for {@link #SESSION_HIGH_SPEED}.
263      *
264      * @param input Input configuration.
265      * @throws UnsupportedOperationException In case it is called for {@link #SESSION_HIGH_SPEED}
266      *                                       type session configuration.
267      */
setInputConfiguration(@onNull InputConfiguration input)268     public void setInputConfiguration(@NonNull InputConfiguration input) {
269         if (mSessionType != SESSION_HIGH_SPEED) {
270             mInputConfig = input;
271         } else {
272             throw new UnsupportedOperationException("Method not supported for high speed session" +
273                     " types");
274         }
275     }
276 
277     /**
278      * Retrieve the {@link InputConfiguration}.
279      *
280      * @return The capture session input configuration.
281      */
getInputConfiguration()282     public InputConfiguration getInputConfiguration() {
283         return mInputConfig;
284     }
285 
286     /**
287      * Sets the session wide camera parameters (see {@link CaptureRequest}). This argument can
288      * be set for every supported session type and will be passed to the camera device as part
289      * of the capture session initialization. Session parameters are a subset of the available
290      * capture request parameters (see {@link CameraCharacteristics#getAvailableSessionKeys})
291      * and their application can introduce internal camera delays. To improve camera performance
292      * it is suggested to change them sparingly within the lifetime of the capture session and
293      * to pass their initial values as part of this method.
294      *
295      * @param params A capture request that includes the initial values for any available
296      *               session wide capture keys. Tags (see {@link CaptureRequest.Builder#setTag}) and
297      *               output targets (see {@link CaptureRequest.Builder#addTarget}) are ignored if
298      *               set. Parameter values not part of
299      *               {@link CameraCharacteristics#getAvailableSessionKeys} will also be ignored. It
300      *               is recommended to build the session parameters using the same template type as
301      *               the initial capture request, so that the session and initial request parameters
302      *               match as much as possible.
303      */
setSessionParameters(CaptureRequest params)304     public void setSessionParameters(CaptureRequest params) {
305         mSessionParameters = params;
306     }
307 
308     /**
309      * Retrieve the session wide camera parameters (see {@link CaptureRequest}).
310      *
311      * @return A capture request that includes the initial values for any available
312      *         session wide capture keys.
313      */
getSessionParameters()314     public CaptureRequest getSessionParameters() {
315         return mSessionParameters;
316     }
317 }
318