fix: Fix blackscreen issues and lifecycle when closing Camera (#2339)

* fix: Fix Blackscreen by deterministically destroying session if `isActive=false`

* Re-open Camera if session died

* Simplify Camera

* Disconnect is optional, block when resetting state

* fix: Log in `configure { ... }`

* fix: Make concurrent configure safe

* fix: Don't resize preview

* fix: Use current `CameraConfiguration`

* Don't start if no outputs are available

* Only mount with preview outputs

* Update CameraSession.kt

* Update PreviewView.kt

* Better logging

* Update CameraSession.kt

* Extract

* fix: Rebuild entire session if `isActive` changed

* isActive safe

* Start session at 1

* Create ActiveCameraDevice.kt

* interrupts

* chore: Freeze `frame` in `useFrameProcessor`

* Revert "chore: Freeze `frame` in `useFrameProcessor`"

This reverts commit dff93d506e29a791d8dea8842b880ab5c892211e.

* chore: Better logging

* fix: Move HDR to `video`/`photo` config

* fix: Fix hdr usage

* fix: Ignore any updates after destroying Camera

* fix: Fix video HDR

* chore: Format code

* fix: Check Camera permission

* Remove unneeded error

* Update CameraSession.kt

* Update CameraPage.tsx

* Delete OutputConfiguration.toDebugString.kt

* Update CameraSession.kt
This commit is contained in:
Marc Rousavy
2024-01-08 11:41:57 +01:00
committed by GitHub
parent 2cd22ad236
commit 0d21bc3a57
16 changed files with 297 additions and 239 deletions

View File

@@ -47,14 +47,6 @@ class CameraView(context: Context) :
// react properties
// props that require reconfiguring
var cameraId: String? = null
set(value) {
if (value != null) {
// TODO: Move this into CameraSession
val f = if (format != null) CameraDeviceFormat.fromJSValue(format!!) else null
previewView.resizeToInputCamera(value, cameraManager, f)
}
field = value
}
var enableDepthData = false
var enableHighQualityPhotos: Boolean? = null
var enablePortraitEffectsMatteDelivery = false
@@ -101,6 +93,7 @@ class CameraView(context: Context) :
// session
internal val cameraSession: CameraSession
private val previewView: PreviewView
private var currentConfigureCall: Long = System.currentTimeMillis()
internal var frameProcessor: FrameProcessor? = null
set(value) {
@@ -138,15 +131,24 @@ class CameraView(context: Context) :
fun update() {
Log.i(TAG, "Updating CameraSession...")
val now = System.currentTimeMillis()
currentConfigureCall = now
launch {
cameraSession.configure { config ->
if (currentConfigureCall != now) {
// configure waits for a lock, and if a new call to update() happens in the meantime we can drop this one.
// this works similar to how React implemented concurrent rendering, the newer call to update() has higher priority.
Log.i(TAG, "A new configure { ... } call arrived, aborting this one...")
return@configure
}
// Input Camera Device
config.cameraId = cameraId
// Photo
if (photo == true) {
config.photo = CameraConfiguration.Output.Enabled.create(CameraConfiguration.Photo(Unit))
config.photo = CameraConfiguration.Output.Enabled.create(CameraConfiguration.Photo(photoHdr))
} else {
config.photo = CameraConfiguration.Output.Disabled.create()
}
@@ -155,6 +157,7 @@ class CameraView(context: Context) :
if (video == true || enableFrameProcessor) {
config.video = CameraConfiguration.Output.Enabled.create(
CameraConfiguration.Video(
videoHdr,
pixelFormat,
enableFrameProcessor
)
@@ -183,10 +186,6 @@ class CameraView(context: Context) :
// Orientation
config.orientation = orientation
// HDR
config.videoHdr = videoHdr
config.photoHdr = photoHdr
// Format
val format = format
if (format != null) {