camera: pin macOS connections to 0° rotation (sensor-native landscape)
Diagnostic from a fresh build with NSLog confirmed the rotation
behaviour on macOS: with `videoRotationAngle = 90`
(`.portrait`), `AVCapturePhoto.cgImageRepresentation()` returned a
720x1280 CGImage — *physical* portrait pixels, not just an EXIF
tag. So Apple's AVCaptureSession.h docs claiming
"AVCapturePhotoOutput uses EXIF only" don't hold on macOS. The
data-output connection on macOS also honors the same setter, which
is why preview + video flipped to rotated as soon as the photo fix
landed.
Pin macOS to 0° rotation (`.landscapeRight`):
- Photo: 1280x720 (sensor-native landscape, matches what the user
sees on screen).
- Preview: 1280x720 (matches the new desktop 4:3 page aspect).
- Video: 1280x720 (was already correct before the .portrait
change; back to that state).
The snapshot orientation argument is still ignored on macOS —
desktop cameras don't rotate. The argument carries through for iOS
where the camera page passes the device orientation.
This commit is contained in:
@@ -16,23 +16,25 @@ import AVFoundation
|
|||||||
/// available, fall back to the deprecated one for older macOS.
|
/// available, fall back to the deprecated one for older macOS.
|
||||||
extension AVCaptureConnection {
|
extension AVCaptureConnection {
|
||||||
func applyUxCaptureOrientation(_ orientation: DeviceOrientationFlutter) {
|
func applyUxCaptureOrientation(_ orientation: DeviceOrientationFlutter) {
|
||||||
// macOS `AVCapturePhotoOutput`'s photo connection captures in
|
// Pin to 0° rotation (`.landscapeRight`) on macOS — desktop
|
||||||
// landscape natively when its rotation hint is `.portrait`
|
// cameras are physically landscape and any non-zero rotation
|
||||||
// (90°). Counter-intuitive vs iOS where `.portrait` rotates
|
// physically rotates the buffer. Diagnostic build confirmed
|
||||||
// the landscape sensor to portrait, but verified empirically
|
// a 720x1280 CGImage (portrait) when this was set to 90°,
|
||||||
// — setting `.landscapeRight` / `videoRotationAngle = 0` left
|
// proving Apple's docs ("AVCapturePhotoOutput uses EXIF only,
|
||||||
// the JPEG rotated 90° CW. The data output's connection on
|
// no physical rotation") don't apply on macOS — and the data
|
||||||
// macOS doesn't honor `videoOrientation` / `videoRotationAngle`
|
// output's connection honors the same setter, so preview +
|
||||||
// (or returns supported = false), so this setter is a no-op
|
// video also rotate.
|
||||||
// there and preview + video stay correct.
|
//
|
||||||
|
// The Flutter snapshot is always `portraitUp` on macOS
|
||||||
|
// (desktops don't rotate); we ignore it and force landscape.
|
||||||
if #available(macOS 14.0, *) {
|
if #available(macOS 14.0, *) {
|
||||||
if isVideoRotationAngleSupported(90) {
|
if isVideoRotationAngleSupported(0) {
|
||||||
videoRotationAngle = 90
|
videoRotationAngle = 0
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if isVideoOrientationSupported {
|
if isVideoOrientationSupported {
|
||||||
videoOrientation = .portrait
|
videoOrientation = .landscapeRight
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user