1 /* 2 * Copyright (C) 2014 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; 18 19 import android.annotation.CallbackExecutor; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.hardware.camera2.CameraOfflineSession; 23 import android.hardware.camera2.CameraOfflineSession.CameraOfflineSessionCallback; 24 import android.hardware.camera2.params.OutputConfiguration; 25 import android.os.Handler; 26 import android.view.Surface; 27 28 import java.util.Collection; 29 import java.util.List; 30 import java.util.concurrent.Executor; 31 32 /** 33 * A configured capture session for a {@link CameraDevice}, used for capturing images from the 34 * camera or reprocessing images captured from the camera in the same session previously. 35 * 36 * <p>A CameraCaptureSession is created by providing a set of target output surfaces to 37 * {@link CameraDevice#createCaptureSession createCaptureSession}, or by providing an 38 * {@link android.hardware.camera2.params.InputConfiguration} and a set of target output surfaces to 39 * {@link CameraDevice#createReprocessableCaptureSession createReprocessableCaptureSession} for a 40 * reprocessable capture session. Once created, the session is active until a new session is 41 * created by the camera device, or the camera device is closed.</p> 42 * 43 * <p>All capture sessions can be used for capturing images from the camera but only reprocessable 44 * capture sessions can reprocess images captured from the camera in the same session previously. 45 * </p> 46 * 47 * <p>Creating a session is an expensive operation and can take several hundred milliseconds, since 48 * it requires configuring the camera device's internal pipelines and allocating memory buffers for 49 * sending images to the desired targets. Therefore the setup is done asynchronously, and 50 * {@link CameraDevice#createCaptureSession createCaptureSession} and 51 * {@link CameraDevice#createReprocessableCaptureSession createReprocessableCaptureSession} will 52 * send the ready-to-use CameraCaptureSession to the provided listener's 53 * {@link CameraCaptureSession.StateCallback#onConfigured onConfigured} callback. If configuration 54 * cannot be completed, then the 55 * {@link CameraCaptureSession.StateCallback#onConfigureFailed onConfigureFailed} is called, and the 56 * session will not become active.</p> 57 *<!-- 58 * <p>Any capture requests (repeating or non-repeating) submitted before the session is ready will 59 * be queued up and will begin capture once the session becomes ready. In case the session cannot be 60 * configured and {@link StateCallback#onConfigureFailed onConfigureFailed} is called, all queued 61 * capture requests are discarded.</p> 62 *--> 63 * <p>If a new session is created by the camera device, then the previous session is closed, and its 64 * associated {@link StateCallback#onClosed onClosed} callback will be invoked. All 65 * of the session methods will throw an IllegalStateException if called once the session is 66 * closed.</p> 67 * 68 * <p>A closed session clears any repeating requests (as if {@link #stopRepeating} had been called), 69 * but will still complete all of its in-progress capture requests as normal, before a newly 70 * created session takes over and reconfigures the camera device.</p> 71 */ 72 public abstract class CameraCaptureSession implements AutoCloseable { 73 74 /** 75 * Used to identify invalid session ID. 76 * @hide 77 */ 78 public static final int SESSION_ID_NONE = -1; 79 80 /** 81 * Get the camera device that this session is created for. 82 */ 83 @NonNull getDevice()84 public abstract CameraDevice getDevice(); 85 86 /** 87 * <p>Pre-allocate all buffers for an output Surface.</p> 88 * 89 * <p>Normally, the image buffers for a given output Surface are allocated on-demand, 90 * to minimize startup latency and memory overhead.</p> 91 * 92 * <p>However, in some cases, it may be desirable for the buffers to be allocated before 93 * any requests targeting the Surface are actually submitted to the device. Large buffers 94 * may take some time to allocate, which can result in delays in submitting requests until 95 * sufficient buffers are allocated to reach steady-state behavior. Such delays can cause 96 * bursts to take longer than desired, or cause skips or stutters in preview output.</p> 97 * 98 * <p>The prepare() method can be used to perform this preallocation. It may only be called for 99 * a given output Surface before that Surface is used as a target for a request. The number of 100 * buffers allocated is the sum of the count needed by the consumer providing the output 101 * Surface, and the maximum number needed by the camera device to fill its pipeline. Since this 102 * may be a larger number than what is actually required for steady-state operation, using 103 * prepare may result in higher memory consumption than the normal on-demand behavior results 104 * in. Prepare() will also delay the time to first output to a given Surface, in exchange for 105 * smoother frame rate once the allocation is complete.</p> 106 * 107 * <p>For example, an application that creates an 108 * {@link android.media.ImageReader#newInstance ImageReader} with a maxImages argument of 10, 109 * but only uses 3 simultaneous Images at once would normally only cause those 3 images to be 110 * allocated (plus what is needed by the camera device for smooth operation). But using 111 * prepare() on the ImageReader Surface will result in all 10 Images being allocated. So 112 * applications using this method should take care to request only the number of buffers 113 * actually necessary for their application.</p> 114 * 115 * <p>If the same output Surface is used in consecutive sessions (without closing the first 116 * session explicitly), then its already-allocated buffers are carried over, and if it was 117 * used as a target of a capture request in the first session, prepare cannot be called on it 118 * in the second session.</p> 119 * 120 * <p>Once allocation is complete, {@link StateCallback#onSurfacePrepared} will be invoked with 121 * the Surface provided to this method. Between the prepare call and the onSurfacePrepared call, 122 * the Surface provided to prepare must not be used as a target of a CaptureRequest submitted 123 * to this session.</p> 124 * 125 * <p>Note that if 2 surfaces share the same stream via {@link 126 * OutputConfiguration#enableSurfaceSharing} and {@link OutputConfiguration#addSurface}, 127 * prepare() only needs to be called on one surface, and {@link 128 * StateCallback#onSurfacePrepared} will be triggered for both surfaces.</p> 129 * 130 * <p>{@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY} 131 * devices cannot pre-allocate output buffers; for those devices, 132 * {@link StateCallback#onSurfacePrepared} will be immediately called, and no preallocation is 133 * done.</p> 134 * 135 * @param surface the output Surface for which buffers should be pre-allocated. Must be one of 136 * the output Surfaces used to create this session. 137 * 138 * @throws CameraAccessException if the camera device is no longer connected or has 139 * encountered a fatal error 140 * @throws IllegalStateException if this session is no longer active, either because the session 141 * was explicitly closed, a new session has been created 142 * or the camera device has been closed. 143 * @throws IllegalArgumentException if the Surface is invalid, not part of this Session, or has 144 * already been used as a target of a CaptureRequest in this 145 * session or immediately prior sessions. 146 * 147 * @see StateCallback#onSurfacePrepared 148 */ prepare(@onNull Surface surface)149 public abstract void prepare(@NonNull Surface surface) throws CameraAccessException; 150 151 /** 152 * <p>Pre-allocate at most maxCount buffers for an output Surface.</p> 153 * 154 * <p>Like the {@link #prepare(Surface)} method, this method can be used to allocate output 155 * buffers for a given Surface. However, while the {@link #prepare(Surface)} method allocates 156 * the maximum possible buffer count, this method allocates at most maxCount buffers.</p> 157 * 158 * <p>If maxCount is greater than the possible maximum count (which is the sum of the buffer 159 * count requested by the creator of the Surface and the count requested by the camera device), 160 * only the possible maximum count is allocated, in which case the function acts exactly like 161 * {@link #prepare(Surface)}.</p> 162 * 163 * <p>The restrictions on when this method can be called are the same as for 164 * {@link #prepare(Surface)}.</p> 165 * 166 * <p>Repeated calls to this method are allowed, and a mix of {@link #prepare(Surface)} and 167 * this method is also allowed. Note that after the first call to {@link #prepare(Surface)}, 168 * subsequent calls to either prepare method are effectively no-ops. In addition, this method 169 * is not additive in terms of buffer count. This means calling it twice with maxCount = 2 170 * will only allocate 2 buffers, not 4 (assuming the possible maximum is at least 2); to 171 * allocate two buffers on the first call and two on the second, the application needs to call 172 * prepare with prepare(surface, 2) and prepare(surface, 4).</p> 173 * 174 * @param maxCount the buffer count to try to allocate. If this is greater than the possible 175 * maximum for this output, the possible maximum is allocated instead. If 176 * maxCount buffers are already allocated, then prepare will do nothing. 177 * @param surface the output Surface for which buffers should be pre-allocated. 178 * 179 * @throws CameraAccessException if the camera device is no longer connected or has 180 * encountered a fatal error. 181 * @throws IllegalStateException if this session is no longer active, either because the 182 * session was explicitly closed, a new session has been created 183 * or the camera device has been closed. 184 * @throws IllegalArgumentException if the Surface is invalid, not part of this Session, 185 * or has already been used as a target of a CaptureRequest in 186 * this session or immediately prior sessions without an 187 * intervening tearDown call. 188 * 189 * @hide 190 */ 191 @SuppressWarnings("HiddenAbstractMethod") prepare(int maxCount, @NonNull Surface surface)192 public abstract void prepare(int maxCount, @NonNull Surface surface) 193 throws CameraAccessException; 194 195 /** 196 * <p>Free all buffers allocated for an output Surface.</p> 197 * 198 * <p>Normally, once allocated, the image buffers for a given output Surface remain allocated 199 * for the lifetime of the capture session, to minimize latency of captures and to reduce 200 * memory allocation overhead.</p> 201 * 202 * <p>However, in some cases, it may be desirable for allocated buffers to be freed to reduce 203 * the application's memory consumption, if the particular output Surface will not be used by 204 * the application for some time.</p> 205 * 206 * <p>The tearDown() method can be used to perform this operation. After the call finishes, all 207 * unfilled image buffers will have been freed. Any future use of the target Surface may require 208 * allocation of additional buffers, as if the session had just been created. Buffers being 209 * held by the application (either explicitly as Image objects from ImageReader, or implicitly 210 * as the current texture in a SurfaceTexture or the current contents of a RS Allocation, will 211 * remain valid and allocated even when tearDown is invoked.</p> 212 * 213 * <p>A Surface that has had tearDown() called on it is eligible to have prepare() invoked on it 214 * again even if it was used as a request target before the tearDown() call, as long as it 215 * doesn't get used as a target of a request between the tearDown() and prepare() calls.</p> 216 * 217 * @param surface the output Surface for which buffers should be freed. Must be one of the 218 * the output Surfaces used to create this session. 219 * 220 * @throws CameraAccessException if the camera device is no longer connected or has 221 * encountered a fatal error. 222 * @throws IllegalStateException if this session is no longer active, either because the session 223 * was explicitly closed, a new session has been created 224 * or the camera device has been closed. 225 * @throws IllegalArgumentException if the Surface is invalid, not part of this Session, or has 226 * already been used as a target of a CaptureRequest in this 227 * session or immediately prior sessions. 228 * 229 * @hide 230 */ 231 @SuppressWarnings("HiddenAbstractMethod") tearDown(@onNull Surface surface)232 public abstract void tearDown(@NonNull Surface surface) throws CameraAccessException; 233 234 /** 235 * <p>Finalize the output configurations that now have their deferred and/or extra Surfaces 236 * included.</p> 237 * 238 * <p>For camera use cases where a preview and other output configurations need to be 239 * configured, it can take some time for the preview Surface to be ready. For example, if the 240 * preview Surface is obtained from {@link android.view.SurfaceView}, the SurfaceView will only 241 * be ready after the UI layout is done, potentially delaying camera startup.</p> 242 * 243 * <p>To speed up camera startup time, the application can configure the 244 * {@link CameraCaptureSession} with the eventual preview size (via 245 * {@link OutputConfiguration#OutputConfiguration(Size,Class) a deferred OutputConfiguration}), 246 * and defer the preview output configuration until the Surface is ready. After the 247 * {@link CameraCaptureSession} is created successfully with this deferred output and other 248 * normal outputs, the application can start submitting requests as long as they do not include 249 * deferred output Surfaces. Once a deferred Surface is ready, the application can add the 250 * Surface to the deferred output configuration with the 251 * {@link OutputConfiguration#addSurface} method, and then update the deferred output 252 * configuration via this method, before it can submit capture requests with this output 253 * target.</p> 254 * 255 * <p>This function can also be called in case where multiple surfaces share the same 256 * OutputConfiguration, and one of the surfaces becomes available after the {@link 257 * CameraCaptureSession} is created. In that case, the application must first create the 258 * OutputConfiguration with the available Surface, then enable further surface sharing via 259 * {@link OutputConfiguration#enableSurfaceSharing}, before creating the CameraCaptureSession. 260 * After the CameraCaptureSession is created, and once the extra Surface becomes available, the 261 * application must then call {@link OutputConfiguration#addSurface} before finalizing the 262 * configuration with this method.</p> 263 * 264 * <p>If the provided OutputConfigurations are unchanged from session creation, this function 265 * call has no effect. This function must only be called once for a particular output 266 * configuration. </p> 267 * 268 * <p>The output Surfaces included by this list of 269 * {@link OutputConfiguration OutputConfigurations} can be used as {@link CaptureRequest} 270 * targets as soon as this call returns.</p> 271 * 272 * <p>This method is not supported by 273 * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY}-level devices.</p> 274 * 275 * @param outputConfigs a list of {@link OutputConfiguration OutputConfigurations} that 276 * have had {@link OutputConfiguration#addSurface addSurface} invoked with a valid 277 * output Surface after {@link CameraDevice#createCaptureSessionByOutputConfigurations}. 278 * @throws CameraAccessException if the camera device is no longer connected or has encountered 279 * a fatal error. 280 * @throws IllegalStateException if this session is no longer active, either because the session 281 * was explicitly closed, a new session has been created, or the camera device has 282 * been closed. 283 * @throws IllegalArgumentException for invalid output configurations, including ones where the 284 * source of the Surface is no longer valid or the Surface is from a unsupported 285 * source. Or if one of the output configuration was already finished with an 286 * included surface in a prior call. 287 */ finalizeOutputConfigurations( List<OutputConfiguration> outputConfigs)288 public abstract void finalizeOutputConfigurations( 289 List<OutputConfiguration> outputConfigs) throws CameraAccessException; 290 291 /** 292 * <p>Submit a request for an image to be captured by the camera device.</p> 293 * 294 * <p>The request defines all the parameters for capturing the single image, 295 * including sensor, lens, flash, and post-processing settings.</p> 296 * 297 * <p>Each request will produce one {@link CaptureResult} and produce new frames for one or more 298 * target Surfaces, set with the CaptureRequest builder's 299 * {@link CaptureRequest.Builder#addTarget} method. The target surfaces (set with 300 * {@link CaptureRequest.Builder#addTarget}) must be a subset of the surfaces provided when this 301 * capture session was created.</p> 302 * 303 * <p>Multiple regular and reprocess requests can be in progress at once. If there are only 304 * regular requests or reprocess requests in progress, they are processed in first-in, 305 * first-out order. If there are both regular and reprocess requests in progress, regular 306 * requests are processed in first-in, first-out order and reprocess requests are processed in 307 * first-in, first-out order, respectively. However, the processing order of a regular request 308 * and a reprocess request in progress is not specified. In other words, a regular request 309 * will always be processed before regular requests that are submitted later. A reprocess 310 * request will always be processed before reprocess requests that are submitted later. However, 311 * a regular request may not be processed before reprocess requests that are submitted later.<p> 312 * 313 * <p>Requests submitted through this method have higher priority than 314 * those submitted through {@link #setRepeatingRequest} or 315 * {@link #setRepeatingBurst}, and will be processed as soon as the current 316 * repeat/repeatBurst processing completes.</p> 317 * 318 * <p>All capture sessions can be used for capturing images from the camera but only capture 319 * sessions created by 320 * {@link CameraDevice#createReprocessableCaptureSession createReprocessableCaptureSession} 321 * can submit reprocess capture requests. Submitting a reprocess request to a regular capture 322 * session will result in an {@link IllegalArgumentException}.</p> 323 * 324 * <p>Submitting a request that targets Surfaces with an unsupported dynamic range combination 325 * will result in an {@link IllegalArgumentException}.</p> 326 * 327 * @param request the settings for this capture 328 * @param listener The callback object to notify once this request has been 329 * processed. If null, no metadata will be produced for this capture, 330 * although image data will still be produced. 331 * @param handler the handler on which the listener should be invoked, or 332 * {@code null} to use the current thread's {@link android.os.Looper 333 * looper}. 334 * 335 * @return int A unique capture sequence ID used by 336 * {@link CaptureCallback#onCaptureSequenceCompleted}. 337 * 338 * @throws CameraAccessException if the camera device is no longer connected or has 339 * encountered a fatal error 340 * @throws IllegalStateException if this session is no longer active, either because the session 341 * was explicitly closed, a new session has been created 342 * or the camera device has been closed. 343 * @throws IllegalArgumentException if the request targets no Surfaces or Surfaces that are not 344 * configured as outputs for this session; or the request 345 * targets a set of Surfaces that cannot be submitted 346 * simultaneously in a reprocessable capture session; or a 347 * reprocess capture request is submitted in a 348 * non-reprocessable capture session; or the reprocess capture 349 * request was created with a {@link TotalCaptureResult} from 350 * a different session; or the capture targets a Surface in 351 * the middle of being {@link #prepare prepared}; or the 352 * handler is null, the listener is not null, and the calling 353 * thread has no looper; or the request targets Surfaces with 354 * an unsupported dynamic range combination 355 * 356 * @see #captureBurst 357 * @see #setRepeatingRequest 358 * @see #setRepeatingBurst 359 * @see #abortCaptures 360 * @see CameraDevice#createReprocessableCaptureSession 361 * @see android.hardware.camera2.params.DynamicRangeProfiles#getProfileCaptureRequestConstraints 362 */ capture(@onNull CaptureRequest request, @Nullable CaptureCallback listener, @Nullable Handler handler)363 public abstract int capture(@NonNull CaptureRequest request, 364 @Nullable CaptureCallback listener, @Nullable Handler handler) 365 throws CameraAccessException; 366 367 /** 368 * <p>Submit a request for an image to be captured by the camera device.</p> 369 * 370 * <p>The behavior of this method matches that of 371 * {@link #capture(CaptureRequest, CaptureCallback, Handler)}, 372 * except that it uses {@link java.util.concurrent.Executor} as an argument 373 * instead of {@link android.os.Handler}.</p> 374 * 375 * @param request the settings for this capture 376 * @param executor the executor which will be used for invoking the listener. 377 * @param listener The callback object to notify once this request has been 378 * processed. 379 * 380 * @return int A unique capture sequence ID used by 381 * {@link CaptureCallback#onCaptureSequenceCompleted}. 382 * 383 * @throws CameraAccessException if the camera device is no longer connected or has 384 * encountered a fatal error 385 * @throws IllegalStateException if this session is no longer active, either because the session 386 * was explicitly closed, a new session has been created 387 * or the camera device has been closed. 388 * @throws IllegalArgumentException if the request targets no Surfaces or Surfaces that are not 389 * configured as outputs for this session; or the request 390 * targets a set of Surfaces that cannot be submitted 391 * simultaneously in a reprocessable capture session; or a 392 * reprocess capture request is submitted in a 393 * non-reprocessable capture session; or the reprocess capture 394 * request was created with a {@link TotalCaptureResult} from 395 * a different session; or the capture targets a Surface in 396 * the middle of being {@link #prepare prepared}; or the 397 * executor is null, or the listener is not null; 398 * or the request targets Surfaces with an unsupported dynamic 399 * range combination; 400 * 401 * @see #captureBurst 402 * @see #setRepeatingRequest 403 * @see #setRepeatingBurst 404 * @see #abortCaptures 405 * @see CameraDevice#createReprocessableCaptureSession 406 * @see android.hardware.camera2.params.DynamicRangeProfiles#getProfileCaptureRequestConstraints 407 */ captureSingleRequest(@onNull CaptureRequest request, @NonNull @CallbackExecutor Executor executor, @NonNull CaptureCallback listener)408 public int captureSingleRequest(@NonNull CaptureRequest request, 409 @NonNull @CallbackExecutor Executor executor, @NonNull CaptureCallback listener) 410 throws CameraAccessException { 411 throw new UnsupportedOperationException("Subclasses must override this method"); 412 } 413 414 /** 415 * Submit a list of requests to be captured in sequence as a burst. The 416 * burst will be captured in the minimum amount of time possible, and will 417 * not be interleaved with requests submitted by other capture or repeat 418 * calls. 419 * 420 * <p>Regular and reprocess requests can be mixed together in a single burst. Regular requests 421 * will be captured in order and reprocess requests will be processed in order, respectively. 422 * However, the processing order between a regular request and a reprocess request is not 423 * specified. Each capture produces one {@link CaptureResult} and image buffers for one or more 424 * target {@link android.view.Surface surfaces}. The target surfaces (set with 425 * {@link CaptureRequest.Builder#addTarget}) must be a subset of the surfaces provided when 426 * this capture session was created.</p> 427 * 428 * <p>The main difference between this method and simply calling 429 * {@link #capture} repeatedly is that this method guarantees that no 430 * other requests will be interspersed with the burst.</p> 431 * 432 * <p>All capture sessions can be used for capturing images from the camera but only capture 433 * sessions created by 434 * {@link CameraDevice#createReprocessableCaptureSession createReprocessableCaptureSession} 435 * can submit reprocess capture requests. Submitting a reprocess request to a regular 436 * capture session will result in an {@link IllegalArgumentException}.</p> 437 * 438 * <p>Submitting a request that targets Surfaces with an unsupported dynamic range combination 439 * will result in an {@link IllegalArgumentException}.</p> 440 * 441 * @param requests the list of settings for this burst capture 442 * @param listener The callback object to notify each time one of the 443 * requests in the burst has been processed. If null, no metadata will be 444 * produced for any requests in this burst, although image data will still 445 * be produced. 446 * @param handler the handler on which the listener should be invoked, or 447 * {@code null} to use the current thread's {@link android.os.Looper 448 * looper}. 449 * 450 * @return int A unique capture sequence ID used by 451 * {@link CaptureCallback#onCaptureSequenceCompleted}. 452 * 453 * @throws CameraAccessException if the camera device is no longer connected or has 454 * encountered a fatal error 455 * @throws IllegalStateException if this session is no longer active, either because the session 456 * was explicitly closed, a new session has been created 457 * or the camera device has been closed. 458 * @throws IllegalArgumentException If the requests target no Surfaces, or the requests target 459 * Surfaces not currently configured as outputs; or one of the 460 * requests targets a set of Surfaces that cannot be submitted 461 * simultaneously in a reprocessable capture session; or a 462 * reprocess capture request is submitted in a 463 * non-reprocessable capture session; or one of the reprocess 464 * capture requests was created with a 465 * {@link TotalCaptureResult} from a different session; or one 466 * of the captures targets a Surface in the middle of being 467 * {@link #prepare prepared}; or if the handler is null, the 468 * listener is not null, and the calling thread has no looper; 469 * or the request targets Surfaces with an unsupported dynamic 470 * range combination. 471 * 472 * @see #capture 473 * @see #setRepeatingRequest 474 * @see #setRepeatingBurst 475 * @see #abortCaptures 476 * @see android.hardware.camera2.params.DynamicRangeProfiles#getProfileCaptureRequestConstraints 477 */ captureBurst(@onNull List<CaptureRequest> requests, @Nullable CaptureCallback listener, @Nullable Handler handler)478 public abstract int captureBurst(@NonNull List<CaptureRequest> requests, 479 @Nullable CaptureCallback listener, @Nullable Handler handler) 480 throws CameraAccessException; 481 482 /** 483 * Submit a list of requests to be captured in sequence as a burst. The 484 * burst will be captured in the minimum amount of time possible, and will 485 * not be interleaved with requests submitted by other capture or repeat 486 * calls. 487 * 488 * <p>The behavior of this method matches that of 489 * {@link #captureBurst(List, CaptureCallback, Handler)}, 490 * except that it uses {@link java.util.concurrent.Executor} as an argument 491 * instead of {@link android.os.Handler}.</p> 492 * 493 * @param requests the list of settings for this burst capture 494 * @param executor the executor which will be used for invoking the listener. 495 * @param listener The callback object to notify each time one of the 496 * requests in the burst has been processed. 497 * 498 * @return int A unique capture sequence ID used by 499 * {@link CaptureCallback#onCaptureSequenceCompleted}. 500 * 501 * @throws CameraAccessException if the camera device is no longer connected or has 502 * encountered a fatal error 503 * @throws IllegalStateException if this session is no longer active, either because the session 504 * was explicitly closed, a new session has been created 505 * or the camera device has been closed. 506 * @throws IllegalArgumentException If the requests target no Surfaces, or the requests target 507 * Surfaces not currently configured as outputs; or one of the 508 * requests targets a set of Surfaces that cannot be submitted 509 * simultaneously in a reprocessable capture session; or a 510 * reprocess capture request is submitted in a 511 * non-reprocessable capture session; or one of the reprocess 512 * capture requests was created with a 513 * {@link TotalCaptureResult} from a different session; or one 514 * of the captures targets a Surface in the middle of being 515 * {@link #prepare prepared}; or if the executor is null; or if 516 * the listener is null; 517 * or the request targets Surfaces with an unsupported dynamic 518 * range combination. 519 * 520 * @see #capture 521 * @see #setRepeatingRequest 522 * @see #setRepeatingBurst 523 * @see #abortCaptures 524 * @see android.hardware.camera2.params.DynamicRangeProfiles#getProfileCaptureRequestConstraints 525 */ captureBurstRequests(@onNull List<CaptureRequest> requests, @NonNull @CallbackExecutor Executor executor, @NonNull CaptureCallback listener)526 public int captureBurstRequests(@NonNull List<CaptureRequest> requests, 527 @NonNull @CallbackExecutor Executor executor, @NonNull CaptureCallback listener) 528 throws CameraAccessException { 529 throw new UnsupportedOperationException("Subclasses must override this method"); 530 } 531 532 /** 533 * Request endlessly repeating capture of images by this capture session. 534 * 535 * <p>With this method, the camera device will continually capture images 536 * using the settings in the provided {@link CaptureRequest}, at the maximum 537 * rate possible.</p> 538 * 539 * <p>Repeating requests are a simple way for an application to maintain a 540 * preview or other continuous stream of frames, without having to 541 * continually submit identical requests through {@link #capture}.</p> 542 * 543 * <p>Repeat requests have lower priority than those submitted 544 * through {@link #capture} or {@link #captureBurst}, so if 545 * {@link #capture} is called when a repeating request is active, the 546 * capture request will be processed before any further repeating 547 * requests are processed.<p> 548 * 549 * <p>To stop the repeating capture, call {@link #stopRepeating}. Calling 550 * {@link #abortCaptures} will also clear the request.</p> 551 * 552 * <p>Calling this method will replace any earlier repeating request or 553 * burst set up by this method or {@link #setRepeatingBurst}, although any 554 * in-progress burst will be completed before the new repeat request will be 555 * used.</p> 556 * 557 * <p>This method does not support reprocess capture requests because each reprocess 558 * {@link CaptureRequest} must be created from the {@link TotalCaptureResult} that matches 559 * the input image to be reprocessed. This is either the {@link TotalCaptureResult} of capture 560 * that is sent for reprocessing, or one of the {@link TotalCaptureResult TotalCaptureResults} 561 * of a set of captures, when data from the whole set is combined by the application into a 562 * single reprocess input image. The request must be capturing images from the camera. If a 563 * reprocess capture request is submitted, this method will throw IllegalArgumentException.</p> 564 * 565 * <p>Submitting a request that targets Surfaces with an unsupported dynamic range combination 566 * will result in an {@link IllegalArgumentException}.</p> 567 * 568 * @param request the request to repeat indefinitely 569 * @param listener The callback object to notify every time the 570 * request finishes processing. If null, no metadata will be 571 * produced for this stream of requests, although image data will 572 * still be produced. 573 * @param handler the handler on which the listener should be invoked, or 574 * {@code null} to use the current thread's {@link android.os.Looper 575 * looper}. 576 * 577 * @return int A unique capture sequence ID used by 578 * {@link CaptureCallback#onCaptureSequenceCompleted}. 579 * 580 * @throws CameraAccessException if the camera device is no longer connected or has 581 * encountered a fatal error 582 * @throws IllegalStateException if this session is no longer active, either because the session 583 * was explicitly closed, a new session has been created 584 * or the camera device has been closed. 585 * @throws IllegalArgumentException If the request references no Surfaces or references Surfaces 586 * that are not currently configured as outputs; or the request 587 * is a reprocess capture request; or the capture targets a 588 * Surface in the middle of being {@link #prepare prepared}; or 589 * the handler is null, the listener is not null, and the 590 * calling thread has no looper; or no requests were passed in; 591 * or the request targets Surfaces with an unsupported dynamic 592 * range combination. 593 * 594 * @see #capture 595 * @see #captureBurst 596 * @see #setRepeatingBurst 597 * @see #stopRepeating 598 * @see #abortCaptures 599 * @see android.hardware.camera2.params.DynamicRangeProfiles#getProfileCaptureRequestConstraints 600 */ setRepeatingRequest(@onNull CaptureRequest request, @Nullable CaptureCallback listener, @Nullable Handler handler)601 public abstract int setRepeatingRequest(@NonNull CaptureRequest request, 602 @Nullable CaptureCallback listener, @Nullable Handler handler) 603 throws CameraAccessException; 604 605 /** 606 * Request endlessly repeating capture of images by this capture session. 607 * 608 * <p>The behavior of this method matches that of 609 * {@link #setRepeatingRequest(CaptureRequest, CaptureCallback, Handler)}, 610 * except that it uses {@link java.util.concurrent.Executor} as an argument 611 * instead of {@link android.os.Handler}.</p> 612 * 613 * @param request the request to repeat indefinitely 614 * @param executor the executor which will be used for invoking the listener. 615 * @param listener The callback object to notify every time the 616 * request finishes processing. 617 * 618 * @return int A unique capture sequence ID used by 619 * {@link CaptureCallback#onCaptureSequenceCompleted}. 620 * 621 * @throws CameraAccessException if the camera device is no longer connected or has 622 * encountered a fatal error 623 * @throws IllegalStateException if this session is no longer active, either because the session 624 * was explicitly closed, a new session has been created 625 * or the camera device has been closed. 626 * @throws IllegalArgumentException If the request references no Surfaces or references Surfaces 627 * that are not currently configured as outputs; or the request 628 * is a reprocess capture request; or the capture targets a 629 * Surface in the middle of being {@link #prepare prepared}; or 630 * the executor is null; or the listener is null; 631 * or the request targets Surfaces with an unsupported dynamic 632 * range combination. 633 * 634 * @see #capture 635 * @see #captureBurst 636 * @see #setRepeatingBurst 637 * @see #stopRepeating 638 * @see #abortCaptures 639 * @see android.hardware.camera2.params.DynamicRangeProfiles#getProfileCaptureRequestConstraints 640 */ setSingleRepeatingRequest(@onNull CaptureRequest request, @NonNull @CallbackExecutor Executor executor, @NonNull CaptureCallback listener)641 public int setSingleRepeatingRequest(@NonNull CaptureRequest request, 642 @NonNull @CallbackExecutor Executor executor, @NonNull CaptureCallback listener) 643 throws CameraAccessException { 644 throw new UnsupportedOperationException("Subclasses must override this method"); 645 } 646 647 /** 648 * <p>Request endlessly repeating capture of a sequence of images by this 649 * capture session.</p> 650 * 651 * <p>With this method, the camera device will continually capture images, 652 * cycling through the settings in the provided list of 653 * {@link CaptureRequest CaptureRequests}, at the maximum rate possible.</p> 654 * 655 * <p>If a request is submitted through {@link #capture} or 656 * {@link #captureBurst}, the current repetition of the request list will be 657 * completed before the higher-priority request is handled. This guarantees 658 * that the application always receives a complete repeat burst captured in 659 * minimal time, instead of bursts interleaved with higher-priority 660 * captures, or incomplete captures.</p> 661 * 662 * <p>Repeating burst requests are a simple way for an application to 663 * maintain a preview or other continuous stream of frames where each 664 * request is different in a predictable way, without having to continually 665 * submit requests through {@link #captureBurst}.</p> 666 * 667 * <p>To stop the repeating capture, call {@link #stopRepeating}. Any 668 * ongoing burst will still be completed, however. Calling 669 * {@link #abortCaptures} will also clear the request.</p> 670 * 671 * <p>Calling this method will replace a previously-set repeating request or 672 * burst set up by this method or {@link #setRepeatingRequest}, although any 673 * in-progress burst will be completed before the new repeat burst will be 674 * used.</p> 675 * 676 * <p>This method does not support reprocess capture requests because each reprocess 677 * {@link CaptureRequest} must be created from the {@link TotalCaptureResult} that matches 678 * the input image to be reprocessed. This is either the {@link TotalCaptureResult} of capture 679 * that is sent for reprocessing, or one of the {@link TotalCaptureResult TotalCaptureResults} 680 * of a set of captures, when data from the whole set is combined by the application into a 681 * single reprocess input image. The request must be capturing images from the camera. If a 682 * reprocess capture request is submitted, this method will throw IllegalArgumentException.</p> 683 * 684 * <p>Submitting a request that targets Surfaces with an unsupported dynamic range combination 685 * will result in an {@link IllegalArgumentException}.</p> 686 * 687 * @param requests the list of requests to cycle through indefinitely 688 * @param listener The callback object to notify each time one of the 689 * requests in the repeating bursts has finished processing. If null, no 690 * metadata will be produced for this stream of requests, although image 691 * data will still be produced. 692 * @param handler the handler on which the listener should be invoked, or 693 * {@code null} to use the current thread's {@link android.os.Looper 694 * looper}. 695 * 696 * @return int A unique capture sequence ID used by 697 * {@link CaptureCallback#onCaptureSequenceCompleted}. 698 * 699 * @throws CameraAccessException if the camera device is no longer connected or has 700 * encountered a fatal error 701 * @throws IllegalStateException if this session is no longer active, either because the session 702 * was explicitly closed, a new session has been created 703 * or the camera device has been closed. 704 * @throws IllegalArgumentException If the requests reference no Surfaces or reference Surfaces 705 * not currently configured as outputs; or one of the requests 706 * is a reprocess capture request; or one of the captures 707 * targets a Surface in the middle of being 708 * {@link #prepare prepared}; or the handler is null, the 709 * listener is not null, and the calling thread has no looper; 710 * or no requests were passed in; 711 * or the request targets Surfaces with an unsupported dynamic 712 * range combination. 713 * 714 * @see #capture 715 * @see #captureBurst 716 * @see #setRepeatingRequest 717 * @see #stopRepeating 718 * @see #abortCaptures 719 * @see android.hardware.camera2.params.DynamicRangeProfiles#getProfileCaptureRequestConstraints 720 */ setRepeatingBurst(@onNull List<CaptureRequest> requests, @Nullable CaptureCallback listener, @Nullable Handler handler)721 public abstract int setRepeatingBurst(@NonNull List<CaptureRequest> requests, 722 @Nullable CaptureCallback listener, @Nullable Handler handler) 723 throws CameraAccessException; 724 725 /** 726 * <p>Request endlessly repeating capture of a sequence of images by this 727 * capture session.</p> 728 * 729 * <p>The behavior of this method matches that of 730 * {@link #setRepeatingBurst(List, CaptureCallback, Handler)}, 731 * except that it uses {@link java.util.concurrent.Executor} as an argument 732 * instead of {@link android.os.Handler}.</p> 733 * 734 * @param requests the list of requests to cycle through indefinitely 735 * @param executor the executor which will be used for invoking the listener. 736 * @param listener The callback object to notify each time one of the 737 * requests in the repeating bursts has finished processing. 738 * 739 * @return int A unique capture sequence ID used by 740 * {@link CaptureCallback#onCaptureSequenceCompleted}. 741 * 742 * @throws CameraAccessException if the camera device is no longer connected or has 743 * encountered a fatal error 744 * @throws IllegalStateException if this session is no longer active, either because the session 745 * was explicitly closed, a new session has been created 746 * or the camera device has been closed. 747 * @throws IllegalArgumentException If the requests reference no Surfaces or reference Surfaces 748 * not currently configured as outputs; or one of the requests 749 * is a reprocess capture request; or one of the captures 750 * targets a Surface in the middle of being 751 * {@link #prepare prepared}; or the executor is null; or the 752 * listener is null; 753 * or the request targets Surfaces with an unsupported dynamic 754 * range combination. 755 * 756 * @see #capture 757 * @see #captureBurst 758 * @see #setRepeatingRequest 759 * @see #stopRepeating 760 * @see #abortCaptures 761 * @see android.hardware.camera2.params.DynamicRangeProfiles#getProfileCaptureRequestConstraints 762 */ setRepeatingBurstRequests(@onNull List<CaptureRequest> requests, @NonNull @CallbackExecutor Executor executor, @NonNull CaptureCallback listener)763 public int setRepeatingBurstRequests(@NonNull List<CaptureRequest> requests, 764 @NonNull @CallbackExecutor Executor executor, @NonNull CaptureCallback listener) 765 throws CameraAccessException { 766 throw new UnsupportedOperationException("Subclasses must override this method"); 767 } 768 769 /** 770 * <p>Cancel any ongoing repeating capture set by either 771 * {@link #setRepeatingRequest setRepeatingRequest} or 772 * {@link #setRepeatingBurst}. Has no effect on requests submitted through 773 * {@link #capture capture} or {@link #captureBurst captureBurst}.</p> 774 * 775 * <p>Any currently in-flight captures will still complete, as will any burst that is 776 * mid-capture. To ensure that the device has finished processing all of its capture requests 777 * and is in ready state, wait for the {@link StateCallback#onReady} callback after 778 * calling this method.</p> 779 * 780 * @throws CameraAccessException if the camera device is no longer connected or has 781 * encountered a fatal error 782 * @throws IllegalStateException if this session is no longer active, either because the session 783 * was explicitly closed, a new session has been created 784 * or the camera device has been closed. 785 * 786 * @see #setRepeatingRequest 787 * @see #setRepeatingBurst 788 * @see StateCallback#onReady 789 */ stopRepeating()790 public abstract void stopRepeating() throws CameraAccessException; 791 792 /** 793 * Discard all captures currently pending and in-progress as fast as possible. 794 * 795 * <p>The camera device will discard all of its current work as fast as possible. Some in-flight 796 * captures may complete successfully and call {@link CaptureCallback#onCaptureCompleted}, while 797 * others will trigger their {@link CaptureCallback#onCaptureFailed} callbacks. If a repeating 798 * request or a repeating burst is set, it will be cleared.</p> 799 * 800 * <p>This method is the fastest way to switch the camera device to a new session with 801 * {@link CameraDevice#createCaptureSession} or 802 * {@link CameraDevice#createReprocessableCaptureSession}, at the cost of discarding in-progress 803 * work. It must be called before the new session is created. Once all pending requests are 804 * either completed or thrown away, the {@link StateCallback#onReady} callback will be called, 805 * if the session has not been closed. Otherwise, the {@link StateCallback#onClosed} 806 * callback will be fired when a new session is created by the camera device.</p> 807 * 808 * <p>Cancelling will introduce at least a brief pause in the stream of data from the camera 809 * device, since once the camera device is emptied, the first new request has to make it through 810 * the entire camera pipeline before new output buffers are produced.</p> 811 * 812 * <p>This means that using {@code abortCaptures()} to simply remove pending requests is not 813 * recommended; it's best used for quickly switching output configurations, or for cancelling 814 * long in-progress requests (such as a multi-second capture).</p> 815 * 816 * @throws CameraAccessException if the camera device is no longer connected or has 817 * encountered a fatal error 818 * @throws IllegalStateException if this session is no longer active, either because the session 819 * was explicitly closed, a new session has been created 820 * or the camera device has been closed. 821 * 822 * @see #setRepeatingRequest 823 * @see #setRepeatingBurst 824 * @see CameraDevice#createCaptureSession 825 * @see CameraDevice#createReprocessableCaptureSession 826 */ abortCaptures()827 public abstract void abortCaptures() throws CameraAccessException; 828 829 /** 830 * Return if the application can submit reprocess capture requests with this camera capture 831 * session. 832 * 833 * @return {@code true} if the application can submit reprocess capture requests with this 834 * camera capture session. {@code false} otherwise. 835 * 836 * @see CameraDevice#createReprocessableCaptureSession 837 */ isReprocessable()838 public abstract boolean isReprocessable(); 839 840 /** 841 * Get the input Surface associated with a reprocessable capture session. 842 * 843 * <p>Each reprocessable capture session has an input {@link Surface} where the reprocess 844 * capture requests get the input images from, rather than the camera device. The application 845 * can create a {@link android.media.ImageWriter ImageWriter} with this input {@link Surface} 846 * and use it to provide input images for reprocess capture requests. When the reprocessable 847 * capture session is closed, the input {@link Surface} is abandoned and becomes invalid.</p> 848 * 849 * @return The {@link Surface} where reprocessing capture requests get the input images from. If 850 * this is not a reprocess capture session, {@code null} will be returned. 851 * 852 * @see CameraDevice#createReprocessableCaptureSession 853 * @see android.media.ImageWriter 854 * @see android.media.ImageReader 855 */ 856 @Nullable getInputSurface()857 public abstract Surface getInputSurface(); 858 859 /** 860 * Update {@link OutputConfiguration} after configuration finalization see 861 * {@link #finalizeOutputConfigurations}. 862 * 863 * <p>Any {@link OutputConfiguration} that has been modified via calls to 864 * {@link OutputConfiguration#addSurface} or {@link OutputConfiguration#removeSurface} must be 865 * updated. After the update call returns without throwing exceptions any newly added surfaces 866 * can be referenced in subsequent capture requests.</p> 867 * 868 * <p>Surfaces that get removed must not be part of any active repeating or single/burst 869 * request or have any pending results. Consider updating any repeating requests first via 870 * {@link #setRepeatingRequest} or {@link #setRepeatingBurst} and then wait for the last frame 871 * number when the sequence completes {@link CaptureCallback#onCaptureSequenceCompleted} 872 * before calling updateOutputConfiguration to remove a previously active Surface.</p> 873 * 874 * <p>Surfaces that get added must not be part of any other registered 875 * {@link OutputConfiguration}.</p> 876 * 877 * @param config Modified output configuration. 878 * 879 * @throws CameraAccessException if the camera device is no longer connected or has 880 * encountered a fatal error. 881 * @throws IllegalArgumentException if an attempt was made to add a {@link Surface} already 882 * in use by another buffer-producing API, such as MediaCodec or 883 * a different camera device or {@link OutputConfiguration}; or 884 * new surfaces are not compatible (see 885 * {@link OutputConfiguration#enableSurfaceSharing}); or a 886 * {@link Surface} that was removed from the modified 887 * {@link OutputConfiguration} still has pending requests. 888 * @throws IllegalStateException if this session is no longer active, either because the session 889 * was explicitly closed, a new session has been created 890 * or the camera device has been closed. 891 */ updateOutputConfiguration(OutputConfiguration config)892 public void updateOutputConfiguration(OutputConfiguration config) 893 throws CameraAccessException { 894 throw new UnsupportedOperationException("Subclasses must override this method"); 895 } 896 897 /** 898 * Switch the current capture session and a given set of registered camera surfaces 899 * to offline processing mode. 900 * 901 * <p>Devices support this method will report 902 * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING OFFLINE_PROCESSING} 903 * capability in {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES}. When this method 904 * is supported, applications can use it to improve the latency of closing camera or recreating 905 * capture session without losing the in progress capture request outputs.</p> 906 * 907 * <p>Offline processing mode and the corresponding {@link CameraOfflineSession} differ from 908 * a regular online camera capture session in several ways. Successful offline switches will 909 * close the currently active camera capture session. Camera clients are also allowed 910 * to call {@link CameraDevice#close} while offline processing of selected capture 911 * requests is still in progress. Such side effects free device close is only possible 912 * when the offline session moves to the ready state. Once this happens, closing the camera 913 * device will not affect the pending offline requests and they must complete as normal.</p> 914 * 915 * <p>Offline processing mode switches may need several hundred milliseconds to complete 916 * as the underlying camera implementation must abort all currently active repeating requests 917 * as well as all other pending requests not specified by the client. Additionally the switch 918 * will be blocked until all requests that continue processing within the offline session 919 * acquire their initial input frame from camera sensor. The call to {@link #switchToOffline} 920 * itself is not blocking and will only trigger the offline switch sequence. Clients will 921 * be notified via {@link CameraOfflineSessionCallback#onReady} once the entire sequence is 922 * complete.</p> 923 * 924 * <p>Please note that after a successful call to this method the currently active capture 925 * session will no longer be valid and clients will begin receiving capture 926 * callbacks with a corresponding {@link CameraOfflineSession} passed as a session 927 * argument.</p> 928 * 929 * @param offlineSurfaces Client-specified collection of input/output camera registered surfaces 930 * that need to be switched to offline mode along with their pending 931 * capture requests. Do note that not all camera registered 932 * surfaces can be switched to offline mode. Offline processing 933 * support for individual surfaces can be queried using 934 * {@link #supportsOfflineProcessing}. Additionally offline mode 935 * switches are not available for shared surfaces 936 * {@link OutputConfiguration#enableSurfaceSharing} and surfaces 937 * as part of a surface group. 938 * 939 * @param executor The executor which will be used for invoking the offline callback listener. 940 * 941 * @param listener The callback object to notify for offline session events. 942 * 943 * @return camera offline session which in case of successful offline switch will move in ready 944 * state after clients receive {@link CameraOfflineSessionCallback#onReady}. In case the 945 * offline switch was not successful clients will receive respective 946 * {@link CameraOfflineSessionCallback#onSwitchFailed} notification. 947 * 948 * @throws IllegalArgumentException if an attempt was made to pass a {@link Surface} that was 949 * not registered with this capture session or a shared 950 * surface {@link OutputConfiguration#enableSurfaceSharing} or 951 * surface as part of a surface group. The current capture 952 * session will remain valid and active in case of this 953 * exception. 954 * 955 * @throws CameraAccessException if the camera device is no longer connected or has 956 * encountered a fatal error. 957 * 958 * @see CameraOfflineSession 959 * @see CameraOfflineSessionCallback 960 * @see #supportsOfflineProcessing 961 * @see CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING 962 */ 963 @Nullable switchToOffline(@onNull Collection<Surface> offlineSurfaces, @NonNull @CallbackExecutor Executor executor, @NonNull CameraOfflineSessionCallback listener)964 public CameraOfflineSession switchToOffline(@NonNull Collection<Surface> offlineSurfaces, 965 @NonNull @CallbackExecutor Executor executor, 966 @NonNull CameraOfflineSessionCallback listener) 967 throws CameraAccessException { 968 throw new UnsupportedOperationException("Subclasses must override this method"); 969 } 970 971 /** 972 * <p>Query whether a given Surface is able to support offline mode. </p> 973 * 974 * <p>Surfaces that support offline mode can be passed as arguments to {@link #switchToOffline}. 975 * </p> 976 * 977 * @param surface An input/output surface that was used to create this session or the result of 978 * {@link #getInputSurface}. 979 * 980 * @return {@code true} if the surface can support offline mode and can be passed as argument to 981 * {@link #switchToOffline}. {@code false} otherwise. 982 * 983 * @throws IllegalArgumentException if an attempt was made to pass a {@link Surface} that was 984 * not registered with this capture session. 985 * @throws UnsupportedOperationException if an attempt was made to call this method using 986 * unsupported camera capture session like 987 * {@link CameraConstrainedHighSpeedCaptureSession} or 988 * {@link CameraOfflineSession}. 989 * 990 * @see #switchToOffline 991 */ supportsOfflineProcessing(@onNull Surface surface)992 public boolean supportsOfflineProcessing(@NonNull Surface surface) { 993 throw new UnsupportedOperationException("Subclasses must override this method"); 994 } 995 996 /** 997 * Close this capture session asynchronously. 998 * 999 * <p>Closing a session frees up the target output Surfaces of the session for reuse with either 1000 * a new session, or to other APIs that can draw to Surfaces.</p> 1001 * 1002 * <p>Note that for common usage scenarios like creating a new session or closing the camera 1003 * device, it is faster to call respective APIs directly (see below for more details) without 1004 * calling into this method. This API is only useful when application wants to unconfigure the 1005 * camera but keep the device open for later use.</p> 1006 * 1007 * <p>Creating a new capture session with {@link CameraDevice#createCaptureSession} 1008 * will close any existing capture session automatically, and call the older session listener's 1009 * {@link StateCallback#onClosed} callback. Using {@link CameraDevice#createCaptureSession} 1010 * directly without closing is the recommended approach for quickly switching to a new session, 1011 * since unchanged target outputs can be reused more efficiently.</p> 1012 * 1013 * <p>Closing the device with {@link CameraDevice#close} directly without calling this API is 1014 * also recommended for quickly closing the camera.</p> 1015 * 1016 * <p>Once a session is closed, all methods on it will throw an IllegalStateException, and any 1017 * repeating requests or bursts are stopped (as if {@link #stopRepeating()} was called). 1018 * However, any in-progress capture requests submitted to the session will be completed as 1019 * normal; once all captures have completed and the session has been torn down, 1020 * {@link StateCallback#onClosed} will be called.</p> 1021 * 1022 * <p>Closing a session is idempotent; closing more than once has no effect.</p> 1023 */ 1024 @Override close()1025 public abstract void close(); 1026 1027 /** 1028 * A callback object for receiving updates about the state of a camera capture session. 1029 * 1030 */ 1031 public static abstract class StateCallback { 1032 1033 /** 1034 * This method is called when the camera device has finished configuring itself, and the 1035 * session can start processing capture requests. 1036 * 1037 * <p>If there are capture requests already queued with the session, they will start 1038 * processing once this callback is invoked, and the session will call {@link #onActive} 1039 * right after this callback is invoked.</p> 1040 * 1041 * <p>If no capture requests have been submitted, then the session will invoke 1042 * {@link #onReady} right after this callback.</p> 1043 * 1044 * <p>If the camera device configuration fails, then {@link #onConfigureFailed} will 1045 * be invoked instead of this callback.</p> 1046 * 1047 * @param session the successfully configured session instance 1048 */ onConfigured(@onNull CameraCaptureSession session)1049 public abstract void onConfigured(@NonNull CameraCaptureSession session); 1050 1051 /** 1052 * This method is called if the session cannot be configured as requested. 1053 * 1054 * <p>This can happen if the set of requested outputs contains unsupported sizes, 1055 * or too many outputs are requested at once.</p> 1056 * 1057 * <p>The session is considered to be closed, and all methods called on it after this 1058 * callback is invoked will throw an IllegalStateException. Any capture requests submitted 1059 * to the session prior to this callback will be discarded and will not produce any 1060 * callbacks on their listeners.</p> 1061 * 1062 * @param session the session instance that failed during configuration 1063 */ onConfigureFailed(@onNull CameraCaptureSession session)1064 public abstract void onConfigureFailed(@NonNull CameraCaptureSession session); 1065 1066 /** 1067 * This method is called every time the session has no more capture requests to process. 1068 * 1069 * <p>During the creation of a new session, this callback is invoked right after 1070 * {@link #onConfigured} if no capture requests were submitted to the session prior to it 1071 * completing configuration.</p> 1072 * 1073 * <p>Otherwise, this callback will be invoked any time the session finishes processing 1074 * all of its active capture requests, and no repeating request or burst is set up.</p> 1075 * 1076 * @param session the session returned by {@link #onConfigured} 1077 * 1078 */ onReady(@onNull CameraCaptureSession session)1079 public void onReady(@NonNull CameraCaptureSession session) { 1080 // default empty implementation 1081 } 1082 1083 /** 1084 * This method is called when the session starts actively processing capture requests. 1085 * 1086 * <p>If capture requests are submitted prior to {@link #onConfigured} being called, 1087 * then the session will start processing those requests immediately after the callback, 1088 * and this method will be immediately called after {@link #onConfigured}. 1089 * 1090 * <p>If the session runs out of capture requests to process and calls {@link #onReady}, 1091 * then this callback will be invoked again once new requests are submitted for capture.</p> 1092 * 1093 * @param session the session returned by {@link #onConfigured} 1094 */ onActive(@onNull CameraCaptureSession session)1095 public void onActive(@NonNull CameraCaptureSession session) { 1096 // default empty implementation 1097 } 1098 1099 /** 1100 * This method is called when camera device's input capture queue becomes empty, 1101 * and is ready to accept the next request. 1102 * 1103 * <p>Pending capture requests exist in one of two queues: the in-flight queue where requests 1104 * are already in different stages of processing pipeline, and an input queue where requests 1105 * wait to enter the in-flight queue. The input queue is needed because more requests may be 1106 * submitted than the current camera device pipeline depth.</p> 1107 * 1108 * <p>This callback is fired when the input queue becomes empty, and the camera device may 1109 * have to fall back to the repeating request if set, or completely skip the next frame from 1110 * the sensor. This can cause glitches to camera preview output, for example. This callback 1111 * will only fire after requests queued by capture() or captureBurst(), not after a 1112 * repeating request or burst enters the in-flight queue. For example, in the common case 1113 * of a repeating request and a single-shot JPEG capture, this callback only fires when the 1114 * JPEG request has entered the in-flight queue for capture.</p> 1115 * 1116 * <p>By only sending a new {@link #capture} or {@link #captureBurst} when the input 1117 * queue is empty, pipeline latency can be minimized.</p> 1118 * 1119 * <p>This callback is not fired when the session is first created. It is different from 1120 * {@link #onReady}, which is fired when all requests in both queues have been processed.</p> 1121 * 1122 * @param session 1123 * The session returned by {@link #onConfigured} 1124 */ onCaptureQueueEmpty(@onNull CameraCaptureSession session)1125 public void onCaptureQueueEmpty(@NonNull CameraCaptureSession session) { 1126 // default empty implementation 1127 } 1128 1129 /** 1130 * This method is called when the session is closed. 1131 * 1132 * <p>A session is closed when a new session is created by the parent camera device, 1133 * or when the parent camera device is closed (either by the user closing the device, 1134 * or due to a camera device disconnection or fatal error).</p> 1135 * 1136 * <p>Once a session is closed, all methods on it will throw an IllegalStateException, and 1137 * any repeating requests or bursts are stopped (as if {@link #stopRepeating()} was called). 1138 * However, any in-progress capture requests submitted to the session will be completed 1139 * as normal.</p> 1140 * 1141 * @param session the session returned by {@link #onConfigured} 1142 */ onClosed(@onNull CameraCaptureSession session)1143 public void onClosed(@NonNull CameraCaptureSession session) { 1144 // default empty implementation 1145 } 1146 1147 /** 1148 * This method is called when the buffer pre-allocation for an output Surface is complete. 1149 * 1150 * <p>Buffer pre-allocation for an output Surface is started by the {@link #prepare} call. 1151 * While allocation is underway, the Surface must not be used as a capture target. 1152 * Once this callback fires, the output Surface provided can again be used as a target for 1153 * a capture request.</p> 1154 * 1155 * <p>In case of a error during pre-allocation (such as running out of suitable memory), 1156 * this callback is still invoked after the error is encountered, though some buffers may 1157 * not have been successfully pre-allocated.</p> 1158 * 1159 * @param session the session returned by {@link #onConfigured} 1160 * @param surface the Surface that was used with the {@link #prepare} call. 1161 */ onSurfacePrepared(@onNull CameraCaptureSession session, @NonNull Surface surface)1162 public void onSurfacePrepared(@NonNull CameraCaptureSession session, 1163 @NonNull Surface surface) { 1164 // default empty implementation 1165 } 1166 } 1167 1168 /** 1169 * <p>A callback object for tracking the progress of a {@link CaptureRequest} submitted to the 1170 * camera device.</p> 1171 * 1172 * <p>This callback is invoked when a request triggers a capture to start, 1173 * and when the capture is complete. In case on an error capturing an image, 1174 * the error method is triggered instead of the completion method.</p> 1175 * 1176 * @see #capture 1177 * @see #captureBurst 1178 * @see #setRepeatingRequest 1179 * @see #setRepeatingBurst 1180 */ 1181 public static abstract class CaptureCallback { 1182 1183 /** 1184 * This constant is used to indicate that no images were captured for 1185 * the request. 1186 * 1187 * @hide 1188 */ 1189 public static final int NO_FRAMES_CAPTURED = -1; 1190 1191 /** 1192 * This method is called when the camera device has started capturing 1193 * the output image for the request, at the beginning of image exposure, or 1194 * when the camera device has started processing an input image for a reprocess 1195 * request. 1196 * 1197 * <p>For a regular capture request, this callback is invoked right as 1198 * the capture of a frame begins, so it is the most appropriate time 1199 * for playing a shutter sound, or triggering UI indicators of capture.</p> 1200 * 1201 * <p>The request that is being used for this capture is provided, along 1202 * with the actual timestamp for the start of exposure. For a reprocess 1203 * request, this timestamp will be the input image's start of exposure 1204 * which matches {@link CaptureResult#SENSOR_TIMESTAMP the result timestamp field} 1205 * of the {@link TotalCaptureResult} that was used to 1206 * {@link CameraDevice#createReprocessCaptureRequest create the reprocess request}. 1207 * This timestamp matches the timestamps that will be 1208 * included in {@link CaptureResult#SENSOR_TIMESTAMP the result timestamp field}, 1209 * and in the buffers sent to each output Surface. These buffer 1210 * timestamps are accessible through, for example, 1211 * {@link android.media.Image#getTimestamp() Image.getTimestamp()} or 1212 * {@link android.graphics.SurfaceTexture#getTimestamp()}. 1213 * The frame number included is equal to the frame number that will be included in 1214 * {@link CaptureResult#getFrameNumber}.</p> 1215 * 1216 * <p>For the simplest way to play a shutter sound camera shutter or a 1217 * video recording start/stop sound, see the 1218 * {@link android.media.MediaActionSound} class.</p> 1219 * 1220 * <p>The default implementation of this method does nothing.</p> 1221 * 1222 * @param session the session returned by {@link CameraDevice#createCaptureSession} 1223 * @param request the request for the capture that just begun 1224 * @param timestamp the timestamp at start of capture for a regular request, or 1225 * the timestamp at the input image's start of capture for a 1226 * reprocess request, in nanoseconds. 1227 * @param frameNumber the frame number for this capture 1228 * 1229 * @see android.media.MediaActionSound 1230 */ onCaptureStarted(@onNull CameraCaptureSession session, @NonNull CaptureRequest request, long timestamp, long frameNumber)1231 public void onCaptureStarted(@NonNull CameraCaptureSession session, 1232 @NonNull CaptureRequest request, long timestamp, long frameNumber) { 1233 // default empty implementation 1234 } 1235 1236 /** 1237 * This method is called when the camera device has started reading out the output 1238 * image for the request, at the beginning of the sensor image readout. 1239 * 1240 * <p>For a capture request, this callback is invoked right after 1241 * {@link #onCaptureStarted}. Unlike {@link #onCaptureStarted}, instead of passing 1242 * a timestamp of start of exposure, this callback passes a timestamp of start of 1243 * camera data readout. This is useful because for a camera running at fixed frame 1244 * rate, the start of readout is at fixed interval, which is not necessarily true for 1245 * the start of exposure, particularly when autoexposure is changing exposure duration 1246 * between frames.</p> 1247 * 1248 * <p>The timestamps match the timestamps of the output surfaces with readout timestamp 1249 * enabled (via {@link OutputConfiguration#setReadoutTimestampEnabled}) if:</p> 1250 * <ul> 1251 * <li> Timestamp base is {@link OutputConfiguration#TIMESTAMP_BASE_DEFAULT} and the 1252 * output 1253 * <ul> 1254 * <li> is not a SurfaceView surface, and </li> 1255 * <li> is not a MediaRecoder, MediaCodec, or ImageReader surface with {@link 1256 * android.hardware.HardwareBuffer#USAGE_VIDEO_ENCODE} usage flag or the device's {@link 1257 * CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE} is {@code UNKNOWN}</li> 1258 * </ul> 1259 * </li> 1260 * <li> Timestamp base is {@link OutputConfiguration#TIMESTAMP_BASE_SENSOR},</li> 1261 * <li> Timestamp base is {@link OutputConfiguration#TIMESTAMP_BASE_MONOTONIC} and the 1262 * device's {@link CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE} is {@code 1263 * UNKNOWN},</li> 1264 * <li> Timestamp base is {@link OutputConfiguration#TIMESTAMP_BASE_REALTIME} and the 1265 * device's {@link CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE} is {@code REALTIME} 1266 * </li> 1267 * </ul> 1268 * <p>Otherwise, the timestamps won't match the timestamp of the output surfaces. See 1269 * the possible parameters for {@link OutputConfiguration#setTimestampBase} for details.</p> 1270 * 1271 * <p>This callback will be called only if {@link 1272 * CameraCharacteristics#SENSOR_READOUT_TIMESTAMP} is 1273 * {@link CameraMetadata#SENSOR_READOUT_TIMESTAMP_HARDWARE}, and it's called 1274 * right after {@link #onCaptureStarted}.</p> 1275 * 1276 * @param session the session returned by {@link CameraDevice#createCaptureSession} 1277 * @param request the request for the readout that just began 1278 * @param timestamp the timestamp at start of readout for a regular request, or 1279 * the timestamp at the input image's start of readout for a 1280 * reprocess request, in nanoseconds. 1281 * @param frameNumber the frame number for this capture 1282 */ onReadoutStarted(@onNull CameraCaptureSession session, @NonNull CaptureRequest request, long timestamp, long frameNumber)1283 public void onReadoutStarted(@NonNull CameraCaptureSession session, 1284 @NonNull CaptureRequest request, long timestamp, long frameNumber) { 1285 // default empty implementation 1286 } 1287 1288 /** 1289 * This method is called when some results from an image capture are 1290 * available. 1291 * 1292 * <p>The result provided here will contain some subset of the fields of 1293 * a full result. Multiple onCapturePartial calls may happen per 1294 * capture; a given result field will only be present in one partial 1295 * capture at most. The final onCaptureCompleted call will always 1296 * contain all the fields, whether onCapturePartial was called or 1297 * not.</p> 1298 * 1299 * <p>The default implementation of this method does nothing.</p> 1300 * 1301 * @param session the session returned by {@link CameraDevice#createCaptureSession} 1302 * @param request The request that was given to the CameraDevice 1303 * @param result The partial output metadata from the capture, which 1304 * includes a subset of the CaptureResult fields. 1305 * 1306 * @see #capture 1307 * @see #captureBurst 1308 * @see #setRepeatingRequest 1309 * @see #setRepeatingBurst 1310 * 1311 * @hide 1312 */ onCapturePartial(CameraCaptureSession session, CaptureRequest request, CaptureResult result)1313 public void onCapturePartial(CameraCaptureSession session, 1314 CaptureRequest request, CaptureResult result) { 1315 // default empty implementation 1316 } 1317 1318 /** 1319 * This method is called when an image capture makes partial forward progress; some 1320 * (but not all) results from an image capture are available. 1321 * 1322 * <p>The result provided here will contain some subset of the fields of 1323 * a full result. Multiple {@link #onCaptureProgressed} calls may happen per 1324 * capture; a given result field will only be present in one partial 1325 * capture at most. The final {@link #onCaptureCompleted} call will always 1326 * contain all the fields (in particular, the union of all the fields of all 1327 * the partial results composing the total result).</p> 1328 * 1329 * <p>For each request, some result data might be available earlier than others. The typical 1330 * delay between each partial result (per request) is a single frame interval. 1331 * For performance-oriented use-cases, applications should query the metadata they need 1332 * to make forward progress from the partial results and avoid waiting for the completed 1333 * result.</p> 1334 * 1335 * <p>For a particular request, {@link #onCaptureProgressed} may happen before or after 1336 * {@link #onCaptureStarted}.</p> 1337 * 1338 * <p>Each request will generate at least {@code 1} partial results, and at most 1339 * {@link CameraCharacteristics#REQUEST_PARTIAL_RESULT_COUNT} partial results.</p> 1340 * 1341 * <p>Depending on the request settings, the number of partial results per request 1342 * will vary, although typically the partial count could be the same as long as the 1343 * camera device subsystems enabled stay the same.</p> 1344 * 1345 * <p>The default implementation of this method does nothing.</p> 1346 * 1347 * @param session the session returned by {@link CameraDevice#createCaptureSession} 1348 * @param request The request that was given to the CameraDevice 1349 * @param partialResult The partial output metadata from the capture, which 1350 * includes a subset of the {@link TotalCaptureResult} fields. 1351 * 1352 * @see #capture 1353 * @see #captureBurst 1354 * @see #setRepeatingRequest 1355 * @see #setRepeatingBurst 1356 */ onCaptureProgressed(@onNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult)1357 public void onCaptureProgressed(@NonNull CameraCaptureSession session, 1358 @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) { 1359 // default empty implementation 1360 } 1361 1362 /** 1363 * This method is called when an image capture has fully completed and all the 1364 * result metadata is available. 1365 * 1366 * <p>This callback will always fire after the last {@link #onCaptureProgressed}; 1367 * in other words, no more partial results will be delivered once the completed result 1368 * is available.</p> 1369 * 1370 * <p>For performance-intensive use-cases where latency is a factor, consider 1371 * using {@link #onCaptureProgressed} instead.</p> 1372 * 1373 * <p>The default implementation of this method does nothing.</p> 1374 * 1375 * @param session the session returned by {@link CameraDevice#createCaptureSession} 1376 * @param request The request that was given to the CameraDevice 1377 * @param result The total output metadata from the capture, including the 1378 * final capture parameters and the state of the camera system during 1379 * capture. 1380 * 1381 * @see #capture 1382 * @see #captureBurst 1383 * @see #setRepeatingRequest 1384 * @see #setRepeatingBurst 1385 */ onCaptureCompleted(@onNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result)1386 public void onCaptureCompleted(@NonNull CameraCaptureSession session, 1387 @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) { 1388 // default empty implementation 1389 } 1390 1391 /** 1392 * This method is called instead of {@link #onCaptureCompleted} when the 1393 * camera device failed to produce a {@link CaptureResult} for the 1394 * request. 1395 * 1396 * <p>Other requests are unaffected, and some or all image buffers from 1397 * the capture may have been pushed to their respective output 1398 * streams.</p> 1399 * 1400 * <p>If a logical multi-camera fails to generate capture result for one of 1401 * its physical cameras, this method will be called with a {@link CaptureFailure} 1402 * for that physical camera. In such cases, as long as the logical camera capture 1403 * result is valid, {@link #onCaptureCompleted} will still be called.</p> 1404 * 1405 * <p>The default implementation of this method does nothing.</p> 1406 * 1407 * @param session 1408 * The session returned by {@link CameraDevice#createCaptureSession} 1409 * @param request 1410 * The request that was given to the CameraDevice 1411 * @param failure 1412 * The output failure from the capture, including the failure reason 1413 * and the frame number. 1414 * 1415 * @see #capture 1416 * @see #captureBurst 1417 * @see #setRepeatingRequest 1418 * @see #setRepeatingBurst 1419 */ onCaptureFailed(@onNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureFailure failure)1420 public void onCaptureFailed(@NonNull CameraCaptureSession session, 1421 @NonNull CaptureRequest request, @NonNull CaptureFailure failure) { 1422 // default empty implementation 1423 } 1424 1425 /** 1426 * This method is called independently of the others in CaptureCallback, 1427 * when a capture sequence finishes and all {@link CaptureResult} 1428 * or {@link CaptureFailure} for it have been returned via this listener. 1429 * 1430 * <p>In total, there will be at least one result/failure returned by this listener 1431 * before this callback is invoked. If the capture sequence is aborted before any 1432 * requests have been processed, {@link #onCaptureSequenceAborted} is invoked instead.</p> 1433 * 1434 * <p>The default implementation does nothing.</p> 1435 * 1436 * @param session 1437 * The session returned by {@link CameraDevice#createCaptureSession} 1438 * @param sequenceId 1439 * A sequence ID returned by the {@link #capture} family of functions. 1440 * @param frameNumber 1441 * The last frame number (returned by {@link CaptureResult#getFrameNumber} 1442 * or {@link CaptureFailure#getFrameNumber}) in the capture sequence. 1443 * 1444 * @see CaptureResult#getFrameNumber() 1445 * @see CaptureFailure#getFrameNumber() 1446 * @see CaptureResult#getSequenceId() 1447 * @see CaptureFailure#getSequenceId() 1448 * @see #onCaptureSequenceAborted 1449 */ onCaptureSequenceCompleted(@onNull CameraCaptureSession session, int sequenceId, long frameNumber)1450 public void onCaptureSequenceCompleted(@NonNull CameraCaptureSession session, 1451 int sequenceId, long frameNumber) { 1452 // default empty implementation 1453 } 1454 1455 /** 1456 * This method is called independently of the others in CaptureCallback, 1457 * when a capture sequence aborts before any {@link CaptureResult} 1458 * or {@link CaptureFailure} for it have been returned via this listener. 1459 * 1460 * <p>Due to the asynchronous nature of the camera device, not all submitted captures 1461 * are immediately processed. It is possible to clear out the pending requests 1462 * by a variety of operations such as {@link CameraCaptureSession#stopRepeating} or 1463 * {@link CameraCaptureSession#abortCaptures}. When such an event happens, 1464 * {@link #onCaptureSequenceCompleted} will not be called.</p> 1465 * 1466 * <p>The default implementation does nothing.</p> 1467 * 1468 * @param session 1469 * The session returned by {@link CameraDevice#createCaptureSession} 1470 * @param sequenceId 1471 * A sequence ID returned by the {@link #capture} family of functions. 1472 * 1473 * @see CaptureResult#getFrameNumber() 1474 * @see CaptureFailure#getFrameNumber() 1475 * @see CaptureResult#getSequenceId() 1476 * @see CaptureFailure#getSequenceId() 1477 * @see #onCaptureSequenceCompleted 1478 */ onCaptureSequenceAborted(@onNull CameraCaptureSession session, int sequenceId)1479 public void onCaptureSequenceAborted(@NonNull CameraCaptureSession session, 1480 int sequenceId) { 1481 // default empty implementation 1482 } 1483 1484 /** 1485 * <p>This method is called if a single buffer for a capture could not be sent to its 1486 * destination surface.</p> 1487 * 1488 * <p>If the whole capture failed, then {@link #onCaptureFailed} will be called instead. If 1489 * some but not all buffers were captured but the result metadata will not be available, 1490 * then onCaptureFailed will be invoked with {@link CaptureFailure#wasImageCaptured} 1491 * returning true, along with one or more calls to {@link #onCaptureBufferLost} for the 1492 * failed outputs.</p> 1493 * 1494 * @param session 1495 * The session returned by {@link CameraDevice#createCaptureSession} 1496 * @param request 1497 * The request that was given to the CameraDevice 1498 * @param target 1499 * The target Surface that the buffer will not be produced for 1500 * @param frameNumber 1501 * The frame number for the request 1502 */ onCaptureBufferLost(@onNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull Surface target, long frameNumber)1503 public void onCaptureBufferLost(@NonNull CameraCaptureSession session, 1504 @NonNull CaptureRequest request, @NonNull Surface target, long frameNumber) { 1505 // default empty implementation 1506 } 1507 } 1508 1509 } 1510