-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
[camerax] Implements setFocusPoint
, setExposurePoint
, setExposureOffset
#6059
Conversation
@@ -446,13 +465,67 @@ class AndroidCameraCameraX extends CameraPlatform { | |||
|
|||
/// Gets the supported step size for exposure offset for the selected camera in EV units. | |||
/// | |||
/// Returns 0 when exposure compensation is not supported. | |||
/// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This explicitly went against the platform interface; 0 should be returned when step sizes are not supported. So, this is an unrelated fix for that fact.
...droid_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraControlHostApiImpl.java
Show resolved
Hide resolved
// supported for the device. | ||
throw CameraException(exposureCompensationNotSupported, | ||
'Exposure compensation not supported for the device.'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking for feedback on throwing an exception here/how to handle exposure compensation not being supported on the device.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would the other options be? Another specific return value for this case, like -1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah something like that! Returning a negative number or throwing an exception are really the only two options I can think of honestly, since we cannot return null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose I lean towards a special negative return value, because it isn't an actual error (or at least CameraX doesn't think it is). But this is a weak preference, if you have any reason for preferring throwing an error instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you know how the other platforms handle this? I'm not familiar with how exposureOffsetStepSize
works, but it seems the app-facing package indicates that a zero should be returned when it is not supported: https://pub.dev/documentation/camera/latest/camera/CameraController/getExposureOffsetStepSize.html
I think we should just return 0 if the other platforms are doing this as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the research!
I changed it to return 0 since that is consistent with iOS and CameraX and added a note in the docs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After talking again with @gmackall, decided to change to -1 and modify the platform interface. I think it will be helpful to have a defined return value for unsupported exposure compensation going forward and help differentiate it from the other platforms, since iOS seems to not support step sizes by always returning 0 and it doesn't seem that exposure control is implemented on web or Windows.
Edit: will need to update the platform interface in another PR it seems
@stuartmorgan let us know if you have any concerns about modifying the interface, though I believe this addition will help future-proof it. Windows could also, then, return -1. This is confusing because Windows just doesn't support it at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Going to land this for now since it's blocking me, but I can revisit this if needed and otherwise, will proceed with a PR for the platform interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stuartmorgan let us know if you have any concerns about modifying the interface, though I believe this addition will help future-proof it.
What do you mean by "modify the platform interface"? If it's just a docs change that sounds reasonable given the discussion above, if it's a code change that's complicated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a docs change :) #6182
'setExposureOffsetFailed', | ||
e.message ?? | ||
'Setting the camera exposure compensation index failed.'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking for feedback on throwing an exception here and forwarding the exception from CameraControl
in order to conform with the platform interface, in the sense that the method
Throws a
CameraException
when an illegal offset is supplied.
as per its documentation. Another option is explicitly checking in this method, but was worried that such an asynchronous call could impact performance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bparrishMines no pressure on a review, but if you have time to take a look, would appreciate your feedback on this decision!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with throwing an exception here since a user is explicitly warned about it in the app-facing package.
Although this does highlight the need for a way to check if a feature is supported without using a try/catch for every method. Something we will consider when the camera platform interface is updated.
cameraControlIdentifier, actionIdentifier); | ||
if (focusMeteringResultId == null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Part of previously mentioned fix.
return setExposureCompensationIndex(identifier, index); | ||
final int? exposureCompensationIndex = | ||
await setExposureCompensationIndex(identifier, index); | ||
if (exposureCompensationIndex == null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Part of previously mentioned fix.
return Future<int?>.value(); | ||
// Surfacing error to plugin layer to maintain consistency of | ||
// setExposureOffset implementation across platform implementations. | ||
rethrow; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking for feedback on this as per https://github.com/flutter/packages/pull/6059/files#r1481841622.
@@ -69,6 +73,9 @@ class AndroidCameraCameraX extends CameraPlatform { | |||
@visibleForTesting | |||
CameraInfo? cameraInfo; | |||
|
|||
/// The [CameraControl] instance that corresponds to the [camera] instance. | |||
CameraControl? cameraControl; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Decided to save this whenever the related camera
is updated versus making async calls to retrieve it every time that it's needed.
DisplayOrientedMeteringPointFactory factory = | ||
getDisplayOrientedMeteringPointFactory(display, 1f, 1f, cameraInfo); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A slightly larger fix: I originally implemented this host API with a different MeteringPointFactory
, which was not technically wrong but would have required that the plugin manually handle changes in camera and device orientation and can be tricky. This factory automatically does that based on the current camera's CameraInfo
and the current display. So, I made changes in this PR to the MeteringPoint
wrapper to accommodate that fact.
Fixes small issues I noticed in starting/stopping video capture while working on #6059, notably: - Change all remaining `unawaited` calls to `await` to avoid any racy behavior. - Update `camera` info after `VideoCapture` use case is bound to the lifecycle of the plugin's `ProcessCameraProvider` to make sure it is up to date. - ~Unbind `VideoCapture` use case when video recording stops since it was suggested to lazily load it for performance reasons (open to pushback on this).~ this would require potentially more changes than I originally thought - Make tests checking that async methods throw exceptions actually wait for those exceptions as this may cause flaky test behavior. Fixes flutter/flutter#132499 as this PR removes any remaining `unawaited` calls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM outside of the decision on how to handle the "Exposure compensation not supported for the device" situation
packages/camera/camera_android_camerax/test/android_camera_camerax_test.dart
Outdated
Show resolved
Hide resolved
…erax_test.dart Co-authored-by: Gray Mackall <34871572+gmackall@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
I'll leave it to @gmackall for the final review.
packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart
Outdated
Show resolved
Hide resolved
// supported for the device. | ||
throw CameraException(exposureCompensationNotSupported, | ||
'Exposure compensation not supported for the device.'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at other platforms:
iOS returns 0: https://github.com/flutter/packages/blob/main/packages/camera/camera_avfoundation/ios/Classes/CameraPlugin.m#L233
Web throws an exception: https://github.com/flutter/packages/blob/main/packages/camera/camera_web/lib/src/camera_web.dart#L557
Windows returns 1. Although, I'm not sure why that is: https://github.com/flutter/packages/blob/main/packages/camera/camera_windows/lib/camera_windows.dart#L299
And as you mentioned above, camera_android
states that all devices have support. So it looks like every platform handles it differently 😞.
I think returning 0
or throwing an exception should be fine. Returning a -1
would make it consistent that each platform handles it uniquely though haha
…odes and the ability to set focus points for each (#6109) Modifies `CameraInitializedEvent` to 1. Set the initial exposure and focus modes to auto, since CameraX defaults to auto exposure mode and only supports auto focus mode without Camera2 interop 2. Sets the ability to set focus and exposure points to be true, since CameraX supports these by default ~Should land after #6059 so that these values reflect what is actually implemented on our end~ Done :)
…tExposureOffset` (flutter/packages#6059)
flutter/packages@48048f6...078c2a3 2024-02-22 engine-flutter-autoroll@skia.org Manual roll Flutter from 5129806 to efee280 (47 revisions) (flutter/packages#6180) 2024-02-22 engine-flutter-autoroll@skia.org Manual roll Flutter (stable) from bae5e49 to abb292a (1 revision) (flutter/packages#6179) 2024-02-21 louisehsu@google.com [in_app_purchase] Convert refreshReceipt(), startObservingPaymentQueue(), stopObservingPaymentQueue(), registerPaymentQueueDelegate(), removePaymentQueueDelegate(), showPriceConsentIfNeeded() to Pigeon (flutter/packages#6165) 2024-02-21 43054281+camsim99@users.noreply.github.com [camerax] Modifies initialized camera info to reflect default AF/AE modes and the ability to set focus points for each (flutter/packages#6109) 2024-02-21 43054281+camsim99@users.noreply.github.com [camerax] Implements `setFocusPoint`, `setExposurePoint`, `setExposureOffset` (flutter/packages#6059) 2024-02-21 stuartmorgan@google.com [various] Commit Windows build migrations (flutter/packages#6175) 2024-02-21 kevmoo@users.noreply.github.com [flutter_markdown] Support wasm (flutter/packages#6168) 2024-02-21 737941+loic-sharma@users.noreply.github.com [ci] Run Windows Arm64 build tests post-submit (flutter/packages#6166) 2024-02-21 stuartmorgan@google.com [url_launcher] Remove `renderView` usage (flutter/packages#6137) 2024-02-21 b@sdevaan.nl [camera_android_camerax] Fix typo in readme (flutter/packages#6143) 2024-02-21 stuartmorgan@google.com [local_auth] Switch iOS endorsement to `local_auth_darwin` (flutter/packages#6107) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC flutter-ecosystem@google.com,rmistry@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
) Documents `getExposureOffsetStepSize` to return -1 if the device does not support exposure compensation. Helps account for `camera_android_camerax` since CameraX does not return a step size if exposure compensation is not supported. A follow up to [this discussion](#6059 (comment)).
Implements `setExposureMode`. Fixes flutter/flutter#120468. ~To be landed after (1) #6059 then (2) #6109 Done :)
…utter#6182) Documents `getExposureOffsetStepSize` to return -1 if the device does not support exposure compensation. Helps account for `camera_android_camerax` since CameraX does not return a step size if exposure compensation is not supported. A follow up to [this discussion](flutter#6059 (comment)).
Implements `setExposureMode`. Fixes flutter/flutter#120468. ~To be landed after (1) flutter#6059 then (2) flutter#6109 Done :)
Fixes small issues I noticed in starting/stopping video capture while working on flutter#6059, notably: - Change all remaining `unawaited` calls to `await` to avoid any racy behavior. - Update `camera` info after `VideoCapture` use case is bound to the lifecycle of the plugin's `ProcessCameraProvider` to make sure it is up to date. - ~Unbind `VideoCapture` use case when video recording stops since it was suggested to lazily load it for performance reasons (open to pushback on this).~ this would require potentially more changes than I originally thought - Make tests checking that async methods throw exceptions actually wait for those exceptions as this may cause flaky test behavior. Fixes flutter/flutter#132499 as this PR removes any remaining `unawaited` calls.
…eOffset` (flutter#6059) This PR implements `setFocusPoint`, `setExposurePoint`, `setExposureOffset` and makes some small fixes here and there, each of which I have left a comment about for context. Part of flutter/flutter#120468 & flutter/flutter#120467. ~NOTE: Should land after flutter#6068 done :)
…odes and the ability to set focus points for each (flutter#6109) Modifies `CameraInitializedEvent` to 1. Set the initial exposure and focus modes to auto, since CameraX defaults to auto exposure mode and only supports auto focus mode without Camera2 interop 2. Sets the ability to set focus and exposure points to be true, since CameraX supports these by default ~Should land after flutter#6059 so that these values reflect what is actually implemented on our end~ Done :)
…utter#6182) Documents `getExposureOffsetStepSize` to return -1 if the device does not support exposure compensation. Helps account for `camera_android_camerax` since CameraX does not return a step size if exposure compensation is not supported. A follow up to [this discussion](flutter#6059 (comment)).
Implements `setExposureMode`. Fixes flutter/flutter#120468. ~To be landed after (1) flutter#6059 then (2) flutter#6109 Done :)
This PR implements
setFocusPoint
,setExposurePoint
,setExposureOffset
and makes some small fixes here and there, each of which I have left a comment about for context.Part of flutter/flutter#120468 & flutter/flutter#120467.
NOTE: Should land after #6068.done :)Pre-launch Checklist
dart format
.)[shared_preferences]
pubspec.yaml
with an appropriate new version according to the pub versioning philosophy, or this PR is exempt from version changes.CHANGELOG.md
to add a description of the change, following repository CHANGELOG style.///
).