1 /* <lambda>null2 * Copyright 2020 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.camera2.pipe 18 19 import android.hardware.camera2.CameraCaptureSession 20 import android.hardware.camera2.CameraConstrainedHighSpeedCaptureSession 21 import android.hardware.camera2.CameraDevice 22 import android.hardware.camera2.CaptureRequest 23 import android.hardware.camera2.params.MeteringRectangle 24 import android.hardware.camera2.params.SessionConfiguration 25 import android.os.Build 26 import android.view.Surface 27 import androidx.annotation.RestrictTo 28 import androidx.camera.camera2.pipe.CameraGraph.Constants3A.DEFAULT_FRAME_LIMIT 29 import androidx.camera.camera2.pipe.CameraGraph.Constants3A.DEFAULT_TIME_LIMIT_NS 30 import androidx.camera.camera2.pipe.CameraGraph.Flags.FinalizeSessionOnCloseBehavior.Companion.OFF 31 import androidx.camera.camera2.pipe.CameraGraph.OperatingMode.Companion.EXTENSION 32 import androidx.camera.camera2.pipe.CameraGraph.OperatingMode.Companion.HIGH_SPEED 33 import androidx.camera.camera2.pipe.CameraGraph.OperatingMode.Companion.NORMAL 34 import androidx.camera.camera2.pipe.CameraGraph.RepeatingRequestRequirementsBeforeCapture.CompletionBehavior.AT_LEAST 35 import androidx.camera.camera2.pipe.CameraGraph.RepeatingRequestRequirementsBeforeCapture.CompletionBehavior.EXACT 36 import androidx.camera.camera2.pipe.GraphState.GraphStateStarting 37 import androidx.camera.camera2.pipe.GraphState.GraphStateStopped 38 import androidx.camera.camera2.pipe.GraphState.GraphStateStopping 39 import androidx.camera.camera2.pipe.compat.Camera2Quirks 40 import androidx.camera.camera2.pipe.core.Log 41 import kotlinx.coroutines.CancellationException 42 import kotlinx.coroutines.CoroutineScope 43 import kotlinx.coroutines.Deferred 44 import kotlinx.coroutines.flow.StateFlow 45 46 /** A [CameraGraph] represents the combined configuration and state of a camera. */ 47 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 48 public interface CameraGraph : AutoCloseable { 49 /** 50 * A unique identifier for this CameraGraph instance. This can be used to identify the graph 51 * without holding a hard reference to the CameraGraph itself. 52 */ 53 public val id: CameraGraphId 54 55 /** The [StreamGraph] for this CameraGraph instance. */ 56 public val streams: StreamGraph 57 58 /** 59 * Returns the state flow of [GraphState], which emits the current state of the [CameraGraph], 60 * including when a [CameraGraph] is stopped, starting or started. 61 */ 62 public val graphState: StateFlow<GraphState> 63 64 /** 65 * This is a hint an app can give to a camera graph to indicate whether the camera is being used 66 * in a foreground setting, for example whether the user could see the app itself. This would 67 * inform the underlying implementation to open cameras more actively (e.g., longer timeout). 68 */ 69 public var isForeground: Boolean 70 71 /** 72 * This enables setting parameter values directly without having callers of [CameraGraph] to 73 * acquire sessions manually, but instead session is acquired on callers' behalf when making 74 * changes in [Parameters]. For detailed usage see [Parameters]. 75 */ 76 public val parameters: Parameters 77 78 /** 79 * This will cause the [CameraGraph] to start opening the [CameraDevice] and configuring a 80 * [CameraCaptureSession]. While the CameraGraph is alive it will attempt to keep the camera 81 * open, active, and in a configured running state. 82 */ 83 public fun start() 84 85 /** 86 * This will cause the [CameraGraph] to stop executing requests and close the current Camera2 87 * [CameraCaptureSession] (if one is active). The most recent repeating request will be 88 * preserved, and any calls to submit a request to a session will be enqueued. To stop requests 89 * from being enqueued, close the [CameraGraph]. 90 */ 91 public fun stop() 92 93 /** 94 * Used exclusively interact with the camera via a [Session] from within an existing suspending 95 * function. This function will suspend until the internal mutex lock can be acquired and 96 * returned. When possible, prefer [useSession] when possible as it will guarantee that the 97 * session will be closed. 98 * 99 * The returned [Session] **must** be closed. 100 */ 101 public suspend fun acquireSession(): Session 102 103 /** 104 * Immediately try to acquire access to the internal mutex lock, and return null if it is not 105 * currently available. 106 * 107 * The returned [Session] **must** be closed. 108 */ 109 public fun acquireSessionOrNull(): Session? 110 111 /** 112 * Used exclusively interact with the camera via a [Session] from within an existing suspending 113 * function. This method will suspend until the internal mutex lock can be acquired. This is 114 * similar to [acquireSession] an [use] with the additional guarantee that all launch and async 115 * calls will complete before the lock is released (unless the [Session] is closed early). The 116 * [action] will always execute unless parent scope has been canceled. 117 * 118 * Example: 119 * ``` 120 * suspend fun process(cameraGraph: CameraGraph, analysisStream: CameraStream) { 121 * cameraGraph.useSession { session -> 122 * val result = session.capture( 123 * Request(streams = listOf(jpegStream.id)) 124 * ) 125 * val frame = result.awaitFrame() 126 * val image = frame?.awaitImage(analysisStream.id) 127 * // process image if not null 128 * } 129 * } 130 * ``` 131 */ 132 public suspend fun <T> useSession(action: suspend CoroutineScope.(Session) -> T): T 133 134 /** 135 * Used to exclusively interact with the camera from a normal function with a [Session] by 136 * acquiring a lock to the internal mutex and running the [action] in the provided [scope]. This 137 * is similar to [useSession] with the additional guarantee that multiple calls to 138 * [useSessionIn] will be executed in the same order they are invoked in, which is not the case 139 * for `scope.launch` or `scope.async`. When possible, prefer using this function when 140 * interacting with a [CameraGraph.Session] from non-suspending code. The [action] will always 141 * execute unless parent scope has been canceled. 142 * 143 * Example: 144 * ``` 145 * fun capture( 146 * cameraGraph: CameraGraph, jpegStream: CameraStream, scope: CoroutineScope 147 * ) { 148 * cameraGraph.useSessionIn(scope) { session -> 149 * val result = session.capture( 150 * Request(streams = listOf(jpegStream.id)) 151 * ) 152 * val frame = result.awaitFrame() 153 * val jpeg = frame?.awaitImage(jpegStream.id) 154 * // Save jpeg 155 * } 156 * } 157 * ``` 158 */ 159 public fun <T> useSessionIn( 160 scope: CoroutineScope, 161 action: suspend CoroutineScope.(Session) -> T 162 ): Deferred<T> 163 164 /** 165 * This configures the camera graph to use a specific Surface for the given stream. 166 * 167 * Changing a surface may cause the camera to stall and/or reconfigure. 168 */ 169 public fun setSurface(stream: StreamId, surface: Surface?) 170 171 /** 172 * CameraPipe allows setting the global audio restriction through [CameraPipe] and audio 173 * restrictions on individual [CameraGraph]s. When multiple settings are present, the highest 174 * level of audio restriction across global and individual [CameraGraph]s is used as the 175 * device's audio restriction. 176 * 177 * Sets the audio restriction of CameraGraph. 178 */ 179 public fun updateAudioRestrictionMode(mode: AudioRestrictionMode) 180 181 /** 182 * This defines the configuration, flags, and pre-defined structure of a [CameraGraph] instance. 183 * Note that for parameters, null is considered a valid value, and unset keys are ignored. 184 * 185 * @param camera The Camera2 [CameraId] that this [CameraGraph] represents. 186 * @param streams A list of [CameraStream]s to use when building the configuration. 187 * @param exclusiveStreamGroups A list of [CameraStream] groups where the [CameraStream]s in a 188 * group aren't expected to used simultaneously. 189 * @param input A list of input configurations to support Camera2 Reprocessing. 190 * @param sessionTemplate The template id to use when creating the [CaptureRequest] to supply 191 * the default parameters for a [SessionConfiguration] object. 192 * @param sessionParameters the extra parameters to apply to the [CaptureRequest] used to supply 193 * the default parameters for a [SessionConfiguration] object. These parameters are *only* 194 * used to create the [CaptureRequest] for session configuration. Use [defaultParameters] or 195 * [requiredParameters] to enforce that the key is set for every request. 196 * @param sessionMode defines the [OperatingMode] of the session. May be used to configure a 197 * [CameraConstrainedHighSpeedCaptureSession] for slow motion capture (If available) 198 * @param defaultTemplate The default template to be used if a [Request] does not specify one. 199 * @param defaultParameters The default parameters to be used for a [Request]. 200 * @param defaultListeners A default set of listeners that will be added to every [Request]. 201 * @param requiredParameters Will override any other configured parameter, and can be used to 202 * enforce that specific keys are always set to specific value for every [CaptureRequest]. 203 * @param cameraBackendId If defined, this tells the [CameraGraph] to use a specific 204 * [CameraBackend] to open and operate the camera. The defined [camera] parameter must be a 205 * camera that can be opened by this [CameraBackend]. If this value is null it will use the 206 * default backend that has been configured by [CameraPipe]. 207 * @param customCameraBackend If defined, this [customCameraBackend] will be created an used for 208 * _only_ this [CameraGraph]. This cannot be defined if [cameraBackendId] is defined. 209 */ 210 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 211 public data class Config( 212 val camera: CameraId, 213 val streams: List<CameraStream.Config>, 214 val exclusiveStreamGroups: List<List<CameraStream.Config>> = listOf(), 215 val input: List<InputStream.Config>? = null, 216 val postviewStream: CameraStream.Config? = null, 217 val sessionTemplate: RequestTemplate = RequestTemplate(1), 218 val sessionParameters: Map<*, Any?> = emptyMap<Any, Any?>(), 219 val sessionMode: OperatingMode = NORMAL, 220 val defaultTemplate: RequestTemplate = RequestTemplate(1), 221 val defaultParameters: Map<*, Any?> = emptyMap<Any, Any?>(), 222 val defaultListeners: List<Request.Listener> = listOf(), 223 val requiredParameters: Map<*, Any?> = emptyMap<Any, Any?>(), 224 val cameraBackendId: CameraBackendId? = null, 225 val customCameraBackend: CameraBackendFactory? = null, 226 val metadataTransform: MetadataTransform = MetadataTransform(), 227 val flags: Flags = Flags(), 228 // TODO: Internal error handling. May be better at the CameraPipe level. 229 ) { 230 internal var sharedCameraIds: List<CameraId> = emptyList() 231 232 init { 233 check(cameraBackendId == null || customCameraBackend == null) { 234 "Setting both cameraBackendId and customCameraBackend is not supported." 235 } 236 } 237 } 238 239 public class ConcurrentConfig(graphConfigs: List<Config>) { 240 public val graphConfigs: List<Config> 241 242 init { 243 check(graphConfigs.size >= 2) { 244 "Cannot create ConcurrentGraphConfig without 2 or more CameraGraph.Config(s)" 245 } 246 val firstConfig = graphConfigs.first() 247 check(graphConfigs.all { it.cameraBackendId == firstConfig.cameraBackendId }) { 248 "Each CameraGraph.Config must use the same camera backend!" 249 } 250 251 val distinctCameraIds = graphConfigs.map { it.camera }.distinct() 252 check(distinctCameraIds.size == graphConfigs.size) { 253 "Each CameraGraph.Config must have a distinct camera id!" 254 } 255 256 this.graphConfigs = 257 graphConfigs.map { config -> 258 config.apply { 259 sharedCameraIds = distinctCameraIds.filter { it != config.camera } 260 } 261 } 262 } 263 } 264 265 /** 266 * Defines the repeating request requirements before a non-repeating capture. 267 * 268 * If `completionBehavior` is [AT_LEAST], repeating frames are completed at least 269 * `repeatingFramesToComplete` number of times before submitting capture. However, CameraPipe 270 * may wait for more repeating capture frames if required. 271 * 272 * If [EXACT] is used, any CameraPipe behavior is overwritten and exactly 273 * `repeatingFramesToComplete` number of frames are completed before submitting capture. This 274 * can be used in conjunction with a `repeatingFramesToComplete` value of zero to disable any 275 * CameraPipe quirky behavior added as a workaround. See 276 * [Camera2Quirks.getRepeatingRequestFrameCountForCapture] for details. 277 * 278 * @param repeatingFramesToComplete Number of repeating frames to complete before submitting a 279 * capture. A value of zero implies no such requirement. 280 * @param completionBehavior The behavior for how `repeatingFramesToComplete` is handled. 281 */ 282 public class RepeatingRequestRequirementsBeforeCapture( 283 public val repeatingFramesToComplete: UInt = 0u, 284 public val completionBehavior: CompletionBehavior = AT_LEAST, 285 ) { 286 /** 287 * Defines the behavior for how [repeatingFramesToComplete] parameter of 288 * `RepeatingRequestRequirementsBeforeCapture` is handled. 289 * 290 * @see RepeatingRequestRequirementsBeforeCapture 291 */ 292 public enum class CompletionBehavior { 293 AT_LEAST, 294 EXACT 295 } 296 } 297 298 /** 299 * Flags define boolean values that are used to adjust the behavior and interactions with 300 * camera2. These flags should default to the ideal behavior and should be overridden on 301 * specific devices to be faster or to work around bad behavior. 302 */ 303 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 304 public data class Flags( 305 val configureBlankSessionOnStop: Boolean = false, 306 307 /** 308 * When creating a new capture session, the camera framework waits for all the inflight 309 * capture requests from the prior session before creating the new session. Calling 310 * abortCaptures() triggers an explicit flush on the camera HAL side. Therefore, aborting 311 * the captures allows us to switch to a new capture session sooner (see the referenced bug 312 * for more info). 313 * 314 * However, there might be cases where we might not want to trigger the flush. For example, 315 * if we're recording a video, we may not want the video recording to be disrupted too 316 * early. Hence, this flag is provided so that we can override this behavior. 317 * 318 * Ideally we should be able to invoke abortCaptures() every time during close. However, 319 * improper flush implementations, which seem to occur largely on older devices, have shown 320 * to cause irregular behaviors, such as NPEs (b/139448807), capture session entering 321 * abnormal states (b/162314023), and (potentially) camera device close stalling based on 322 * testing, etc. Hence, we're enabling this behavior by default on API level >= R (30) for 323 * now. 324 * - Bug(s): b/287020251 325 * - API levels: R (30) and above 326 */ 327 val abortCapturesOnStop: Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.R, 328 329 /** 330 * An override flag for quirk that requires waiting for the last repeating capture request 331 * (if any) to start before submitting a non-repeating capture request in case no repeating 332 * request has started yet. 333 * 334 * The value represents how many repeating request captures need to be completed before a 335 * non-repeating capture. Note that CameraPipe may have its own logic to. When null, 336 * CameraPipe will use its own logic to decide whether such a workaround is required. When 337 * zero or negative, CameraPipe will disable such behavior. 338 * 339 * Please refer to the bugs linked here, or 340 * [Camera2Quirks.getRepeatingRequestFrameCountForCapture] for more information. This flag 341 * provides the overrides for you to enable a workaround to fix such issues. 342 * - Bug(s): b/356792665 343 * - API levels: All 344 */ 345 val awaitRepeatingRequestBeforeCapture: RepeatingRequestRequirementsBeforeCapture = 346 RepeatingRequestRequirementsBeforeCapture(), 347 348 /** 349 * Flag to wait for the last repeating capture request to start before stopping the current 350 * capture session. Please refer to the bugs linked here, or 351 * [Camera2Quirks.shouldWaitForRepeatingRequestStartOnDisconnect] for more information. 352 * 353 * This flag provides the overrides for you to override the default behavior (CameraPipe 354 * would turn on/off the quirk automatically based on device information). 355 * - Bug(s): b/146773463, b/267557892 356 * - Device(s): Camera devices on hardware level LEGACY 357 * - API levels: All 358 */ 359 val awaitRepeatingRequestOnDisconnect: Boolean? = null, 360 361 /** 362 * Flag to finalize [androidx.camera.camera2.pipe.compat.CaptureSessionState] when the 363 * CameraGraph is stopped or closed. When a CameraGraph is started, the app might wait for 364 * the Surfaces to be released before setting the new Surfaces. This creates a potential 365 * deadlock, and this quirk is aimed to mitigate such behavior by releasing the Surfaces 366 * (finalizing the session) when the graph is stopped or closed. 367 * - Bug(s): b/277310425 368 * - Device(s): All (but behaviors might differ across devices) 369 * - API levels: All 370 */ 371 val finalizeSessionOnCloseBehavior: FinalizeSessionOnCloseBehavior = OFF, 372 373 /** 374 * Flag to close the camera capture session when the CameraGraph is stopped or closed. This 375 * is needed in cases where the app that do not wish to receive further frames, or in cases 376 * where not closing the capture session before closing the camera device might cause the 377 * camera close call itself to hang indefinitely. 378 * - Bug(s): b/277310425, b/277310425 379 * - Device(s): Depends on the situation and the use case. 380 * - API levels: All 381 */ 382 val closeCaptureSessionOnDisconnect: Boolean = false, 383 384 /** 385 * Flag to close the camera device when the CameraGraph is closed. This is needed on devices 386 * where not closing the camera device before creating a new capture session can lead to 387 * crashes. 388 * - Bug(s): b/282871038 389 * - Device(s): Exynos7870 platforms. 390 * - API levels: All 391 */ 392 val closeCameraDeviceOnClose: Boolean = false, 393 394 /** 395 * Flag to enable CameraGraph to restart its internal camera controller(s) with a delay. The 396 * delay might be needed during Activity switching, to allow time for the preceding Activity 397 * to close its CameraGraphs to allow for the succeeding Activity to acquire the same 398 * camera. 399 * - Bug(s): b/344752133, b/153714651 400 * - Device(s): CameraX users 401 */ 402 val enableRestartDelays: Boolean = false 403 ) { 404 405 @JvmInline 406 public value class FinalizeSessionOnCloseBehavior 407 private constructor(public val value: Int) { 408 public companion object { 409 /** 410 * OFF indicates that the CameraGraph only finalizes capture session under regular 411 * conditions, i.e., when the camera device is closed, or when a new capture session 412 * is created. 413 */ 414 public val OFF: FinalizeSessionOnCloseBehavior = FinalizeSessionOnCloseBehavior(0) 415 416 /** 417 * IMMEDIATE indicates that the CameraGraph will finalize the current session 418 * immediately when the CameraGraph is stopped or closed. This should be the default 419 * behavior for devices that allows for immediate Surface reuse. 420 */ 421 public val IMMEDIATE: FinalizeSessionOnCloseBehavior = 422 FinalizeSessionOnCloseBehavior(1) 423 424 /** 425 * TIMEOUT indicates that the CameraGraph will finalize the current session on a 2s 426 * timeout when the CameraGraph is stopped or closed. This should only be enabled 427 * for devices that require waiting for Surfaces to be released. 428 */ 429 public val TIMEOUT: FinalizeSessionOnCloseBehavior = 430 FinalizeSessionOnCloseBehavior(2) 431 } 432 } 433 } 434 435 /** 436 * Operating mode defines the major categories of how a CameraGraph instance will operate when 437 * not operating a [NORMAL] camera graph. 438 * 439 * @property NORMAL represents standard camera operation and behavior. 440 * @property HIGH_SPEED represents a camera operating at high frame rate, usually used to 441 * produce slow motion videos. 442 * @property EXTENSION represents device-specific modes that may operate differently or have 443 * significant limitations in order to produce specific kinds of camera results. 444 */ 445 @JvmInline 446 public value class OperatingMode private constructor(internal val mode: Int) { 447 public companion object { 448 public val NORMAL: OperatingMode = OperatingMode(0) 449 public val HIGH_SPEED: OperatingMode = OperatingMode(1) 450 public val EXTENSION: OperatingMode = OperatingMode(2) 451 452 public fun custom(mode: Int): OperatingMode { 453 require(mode != NORMAL.mode && mode != HIGH_SPEED.mode) { 454 Log.error { "Custom operating mode $mode conflicts with standard modes" } 455 } 456 return OperatingMode(mode) 457 } 458 } 459 } 460 461 public object Constants3A { 462 // Constants related to controlling the time or frame budget a 3A operation should get. 463 public const val DEFAULT_FRAME_LIMIT: Int = 60 464 public const val DEFAULT_TIME_LIMIT_MS: Int = 3_000 465 public const val DEFAULT_TIME_LIMIT_NS: Long = 3_000_000_000L 466 467 // Constants related to metering regions. 468 /** No metering region is specified. */ 469 public val METERING_REGIONS_EMPTY: Array<MeteringRectangle> = emptyArray() 470 471 /** 472 * No-op metering regions, this will tell camera device to pick the right metering region 473 * for us. 474 */ 475 public val METERING_REGIONS_DEFAULT: Array<MeteringRectangle> = 476 arrayOf(MeteringRectangle(0, 0, 0, 0, 0)) 477 478 /** Placeholder frame number for [Result3A] when a 3A method encounters an error. */ 479 public val FRAME_NUMBER_INVALID: FrameNumber = FrameNumber(-1L) 480 } 481 482 /** 483 * A [Session] is an interactive lock for [CameraGraph] and allows state to be changed. 484 * 485 * Holding this object prevents other systems from acquiring a [Session] until the currently 486 * held session is released. Because of its exclusive nature, [Session]s are intended for fast, 487 * short-lived state updates, or for interactive capture sequences that must not be altered. 488 * (Flash photo sequences, for example). 489 * 490 * While this object is thread-safe, it should not shared or held for long periods of time. 491 * Example: A [Session] should *not* be held during video recording. 492 */ 493 @JvmDefaultWithCompatibility 494 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 495 public interface Session : AutoCloseable { 496 /** 497 * Causes the CameraGraph to start or update the current repeating request with the provided 498 * [Request] object. The [Request] object may be cached, and may be used for other 499 * interactions with the camera (such as updating 3A, or issuing 3A triggers). 500 */ 501 public fun startRepeating(request: Request) 502 503 /** Stop the current repeating request. */ 504 public fun stopRepeating() 505 506 /** 507 * Submit the [Request] to the camera. Requests are issued to the Camera, in order, on a 508 * background queue. Each call to submit will issue the [Request] to the camera exactly once 509 * unless the request is invalid, or unless the requests are aborted via [abort]. The same 510 * request can be submitted multiple times. 511 */ 512 public fun submit(request: Request) 513 514 /** 515 * Submit the [Request]s to the camera. [Request]s are issued to the Camera, in order, on a 516 * background queue. Each call to submit will issue the List of [Request]s to the camera 517 * exactly once unless the one or more of the requests are invalid, or unless the requests 518 * are aborted via [abort]. The same list of [Request]s may be submitted multiple times. 519 */ 520 public fun submit(requests: List<Request>) 521 522 /** 523 * Submit the [Request] to the camera, and aggregate the results into a [FrameCapture], 524 * which can be used to wait for the [Frame] to start using [FrameCapture.awaitFrame]. 525 * 526 * The [FrameCapture] **must** be closed, or it will result in a memory leak. 527 */ 528 public fun capture(request: Request): FrameCapture 529 530 /** 531 * Submit the [Request]s to the camera, and aggregate the results into a list of 532 * [FrameCapture]s, which can be used to wait for the associated [Frame] using 533 * [FrameCapture.awaitFrame]. 534 * 535 * Each [FrameCapture] **must** be closed, or it will result in a memory leak. 536 */ 537 public fun capture(requests: List<Request>): List<FrameCapture> 538 539 /** 540 * Abort in-flight requests. This will abort *all* requests in the current 541 * CameraCaptureSession as well as any requests that are enqueued, but that have not yet 542 * been submitted to the camera. 543 */ 544 public fun abort() 545 546 /** 547 * Applies the given 3A parameters to the camera device. 548 * 549 * @return A [Deferred] of [Result3A] value which will contain the frame number for which 550 * these parameters were applied. It may be cancelled with a [CancellationException] if a 551 * newer request is submitted before completion. 552 */ 553 public fun update3A( 554 aeMode: AeMode? = null, 555 afMode: AfMode? = null, 556 awbMode: AwbMode? = null, 557 aeRegions: List<MeteringRectangle>? = null, 558 afRegions: List<MeteringRectangle>? = null, 559 awbRegions: List<MeteringRectangle>? = null 560 ): Deferred<Result3A> 561 562 /** 563 * Applies the given 3A parameters to the camera device but for only one frame. 564 * 565 * @return the FrameNumber for which these parameters were applied. 566 */ 567 public suspend fun submit3A( 568 aeMode: AeMode? = null, 569 afMode: AfMode? = null, 570 awbMode: AwbMode? = null, 571 aeRegions: List<MeteringRectangle>? = null, 572 afRegions: List<MeteringRectangle>? = null, 573 awbRegions: List<MeteringRectangle>? = null 574 ): Deferred<Result3A> 575 576 /** 577 * Turns the torch to ON. 578 * 579 * This method has a side effect on the currently set AE mode. Ref: 580 * https://developer.android.com/reference/android/hardware/camera2/CaptureRequest#FLASH_MODE 581 * To use the flash control, AE mode must be set to ON or OFF. So if the AE mode is already 582 * not either ON or OFF, we will need to update the AE mode to one of those states, here we 583 * will choose ON. It is the responsibility of the application layer above CameraPipe to 584 * restore the AE mode after the torch control has been used. The [setTorchOff] or 585 * [update3A] method can be used to restore the AE state to a previous value. 586 * 587 * @return the FrameNumber at which the turn was fully turned on if switch was ON, or the 588 * FrameNumber at which it was completely turned off when the switch was OFF. 589 */ 590 public fun setTorchOn(): Deferred<Result3A> 591 592 /** 593 * Turns the torch to OFF. 594 * 595 * @param aeMode The [AeMode] to set while disabling the torch value. If null which is the 596 * default value, the current AE mode is used. 597 * @return the FrameNumber at which the turn was fully turned on if switch was ON, or the 598 * FrameNumber at which it was completely turned off when the switch was OFF. 599 */ 600 public fun setTorchOff(aeMode: AeMode? = null): Deferred<Result3A> 601 602 /** 603 * Locks the auto-exposure, auto-focus and auto-whitebalance as per the given desired 604 * behaviors. This given 3A parameters are applied before the lock is obtained. If 'null' 605 * value is passed for a parameter, that parameter is ignored, and the current value for 606 * that parameter continues to be applied. 607 * 608 * @param afTriggerStartAeMode the AeMode value that should override current AeMode for 609 * AF_TRIGGER_START request, this value should not be retained for following requests 610 * @param convergedCondition an optional function can be used to identify if the result 611 * frame with correct 3A converge state is received. Returns true to complete the 3A scan 612 * and going to lock the 3A state, otherwise it will continue to receive the frame results 613 * until the [frameLimit] or [convergedTimeLimitNs] is reached. 614 * @param lockedCondition an optional function can be used to identify if the result frame 615 * with correct 3A lock states are received. Returns true to complete lock 3A task, 616 * otherwise it will continue to receive the frame results until the [frameLimit] or 617 * [lockedTimeLimitNs] is reached. 618 * @param frameLimit the maximum number of frames to wait before we give up waiting for this 619 * operation to complete. 620 * @param convergedTimeLimitNs the maximum time limit in ns we wait before we give up 621 * waiting for 3A convergence to complete. 622 * @param lockedTimeLimitNs the maximum time limit in ns we wait before we give up waiting 623 * for 3A locking to complete. 624 * @return [Result3A], which will contain the latest frame number at which the locks were 625 * applied or the frame number at which the method returned early because either frame 626 * limit or time limit was reached. 627 * 628 * TODO(sushilnath@): Add support for specifying the AE, AF and AWB modes as well. The 629 * update of modes require special care if the desired lock behavior is immediate. In that 630 * case we have to submit a combination of repeating and single requests so that the AF 631 * skips the initial state of the new mode's state machine and stays locks in the new mode 632 * as well. 633 */ 634 public suspend fun lock3A( 635 aeMode: AeMode? = null, 636 afMode: AfMode? = null, 637 awbMode: AwbMode? = null, 638 aeRegions: List<MeteringRectangle>? = null, 639 afRegions: List<MeteringRectangle>? = null, 640 awbRegions: List<MeteringRectangle>? = null, 641 aeLockBehavior: Lock3ABehavior? = null, 642 afLockBehavior: Lock3ABehavior? = null, 643 awbLockBehavior: Lock3ABehavior? = null, 644 afTriggerStartAeMode: AeMode? = null, 645 convergedCondition: ((FrameMetadata) -> Boolean)? = null, 646 lockedCondition: ((FrameMetadata) -> Boolean)? = null, 647 frameLimit: Int = DEFAULT_FRAME_LIMIT, 648 convergedTimeLimitNs: Long = DEFAULT_TIME_LIMIT_NS, 649 lockedTimeLimitNs: Long = DEFAULT_TIME_LIMIT_NS 650 ): Deferred<Result3A> 651 652 /** 653 * Unlocks auto-exposure, auto-focus, auto-whitebalance. Once they are unlocked they get 654 * back to their initial state or resume their auto scan depending on the current mode they 655 * are operating in. 656 * 657 * Providing 'true' for a parameter in this method will unlock that component and if 'false' 658 * is provided or the parameter is not specified then it will have no effect on the lock of 659 * that component, i.e. if it was locked earlier it will stay locked and if it was already 660 * unlocked, it will stay unlocked. 661 * 662 * @param unlockedCondition an optional function can be used to identify if the result frame 663 * with correct ae, af and awb states are received. Returns true to complete the unlock 3A 664 * task, otherwise it will continue to receive the frame results until the [frameLimit] or 665 * [timeLimitNs] is reached. 666 * @param frameLimit the maximum number of frames to wait before we give up waiting for this 667 * operation to complete. 668 * @param timeLimitNs the maximum time limit in ms we wait before we give up waiting for 669 * this operation to complete. 670 * @return [Result3A], which will contain the latest frame number at which the auto-focus, 671 * auto-exposure, auto-white balance were unlocked as per the method arguments. 672 */ 673 public suspend fun unlock3A( 674 ae: Boolean? = null, 675 af: Boolean? = null, 676 awb: Boolean? = null, 677 unlockedCondition: ((FrameMetadata) -> Boolean)? = null, 678 frameLimit: Int = DEFAULT_FRAME_LIMIT, 679 timeLimitNs: Long = DEFAULT_TIME_LIMIT_NS 680 ): Deferred<Result3A> 681 682 /** 683 * This methods does pre-capture metering sequence and locks auto-focus. Once the operation 684 * completes, we can proceed to take high-quality pictures. 685 * 686 * Note: Flash will be used during pre-capture metering and during image capture if the AE 687 * mode was set to [AeMode.ON_AUTO_FLASH] or [AeMode.ON_ALWAYS_FLASH], thus firing it for 688 * low light captures or for every capture, respectively. 689 * 690 * @param lockedCondition an optional function can be used to identify if the result frame 691 * with correct lock states for ae, af and awb is received. Returns true to complete lock 692 * 3A task, otherwise it will continue to receive the frame results until the [frameLimit] 693 * or [timeLimitNs] is reached. 694 * @param frameLimit the maximum number of frames to wait before we give up waiting for this 695 * operation to complete. 696 * @param timeLimitNs the maximum time limit in ms we wait before we give up waiting for 697 * this operation to complete. 698 * @return [Result3A], which will contain the latest frame number at which the locks were 699 * applied or the frame number at which the method returned early because either frame 700 * limit or time limit was reached. 701 */ 702 public suspend fun lock3AForCapture( 703 lockedCondition: ((FrameMetadata) -> Boolean)? = null, 704 frameLimit: Int = DEFAULT_FRAME_LIMIT, 705 timeLimitNs: Long = DEFAULT_TIME_LIMIT_NS, 706 ): Deferred<Result3A> 707 708 /** 709 * This methods does pre-capture metering sequence and locks auto-focus. Once the operation 710 * completes, we can proceed to take high-quality pictures. 711 * 712 * Note: Flash will be used during pre-capture metering and during image capture if the AE 713 * mode was set to [AeMode.ON_AUTO_FLASH] or [AeMode.ON_ALWAYS_FLASH], thus firing it for 714 * low light captures or for every capture, respectively. 715 * 716 * @param triggerAf Whether to trigger AF, enabled by default. 717 * @param waitForAwb Whether to wait for AWB to converge/lock, disabled by default. 718 * @param frameLimit the maximum number of frames to wait before we give up waiting for this 719 * operation to complete. 720 * @param timeLimitNs the maximum time limit in ms we wait before we give up waiting for 721 * this operation to complete. 722 * @return [Result3A], which will contain the latest frame number at which the locks were 723 * applied or the frame number at which the method returned early because either frame 724 * limit or time limit was reached. 725 */ 726 public suspend fun lock3AForCapture( 727 triggerAf: Boolean = true, 728 waitForAwb: Boolean = false, 729 frameLimit: Int = DEFAULT_FRAME_LIMIT, 730 timeLimitNs: Long = DEFAULT_TIME_LIMIT_NS, 731 ): Deferred<Result3A> 732 733 /** 734 * After submitting pre-capture metering sequence needed by [lock3AForCapture] method, the 735 * camera system can internally lock the auto-exposure routine for subsequent still image 736 * capture, and if not image capture request is submitted the auto-exposure may not resume 737 * it's normal scan. This method brings focus and exposure back to normal after high quality 738 * image captures using [lock3AForCapture] method. 739 * 740 * @param cancelAf Whether to trigger AF cancel, enabled by default. 741 */ 742 public suspend fun unlock3APostCapture(cancelAf: Boolean = true): Deferred<Result3A> 743 } 744 745 /** 746 * [Parameters] is a Map-like interface that stores the key-value parameter pairs from 747 * [CaptureRequest] and [Metadata] for each [CameraGraph]. Parameter are read/set directly using 748 * get/set methods in this interface. 749 * 750 * During an active [CameraGraph.Session], changes in [Parameters] may not be applied right 751 * away. Instead, the change will be applied after [CameraGraph.Session] closes. When there is 752 * no active [CameraGraph.Session], the change will be applied without having to wait for the 753 * session to close. When applying parameter changes, it will overwrite parameter values that 754 * were configured when building the request, and overwrite [Config.defaultParameters]. It will 755 * not overwrite [Config.requiredParameters]. 756 * 757 * Note that [Parameters] only store values that is a result of methods from this interface. The 758 * parameter values that were set from implicit template values, or from building a request 759 * directly will not be reflected here. 760 */ 761 public interface Parameters { 762 /** Get the value correspond to the given [CaptureRequest.Key]. */ 763 public operator fun <T> get(key: CaptureRequest.Key<T>): T? 764 765 /** Get the value correspond to the given [Metadata.Key]. */ 766 public operator fun <T> get(key: Metadata.Key<T>): T? 767 768 /** Store the [CaptureRequest] key value pair in the class. */ 769 public operator fun <T : Any> set(key: CaptureRequest.Key<T>, value: T?) 770 771 /** Store the [Metadata] key value pair in the class. */ 772 public operator fun <T : Any> set(key: Metadata.Key<T>, value: T?) 773 774 /** 775 * Store the key value pairs in the class. The key is either [CaptureRequest.Key] or 776 * [Metadata.Key]. 777 */ 778 public fun setAll(newParameters: Map<Any, Any?>) 779 780 /** Clear all [CaptureRequest] and [Metadata] parameters stored in the class. */ 781 public fun clear() 782 783 /** 784 * Remove the [CaptureRequest] key value pair associated with the given key. Returns true if 785 * a key was present and removed. 786 */ 787 public fun <T> remove(key: CaptureRequest.Key<T>): Boolean 788 789 /** 790 * Remove the [Metadata] key value pair associated with the given key. Returns true if a key 791 * was present and removed. 792 */ 793 public fun <T> remove(key: Metadata.Key<T>): Boolean 794 795 /** 796 * Remove all parameters that match the given keys. The key is either [CaptureRequest.Key] 797 * or [Metadata.Key]. 798 */ 799 public fun removeAll(keys: Set<*>): Boolean 800 } 801 } 802 803 /** 804 * GraphState represents public the public facing state of a [CameraGraph] instance. When created, a 805 * [CameraGraph] starts in [GraphStateStopped]. Calling [CameraGraph.start] puts the graph into 806 * [GraphStateStarting], and [CameraGraph.stop] puts the graph into [GraphStateStopping]. Remaining 807 * states are produced by the underlying camera as a result of these start/stop calls. 808 */ 809 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 810 public abstract class GraphState internal constructor(private val name: String) { 811 /** 812 * When the [CameraGraph] is starting. This means we're in the process of opening a (virtual) 813 * camera and creating a capture session. 814 */ 815 public object GraphStateStarting : GraphState("GRAPH_STARTING") 816 817 /** 818 * When the [CameraGraph] is started. This means a capture session has been successfully created 819 * for the [CameraGraph]. 820 */ 821 public object GraphStateStarted : GraphState("GRAPH_STARTED") 822 823 /** 824 * When the [CameraGraph] is stopping. This means we're in the process of stopping the graph. 825 */ 826 public object GraphStateStopping : GraphState("GRAPH_STOPPING") 827 828 /** 829 * When the [CameraGraph] hasn't been started, or stopped. This does not guarantee the closure 830 * of the capture session or the camera device itself. 831 */ 832 public object GraphStateStopped : GraphState("GRAPH_STOPPED") 833 834 /** 835 * When the [CameraGraph] has encountered an error. If [willAttemptRetry] is true, CameraPipe 836 * will retry opening the camera (and creating a capture session). 837 */ 838 public class GraphStateError( 839 public val cameraError: CameraError, 840 public val willAttemptRetry: Boolean 841 ) : GraphState("GRAPH_ERROR") { toStringnull842 override fun toString(): String = 843 super.toString() + "(cameraError=$cameraError, willAttemptRetry=$willAttemptRetry)" 844 } 845 846 override fun toString(): String = name 847 } 848 849 /** @see [CameraDevice.AUDIO_RESTRICTION_NONE] and other constants. */ 850 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 851 @JvmInline 852 public value class AudioRestrictionMode internal constructor(public val value: Int) { 853 public companion object { 854 public val AUDIO_RESTRICTION_NONE: AudioRestrictionMode = AudioRestrictionMode(0) 855 public val AUDIO_RESTRICTION_VIBRATION: AudioRestrictionMode = AudioRestrictionMode(1) 856 public val AUDIO_RESTRICTION_VIBRATION_SOUND: AudioRestrictionMode = AudioRestrictionMode(3) 857 } 858 } 859