【问题标题】:AVCaptureSession in modalviewcontroller on iOS5 with ARC带有ARC的iOS5上modalviewcontroller中的AVCaptureSession
【发布时间】: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


    【解决方案1】:

    我意识到我正在后置摄像头上执行 setFocusPointOfInterest,并且由于某种原因它在重新启动时破坏了会话。我不明白为什么这会导致问题,但我会对此进行调查。

    【讨论】:

    • 这也解决了我的问题。
    【解决方案2】:

    在您的程序中使用源代码之前,您可以尝试将 SquareCam 项目转换为 ARC。我可以通过在转换器抱怨的地方使用 __bridge 强制转换来做到这一点,并将“保释:”goto 替换为简单的 if 语句。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-03
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 2012-05-16
      • 1970-01-01
      相关资源
      最近更新 更多