• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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