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
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.9.22+10

* Removes dependence on MediaSettings mutability.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you explain more about what this means? Is it removing a feature?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't remove any feature. It's just a refactor, I've described it in the description

Current implementation of FormatUtils.selectBestFormat overrides MediaSettings.framesPerSecond. With swift pigeon contracts MediaSettings is non mutable so that will no longer be possible.

MediaSettings class is generated by pigeon. And when pigeon output is ObjC its fields are mutable specifically framesPerSecond. This field is overwritten as a result of FormatUtils.selectBestFormat execution. When pigeon output is Swift all fields in MediaSettings are declared as let so selectBestFormat can no longer set it. Also in Swift framesPerSecond is an Int64 not NSNumber so it's not possible to assign floating point frame rate to it.


## 0.9.22+9

* Migrates `FLTSavePhotoDelegate`, `FLTWritableData`, and `FLTImageStreamHandler` classes to Swift.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

private let videoCaptureSession: CaptureSession
Expand Down Expand Up @@ -213,14 +214,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)
Expand Down Expand Up @@ -542,14 +543,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
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
) {
) -> (CaptureDeviceFormat, 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 {
Expand All @@ -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)
}
}
2 changes: 1 addition & 1 deletion packages/camera/camera_avfoundation/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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.22+9
version: 0.9.22+10

environment:
sdk: ^3.9.0
Expand Down
Loading