画面の領域でモーション検出を行っています。検出を開始する前に、フォーカスと露出を設定してロックし、誤ったモーションをトリガーしないようにします。したがって、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