1 /* 2 * Copyright 2021 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 androidx.camera.core.impl; 18 19 import android.hardware.camera2.CameraCharacteristics; 20 import android.hardware.camera2.CameraExtensionSession; 21 import android.media.ImageReader; 22 import android.os.Build; 23 import android.util.Pair; 24 import android.util.Range; 25 import android.util.Size; 26 27 import androidx.annotation.IntRange; 28 import androidx.camera.core.CameraInfo; 29 30 import org.jspecify.annotations.NonNull; 31 import org.jspecify.annotations.Nullable; 32 33 import java.util.Collections; 34 import java.util.List; 35 import java.util.Map; 36 import java.util.Set; 37 38 /** 39 * A processor for (1) transforming the surfaces used in Preview/ImageCapture/ImageAnalysis 40 * into final session configuration where intermediate {@link ImageReader}s could be created for 41 * processing the image and writing the result to output surfaces (2) performing repeating request 42 * and still image capture by using {@link RequestProcessor}. 43 * 44 * <p>A {@link RequestProcessor} will be passed to the {@link SessionProcessor} when 45 * {@link SessionProcessor#onCaptureSessionStart(RequestProcessor)} is called to execute camera 46 * requests. When being requested to execute repeating request or still capture, the 47 * SessionProcessor can set any target surfaces and parameters it needs. It can also send 48 * multiple requests if necessary. 49 * 50 * <p>The SessionProcessor is expected to release all intermediate {@link ImageReader}s when 51 * {@link #deInitSession()} is called. 52 */ 53 public interface SessionProcessor { 54 /** 55 * The session processor is used for CameraX extension modes that will directly access the 56 * vendor library implementation. 57 */ 58 int TYPE_VENDOR_LIBRARY = 0; 59 60 /** 61 * The session processor is used for Camera2 extension modes that should create the capture 62 * session via Camera2 Extensions API. 63 */ 64 int TYPE_CAMERA2_EXTENSION = 1; 65 66 /** 67 * Initializes the session and returns a transformed {@link SessionConfig} which should be 68 * used to configure the camera instead of original one. 69 * 70 * <p>Output surfaces of preview, image capture and imageAnalysis should be passed in. The 71 * SessionProcessor is responsible to write the output to this given output surfaces. 72 * 73 * @param cameraInfo cameraInfo for querying the camera info 74 * @param outputSurfaceConfig output surface configuration for preview, image capture, 75 * image analysis and the postview. This can be null under 76 * Camera2 Extensions implementation mode. In that case, this 77 * function is invoked to setup the necessary stuffs only. 78 * @return a {@link SessionConfig} that contains the surfaces and the session parameters and 79 * should be used to configure the camera session. Return null when the input 80 * <code>outputSurfaceConfig</code> is null. 81 */ initSession(@onNull CameraInfo cameraInfo, @Nullable OutputSurfaceConfiguration outputSurfaceConfig)82 @Nullable SessionConfig initSession(@NonNull CameraInfo cameraInfo, 83 @Nullable OutputSurfaceConfiguration outputSurfaceConfig); 84 85 /** 86 * De-initializes the session. This is called after the camera session is closed. 87 */ deInitSession()88 void deInitSession(); 89 90 /** 91 * Sets the camera parameters to be enabled in every single and repeating request. 92 */ setParameters(@onNull Config config)93 void setParameters(@NonNull Config config); 94 95 /** 96 * Notifies the SessionProcessor that the camera session is just started. A 97 * {@link RequestProcessor} is provided to execute camera requests. 98 */ onCaptureSessionStart( @onNull RequestProcessor requestProcessor)99 void onCaptureSessionStart( 100 @NonNull RequestProcessor requestProcessor); 101 102 /** 103 * Notifies the SessionProcessor that the camera session is going to be closed. 104 * {@link RequestProcessor} will no longer accept any requests 105 * after onCaptureSessionEnd() returns. 106 */ onCaptureSessionEnd()107 void onCaptureSessionEnd(); 108 109 /** 110 * Requests the SessionProcessor to start the repeating request that enables 111 * preview and image analysis. 112 * 113 * @param tagBundle the {@link TagBundle} to be attached to the {@link CameraCaptureResult} in 114 * {@link CaptureCallback#onCaptureCompleted(long, int, CameraCaptureResult)}. 115 * @param callback callback to notify the status. 116 * @return the id of the capture sequence. 117 */ startRepeating(@onNull TagBundle tagBundle, @NonNull CaptureCallback callback)118 int startRepeating(@NonNull TagBundle tagBundle, @NonNull CaptureCallback callback); 119 120 /** 121 * Stop the repeating request. 122 */ stopRepeating()123 void stopRepeating(); 124 125 /** 126 * Requests the SessionProcessor to start the still image capture. The capture task can only 127 * perform one at a time. 128 * 129 * @param postviewEnabled if postview is enabled or not. 130 * @param tagBundle the {@link TagBundle} to be attached to the {@link CameraCaptureResult} in 131 * {@link CaptureCallback#onCaptureCompleted(long, int, CameraCaptureResult)}. 132 * @param callback callback to notify the status. 133 * @return the id of the capture sequence. 134 */ startCapture(boolean postviewEnabled, @NonNull TagBundle tagBundle, @NonNull CaptureCallback callback)135 int startCapture(boolean postviewEnabled, @NonNull TagBundle tagBundle, 136 @NonNull CaptureCallback callback); 137 138 /** 139 * Aborts the pending capture. 140 */ abortCapture(int captureSequenceId)141 void abortCapture(int captureSequenceId); 142 143 /** 144 * Sends trigger-type single request such as AF/AE triggers. 145 * @param config the {@link Config} that contains the parameters to be set in the trigger. 146 * @param tagBundle the {@link TagBundle} to be attached to the {@link CameraCaptureResult} in 147 * {@link CaptureCallback#onCaptureCompleted(long, int, CameraCaptureResult)}. 148 * @param callback callback to notify the status 149 * @return the id of the capture sequence. 150 */ startTrigger(@onNull Config config, @NonNull TagBundle tagBundle, @NonNull CaptureCallback callback)151 default int startTrigger(@NonNull Config config, @NonNull TagBundle tagBundle, 152 @NonNull CaptureCallback callback) { 153 return -1; 154 } 155 156 /** 157 * Returns supported output format/size map for postview image. The API is provided 158 * for camera-core to query the supported postview sizes from SessionProcessor. 159 */ getSupportedPostviewSize(@onNull Size captureSize)160 default @NonNull Map<Integer, List<Size>> getSupportedPostviewSize(@NonNull Size captureSize) { 161 return Collections.emptyMap(); 162 } 163 164 /** 165 * Returns the supported camera operations when the SessionProcessor is enabled. 166 */ 167 default @AdapterCameraInfo.CameraOperation @NonNull Set<Integer> getSupportedCameraOperations()168 getSupportedCameraOperations() { 169 return Collections.emptySet(); 170 } 171 172 default @NonNull List<Pair<CameraCharacteristics.Key, Object>> getAvailableCharacteristicsKeyValues()173 getAvailableCharacteristicsKeyValues() { 174 return Collections.emptyList(); 175 } 176 177 /** 178 * Returns the extensions-specific zoom range 179 */ 180 @SuppressWarnings("unchecked") getExtensionZoomRange()181 default @Nullable Range<Float> getExtensionZoomRange() { 182 if (Build.VERSION.SDK_INT >= 30) { 183 List<Pair<CameraCharacteristics.Key, Object>> keyValues = 184 getAvailableCharacteristicsKeyValues(); 185 for (Pair<CameraCharacteristics.Key, Object> keyValue : keyValues) { 186 if (keyValue.first.equals(CameraCharacteristics.CONTROL_ZOOM_RATIO_RANGE)) { 187 return (Range<Float>) keyValue.second; 188 } 189 } 190 } 191 return null; 192 } 193 194 /** 195 * Returns the extensions-specific available stabilization modes. 196 */ 197 @SuppressWarnings("unchecked") getExtensionAvailableStabilizationModes()198 default int @Nullable [] getExtensionAvailableStabilizationModes() { 199 List<Pair<CameraCharacteristics.Key, Object>> keyValues = 200 getAvailableCharacteristicsKeyValues(); 201 for (Pair<CameraCharacteristics.Key, Object> keyValue : keyValues) { 202 if (keyValue.first.equals( 203 CameraCharacteristics.CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES)) { 204 return (int[]) keyValue.second; 205 } 206 } 207 return null; 208 } 209 210 /** 211 * Returns the dynamically calculated capture latency pair in milliseconds. 212 * 213 * The measurement is expected to take in to account dynamic parameters such as the current 214 * scene, the state of 3A algorithms, the state of internal HW modules and return a more 215 * accurate assessment of the capture and/or processing latency.</p> 216 * 217 * @return pair that includes the estimated input frame/frames camera capture latency as the 218 * first field. This is the time between {@link CaptureCallback#onCaptureStarted} and 219 * {@link CaptureCallback#onCaptureProcessStarted}. The second field value includes the 220 * estimated post-processing latency. This is the time between 221 * {@link CaptureCallback#onCaptureProcessStarted} until the processed frame returns back to the 222 * client registered surface. 223 * Both first and second values will be in milliseconds. The total still capture latency will be 224 * the sum of both the first and second values of the pair. 225 * The pair is expected to be null if the dynamic latency estimation is not supported. 226 * If clients have not configured a still capture output, then this method can also return a 227 * null pair. 228 */ getRealtimeCaptureLatency()229 default @Nullable Pair<Long, Long> getRealtimeCaptureLatency() { 230 return null; 231 } 232 233 /** 234 * Returns the implementation type info composited by the extension impl type and the 235 * extension mode. 236 * 237 * <p>The first value of the returned {@link Pair} can be {@link #TYPE_VENDOR_LIBRARY} or 238 * {@link #TYPE_CAMERA2_EXTENSION} that can let the caller know how to use the 239 * SessionProcessor to create the capture session. The second value is the mode under the impl 240 * type. 241 * 242 * @return a {@link Pair} composited by the extension impl type and the extension mode. 243 */ 244 @NonNull getImplementationType()245 default Pair<Integer, Integer> getImplementationType() { 246 return Pair.create(TYPE_VENDOR_LIBRARY, 0 /* ExtensionMode.None */); 247 } 248 249 /** 250 * Sets a {@link CaptureSessionRequestProcessor} for retrieving specific information from the 251 * camera capture session or submitting requests. 252 * 253 * <p>This is used for the SessionProcessor implementation that needs to directly interact 254 * with the camera capture session to retrieve specific information or submit requests. 255 * 256 * <p>Callers should clear this by calling with null to avoid the session processor to hold 257 * the camera capture session related resources. 258 */ setCaptureSessionRequestProcessor( @ullable CaptureSessionRequestProcessor processor)259 default void setCaptureSessionRequestProcessor( 260 @Nullable CaptureSessionRequestProcessor processor) { 261 } 262 263 /** 264 * Callback for {@link #startRepeating} and {@link #startCapture}. 265 */ 266 interface CaptureCallback { 267 /** 268 * This method is called when the camera has started capturing the initial input 269 * image. 270 * 271 * For a multi-frame capture, the method is called when the onCaptureStarted of first 272 * frame is called and its timestamp is directly forwarded to timestamp parameter of 273 * this method. 274 * 275 * @param captureSequenceId id of the current capture sequence 276 * @param timestamp the timestamp at start of capture for repeating 277 * request or the timestamp at start of capture of the 278 * first frame in a multi-frame capture, in nanoseconds. 279 */ onCaptureStarted(int captureSequenceId, long timestamp)280 default void onCaptureStarted(int captureSequenceId, long timestamp) {} 281 282 /** 283 * This method is called when an image (or images in case of multi-frame 284 * capture) is captured and device-specific extension processing is triggered. 285 * 286 * @param captureSequenceId id of the current capture sequence 287 */ onCaptureProcessStarted(int captureSequenceId)288 default void onCaptureProcessStarted(int captureSequenceId) {} 289 290 /** 291 * This method is called instead of {@link #onCaptureProcessStarted} when the camera 292 * device failed to produce the required input image. The cause could be a failed camera 293 * capture request, a failed capture result or dropped camera frame. 294 * 295 * @param captureSequenceId id of the current capture sequence 296 */ onCaptureFailed(int captureSequenceId)297 default void onCaptureFailed(int captureSequenceId) {} 298 299 /** 300 * This method is called independently of the others in the CaptureCallback, when a capture 301 * sequence finishes. 302 * 303 * <p>In total, there will be at least one {@link #onCaptureProcessStarted}/ 304 * {@link #onCaptureFailed} invocation before this callback is triggered. If the capture 305 * sequence is aborted before any requests have begun processing, 306 * {@link #onCaptureSequenceAborted} is invoked instead.</p> 307 * 308 * @param captureSequenceId id of the current capture sequence 309 */ onCaptureSequenceCompleted(int captureSequenceId)310 default void onCaptureSequenceCompleted(int captureSequenceId) {} 311 312 /** 313 * This method is called when a capture sequence aborts. 314 * 315 * @param captureSequenceId id of the current capture sequence 316 */ onCaptureSequenceAborted(int captureSequenceId)317 default void onCaptureSequenceAborted(int captureSequenceId) {} 318 319 /** 320 * Capture result callback that needs to be called when the process capture results are 321 * ready as part of frame post-processing. 322 * 323 * This callback will fire after {@link #onCaptureStarted}, {@link #onCaptureProcessStarted} 324 * and before {@link #onCaptureSequenceCompleted}. The callback is not expected to fire 325 * in case of capture failure {@link #onCaptureFailed} or capture abort 326 * {@link #onCaptureSequenceAborted}. 327 * 328 * @param timestamp The timestamp at start of capture. The same timestamp value 329 * passed to {@link #onCaptureStarted}. 330 * @param captureSequenceId the capture id of the request that generated the capture 331 * results. This is the return value of either 332 * {@link #startRepeating} or {@link #startCapture}. 333 * @param captureResult the capture result that contains the metadata and the 334 * timestamp of the capture. 335 */ onCaptureCompleted(long timestamp, int captureSequenceId, @NonNull CameraCaptureResult captureResult)336 default void onCaptureCompleted(long timestamp, int captureSequenceId, 337 @NonNull CameraCaptureResult captureResult) {} 338 339 /** 340 * Capture progress callback that needs to be called when the process capture is 341 * ongoing and includes the estimated progress of the processing. 342 * 343 * <p>Extensions must ensure that they always call this callback with monotonically 344 * increasing values.</p> 345 * 346 * <p>Extensions are allowed to trigger this callback multiple times but at the minimum the 347 * callback is expected to be called once when processing is done with value 100.</p> 348 * 349 * @param progress Value between 0 and 100. 350 */ onCaptureProcessProgressed(int progress)351 default void onCaptureProcessProgressed(int progress) {} 352 } 353 354 /** 355 * An interface for retrieving specific information from the camera capture session or 356 * submitting requests. 357 */ 358 interface CaptureSessionRequestProcessor { 359 /** 360 * Returns the realtime still capture latency information. 361 * 362 * @see CameraExtensionSession#getRealtimeStillCaptureLatency() 363 */ 364 @Nullable getRealtimeStillCaptureLatency()365 Pair<Long, Long> getRealtimeStillCaptureLatency(); 366 367 /** 368 * Sets the strength of the extension post-processing effect. 369 * 370 * @param strength the new extension strength value 371 * @see android.hardware.camera2.CaptureRequest#EXTENSION_STRENGTH 372 */ setExtensionStrength(@ntRangefrom = 0, to = 100) int strength)373 void setExtensionStrength(@IntRange(from = 0, to = 100) int strength); 374 } 375 } 376