RotationCoordinator returns angles 90 degrees lower on iPhone 17 Pro front camera — clarification on contract with AVSampleBufferDisplayLayer

Hi AVFoundation team,

I'm seeing a uniform 90° offset in AVCaptureDevice.RotationCoordinator's reported angles between iPhone 17 Pro and iPhone 14 Pro using the front-facing .builtInWideAngleCamera (Center Stage on 17 Pro), and I'd like to confirm whether this is by design and what the recommended consumption pattern is when the rendering surface is an AVSampleBufferDisplayLayer rather than an AVCaptureVideoPreviewLayer.

Here is the github repo of sample project.

Setup

  • Devices: iPhone 14 Pro (iOS 26.5) and iPhone 17 Pro (iOS 26.4.2)
  • Camera: front, AVCaptureDeviceTypeBuiltInWideAngleCamera
  • Active format: 1920×1080
  • Three RotationCoordinator instances are created on the same AVCaptureDevice,

varying only the previewLayer: argument: - previewLayer: nil - previewLayer: AVSampleBufferDisplayLayer (the surface receiving frames from AVCaptureVideoDataOutput) - previewLayer: AVCaptureVideoPreviewLayer (with .session = captureSession, not displayed)

Each instance is KVO-observed for videoRotationAngleForHorizonLevelPreview and videoRotationAngleForHorizonLevelCapture.

Observed angles

Device / Orientation: 14 Pro · Portrait (interface=1) RC[nil] prev / cap: 0° / 90° RC[AVSampleBufferLayer] prev / cap: 90° / 90° RC[AVCaptureVideoPreviewLayer] prev / cap: 0° / 90° ──────────────────────────────────────── Device / Orientation: 14 Pro · LandscapeRight (interface=3) RC[nil] prev / cap: 0° / 180° RC[AVSampleBufferLayer] prev / cap: 180° / 180° RC[AVCaptureVideoPreviewLayer] prev / cap: 0° / 180° ──────────────────────────────────────── Device / Orientation: 17 Pro · Portrait (interface=1) RC[nil] prev / cap: 0° / 0° RC[AVSampleBufferLayer] prev / cap: 0° / 0° RC[AVCaptureVideoPreviewLayer] prev / cap: 0° / 0° ──────────────────────────────────────── Device / Orientation: 17 Pro · LandscapeRight (interface=3) RC[nil] prev / cap: 0° / 90° RC[AVSampleBufferLayer] prev / cap: 90° / 90° RC[AVCaptureVideoPreviewLayer] prev / cap: 0° / 90°

The −90° offset on 17 Pro is uniform: it appears in every RC variant, in both the preview-angle and the capture-angle properties, at every orientation tested. It is not specific to the previewLayer: argument.

To clarify the issue, our preview pipeline rotates the sample-buffer display layer by applying the RotationCoordinator angle as a transform on the layer itself, while leaving the data-output connection's rotation unset — a pattern that worked on every iPhone before 17 Pro because the buffer always arrived in the same default orientation. On the iPhone 17 Pro front cam the same code renders 90° off: RC still returns correct values, but the buffer's default orientation is itself 90° offset from every earlier device, so "RC's angle applied as a layer transform" no longer lands upright. The hidden dependency that broke is exactly this — applying RC's angle on the layer only works when the buffer's default orientation is fixed across devices, and since we never set the connection's rotation, we were silently relying on that default, which shifted on this one camera. The supported fix (driving connection.videoRotationAngle directly) corrects orientation but causes the emitted buffer's pixel dimensions to swap between portrait and landscape(1920x1080 to 1080x1920, which then breaks the preview aspect-ratio layout and the AVAssetWriter transform that were both built around stable buffer dimensions.

RotationCoordinator returns angles 90 degrees lower on iPhone 17 Pro front camera — clarification on contract with AVSampleBufferDisplayLayer
 
 
Q