Skip to content

Commit f249f53

Browse files
committed
[camera_avfoundation] Adds support for video stabilization
- Implements getSupportedVideoStabilizationModes() and setVideoStabilizationMode() methods in AVFoundationCamera.
1 parent 8efc4da commit f249f53

File tree

19 files changed

+649
-22
lines changed

19 files changed

+649
-22
lines changed

packages/camera/camera_avfoundation/AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,4 @@ Aleksandr Yurkovskiy <[email protected]>
6464
Anton Borries <[email protected]>
6565
6666
Rahul Raj <[email protected]>
67+
Rui Craveiro <[email protected]>

packages/camera/camera_avfoundation/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 0.10.0
2+
3+
* Adds video stabilization.
4+
- Adds getSupportedVideoStabilizationModes method.
5+
- Adds setVideoStabilizationMode method.
6+
17
## 0.9.23+2
28

39
* Code refactor related to Swift pigeon's generated struct MediaSettings being immutable.

packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockCamera.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ final class MockCamera: NSObject, Camera {
4444
var setDescriptionWhileRecordingStub: ((String, ((FlutterError?) -> Void)?) -> Void)?
4545
var startImageStreamStub: ((FlutterBinaryMessenger, (FlutterError?) -> Void) -> Void)?
4646
var stopImageStreamStub: (() -> Void)?
47+
var setVideoStabilizationModeStub:
48+
((FCPPlatformVideoStabilizationMode, (FlutterError?) -> Void) -> Void)?
49+
var getIsVideoStabilizationModeSupportedStub: ((FCPPlatformVideoStabilizationMode) -> Bool)?
4750

4851
var dartAPI: FCPCameraEventApi? {
4952
get {
@@ -188,6 +191,16 @@ final class MockCamera: NSObject, Camera {
188191
resumePreviewStub?()
189192
}
190193

194+
func setVideoStabilizationMode(
195+
_ mode: FCPPlatformVideoStabilizationMode, withCompletion: @escaping (FlutterError?) -> Void
196+
) {
197+
setVideoStabilizationModeStub?(mode, withCompletion)
198+
}
199+
200+
func isVideoStabilizationModeSupported(_ mode: FCPPlatformVideoStabilizationMode) -> Bool {
201+
return getIsVideoStabilizationModeSupportedStub?(mode) ?? false
202+
}
203+
191204
func setDescriptionWhileRecording(
192205
_ cameraName: String,
193206
withCompletion completion: @escaping (FlutterError?) -> Void

packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockCaptureConnection.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@ final class MockCaptureConnection: NSObject, CaptureConnection {
2828
var inputPorts: [AVCaptureInput.Port] = []
2929
var isVideoMirroringSupported = false
3030
var isVideoOrientationSupported = false
31+
var preferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.off
3132
}

packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockCaptureDevice.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,12 @@ class MockCaptureDevice: NSObject, CaptureDevice {
118118

119119
var iso: Float { 0 }
120120

121+
func isVideoStabilizationModeSupported(_ videoStabilizationMode: AVCaptureVideoStabilizationMode)
122+
-> Bool
123+
{
124+
return false
125+
}
126+
121127
func lockForConfiguration() throws {
122128
try lockForConfigurationStub?()
123129
}

packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/Camera.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@ protocol Camera: FlutterTexture, AVCaptureVideoDataOutputSampleBufferDelegate,
102102

103103
func setZoomLevel(_ zoom: CGFloat, withCompletion: @escaping (_ error: FlutterError?) -> Void)
104104

105+
func setVideoStabilizationMode(
106+
_ mode: FCPPlatformVideoStabilizationMode,
107+
withCompletion: @escaping (_ error: FlutterError?) -> Void)
108+
109+
func isVideoStabilizationModeSupported(_ mode: FCPPlatformVideoStabilizationMode) -> Bool
110+
105111
func setFlashMode(
106112
_ mode: FCPPlatformFlashMode,
107113
withCompletion: @escaping (_ error: FlutterError?) -> Void

packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraPlugin.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,29 @@ extension CameraPlugin: FCPCameraApi {
514514
}
515515
}
516516

517+
public func setVideoStabilizationMode(
518+
_ mode: FCPPlatformVideoStabilizationMode, completion: @escaping (FlutterError?) -> Void
519+
) {
520+
captureSessionQueue.async { [weak self] in
521+
self?.camera?.setVideoStabilizationMode(mode, withCompletion: completion)
522+
}
523+
}
524+
525+
public func isVideoStabilizationModeSupported(
526+
_ mode: FCPPlatformVideoStabilizationMode,
527+
completion: @escaping (NSNumber?, FlutterError?) -> Void
528+
) {
529+
captureSessionQueue.async { [weak self] in
530+
531+
if let camera = self?.camera {
532+
let isSupported = camera.isVideoStabilizationModeSupported(mode)
533+
completion(NSNumber(value: isSupported), nil)
534+
} else {
535+
completion(nil, nil)
536+
}
537+
}
538+
}
539+
517540
public func pausePreview(completion: @escaping (FlutterError?) -> Void) {
518541
captureSessionQueue.async { [weak self] in
519542
self?.camera?.pausePreview()

packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraProperties.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,27 @@ func getPixelFormat(for imageFormat: FCPPlatformImageFormatGroup) -> OSType {
8181
return kCVPixelFormatType_32BGRA
8282
}
8383
}
84+
85+
/// Gets video stabilization mode from its Pigeon representation.
86+
/// videoStabilizationMode - the Pigeon video stabilization mode.
87+
func getAvCaptureVideoStabilizationMode(
88+
_ videoStabilizationMode: FCPPlatformVideoStabilizationMode
89+
) -> AVCaptureVideoStabilizationMode {
90+
91+
switch videoStabilizationMode {
92+
case .off:
93+
return .off
94+
case .standard:
95+
return .standard
96+
case .cinematic:
97+
return .cinematic
98+
case .cinematicExtended:
99+
if #available(iOS 13.0, *) {
100+
return .cinematicExtended
101+
} else {
102+
return .cinematic
103+
}
104+
@unknown default:
105+
return .off
106+
}
107+
}

packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CaptureConnection.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ protocol CaptureConnection: NSObjectProtocol {
2121

2222
/// Corresponds to the `supportsVideoOrientation` property of `AVCaptureConnection`
2323
var isVideoOrientationSupported: Bool { get }
24+
25+
/// Corresponds to the preferredVideoStabilizationMode property of `AVCaptureConnection`
26+
var preferredVideoStabilizationMode: AVCaptureVideoStabilizationMode { get set }
27+
2428
}
2529

2630
extension AVCaptureConnection: CaptureConnection {}

packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CaptureDevice.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ protocol CaptureDevice: NSObjectProtocol {
5858
var minAvailableVideoZoomFactor: CGFloat { get }
5959
var videoZoomFactor: CGFloat { get set }
6060

61+
// Video Stabilization
62+
func isVideoStabilizationModeSupported(_ videoStabilizationMode: AVCaptureVideoStabilizationMode)
63+
-> Bool
64+
6165
// Camera Properties
6266
var lensAperture: Float { get }
6367
var exposureDuration: CMTime { get }
@@ -97,6 +101,13 @@ extension AVCaptureDevice: CaptureDevice {
97101
}
98102

99103
var flutterFormats: [CaptureDeviceFormat] { formats }
104+
105+
func isVideoStabilizationModeSupported(_ videoStabilizationMode: AVCaptureVideoStabilizationMode)
106+
-> Bool
107+
{
108+
return self.activeFormat.isVideoStabilizationModeSupported(videoStabilizationMode)
109+
}
110+
100111
}
101112

102113
extension AVCaptureInput: CaptureInput {

0 commit comments

Comments
 (0)