Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
b915f7d
Locked hacking
camsim99 Feb 20, 2024
0b33c78
This works but may need to swap in/out af points. I will see
camsim99 Feb 21, 2024
03b2095
Merge remote-tracking branch 'upstream/main' into camx_fmode
camsim99 Feb 21, 2024
f1bdb1f
Formatting
camsim99 Feb 21, 2024
bd1f1ba
Undo incorrect test changes
camsim99 Feb 21, 2024
24dd03b
Undo more changes
camsim99 Feb 21, 2024
f73c2fb
Add disableAutoCancel param + leave todos for case handling
camsim99 Feb 21, 2024
d4d1588
Formatting
camsim99 Feb 21, 2024
dd4f6b3
Add case logic
camsim99 Feb 22, 2024
b902c04
Add todo for AWB
camsim99 Feb 22, 2024
81a5170
Merge remote-tracking branch 'upstream/main' into camx_fmode
camsim99 Feb 22, 2024
72d2d5f
Manual testing
camsim99 Feb 26, 2024
32118bc
Self review
camsim99 Feb 26, 2024
da114ab
Start adding tests
camsim99 Feb 27, 2024
2965929
Add more tests
camsim99 Feb 27, 2024
861ae64
Adding more tests
camsim99 Feb 27, 2024
211962d
Merge remote-tracking branch 'upstream/main' into camx_fmode
camsim99 Feb 27, 2024
23d23ed
Finish adding tests
camsim99 Feb 27, 2024
49392ae
Self review 2
camsim99 Feb 27, 2024
faa61c5
Java fixes
camsim99 Feb 27, 2024
d025a79
Nits
camsim99 Feb 27, 2024
f8d1a6d
Add scott warning
camsim99 Feb 27, 2024
d4b4998
Merge remote-tracking branch 'upstream/main' into camx_fmode
camsim99 Feb 27, 2024
7b2fb39
Address part of review + bump version to 0.6.0
camsim99 Mar 6, 2024
7ff3bc6
Use results
camsim99 Mar 8, 2024
81d0453
Add todo fix resetting mode
camsim99 Mar 11, 2024
1ec2045
Final fixes
camsim99 Mar 11, 2024
92123c3
Fix tests
camsim99 Mar 11, 2024
94622d0
Merge remote-tracking branch 'upstream/main' into camx_fmode
camsim99 Mar 11, 2024
b3d72cb
Add additional tests
camsim99 Mar 11, 2024
54e8fd3
Avoid breaking readme
camsim99 Mar 18, 2024
9568190
Update packages/camera/camera_android_camerax/CHANGELOG.md
camsim99 Mar 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Self review
  • Loading branch information
camsim99 committed Feb 26, 2024
commit 32118bc7a31bf01d99a5671b8185aafbf3759dc4
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public static class FocusMeteringActionProxy {
}
}

// Disable auto-cancel if specified.
if (disableAutoCancel != null && disableAutoCancel == true) {
focusMeteringActionBuilder.disableAutoCancel();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand All @@ -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:
/// * Another focus point is set via [setFocusPoint], or
/// * Locked focus mode is unset by setting [FocusMode.auto].
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This maps to camera_android's behavior.

@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
// 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;

// Determine if there is an auto-focus point set currently to lock.
if (currentFocusMeteringAction != null) {
final List<(MeteringPoint, int?)> possibleCurrentAfPoints =
currentFocusMeteringAction!.meteringPointInfos
Expand All @@ -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!);
Copy link
Contributor Author

@camsim99 camsim99 Feb 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This point will center focus on entire sensor area and was recommended to me to use in this case to maintain current focus.

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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Copy link
Contributor Author

Choose a reason for hiding this comment

The 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.
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -287,7 +287,7 @@ class CameraXProxy {
return Camera2CameraControl(cameraControl: cameraControl);
}

static CaptureRequestOptions _createCaptureRequestOptions(
static CaptureRequestOptions _createAttachedCaptureRequestOptions(
List<(CaptureRequestKeySupportedType, Object?)> options) {
return CaptureRequestOptions(requestedOptions: options);
}
Expand Down