How to accurately set fast shutter speeds (exposure duration) on an AVCaptureDevice?

亡梦爱人 提交于 2020-01-15 06:31:47

问题


I'm working on a camera app for IOS (13). For that I use an AVCaptureSession in conjunction with an AVCaptureVideoPreviewLayer. So far everything works fine.

Now I want to let the user choose and set a custom shutter speed (exposure duration) out of an given array of typical shutter speed values (in 1/3-exposure-stops) as an [Int32]:

let shutterSpeedValues: [Int32] = [1, 2, 3, 4, 5, 6, 8, 10, 13, 15, 20, 25, 30, 40, 50, 60, 80, 100, 125, 160, 200, 250, 320, 400, 500, 640, 800, 1000, 1250, 1600, 2000, 2500, 3200, 4000, 5000, 6400, 8000, 10000, 12800, 16000, 20000, 2400]

I set the desired exposure the - as far as I understand - only possible way with following function:

captureDevice?.setExposureModeCustom(duration: CMTimeMake(value: 1, timescale: shutterSpeedValues[index]), iso: AVCaptureDevice.currentISO, completionHandler: nil)

Checking AVCaptureDevice's exposureDuration value shows that this gives totaly accurate results for slower shutter speeds (up to 1/200th of a second). Than the discrepancies become exponentially bigger the faster the choosen exposure duration is. E.g.:

1/250th -> 1/251th
1/400th -> 1/403th
1/640th -> 1/648th
1/1000th -> 1/1021th
1/4000th -> 1/4366th
1/8000th -> 1/9615th
1/1200th -> 1/16129th
1/16000th -> 1/24390th
1/20000th -> 1/24390th
1/24000th -> 1/49999th (which is the activeFormat's minExposureDuration in this case)

I understand that there is a difference between the nominal shutter speeds (rounded approximate numbers which are more convenient for the user), and the precise actual shutter speed the camera uses (see https://www.scantips.com/lights/fstop2.html). Latter ones differing from each other exactly by a factor of 2x or 1/2 exposure of the adjacent stop (which would be values like 1/2, 1/4, 1/8, 1/16, 1/32, 1/64, 1/128, 1/256, 1/512, 1/1024, ..., 1/4096, ..., 1/8192...). This however still doesn't explain these extreme discrepancies I get with faster shutter speeds.

I also tried setting a (random) fast shutter speed explicitly like this:

captureDevice?.setExposureModeCustom(duration: CMTimeMake(value: 1, timescale: 10000, iso: AVCaptureDevice.currentISO, completionHandler: nil)

or this

captureDevice?.setExposureModeCustom(duration: CMTimeMakeWithSeconds(0.0001, preferredTimescale: 1000000000), iso: AVCaptureDevice.currentISO, completionHandler: nil) 

but both still results in a exposure duration of 1/12048th (instead of 1/10000)...

Am I missing something CMTime related, has this something to do with the frame rate of the video (though changing the captureDevice's activeVideoMinFrameDuration and activeVideoMaxFrameDuration didn't have any effect) or is it simply impossible to set completely custom exposure durations?

Btw. I encountered the same problem while trying to implement a feature which should allow the user to define a minimum shutter speed in (continuous) auto exposure mode (for which I used the captureDevice's activeMaxExposureDuration function)...

Any ideas or hints would be greatly appreciated.

来源:https://stackoverflow.com/questions/59094770/how-to-accurately-set-fast-shutter-speeds-exposure-duration-on-an-avcapturedev

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!