From bafeb578daf0e728b752be77147fa591a1ad5543 Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Tue, 30 Jan 2024 10:41:39 +0100 Subject: [PATCH 1/6] fix: Expose auto-focus system for Android --- .../mrousavy/camera/core/CameraDeviceDetails.kt | 15 ++++++++++++++- .../com/mrousavy/camera/types/AutoFocusSystem.kt | 1 + 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/package/android/src/main/java/com/mrousavy/camera/core/CameraDeviceDetails.kt b/package/android/src/main/java/com/mrousavy/camera/core/CameraDeviceDetails.kt index 82a9711dae..f363227322 100644 --- a/package/android/src/main/java/com/mrousavy/camera/core/CameraDeviceDetails.kt +++ b/package/android/src/main/java/com/mrousavy/camera/core/CameraDeviceDetails.kt @@ -76,6 +76,7 @@ class CameraDeviceDetails(val cameraManager: CameraManager, val cameraId: String characteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION) ?: IntArray(0) val supportsPhotoHdr = extensions.contains(3) // TODO: CameraExtensionCharacteristics.EXTENSION_HDR val supportsVideoHdr = getHasVideoHdr() + val autoFocusSystem = getAutoFocusSystem() val videoFormat = ImageFormat.YUV_420_888 @@ -132,6 +133,18 @@ class CameraDeviceDetails(val cameraManager: CameraManager, val cameraId: String return deviceTypes } + private fun getAutoFocusSystem(): AutoFocusSystem { + val supportedAFModes = characteristics.get(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES) + val supportsAF = supportedAFModes?.contains(CameraCharacteristics.CONTROL_AF_MODE_AUTO) == true + if (!supportsAF) return AutoFocusSystem.NONE + + val focusCalibrationSystem = characteristics.get(CameraCharacteristics.LENS_INFO_FOCUS_DISTANCE_CALIBRATION) + return when (focusCalibrationSystem) { + CameraCharacteristics.LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED -> AutoFocusSystem.PHASE_DETECTION + else -> AutoFocusSystem.CONTRAST_DETECTION + } + } + private fun getFieldOfView(focalLength: Float): Double { val sensorDiagonal = sqrt((sensorSize.width * sensorSize.width + sensorSize.height * sensorSize.height).toDouble()) val fovRadians = 2.0 * atan2(sensorDiagonal, (2.0 * focalLength)) @@ -190,7 +203,7 @@ class CameraDeviceDetails(val cameraManager: CameraManager, val cameraId: String map.putBoolean("supportsVideoHdr", supportsVideoHdr) map.putBoolean("supportsPhotoHdr", supportsPhotoHdr) map.putBoolean("supportsDepthCapture", supportsDepthCapture) - map.putString("autoFocusSystem", AutoFocusSystem.CONTRAST_DETECTION.unionValue) + map.putString("autoFocusSystem", autoFocusSystem.unionValue) map.putArray("videoStabilizationModes", createStabilizationModes()) map.putArray("pixelFormats", createPixelFormats()) return map diff --git a/package/android/src/main/java/com/mrousavy/camera/types/AutoFocusSystem.kt b/package/android/src/main/java/com/mrousavy/camera/types/AutoFocusSystem.kt index ef7efe6cfa..4da1053c2e 100644 --- a/package/android/src/main/java/com/mrousavy/camera/types/AutoFocusSystem.kt +++ b/package/android/src/main/java/com/mrousavy/camera/types/AutoFocusSystem.kt @@ -1,6 +1,7 @@ package com.mrousavy.camera.types enum class AutoFocusSystem(override val unionValue: String) : JSUnionValue { + PHASE_DETECTION("phase-detection"), CONTRAST_DETECTION("contrast-detection"), NONE("none"); From cb2e07e77795156e060d4e95707349144f9e64b2 Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Tue, 30 Jan 2024 10:46:03 +0100 Subject: [PATCH 2/6] Add `autoFocusSystem` to filter --- package/src/devices/getCameraFormat.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/package/src/devices/getCameraFormat.ts b/package/src/devices/getCameraFormat.ts index 9f537f80bc..8f88d4ee1d 100644 --- a/package/src/devices/getCameraFormat.ts +++ b/package/src/devices/getCameraFormat.ts @@ -1,4 +1,4 @@ -import type { CameraDevice, CameraDeviceFormat, VideoStabilizationMode } from '../CameraDevice' +import type { AutoFocusSystem, CameraDevice, CameraDeviceFormat, VideoStabilizationMode } from '../CameraDevice' import { CameraRuntimeError } from '../CameraError' import { PixelFormat } from '../PixelFormat' @@ -74,6 +74,12 @@ export interface FormatFilter { * Lower ISO values tend to capture photos quicker. */ iso?: number | 'max' | 'min' + /** + * The target auto-focus system. + * While `phase-detection` is generally the best system available, + * you might want to choose a different auto-focus system. + */ + autoFocusSystem?: AutoFocusSystem } type FilterWithPriority = { @@ -234,6 +240,12 @@ export function getCameraFormat(device: CameraDevice, filters: FormatFilter[]): if (format.supportsVideoHdr === filter.videoHdr.target) rightPoints++ } + // phase-detection is generally the best AF system + if (filter.autoFocusSystem != null) { + if (bestFormat.autoFocusSystem === filter.autoFocusSystem) leftPoints++ + if (format.autoFocusSystem === filter.autoFocusSystem) rightPoints++ + } + if (rightPoints > leftPoints) bestFormat = format } From 90882576a2880dfa472225418fe7b7e7b4bd1b49 Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Tue, 30 Jan 2024 10:46:42 +0100 Subject: [PATCH 3/6] Update CameraDeviceDetails.kt --- .../main/java/com/mrousavy/camera/core/CameraDeviceDetails.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/android/src/main/java/com/mrousavy/camera/core/CameraDeviceDetails.kt b/package/android/src/main/java/com/mrousavy/camera/core/CameraDeviceDetails.kt index f363227322..2f86c7275c 100644 --- a/package/android/src/main/java/com/mrousavy/camera/core/CameraDeviceDetails.kt +++ b/package/android/src/main/java/com/mrousavy/camera/core/CameraDeviceDetails.kt @@ -76,7 +76,7 @@ class CameraDeviceDetails(val cameraManager: CameraManager, val cameraId: String characteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION) ?: IntArray(0) val supportsPhotoHdr = extensions.contains(3) // TODO: CameraExtensionCharacteristics.EXTENSION_HDR val supportsVideoHdr = getHasVideoHdr() - val autoFocusSystem = getAutoFocusSystem() + val autoFocusSystem = getAutoFocusSystemMode() val videoFormat = ImageFormat.YUV_420_888 @@ -133,7 +133,7 @@ class CameraDeviceDetails(val cameraManager: CameraManager, val cameraId: String return deviceTypes } - private fun getAutoFocusSystem(): AutoFocusSystem { + private fun getAutoFocusSystemMode(): AutoFocusSystem { val supportedAFModes = characteristics.get(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES) val supportsAF = supportedAFModes?.contains(CameraCharacteristics.CONTROL_AF_MODE_AUTO) == true if (!supportsAF) return AutoFocusSystem.NONE From d34eef1f8a13dcca4a9d888973fdc8249145bde2 Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Tue, 30 Jan 2024 10:48:08 +0100 Subject: [PATCH 4/6] Update getCameraFormat.ts --- package/src/devices/getCameraFormat.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/src/devices/getCameraFormat.ts b/package/src/devices/getCameraFormat.ts index 8f88d4ee1d..e0f5b33199 100644 --- a/package/src/devices/getCameraFormat.ts +++ b/package/src/devices/getCameraFormat.ts @@ -242,8 +242,8 @@ export function getCameraFormat(device: CameraDevice, filters: FormatFilter[]): // phase-detection is generally the best AF system if (filter.autoFocusSystem != null) { - if (bestFormat.autoFocusSystem === filter.autoFocusSystem) leftPoints++ - if (format.autoFocusSystem === filter.autoFocusSystem) rightPoints++ + if (bestFormat.autoFocusSystem === filter.autoFocusSystem.target) leftPoints++ + if (format.autoFocusSystem === filter.autoFocusSystem.target) rightPoints++ } if (rightPoints > leftPoints) bestFormat = format From 38a4e7c4a1866e0126f2eecadbc68f521e903919 Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Tue, 30 Jan 2024 10:49:10 +0100 Subject: [PATCH 5/6] fix: Fix `priority` being ignored in some Format filters --- package/src/devices/getCameraFormat.ts | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/package/src/devices/getCameraFormat.ts b/package/src/devices/getCameraFormat.ts index e0f5b33199..5248015768 100644 --- a/package/src/devices/getCameraFormat.ts +++ b/package/src/devices/getCameraFormat.ts @@ -218,32 +218,34 @@ export function getCameraFormat(device: CameraDevice, filters: FormatFilter[]): // Find video stabilization mode if (filter.videoStabilizationMode != null) { - if (bestFormat.videoStabilizationModes.includes(filter.videoStabilizationMode.target)) leftPoints++ - if (format.videoStabilizationModes.includes(filter.videoStabilizationMode.target)) rightPoints++ + if (bestFormat.videoStabilizationModes.includes(filter.videoStabilizationMode.target)) + leftPoints += filter.videoStabilizationMode.priority + if (format.videoStabilizationModes.includes(filter.videoStabilizationMode.target)) + rightPoints += filter.videoStabilizationMode.priority } // Find pixel format if (filter.pixelFormat != null) { - if (bestFormat.pixelFormats.includes(filter.pixelFormat.target)) leftPoints++ - if (format.pixelFormats.includes(filter.pixelFormat.target)) rightPoints++ + if (bestFormat.pixelFormats.includes(filter.pixelFormat.target)) leftPoints += filter.pixelFormat.priority + if (format.pixelFormats.includes(filter.pixelFormat.target)) rightPoints += filter.pixelFormat.priority } // Find Photo HDR formats if (filter.photoHdr != null) { - if (bestFormat.supportsPhotoHdr === filter.photoHdr.target) leftPoints++ - if (format.supportsPhotoHdr === filter.photoHdr.target) rightPoints++ + if (bestFormat.supportsPhotoHdr === filter.photoHdr.target) leftPoints += filter.photoHdr.priority + if (format.supportsPhotoHdr === filter.photoHdr.target) rightPoints += filter.photoHdr.priority } // Find Video HDR formats if (filter.videoHdr != null) { - if (bestFormat.supportsVideoHdr === filter.videoHdr.target) leftPoints++ - if (format.supportsVideoHdr === filter.videoHdr.target) rightPoints++ + if (bestFormat.supportsVideoHdr === filter.videoHdr.target) leftPoints += filter.videoHdr.priority + if (format.supportsVideoHdr === filter.videoHdr.target) rightPoints += filter.videoHdr.priority } // phase-detection is generally the best AF system if (filter.autoFocusSystem != null) { - if (bestFormat.autoFocusSystem === filter.autoFocusSystem.target) leftPoints++ - if (format.autoFocusSystem === filter.autoFocusSystem.target) rightPoints++ + if (bestFormat.autoFocusSystem === filter.autoFocusSystem.target) leftPoints += filter.autoFocusSystem.priority + if (format.autoFocusSystem === filter.autoFocusSystem.target) rightPoints += filter.autoFocusSystem.priority } if (rightPoints > leftPoints) bestFormat = format From 39a2b6d2c99a3ee83352ba149e3527605abd9f4e Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Tue, 30 Jan 2024 10:51:34 +0100 Subject: [PATCH 6/6] Update getCameraFormat.ts --- package/src/devices/getCameraFormat.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/package/src/devices/getCameraFormat.ts b/package/src/devices/getCameraFormat.ts index 8a6d6990f8..f4a86987cd 100644 --- a/package/src/devices/getCameraFormat.ts +++ b/package/src/devices/getCameraFormat.ts @@ -242,18 +242,12 @@ export function getCameraFormat(device: CameraDevice, filters: FormatFilter[]): if (format.supportsVideoHdr === filter.videoHdr.target) rightPoints += filter.videoHdr.priority } - // phase-detection is generally the best AF system + // Find matching AF system if (filter.autoFocusSystem != null) { if (bestFormat.autoFocusSystem === filter.autoFocusSystem.target) leftPoints += filter.autoFocusSystem.priority if (format.autoFocusSystem === filter.autoFocusSystem.target) rightPoints += filter.autoFocusSystem.priority } - // phase-detection is generally the best AF system - if (filter.autoFocusSystem != null) { - if (bestFormat.autoFocusSystem === filter.autoFocusSystem.target) leftPoints++ - if (format.autoFocusSystem === filter.autoFocusSystem.target) rightPoints++ - } - if (rightPoints > leftPoints) bestFormat = format }