OutputConfiguration.java revision 445b316755923565c3b5b8ebb642db10de5d0ab7
1/* 2 * Copyright (C) 2015 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 18package android.hardware.camera2.params; 19 20import android.annotation.SystemApi; 21import android.hardware.camera2.CameraDevice; 22import android.hardware.camera2.utils.HashCodeHelpers; 23import android.hardware.camera2.utils.SurfaceUtils; 24import android.util.Log; 25import android.util.Size; 26import android.view.Surface; 27import android.os.Parcel; 28import android.os.Parcelable; 29 30import static com.android.internal.util.Preconditions.*; 31 32/** 33 * A class for describing camera output, which contains a {@link Surface} and its specific 34 * configuration for creating capture session. 35 * 36 * @see CameraDevice#createCaptureSessionByOutputConfiguration 37 * 38 */ 39public final class OutputConfiguration implements Parcelable { 40 41 /** 42 * Rotation constant: 0 degree rotation (no rotation) 43 * 44 * @hide 45 */ 46 @SystemApi 47 public static final int ROTATION_0 = 0; 48 49 /** 50 * Rotation constant: 90 degree counterclockwise rotation. 51 * 52 * @hide 53 */ 54 @SystemApi 55 public static final int ROTATION_90 = 1; 56 57 /** 58 * Rotation constant: 180 degree counterclockwise rotation. 59 * 60 * @hide 61 */ 62 @SystemApi 63 public static final int ROTATION_180 = 2; 64 65 /** 66 * Rotation constant: 270 degree counterclockwise rotation. 67 * 68 * @hide 69 */ 70 @SystemApi 71 public static final int ROTATION_270 = 3; 72 73 /** 74 * Invalid surface set ID. 75 * 76 *<p>An {@link OutputConfiguration} with this value indicates that the included surface 77 *doesn't belong to any surface set.</p> 78 */ 79 public static final int SURFACE_SET_ID_INVALID = -1; 80 81 /** 82 * Create a new {@link OutputConfiguration} instance with a {@link Surface}. 83 * 84 * @param surface 85 * A Surface for camera to output to. 86 * 87 * <p>This constructor creates a default configuration.</p> 88 * 89 */ 90 public OutputConfiguration(Surface surface) { 91 this(surface, ROTATION_0); 92 } 93 94 /** 95 * Create a new {@link OutputConfiguration} instance. 96 * 97 * <p>This constructor takes an argument for desired camera rotation</p> 98 * 99 * @param surface 100 * A Surface for camera to output to. 101 * @param rotation 102 * The desired rotation to be applied on camera output. Value must be one of 103 * ROTATION_[0, 90, 180, 270]. Note that when the rotation is 90 or 270 degree, 104 * application should make sure corresponding surface size has width and height 105 * transposed corresponding to the width and height without rotation. For example, 106 * if application needs camera to capture 1280x720 picture and rotate it by 90 degree, 107 * application should set rotation to {@code ROTATION_90} and make sure the 108 * corresponding Surface size is 720x1280. Note that {@link CameraDevice} might 109 * throw {@code IllegalArgumentException} if device cannot perform such rotation. 110 * @hide 111 */ 112 @SystemApi 113 public OutputConfiguration(Surface surface, int rotation) { 114 checkNotNull(surface, "Surface must not be null"); 115 checkArgumentInRange(rotation, ROTATION_0, ROTATION_270, "Rotation constant"); 116 mSurfaceSetId = SURFACE_SET_ID_INVALID; 117 mSurface = surface; 118 mRotation = rotation; 119 mConfiguredSize = SurfaceUtils.getSurfaceSize(surface); 120 mConfiguredFormat = SurfaceUtils.getSurfaceFormat(surface); 121 mConfiguredDataspace = SurfaceUtils.getSurfaceDataspace(surface); 122 } 123 124 /** 125 * Create a new {@link OutputConfiguration} instance with another {@link OutputConfiguration} 126 * instance. 127 * 128 * @param other Another {@link OutputConfiguration} instance to be copied. 129 * 130 * @hide 131 */ 132 @SystemApi 133 public OutputConfiguration(OutputConfiguration other) { 134 if (other == null) { 135 throw new IllegalArgumentException("OutputConfiguration shouldn't be null"); 136 } 137 138 this.mSurface = other.mSurface; 139 this.mRotation = other.mRotation; 140 this.mSurfaceSetId = other.mSurfaceSetId; 141 this.mConfiguredDataspace = other.mConfiguredDataspace; 142 this.mConfiguredFormat = other.mConfiguredFormat; 143 this.mConfiguredSize = other.mConfiguredSize; 144 } 145 146 /** 147 * Create an OutputConfiguration from Parcel. 148 */ 149 private OutputConfiguration(Parcel source) { 150 int rotation = source.readInt(); 151 int surfaceSetId = source.readInt(); 152 Surface surface = Surface.CREATOR.createFromParcel(source); 153 checkNotNull(surface, "Surface must not be null"); 154 checkArgumentInRange(rotation, ROTATION_0, ROTATION_270, "Rotation constant"); 155 mSurfaceSetId = surfaceSetId; 156 mSurface = surface; 157 mRotation = rotation; 158 mConfiguredSize = SurfaceUtils.getSurfaceSize(mSurface); 159 mConfiguredFormat = SurfaceUtils.getSurfaceFormat(mSurface); 160 mConfiguredDataspace = SurfaceUtils.getSurfaceDataspace(mSurface); 161 } 162 163 /** 164 * Get the {@link Surface} associated with this {@link OutputConfiguration}. 165 * 166 * @return the {@link Surface} associated with this {@link OutputConfiguration}. 167 */ 168 public Surface getSurface() { 169 return mSurface; 170 } 171 172 /** 173 * Get the rotation associated with this {@link OutputConfiguration}. 174 * 175 * @return the rotation associated with this {@link OutputConfiguration}. 176 * Value will be one of ROTATION_[0, 90, 180, 270] 177 * 178 * @hide 179 */ 180 @SystemApi 181 public int getRotation() { 182 return mRotation; 183 } 184 185 /** 186 * Set the surface set ID to this {@link OutputConfiguration}. 187 * 188 * <p> 189 * A surface set ID is used to identify which surface set this output surface belongs to. A 190 * surface set is a group of output surfaces that are not intended to receive camera output 191 * buffer streams simultaneously. The {@link CameraDevice} may be able to share the buffers used 192 * by all the surfaces from the same surface set, therefore may save the overall memory 193 * footprint. The application should only set the same set ID for the streams that are not 194 * simultaneously streaming. A negative ID indicates that this surface doesn't belong to any 195 * surface set. The default value will be {@value #SURFACE_SET_ID_INVALID}. 196 * </p> 197 * 198 * @param setId 199 */ 200 public void setSurfaceSetId(int setId) { 201 if (setId < 0) { 202 setId = SURFACE_SET_ID_INVALID; 203 } 204 mSurfaceSetId = setId; 205 } 206 207 /** 208 * Get the surface set Id associated with this {@link OutputConfiguration}. 209 * 210 * @return the surface set Id associated with this {@link OutputConfiguration}. 211 * Value will be one of ROTATION_[0, 90, 180, 270] 212 */ 213 public int getSurfaceSetId() { 214 return mSurfaceSetId; 215 } 216 217 public static final Parcelable.Creator<OutputConfiguration> CREATOR = 218 new Parcelable.Creator<OutputConfiguration>() { 219 @Override 220 public OutputConfiguration createFromParcel(Parcel source) { 221 try { 222 OutputConfiguration outputConfiguration = new OutputConfiguration(source); 223 return outputConfiguration; 224 } catch (Exception e) { 225 Log.e(TAG, "Exception creating OutputConfiguration from parcel", e); 226 return null; 227 } 228 } 229 230 @Override 231 public OutputConfiguration[] newArray(int size) { 232 return new OutputConfiguration[size]; 233 } 234 }; 235 236 @Override 237 public int describeContents() { 238 return 0; 239 } 240 241 @Override 242 public void writeToParcel(Parcel dest, int flags) { 243 if (dest == null) { 244 throw new IllegalArgumentException("dest must not be null"); 245 } 246 dest.writeInt(mRotation); 247 dest.writeInt(mSurfaceSetId); 248 mSurface.writeToParcel(dest, flags); 249 } 250 251 /** 252 * Check if this {@link OutputConfiguration} is equal to another {@link OutputConfiguration}. 253 * 254 * <p>Two output configurations are only equal if and only if the underlying surfaces, surface 255 * properties (width, height, format, dataspace) when the output configurations are created, 256 * and all other configuration parameters are equal. </p> 257 * 258 * @return {@code true} if the objects were equal, {@code false} otherwise 259 */ 260 @Override 261 public boolean equals(Object obj) { 262 if (obj == null) { 263 return false; 264 } else if (this == obj) { 265 return true; 266 } else if (obj instanceof OutputConfiguration) { 267 final OutputConfiguration other = (OutputConfiguration) obj; 268 return mSurface == other.mSurface && 269 mRotation == other.mRotation && 270 mConfiguredSize.equals(other.mConfiguredSize) && 271 mConfiguredFormat == other.mConfiguredFormat && 272 mConfiguredDataspace == other.mConfiguredDataspace && 273 mSurfaceSetId == other.mSurfaceSetId; 274 } 275 return false; 276 } 277 278 /** 279 * {@inheritDoc} 280 */ 281 @Override 282 public int hashCode() { 283 return HashCodeHelpers.hashCode(mSurface.hashCode(), mRotation); 284 } 285 286 private static final String TAG = "OutputConfiguration"; 287 private final Surface mSurface; 288 private final int mRotation; 289 private int mSurfaceSetId; 290 291 // The size, format, and dataspace of the surface when OutputConfiguration is created. 292 private final Size mConfiguredSize; 293 private final int mConfiguredFormat; 294 private final int mConfiguredDataspace; 295} 296