我正在屏幕区域上进行一些运动检测。在开始检测之前,我想设置焦点和曝光并锁定它们,这样它们就不会触发错误动作。因此,我向设备发送了 AVCaptureFocusModeAutoFocus 和 AVCaptureExposureModeAutoExpose 并添加了 KeyvalueObserver。当观察者说它已经完成聚焦和改变曝光时,它会锁定它们(并开始运动检测)。对焦一切正常,但锁定曝光会在几秒钟内使应用程序崩溃”,尽管在两种情况下都有相同的代码。
static void * const MyAdjustingFocusObservationContext = (void*)&MyAdjustingFocusObservationContext;
static void * const MyAdjustingExposureObservationContext = (void*)&MyAdjustingExposureObservationContext;
-(void)focusAtPoint{
CGPoint point;
if(fromRight) point.x = 450.0/480.0;
else point.x = 30.0/480.0;
point.y = 245.0/320.0;
AVCaptureDevice *device =[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if(device != nil) {
NSError *error;
if([device lockForConfiguration:&error]){
if([device isExposureModeSupported:AVCaptureFocusModeContinuousAutoFocus] && [device isFocusPointOfInterestSupported]) {
[device setFocusPointOfInterest:point];
[device setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
[device addObserver:self forKeyPath:@"adjustingFocus" options:NSKeyValueObservingOptionNew context:MyAdjustingFocusObservationContext];
NSLog(@"focus now");
}
if([device isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure] && [device isExposurePointOfInterestSupported]) {
[device setExposurePointOfInterest:point];
[device setExposureMode:AVCaptureExposureModeContinuousAutoExposure];
[device addObserver:self forKeyPath:@"adjustingExposure" options:NSKeyValueObservingOptionNew context:MyAdjustingExposureObservationContext];
NSLog(@"expose now");
}
[device unlockForConfiguration];
}else{
NSLog(@"Error in Focus Mode");
}
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error;
if([keyPath isEqualToString:@"adjustingFocus"]){
if(![object isAdjustingFocus]){
[device removeObserver:self forKeyPath:keyPath context:context];
if([device isFocusModeSupported:AVCaptureFocusModeLocked]) {
[device lockForConfiguration:&error];
device.focusMode = AVCaptureFocusModeLocked;
[device unlockForConfiguration];
NSLog(@" focus locked");
}
}
}
if([keyPath isEqualToString:@"adjustingExposure"]){
if(![object isAdjustingExposure]){
[device removeObserver:self forKeyPath:keyPath context:context];
if([device isExposureModeSupported:AVCaptureExposureModeLocked]) {
[device lockForConfiguration:&error];
device.exposureMode=AVCaptureExposureModeLocked; //causes the crash
[device unlockForConfiguration];
NSLog(@" exposure locked");
}
}
}
如果我注释掉“device.exposureMode=AVCaptureExposureModeLocked”行,一切正常(除了焦点没有锁定)。如果我将线移动到焦点观察者,一切正常(除了曝光有时在正确设置之前锁定)。如果我以其他方式锁定曝光,例如通过计时器,它可以工作。
崩溃日志对我没有多大帮助(希望有人可以解释它)
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x00000000
Crashed Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 Foundation 0x3209d5e2 NSKVOPendingNotificationRelease + 6
1 CoreFoundation 0x317b21c8 __CFArrayReleaseValues + 352
2 CoreFoundation 0x317419f8 _CFArrayReplaceValues + 308
3 CoreFoundation 0x3174391c CFArrayRemoveValueAtIndex + 80
4 Foundation 0x3209d6b6 NSKeyValuePopPendingNotificationPerThread + 38
5 Foundation 0x32090328 NSKeyValueDidChange + 356
6 Foundation 0x3206a6ce -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] + 90
7 AVFoundation 0x30989fd0 -[AVCaptureFigVideoDevice handleNotification:payload:] + 1668
8 AVFoundation 0x30983f60 -[AVCaptureDeviceInput handleNotification:payload:] + 84
9 AVFoundation 0x3098fc64 avcaptureSessionFigRecorderNotification + 924
10 AVFoundation 0x309b1c64 AVCMNotificationDispatcherCallback + 188
11 CoreFoundation 0x317cee22 __CFNotificationCenterAddObserver_block_invoke_0 + 122
12 CoreFoundation 0x31753034 _CFXNotificationPost + 1424
13 CoreFoundation 0x3175460c CFNotificationCenterPostNotification + 100
14 CoreMedia 0x31d3db8e CMNotificationCenterPostNotification + 114
15 Celestial 0x34465aa4 FigRecorderRemoteCallbacksServer_NotificationIsPending + 628
16 Celestial 0x34465826 _XNotificationIsPending + 66
17 Celestial 0x344657dc figrecordercallbacks_server + 96
18 Celestial 0x34465028 remrec_ClientPortCallBack + 172
19 CoreFoundation 0x317cc5d8 __CFMachPortPerform + 116
20 CoreFoundation 0x317d7170 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 32
21 CoreFoundation 0x317d7112 __CFRunLoopDoSource1 + 134
22 CoreFoundation 0x317d5f94 __CFRunLoopRun + 1380
23 CoreFoundation 0x31748eb8 CFRunLoopRunSpecific + 352
24 CoreFoundation 0x31748d44 CFRunLoopRunInMode + 100
25 GraphicsServices 0x3530c2e6 GSEventRunModal + 70
26 UIKit 0x3365e2fc UIApplicationMain + 1116
27 ShootKing 0x000ed304 main (main.m:16)
28 ShootKing 0x000ed28c start + 36