fix: Add extra sanity-checks for CaptureRequest
(#2571)
* fix: Add extra sanity-checks for `CaptureRequest` * Update CameraDeviceDetails.kt * Refactor zoom a bit * fix: Remove unneeded flash * Move to AE instead of FLASH control * Revert "Move to AE instead of FLASH control" This reverts commit 755689411535803d156a4e84f143d0c9d08c858f. * Set AE Mode to ON for manual flash control
This commit is contained in:
parent
57c6431353
commit
b105de0194
@ -30,10 +30,12 @@ suspend fun CameraView.takePhoto(optionsMap: ReadableMap): WritableMap {
|
||||
|
||||
val qualityPrioritization = options["qualityPrioritization"] as? String ?: "balanced"
|
||||
val flash = options["flash"] as? String ?: "off"
|
||||
val enableAutoRedEyeReduction = options["enableAutoRedEyeReduction"] == true
|
||||
val enableAutoStabilization = options["enableAutoStabilization"] == true
|
||||
val enableShutterSound = options["enableShutterSound"] as? Boolean ?: true
|
||||
|
||||
// TODO: Implement Red Eye Reduction
|
||||
options["enableAutoRedEyeReduction"]
|
||||
|
||||
val flashMode = Flash.fromUnionValue(flash)
|
||||
val qualityPrioritizationMode = QualityPrioritization.fromUnionValue(qualityPrioritization)
|
||||
|
||||
@ -41,7 +43,6 @@ suspend fun CameraView.takePhoto(optionsMap: ReadableMap): WritableMap {
|
||||
qualityPrioritizationMode,
|
||||
flashMode,
|
||||
enableShutterSound,
|
||||
enableAutoRedEyeReduction,
|
||||
enableAutoStabilization,
|
||||
orientation
|
||||
)
|
||||
|
@ -58,7 +58,10 @@ class CameraDeviceDetails(private val cameraManager: CameraManager, val cameraId
|
||||
val isMultiCam by lazy { capabilities.contains(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) }
|
||||
val supportsDepthCapture by lazy { capabilities.contains(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) }
|
||||
val supportsRawCapture by lazy { capabilities.contains(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW) }
|
||||
val supportsLowLightBoost by lazy { extensions.contains(CameraExtensionCharacteristics.EXTENSION_NIGHT) }
|
||||
val supportsLowLightBoost by lazy {
|
||||
extensions.contains(CameraExtensionCharacteristics.EXTENSION_NIGHT) &&
|
||||
modes.contains(CameraCharacteristics.CONTROL_MODE_USE_SCENE_MODE)
|
||||
}
|
||||
val lensFacing by lazy { LensFacing.fromCameraCharacteristics(characteristics) }
|
||||
val hasFlash by lazy { characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE) ?: false }
|
||||
val focalLengths by lazy {
|
||||
@ -122,6 +125,7 @@ class CameraDeviceDetails(private val cameraManager: CameraManager, val cameraId
|
||||
val supportsExposureRegions by lazy { (characteristics.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AE) ?: 0) > 0 }
|
||||
val supportsWhiteBalanceRegions by lazy { (characteristics.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AWB) ?: 0) > 0 }
|
||||
|
||||
val modes by lazy { characteristics.get(CameraCharacteristics.CONTROL_AVAILABLE_MODES)?.toList() ?: emptyList() }
|
||||
val afModes by lazy { characteristics.get(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES)?.toList() ?: emptyList() }
|
||||
val aeModes by lazy { characteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES)?.toList() ?: emptyList() }
|
||||
val awbModes by lazy { characteristics.get(CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES)?.toList() ?: emptyList() }
|
||||
|
@ -368,7 +368,6 @@ class CameraSession(private val context: Context, private val cameraManager: Cam
|
||||
qualityPrioritization: QualityPrioritization,
|
||||
flash: Flash,
|
||||
enableShutterSound: Boolean,
|
||||
enableRedEyeReduction: Boolean,
|
||||
enableAutoStabilization: Boolean,
|
||||
outputOrientation: Orientation
|
||||
): CapturedPhoto {
|
||||
@ -378,7 +377,6 @@ class CameraSession(private val context: Context, private val cameraManager: Cam
|
||||
val result = captureSession.capture(
|
||||
qualityPrioritization,
|
||||
flash,
|
||||
enableRedEyeReduction,
|
||||
enableAutoStabilization,
|
||||
photoOutput.enableHdr,
|
||||
outputOrientation,
|
||||
|
@ -140,7 +140,6 @@ class PersistentCameraCaptureSession(private val cameraManager: CameraManager, p
|
||||
suspend fun capture(
|
||||
qualityPrioritization: QualityPrioritization,
|
||||
flash: Flash,
|
||||
enableRedEyeReduction: Boolean,
|
||||
enableAutoStabilization: Boolean,
|
||||
enablePhotoHdr: Boolean,
|
||||
orientation: Orientation,
|
||||
@ -157,8 +156,6 @@ class PersistentCameraCaptureSession(private val cameraManager: CameraManager, p
|
||||
val photoRequest = PhotoCaptureRequest(
|
||||
repeatingRequest,
|
||||
qualityPrioritization,
|
||||
flash,
|
||||
enableRedEyeReduction,
|
||||
enableAutoStabilization,
|
||||
enablePhotoHdr,
|
||||
orientation
|
||||
@ -195,6 +192,7 @@ class PersistentCameraCaptureSession(private val cameraManager: CameraManager, p
|
||||
// 2. Once precapture AF/AE/AWB successfully locked, capture the actual photo
|
||||
val singleRequest = photoRequest.createCaptureRequest(device, deviceDetails, outputs)
|
||||
if (result.needsFlash) {
|
||||
singleRequest.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON)
|
||||
singleRequest.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_SINGLE)
|
||||
}
|
||||
return session.capture(singleRequest.build(), enableShutterSound)
|
||||
|
@ -75,7 +75,7 @@ abstract class CameraCaptureRequest(
|
||||
}
|
||||
|
||||
// Set Zoom
|
||||
builder.setZoom(zoom, deviceDetails.characteristics)
|
||||
builder.setZoom(zoom, deviceDetails)
|
||||
|
||||
// Set Torch
|
||||
if (torch == Torch.ON) {
|
||||
|
@ -7,7 +7,6 @@ import android.os.Build
|
||||
import android.util.Log
|
||||
import com.mrousavy.camera.core.CameraDeviceDetails
|
||||
import com.mrousavy.camera.core.outputs.SurfaceOutput
|
||||
import com.mrousavy.camera.types.Flash
|
||||
import com.mrousavy.camera.types.HardwareLevel
|
||||
import com.mrousavy.camera.types.Orientation
|
||||
import com.mrousavy.camera.types.QualityPrioritization
|
||||
@ -16,8 +15,6 @@ import com.mrousavy.camera.types.Torch
|
||||
class PhotoCaptureRequest(
|
||||
repeatingRequest: RepeatingCaptureRequest,
|
||||
private val qualityPrioritization: QualityPrioritization,
|
||||
private val flash: Flash,
|
||||
private val enableRedEyeReduction: Boolean,
|
||||
private val enableAutoStabilization: Boolean,
|
||||
enablePhotoHdr: Boolean,
|
||||
private val outputOrientation: Orientation
|
||||
@ -138,26 +135,6 @@ class PhotoCaptureRequest(
|
||||
val targetOrientation = outputOrientation.toSensorRelativeOrientation(deviceDetails)
|
||||
builder.set(CaptureRequest.JPEG_ORIENTATION, targetOrientation.toDegrees())
|
||||
|
||||
// TODO: Fix flash.
|
||||
when (flash) {
|
||||
// Set the Flash Mode
|
||||
Flash.OFF -> {
|
||||
builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON)
|
||||
builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF)
|
||||
}
|
||||
Flash.ON -> {
|
||||
builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON)
|
||||
builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH)
|
||||
}
|
||||
Flash.AUTO -> {
|
||||
if (enableRedEyeReduction) {
|
||||
builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE)
|
||||
} else {
|
||||
builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set stabilization for this Frame
|
||||
if (enableAutoStabilization) {
|
||||
if (deviceDetails.opticalStabilizationModes.contains(CameraCharacteristics.LENS_OPTICAL_STABILIZATION_MODE_ON)) {
|
||||
|
@ -11,6 +11,7 @@ import com.mrousavy.camera.core.InvalidVideoStabilizationMode
|
||||
import com.mrousavy.camera.core.PropRequiresFormatToBeNonNullError
|
||||
import com.mrousavy.camera.core.outputs.SurfaceOutput
|
||||
import com.mrousavy.camera.types.CameraDeviceFormat
|
||||
import com.mrousavy.camera.types.HardwareLevel
|
||||
import com.mrousavy.camera.types.Torch
|
||||
import com.mrousavy.camera.types.VideoStabilizationMode
|
||||
|
||||
@ -51,7 +52,9 @@ class RepeatingCaptureRequest(
|
||||
): CaptureRequest.Builder {
|
||||
val builder = super.createCaptureRequest(template, device, deviceDetails, outputs)
|
||||
|
||||
if (deviceDetails.modes.contains(CameraCharacteristics.CONTROL_MODE_AUTO)) {
|
||||
builder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO)
|
||||
}
|
||||
|
||||
// Set AF
|
||||
if (enableVideoPipeline && deviceDetails.afModes.contains(CameraCharacteristics.CONTROL_AF_MODE_CONTINUOUS_VIDEO)) {
|
||||
@ -95,7 +98,11 @@ class RepeatingCaptureRequest(
|
||||
builder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE, getBestDigitalStabilizationMode(deviceDetails))
|
||||
}
|
||||
VideoStabilizationMode.CINEMATIC, VideoStabilizationMode.CINEMATIC_EXTENDED -> {
|
||||
if (deviceDetails.hardwareLevel.isAtLeast(HardwareLevel.LIMITED)) {
|
||||
builder.set(CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE, CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE_ON)
|
||||
} else {
|
||||
builder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE, getBestDigitalStabilizationMode(deviceDetails))
|
||||
}
|
||||
}
|
||||
else -> throw InvalidVideoStabilizationMode(videoStabilizationMode)
|
||||
}
|
||||
|
@ -1,20 +1,18 @@
|
||||
package com.mrousavy.camera.extensions
|
||||
|
||||
import android.hardware.camera2.CameraCharacteristics
|
||||
import android.hardware.camera2.CaptureRequest
|
||||
import android.os.Build
|
||||
import android.util.Range
|
||||
import com.mrousavy.camera.core.CameraDeviceDetails
|
||||
import com.mrousavy.camera.types.HardwareLevel
|
||||
|
||||
fun CaptureRequest.Builder.setZoom(zoom: Float, cameraCharacteristics: CameraCharacteristics) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val zoomRange = cameraCharacteristics.get(CameraCharacteristics.CONTROL_ZOOM_RATIO_RANGE) ?: Range(1f, 1f)
|
||||
fun CaptureRequest.Builder.setZoom(zoom: Float, deviceDetails: CameraDeviceDetails) {
|
||||
val zoomRange = deviceDetails.zoomRange
|
||||
val zoomClamped = zoomRange.clamp(zoom)
|
||||
|
||||
if (deviceDetails.hardwareLevel.isAtLeast(HardwareLevel.LIMITED) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
this.set(CaptureRequest.CONTROL_ZOOM_RATIO, zoomClamped)
|
||||
} else {
|
||||
val maxZoom = cameraCharacteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM)
|
||||
val zoomRange = Range(1f, maxZoom ?: 1f)
|
||||
val size = cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE)!!
|
||||
val zoomClamped = zoomRange.clamp(zoom)
|
||||
val size = deviceDetails.activeSize
|
||||
this.set(CaptureRequest.SCALER_CROP_REGION, size.zoomed(zoomClamped))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user