From b5eb01bac8d4722b29b59768b815d48dd536d2e6 Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Tue, 30 Jan 2024 10:49:28 +0100 Subject: [PATCH] fix: Expose auto-focus system for Android (#2455) * fix: Expose auto-focus system for Android * Add `autoFocusSystem` to filter * Update CameraDeviceDetails.kt * Update getCameraFormat.ts --- .../mrousavy/camera/core/CameraDeviceDetails.kt | 15 ++++++++++++++- .../com/mrousavy/camera/types/AutoFocusSystem.kt | 1 + package/src/devices/getCameraFormat.ts | 14 +++++++++++++- 3 files changed, 28 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 82a9711..2f86c72 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 = getAutoFocusSystemMode() val videoFormat = ImageFormat.YUV_420_888 @@ -132,6 +133,18 @@ class CameraDeviceDetails(val cameraManager: CameraManager, val cameraId: String return deviceTypes } + 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 + + 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 ef7efe6..4da1053 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"); diff --git a/package/src/devices/getCameraFormat.ts b/package/src/devices/getCameraFormat.ts index 9f537f8..e0f5b33 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.target) leftPoints++ + if (format.autoFocusSystem === filter.autoFocusSystem.target) rightPoints++ + } + if (rightPoints > leftPoints) bestFormat = format }