我正在使用 AVFoundation 类从摄像机捕获实时视频流并处理视频样本。这很好用。但是,一旦完成,我确实在正确释放 AVFoundation 实例(捕获会话、预览层、输入和输出)时遇到了问题。
当我不再需要会话和所有关联对象时,我会停止捕获会话并释放它。这在大多数情况下都有效。EXEC_BAD_ACCESS
但是,有时应用程序会因调度队列(以及处理视频样本的位置)创建的第二个线程中引发的信号而崩溃。崩溃主要是由于我自己的类实例,它充当样本缓冲区委托,并在我停止捕获会话后被释放。
Apple 文档提到了这个问题:停止捕获会话是一个异步操作。那就是:它不会立即发生。特别是,第二个线程继续处理视频样本并访问不同的实例,如捕获会话或输入和输出设备。
那么如何正确释放AVCaptureSession
所有相关实例呢?是否有可靠地告诉我AVCaptureSession
已经完成的通知?
这是我的代码:
声明:
AVCaptureSession* session;
AVCaptureVideoPreviewLayer* previewLayer;
UIView* view;
实例设置:
AVCaptureDevice* camera = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];
session = [[AVCaptureSession alloc] init];
AVCaptureDeviceInput* input = [AVCaptureDeviceInput deviceInputWithDevice: camera error: &error];
[session addInput: input];
AVCaptureVideoDataOutput* output = [[[AVCaptureVideoDataOutput alloc] init] autorelease];
[session addOutput: output];
dispatch_queue_t queue = dispatch_queue_create("augm_reality", NULL);
[output setSampleBufferDelegate: self queue: queue];
dispatch_release(queue);
previewLayer = [[AVCaptureVideoPreviewLayer layerWithSession: session] retain];
previewLayer.frame = view.bounds;
[view.layer addSublayer: previewLayer];
[session startRunning];
清理:
[previewLayer removeFromSuperlayer];
[previewLayer release];
[session stopRunning];
[session release];