diff --git a/android/build.gradle b/android/build.gradle index 4f12efa..4b58789 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -234,11 +234,11 @@ dependencies { implementation "org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.5.0" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0" - implementation "androidx.camera:camera-core:1.1.0-alpha05" - implementation "androidx.camera:camera-camera2:1.1.0-alpha05" - implementation "androidx.camera:camera-lifecycle:1.1.0-alpha05" - implementation "androidx.camera:camera-extensions:1.0.0-alpha25" - implementation "androidx.camera:camera-view:1.0.0-alpha25" + implementation "androidx.camera:camera-core:1.1.0-alpha06" + implementation "androidx.camera:camera-camera2:1.1.0-alpha06" + implementation "androidx.camera:camera-lifecycle:1.1.0-alpha06" + implementation "androidx.camera:camera-extensions:1.0.0-alpha26" + implementation "androidx.camera:camera-view:1.0.0-alpha26" implementation "androidx.exifinterface:exifinterface:1.3.2" } diff --git a/android/src/main/cpp/JImageProxy.h b/android/src/main/cpp/JImageProxy.h index 960c7a2..137165e 100644 --- a/android/src/main/cpp/JImageProxy.h +++ b/android/src/main/cpp/JImageProxy.h @@ -19,7 +19,6 @@ struct JImageProxy : public facebook::jni::JavaClass { int getPlaneCount(); int getBytesPerRow(); void close(); - }; } // namespace vision diff --git a/android/src/main/cpp/JImageProxyHostObject.h b/android/src/main/cpp/JImageProxyHostObject.h index f6fa0fb..db89fa8 100644 --- a/android/src/main/cpp/JImageProxyHostObject.h +++ b/android/src/main/cpp/JImageProxyHostObject.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "JImageProxy.h" @@ -32,7 +33,7 @@ class JSI_EXPORT JImageProxyHostObject : public jsi::HostObject { private: static auto constexpr TAG = "VisionCamera"; - void assertIsFrameStrong(jsi::Runtime& runtime, const std::string& accessedPropName); + void assertIsFrameStrong(jsi::Runtime& runtime, const std::string& accessedPropName); // NOLINT(runtime/references) }; } // namespace vision diff --git a/android/src/main/java/com/mrousavy/camera/CameraView.kt b/android/src/main/java/com/mrousavy/camera/CameraView.kt index 3892db7..1a1404f 100644 --- a/android/src/main/java/com/mrousavy/camera/CameraView.kt +++ b/android/src/main/java/com/mrousavy/camera/CameraView.kt @@ -13,10 +13,7 @@ import android.widget.FrameLayout import androidx.camera.camera2.interop.Camera2Interop import androidx.camera.core.* import androidx.camera.core.impl.* -import androidx.camera.extensions.HdrImageCaptureExtender -import androidx.camera.extensions.HdrPreviewExtender -import androidx.camera.extensions.NightImageCaptureExtender -import androidx.camera.extensions.NightPreviewExtender +import androidx.camera.extensions.* import androidx.camera.lifecycle.ProcessCameraProvider import androidx.camera.view.PreviewView import androidx.core.content.ContextCompat @@ -102,6 +99,7 @@ class CameraView(context: Context) : FrameLayout(context), LifecycleOwner { internal var imageCapture: ImageCapture? = null internal var videoCapture: VideoCapture? = null internal var imageAnalysis: ImageAnalysis? = null + private var extensionsManager: ExtensionsManager? = null private val scaleGestureListener: ScaleGestureDetector.SimpleOnScaleGestureListener private val scaleGestureDetector: ScaleGestureDetector @@ -303,7 +301,21 @@ class CameraView(context: Context) : FrameLayout(context), LifecycleOwner { // Used to bind the lifecycle of cameras to the lifecycle owner val cameraProvider = ProcessCameraProvider.getInstance(reactContext).await() - val cameraSelector = CameraSelector.Builder().byID(cameraId!!).build() + var cameraSelector = CameraSelector.Builder().byID(cameraId!!).build() + + val tryEnableExtension: (suspend (extension: Int) -> Unit) = lambda@ { extension -> + if (extensionsManager == null) { + Log.i(TAG, "Initializing ExtensionsManager...") + extensionsManager = ExtensionsManager.getInstance(context).await() + } + if (extensionsManager!!.isExtensionAvailable(cameraProvider, cameraSelector, extension)) { + Log.i(TAG, "Enabling extension $extension...") + cameraSelector = extensionsManager!!.getExtensionEnabledCameraSelector(cameraProvider, cameraSelector, extension) + } else { + Log.e(TAG, "Extension $extension is not available for the given Camera!") + throw HdrNotContainedInFormatError() + } + } val rotation = previewView.display.rotation @@ -349,38 +361,11 @@ class CameraView(context: Context) : FrameLayout(context), LifecycleOwner { throw FpsNotContainedInFormatError(fps) } } - hdr?.let { hdr -> - // Enable HDR scene mode if set - if (hdr) { - val imageExtension = HdrImageCaptureExtender.create(imageCaptureBuilder) - val previewExtension = HdrPreviewExtender.create(previewBuilder) - val isExtensionAvailable = imageExtension.isExtensionAvailable(cameraSelector) && - previewExtension.isExtensionAvailable(cameraSelector) - if (isExtensionAvailable) { - Log.i(TAG, "Enabling native HDR extension...") - imageExtension.enableExtension(cameraSelector) - previewExtension.enableExtension(cameraSelector) - } else { - Log.e(TAG, "Native HDR vendor extension not available!") - throw HdrNotContainedInFormatError() - } - } + if (hdr == true) { + tryEnableExtension(ExtensionMode.HDR) } - lowLightBoost?.let { lowLightBoost -> - if (lowLightBoost) { - val imageExtension = NightImageCaptureExtender.create(imageCaptureBuilder) - val previewExtension = NightPreviewExtender.create(previewBuilder) - val isExtensionAvailable = imageExtension.isExtensionAvailable(cameraSelector) && - previewExtension.isExtensionAvailable(cameraSelector) - if (isExtensionAvailable) { - Log.i(TAG, "Enabling native night-mode extension...") - imageExtension.enableExtension(cameraSelector) - previewExtension.enableExtension(cameraSelector) - } else { - Log.e(TAG, "Native night-mode vendor extension not available!") - throw LowLightBoostNotContainedInFormatError() - } - } + if (lowLightBoost == true) { + tryEnableExtension(ExtensionMode.NIGHT) } } diff --git a/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt b/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt index d5e9e65..417dcf5 100644 --- a/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt +++ b/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt @@ -8,10 +8,8 @@ import android.hardware.camera2.CameraManager import android.os.Build import android.util.Log import androidx.camera.core.CameraSelector -import androidx.camera.core.ImageCapture +import androidx.camera.extensions.ExtensionMode import androidx.camera.extensions.ExtensionsManager -import androidx.camera.extensions.HdrImageCaptureExtender -import androidx.camera.extensions.NightImageCaptureExtender import androidx.camera.lifecycle.ProcessCameraProvider import androidx.core.content.ContextCompat import com.facebook.react.bridge.* @@ -127,8 +125,8 @@ class CameraViewModule(reactContext: ReactApplicationContext) : ReactContextBase val startTime = System.currentTimeMillis() GlobalScope.launch(Dispatchers.Main) { withPromise(promise) { - // I need to init those because the HDR/Night Mode Extension expects them to be initialized - ExtensionsManager.init(reactApplicationContext).await() + val extensionsManager = ExtensionsManager.getInstance(reactApplicationContext).await() + val cameraProvider = ProcessCameraProvider.getInstance(reactApplicationContext).await() ProcessCameraProvider.getInstance(reactApplicationContext).await() val manager = reactApplicationContext.getSystemService(Context.CAMERA_SERVICE) as? CameraManager @@ -138,8 +136,6 @@ class CameraViewModule(reactContext: ReactApplicationContext) : ReactContextBase manager.cameraIdList.forEach loop@{ id -> val cameraSelector = CameraSelector.Builder().byID(id).build() - // TODO: ImageCapture.Builder - I'm not setting the target resolution, does that matter? - val imageCaptureBuilder = ImageCapture.Builder() val characteristics = manager.getCameraCharacteristics(id) val hardwareLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)!! @@ -166,10 +162,8 @@ class CameraViewModule(reactContext: ReactApplicationContext) : ReactContextBase else null val fpsRanges = characteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES)!! - val hdrExtension = HdrImageCaptureExtender.create(imageCaptureBuilder) - val supportsHdr = hdrExtension.isExtensionAvailable(cameraSelector) - val nightExtension = NightImageCaptureExtender.create(imageCaptureBuilder) - val supportsLowLightBoost = nightExtension.isExtensionAvailable(cameraSelector) + val supportsHdr = extensionsManager.isExtensionAvailable(cameraProvider, cameraSelector, ExtensionMode.HDR) + val supportsLowLightBoost = extensionsManager.isExtensionAvailable(cameraProvider, cameraSelector, ExtensionMode.NIGHT) // see https://developer.android.com/reference/android/hardware/camera2/CameraDevice#regular-capture val supportsParallelVideoProcessing = hardwareLevel != CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY && hardwareLevel != CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED