Strange behavior after changing exposure duration and returning to AVCaptureExposureModeContinuousAutoExposure

I'm working on an app that provides manual controls for the camera with the new APIs introduced in iOS 8, and I'm using this example app from WWDC 2014 as a reference.

However, I noticed a strange bahaviour (on my 5s and 6s): 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.

bug

Here is the code involved in each step (from the sample application without any changes):

- (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 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);
    }
}

      

+3


source to share


3 answers


I noticed that too. This seems to be due to the slow shutter speeds. Try this: go to custom. Set a fast shutter speed. Then go back to the car. Boom, you're here. 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 return to a reasonable setting.

This is an example in the sample code and in the app I wrote based on the sample code. This is also the same for my 4 and 5.



I believe this is because the sensor has to capture a certain number of images in order to select the correct auto setting. At a very slow shutter speed (up to a maximum of 1 second), this means it may take a few seconds for the correct setting. The variety makes sense, even if not what we would like. Luckily for me, my app never needs a shutter speed of more than a quarter of a second if that is.

0


source


In my own code, I found that the setExposureModeCustomWithDuration method has some problems. While this has a completion handler to be called AFTER the duration and the ISO is set in the device, it doesn't always work. There are cases, for example when switching from auto exposure to manual exposure, that if you grab still from the setExposureModeCustomWithDuration completion handler, it is still taken with the auto exposure setting. If you then take another step forward, it will be set to the correct manual exposure.

I found that a 1 second delay at the start of the completion handler works around this issue, but that may not be the correct solution.



I also tried setting a sleep / sleep loop at the beginning of the completion handler, where it waits until the device adjusts the exposure - that doesn't help.

0


source


I tried the same sample app and tried to reproduce the problem but couldn't, it looks like it fixed it now.

0


source







All Articles