feat: New Core/ library (#1975)

Moves everything Camera related into `core/` / `Core/` so that it is better encapsulated from React Native.

Benefits:

1. Code is much better organized. Should be easier for collaborators now, and cleaner codebase for me.
2. Locking is fully atomically as you can now only configure the session through a lock/Mutex which is batch-overridable
    * On iOS, this makes Camera startup time **MUCH** faster, I measured speedups from **1.5 seconds** to only **240 milliseconds** since we only lock/commit once! 🚀 
    * On Android, this fixes a few out-of-sync/concurrency issues like "Capture Request contains unconfigured Input/Output Surface!" since it is now a single lock-operation! 💪 
3. It is easier to integrate VisionCamera outside of React Native (e.g. Native iOS Apps, NativeScript, Flutter, etc)

With this PR, VisionCamera V3 is up to **7x** faster than V2
This commit is contained in:
Marc Rousavy
2023-10-13 18:33:20 +02:00
committed by GitHub
parent 54871022f4
commit cd0b413706
72 changed files with 2326 additions and 1521 deletions

View File

@@ -6,6 +6,9 @@ import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.WritableMap
import com.facebook.react.uimanager.events.RCTEventEmitter
import com.google.mlkit.vision.barcode.common.Barcode
import com.mrousavy.camera.core.CameraError
import com.mrousavy.camera.core.UnknownCameraError
import com.mrousavy.camera.core.code
import com.mrousavy.camera.parsers.CodeType
fun CameraView.invokeOnInitialized() {

View File

@@ -5,7 +5,10 @@ import android.annotation.SuppressLint
import android.content.pm.PackageManager
import androidx.core.content.ContextCompat
import com.facebook.react.bridge.*
import com.mrousavy.camera.core.MicrophonePermissionError
import com.mrousavy.camera.core.RecorderError
import com.mrousavy.camera.core.RecordingSession
import com.mrousavy.camera.core.code
import com.mrousavy.camera.parsers.Torch
import com.mrousavy.camera.parsers.VideoCodec
import com.mrousavy.camera.parsers.VideoFileType

View File

@@ -13,7 +13,10 @@ import android.view.Surface
import android.widget.FrameLayout
import androidx.core.content.ContextCompat
import com.facebook.react.bridge.ReadableMap
import com.mrousavy.camera.core.CameraPermissionError
import com.mrousavy.camera.core.CameraQueues
import com.mrousavy.camera.core.CameraSession
import com.mrousavy.camera.core.NoCameraDeviceError
import com.mrousavy.camera.core.PreviewView
import com.mrousavy.camera.core.outputs.CameraOutputs
import com.mrousavy.camera.extensions.bigger

View File

@@ -9,6 +9,8 @@ import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.modules.core.PermissionAwareActivity
import com.facebook.react.modules.core.PermissionListener
import com.facebook.react.uimanager.UIManagerHelper
import com.mrousavy.camera.core.CameraError
import com.mrousavy.camera.core.ViewNotFoundError
import com.mrousavy.camera.frameprocessor.VisionCameraInstaller
import com.mrousavy.camera.frameprocessor.VisionCameraProxy
import com.mrousavy.camera.parsers.*

View File

@@ -1,4 +1,4 @@
package com.mrousavy.camera
package com.mrousavy.camera.core
import com.mrousavy.camera.core.outputs.CameraOutputs
import com.mrousavy.camera.parsers.CameraDeviceError

View File

@@ -1,4 +1,4 @@
package com.mrousavy.camera
package com.mrousavy.camera.core
import android.os.Handler
import android.os.HandlerThread

View File

@@ -16,15 +16,7 @@ import android.os.Build
import android.util.Log
import android.util.Range
import android.util.Size
import com.mrousavy.camera.CameraNotReadyError
import com.mrousavy.camera.CameraQueues
import com.mrousavy.camera.CameraView
import com.mrousavy.camera.CaptureAbortedError
import com.mrousavy.camera.NoRecordingInProgressError
import com.mrousavy.camera.PhotoNotEnabledError
import com.mrousavy.camera.RecorderError
import com.mrousavy.camera.RecordingInProgressError
import com.mrousavy.camera.VideoNotEnabledError
import com.mrousavy.camera.core.outputs.CameraOutputs
import com.mrousavy.camera.extensions.capture
import com.mrousavy.camera.extensions.createCaptureSession

View File

@@ -7,7 +7,6 @@ import com.google.mlkit.vision.barcode.BarcodeScanner
import com.google.mlkit.vision.barcode.BarcodeScannerOptions
import com.google.mlkit.vision.barcode.BarcodeScanning
import com.google.mlkit.vision.common.InputImage
import com.mrousavy.camera.CameraQueues
import com.mrousavy.camera.core.outputs.CameraOutputs
import com.mrousavy.camera.parsers.Orientation
import java.io.Closeable

View File

@@ -7,7 +7,6 @@ import android.os.Build
import android.util.Log
import android.util.Size
import android.view.Surface
import com.mrousavy.camera.RecorderError
import com.mrousavy.camera.parsers.Orientation
import com.mrousavy.camera.parsers.VideoCodec
import com.mrousavy.camera.parsers.VideoFileType

View File

@@ -9,8 +9,6 @@ import android.os.Build
import android.util.Log
import android.view.Surface
import com.facebook.jni.HybridData
import com.mrousavy.camera.CameraQueues
import com.mrousavy.camera.FrameProcessorsUnavailableError
import com.mrousavy.camera.frameprocessor.Frame
import com.mrousavy.camera.frameprocessor.FrameProcessor
import com.mrousavy.camera.parsers.Orientation

View File

@@ -9,7 +9,7 @@ import android.util.Log
import android.util.Size
import android.view.Surface
import com.google.mlkit.vision.barcode.common.Barcode
import com.mrousavy.camera.CameraQueues
import com.mrousavy.camera.core.CameraQueues
import com.mrousavy.camera.core.CodeScannerPipeline
import com.mrousavy.camera.core.VideoPipeline
import com.mrousavy.camera.extensions.bigger

View File

@@ -5,9 +5,9 @@ import android.hardware.camera2.CaptureFailure
import android.hardware.camera2.CaptureRequest
import android.hardware.camera2.TotalCaptureResult
import android.media.MediaActionSound
import com.mrousavy.camera.CameraQueues
import com.mrousavy.camera.CaptureAbortedError
import com.mrousavy.camera.UnknownCaptureError
import com.mrousavy.camera.core.CameraQueues
import com.mrousavy.camera.core.CaptureAbortedError
import com.mrousavy.camera.core.UnknownCaptureError
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine

View File

@@ -8,8 +8,8 @@ import android.hardware.camera2.params.OutputConfiguration
import android.hardware.camera2.params.SessionConfiguration
import android.os.Build
import android.util.Log
import com.mrousavy.camera.CameraQueues
import com.mrousavy.camera.CameraSessionCannotBeConfiguredError
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

View File

@@ -5,9 +5,9 @@ import android.hardware.camera2.CameraDevice
import android.hardware.camera2.CameraManager
import android.os.Build
import android.util.Log
import com.mrousavy.camera.CameraCannotBeOpenedError
import com.mrousavy.camera.CameraDisconnectedError
import com.mrousavy.camera.CameraQueues
import com.mrousavy.camera.core.CameraCannotBeOpenedError
import com.mrousavy.camera.core.CameraDisconnectedError
import com.mrousavy.camera.core.CameraQueues
import com.mrousavy.camera.parsers.CameraDeviceError
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException

View File

@@ -4,12 +4,10 @@ import android.hardware.HardwareBuffer;
import android.media.Image;
import android.os.Build;
import com.facebook.proguard.annotations.DoNotStrip;
import com.mrousavy.camera.HardwareBuffersNotAvailableError;
import com.mrousavy.camera.core.HardwareBuffersNotAvailableError;
import com.mrousavy.camera.parsers.PixelFormat;
import com.mrousavy.camera.parsers.Orientation;
import java.nio.ByteBuffer;
public class Frame {
private final Image image;
private final boolean isMirrored;

View File

@@ -10,7 +10,7 @@ import com.facebook.react.bridge.UiThreadUtil
import com.facebook.react.turbomodule.core.CallInvokerHolderImpl
import com.facebook.react.uimanager.UIManagerHelper
import com.mrousavy.camera.CameraView
import com.mrousavy.camera.ViewNotFoundError
import com.mrousavy.camera.core.ViewNotFoundError
import java.lang.ref.WeakReference
@Suppress("KotlinJniMissingFunction") // we use fbjni.

View File

@@ -2,9 +2,7 @@ package com.mrousavy.camera.frameprocessor;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
import com.mrousavy.camera.CameraQueues;
import java.util.concurrent.ExecutorService;
import com.mrousavy.camera.core.CameraQueues;
@SuppressWarnings("JavaJniMissingFunction") // using fbjni here
public class VisionCameraScheduler {

View File

@@ -1,7 +1,7 @@
package com.mrousavy.camera.parsers
import com.facebook.react.bridge.ReadableMap
import com.mrousavy.camera.InvalidTypeScriptUnionError
import com.mrousavy.camera.core.InvalidTypeScriptUnionError
class CodeScanner(map: ReadableMap) {
val codeTypes: List<CodeType>

View File

@@ -1,8 +1,8 @@
package com.mrousavy.camera.parsers
import com.google.mlkit.vision.barcode.common.Barcode
import com.mrousavy.camera.CodeTypeNotSupportedError
import com.mrousavy.camera.InvalidTypeScriptUnionError
import com.mrousavy.camera.core.CodeTypeNotSupportedError
import com.mrousavy.camera.core.InvalidTypeScriptUnionError
enum class CodeType(override val unionValue: String) : JSUnionValue {
CODE_128("code-128"),

View File

@@ -1,6 +1,6 @@
package com.mrousavy.camera.parsers
import com.mrousavy.camera.InvalidTypeScriptUnionError
import com.mrousavy.camera.core.InvalidTypeScriptUnionError
enum class Flash(override val unionValue: String) : JSUnionValue {
OFF("off"),

View File

@@ -1,7 +1,7 @@
package com.mrousavy.camera.parsers
import android.graphics.ImageFormat
import com.mrousavy.camera.PixelFormatNotSupportedError
import com.mrousavy.camera.core.PixelFormatNotSupportedError
enum class PixelFormat(override val unionValue: String) : JSUnionValue {
YUV("yuv"),

View File

@@ -1,6 +1,6 @@
package com.mrousavy.camera.parsers
import com.mrousavy.camera.InvalidTypeScriptUnionError
import com.mrousavy.camera.core.InvalidTypeScriptUnionError
enum class VideoFileType(override val unionValue: String) : JSUnionValue {
MOV("mov"),

View File

@@ -1,8 +1,8 @@
package com.mrousavy.camera.utils
import com.facebook.react.bridge.Promise
import com.mrousavy.camera.CameraError
import com.mrousavy.camera.UnknownCameraError
import com.mrousavy.camera.core.CameraError
import com.mrousavy.camera.core.UnknownCameraError
inline fun withPromise(promise: Promise, closure: () -> Any?) {
try {