-
Notifications
You must be signed in to change notification settings - Fork 3.6k
[camerax] Implements setFocusMode
#6176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
b915f7d
0b33c78
03b2095
f1bdb1f
bd1f1ba
24dd03b
f73c2fb
d4d1588
dd4f6b3
b902c04
81a5170
72d2d5f
32118bc
da114ab
2965929
861ae64
211962d
23d23ed
49392ae
faa61c5
d025a79
f8d1a6d
d4b4998
7b2fb39
7ff3bc6
81d0453
1ec2045
92123c3
94622d0
b3d72cb
54e8fd3
9568190
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -194,19 +194,23 @@ class AndroidCameraCameraX extends CameraPlatform { | |
| @visibleForTesting | ||
| FocusMeteringAction? currentFocusMeteringAction; | ||
|
|
||
| /// Current focus mode. | ||
| /// Current focus mode set via [setFocusMode]. | ||
| /// | ||
| /// CameraX defaults to auto-focus mode. | ||
| FocusMode currentFocusMode = FocusMode.auto; | ||
|
|
||
| /// Current exposure mode. | ||
| /// Current exposure mode set via [setExposureMode]. | ||
| /// | ||
| /// CameraX defaults to auto-exposure mode. | ||
| ExposureMode currentExposureMode = ExposureMode.auto; | ||
|
|
||
| /// Whether or not a default focus point of the dentire sensor area was added | ||
| /// to lock focus. | ||
| bool defaultFocusPointAdded = false; | ||
| /// Whether or not a default focus point of the entire sensor area was focused | ||
| /// and locked. | ||
| /// | ||
| /// This should only be true if [setExposureMode] was called to set | ||
| /// [FocusMode.locked] and no previous focus point was set via | ||
| /// [setFocusPoint]. | ||
| bool defaultFocusPointLocked = false; | ||
|
|
||
| /// Error code indicating that exposure compensation is not supported by | ||
| /// CameraX for the device. | ||
|
|
@@ -468,10 +472,16 @@ class AndroidCameraCameraX extends CameraPlatform { | |
| /// [cameraId] is not used. | ||
| @override | ||
| Future<void> setExposurePoint(int cameraId, Point<double>? point) async { | ||
| // We lock the new focus and metering action if focus mode has been locked | ||
| // to ensure that the current focus point remains locked. Any exposure mode | ||
| // setting will not be impacted by this lock (setting an exposure mode | ||
| // is implemented with Camera2 interop that will override any settings | ||
| // to achieve the expected exposure mode as needed). | ||
| final bool disableAutoCancel = currentFocusMode == FocusMode.locked; | ||
| await _startFocusAndMeteringForPoint( | ||
| point: point, | ||
| meteringMode: FocusMeteringAction.flagAe, | ||
| disableAutoCancel: currentFocusMode == FocusMode.locked); | ||
| disableAutoCancel: disableAutoCancel); | ||
| } | ||
|
|
||
| /// Gets the minimum supported exposure offset for the selected camera in EV units. | ||
|
|
@@ -495,26 +505,39 @@ class AndroidCameraCameraX extends CameraPlatform { | |
| } | ||
|
|
||
| /// Sets the focus mode for taking pictures. | ||
| /// | ||
| /// Setting [FocusMode.locked] will lock current focus point if one exists or | ||
| /// center of entire sensor area if not and will stay locked until either: | ||
camsim99 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// * Another focus point is set via [setFocusPoint], or | ||
| /// * Locked focus mode is unset by setting [FocusMode.auto]. | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This maps to |
||
| @override | ||
| Future<void> setFocusMode(int cameraId, FocusMode mode) async { | ||
| switch (mode) { | ||
| case FocusMode.auto: | ||
| if (currentFocusMode == FocusMode.auto) { | ||
| // CameraX uses auto-focus mode by default, so no need to reconfigure | ||
camsim99 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // auto-focus if already set. | ||
| return; | ||
| } | ||
| final MeteringPoint? autoAfPoint = defaultFocusPointAdded | ||
|
|
||
| // Determine auto-focus point to restore, if any. We do not restore | ||
| // default auto-focus point if set previously to lock focus. | ||
| final MeteringPoint? autoAfPoint = defaultFocusPointLocked | ||
| ? null | ||
| : currentFocusMeteringAction!.meteringPointInfos | ||
| .where(((MeteringPoint, int?) meteringPointInfo) => | ||
| meteringPointInfo.$2 != FocusMeteringAction.flagAf) | ||
| .toList() | ||
| .first | ||
| .$1; | ||
| defaultFocusPointAdded = false; | ||
| defaultFocusPointLocked = false; | ||
|
|
||
| await _startFocusAndMeteringFor( | ||
| point: autoAfPoint, meteringMode: FocusMeteringAction.flagAf); | ||
| case FocusMode.locked: | ||
| MeteringPoint? lockedAfPoint; | ||
camsim99 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| // Determine if there is an auto-focus point set currently to lock. | ||
| if (currentFocusMeteringAction != null) { | ||
| final List<(MeteringPoint, int?)> possibleCurrentAfPoints = | ||
| currentFocusMeteringAction!.meteringPointInfos | ||
|
|
@@ -525,16 +548,24 @@ class AndroidCameraCameraX extends CameraPlatform { | |
| ? null | ||
| : possibleCurrentAfPoints.first.$1; | ||
| } | ||
|
|
||
| // If there isn't, lock center of entire sensor area by default. | ||
| if (lockedAfPoint == null) { | ||
| lockedAfPoint = proxy.createMeteringPoint(0.5, 0.5, 1, cameraInfo!); | ||
|
||
| defaultFocusPointAdded = true; | ||
| defaultFocusPointLocked = true; | ||
| } | ||
|
|
||
| await _startFocusAndMeteringFor( | ||
| point: lockedAfPoint, | ||
| meteringMode: FocusMeteringAction.flagAf, | ||
| disableAutoCancel: true); | ||
| } | ||
| // Update current focus mode. | ||
| currentFocusMode = mode; | ||
|
|
||
| // If focus mode was just locked and exposure mode is not, unlock exposure | ||
| // mode to ensure that disabling auto-cancel does not interfere with | ||
| // automatic exposure metering. | ||
| if (currentExposureMode == ExposureMode.auto && | ||
| currentFocusMode == FocusMode.locked) { | ||
| await setExposureMode(cameraId, currentExposureMode); | ||
|
|
@@ -625,6 +656,11 @@ class AndroidCameraCameraX extends CameraPlatform { | |
| /// [cameraId] is not used. | ||
| @override | ||
| Future<void> setFocusPoint(int cameraId, Point<double>? point) async { | ||
| // We lock the new focus and metering action if focus mode has been locked | ||
| // to ensure that the current focus point remains locked. Any exposure mode | ||
| // setting will not be impacted by this lock (setting an exposure mode | ||
| // is implemented with Camera2 interop that will override any settings | ||
| // to achieve the expected exposure mode as needed). | ||
| await _startFocusAndMeteringForPoint( | ||
| point: point, | ||
| meteringMode: FocusMeteringAction.flagAf, | ||
|
|
@@ -1164,26 +1200,25 @@ class AndroidCameraCameraX extends CameraPlatform { | |
| disableAutoCancel: disableAutoCancel); | ||
| } | ||
|
|
||
| // TODO(camsim99): Clarify behavior when there is no current action. | ||
| // TODO(camsim99): Throw exception for AWB because I'm not handling this at all. | ||
| /// Starts a focus and metering action. | ||
| /// | ||
| /// This method will modify and start the current action's metering points | ||
| /// overriden with the [point] provided for the specified [meteringMode] type | ||
| /// only, with all other points of other modes left untouched. Thus, the | ||
| /// focus and metering action started will contain only the one most recently | ||
| /// set point for each metering mode: AF, AE, AWB. | ||
| /// only, with all other points of other modes left untouched. If no current | ||
| /// action exists, only the specified [point] will be set. Thus, the focus | ||
| /// and metering action started will only contain at most the one most | ||
| /// recently set point for each metering mode: AF, AE, AWB. | ||
| /// | ||
| /// Thus, if [point] is non-null, this action includes: | ||
| /// * metering points and their modes previously added to | ||
| /// [currentFocusMeteringAction] that do not share a metering mode with | ||
| /// [point] and | ||
| /// [point] (if [currentFocusMeteringAction] is non-null) and | ||
| /// * [point] with the specified [meteringMode]. | ||
| /// If [point] is null, this action includes only metering points and | ||
| /// their modes previously added to [currentFocusMeteringAction] that do not | ||
| /// share a metering mode with [point]. If there are no such metering | ||
| /// points, then the previously enabled focus and metering actions will be | ||
| /// canceled. | ||
| /// share a metering mode with [point] (if [currentFocusMeteringAction] is | ||
| /// non-null). If there are no such metering points, then the previously | ||
| /// enabled focus and metering actions will be canceled. | ||
| Future<void> _startFocusAndMeteringFor( | ||
| {required MeteringPoint? point, | ||
| required int meteringMode, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -55,10 +55,10 @@ class CameraXProxy { | |
| _startListeningForDeviceOrientationChange, | ||
| this.setPreviewSurfaceProvider = _setPreviewSurfaceProvider, | ||
| this.getDefaultDisplayRotation = _getDefaultDisplayRotation, | ||
| this.createMeteringPoint = _createMeteringPoint, | ||
| this.createFocusMeteringAction = _createFocusMeteringAction, | ||
| this.createMeteringPoint = _createAttachedMeteringPoint, | ||
| this.createFocusMeteringAction = _createAttachedFocusMeteringAction, | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Renaming for consistency. |
||
| this.getCamera2CameraControl = _getCamera2CameraControl, | ||
| this.createCaptureRequestOptions = _createCaptureRequestOptions, | ||
| this.createCaptureRequestOptions = _createAttachedCaptureRequestOptions, | ||
| }); | ||
|
|
||
| /// Returns a [ProcessCameraProvider] instance. | ||
|
|
@@ -158,11 +158,11 @@ class CameraXProxy { | |
| FocusMeteringAction Function(List<(MeteringPoint, int?)> meteringPointInfos, | ||
| bool? disableAutoCancel) createFocusMeteringAction; | ||
|
|
||
| /// Get [Camera2CameraControl] instance from [cameraControl]. | ||
| /// Retrieves [Camera2CameraControl] instance from [cameraControl]. | ||
| Camera2CameraControl Function(CameraControl cameraControl) | ||
| getCamera2CameraControl; | ||
|
|
||
| /// Create [CapureRequestOptions] with specified options. | ||
| /// Returns a [CapureRequestOptions] with specified options. | ||
| CaptureRequestOptions Function( | ||
| List<(CaptureRequestKeySupportedType, Object?)> options) | ||
| createCaptureRequestOptions; | ||
|
|
@@ -270,12 +270,12 @@ class CameraXProxy { | |
| return DeviceOrientationManager.getDefaultDisplayRotation(); | ||
| } | ||
|
|
||
| static MeteringPoint _createMeteringPoint( | ||
| static MeteringPoint _createAttachedMeteringPoint( | ||
| double x, double y, double? size, CameraInfo cameraInfo) { | ||
| return MeteringPoint(x: x, y: y, size: size, cameraInfo: cameraInfo); | ||
| } | ||
|
|
||
| static FocusMeteringAction _createFocusMeteringAction( | ||
| static FocusMeteringAction _createAttachedFocusMeteringAction( | ||
| List<(MeteringPoint, int?)> meteringPointInfos, bool? disableAutoCancel) { | ||
| return FocusMeteringAction( | ||
| meteringPointInfos: meteringPointInfos, | ||
|
|
@@ -287,7 +287,7 @@ class CameraXProxy { | |
| return Camera2CameraControl(cameraControl: cameraControl); | ||
| } | ||
|
|
||
| static CaptureRequestOptions _createCaptureRequestOptions( | ||
| static CaptureRequestOptions _createAttachedCaptureRequestOptions( | ||
| List<(CaptureRequestKeySupportedType, Object?)> options) { | ||
| return CaptureRequestOptions(requestedOptions: options); | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.