Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/camera/camera_avfoundation/AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,4 @@ Aleksandr Yurkovskiy <sanekyy@gmail.com>
Anton Borries <mail@antonborri.es>
Alex Li <google@alexv525.com>
Rahul Raj <64.rahulraj@gmail.com>
Rui Craveiro <ruicraveiro@squarealfa.com>
4 changes: 4 additions & 0 deletions packages/camera/camera_avfoundation/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.10.0

* Adds video stabilization.

## 0.9.22+4

* Migrates `FLTCameraDeviceDiscovering` and `FLTDeviceOrientationProviding` classes to Swift.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 60;
objectVersion = 54;
objects = {

/* Begin PBXBuildFile section */
Expand Down Expand Up @@ -340,8 +340,6 @@
03BB766E2665316900CE5A93 /* PBXTargetDependency */,
);
name = RunnerTests;
packageProductDependencies = (
);
productName = camera_exampleTests;
productReference = 03BB76682665316900CE5A93 /* RunnerTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
Expand Down Expand Up @@ -401,7 +399,7 @@
);
mainGroup = 97C146E51CF9000F007C117D;
packageReferences = (
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */,
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */,
);
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -879,7 +877,7 @@
/* End XCConfigurationList section */

/* Begin XCLocalSwiftPackageReference section */
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = {
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */ = {
isa = XCLocalSwiftPackageReference;
relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
Expand Down Expand Up @@ -71,6 +72,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ final class MockCamera: NSObject, Camera {
var setDescriptionWhileRecordingStub: ((String, ((FlutterError?) -> Void)?) -> Void)?
var startImageStreamStub: ((FlutterBinaryMessenger, (FlutterError?) -> Void) -> Void)?
var stopImageStreamStub: (() -> Void)?
var setVideoStabilizationModeStub:
((FCPPlatformVideoStabilizationMode, (FlutterError?) -> Void) -> Void)?
var getIsVideoStabilizationModeSupportedStub: ((FCPPlatformVideoStabilizationMode) -> Bool)?

var dartAPI: FCPCameraEventApi? {
get {
Expand Down Expand Up @@ -185,6 +188,16 @@ final class MockCamera: NSObject, Camera {
resumePreviewStub?()
}

func setVideoStabilizationMode(
_ mode: FCPPlatformVideoStabilizationMode, withCompletion: @escaping (FlutterError?) -> Void
) {
setVideoStabilizationModeStub?(mode, withCompletion)
}

func isVideoStabilizationModeSupported(_ mode: FCPPlatformVideoStabilizationMode) -> Bool {
return getIsVideoStabilizationModeSupportedStub?(mode) ?? false
}

func setDescriptionWhileRecording(
_ cameraName: String,
withCompletion completion: @escaping (FlutterError?) -> Void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ final class MockCaptureConnection: NSObject, FLTCaptureConnection {
var inputPorts: [AVCaptureInput.Port] = []
var isVideoMirroringSupported = false
var isVideoOrientationSupported = false
var preferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.off
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ class MockCaptureDevice: NSObject, FLTCaptureDevice {
return 0
}

func isVideoStabilizationModeSupported(_ videoStabilizationMode: AVCaptureVideoStabilizationMode)
-> Bool
{
return false
}

func lockForConfiguration() throws {
try lockForConfigurationStub?()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ protocol Camera: FlutterTexture, AVCaptureVideoDataOutputSampleBufferDelegate,

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

func setVideoStabilizationMode(
_ mode: FCPPlatformVideoStabilizationMode,
withCompletion: @escaping (_ error: FlutterError?) -> Void)

func isVideoStabilizationModeSupported(_ mode: FCPPlatformVideoStabilizationMode) -> Bool

func setFlashMode(
_ mode: FCPPlatformFlashMode,
withCompletion: @escaping (_ error: FlutterError?) -> Void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,28 @@ extension CameraPlugin: FCPCameraApi {
}
}

public func setVideoStabilizationMode(
_ mode: FCPPlatformVideoStabilizationMode, completion: @escaping (FlutterError?) -> Void
) {
captureSessionQueue.async { [weak self] in
self?.camera?.setVideoStabilizationMode(mode, withCompletion: completion)
}
}

public func isVideoStabilizationModeSupported(
_ mode: FCPPlatformVideoStabilizationMode,
completion: @escaping (NSNumber?, FlutterError?) -> Void
) {
captureSessionQueue.async { [weak self] in

if let isSupported = self?.camera?.isVideoStabilizationModeSupported(mode) {
completion(NSNumber(value: isSupported), nil)
} else {
completion(nil, nil)
}
}
}

public func pausePreview(completion: @escaping (FlutterError?) -> Void) {
captureSessionQueue.async { [weak self] in
self?.camera?.pausePreview()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,33 @@ final class DefaultCamera: NSObject, Camera {
completion(nil)
}

func setVideoStabilizationMode(
_ mode: FCPPlatformVideoStabilizationMode,
withCompletion completion: @escaping (FlutterError?) -> Void
) {
let stabilizationMode = getAvCaptureVideoStabilizationMode(mode)

guard captureDevice.isVideoStabilizationModeSupported(stabilizationMode) else {
completion(
FlutterError(
code: "VIDEO_STABILIZATION_ERROR",
message: "Unavailable video stabilization mode.",
details: nil
)
)
return
}
if let connection = captureVideoOutput.connection(with: .video) {
connection.preferredVideoStabilizationMode = stabilizationMode
}
completion(nil)
}

func isVideoStabilizationModeSupported(_ mode: FCPPlatformVideoStabilizationMode) -> Bool {
let stabilizationMode = getAvCaptureVideoStabilizationMode(mode)
return captureDevice.isVideoStabilizationModeSupported(stabilizationMode)
}

func setFlashMode(
_ mode: FCPPlatformFlashMode,
withCompletion completion: @escaping (FlutterError?) -> Void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,24 @@ OSType FCPGetPixelFormatForPigeonFormat(FCPPlatformImageFormatGroup imageFormat)
return kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
}
}

AVCaptureVideoStabilizationMode getAvCaptureVideoStabilizationMode(
FCPPlatformVideoStabilizationMode videoStabilizationMode) {
switch (videoStabilizationMode) {
case FCPPlatformVideoStabilizationModeOff:
return AVCaptureVideoStabilizationModeOff;
case FCPPlatformVideoStabilizationModeStandard:
return AVCaptureVideoStabilizationModeStandard;
case FCPPlatformVideoStabilizationModeCinematic:
return AVCaptureVideoStabilizationModeCinematic;
case FCPPlatformVideoStabilizationModeCinematicExtended:
if (@available(iOS 13.0, *)) {
return AVCaptureVideoStabilizationModeCinematicExtended;
} else {
return AVCaptureVideoStabilizationModeCinematic;
}

default:
return AVCaptureVideoStabilizationModeOff;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,13 @@ - (AVCaptureVideoOrientation)videoOrientation {
return self.connection.inputPorts;
}

- (void)setPreferredVideoStabilizationMode:
(AVCaptureVideoStabilizationMode)preferredVideoStabilizationMode {
self.connection.preferredVideoStabilizationMode = preferredVideoStabilizationMode;
}

- (AVCaptureVideoStabilizationMode)preferredVideoStabilizationMode {
return self.connection.preferredVideoStabilizationMode;
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ - (void)setVideoZoomFactor:(CGFloat)factor {
self.device.videoZoomFactor = factor;
}

// Video Stabilization
- (BOOL)isVideoStabilizationModeSupported:(AVCaptureVideoStabilizationMode)videoStabilizationMode {
return [self.device.activeFormat isVideoStabilizationModeSupported:videoStabilizationMode];
}

// Camera Properties
- (float)lensAperture {
return self.device.lensAperture;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,7 @@ extern FCPPlatformDeviceOrientation FCPGetPigeonDeviceOrientationForOrientation(
/// Gets VideoFormat from its Pigeon representation.
extern OSType FCPGetPixelFormatForPigeonFormat(FCPPlatformImageFormatGroup imageFormat);

extern AVCaptureVideoStabilizationMode getAvCaptureVideoStabilizationMode(
FCPPlatformVideoStabilizationMode videoStabilizationMode);

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ NS_ASSUME_NONNULL_BEGIN
/// Corresponds to the `supportsVideoOrientation` property of `AVCaptureConnection`
@property(nonatomic, readonly, getter=isVideoOrientationSupported) BOOL supportsVideoOrientation;

/// Corresponds to the `preferredVideoStabilizationMode` property of `AVCaptureConnection`
@property(nonatomic) AVCaptureVideoStabilizationMode preferredVideoStabilizationMode;

@end

/// A default implementation of the `FLTCaptureConnection` protocol. It wraps an instance
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) CGFloat minAvailableVideoZoomFactor;
@property(nonatomic) CGFloat videoZoomFactor;

// Video Stabilization
- (BOOL)isVideoStabilizationModeSupported:(AVCaptureVideoStabilizationMode)videoStabilizationMode;

// Camera Properties
- (float)lensAperture;
- (CMTime)exposureDuration;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,19 @@ typedef NS_ENUM(NSUInteger, FCPPlatformResolutionPreset) {
- (instancetype)initWithValue:(FCPPlatformResolutionPreset)value;
@end

typedef NS_ENUM(NSUInteger, FCPPlatformVideoStabilizationMode) {
FCPPlatformVideoStabilizationModeOff = 0,
FCPPlatformVideoStabilizationModeStandard = 1,
FCPPlatformVideoStabilizationModeCinematic = 2,
FCPPlatformVideoStabilizationModeCinematicExtended = 3,
};

/// Wrapper for FCPPlatformVideoStabilizationMode to allow for nullability.
@interface FCPPlatformVideoStabilizationModeBox : NSObject
@property(nonatomic, assign) FCPPlatformVideoStabilizationMode value;
- (instancetype)initWithValue:(FCPPlatformVideoStabilizationMode)value;
@end

@class FCPPlatformCameraDescription;
@class FCPPlatformCameraState;
@class FCPPlatformMediaSettings;
Expand Down Expand Up @@ -283,6 +296,13 @@ NSObject<FlutterMessageCodec> *FCPGetMessagesCodec(void);
- (void)getMaximumZoomLevel:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion;
/// Sets the zoom factor.
- (void)setZoomLevel:(double)zoom completion:(void (^)(FlutterError *_Nullable))completion;
/// Sets the video stabilization mode.
- (void)setVideoStabilizationMode:(FCPPlatformVideoStabilizationMode)mode
completion:(void (^)(FlutterError *_Nullable))completion;
/// Sets the video stabilization mode.
- (void)isVideoStabilizationModeSupported:(FCPPlatformVideoStabilizationMode)mode
completion:(void (^)(NSNumber *_Nullable,
FlutterError *_Nullable))completion;
/// Pauses streaming of preview frames.
- (void)pausePreviewWithCompletion:(void (^)(FlutterError *_Nullable))completion;
/// Resumes a previously paused preview stream.
Expand Down
Loading