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

@@ -28,18 +28,22 @@ enum CaptureDevice {
DiscoveredCamera(
device: device,
lens: lensName(for: device.position),
// iOS doesn't expose sensor orientation directly;
// 90° matches what `camera_avfoundation` reports
// and what banlu's `normalizeCameraCapture` math
// assumes for iOS sensors. macOS desktop cameras
// are already landscape 0 is the right answer
// there but the value is unused on macOS (no
// recording rotation, no preview rotation).
sensorOrientation: 90
sensorOrientation: defaultSensorOrientation
)
}
}
/// Hardcoded per platform: 90° on iOS (matches the value
/// `camera_avfoundation` reports and that banlu's
/// `normalizeCameraCapture` math assumes), 0° on macOS (desktop
/// cams are already physically landscape any non-zero value
/// would make `normalizeCameraCapture` rotate the saved JPEG).
#if os(iOS)
private static let defaultSensorOrientation = 90
#else
private static let defaultSensorOrientation = 0
#endif
/// Per-platform set of device types the discovery session asks
/// for. iOS only has the built-in cameras; macOS additionally
/// surfaces externals + Continuity Camera (iPhone-as-webcam).