【发布时间】:2012-04-09 00:16:29
【问题描述】:
试图在我的项目中呈现和关闭 AVCaptureSession(在视图控制器中),我快疯了。我目前使用的是 iOS5.1 并启用了 ARC。
我第一次展示视图控制器并启动会话时可以让它正常工作,但是当我第二次关闭并展示会话时,会话将无法启动。我订阅了“AVCaptureSessionRuntimeErrorNotification”通知并收到以下错误:
"Error Domain=AVFoundationErrorDomain Code=-11819 "Cannot Complete Action" UserInfo=0x1a4020 {NSLocalizedRecoverySuggestion=稍后再试。,NSLocalizedDescription=Cannot Complete Action}"
我假设在我的会话中没有正确发布某些内容,但是使用 ARC 没有发布,我将所有要发布的内容设置为 nil。
我的 viewDidLoad 方法基本上只是触发 initCamera
initCamera 方法:
AVCaptureSession *tmpSession = [[AVCaptureSession alloc] init];
session = tmpSession;
session.sessionPreset = AVCaptureSessionPresetMedium;
captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
captureVideoPreviewLayer.frame = self.vImagePreview.bounds;
[self.vImagePreview.layer addSublayer:captureVideoPreviewLayer];
rearCamera = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
input = [AVCaptureDeviceInput deviceInputWithDevice:rearCamera error:&error];
if (!input) {
// Handle the error appropriately.
NSLog(@"ERROR: trying to open camera: %@", error);
}
[session addInput:input];
videoDataOutput = [[AVCaptureVideoDataOutput alloc] init];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: [NSNumber numberWithInt:kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey, nil];
[videoDataOutput setVideoSettings:outputSettings];
[videoDataOutput setAlwaysDiscardsLateVideoFrames:YES];
queue = dispatch_queue_create("cameraQueue", DISPATCH_QUEUE_SERIAL);
[videoDataOutput setSampleBufferDelegate:self queue:queue];
dispatch_release(queue);
[session addOutput:videoDataOutput];
NSNotificationCenter *notify =
[NSNotificationCenter defaultCenter];
[notify addObserver: self
selector: @selector(onVideoError:)
name: AVCaptureSessionRuntimeErrorNotification
object: session];
[session startRunning];
[rearCamera lockForConfiguration:nil];
rearCamera.whiteBalanceMode = AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance;
rearCamera.exposureMode = AVCaptureExposureModeContinuousAutoExposure;
rearCamera.focusMode = AVCaptureFocusModeContinuousAutoFocus;
[rearCamera unlockForConfiguration];
方法
captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)连接
第一次显示模态视图控制器时调用没有问题,但在第二次尝试时,此方法停止调用(因为会话未启动)
为了清理,我在关闭之前从我的父视图控制器调用 stopSession,它执行以下操作:
if ([session isRunning]) {
[session removeInput:input];
[session stopRunning];
[vImagePreview removeFromSuperview];
vImagePreview = nil;
input = nil;
videoDataOutput = nil;
captureVideoPreviewLayer = nil;
session = nil;
queue = nil;
}
我觉得我已经尝试了各种各样的事情,例如在队列上执行 dispatch_sync(queue, ^{}) 以等待它被刷新,但这似乎没有什么区别(调用时dispatch_sync 我在我的初始化相机方法中删除了 dispatch_release 调用)。我也尝试过使用另一个问题中建议的 dispatch_set_finalizer_f(queue, capture_cleanup) 方法,但我不知道在 capture_cleanup 方法中实际需要做什么,因为我发现的所有示例都是非 ARC 代码,它们调用 release on指向自我的指针。我还梳理了我可以从 Apple 找到的所有示例代码(SquareCam 和 AVCam),但这些也不是 ARC。任何帮助将不胜感激。
【问题讨论】:
标签: ios automatic-ref-counting modalviewcontroller avcapturesession