Repository navigation
[camera] Add zero-shutter-lag support to camera_android_camerax and camera_avfoundation - #13199
Conversation
…amera_avfoundation Implementation portion of flutter#12374, now that camera_platform_interface 2.15.0 is published.
There was a problem hiding this comment.
Code Review
This pull request introduces support for zero-shutter-lag still image capture in both the Android (CameraX) and iOS (AVFoundation) camera implementations by adding isZeroShutterLagSupported and setZeroShutterLagEnabled. The review feedback identifies a potential race condition in the Android _recreateImageCapture() method when triggered concurrently, recommending that the recreation process be serialized using a Future chain.
| Future<void> _recreateImageCapture() async { | ||
| if (imageCapture == null) { | ||
| return; | ||
| } | ||
|
|
||
| // Recreate ImageCapture with the requested JPEG quality. | ||
| // Unbind the current ImageCapture if it exists and is bound. | ||
| await _unbindUseCaseFromLifecycle(imageCapture!); | ||
|
|
||
| // Recreate ImageCapture with the requested settings. | ||
| // Preserve locked orientation if set, otherwise use default display rotation. | ||
| final int targetRotation = | ||
| _lockedCaptureOrientation ?? await deviceOrientationManager.getDefaultDisplayRotation(); | ||
| imageCapture = ImageCapture( | ||
| resolutionSelector: _presetResolutionSelector, | ||
| targetRotation: targetRotation, | ||
| jpegQuality: quality, | ||
| jpegQuality: _jpegQuality, | ||
| zeroShutterLagEnabled: _zeroShutterLagEnabled, | ||
| ); | ||
| } |
There was a problem hiding this comment.
There is a potential race condition in _recreateImageCapture() if it is called concurrently (for example, if setJpegImageQuality and setZeroShutterLagEnabled are called in rapid succession). Since _unbindUseCaseFromLifecycle is asynchronous, multiple concurrent calls can interleave, leading to _unbindUseCaseFromLifecycle being called multiple times on the same imageCapture instance, or creating redundant ImageCapture instances.
Consider serializing the recreation process using a Future chain to ensure thread-safe/reentrant-safe execution. Note that you will need to declare Future<void>? _recreationFuture; as an instance variable in the AndroidCameraCameraX class.
Future<void> _recreateImageCapture() async {
if (imageCapture == null) {
return;
}
if (_recreationFuture != null) {
await _recreationFuture;
return _recreateImageCapture();
}
final Future<void> recreation = () async {
await _unbindUseCaseFromLifecycle(imageCapture!);
final int targetRotation =
_lockedCaptureOrientation ?? await deviceOrientationManager.getDefaultDisplayRotation();
imageCapture = ImageCapture(
resolutionSelector: _presetResolutionSelector,
targetRotation: targetRotation,
jpegQuality: _jpegQuality,
zeroShutterLagEnabled: _zeroShutterLagEnabled,
);
}();
_recreationFuture = recreation;
try {
await recreation;
} finally {
if (_recreationFuture == recreation) {
_recreationFuture = null;
}
}
}There was a problem hiding this comment.
This unbind-and-recreate flow already existed in setJpegImageQuality on main; this PR only extracts it into _recreateImageCapture(), and the code is unchanged from what was reviewed in #12374. Leaving serialization out of scope here; it can be handled in a separate PR if needed.
|
@bparrishMines @camsim99 @hellohuanlin Follow-up to #12996: this is the platform implementation part of #12374, unchanged from what you reviewed there. PTAL. |
|
2 similar comments
|
|
camsim99
left a comment
There was a problem hiding this comment.
Sorry I missed your last ping! This LGTM!
|
This pull request is not mergeable in its current state, likely because of a merge conflict. Pre-submit CI jobs were not triggered. Pushing a new commit to this branch that resolves the issue will result in pre-submit jobs being scheduled. |
…tations # Conflicts: # packages/camera/camera_avfoundation/CHANGELOG.md # packages/camera/camera_avfoundation/pubspec.yaml
|
@camsim99 @hellohuanlin Resolved merge conflicts with main (version bump only). Could one of you re-add |
|
@camsim99 @hellohuanlin The post-merge release run for this PR failed because the Could one of you re-run that release workflow? Thanks! |
Done. It should be released now. |
flutter/packages@618afba...1383427 2026-10-21 [email protected] [shared_preferences] Keep Kotlin classes used through JNI in Android release builds (flutter/packages#13311) 2026-10-20 [email protected] [webview_flutter_wkwebview] Roll back iOS and macOS versions (flutter/packages#13354) 2026-10-20 [email protected] [camera]fix resolution test failure due to hardware restriction (flutter/packages#13356) 2026-10-20 [email protected] [google_maps_flutter_web] Fail fast and deduplicate map setup in integration tests (flutter/packages#13092) 2026-10-20 [email protected] [camera_avfoundation] Fix Swift analyzer issues in tests (flutter/packages#13340) 2026-10-20 [email protected] Sync release-material_ui-1.8.0 to main (flutter/packages#13346) 2026-10-20 [email protected] [material_ui] add a `barFocusNode` to `SearchAnchor.bar` (ref: flutter#186073) (flutter/packages#12863) 2026-10-20 [email protected] [in_app_purchase_storekit] Expose sk2Transaction on SK2PurchaseDetails (flutter/packages#13341) 2026-10-20 [email protected] Sync release-cupertino_ui-1.1.4 to main (flutter/packages#13350) 2026-10-20 [email protected] [google_maps_flutter_web] Don't hang `onMapCreated` when tiles fail to load (flutter/packages#13059) 2026-10-20 [email protected] [material_ui] Unskip web tests that pass on CanvasKit and Skwasm: adaptive_text_selection_toolbar_test, material_button_test, outlined_button_test, text_button_test (flutter/packages#13335) 2026-10-20 [email protected] Sync release-go_router-18.1.1 to main (flutter/packages#13347) 2026-10-20 [email protected] [camera] Add zero-shutter-lag support to camera_android_camerax and camera_avfoundation (flutter/packages#13199) If this roll has caused a breakage, revert this CL and set the roller to dry run mode using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC [email protected] 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
flutter/packages@618afba...1383427 2026-10-21 [email protected] [shared_preferences] Keep Kotlin classes used through JNI in Android release builds (flutter/packages#13311) 2026-10-20 [email protected] [webview_flutter_wkwebview] Roll back iOS and macOS versions (flutter/packages#13354) 2026-10-20 [email protected] [camera]fix resolution test failure due to hardware restriction (flutter/packages#13356) 2026-10-20 [email protected] [google_maps_flutter_web] Fail fast and deduplicate map setup in integration tests (flutter/packages#13092) 2026-10-20 [email protected] [camera_avfoundation] Fix Swift analyzer issues in tests (flutter/packages#13340) 2026-10-20 [email protected] Sync release-material_ui-1.8.0 to main (flutter/packages#13346) 2026-10-20 [email protected] [material_ui] add a `barFocusNode` to `SearchAnchor.bar` (ref: flutter#186073) (flutter/packages#12863) 2026-10-20 [email protected] [in_app_purchase_storekit] Expose sk2Transaction on SK2PurchaseDetails (flutter/packages#13341) 2026-10-20 [email protected] Sync release-cupertino_ui-1.1.4 to main (flutter/packages#13350) 2026-10-20 [email protected] [google_maps_flutter_web] Don't hang `onMapCreated` when tiles fail to load (flutter/packages#13059) 2026-10-20 [email protected] [material_ui] Unskip web tests that pass on CanvasKit and Skwasm: adaptive_text_selection_toolbar_test, material_button_test, outlined_button_test, text_button_test (flutter/packages#13335) 2026-10-20 [email protected] Sync release-go_router-18.1.1 to main (flutter/packages#13347) 2026-10-20 [email protected] [camera] Add zero-shutter-lag support to camera_android_camerax and camera_avfoundation (flutter/packages#13199) If this roll has caused a breakage, revert this CL and set the roller to dry run mode using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC [email protected] 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
flutter/packages@618afba...1383427 2026-10-21 [email protected] [shared_preferences] Keep Kotlin classes used through JNI in Android release builds (flutter/packages#13311) 2026-10-20 [email protected] [webview_flutter_wkwebview] Roll back iOS and macOS versions (flutter/packages#13354) 2026-10-20 [email protected] [camera]fix resolution test failure due to hardware restriction (flutter/packages#13356) 2026-10-20 [email protected] [google_maps_flutter_web] Fail fast and deduplicate map setup in integration tests (flutter/packages#13092) 2026-10-20 [email protected] [camera_avfoundation] Fix Swift analyzer issues in tests (flutter/packages#13340) 2026-10-20 [email protected] Sync release-material_ui-1.8.0 to main (flutter/packages#13346) 2026-10-20 [email protected] [material_ui] add a `barFocusNode` to `SearchAnchor.bar` (ref: flutter#186073) (flutter/packages#12863) 2026-10-20 [email protected] [in_app_purchase_storekit] Expose sk2Transaction on SK2PurchaseDetails (flutter/packages#13341) 2026-10-20 [email protected] Sync release-cupertino_ui-1.1.4 to main (flutter/packages#13350) 2026-10-20 [email protected] [google_maps_flutter_web] Don't hang `onMapCreated` when tiles fail to load (flutter/packages#13059) 2026-10-20 [email protected] [material_ui] Unskip web tests that pass on CanvasKit and Skwasm: adaptive_text_selection_toolbar_test, material_button_test, outlined_button_test, text_button_test (flutter/packages#13335) 2026-10-20 [email protected] Sync release-go_router-18.1.1 to main (flutter/packages#13347) 2026-10-20 [email protected] [camera] Add zero-shutter-lag support to camera_android_camerax and camera_avfoundation (flutter/packages#13199) If this roll has caused a breakage, revert this CL and set the roller to dry run mode using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC [email protected] 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
Platform implementation portion of #12374, split out per the federated plugin process now that
camera_platform_interface2.15.0 is published (#12996). No changes from what was reviewed there, other than rebasing ontomainand resolving version/CHANGELOG conflicts.Implements
isZeroShutterLagSupported/setZeroShutterLagEnabledin:camera_android_camerax(0.7.6)camera_avfoundation(0.11.1, iOS 17+)Part of flutter/flutter#190598
Pre-Review Checklist
[shared_preferences]///).Footnotes
Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. ↩ ↩2