feat: Implement atomically single-lock core/ library on Android (#2049)

* feat: Create base for `CameraConfiguration` diff

* Fix

* Write three configure methods

* Build?

* MOre

* Update CameraView+RecordVideo.kt

* Fix errors

* Update CameraDeviceDetails.kt

* Update CameraSession.kt

* Auto-resize Preview View

* More

* Make it work? idk

* Format

* Call `configure` under mutex, and change isActive

* fix: Make Outputs comparable

* fix: Make CodeScanner comparable

* Format

* fix: Update outputs after reconfiguring

* Update CameraPage.tsx

* fix: Close CaptureSession before
This commit is contained in:
Marc Rousavy
2023-10-24 11:19:03 +02:00
committed by GitHub
parent 23d173f6fc
commit de0d6cda5d
23 changed files with 821 additions and 889 deletions

View File

@@ -6,7 +6,7 @@ import android.util.Size
import android.view.SurfaceHolder
import kotlin.math.abs
private fun getMaximumPreviewSize(): Size {
fun getMaximumPreviewSize(): Size {
// See https://developer.android.com/reference/android/hardware/camera2/params/StreamConfigurationMap
// According to the Android Developer documentation, PREVIEW streams can have a resolution
// of up to the phone's display's resolution, with a maximum of 1920x1080.

View File

@@ -10,7 +10,6 @@ import android.os.Build
import android.util.Log
import com.mrousavy.camera.core.CameraQueues
import com.mrousavy.camera.core.CameraSessionCannotBeConfiguredError
import com.mrousavy.camera.core.outputs.CameraOutputs
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlinx.coroutines.suspendCancellableCoroutine
@@ -20,7 +19,7 @@ private var sessionId = 1000
suspend fun CameraDevice.createCaptureSession(
cameraManager: CameraManager,
outputs: CameraOutputs,
outputs: List<OutputConfiguration>,
onClosed: (session: CameraCaptureSession) -> Unit,
queue: CameraQueues.CameraQueue
): CameraCaptureSession =
@@ -42,7 +41,7 @@ suspend fun CameraDevice.createCaptureSession(
override fun onConfigureFailed(session: CameraCaptureSession) {
Log.e(TAG, "Camera $id: Failed to configure Capture Session #$sessionId!")
continuation.resumeWithException(CameraSessionCannotBeConfiguredError(id, outputs))
continuation.resumeWithException(CameraSessionCannotBeConfiguredError(id))
}
override fun onClosed(session: CameraCaptureSession) {
@@ -52,36 +51,12 @@ suspend fun CameraDevice.createCaptureSession(
}
}
val outputConfigurations = arrayListOf<OutputConfiguration>()
outputs.previewOutput?.let { output ->
outputConfigurations.add(output.toOutputConfiguration(characteristics))
}
outputs.photoOutput?.let { output ->
outputConfigurations.add(output.toOutputConfiguration(characteristics))
}
outputs.videoOutput?.let { output ->
outputConfigurations.add(output.toOutputConfiguration(characteristics))
}
outputs.codeScannerOutput?.let { output ->
outputConfigurations.add(output.toOutputConfiguration(characteristics))
}
if (outputs.enableHdr == true && Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val supportedProfiles = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES)
val hdrProfile = supportedProfiles?.bestProfile ?: supportedProfiles?.supportedProfiles?.firstOrNull()
if (hdrProfile != null) {
Log.i(TAG, "Camera $id: Using HDR Profile $hdrProfile...")
outputConfigurations.forEach { it.dynamicRangeProfile = hdrProfile }
} else {
Log.w(TAG, "Camera $id: HDR was enabled, but the device does not support any matching HDR profile!")
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
Log.i(TAG, "Using new API (>=28)")
val config = SessionConfiguration(SessionConfiguration.SESSION_REGULAR, outputConfigurations, queue.executor, callback)
val config = SessionConfiguration(SessionConfiguration.SESSION_REGULAR, outputs, queue.executor, callback)
this.createCaptureSession(config)
} else {
Log.i(TAG, "Using legacy API (<28)")
this.createCaptureSessionByOutputConfigurations(outputConfigurations, callback, queue.handler)
this.createCaptureSessionByOutputConfigurations(outputs, callback, queue.handler)
}
}