我正在使用 AVFoundation 类从摄像机捕获实时视频流并处理视频样本。这很好用。但是,完成后我确实无法正确释放 AVFoundation 实例(捕获 session 、预览层、输入和输出)。
当我不再需要 session 和所有关联的对象时,我会停止捕获 session 并释放它。这在大多数情况下都有效。但是,有时应用程序会因调度队列(以及处理视频样本的位置)创建的第二个线程中引发的 EXEC_BAD_ACCESS
信号而崩溃。崩溃主要是由于我自己的类实例,它充当示例缓冲区委托(delegate)并在我停止捕获 session 后被释放。
Apple 文档提到了这个问题:停止捕获 session 是一个异步操作。也就是说:它不会立即发生。特别是,第二个线程继续处理视频样本并访问不同的实例,如捕获 session 或输入和输出设备。
那么我该如何正确释放 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];
最佳答案
这是迄今为止我找到的最佳解决方案。基本思想是使用调度队列的终结器。当调度队列退出时,我们可以确定在处理样本缓冲区的第二个线程中不会再有任何操作。
static void capture_cleanup(void* p)
{
AugmReality* ar = (AugmReality *)p; // cast to original context instance
[ar release]; // releases capture session if dealloc is called
}
...
dispatch_queue_t queue = dispatch_queue_create("augm_reality", NULL);
dispatch_set_context(queue, self);
dispatch_set_finalizer_f(queue, capture_cleanup);
[output setSampleBufferDelegate: self queue: queue];
dispatch_release(queue);
[self retain];
...
不幸的是,我现在必须明确停止捕获。否则释放我的实例不会释放它,因为第二个线程现在也会递增和递减计数器。
另一个问题是我的类现在从两个不同的线程中释放。这是可靠的还是下一个导致崩溃的问题?
关于iphone - 如何正确释放 AVCaptureSession,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3741121/