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