diff --git a/packages/camera/camera_avfoundation/CHANGELOG.md b/packages/camera/camera_avfoundation/CHANGELOG.md index 332fbe27c02..f66df6476e7 100644 --- a/packages/camera/camera_avfoundation/CHANGELOG.md +++ b/packages/camera/camera_avfoundation/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.23+2 + +* Code refactor related to Swift pigeon's generated struct MediaSettings being immutable. + ## 0.9.23+1 * Fixes error handling in `startWriting`. diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSettingsTests.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSettingsTests.swift index 9e40743dadd..2db565ff541 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSettingsTests.swift +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSettingsTests.swift @@ -86,8 +86,8 @@ private final class TestMediaSettingsAVWrapper: FLTCamMediaSettingsAVWrapper { if let compressionProperties = outputSettings?[AVVideoCompressionPropertiesKey] as? [String: Any], let bitrate = compressionProperties[AVVideoAverageBitRateKey] as? Int, - let frameRate = compressionProperties[AVVideoExpectedSourceFrameRateKey] as? Int, - bitrate == testVideoBitrate, frameRate == testFramesPerSecond + let frameRate = compressionProperties[AVVideoExpectedSourceFrameRateKey] as? Double, + bitrate == testVideoBitrate, frameRate == Double(testFramesPerSecond) { videoSettingsExpectation.fulfill() } diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift index 7080d46b558..36b5e3cbfca 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift @@ -43,6 +43,7 @@ final class DefaultCamera: NSObject, Camera { private let captureSessionQueue: DispatchQueue private let mediaSettings: FCPPlatformMediaSettings + private var framesPerSecond: Double? private let mediaSettingsAVWrapper: FLTCamMediaSettingsAVWrapper let videoCaptureSession: CaptureSession @@ -217,14 +218,14 @@ final class DefaultCamera: NSObject, Camera { try setCaptureSessionPreset(mediaSettings.resolutionPreset) - FormatUtils.selectBestFormat( + (captureDevice.flutterActiveFormat, framesPerSecond) = FormatUtils.findBestFormat( for: captureDevice, mediaSettings: mediaSettings, videoDimensionsConverter: videoDimensionsConverter) - if let framesPerSecond = mediaSettings.framesPerSecond { + if let framesPerSecond = framesPerSecond { // Set frame rate with 1/10 precision allowing non-integral values. - let fpsNominator = floor(framesPerSecond.doubleValue * 10.0) + let fpsNominator = floor(framesPerSecond * 10.0) let duration = CMTimeMake(value: 10, timescale: Int32(fpsNominator)) mediaSettingsAVWrapper.setMinFrameDuration(duration, on: captureDevice) @@ -580,14 +581,14 @@ final class DefaultCamera: NSObject, Camera { for: captureVideoOutput ) - if mediaSettings.videoBitrate != nil || mediaSettings.framesPerSecond != nil { + if mediaSettings.videoBitrate != nil || framesPerSecond != nil { var compressionProperties: [String: Any] = [:] if let videoBitrate = mediaSettings.videoBitrate { compressionProperties[AVVideoAverageBitRateKey] = videoBitrate } - if let framesPerSecond = mediaSettings.framesPerSecond { + if let framesPerSecond = framesPerSecond { compressionProperties[AVVideoExpectedSourceFrameRateKey] = framesPerSecond } diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/FormatUtils.swift b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/FormatUtils.swift index 11c2b255b82..d441d2bce6e 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/FormatUtils.swift +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/FormatUtils.swift @@ -36,22 +36,21 @@ enum FormatUtils { /// Finds format with same resolution as current activeFormat in captureDevice for which /// bestFrameRate returned frame rate closest to mediaSettings.framesPerSecond. - /// Preferred are formats with the same subtype as current activeFormat. Sets this format - /// as activeFormat and also updates mediaSettings.framesPerSecond to value which - /// bestFrameRate returned for that format. - static func selectBestFormat( + /// Preferred are formats with the same subtype as current activeFormat. Returns this format + /// and frame rate which bestFrameRate returned for that format. + static func findBestFormat( for captureDevice: CaptureDevice, mediaSettings: FCPPlatformMediaSettings, videoDimensionsConverter: VideoDimensionsConverter - ) { + ) -> (format: CaptureDeviceFormat, frameRate: Double) { let targetResolution = videoDimensionsConverter(captureDevice.flutterActiveFormat) let targetFrameRate = mediaSettings.framesPerSecond?.doubleValue ?? 0 let preferredSubType = CMFormatDescriptionGetMediaSubType( captureDevice.flutterActiveFormat.formatDescription) var bestFormat = captureDevice.flutterActiveFormat - var resolvedBastFrameRate = bestFrameRate(for: bestFormat, targetFrameRate: targetFrameRate) - var minDistance = abs(resolvedBastFrameRate - targetFrameRate) + var resolvedBestFrameRate = bestFrameRate(for: bestFormat, targetFrameRate: targetFrameRate) + var minDistance = abs(resolvedBestFrameRate - targetFrameRate) var isBestSubTypePreferred = true for format in captureDevice.flutterFormats { @@ -70,13 +69,12 @@ enum FormatUtils { || (distance == minDistance && isSubTypePreferred && !isBestSubTypePreferred) { bestFormat = format - resolvedBastFrameRate = frameRate + resolvedBestFrameRate = frameRate minDistance = distance isBestSubTypePreferred = isSubTypePreferred } } - captureDevice.flutterActiveFormat = bestFormat - mediaSettings.framesPerSecond = NSNumber(value: resolvedBastFrameRate) + return (bestFormat, resolvedBestFrameRate) } } diff --git a/packages/camera/camera_avfoundation/pubspec.yaml b/packages/camera/camera_avfoundation/pubspec.yaml index e0d130d61e0..1e87023aa7b 100644 --- a/packages/camera/camera_avfoundation/pubspec.yaml +++ b/packages/camera/camera_avfoundation/pubspec.yaml @@ -2,7 +2,7 @@ name: camera_avfoundation description: iOS implementation of the camera plugin. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_avfoundation issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.9.23+1 +version: 0.9.23+2 environment: sdk: ^3.9.0