Tôi đang thực hiện một số phát hiện chuyển động trên một khu vực của màn hình. Trước khi bắt đầu phát hiện, tôi muốn đặt lấy nét và phơi sáng và khóa chúng để chúng không kích hoạt chuyển động sai. Do đó, tôi gửi một AVCaptureFocusModeAutoFocus và AVCaptureExposureModeAutoExpose vào thiết bị và thêm một KeyvalueObserver. Khi người quan sát nói rằng nó đã hoàn thành việc lấy nét và thay đổi phơi sáng, nó sẽ khóa chúng (và bắt đầu phát hiện chuyển động). Tất cả mọi thứ hoạt động tốt với trọng tâm, nhưng khóa phơi sáng bị treo ứng dụng trong vòng vài giây", mặc dù có mã giống hệt nhau trong cả hai trường hợp.Khóa phơi sángMode với người quan sát giá trị quan trọng gây ra tai nạn
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");
}
}
}
Nếu tôi nhận xét ra dòng 'device.exposureMode = AVCaptureExposureModeLocked' tất cả mọi thứ công trình Nếu tôi di chuyển đường tới máy quan sát lấy nét, mọi thứ hoạt động tốt (ngoại trừ việc phơi sáng đôi khi khóa trước khi nó được đặt chính xác). Nếu tôi khóa phơi sáng theo cách khác, ví dụ: thông qua
Nhật ký sự cố không giúp ích nhiều cho tôi (hy vọng ai đó có thể giải thích nó)
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
Cảm ơn câu trả lời của bạn. Bạn có lẽ đúng khi sử dụng ngữ cảnh tốt hơn, ngay cả khi nó không giúp ích trong trường hợp này. Tôi đã cập nhật câu hỏi của mình. Bạn hoàn toàn đúng trong đó có một cái gì đó kỳ lạ xảy ra khi tôi cố gắng để loại bỏ các quan sát viên (nó bắt đầu gửi giá trị ở một tỷ lệ tuyệt vời cho đến khi nó bị treo). Tôi đã thử thay đổi khi nào và theo thứ tự nào tôi thêm KVO: s, không may mắn. Tôi không chắc chắn làm thế nào để kiểm tra đề xuất của bạn để đăng một NSNotification kể từ khi AdjustFocus là chỉ đọc (hoặc tôi có thể đã hiểu lầm bạn). – Sten
@Sten cập nhật với nhiều suy nghĩ hơn – ipmcc
Thật không may tôi đã chạy KVO liên tục để bắt đầu, và nó không hoạt động (hoặc tôi đã thử nghiệm một lần nữa để chắc chắn). Vấn đề có vẻ là AVCaptureExposureModeLocked khiến KVO chạy tự do, độc lập nếu bạn loại bỏ người quan sát hay không. Trong khi AVCaptureFocusModeLocked hoạt động như mong đợi. Vì vậy, nó là một cái gì đó trong sự kết hợp của phơi sáng và KVO gây ra vấn đề. Tôi thực sự đánh giá cao nỗ lực của bạn, nhưng tôi có lẽ phải tìm cách khác để thực hiện nó. – Sten