Skip to content

Commit 75382f6

Browse files
committed
Video stabilization fallback
1 parent 068141d commit 75382f6

File tree

5 files changed

+469
-21
lines changed

5 files changed

+469
-21
lines changed

packages/camera/camera/lib/src/camera_controller.dart

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

packages/camera/camera/test/camera_preview_test.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,10 @@ class FakeController extends ValueNotifier<CameraValue>
134134
CameraDescription get description => value.description;
135135

136136
@override
137-
Future<void> setVideoStabilizationMode(VideoStabilizationMode mode) async {}
137+
Future<void> setVideoStabilizationMode(
138+
VideoStabilizationMode mode, {
139+
bool allowFallback = true,
140+
}) async {}
138141

139142
@override
140143
Future<Iterable<VideoStabilizationMode>>

0 commit comments

Comments
 (0)