Skip to content
Merged
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.23+2

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

## 0.9.23+1

* Fixes error handling in `startWriting`.
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

let videoCaptureSession: CaptureSession
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
}

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
) {
) -> (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 {
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.23+1
version: 0.9.23+2

environment:
sdk: ^3.9.0
Expand Down
Loading