iOS 27 beta: setExposureModeCustom silently ignored on the front camera

On every iOS 27.0 beta, setExposureModeCustom has no effect on the front camera (.builtInTrueDepthCamera). exposureMode does change to .custom, but the sensor keeps auto-exposing: device.iso and device.exposureDuration report auto-exposure's values, not the requested ones, and frame brightness does not change. No error is thrown. The same code works on iOS 18.x and 26.x on the same devices.

Device: iPhone 15 Pro, every iOS 27.0 beta. Also seen on iPhone 14 Pro Max, 16, 16 Pro Max and 17 Pro Max. Session: front camera, AVCaptureVideoDataOutput (BGRA) + AVCaptureDepthDataOutput. Format advertises ISO 20...1920, duration 0.00004...0.06667 s. isExposureModeSupported(.custom) is true.

Repro: let auto-exposure settle, then

try device.lockForConfiguration()
device.setExposureModeCustom(duration: CMTime(value: 1, timescale: 15), iso: 1920,
                             completionHandler: nil)
device.unlockForConfiguration()

then poll device.iso / device.exposureDuration (the completion handler never fires on this device) and measure frame luma.

Readback, polled 0.8 s after the call:

requested ISO 1920, 66.7 ms  ->  reported ISO 349, 60.0 ms
requested ISO   20,  0.04 ms ->  reported ISO 188, 66.5 ms

Requesting the shortest exposure returns the longest, and the same ISO 1920 request returned 249, 349 and 450 on three consecutive runs, so these are auto-exposure's values. Frame luma stayed within 1% between the two phases.

setExposureTargetBias, however, is honored on the same device: at +4 EV auto-exposure drives the sensor to ISO 1920 / 66.5 ms and at -4 EV to ISO 24 / 30.0 ms, moving mean luma from 49 to 232. So the sensor does reach the values setExposureModeCustom cannot set.

Question: is this intentional or a regression, and how should an app detect that a custom exposure request was refused?

Not intentional. But I'm also not reproducing this behavior in an internal test app. Please file a report at feedbackassistant.apple.com, then come back here and copy paste the FB #. Include as much info as possible, including a test app that reproduces the problem, if you can.

FB24664874

Thanks for looking at this. I found the missing piece in the meantime, and I think it explains why it did not reproduce in your test app.

The trigger is AVCaptureDepthDataOutput. With one attached to the session, setExposureModeCustom is ignored on the front camera. Remove that output and the same call is honored, on the same device and the same OS build, with nothing else changed. My original post listed the depth output in the session description but never called it out as the condition, and the repro snippet did not mention it at all, which was my mistake.

The minimal setup:

  • AVCaptureDeviceInput on .builtInTrueDepthCamera
  • AVCaptureVideoDataOutput (BGRA)
  • AVCaptureDepthDataOutput, connection enabled, activeDepthDataFormat set

Let auto-exposure settle, call setExposureModeCustom, then poll device.iso and device.exposureDuration. Repeat after removing the depth output:

session.beginConfiguration()
session.removeOutput(depthDataOutput)
session.commitConfiguration()

The readback then matches the request.

One thing I could not isolate is whether it is the depth output being in the session graph or activeDepthDataFormat being non-nil, because removing the output also clears the active format.

The FB has the full steps, the readback numbers for both cases, and the device list. I did not attach a sample app, but adding an AVCaptureDepthDataOutput to a TrueDepth test app you already have should be enough to reproduce it.

iOS 27 beta: setExposureModeCustom silently ignored on the front camera
 
 
Q