问题
I am working on an app that exposes manual controls for the camera with the new APIs introduced in iOS 8, and I am using this sample app from WWDC 2014 as a reference.
However I noticed a strange bahaviour (on my 5s and on a 6): after setting the exposure mode to "custom" and then back to "auto" the image continues to lag as if the exposure duration was not affected by this change.

Here is the code involved in each step (from the sample app, without any modification):
- (IBAction)changeExposureMode:(id)sender
{
UISegmentedControl *control = sender;
NSError *error = nil;
AVCaptureExposureMode mode = (AVCaptureExposureMode)[self.exposureModes[control.selectedSegmentIndex] intValue];
if ([self.videoDevice lockForConfiguration:&error])
{
if ([self.videoDevice isExposureModeSupported:mode])
{
[self.videoDevice setExposureMode:mode];
}
else
{
NSLog(@"Exposure mode %@ is not supported. Exposure mode is %@.", [self stringFromExposureMode:mode], [self stringFromExposureMode:self.videoDevice.exposureMode]);
}
}
else
{
NSLog(@"%@", error);
}
}
- (IBAction)changeExposureDuration:(id)sender
{
UISlider *control = sender;
NSError *error = nil;
double p = pow( control.value, EXPOSURE_DURATION_POWER ); // Apply power function to expand slider's low-end range
double minDurationSeconds = MAX(CMTimeGetSeconds(self.videoDevice.activeFormat.minExposureDuration), EXPOSURE_MINIMUM_DURATION);
double maxDurationSeconds = CMTimeGetSeconds(self.videoDevice.activeFormat.maxExposureDuration);
double newDurationSeconds = p * ( maxDurationSeconds - minDurationSeconds ) + minDurationSeconds; // Scale from 0-1 slider range to actual duration
if (self.videoDevice.exposureMode == AVCaptureExposureModeCustom)
{
if ( newDurationSeconds < 1 )
{
int digits = MAX( 0, 2 + floor( log10( newDurationSeconds ) ) );
self.exposureDurationValueLabel.text = [NSString stringWithFormat:@"1/%.*f", digits, 1/newDurationSeconds];
}
else
{
self.exposureDurationValueLabel.text = [NSString stringWithFormat:@"%.2f", newDurationSeconds];
}
}
if ([self.videoDevice lockForConfiguration:&error])
{
[self.videoDevice setExposureModeCustomWithDuration:CMTimeMakeWithSeconds(newDurationSeconds, 1000*1000*1000) ISO:AVCaptureISOCurrent completionHandler:nil];
}
else
{
NSLog(@"%@", error);
}
}
回答1:
I noticed this too. It seems to be related to slow shutter speeds. Try this: Go to custom. Set a fast shutter speed. Then go back to Auto. Boom, you're right there. Now, go to custom, set a slow shutter speed (slider to the right). Go back to auto and you can watch the shutter speed gradually move back to a reasonable setting.
This is the case in the sample code and in the app that I wrote based on the sample code. It is also the same for my 4s and 5s.
I believe that this is because the sensor needs to catch a certain number of images in order to pick the right auto setting. With a very slow shutter speed (up to 1 second long max) this means it could take several seconds to find the right setting. Sort of makes sense, even if not what we'd like. Fortunately for me my app never needs a shutter speed more than quarter of second, if that.
回答2:
I have found in my own code that the setExposureModeCustomWithDuration method has some issue. Though it has a completion handler which is supposed to be called AFTER the duration and ISO are set in the device, it doesn't always work. There are times, for instance when switching from Auto expose to manual exposure, that if you grab a still from within setExposureModeCustomWithDuration's completion handler, the still is taken with an auto expose setting. If you take another still imedeately after that, it has the correct manual exposure set on it.
I found that a 1 second delay at the beginning of the completion handler works around this issue, but that can't be a proper solution.
I have also tried placing a wait/sleep loop at the beginning of the completion handler where it waits until the device is not adjusting exposure -- that does not help.
回答3:
I tried the same sample app and tried to reproduce the issue but was not able to it looks like they have fixed it now.
来源:https://stackoverflow.com/questions/26312634/strange-behaviour-after-modifying-exposure-duration-and-going-back-to-avcapturee