@@ -702,18 +702,58 @@ class CameraController extends ValueNotifier<CameraValue> {
702702 /// the supplied [mode] value should be a mode in the list returned
703703 /// by [getSupportedVideoStabilizationModes] .
704704 ///
705- /// Throws a [CameraException] when an unsupported video stabilization
706- /// mode is supplied.
707- Future <void > setVideoStabilizationMode (VideoStabilizationMode mode) async {
705+ /// When [allowFallback] is true (default) and when
706+ /// the camera supports any video stabilization other than
707+ /// [VideoStabilizationMode.off] , then the camera will
708+ /// be set to the best video stabilization mode up to, and including, [mode] .
709+ ///
710+ /// When either [allowFallback] is false or the only
711+ /// supported video stabilization mode is [VideoStabilizationMode.off] ,
712+ /// and if [mode] is not one of the supported modes,
713+ /// then it throws an [ArgumentError] .
714+ Future <void > setVideoStabilizationMode (
715+ VideoStabilizationMode mode, {
716+ bool allowFallback = true ,
717+ }) async {
708718 _throwIfNotInitialized ('setVideoStabilizationMode' );
709719 try {
710- await CameraPlatform .instance.setVideoStabilizationMode (_cameraId, mode);
720+ final VideoStabilizationMode requestMode =
721+ allowFallback ? await _getVideoStabilizationFallbackMode (mode) : mode;
722+
723+ await CameraPlatform .instance
724+ .setVideoStabilizationMode (_cameraId, requestMode);
711725 value = value.copyWith (videoStabilizationMode: mode);
712726 } on PlatformException catch (e) {
713727 throw CameraException (e.code, e.message);
714728 }
715729 }
716730
731+ Future <VideoStabilizationMode > _getVideoStabilizationFallbackMode (
732+ VideoStabilizationMode mode) async {
733+ final Iterable <VideoStabilizationMode > supportedModes = await CameraPlatform
734+ .instance
735+ .getSupportedVideoStabilizationModes (_cameraId);
736+
737+ // if there are no supported modes or if the only supported mode is Off
738+ // and something else is requested, then we throw an ArgumentError.
739+ if (supportedModes.isEmpty ||
740+ (mode != VideoStabilizationMode .off &&
741+ supportedModes.every ((VideoStabilizationMode sm) =>
742+ sm == VideoStabilizationMode .off))) {
743+ throw ArgumentError ('Unavailable video stabilization mode.' , 'mode' );
744+ }
745+
746+ VideoStabilizationMode requestMode = VideoStabilizationMode .off;
747+ for (final VideoStabilizationMode supportedMode in supportedModes) {
748+ if (supportedMode.index <= mode.index &&
749+ supportedMode.index >= requestMode.index) {
750+ requestMode = supportedMode;
751+ }
752+ }
753+
754+ return requestMode;
755+ }
756+
717757 /// Gets a list of video stabilization modes that are supported for the selected camera.
718758 ///
719759 /// Will return the list of supported video stabilization modes
0 commit comments