| /* |
| * Copyright (C) 2017 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 android.hardware.camera2.params; |
| |
| import static com.android.internal.util.Preconditions.*; |
| |
| import android.annotation.CallbackExecutor; |
| import android.annotation.IntDef; |
| import android.annotation.NonNull; |
| import android.hardware.camera2.CameraCaptureSession; |
| import android.hardware.camera2.CameraCharacteristics; |
| import android.hardware.camera2.CameraDevice; |
| import android.hardware.camera2.CaptureRequest; |
| import android.hardware.camera2.params.InputConfiguration; |
| import android.hardware.camera2.params.OutputConfiguration; |
| import android.hardware.camera2.utils.HashCodeHelpers; |
| import android.os.Parcel; |
| import android.os.Parcelable; |
| import android.util.Log; |
| |
| import java.lang.annotation.Retention; |
| import java.lang.annotation.RetentionPolicy; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.concurrent.Executor; |
| |
| /** |
| * A helper class that aggregates all supported arguments for capture session initialization. |
| */ |
| public final class SessionConfiguration implements Parcelable { |
| private static final String TAG = "SessionConfiguration"; |
| |
| /** |
| * A regular session type containing instances of {@link OutputConfiguration} running |
| * at regular non high speed FPS ranges and optionally {@link InputConfiguration} for |
| * reprocessable sessions. |
| * |
| * @see CameraDevice#createCaptureSession |
| * @see CameraDevice#createReprocessableCaptureSession |
| */ |
| public static final int SESSION_REGULAR = CameraDevice.SESSION_OPERATION_MODE_NORMAL; |
| |
| /** |
| * A high speed session type that can only contain instances of {@link OutputConfiguration}. |
| * The outputs can run using high speed FPS ranges. Calls to {@link #setInputConfiguration} |
| * are not supported. |
| * <p> |
| * When using this type, the CameraCaptureSession returned by |
| * {@link android.hardware.camera2.CameraCaptureSession.StateCallback} can be cast to a |
| * {@link android.hardware.camera2.CameraConstrainedHighSpeedCaptureSession} to access the extra |
| * methods for constrained high speed recording. |
| * </p> |
| * |
| * @see CameraDevice#createConstrainedHighSpeedCaptureSession |
| */ |
| public static final int SESSION_HIGH_SPEED = |
| CameraDevice.SESSION_OPERATION_MODE_CONSTRAINED_HIGH_SPEED; |
| |
| /** |
| * First vendor-specific session mode |
| * @hide |
| */ |
| public static final int SESSION_VENDOR_START = |
| CameraDevice.SESSION_OPERATION_MODE_VENDOR_START; |
| |
| /** @hide */ |
| @Retention(RetentionPolicy.SOURCE) |
| @IntDef(prefix = {"SESSION_"}, value = |
| {SESSION_REGULAR, |
| SESSION_HIGH_SPEED }) |
| public @interface SessionMode {}; |
| |
| // Camera capture session related parameters. |
| private List<OutputConfiguration> mOutputConfigurations; |
| private CameraCaptureSession.StateCallback mStateCallback; |
| private int mSessionType; |
| private Executor mExecutor = null; |
| private InputConfiguration mInputConfig = null; |
| private CaptureRequest mSessionParameters = null; |
| |
| /** |
| * Create a new {@link SessionConfiguration}. |
| * |
| * @param sessionType The session type. |
| * @param outputs A list of output configurations for the capture session. |
| * @param executor The executor which should be used to invoke the callback. In general it is |
| * recommended that camera operations are not done on the main (UI) thread. |
| * @param cb A state callback interface implementation. |
| * |
| * @see #SESSION_REGULAR |
| * @see #SESSION_HIGH_SPEED |
| * @see CameraDevice#createCaptureSession(List, CameraCaptureSession.StateCallback, Handler) |
| * @see CameraDevice#createCaptureSessionByOutputConfigurations |
| * @see CameraDevice#createReprocessableCaptureSession |
| * @see CameraDevice#createConstrainedHighSpeedCaptureSession |
| */ |
| public SessionConfiguration(@SessionMode int sessionType, |
| @NonNull List<OutputConfiguration> outputs, |
| @NonNull @CallbackExecutor Executor executor, |
| @NonNull CameraCaptureSession.StateCallback cb) { |
| mSessionType = sessionType; |
| mOutputConfigurations = Collections.unmodifiableList(new ArrayList<>(outputs)); |
| mStateCallback = cb; |
| mExecutor = executor; |
| } |
| |
| /** |
| * Create a SessionConfiguration from Parcel. |
| * No support for parcelable 'mStateCallback', 'mExecutor' and 'mSessionParameters' yet. |
| */ |
| private SessionConfiguration(@NonNull Parcel source) { |
| int sessionType = source.readInt(); |
| int inputWidth = source.readInt(); |
| int inputHeight = source.readInt(); |
| int inputFormat = source.readInt(); |
| ArrayList<OutputConfiguration> outConfigs = new ArrayList<OutputConfiguration>(); |
| source.readTypedList(outConfigs, OutputConfiguration.CREATOR); |
| |
| if ((inputWidth > 0) && (inputHeight > 0) && (inputFormat != -1)) { |
| mInputConfig = new InputConfiguration(inputWidth, inputHeight, inputFormat); |
| } |
| mSessionType = sessionType; |
| mOutputConfigurations = outConfigs; |
| } |
| |
| public static final @android.annotation.NonNull Parcelable.Creator<SessionConfiguration> CREATOR = |
| new Parcelable.Creator<SessionConfiguration> () { |
| @Override |
| public SessionConfiguration createFromParcel(Parcel source) { |
| try { |
| SessionConfiguration sessionConfiguration = new SessionConfiguration(source); |
| return sessionConfiguration; |
| } catch (Exception e) { |
| Log.e(TAG, "Exception creating SessionConfiguration from parcel", e); |
| return null; |
| } |
| } |
| |
| @Override |
| public SessionConfiguration[] newArray(int size) { |
| return new SessionConfiguration[size]; |
| } |
| }; |
| |
| @Override |
| public void writeToParcel(Parcel dest, int flags) { |
| if (dest == null) { |
| throw new IllegalArgumentException("dest must not be null"); |
| } |
| dest.writeInt(mSessionType); |
| if (mInputConfig != null) { |
| dest.writeInt(mInputConfig.getWidth()); |
| dest.writeInt(mInputConfig.getHeight()); |
| dest.writeInt(mInputConfig.getFormat()); |
| } else { |
| dest.writeInt(/*inputWidth*/ 0); |
| dest.writeInt(/*inputHeight*/ 0); |
| dest.writeInt(/*inputFormat*/ -1); |
| } |
| dest.writeTypedList(mOutputConfigurations); |
| } |
| |
| @Override |
| public int describeContents() { |
| return 0; |
| } |
| |
| /** |
| * Check if this {@link SessionConfiguration} is equal to another {@link SessionConfiguration}. |
| * |
| * <p>Two output session configurations are only equal if and only if the underlying input |
| * configuration, output configurations, and session type are equal. </p> |
| * |
| * @return {@code true} if the objects were equal, {@code false} otherwise |
| */ |
| @Override |
| public boolean equals(Object obj) { |
| if (obj == null) { |
| return false; |
| } else if (this == obj) { |
| return true; |
| } else if (obj instanceof SessionConfiguration) { |
| final SessionConfiguration other = (SessionConfiguration) obj; |
| if (mInputConfig != other.mInputConfig || mSessionType != other.mSessionType || |
| mOutputConfigurations.size() != other.mOutputConfigurations.size()) { |
| return false; |
| } |
| |
| for (int i = 0; i < mOutputConfigurations.size(); i++) { |
| if (!mOutputConfigurations.get(i).equals(other.mOutputConfigurations.get(i))) |
| return false; |
| } |
| |
| return true; |
| } |
| |
| return false; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public int hashCode() { |
| return HashCodeHelpers.hashCode(mOutputConfigurations.hashCode(), mInputConfig.hashCode(), |
| mSessionType); |
| } |
| |
| /** |
| * Retrieve the type of the capture session. |
| * |
| * @return The capture session type. |
| */ |
| public @SessionMode int getSessionType() { |
| return mSessionType; |
| } |
| |
| /** |
| * Retrieve the {@link OutputConfiguration} list for the capture session. |
| * |
| * @return A list of output configurations for the capture session. |
| */ |
| public List<OutputConfiguration> getOutputConfigurations() { |
| return mOutputConfigurations; |
| } |
| |
| /** |
| * Retrieve the {@link CameraCaptureSession.StateCallback} for the capture session. |
| * |
| * @return A state callback interface implementation. |
| */ |
| public CameraCaptureSession.StateCallback getStateCallback() { |
| return mStateCallback; |
| } |
| |
| /** |
| * Retrieve the {@link java.util.concurrent.Executor} for the capture session. |
| * |
| * @return The Executor on which the callback will be invoked. |
| */ |
| public Executor getExecutor() { |
| return mExecutor; |
| } |
| |
| /** |
| * Sets the {@link InputConfiguration} for a reprocessable session. Input configuration are not |
| * supported for {@link #SESSION_HIGH_SPEED}. |
| * |
| * @param input Input configuration. |
| * @throws UnsupportedOperationException In case it is called for {@link #SESSION_HIGH_SPEED} |
| * type session configuration. |
| */ |
| public void setInputConfiguration(@NonNull InputConfiguration input) { |
| if (mSessionType != SESSION_HIGH_SPEED) { |
| mInputConfig = input; |
| } else { |
| throw new UnsupportedOperationException("Method not supported for high speed session" + |
| " types"); |
| } |
| } |
| |
| /** |
| * Retrieve the {@link InputConfiguration}. |
| * |
| * @return The capture session input configuration. |
| */ |
| public InputConfiguration getInputConfiguration() { |
| return mInputConfig; |
| } |
| |
| /** |
| * Sets the session wide camera parameters (see {@link CaptureRequest}). This argument can |
| * be set for every supported session type and will be passed to the camera device as part |
| * of the capture session initialization. Session parameters are a subset of the available |
| * capture request parameters (see {@link CameraCharacteristics#getAvailableSessionKeys}) |
| * and their application can introduce internal camera delays. To improve camera performance |
| * it is suggested to change them sparingly within the lifetime of the capture session and |
| * to pass their initial values as part of this method. |
| * |
| * @param params A capture request that includes the initial values for any available |
| * session wide capture keys. Tags (see {@link CaptureRequest.Builder#setTag}) and |
| * output targets (see {@link CaptureRequest.Builder#addTarget}) are ignored if |
| * set. Parameter values not part of |
| * {@link CameraCharacteristics#getAvailableSessionKeys} will also be ignored. It |
| * is recommended to build the session parameters using the same template type as |
| * the initial capture request, so that the session and initial request parameters |
| * match as much as possible. |
| */ |
| public void setSessionParameters(CaptureRequest params) { |
| mSessionParameters = params; |
| } |
| |
| /** |
| * Retrieve the session wide camera parameters (see {@link CaptureRequest}). |
| * |
| * @return A capture request that includes the initial values for any available |
| * session wide capture keys. |
| */ |
| public CaptureRequest getSessionParameters() { |
| return mSessionParameters; |
| } |
| } |