Files
ux/macos/Classes/Camera/AVCaptureConnection+macOS.swift
agra 41c3fab7b5 camera: pin macOS photo connection to .portrait (counter-intuitive)
`.landscapeRight` / `videoRotationAngle = 0` both still produced a
JPEG rotated 90° CW on macOS. User verified that `.portrait` /
`videoRotationAngle = 90` is the value that DOES NOT rotate the
captured frame on the photo output's connection — counter to the
iOS convention where `.portrait` rotates the landscape sensor
frame into portrait pixels.

I'd expect this to be macOS-specific photo-pipeline plumbing; the
data output's connection still doesn't honor the setter (isSupported
returns false or the setter no-ops), so preview + video stay
unaffected. Verified empirically; not chasing the AVFoundation
source for the why.
2026-05-13 19:48:04 +03:00

39 lines
1.8 KiB
Swift

import AVFoundation
/// macOS counterpart of `AVCaptureConnection+iOS.swift`.
///
/// macOS desktop cameras are physically fixed landscape, but
/// `AVCapturePhotoOutput`'s connection defaults to a setting that
/// rotates the captured JPEG 90° CW. We pin the connection to
/// landscape (or 0° rotation, depending on the available API) so
/// the JPEG matches what the preview shows.
///
/// `videoOrientation` was deprecated in macOS 14 / iOS 17 in favour
/// of `videoRotationAngle` (a `CGFloat` in degrees). On macOS 14+
/// `videoOrientation` may be silently ignored that's exactly the
/// symptom we hit ("photo still rotated 90° CW even after setting
/// videoOrientation = .landscapeRight"). Prefer the new API where
/// available, fall back to the deprecated one for older macOS.
extension AVCaptureConnection {
func applyUxCaptureOrientation(_ orientation: DeviceOrientationFlutter) {
// macOS `AVCapturePhotoOutput`'s photo connection captures in
// landscape natively when its rotation hint is `.portrait`
// (90°). Counter-intuitive vs iOS where `.portrait` rotates
// the landscape sensor to portrait, but verified empirically
// setting `.landscapeRight` / `videoRotationAngle = 0` left
// the JPEG rotated 90° CW. The data output's connection on
// macOS doesn't honor `videoOrientation` / `videoRotationAngle`
// (or returns supported = false), so this setter is a no-op
// there and preview + video stay correct.
if #available(macOS 14.0, *) {
if isVideoRotationAngleSupported(90) {
videoRotationAngle = 90
return
}
}
if isVideoOrientationSupported {
videoOrientation = .portrait
}
}
}