1 /* 2 * Copyright (C) 2024 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 android.hardware.camera2.params; 18 19 import android.annotation.FlaggedApi; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.SuppressLint; 23 import android.annotation.SystemApi; 24 import android.annotation.TestApi; 25 import android.graphics.ColorSpace; 26 import android.graphics.ImageFormat.Format; 27 import android.hardware.DataSpace.NamedDataSpace; 28 import android.hardware.HardwareBuffer.Usage; 29 import android.hardware.camera2.params.OutputConfiguration.MirrorMode; 30 import android.hardware.camera2.params.OutputConfiguration.StreamUseCase; 31 import android.hardware.camera2.params.OutputConfiguration.TimestampBase; 32 import android.util.Log; 33 import android.util.Size; 34 35 import com.android.internal.camera.flags.Flags; 36 37 import java.util.ArrayList; 38 import java.util.Collections; 39 import java.util.List; 40 41 /** 42 * Immutable class to store the shared session configuration 43 * {@link CameraCharacteristics#SHARED_SESSION_CONFIGURATION} to set up 44 * {@link android.view.Surface Surfaces} for creating a 45 * {@link android.hardware.camera2.CameraSharedCaptureSession capture session} using 46 * {@link android.hardware.camera2.CameraDevice#createCaptureSession(SessionConfiguration)} and 47 * {@link android.hardware.camera2.params.SessionConfiguration#SESSION_SHARED 48 * shared capture session} when camera has been opened in shared mode using 49 * {@link #openSharedCamera(String, Executor, StateCallback)}. 50 * 51 * <p>This is the authoritative list for all output configurations that are supported by a camera 52 * device when opened in shared mode.</p> 53 * 54 * <p>An instance of this object is available from {@link CameraCharacteristics} using 55 * the {@link CameraCharacteristics#SHARED_SESSION_CONFIGURATION} key and the 56 * {@link CameraCharacteristics#get} method.</p> 57 * 58 * <pre><code>{@code 59 * CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId); 60 * StreamConfigurationMap configs = characteristics.get( 61 * CameraCharacteristics.SHARED_SESSION_CONFIGURATION); 62 * }</code></pre> 63 * 64 * @see CameraCharacteristics#SHARED_SESSION_CONFIGURATION 65 * @see CameraDevice#createCaptureSession(SessionConfiguration) 66 * @see SessionConfiguration#SESSION_SHARED 67 * @see CameraManager#openSharedCamera(String, Executor, StateCallback) 68 * 69 * @hide 70 */ 71 @SystemApi 72 @FlaggedApi(Flags.FLAG_CAMERA_MULTI_CLIENT) 73 public final class SharedSessionConfiguration { 74 private static final String TAG = "SharedSessionConfiguration"; 75 // Metadata android.info.availableSharedOutputConfigurations has list of shared output 76 // configurations. Each output configuration has minimum of 11 entries of size long 77 // followed by the physical camera id if present. 78 // See android.info.availableSharedOutputConfigurations for details. 79 private static final int SHARED_OUTPUT_CONFIG_NUM_OF_ENTRIES = 11; 80 /** 81 * Immutable class to store shared output stream information. 82 */ 83 public static final class SharedOutputConfiguration { 84 private final int mSurfaceType; 85 private final Size mSize; 86 private final int mFormat; 87 private final int mDataspace; 88 private final long mStreamUseCase; 89 private String mPhysicalCameraId; 90 private final long mUsage; 91 private int mTimestampBase; 92 private int mMirrorMode; 93 private boolean mReadoutTimestampEnabled; 94 95 /** 96 * Create a new {@link SharedOutputConfiguration}. 97 * 98 * @param surfaceType Surface Type for this output configuration. 99 * @param sz Size for this output configuration. 100 * @param format {@link android.graphics.ImageFormat#Format} associated with this 101 * {@link OutputConfiguration}. 102 * @param mirrorMode {@link OutputConfiguration#MirrorMode} for this output configuration. 103 * @param readoutTimeStampEnabled Flag indicating whether readout timestamp is enabled 104 * for this output configuration. 105 * @param timestampBase {@link OutputConfiguration#TimestampBase} for this output 106 * configuration. 107 * @param dataspace {@link Dataspace#NamedDataSpace} for this output configuration. 108 * @param usage {@link HardwareBuffer#Usage} for this output configuration. 109 * @param streamUseCase {@link OutputConfiguration#StreamUseCase} for this output 110 * configuration. 111 * @param physicalCamId Physical Camera Id for this output configuration. 112 * 113 * @hide 114 */ SharedOutputConfiguration(int surfaceType, @NonNull Size sz, @Format int format, @MirrorMode int mirrorMode, boolean readoutTimeStampEnabled, @TimestampBase int timestampBase, @NamedDataSpace int dataspace, @Usage long usage, @StreamUseCase long streamUseCase, @Nullable String physicalCamId)115 public SharedOutputConfiguration(int surfaceType, @NonNull Size sz, @Format int format, 116 @MirrorMode int mirrorMode, boolean readoutTimeStampEnabled, 117 @TimestampBase int timestampBase, @NamedDataSpace int dataspace, @Usage long usage, 118 @StreamUseCase long streamUseCase, @Nullable String physicalCamId) { 119 mSurfaceType = surfaceType; 120 mSize = sz; 121 mFormat = format; 122 mMirrorMode = mirrorMode; 123 mReadoutTimestampEnabled = readoutTimeStampEnabled; 124 mTimestampBase = timestampBase; 125 mDataspace = dataspace; 126 mUsage = usage; 127 mStreamUseCase = streamUseCase; 128 mPhysicalCameraId = physicalCamId; 129 } 130 131 /** 132 * Returns the surface type configured for the shared output configuration. 133 * @return SURFACE_TYPE_UNKNOWN = -1 134 * SURFACE_TYPE_SURFACE_VIEW = 0 135 * SURFACE_TYPE_SURFACE_TEXTURE = 1 136 * SURFACE_TYPE_MEDIA_RECORDER = 2 137 * SURFACE_TYPE_MEDIA_CODEC = 3 138 * SURFACE_TYPE_IMAGE_READER = 4 139 */ getSurfaceType()140 public int getSurfaceType() { 141 return mSurfaceType; 142 } 143 144 /** 145 * Returns the format of the shared output configuration. 146 * @return format The format of the configured output. This must be one of the 147 * {@link android.graphics.ImageFormat} or {@link android.graphics.PixelFormat} 148 * constants. Note that not all formats are supported by the camera device. 149 */ getFormat()150 public @Format int getFormat() { 151 return mFormat; 152 } 153 154 /** 155 * Returns the configured size for the shared output configuration. 156 * @return surfaceSize Size for the shared output configuration 157 * 158 */ getSize()159 public @NonNull Size getSize() { 160 return mSize; 161 } 162 163 /** 164 * Return datatspace configured for the shared output configuration. 165 * 166 * @return {@link Dataspace#NamedDataSpace} configured for shared session 167 */ getDataspace()168 public @NamedDataSpace int getDataspace() { 169 return mDataspace; 170 } 171 172 /** 173 * Get the mirroring mode configured for the shared output configuration. 174 * 175 * @return {@link OutputConfiguration#MirrorMode} configured for the shared session 176 */ getMirrorMode()177 public @MirrorMode int getMirrorMode() { 178 return mMirrorMode; 179 } 180 181 /** 182 * Get the stream use case configured for the shared output configuration. 183 * 184 * @return {@link OutputConfiguration#StreamUseCase} configured for the shared session 185 */ getStreamUseCase()186 public @StreamUseCase long getStreamUseCase() { 187 return mStreamUseCase; 188 } 189 190 /** 191 * Get the timestamp base configured for the shared output configuration. 192 * 193 * @return {@link OutputConfiguration#TimestampBase} configured for the shared session 194 */ getTimestampBase()195 public @TimestampBase int getTimestampBase() { 196 return mTimestampBase; 197 } 198 199 /** Whether readout timestamp is used for this shared output configuration. 200 * 201 */ isReadoutTimestampEnabled()202 public boolean isReadoutTimestampEnabled() { 203 return mReadoutTimestampEnabled; 204 } 205 206 /** Returns the usage if set for this shared output configuration. 207 * 208 * @return {@link HardwareBuffer#Usage} flags if set for shared output configuration with 209 * the ImageReader output surface. 210 */ getUsage()211 public @Usage long getUsage() { 212 return mUsage; 213 } 214 getPhysicalCameraId()215 public @Nullable String getPhysicalCameraId() { 216 return mPhysicalCameraId.isEmpty() ? null : mPhysicalCameraId; 217 } 218 } 219 220 /** 221 * Create a new {@link SharedSessionConfiguration}. 222 * 223 * <p>The array parameters ownership is passed to this object after creation; do not 224 * write to them after this constructor is invoked.</p> 225 * 226 * @param sharedColorSpace the colorspace to be used for the shared output configurations. 227 * @param sharedOutputConfigurations a non-{@code null} array of metadata 228 * android.info.availableSharedOutputConfigurations 229 * 230 * @hide 231 */ 232 @TestApi SharedSessionConfiguration(int sharedColorSpace, @NonNull long[] sharedOutputConfigurations)233 public SharedSessionConfiguration(int sharedColorSpace, 234 @NonNull long[] sharedOutputConfigurations) { 235 mColorSpace = sharedColorSpace; 236 byte physicalCameraIdLen; 237 int surfaceType, width, height, format, mirrorMode, timestampBase, dataspace; 238 long usage, streamUseCase; 239 boolean isReadOutTimestampEnabled; 240 // Parse metadata android.info.availableSharedOutputConfigurations which contains 241 // list of shared output configurations. 242 int numOfEntries = sharedOutputConfigurations.length; 243 int i = 0; 244 while (numOfEntries >= SharedSessionConfiguration.SHARED_OUTPUT_CONFIG_NUM_OF_ENTRIES) { 245 surfaceType = (int) sharedOutputConfigurations[i]; 246 width = (int) sharedOutputConfigurations[i + 1]; 247 height = (int) sharedOutputConfigurations[i + 2]; 248 format = (int) sharedOutputConfigurations[i + 3]; 249 mirrorMode = (int) sharedOutputConfigurations[i + 4]; 250 isReadOutTimestampEnabled = (sharedOutputConfigurations[i + 5] != 0); 251 timestampBase = (int) sharedOutputConfigurations[i + 6]; 252 dataspace = (int) sharedOutputConfigurations[i + 7]; 253 usage = sharedOutputConfigurations[i + 8]; 254 streamUseCase = sharedOutputConfigurations[i + 9]; 255 physicalCameraIdLen = (byte) sharedOutputConfigurations[i + 10]; 256 numOfEntries -= SharedSessionConfiguration.SHARED_OUTPUT_CONFIG_NUM_OF_ENTRIES; 257 i += SharedSessionConfiguration.SHARED_OUTPUT_CONFIG_NUM_OF_ENTRIES; 258 if (numOfEntries < physicalCameraIdLen) { 259 Log.e(TAG, "Number of remaining data in shared configuration is less than" 260 + " physical camera id length . Malformed metadata" 261 + " android.info.availableSharedOutputConfigurations."); 262 break; 263 } 264 StringBuilder physicalCameraId = new StringBuilder(); 265 long asciiValue; 266 for (int j = 0; j < physicalCameraIdLen; j++) { 267 asciiValue = sharedOutputConfigurations[i + j]; 268 if (asciiValue == 0) { // Check for null terminator 269 break; 270 } 271 physicalCameraId.append((char) asciiValue); 272 } 273 SharedOutputConfiguration outputInfo; 274 outputInfo = new SharedOutputConfiguration(surfaceType, new Size(width, height), 275 format, mirrorMode, isReadOutTimestampEnabled, timestampBase, 276 dataspace, usage, streamUseCase, physicalCameraId.toString()); 277 mOutputStreamConfigurations.add(outputInfo); 278 i += physicalCameraIdLen; 279 numOfEntries -= physicalCameraIdLen; 280 } 281 if (numOfEntries != 0) { 282 Log.e(TAG, "Unexpected entries left in shared output configuration." 283 + " Malformed metadata android.info.availableSharedOutputConfigurations."); 284 } 285 } 286 287 /** 288 * Return the shared session color space which is configured. 289 * 290 * @return the shared session color space 291 */ 292 @SuppressLint("MethodNameUnits") getColorSpace()293 public @Nullable ColorSpace getColorSpace() { 294 if (mColorSpace != ColorSpaceProfiles.UNSPECIFIED) { 295 return ColorSpace.get(ColorSpace.Named.values()[mColorSpace]); 296 } else { 297 return null; 298 } 299 } 300 /** 301 * Get information about each shared output configuarion in the shared session. 302 * 303 * @return Non-modifiable list of output configuration. 304 * 305 */ getOutputStreamsInformation()306 public @NonNull List<SharedOutputConfiguration> getOutputStreamsInformation() { 307 return Collections.unmodifiableList(mOutputStreamConfigurations); 308 } 309 310 private int mColorSpace; 311 private final ArrayList<SharedOutputConfiguration> mOutputStreamConfigurations = 312 new ArrayList<SharedOutputConfiguration>(); 313 } 314 315