Ramy Al Zuhouri
Ramy Al Zuhouri

Reputation: 21966

AVFoundation - exposure is not changing

I am trying to change the exposure duration of the camera by reading a pan gesture:

AVCaptureDeviceInput* deviceInput = (AVCaptureDeviceInput*)input;
NSError* error;
        
if([deviceInput.device isExposurePointOfInterestSupported] && [deviceInput.device isExposureModeSupported:AVCaptureExposureModeCustom]) {
    Float64 minExposure = CMTimeGetSeconds([deviceInput.device.activeFormat minExposureDuration]);
    Float64 maxExposure = CMTimeGetSeconds([deviceInput.device.activeFormat maxExposureDuration]);
    Float64 currentExposure = CMTimeGetSeconds([deviceInput.device exposureDuration]);
    Float64 delta = translation.y * (maxExposure - minExposure) + minExposure;
    Float64 newExposure = MIN(MAX(currentExposure + delta, minExposure), maxExposure);
            
    [deviceInput.device addObserver:self forKeyPath:@"isAdjustingExposure" options:NSKeyValueObservingOptionNew context:nil];
            
    [deviceInput.device lockForConfiguration:&error];
            
    [deviceInput.device setExposureMode:AVCaptureExposureModeAutoExpose];
    [deviceInput.device setExposurePointOfInterest:focusPoint];
    [deviceInput.device setExposureModeCustomWithDuration:CMTimeMake(newExposure, 0) ISO:AVCaptureISOCurrent completionHandler:nil];                                                  
                                                
            
    [deviceInput.device unlockForConfiguration];
}

Then based on this answer to a previous question I am also observing "isAdjustingExposure" in order to lock the exposure when it's set:

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary<NSKeyValueChangeKey,id> *)change
                       context:(void *)context {
    if([keyPath isEqualToString:@"isAdjustingExposure"]) {
        NSNumber* value = [object valueForKey:@"isAdjustingExposure"];
            
        if(value && ![value boolValue]) {
            [object setExposureMode:AVCaptureExposureModeLocked];
        }
    }
}

But for some reason this method is never called. I am not sure if this last step is necessary, but anyways this is not working because I notice that the current exposure value stays always the same, and I can also see visually that the camera doesn't adjust its exposure.

Upvotes: 2

Views: 161

Answers (1)

Gordon Childs
Gordon Childs

Reputation: 36072

The key name is "adjustingExposure" and not "isAdjustingExposure" and your exposure duration becomes 0/0 with the Float64 to int64_t conversion in CMTimeMake(), so try

CMTimeMakeWithSeconds(newExposure, 10000)

for your custom exposure duration

Upvotes: 1

Related Questions