camera: per-platform capture-orientation extension + macOS sensor=0

macOS preview was stretching (aspect wrong) and macOS photo capture
was rotating the landscape sensor 90° because the shared
PhotoOutput / CameraInstance code was setting
`AVCaptureConnection.videoOrientation` from the orientation snapshot
unconditionally. iOS needs that to rotate sample buffers to portrait;
macOS desktop cams are physically landscape and any rotation just
skews the result.

Moved the rotation call behind a per-platform extension on
`AVCaptureConnection`:
  - `ios/Classes/Camera/AVCaptureConnection+iOS.swift` applies the
    snapshot orientation (current behavior).
  - `macos/Classes/Camera/AVCaptureConnection+macOS.swift` is a
    no-op. macOS-flavoured photos / preview frames now flow at
    native landscape orientation.

`CaptureDevice` reports sensorOrientation=0 on macOS (was hardcoded
90 for iOS); on macOS the page's `normalizeCameraCapture` math then
collapses to identity and the saved JPEG stays the landscape the
sensor produced. iOS keeps sensorOrientation=90 (matches
camera_avfoundation's reported value and the existing capture-
transform math).

Photo and video paths now both produce upright content on macOS
(video already worked because VideoRecorder's transform table maps
the always-portraitUp macOS snapshot to `.identity`).
This commit is contained in:
agra
2026-05-13 19:07:29 +03:00
parent a6d2539722
commit 8ab672c12a
5 changed files with 62 additions and 26 deletions

View File

@@ -0,0 +1,16 @@
import AVFoundation
/// Per-platform shim for applying capture-time rotation to an
/// `AVCaptureConnection`. On iOS the connection's `videoOrientation`
/// genuinely rotates the sample buffers / captured photo; on macOS
/// it appears to rotate stills but not preview/data-output, AND
/// desktop cameras are physically landscape so any rotation skews
/// the result. The macOS counterpart in
/// `macos/Classes/Camera/AVCaptureConnection+macOS.swift` is a no-op.
extension AVCaptureConnection {
func applyUxCaptureOrientation(_ orientation: DeviceOrientationFlutter) {
if isVideoOrientationSupported {
videoOrientation = orientation.avVideoOrientation
}
}
}