Merge "[CameraPipe] Fix updates happening in out of order" into androidx-main
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/FocusMeteringControl.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/FocusMeteringControl.kt
index 5621082..b5eb887 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/FocusMeteringControl.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/FocusMeteringControl.kt
@@ -30,6 +30,7 @@
import androidx.camera.camera2.pipe.Lock3ABehavior
import androidx.camera.camera2.pipe.Result3A
import androidx.camera.camera2.pipe.core.Log.debug
+import androidx.camera.camera2.pipe.core.Log.warn
import androidx.camera.camera2.pipe.integration.adapter.asListenableFuture
import androidx.camera.camera2.pipe.integration.adapter.propagateTo
import androidx.camera.camera2.pipe.integration.compat.ZoomCompat
@@ -291,6 +292,9 @@
) {
invokeOnCompletion { throwable ->
if (throwable != null) {
+ warn(throwable) {
+ "propagateToFocusMeteringResultDeferred: completed exceptionally!"
+ }
resultDeferred.completeExceptionally(throwable)
} else {
val result3A = getCompleted()
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraState.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraState.kt
index 0a5a70a..e5552c8 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraState.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraState.kt
@@ -32,7 +32,6 @@
import androidx.camera.camera2.pipe.RequestMetadata
import androidx.camera.camera2.pipe.RequestTemplate
import androidx.camera.camera2.pipe.StreamId
-import androidx.camera.camera2.pipe.core.Log
import androidx.camera.camera2.pipe.core.Log.debug
import androidx.camera.camera2.pipe.integration.config.UseCaseCameraScope
import androidx.camera.camera2.pipe.integration.config.UseCaseGraphConfig
@@ -189,7 +188,7 @@
}
fun capture(requests: List<Request>) {
- threads.scope.launch(start = CoroutineStart.UNDISPATCHED) {
+ threads.sequentialScope.launch(start = CoroutineStart.UNDISPATCHED) {
cameraGraph.acquireSession().use { it.submit(requests) }
}
}
@@ -259,13 +258,13 @@
// synchronously with the latest values. The startRepeating/stopRepeating call happens
// outside of the synchronized block to avoid holding a lock while updating the camera
// state.
- threads.scope.launch(start = CoroutineStart.UNDISPATCHED) {
+ threads.sequentialScope.launch(start = CoroutineStart.UNDISPATCHED) {
val result: CompletableDeferred<Unit>?
val request: Request?
try {
cameraGraph.acquireSession()
} catch (e: CancellationException) {
- Log.debug(e) { "Cannot acquire session at ${this@UseCaseCameraState}" }
+ debug(e) { "Cannot acquire session at ${this@UseCaseCameraState}" }
null
}
.let { session ->
@@ -305,8 +304,9 @@
)
}
}
- Log.debug { "Update RepeatingRequest: $request" }
+ debug { "Update RepeatingRequest: $request" }
it.startRepeating(request)
+ // TODO: Invoke update3A only if required e.g. a 3A value has changed
it.update3A(request.parameters)
}
}
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/ZoomControl.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/ZoomControl.kt
index 210ae47..aeeb4db 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/ZoomControl.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/ZoomControl.kt
@@ -25,6 +25,7 @@
import androidx.camera.camera2.pipe.integration.internal.ZoomMath.getZoomRatioFromLinearZoom
import androidx.camera.core.CameraControl
import androidx.camera.core.ZoomState
+import androidx.camera.core.impl.utils.Threads
import androidx.camera.core.impl.utils.futures.Futures
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
@@ -35,10 +36,8 @@
import javax.inject.Inject
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineStart
-import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
const val DEFAULT_ZOOM_RATIO = 1.0f
@@ -92,11 +91,12 @@
applyZoomState(defaultZoomState)
}
- private suspend fun setZoomState(value: ZoomState) {
- // TODO: camera-camera2 updates livedata with setValue if calling thread is main thread,
- // and updates with postValue otherwise. Need to consider if always using setValue
- // via main thread is alright in camera-pipe.
- withContext(Dispatchers.Main) { _zoomState.value = value }
+ private fun setZoomState(value: ZoomState) {
+ if (Threads.isMainThread()) {
+ _zoomState.value = value
+ } else {
+ _zoomState.postValue(value)
+ }
}
fun setLinearZoom(linearZoom: Float): ListenableFuture<Void> {
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/graph/Controller3A.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/graph/Controller3A.kt
index a124a2a..90ebc54 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/graph/Controller3A.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/graph/Controller3A.kt
@@ -215,6 +215,7 @@
val result = listener.result
synchronized(this) {
+ debug { "Controller3A#update3A: cancelling previous request $lastUpdate3AResult" }
lastUpdate3AResult?.cancel("A newer call for 3A state update initiated.")
lastUpdate3AResult = result
}