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:
@@ -34,9 +34,12 @@ final class PhotoOutput {
|
||||
)))
|
||||
return
|
||||
}
|
||||
if connection.isVideoOrientationSupported {
|
||||
connection.videoOrientation = orientation.avVideoOrientation
|
||||
}
|
||||
// Rotation handled per-platform: iOS applies the snapshot
|
||||
// orientation to the connection (which rotates the captured
|
||||
// JPEG); macOS is a no-op (desktop cams are physically
|
||||
// landscape, any rotation skews the photo). See
|
||||
// `AVCaptureConnection+iOS.swift` / `…+macOS.swift`.
|
||||
connection.applyUxCaptureOrientation(orientation)
|
||||
// The recorded photo carries no mirror; mirroring is a
|
||||
// preview-only concern.
|
||||
if connection.isVideoMirroringSupported {
|
||||
@@ -57,12 +60,12 @@ final class PhotoOutput {
|
||||
}
|
||||
|
||||
let delegate = PhotoCaptureDelegate { [weak self] result in
|
||||
// Reset orientation on the photo connection so a future
|
||||
// capture without a snapshot defaults to portrait.
|
||||
if let conn = self?.avOutput.connection(with: .video),
|
||||
conn.isVideoOrientationSupported {
|
||||
conn.videoOrientation = .portrait
|
||||
}
|
||||
// Reset orientation back to portraitUp on the photo
|
||||
// connection so a follow-up shot without an explicit
|
||||
// snapshot defaults cleanly. No-op on macOS (the
|
||||
// extension method is empty there).
|
||||
self?.avOutput.connection(with: .video)?
|
||||
.applyUxCaptureOrientation(.portraitUp)
|
||||
self?.inFlight = nil
|
||||
DispatchQueue.main.async { completion(result) }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user